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 |
40 | Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettraceDSF(); |
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; |
221 | #ifdef DEB |
222 | TopAbs_Orientation O; |
223 | #else |
224 | TopAbs_Orientation O = TopAbs_FORWARD; |
225 | #endif |
226 | |
227 | IntSurf_TypeTrans trans; |
228 | trans = (Index == 1) ? L.TransitionOnS1() : L.TransitionOnS2(); |
229 | |
230 | switch (trans) { |
231 | |
232 | case IntSurf_In : O = TopAbs_FORWARD; break; |
233 | |
234 | case IntSurf_Out : O = TopAbs_REVERSED; break; |
235 | |
236 | case IntSurf_Touch : { |
237 | |
238 | IntSurf_Situation situa; |
239 | situa = (Index == 1 ) ? L.SituationS1() : L.SituationS2(); |
240 | |
241 | switch (situa) { |
242 | |
243 | case IntSurf_Inside : O = TopAbs_INTERNAL; break; |
244 | |
245 | case IntSurf_Outside : O = TopAbs_EXTERNAL; break; |
246 | |
247 | case IntSurf_Unknown : |
248 | |
249 | Odefined = Standard_False; |
250 | #ifdef DEB |
251 | if ( TopOpeBRepDS_GettraceDSF() ) { |
252 | cout<<"ProcessFaceTransition : unknown situation"<<endl; |
253 | } |
254 | #endif |
255 | break; |
256 | } |
257 | break; |
258 | } // case Touch |
259 | |
260 | case IntSurf_Undecided : |
261 | |
262 | Odefined = Standard_False; |
263 | #ifdef DEB |
264 | if ( TopOpeBRepDS_GettraceDSF() ) { |
265 | cout<<"ProcessFaceTransition : undecided transition"<<endl; |
266 | } |
267 | #endif |
268 | break; |
269 | |
270 | } // trans |
271 | |
272 | if (Odefined) { |
273 | if (FaceOrientation == TopAbs_REVERSED) O = TopAbs::Complement(O); |
274 | TT.Set(O); |
275 | } |
276 | else { |
277 | TT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN); |
278 | } |
279 | } |
280 | |
281 | return TT; |
282 | } |
283 | |
284 | |
285 | // ------------------------------------------------- |
286 | // input : P1 : point |
287 | // input : C2 : courbe, FC2,LC2 : bornes de C2 |
288 | // output : T2 = parametre de P1 sur C2 |
289 | // ------------------------------------------------- |
290 | static Standard_Boolean FUN_ProjectPoint(const gp_Pnt& P1, |
291 | const Handle(Geom_Curve)& C2, |
292 | const Standard_Real FC2, |
293 | const Standard_Real LC2, |
294 | Standard_Real& T2) |
295 | { |
296 | if ( C2.IsNull() ) { |
297 | return Standard_False; |
298 | } |
299 | Standard_Real res = Standard_False; |
300 | |
301 | GeomAPI_ProjectPointOnCurve mydist(P1,C2,FC2,LC2); |
302 | if ( mydist.Extrema().IsDone() ) { |
303 | if ( mydist.NbPoints() ) { |
304 | T2 = mydist.LowerDistanceParameter(); |
305 | res = Standard_True; |
306 | } |
307 | } |
308 | //#ifdef DEB |
309 | // return res; // BUG ??? |
310 | //#else |
311 | return (Standard_Boolean ) res ; |
312 | //#endif |
313 | |
314 | } |
315 | |
316 | // ------------------------------------------------- |
317 | // input : S1,U1,V1,C1,T1 avec D0(S1(U1,V1)) = D0(C1(T1)) |
318 | // input : C2,FC2,LC2 : courbe, bornes de C2 |
319 | // output : Trans : transition sur C1 en T1 en croisant C2 |
320 | // ------------------------------------------------- |
321 | static Standard_Boolean FUN_GeomTrans(const Handle(Geom_Surface)& S1, |
322 | const Standard_Real U1, |
323 | const Standard_Real V1, |
324 | const Handle(Geom_Curve)& C1, |
325 | const Standard_Real T1, |
326 | const Handle(Geom_Curve)& C2, |
327 | const Standard_Real FC2, |
328 | const Standard_Real LC2, |
329 | TopOpeBRepDS_Transition& Trans) |
330 | { |
331 | if ( C1.IsNull() || C2.IsNull() ) { |
332 | return Standard_False; |
333 | } |
334 | |
335 | // P1 : D0(C1(T1), D1_C1 : D1(C1(T1)) |
336 | gp_Pnt P1; gp_Vec D1_C1; C1->D1(T1,P1,D1_C1); |
337 | |
338 | // D1_C2 : D1(C2(P1)) |
339 | Standard_Real T2; |
340 | Standard_Boolean projok = ::FUN_ProjectPoint(P1,C2,FC2,LC2,T2); |
341 | if ( !projok ) { |
342 | return Standard_False; |
343 | } |
344 | gp_Pnt P2; gp_Vec D1_C2; C2->D1(T2,P2,D1_C2); |
345 | |
346 | // N1 : D1(S1(U1,V1)) |
347 | gp_Vec N1,D1U,D1V; |
348 | gp_Pnt PS; |
349 | S1->D1(U1,V1,PS,D1U,D1V); |
350 | D1U.Normalize(); |
351 | D1V.Normalize(); |
352 | N1 = D1U.Crossed(D1V); |
353 | N1.Normalize(); |
354 | |
355 | gp_Vec N1D1_C1 = N1.Crossed(D1_C1); |
356 | Standard_Real dot = N1D1_C1.Dot(D1_C2); |
357 | if ( dot > 0 ) { |
358 | Trans.Before(TopAbs_OUT); |
359 | Trans.After(TopAbs_IN); |
360 | } |
361 | else { |
362 | Trans.Before(TopAbs_IN); |
363 | Trans.After(TopAbs_OUT); |
364 | } |
365 | |
366 | return Standard_True; |
367 | } |
368 | |
369 | //======================================================================= |
370 | //function : ProcessEdgeONTransition |
371 | //purpose : |
372 | //======================================================================= |
373 | |
374 | TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessEdgeONTransition |
375 | (const TopOpeBRep_VPointInter& VP, |
376 | const Standard_Integer ShapeIndex, |
377 | const TopoDS_Shape& RR, |
378 | const TopoDS_Shape& EE, |
379 | const TopoDS_Shape& FF) |
380 | { |
381 | const TopoDS_Edge& R = TopoDS::Edge(RR); |
382 | const TopoDS_Edge& E = TopoDS::Edge(EE); |
383 | const TopoDS_Face& F = TopoDS::Face(FF); |
384 | |
385 | TopAbs_Orientation oriE = E.Orientation(); |
386 | |
387 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(F); |
388 | Standard_Real U,V; |
389 | if (ShapeIndex == 1) VP.ParametersOnS1(U,V); |
390 | else if (ShapeIndex == 2) VP.ParametersOnS2(U,V); |
391 | |
392 | Standard_Real fE,lE; |
393 | const Handle(Geom_Curve)& CE = BRep_Tool::Curve(E,fE,lE); |
394 | Standard_Real TE = VP.EdgeParameter(ShapeIndex); |
395 | |
396 | Standard_Real fR,lR; |
397 | const Handle(Geom_Curve)& CR = BRep_Tool::Curve(R,fR,lR); |
398 | |
399 | TopOpeBRepDS_Transition Trans; |
400 | Standard_Boolean transok = ::FUN_GeomTrans(S,U,V,CE,TE,CR,fR,lR,Trans); |
401 | if ( transok ) { |
402 | // Trans : transition sur R en croisant l'arete E orientee dans la face F |
403 | if (oriE == TopAbs_REVERSED) Trans = Trans.Complement(); |
404 | } |
405 | |
406 | return Trans; |
407 | } |