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