00e0b60b5744c150bba7fc5490dc140488db1808
[occt.git] / TopOpeBRepDS_FaceInterferenceTool.cxx
1 // File:        TopOpeBRepDS_FaceInterferenceTool.cxx
2 // Created:     Tue Nov  8 14:52:21 1994
3 // Author:      Jean Yves LEBEY
4 //              <jyl@bravox>
5
6 #include <TopOpeBRepDS_FaceInterferenceTool.ixx>
7
8 #include <Extrema_ExtPS.hxx>
9 #include <BRep_Tool.hxx>
10 #include <BRepAdaptor_Curve2d.hxx>
11 #include <BRepAdaptor_Surface.hxx>
12 #include <BRepLProp_SLProps.hxx>
13 #include <TopoDS.hxx>
14 #include <TopExp_Explorer.hxx>
15 #include <Precision.hxx>
16 #include <gp_Sphere.hxx>
17 #include <Standard_ProgramError.hxx>
18 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
19 #include <TopOpeBRepTool_ShapeTool.hxx>
20 #include <TopOpeBRepTool_EXPORT.hxx>
21 #include <TopOpeBRepTool_TOOL.hxx>
22 #include <TopOpeBRepDS_define.hxx>
23
24 #ifdef DEB
25 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
26 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettracePEI();
27 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettracePFI();
28 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettracePI();
29 Standard_IMPORT Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer);
30 static Standard_Boolean FTRCF(const Standard_Integer F) {
31   Standard_Boolean b1 = TopOpeBRepDS_GettracePFI();
32   Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
33   Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(F);
34   return (b1 || b2 || b3);
35 }
36 //unreferenced function, commented 
37 /*
38 static Standard_Boolean FTRCE(const Standard_Integer E) {
39   Standard_Boolean b1 = TopOpeBRepDS_GettracePEI();
40   Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
41   Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(E);
42   return (b1 || b2 || b3);
43 }*/
44 Standard_IMPORT void debredfac(const Standard_Integer I);
45 #endif
46
47 static Standard_Boolean STATIC_TOREVERSE = Standard_False; // xpu150498
48 #define M_FORWARD(ori) (ori == TopAbs_FORWARD)
49 #define M_REVERSED(ori) (ori == TopAbs_REVERSED)
50
51 //------------------------------------------------------
52 static void FUN_RaiseError(){Standard_ProgramError::Raise("TopOpeBRepDS_FaceInterferenceTool");}
53
54 //------------------------------------------------------
55 Standard_EXPORT Standard_Boolean FUN_Parameters
56 (const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
57 {
58   BRepAdaptor_Surface Surf(TopoDS::Face(F));
59   // Get 2d coord of the projection of <Pnt> on surface of <F>.
60   Standard_Real uvtol = Surf.Tolerance();
61   Standard_Real fu=Surf.FirstUParameter(),lu=Surf.LastUParameter();
62   Standard_Real fv=Surf.FirstVParameter(),lv=Surf.LastVParameter();
63   Extrema_ExtPS extps(Pnt,Surf,fu,lu,fv,lv,uvtol,uvtol);
64   if (!extps.IsDone()) {
65     return Standard_False;
66   }
67   if (extps.NbExt() == 0) {
68     return Standard_False;
69   }
70   extps.Point(1).Parameter(u,v);
71
72   // xpu281098 : CTS21216 (FIR, f4,e7on)
73   Standard_Real d2 = extps.SquareDistance(1);
74   Standard_Real tolF = BRep_Tool::Tolerance(TopoDS::Face(F));
75   Standard_Boolean ok = (d2 < tolF*tolF*1.e6); // NYINYI
76   return ok;
77 }
78
79 //------------------------------------------------------
80 // Unused :
81 /*#ifdef DEB
82 static Standard_Boolean FUN_Parameters
83 (const Standard_Real& Param,const TopoDS_Shape& E,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
84 {
85   // Get 2d coordinates of point of param <Param> on <E> of <F>.
86   BRepAdaptor_Curve2d curv2d(TopoDS::Edge(E),TopoDS::Face(F));
87   gp_Pnt2d p2d;
88   curv2d.D0(Param,p2d);
89   p2d.Coord(u,v);
90   return Standard_True;
91 }
92 #endif
93 */
94
95 //------------------------------------------------------
96 Standard_EXPORT void FUN_ComputeGeomData
97 (const TopoDS_Shape& F,const gp_Pnt2d& uv,gp_Dir& Norm)
98
99   gp_Vec ngF = FUN_tool_nggeomF(uv,TopoDS::Face(F));
100   Norm = gp_Dir(ngF);
101 }
102
103 //------------------------------------------------------
104 static Standard_Boolean FUN_sphere(const TopoDS_Shape& F)
105 {
106   Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
107   GeomAdaptor_Surface GAS(su);  
108   return (GAS.GetType() == GeomAbs_Sphere);
109 }
110
111 //------------------------------------------------------
112 //unreferenced function, commented 
113 /*#ifdef DEB
114 static void FUN_middleUV(const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
115 {
116   Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
117   GeomAdaptor_Surface GAS(su);
118   u = (GAS.LastUParameter() + GAS.FirstUParameter())*.5;
119   v = (GAS.LastVParameter() + GAS.FirstVParameter())*.5;
120 }
121 #endif*/
122
123 //------------------------------------------------------
124 Standard_EXPORT void FUN_ComputeGeomData
125 (const TopoDS_Shape& F,const gp_Pnt2d& uv,
126  gp_Dir& Norm,gp_Dir& D1,gp_Dir& D2,Standard_Real& Cur1,Standard_Real& Cur2)
127 {    
128   BRepAdaptor_Surface surf(TopoDS::Face(F));
129   Standard_Real uu = uv.X(),vv = uv.Y();
130   
131   Standard_Boolean sphere = FUN_sphere(F);
132   Standard_Boolean plane = FUN_tool_plane(F);
133   
134   // Getting the principle directions,the normal and the curvatures
135   BRepLProp_SLProps props(surf,uu,vv,2,Precision::Confusion());
136   Standard_Boolean curdef = props.IsCurvatureDefined();
137   if (!curdef) Standard_ProgramError::Raise("TopOpeBRepDS_FaceInterferenceTool::Init");
138   Standard_Boolean umbilic = props.IsUmbilic();
139   if (umbilic) { 
140     Cur1 = Cur2 = props.MeanCurvature(); 
141
142     // xpu030998 : cto901A3
143     Standard_Real toll = 1.e-8;
144     Standard_Boolean ooplane = (Abs(Cur1)<toll) && (Abs(Cur2)<toll);
145     plane = plane || ooplane;
146
147     if      (plane) 
148       Norm = FUN_tool_nggeomF(uv, TopoDS::Face(F));
149     else if (sphere) {
150       gp_Pnt center = surf.Sphere().Location();
151       gp_Pnt value  = surf.Value(uu,vv);  
152       Norm = gp_Dir(gp_Vec(center,value)); // recall : input data for TopTrans_SurfaceTransition
153                                            //          describes "direct" geometry 
154     }
155     else                
156       Standard_Failure::Raise("FUN_ComputeGeomData");
157     
158     D1 = Norm; Standard_Real x = D1.X(),y = D1.Y(),z = D1.Z(),tol = Precision::Confusion(); 
159     Standard_Boolean nullx = (Abs(x)<tol),nully = (Abs(y)<tol),nullz = (Abs(z)<tol);
160     if      (nullx && nully) D2 = gp_Dir(1,0,0);
161     else if (nullx && nullz) D2 = gp_Dir(1,0,0);
162     else if (nully && nullz) D2 = gp_Dir(0,1,0);
163     else                     D2 = gp_Dir(y*z,x*z,-2.*x*y);
164   }
165   else {
166     Cur1 = props.MaxCurvature();
167     Cur2 = props.MinCurvature();
168     props.CurvatureDirections(D1,D2);        
169     Norm = FUN_tool_nggeomF(uv,TopoDS::Face(F));
170   }
171 }
172
173 //=======================================================================
174 //function : TopOpeBRepDS_FaceInterferenceTool
175 //purpose  : 
176 //=======================================================================
177 TopOpeBRepDS_FaceInterferenceTool::TopOpeBRepDS_FaceInterferenceTool
178 (const TopOpeBRepDS_PDataStructure& PBDS)
179 : myPBDS(PBDS),myrefdef(Standard_False),myOnEdDef(Standard_False)
180 {
181 }
182
183 //=======================================================================
184 //function : Init
185 //purpose  : Initializes reference data for face/curve complex transition           
186 //=======================================================================
187 void TopOpeBRepDS_FaceInterferenceTool::Init
188 (const TopoDS_Shape& FFI,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin)
189 {
190   const Handle(TopOpeBRepDS_ShapeShapeInterference)& I = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin); if (I.IsNull()) return;  
191   const TopoDS_Face& FI = TopoDS::Face(FFI);
192   const TopoDS_Edge& E = TopoDS::Edge(EE);
193 #ifdef DEB
194 //  Standard_Integer iFI = myPBDS->Shape(FI);
195   //  Standard_Boolean TRCFI = FTRCF(iFI);if (TRCFI) debredfac(iFI);
196 #endif
197   
198   //   xpu150498
199   STATIC_TOREVERSE = Standard_False;
200   if (EEisnew) {
201     Standard_Integer G = I->Geometry(); const TopoDS_Edge& EG = TopoDS::Edge(myPBDS->Shape(G));    
202     TopOpeBRepDS_Config cf; Standard_Boolean cfok = FDS_Config3d(E,EG,cf);
203     if (!cfok) { FUN_RaiseError(); return; }
204     if (cf == TopOpeBRepDS_DIFFORIENTED) STATIC_TOREVERSE = Standard_True;
205   } // xpu150498
206
207   myFaceOrientation = FI.Orientation();
208   myFaceOriented    = I->Support();
209   
210   myEdge = E;
211   // Get a middle point on <E>
212   // Geometric data is described locally around this point.
213   // initialize : isLine,myParOnEd,myPntOnEd,myTole,Tgt.
214   
215   TopAbs_Orientation oEinFI; Standard_Boolean edonfa = FUN_tool_orientEinFFORWARD(E,FI,oEinFI);
216 //  isLine = FUN_tool_line(E);
217   isLine = Standard_False;
218   
219   if (!myOnEdDef) {
220     Standard_Boolean ok = FUN_tool_findPinE(E,myPntOnEd,myParOnEd);
221     if (!ok) { FUN_RaiseError(); return;}
222   }
223   
224   myTole = Precision::Angular();
225   gp_Pnt2d uv; Standard_Boolean ok = Standard_False; Standard_Real d = 0.;
226   if (edonfa) ok = FUN_tool_paronEF(E,myParOnEd,FI,uv);
227   else        ok = FUN_tool_projPonF(myPntOnEd,FI,uv,d);
228   if (!ok) { FUN_RaiseError(); return;}
229   
230   gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(myParOnEd,E,tmp);
231   if (!ok) { FUN_RaiseError(); return;}
232   gp_Dir Tgt(tmp);
233   gp_Dir Norm;
234   if(isLine) {
235     FUN_ComputeGeomData(FI,uv,Norm); 
236     myTool.Reset(Tgt,Norm);
237   }
238   else { 
239     gp_Dir D1,D2;
240     Standard_Real Cur1,Cur2;
241     FUN_ComputeGeomData(FI,uv,Norm,D1,D2,Cur1,Cur2);
242     myTool.Reset(Tgt,Norm,D1,D2,Cur1,Cur2); 
243   }
244   myrefdef = Standard_True;
245 }
246
247 //=======================================================================
248 //function : Add
249 //purpose  : 
250 //=======================================================================
251 void TopOpeBRepDS_FaceInterferenceTool::Add
252 (const TopoDS_Shape& FFI,const TopoDS_Shape& FFT,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin)
253 {
254   const Handle(TopOpeBRepDS_ShapeShapeInterference)& I = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin); if (I.IsNull()) return;  
255   const TopoDS_Face& FI = TopoDS::Face(FFI);
256   const TopoDS_Face& FT = TopoDS::Face(FFT);
257   const TopoDS_Edge& E = TopoDS::Edge(EE);
258 #ifdef DEB
259   Standard_Integer iFI =
260 #endif
261             myPBDS->Shape(FI);
262 //    myPBDS->Shape(FT);
263
264 #ifdef DEB
265   Standard_Boolean TRCFI = FTRCF(iFI);if (TRCFI) debredfac(iFI);
266 #endif
267
268   if (!E.IsSame(myEdge)) {FUN_RaiseError();return;}
269
270   if (!myrefdef) { 
271     Init(FI,E,EEisnew,I); // premiere interference sur face orientee : Init
272     return;
273   }
274
275 #ifdef DEB
276 //  TopAbs_Orientation FTori = FT.Orientation();
277 #endif
278   TopOpeBRepDS_Kind GT,ST; Standard_Integer G,S; FDS_data(I,GT,G,ST,S);
279 #ifdef DEB
280 //  Standard_Boolean gisb = I->GBound(); 
281 #endif
282   const TopoDS_Edge& EG = TopoDS::Edge(myPBDS->Shape(G));
283 #ifdef DEB
284 //  Standard_Boolean ghassd3d =
285 #endif
286                  FDS_HasSameDomain3d(*myPBDS,EG);
287 #ifdef DEB
288 //  Standard_Integer gr = myPBDS->SameDomainRef(G);
289 //  const TopoDS_Edge& ER = TopoDS::Edge(myPBDS->Shape(gr));
290 //  Standard_Integer gisr = (G == gr);
291 #endif
292   Standard_Boolean same = !STATIC_TOREVERSE; // xpu150498
293   
294   TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN);
295   // xpu150498 : CTS20205 : sp(e5) = sp(e4 of rank=1) and c3d(e5) c3d(e4) are diff oriented
296   //            As transitions on face<iFI> are given relative to the geometry of e5,
297   //            we have to complement them.
298   //             cto 016 E1
299   Standard_Boolean rev = !same && (M_FORWARD(oriloc) || M_REVERSED(oriloc)); //xpu150498 
300   if (rev) oriloc = TopAbs::Complement(oriloc); //xpu150498 
301
302   TopAbs_Orientation oritan;
303   TopAbs_Orientation oriEFT; Standard_Boolean egofft = FUN_tool_orientEinFFORWARD(EG,FT,oriEFT);
304   TopAbs_Orientation oriEFI; Standard_Boolean egoffi = FUN_tool_orientEinFFORWARD(EG,FI,oriEFI);
305   if      (egofft) {
306     oritan = oriEFT;    
307     if (EEisnew && !same) oritan = TopAbs::Complement(oriEFT);
308   }
309   else if (egoffi) {
310     oritan = oriEFI;    
311     if (EEisnew && !same) oritan = TopAbs::Complement(oriEFI);
312   }
313   else { FUN_RaiseError(); return; }
314
315   gp_Pnt2d uv; Standard_Boolean ok = Standard_False;
316   if (egofft) ok = FUN_tool_paronEF(E,myParOnEd,FT,uv);
317   if (!ok) {Standard_Real d; ok = FUN_tool_projPonF(myPntOnEd,FT,uv,d);}
318   if (!ok) { FUN_RaiseError(); return;}
319
320   gp_Dir Norm;
321   if(isLine) {
322     FUN_ComputeGeomData(FT,uv,Norm);
323 //    if (Fori == TopAbs_REVERSED) Norm.Reverse();
324     myTool.Compare(myTole,Norm,oriloc,oritan);
325   }
326   else {
327     gp_Dir D1,D2; Standard_Real Cur1,Cur2;
328     FUN_ComputeGeomData(FT,uv,Norm,D1,D2,Cur1,Cur2);
329 //    if (Fori == TopAbs_REVERSED) Norm.Reverse();
330     myTool.Compare(myTole,Norm,D1,D2,Cur1,Cur2,oriloc,oritan); 
331   }  
332 }
333
334 //=======================================================================
335 //function : Add
336 //purpose  :
337 //=======================================================================
338 void TopOpeBRepDS_FaceInterferenceTool::Add
339 //(const TopoDS_Shape& F,const TopOpeBRepDS_Curve& C,const Handle(TopOpeBRepDS_Interference)& I)
340 (const TopoDS_Shape& ,const TopOpeBRepDS_Curve& ,const Handle(TopOpeBRepDS_Interference)& )
341 {
342   // NYI
343 }
344
345 //=======================================================================
346 //function : Transition
347 //purpose  : 
348 //=======================================================================
349 void TopOpeBRepDS_FaceInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const 
350 {
351   TopOpeBRepDS_Transition& T = I->ChangeTransition();
352
353   if (myFaceOrientation == TopAbs_INTERNAL) {
354     T.Set(TopAbs_IN,TopAbs_IN);
355   }
356   else if (myFaceOrientation == TopAbs_EXTERNAL) {
357     T.Set(TopAbs_OUT,TopAbs_OUT);
358   }
359   else {
360     I->Support(myFaceOriented);
361     TopAbs_State stb = myTool.StateBefore();
362     TopAbs_State sta = myTool.StateAfter();
363     T.Set(stb,sta);
364     //xpu150498 
365     TopAbs_Orientation o = T.Orientation(TopAbs_IN);
366     Standard_Boolean rev = STATIC_TOREVERSE && (M_FORWARD(o) || M_REVERSED(o));
367     if (rev) o = TopAbs::Complement(o);
368     T.Set(o);
369     //xpu150498 
370   }
371 }
372
373 //=======================================================================
374 //function : SetEdgePntPar
375 //purpose  : 
376 //=======================================================================
377 void TopOpeBRepDS_FaceInterferenceTool::SetEdgePntPar(const gp_Pnt& P,const Standard_Real p)
378 {
379   myPntOnEd = P;
380   myParOnEd = p;
381   myOnEdDef = Standard_True;
382 }
383
384 //=======================================================================
385 //function : GetEdgePnt
386 //purpose  : 
387 //=======================================================================
388 void TopOpeBRepDS_FaceInterferenceTool::GetEdgePntPar(gp_Pnt& P,Standard_Real& p) const
389 {
390   if (!myOnEdDef) Standard_ProgramError::Raise("GetEdgePntPar");
391   P = myPntOnEd;
392   p = myParOnEd;
393 }
394
395 //=======================================================================
396 //function : IsEdgePnt
397 //purpose  : 
398 //=======================================================================
399
400 Standard_Boolean TopOpeBRepDS_FaceInterferenceTool::IsEdgePntParDef() const
401 {
402   return myOnEdDef;
403 }