0024059: Eliminate compiler warning C4701 in MSVC++ with warning level 4
[occt.git] / src / TopOpeBRep / TopOpeBRep_FFTransitionTool.cxx
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
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 extern 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
222     TopAbs_Orientation O = TopAbs_FORWARD;
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);
385  Standard_Real U = 0.,V = 0.;
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 }