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