0027525: Coding - eliminate warnings on Windows for OCCT with static type of libraries
[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-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Tool.hxx>
19 #include <Geom_Curve.hxx>
20 #include <Geom_Surface.hxx>
21 #include <GeomAPI_ProjectPointOnCurve.hxx>
22 #include <gp_Vec.hxx>
23 #include <IntSurf_Situation.hxx>
24 #include <IntSurf_Transition.hxx>
25 #include <IntSurf_TypeTrans.hxx>
26 #include <TopAbs.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopOpeBRep_FFTransitionTool.hxx>
32 #include <TopOpeBRep_LineInter.hxx>
33 #include <TopOpeBRep_VPointInter.hxx>
34 #include <TopOpeBRepDS_CurvePointInterference.hxx>
35 #include <TopOpeBRepDS_SolidSurfaceInterference.hxx>
36 #include <TopOpeBRepDS_SurfaceCurveInterference.hxx>
37 #include <TopOpeBRepDS_Transition.hxx>
38
39 //-----------------------------------------------------------------------
40 //function : TransitionToOrientation
41 //purpose  : static
42 //-----------------------------------------------------------------------
43
44 static Standard_Boolean TransitionToOrientation
45 (const IntSurf_Transition& T, 
46  TopAbs_Orientation& O)
47 {
48   Standard_Boolean Odefined = Standard_True;
49   TopAbs_Orientation result = TopAbs_FORWARD;
50   IntSurf_TypeTrans trans;
51   IntSurf_Situation situa;
52
53   trans = T.TransitionType();
54
55   switch (trans) {
56     
57   case IntSurf_In  : result = TopAbs_FORWARD; break;
58   case IntSurf_Out : result = TopAbs_REVERSED; break;
59     
60   case IntSurf_Touch :
61     situa = T.Situation();
62     switch (situa) {
63     case IntSurf_Inside  : result = TopAbs_INTERNAL;  break;
64     case IntSurf_Outside : result = TopAbs_EXTERNAL; break;
65     case IntSurf_Unknown :
66     Odefined = Standard_False;
67     break;
68     }
69     break;
70
71   case IntSurf_Undecided :
72   Odefined = Standard_False;
73   break;
74   }
75
76   O = result;
77   return Odefined;
78 }
79
80
81 //=======================================================================
82 //function : ProcessLineTransition
83 //purpose  : compute the transition of the intersection
84 //         : point <P> on the intersected shape of index <Index> (1 or 2)
85 //         : for a line crossing an edge
86 //=======================================================================
87
88 TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessLineTransition
89   (const TopOpeBRep_VPointInter &P,
90    const Standard_Integer Index,
91    const TopAbs_Orientation EdgeOrientation)
92 {
93   TopOpeBRepDS_Transition TT;
94
95   if ((EdgeOrientation==TopAbs_INTERNAL)||(EdgeOrientation==TopAbs_EXTERNAL)) {
96     TT.Set(EdgeOrientation);
97   }
98   else {
99     TopAbs_Orientation O;
100     
101     IntSurf_Transition T; {
102     switch (Index) {
103     case 1 : T = P.TransitionLineArc1(); break;
104     case 2 : T = P.TransitionLineArc2(); break;
105     }
106     Standard_Boolean Odefined = ::TransitionToOrientation(T,O);
107     if (Odefined) {
108       if (EdgeOrientation == TopAbs_REVERSED) O = TopAbs::Complement(O);
109       TT.Set(O);
110     }
111     else {
112       TT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
113     }
114     }
115   }
116   return TT;
117 }
118
119 //=======================================================================
120 //function : ProcessLineTransition
121 //purpose  : compute the transition of point P on line L, P lying on
122 //           neither of the intersecting shapes
123 //=======================================================================
124
125 TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessLineTransition
126 (const TopOpeBRep_VPointInter &P, const TopOpeBRep_LineInter& LI)
127 {
128   TopOpeBRepDS_Transition TT;
129   TopAbs_Orientation result;
130   
131   // P.IsOnDomS1() and P.IsOnDomS2() are both false
132
133   Standard_Integer nbv = LI.NbVPoint();
134   TopOpeBRep_VPointInter P1 = LI.VPoint(1);
135   Standard_Real par1 = P1.ParameterOnLine();
136   TopOpeBRep_VPointInter Pn = LI.VPoint(nbv);
137   Standard_Real parn = Pn.ParameterOnLine();
138
139   Standard_Real par = P.ParameterOnLine();
140   if      ( par == par1 ) result = TopAbs_FORWARD;
141   else if ( par == parn ) result = TopAbs_REVERSED;
142   else result = TopAbs_INTERNAL;
143
144   TT.Set(result);
145   return TT;
146 }
147
148
149 //=======================================================================
150 //function : ProcessEdgeTransition
151 //purpose  : compute the transition from the transition of the intersection
152 //         : point <P> on the intersected shape of index <Index> (1 or 2)
153 //         : for an edge on a line on a Face
154 //=======================================================================
155
156 TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessEdgeTransition
157   (const TopOpeBRep_VPointInter &P,
158    const Standard_Integer Index,
159    const TopAbs_Orientation FaceTransition)
160 {
161   TopOpeBRepDS_Transition TT;
162
163   if ((FaceTransition == TopAbs_INTERNAL) || 
164       (FaceTransition == TopAbs_EXTERNAL)) {
165     TT.Set(FaceTransition);
166   }
167   else {
168     IntSurf_Transition T;
169     if      ( Index == 1 ) T = P.TransitionOnS1();
170     else if ( Index == 2 ) T = P.TransitionOnS2();
171     
172     TopAbs_Orientation O;
173     Standard_Boolean defined = ::TransitionToOrientation(T,O);
174     if (defined) {
175       if (FaceTransition == TopAbs_REVERSED) O = TopAbs::Complement(O);
176       TT.Set(O);
177     }
178     else {
179       TT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
180     }
181   }
182
183   return TT;
184 }
185
186
187 //=======================================================================
188 //function : ProcessFaceTransition
189 //purpose  : compute the transition from a Line
190 //=======================================================================
191
192 TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessFaceTransition
193   (const TopOpeBRep_LineInter& L,
194    const Standard_Integer Index,
195    const TopAbs_Orientation FaceOrientation)
196 {
197   // If Index == 1, on first shape
198   // If Index == 2, on second shape
199   TopOpeBRepDS_Transition TT;
200
201   if ((FaceOrientation == TopAbs_INTERNAL) || 
202       (FaceOrientation == TopAbs_EXTERNAL)) {
203     TT.Set(FaceOrientation);
204   }
205   else {
206     Standard_Boolean Odefined = Standard_True;
207
208     TopAbs_Orientation O = TopAbs_FORWARD;
209
210     IntSurf_TypeTrans trans;
211     trans = (Index == 1) ? L.TransitionOnS1() : L.TransitionOnS2();
212
213     switch (trans) {
214     
215     case IntSurf_In  : O = TopAbs_FORWARD; break;
216
217     case IntSurf_Out : O = TopAbs_REVERSED; break;
218       
219     case IntSurf_Touch : {     
220
221       IntSurf_Situation situa;
222       situa = (Index == 1 ) ? L.SituationS1() : L.SituationS2();
223
224       switch (situa) {  
225
226       case IntSurf_Inside  : O = TopAbs_INTERNAL; break;
227
228       case IntSurf_Outside : O = TopAbs_EXTERNAL; break;
229
230       case IntSurf_Unknown :
231
232         Odefined = Standard_False;
233         break;
234       }
235       break;
236       } // case Touch
237
238     case IntSurf_Undecided :
239       Odefined = Standard_False;
240       break;
241
242     } // trans
243   
244     if (Odefined) {
245       if (FaceOrientation == TopAbs_REVERSED) O = TopAbs::Complement(O);
246       TT.Set(O);
247     }
248     else {
249       TT.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
250     }
251   }
252
253   return TT;
254 }
255
256
257 // -------------------------------------------------
258 // input : P1 : point 
259 // input : C2 : courbe, FC2,LC2 : bornes de C2
260 // output : T2 = parametre de P1 sur C2
261 // -------------------------------------------------
262 static Standard_Boolean FUN_ProjectPoint(const gp_Pnt& P1,
263                                          const Handle(Geom_Curve)& C2,
264                                          const Standard_Real FC2, 
265                                          const Standard_Real LC2, 
266                                          Standard_Real& T2)
267 {
268   if ( C2.IsNull() ) {
269     return Standard_False;
270   }
271   Standard_Real res = Standard_False;
272   
273   GeomAPI_ProjectPointOnCurve mydist(P1,C2,FC2,LC2);
274   if ( mydist.Extrema().IsDone() ) {
275     if ( mydist.NbPoints() ) {
276       T2 = mydist.LowerDistanceParameter();
277       res = Standard_True;
278     }
279   }
280 //#ifdef OCCT_DEBUG
281 //  return res; // BUG ???
282 //#else
283   return (Standard_Boolean ) res ;
284 //#endif
285
286 }
287
288 // -------------------------------------------------
289 // input : S1,U1,V1,C1,T1 avec D0(S1(U1,V1)) = D0(C1(T1))
290 // input : C2,FC2,LC2 : courbe, bornes de C2
291 // output : Trans : transition sur C1 en T1 en croisant C2
292 // -------------------------------------------------
293 static Standard_Boolean FUN_GeomTrans(const Handle(Geom_Surface)& S1,
294                                       const Standard_Real U1,
295                                       const Standard_Real V1,
296                                       const Handle(Geom_Curve)& C1,
297                                       const Standard_Real T1,
298                                       const Handle(Geom_Curve)& C2,
299                                       const Standard_Real FC2,
300                                       const Standard_Real LC2,
301                                       TopOpeBRepDS_Transition& Trans)
302 {
303   if ( C1.IsNull() || C2.IsNull() ) {
304     return Standard_False;
305   }
306   
307   // P1 : D0(C1(T1), D1_C1 : D1(C1(T1))
308   gp_Pnt P1; gp_Vec D1_C1; C1->D1(T1,P1,D1_C1);
309   
310   // D1_C2 : D1(C2(P1))
311   Standard_Real T2 = 0.0; 
312   Standard_Boolean projok = ::FUN_ProjectPoint(P1,C2,FC2,LC2,T2);
313   if ( !projok ) {
314     return Standard_False;
315   }
316   gp_Pnt P2; gp_Vec D1_C2; C2->D1(T2,P2,D1_C2);
317   
318   // N1 : D1(S1(U1,V1))
319   gp_Vec N1,D1U,D1V; 
320   gp_Pnt PS;
321   S1->D1(U1,V1,PS,D1U,D1V);
322   D1U.Normalize();
323   D1V.Normalize();
324   N1 = D1U.Crossed(D1V);
325   N1.Normalize();
326   
327   gp_Vec N1D1_C1 = N1.Crossed(D1_C1);
328   Standard_Real dot = N1D1_C1.Dot(D1_C2);
329   if ( dot > 0 ) {
330     Trans.Before(TopAbs_OUT);
331     Trans.After(TopAbs_IN);
332   }
333   else {
334     Trans.Before(TopAbs_IN);
335     Trans.After(TopAbs_OUT);
336   }
337   
338   return Standard_True;
339 }
340  
341 //=======================================================================
342 //function : ProcessEdgeONTransition
343 //purpose  : 
344 //=======================================================================
345
346 TopOpeBRepDS_Transition TopOpeBRep_FFTransitionTool::ProcessEdgeONTransition
347 (const TopOpeBRep_VPointInter& VP,
348  const Standard_Integer ShapeIndex,
349  const TopoDS_Shape& RR,
350  const TopoDS_Shape& EE,
351  const TopoDS_Shape& FF)
352 {
353  const TopoDS_Edge& R = TopoDS::Edge(RR);
354  const TopoDS_Edge& E = TopoDS::Edge(EE);
355  const TopoDS_Face& F = TopoDS::Face(FF);
356
357  TopAbs_Orientation oriE = E.Orientation();
358  
359  const Handle(Geom_Surface)& S = BRep_Tool::Surface(F);
360  Standard_Real U = 0.,V = 0.;
361  if      (ShapeIndex == 1) VP.ParametersOnS1(U,V);
362  else if (ShapeIndex == 2) VP.ParametersOnS2(U,V);
363  
364  Standard_Real fE,lE;
365  const Handle(Geom_Curve)& CE = BRep_Tool::Curve(E,fE,lE);
366  Standard_Real TE = VP.EdgeParameter(ShapeIndex);
367  
368  Standard_Real fR,lR;
369  const Handle(Geom_Curve)& CR = BRep_Tool::Curve(R,fR,lR);
370  
371  TopOpeBRepDS_Transition Trans;
372  Standard_Boolean transok = ::FUN_GeomTrans(S,U,V,CE,TE,CR,fR,lR,Trans);
373  if ( transok ) {
374    // Trans : transition sur R en croisant l'arete E orientee dans la face F
375    if (oriE == TopAbs_REVERSED) Trans = Trans.Complement();
376  }
377  
378   return Trans;
379 }