b311480e |
1 | // Created on: 1994-10-27 |
2 | // Created by: Jean Yves LEBEY |
3 | // Copyright (c) 1994-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | #include <TopOpeBRepDS_SolidSurfaceInterference.hxx> |
23 | #include <TopOpeBRepDS_CurvePointInterference.hxx> |
24 | #include <TopOpeBRepDS_SurfaceCurveInterference.hxx> |
25 | #include <TopAbs.hxx> |
26 | #include <IntSurf_Transition.hxx> |
27 | #include <IntSurf_TypeTrans.hxx> |
28 | #include <IntSurf_Situation.hxx> |
29 | #include <TopOpeBRep_FFTransitionTool.ixx> |
30 | #include <TopoDS_Edge.hxx> |
31 | #include <TopoDS_Face.hxx> |
32 | #include <TopoDS.hxx> |
33 | #include <BRep_Tool.hxx> |
34 | #include <Geom_Surface.hxx> |
35 | #include <Geom_Curve.hxx> |
36 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
37 | #include <gp_Vec.hxx> |
38 | |
39 | #ifdef DEB |
1d0a9d4d |
40 | extern Standard_Boolean TopOpeBRepDS_GettraceDSF(); |
7fd59977 |
41 | #endif |
42 | |
43 | //----------------------------------------------------------------------- |
44 | //function : TransitionToOrientation |
45 | //purpose : static |
46 | //----------------------------------------------------------------------- |
47 | |
48 | static Standard_Boolean TransitionToOrientation |
49 | (const IntSurf_Transition& T, |
50 | TopAbs_Orientation& O) |
51 | { |
52 | Standard_Boolean Odefined = Standard_True; |
53 | TopAbs_Orientation result = TopAbs_FORWARD; |
54 | IntSurf_TypeTrans trans; |
55 | IntSurf_Situation situa; |
56 | |
57 | trans = T.TransitionType(); |
58 | |
59 | switch (trans) { |
60 | |
61 | case IntSurf_In : result = TopAbs_FORWARD; break; |
62 | case IntSurf_Out : result = TopAbs_REVERSED; break; |
63 | |
64 | case IntSurf_Touch : |
65 | situa = T.Situation(); |
66 | switch (situa) { |
67 | case IntSurf_Inside : result = TopAbs_INTERNAL; break; |
68 | case IntSurf_Outside : result = TopAbs_EXTERNAL; break; |
69 | case IntSurf_Unknown : |
70 | Odefined = Standard_False; |
71 | #ifdef DEB |
72 | // if ( TopOpeBRepDS_GettraceDSF() ) { |
73 | // cout<<"TopOpeBRepDS:TransitionToOrientation : unknown situation"<<endl; |
74 | // } |
75 | #endif |
76 | break; |
77 | } |
78 | break; |
79 | |
80 | case IntSurf_Undecided : |
81 | Odefined = Standard_False; |
82 | #ifdef DEB |
83 | // if ( TopOpeBRepDS_GettraceDSF() ) { |
84 | // cout<<"TopOpeBRepDS:TransitionToOrientation : undecided transition"<<endl; |
85 | // } |
86 | #endif |
87 | break; |
88 | } |
89 | |
90 | O = result; |
91 | return Odefined; |
92 | } |
93 | |
94 | |
95 | //======================================================================= |
96 | //function : ProcessLineTransition |
97 | //purpose : compute the transition of the intersection |
98 | // : point <P> on the intersected shape of index <Index> (1 or 2) |
99 | // : for a line crossing an edge |
100 | //======================================================================= |
101 | |
102 | TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessLineTransition |
103 | (const TopOpeBRep_VPointInter &P, |
104 | const Standard_Integer Index, |
105 | const TopAbs_Orientation EdgeOrientation) |
106 | { |
107 | TopOpeBRepDS_Transition TT; |
108 | |
109 | if ((EdgeOrientation==TopAbs_INTERNAL)||(EdgeOrientation==TopAbs_EXTERNAL)) { |
110 | TT.Set(EdgeOrientation); |
111 | } |
112 | else { |
113 | TopAbs_Orientation O; |
114 | |
115 | IntSurf_Transition T; { |
116 | switch (Index) { |
117 | case 1 : T = P.TransitionLineArc1(); break; |
118 | case 2 : T = P.TransitionLineArc2(); break; |
119 | } |
120 | Standard_Boolean Odefined = ::TransitionToOrientation(T,O); |
121 | if (Odefined) { |
122 | if (EdgeOrientation == TopAbs_REVERSED) O = TopAbs::Complement(O); |
123 | TT.Set(O); |
124 | } |
125 | else { |
126 | TT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN); |
127 | } |
128 | } |
129 | } |
130 | return TT; |
131 | } |
132 | |
133 | //======================================================================= |
134 | //function : ProcessLineTransition |
135 | //purpose : compute the transition of point P on line L, P lying on |
136 | // neither of the intersecting shapes |
137 | //======================================================================= |
138 | |
139 | TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessLineTransition |
140 | (const TopOpeBRep_VPointInter &P, const TopOpeBRep_LineInter& LI) |
141 | { |
142 | TopOpeBRepDS_Transition TT; |
143 | TopAbs_Orientation result; |
144 | |
145 | // P.IsOnDomS1() and P.IsOnDomS2() are both false |
146 | |
147 | Standard_Integer nbv = LI.NbVPoint(); |
148 | TopOpeBRep_VPointInter P1 = LI.VPoint(1); |
149 | Standard_Real par1 = P1.ParameterOnLine(); |
150 | TopOpeBRep_VPointInter Pn = LI.VPoint(nbv); |
151 | Standard_Real parn = Pn.ParameterOnLine(); |
152 | |
153 | Standard_Real par = P.ParameterOnLine(); |
154 | if ( par == par1 ) result = TopAbs_FORWARD; |
155 | else if ( par == parn ) result = TopAbs_REVERSED; |
156 | else result = TopAbs_INTERNAL; |
157 | |
158 | TT.Set(result); |
159 | return TT; |
160 | } |
161 | |
162 | |
163 | //======================================================================= |
164 | //function : ProcessEdgeTransition |
165 | //purpose : compute the transition from the transition of the intersection |
166 | // : point <P> on the intersected shape of index <Index> (1 or 2) |
167 | // : for an edge on a line on a Face |
168 | //======================================================================= |
169 | |
170 | TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessEdgeTransition |
171 | (const TopOpeBRep_VPointInter &P, |
172 | const Standard_Integer Index, |
173 | const TopAbs_Orientation FaceTransition) |
174 | { |
175 | TopOpeBRepDS_Transition TT; |
176 | |
177 | if ((FaceTransition == TopAbs_INTERNAL) || |
178 | (FaceTransition == TopAbs_EXTERNAL)) { |
179 | TT.Set(FaceTransition); |
180 | } |
181 | else { |
182 | IntSurf_Transition T; |
183 | if ( Index == 1 ) T = P.TransitionOnS1(); |
184 | else if ( Index == 2 ) T = P.TransitionOnS2(); |
185 | |
186 | TopAbs_Orientation O; |
187 | Standard_Boolean defined = ::TransitionToOrientation(T,O); |
188 | if (defined) { |
189 | if (FaceTransition == TopAbs_REVERSED) O = TopAbs::Complement(O); |
190 | TT.Set(O); |
191 | } |
192 | else { |
193 | TT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN); |
194 | } |
195 | } |
196 | |
197 | return TT; |
198 | } |
199 | |
200 | |
201 | //======================================================================= |
202 | //function : ProcessFaceTransition |
203 | //purpose : compute the transition from a Line |
204 | //======================================================================= |
205 | |
206 | TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessFaceTransition |
207 | (const TopOpeBRep_LineInter& L, |
208 | const Standard_Integer Index, |
209 | const TopAbs_Orientation FaceOrientation) |
210 | { |
211 | // If Index == 1, on first shape |
212 | // If Index == 2, on second shape |
213 | TopOpeBRepDS_Transition TT; |
214 | |
215 | if ((FaceOrientation == TopAbs_INTERNAL) || |
216 | (FaceOrientation == TopAbs_EXTERNAL)) { |
217 | TT.Set(FaceOrientation); |
218 | } |
219 | else { |
220 | Standard_Boolean Odefined = Standard_True; |
1d47d8d0 |
221 | |
7fd59977 |
222 | TopAbs_Orientation O = TopAbs_FORWARD; |
7fd59977 |
223 | |
224 | IntSurf_TypeTrans trans; |
225 | trans = (Index == 1) ? L.TransitionOnS1() : L.TransitionOnS2(); |
226 | |
227 | switch (trans) { |
228 | |
229 | case IntSurf_In : O = TopAbs_FORWARD; break; |
230 | |
231 | case IntSurf_Out : O = TopAbs_REVERSED; break; |
232 | |
233 | case IntSurf_Touch : { |
234 | |
235 | IntSurf_Situation situa; |
236 | situa = (Index == 1 ) ? L.SituationS1() : L.SituationS2(); |
237 | |
238 | switch (situa) { |
239 | |
240 | case IntSurf_Inside : O = TopAbs_INTERNAL; break; |
241 | |
242 | case IntSurf_Outside : O = TopAbs_EXTERNAL; break; |
243 | |
244 | case IntSurf_Unknown : |
245 | |
246 | Odefined = Standard_False; |
247 | #ifdef DEB |
248 | if ( TopOpeBRepDS_GettraceDSF() ) { |
249 | cout<<"ProcessFaceTransition : unknown situation"<<endl; |
250 | } |
251 | #endif |
252 | break; |
253 | } |
254 | break; |
255 | } // case Touch |
256 | |
257 | case IntSurf_Undecided : |
258 | |
259 | Odefined = Standard_False; |
260 | #ifdef DEB |
261 | if ( TopOpeBRepDS_GettraceDSF() ) { |
262 | cout<<"ProcessFaceTransition : undecided transition"<<endl; |
263 | } |
264 | #endif |
265 | break; |
266 | |
267 | } // trans |
268 | |
269 | if (Odefined) { |
270 | if (FaceOrientation == TopAbs_REVERSED) O = TopAbs::Complement(O); |
271 | TT.Set(O); |
272 | } |
273 | else { |
274 | TT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN); |
275 | } |
276 | } |
277 | |
278 | return TT; |
279 | } |
280 | |
281 | |
282 | // ------------------------------------------------- |
283 | // input : P1 : point |
284 | // input : C2 : courbe, FC2,LC2 : bornes de C2 |
285 | // output : T2 = parametre de P1 sur C2 |
286 | // ------------------------------------------------- |
287 | static Standard_Boolean FUN_ProjectPoint(const gp_Pnt& P1, |
288 | const Handle(Geom_Curve)& C2, |
289 | const Standard_Real FC2, |
290 | const Standard_Real LC2, |
291 | Standard_Real& T2) |
292 | { |
293 | if ( C2.IsNull() ) { |
294 | return Standard_False; |
295 | } |
296 | Standard_Real res = Standard_False; |
297 | |
298 | GeomAPI_ProjectPointOnCurve mydist(P1,C2,FC2,LC2); |
299 | if ( mydist.Extrema().IsDone() ) { |
300 | if ( mydist.NbPoints() ) { |
301 | T2 = mydist.LowerDistanceParameter(); |
302 | res = Standard_True; |
303 | } |
304 | } |
305 | //#ifdef DEB |
306 | // return res; // BUG ??? |
307 | //#else |
308 | return (Standard_Boolean ) res ; |
309 | //#endif |
310 | |
311 | } |
312 | |
313 | // ------------------------------------------------- |
314 | // input : S1,U1,V1,C1,T1 avec D0(S1(U1,V1)) = D0(C1(T1)) |
315 | // input : C2,FC2,LC2 : courbe, bornes de C2 |
316 | // output : Trans : transition sur C1 en T1 en croisant C2 |
317 | // ------------------------------------------------- |
318 | static Standard_Boolean FUN_GeomTrans(const Handle(Geom_Surface)& S1, |
319 | const Standard_Real U1, |
320 | const Standard_Real V1, |
321 | const Handle(Geom_Curve)& C1, |
322 | const Standard_Real T1, |
323 | const Handle(Geom_Curve)& C2, |
324 | const Standard_Real FC2, |
325 | const Standard_Real LC2, |
326 | TopOpeBRepDS_Transition& Trans) |
327 | { |
328 | if ( C1.IsNull() || C2.IsNull() ) { |
329 | return Standard_False; |
330 | } |
331 | |
332 | // P1 : D0(C1(T1), D1_C1 : D1(C1(T1)) |
333 | gp_Pnt P1; gp_Vec D1_C1; C1->D1(T1,P1,D1_C1); |
334 | |
335 | // D1_C2 : D1(C2(P1)) |
336 | Standard_Real T2; |
337 | Standard_Boolean projok = ::FUN_ProjectPoint(P1,C2,FC2,LC2,T2); |
338 | if ( !projok ) { |
339 | return Standard_False; |
340 | } |
341 | gp_Pnt P2; gp_Vec D1_C2; C2->D1(T2,P2,D1_C2); |
342 | |
343 | // N1 : D1(S1(U1,V1)) |
344 | gp_Vec N1,D1U,D1V; |
345 | gp_Pnt PS; |
346 | S1->D1(U1,V1,PS,D1U,D1V); |
347 | D1U.Normalize(); |
348 | D1V.Normalize(); |
349 | N1 = D1U.Crossed(D1V); |
350 | N1.Normalize(); |
351 | |
352 | gp_Vec N1D1_C1 = N1.Crossed(D1_C1); |
353 | Standard_Real dot = N1D1_C1.Dot(D1_C2); |
354 | if ( dot > 0 ) { |
355 | Trans.Before(TopAbs_OUT); |
356 | Trans.After(TopAbs_IN); |
357 | } |
358 | else { |
359 | Trans.Before(TopAbs_IN); |
360 | Trans.After(TopAbs_OUT); |
361 | } |
362 | |
363 | return Standard_True; |
364 | } |
365 | |
366 | //======================================================================= |
367 | //function : ProcessEdgeONTransition |
368 | //purpose : |
369 | //======================================================================= |
370 | |
371 | TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessEdgeONTransition |
372 | (const TopOpeBRep_VPointInter& VP, |
373 | const Standard_Integer ShapeIndex, |
374 | const TopoDS_Shape& RR, |
375 | const TopoDS_Shape& EE, |
376 | const TopoDS_Shape& FF) |
377 | { |
378 | const TopoDS_Edge& R = TopoDS::Edge(RR); |
379 | const TopoDS_Edge& E = TopoDS::Edge(EE); |
380 | const TopoDS_Face& F = TopoDS::Face(FF); |
381 | |
382 | TopAbs_Orientation oriE = E.Orientation(); |
383 | |
384 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(F); |
1d47d8d0 |
385 | Standard_Real U = 0.,V = 0.; |
7fd59977 |
386 | if (ShapeIndex == 1) VP.ParametersOnS1(U,V); |
387 | else if (ShapeIndex == 2) VP.ParametersOnS2(U,V); |
388 | |
389 | Standard_Real fE,lE; |
390 | const Handle(Geom_Curve)& CE = BRep_Tool::Curve(E,fE,lE); |
391 | Standard_Real TE = VP.EdgeParameter(ShapeIndex); |
392 | |
393 | Standard_Real fR,lR; |
394 | const Handle(Geom_Curve)& CR = BRep_Tool::Curve(R,fR,lR); |
395 | |
396 | TopOpeBRepDS_Transition Trans; |
397 | Standard_Boolean transok = ::FUN_GeomTrans(S,U,V,CE,TE,CR,fR,lR,Trans); |
398 | if ( transok ) { |
399 | // Trans : transition sur R en croisant l'arete E orientee dans la face F |
400 | if (oriE == TopAbs_REVERSED) Trans = Trans.Complement(); |
401 | } |
402 | |
403 | return Trans; |
404 | } |