1 // Created on: 1994-11-08
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TopOpeBRepDS_FaceInterferenceTool.ixx>
19 #include <Extrema_ExtPS.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve2d.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRepLProp_SLProps.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <Precision.hxx>
27 #include <gp_Sphere.hxx>
28 #include <Standard_ProgramError.hxx>
29 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
30 #include <TopOpeBRepTool_ShapeTool.hxx>
31 #include <TopOpeBRepTool_EXPORT.hxx>
32 #include <TopOpeBRepTool_TOOL.hxx>
33 #include <TopOpeBRepDS_define.hxx>
34 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
37 extern Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
38 extern Standard_Boolean TopOpeBRepDS_GettracePEI();
39 extern Standard_Boolean TopOpeBRepDS_GettracePFI();
40 extern Standard_Boolean TopOpeBRepDS_GettracePI();
41 extern Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer);
42 static Standard_Boolean FTRCF(const Standard_Integer F) {
43 Standard_Boolean b1 = TopOpeBRepDS_GettracePFI();
44 Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
45 Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(F);
46 return (b1 || b2 || b3);
48 //unreferenced function, commented
50 static Standard_Boolean FTRCE(const Standard_Integer E) {
51 Standard_Boolean b1 = TopOpeBRepDS_GettracePEI();
52 Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
53 Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(E);
54 return (b1 || b2 || b3);
56 extern void debredfac(const Standard_Integer I);
59 static Standard_Boolean STATIC_TOREVERSE = Standard_False; // xpu150498
60 #define M_FORWARD(ori) (ori == TopAbs_FORWARD)
61 #define M_REVERSED(ori) (ori == TopAbs_REVERSED)
63 //------------------------------------------------------
64 static void FUN_RaiseError(){Standard_ProgramError::Raise("TopOpeBRepDS_FaceInterferenceTool");}
66 //------------------------------------------------------
67 Standard_EXPORT Standard_Boolean FUN_Parameters
68 (const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
70 BRepAdaptor_Surface Surf(TopoDS::Face(F));
71 // Get 2d coord of the projection of <Pnt> on surface of <F>.
72 Standard_Real uvtol = Surf.Tolerance();
73 Standard_Real fu=Surf.FirstUParameter(),lu=Surf.LastUParameter();
74 Standard_Real fv=Surf.FirstVParameter(),lv=Surf.LastVParameter();
75 Extrema_ExtPS extps(Pnt,Surf,fu,lu,fv,lv,uvtol,uvtol);
76 if (!extps.IsDone()) {
77 return Standard_False;
79 if (extps.NbExt() == 0) {
80 return Standard_False;
82 extps.Point(1).Parameter(u,v);
84 // xpu281098 : CTS21216 (FIR, f4,e7on)
85 Standard_Real d2 = extps.SquareDistance(1);
86 Standard_Real tolF = BRep_Tool::Tolerance(TopoDS::Face(F));
87 Standard_Boolean ok = (d2 < tolF*tolF*1.e6); // NYINYI
91 //------------------------------------------------------
94 static Standard_Boolean FUN_Parameters
95 (const Standard_Real& Param,const TopoDS_Shape& E,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
97 // Get 2d coordinates of point of param <Param> on <E> of <F>.
98 BRepAdaptor_Curve2d curv2d(TopoDS::Edge(E),TopoDS::Face(F));
100 curv2d.D0(Param,p2d);
102 return Standard_True;
107 //------------------------------------------------------
108 Standard_EXPORT void FUN_ComputeGeomData
109 (const TopoDS_Shape& F,const gp_Pnt2d& uv,gp_Dir& Norm)
111 gp_Vec ngF = FUN_tool_nggeomF(uv,TopoDS::Face(F));
115 //------------------------------------------------------
116 static Standard_Boolean FUN_sphere(const TopoDS_Shape& F)
118 Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
119 GeomAdaptor_Surface GAS(su);
120 return (GAS.GetType() == GeomAbs_Sphere);
123 //------------------------------------------------------
124 //unreferenced function, commented
126 static void FUN_middleUV(const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
128 Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
129 GeomAdaptor_Surface GAS(su);
130 u = (GAS.LastUParameter() + GAS.FirstUParameter())*.5;
131 v = (GAS.LastVParameter() + GAS.FirstVParameter())*.5;
135 //------------------------------------------------------
136 Standard_EXPORT void FUN_ComputeGeomData
137 (const TopoDS_Shape& F,const gp_Pnt2d& uv,
138 gp_Dir& Norm,gp_Dir& D1,gp_Dir& D2,Standard_Real& Cur1,Standard_Real& Cur2)
140 BRepAdaptor_Surface surf(TopoDS::Face(F));
141 Standard_Real uu = uv.X(),vv = uv.Y();
143 Standard_Boolean sphere = FUN_sphere(F);
144 Standard_Boolean plane = FUN_tool_plane(F);
146 // Getting the principle directions,the normal and the curvatures
147 BRepLProp_SLProps props(surf,uu,vv,2,Precision::Confusion());
148 Standard_Boolean curdef = props.IsCurvatureDefined();
149 if (!curdef) Standard_ProgramError::Raise("TopOpeBRepDS_FaceInterferenceTool::Init");
150 Standard_Boolean umbilic = props.IsUmbilic();
152 Cur1 = Cur2 = props.MeanCurvature();
154 // xpu030998 : cto901A3
155 Standard_Real toll = 1.e-8;
156 Standard_Boolean ooplane = (Abs(Cur1)<toll) && (Abs(Cur2)<toll);
157 plane = plane || ooplane;
160 Norm = FUN_tool_nggeomF(uv, TopoDS::Face(F));
162 gp_Pnt center = surf.Sphere().Location();
163 gp_Pnt value = surf.Value(uu,vv);
164 Norm = gp_Dir(gp_Vec(center,value)); // recall : input data for TopTrans_SurfaceTransition
165 // describes "direct" geometry
168 Standard_Failure::Raise("FUN_ComputeGeomData");
170 D1 = Norm; Standard_Real x = D1.X(),y = D1.Y(),z = D1.Z(),tol = Precision::Confusion();
171 Standard_Boolean nullx = (Abs(x)<tol),nully = (Abs(y)<tol),nullz = (Abs(z)<tol);
172 if (nullx && nully) D2 = gp_Dir(1,0,0);
173 else if (nullx && nullz) D2 = gp_Dir(1,0,0);
174 else if (nully && nullz) D2 = gp_Dir(0,1,0);
175 else D2 = gp_Dir(y*z,x*z,-2.*x*y);
178 Cur1 = props.MaxCurvature();
179 Cur2 = props.MinCurvature();
180 props.CurvatureDirections(D1,D2);
181 Norm = FUN_tool_nggeomF(uv,TopoDS::Face(F));
185 //=======================================================================
186 //function : TopOpeBRepDS_FaceInterferenceTool
188 //=======================================================================
189 TopOpeBRepDS_FaceInterferenceTool::TopOpeBRepDS_FaceInterferenceTool
190 (const TopOpeBRepDS_PDataStructure& PBDS)
191 : myPBDS(PBDS),myrefdef(Standard_False),myOnEdDef(Standard_False)
195 //=======================================================================
197 //purpose : Initializes reference data for face/curve complex transition
198 //=======================================================================
199 void TopOpeBRepDS_FaceInterferenceTool::Init
200 (const TopoDS_Shape& FFI,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin)
202 const Handle(TopOpeBRepDS_ShapeShapeInterference)& I = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin); if (I.IsNull()) return;
203 const TopoDS_Face& FI = TopoDS::Face(FFI);
204 const TopoDS_Edge& E = TopoDS::Edge(EE);
206 // Standard_Integer iFI = myPBDS->Shape(FI);
207 // Standard_Boolean TRCFI = FTRCF(iFI);if (TRCFI) debredfac(iFI);
211 STATIC_TOREVERSE = Standard_False;
213 Standard_Integer G = I->Geometry(); const TopoDS_Edge& EG = TopoDS::Edge(myPBDS->Shape(G));
214 TopOpeBRepDS_Config cf; Standard_Boolean cfok = FDS_Config3d(E,EG,cf);
215 if (!cfok) { FUN_RaiseError(); return; }
216 if (cf == TopOpeBRepDS_DIFFORIENTED) STATIC_TOREVERSE = Standard_True;
219 myFaceOrientation = FI.Orientation();
220 myFaceOriented = I->Support();
223 // Get a middle point on <E>
224 // Geometric data is described locally around this point.
225 // initialize : isLine,myParOnEd,myPntOnEd,myTole,Tgt.
227 TopAbs_Orientation oEinFI; Standard_Boolean edonfa = FUN_tool_orientEinFFORWARD(E,FI,oEinFI);
228 // isLine = FUN_tool_line(E);
229 isLine = Standard_False;
232 Standard_Boolean ok = FUN_tool_findPinE(E,myPntOnEd,myParOnEd);
233 if (!ok) { FUN_RaiseError(); return;}
236 myTole = Precision::Angular();
237 gp_Pnt2d uv; Standard_Boolean ok = Standard_False; Standard_Real d = 0.;
238 if (edonfa) ok = FUN_tool_paronEF(E,myParOnEd,FI,uv);
239 else ok = FUN_tool_projPonF(myPntOnEd,FI,uv,d);
240 if (!ok) { FUN_RaiseError(); return;}
242 gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(myParOnEd,E,tmp);
243 if (!ok) { FUN_RaiseError(); return;}
247 FUN_ComputeGeomData(FI,uv,Norm);
248 myTool.Reset(Tgt,Norm);
252 Standard_Real Cur1,Cur2;
253 FUN_ComputeGeomData(FI,uv,Norm,D1,D2,Cur1,Cur2);
254 myTool.Reset(Tgt,Norm,D1,D2,Cur1,Cur2);
256 myrefdef = Standard_True;
259 //=======================================================================
262 //=======================================================================
263 void TopOpeBRepDS_FaceInterferenceTool::Add
264 (const TopoDS_Shape& FFI,const TopoDS_Shape& FFT,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin)
266 const Handle(TopOpeBRepDS_ShapeShapeInterference)& I = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin); if (I.IsNull()) return;
267 const TopoDS_Face& FI = TopoDS::Face(FFI);
268 const TopoDS_Face& FT = TopoDS::Face(FFT);
269 const TopoDS_Edge& E = TopoDS::Edge(EE);
271 Standard_Integer iFI =
274 // myPBDS->Shape(FT);
277 Standard_Boolean TRCFI = FTRCF(iFI);if (TRCFI) debredfac(iFI);
280 if (!E.IsSame(myEdge)) {FUN_RaiseError();return;}
283 Init(FI,E,EEisnew,I); // premiere interference sur face orientee : Init
288 // TopAbs_Orientation FTori = FT.Orientation();
290 TopOpeBRepDS_Kind GT,ST; Standard_Integer G,S; FDS_data(I,GT,G,ST,S);
292 // Standard_Boolean gisb = I->GBound();
294 const TopoDS_Edge& EG = TopoDS::Edge(myPBDS->Shape(G));
296 // Standard_Boolean ghassd3d =
298 FDS_HasSameDomain3d(*myPBDS,EG);
300 // Standard_Integer gr = myPBDS->SameDomainRef(G);
301 // const TopoDS_Edge& ER = TopoDS::Edge(myPBDS->Shape(gr));
302 // Standard_Integer gisr = (G == gr);
304 Standard_Boolean same = !STATIC_TOREVERSE; // xpu150498
306 TopAbs_Orientation oriloc = I->Transition().Orientation(TopAbs_IN);
307 // xpu150498 : CTS20205 : sp(e5) = sp(e4 of rank=1) and c3d(e5) c3d(e4) are diff oriented
308 // As transitions on face<iFI> are given relative to the geometry of e5,
309 // we have to complement them.
311 Standard_Boolean rev = !same && (M_FORWARD(oriloc) || M_REVERSED(oriloc)); //xpu150498
312 if (rev) oriloc = TopAbs::Complement(oriloc); //xpu150498
314 TopAbs_Orientation oritan;
315 TopAbs_Orientation oriEFT; Standard_Boolean egofft = FUN_tool_orientEinFFORWARD(EG,FT,oriEFT);
316 TopAbs_Orientation oriEFI; Standard_Boolean egoffi = FUN_tool_orientEinFFORWARD(EG,FI,oriEFI);
319 if (EEisnew && !same) oritan = TopAbs::Complement(oriEFT);
323 if (EEisnew && !same) oritan = TopAbs::Complement(oriEFI);
325 else { FUN_RaiseError(); return; }
327 gp_Pnt2d uv; Standard_Boolean ok = Standard_False;
328 if (egofft) ok = FUN_tool_paronEF(E,myParOnEd,FT,uv);
329 if (!ok) {Standard_Real d; ok = FUN_tool_projPonF(myPntOnEd,FT,uv,d);}
330 if (!ok) { FUN_RaiseError(); return;}
334 FUN_ComputeGeomData(FT,uv,Norm);
335 // if (Fori == TopAbs_REVERSED) Norm.Reverse();
336 myTool.Compare(myTole,Norm,oriloc,oritan);
339 gp_Dir D1,D2; Standard_Real Cur1,Cur2;
340 FUN_ComputeGeomData(FT,uv,Norm,D1,D2,Cur1,Cur2);
341 // if (Fori == TopAbs_REVERSED) Norm.Reverse();
342 myTool.Compare(myTole,Norm,D1,D2,Cur1,Cur2,oriloc,oritan);
346 //=======================================================================
349 //=======================================================================
350 void TopOpeBRepDS_FaceInterferenceTool::Add
351 //(const TopoDS_Shape& F,const TopOpeBRepDS_Curve& C,const Handle(TopOpeBRepDS_Interference)& I)
352 (const TopoDS_Shape& ,const TopOpeBRepDS_Curve& ,const Handle(TopOpeBRepDS_Interference)& )
357 //=======================================================================
358 //function : Transition
360 //=======================================================================
361 void TopOpeBRepDS_FaceInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const
363 TopOpeBRepDS_Transition& T = I->ChangeTransition();
365 if (myFaceOrientation == TopAbs_INTERNAL) {
366 T.Set(TopAbs_IN,TopAbs_IN);
368 else if (myFaceOrientation == TopAbs_EXTERNAL) {
369 T.Set(TopAbs_OUT,TopAbs_OUT);
372 I->Support(myFaceOriented);
373 TopAbs_State stb = myTool.StateBefore();
374 TopAbs_State sta = myTool.StateAfter();
377 TopAbs_Orientation o = T.Orientation(TopAbs_IN);
378 Standard_Boolean rev = STATIC_TOREVERSE && (M_FORWARD(o) || M_REVERSED(o));
379 if (rev) o = TopAbs::Complement(o);
385 //=======================================================================
386 //function : SetEdgePntPar
388 //=======================================================================
389 void TopOpeBRepDS_FaceInterferenceTool::SetEdgePntPar(const gp_Pnt& P,const Standard_Real p)
393 myOnEdDef = Standard_True;
396 //=======================================================================
397 //function : GetEdgePnt
399 //=======================================================================
400 void TopOpeBRepDS_FaceInterferenceTool::GetEdgePntPar(gp_Pnt& P,Standard_Real& p) const
402 if (!myOnEdDef) Standard_ProgramError::Raise("GetEdgePntPar");
407 //=======================================================================
408 //function : IsEdgePnt
410 //=======================================================================
412 Standard_Boolean TopOpeBRepDS_FaceInterferenceTool::IsEdgePntParDef() const