0024947: Redesign OCCT legacy type system -- automatic
[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
17#include <TopOpeBRepDS_FaceInterferenceTool.ixx>
18
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>
24#include <TopoDS.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>
ec357c5c 34#include <TopOpeBRepDS_ShapeShapeInterference.hxx>
7fd59977 35
0797d9d3 36#ifdef OCCT_DEBUG
1d0a9d4d 37extern Standard_Boolean TopOpeBRepDS_GettraceSTRANGE();
38extern Standard_Boolean TopOpeBRepDS_GettracePEI();
39extern Standard_Boolean TopOpeBRepDS_GettracePFI();
40extern Standard_Boolean TopOpeBRepDS_GettracePI();
41extern Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer);
7fd59977 42static 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);
47}
48//unreferenced function, commented
49/*
50static 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);
55}*/
1d0a9d4d 56extern void debredfac(const Standard_Integer I);
7fd59977 57#endif
58
59static Standard_Boolean STATIC_TOREVERSE = Standard_False; // xpu150498
60#define M_FORWARD(ori) (ori == TopAbs_FORWARD)
61#define M_REVERSED(ori) (ori == TopAbs_REVERSED)
62
63//------------------------------------------------------
64static void FUN_RaiseError(){Standard_ProgramError::Raise("TopOpeBRepDS_FaceInterferenceTool");}
65
66//------------------------------------------------------
67Standard_EXPORT Standard_Boolean FUN_Parameters
68(const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
69{
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;
78 }
79 if (extps.NbExt() == 0) {
80 return Standard_False;
81 }
82 extps.Point(1).Parameter(u,v);
83
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
88 return ok;
89}
90
91//------------------------------------------------------
92// Unused :
0797d9d3 93/*#ifdef OCCT_DEBUG
7fd59977 94static Standard_Boolean FUN_Parameters
95(const Standard_Real& Param,const TopoDS_Shape& E,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
96{
97 // Get 2d coordinates of point of param <Param> on <E> of <F>.
98 BRepAdaptor_Curve2d curv2d(TopoDS::Edge(E),TopoDS::Face(F));
99 gp_Pnt2d p2d;
100 curv2d.D0(Param,p2d);
101 p2d.Coord(u,v);
102 return Standard_True;
103}
104#endif
105*/
106
107//------------------------------------------------------
108Standard_EXPORT void FUN_ComputeGeomData
109(const TopoDS_Shape& F,const gp_Pnt2d& uv,gp_Dir& Norm)
110{
111 gp_Vec ngF = FUN_tool_nggeomF(uv,TopoDS::Face(F));
112 Norm = gp_Dir(ngF);
113}
114
115//------------------------------------------------------
116static Standard_Boolean FUN_sphere(const TopoDS_Shape& F)
117{
118 Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
119 GeomAdaptor_Surface GAS(su);
120 return (GAS.GetType() == GeomAbs_Sphere);
121}
122
123//------------------------------------------------------
124//unreferenced function, commented
0797d9d3 125/*#ifdef OCCT_DEBUG
7fd59977 126static void FUN_middleUV(const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v)
127{
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;
132}
133#endif*/
134
135//------------------------------------------------------
136Standard_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)
139{
140 BRepAdaptor_Surface surf(TopoDS::Face(F));
141 Standard_Real uu = uv.X(),vv = uv.Y();
142
143 Standard_Boolean sphere = FUN_sphere(F);
144 Standard_Boolean plane = FUN_tool_plane(F);
145
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();
151 if (umbilic) {
152 Cur1 = Cur2 = props.MeanCurvature();
153
154 // xpu030998 : cto901A3
155 Standard_Real toll = 1.e-8;
156 Standard_Boolean ooplane = (Abs(Cur1)<toll) && (Abs(Cur2)<toll);
157 plane = plane || ooplane;
158
159 if (plane)
160 Norm = FUN_tool_nggeomF(uv, TopoDS::Face(F));
161 else if (sphere) {
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
166 }
167 else
168 Standard_Failure::Raise("FUN_ComputeGeomData");
169
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);
176 }
177 else {
178 Cur1 = props.MaxCurvature();
179 Cur2 = props.MinCurvature();
180 props.CurvatureDirections(D1,D2);
181 Norm = FUN_tool_nggeomF(uv,TopoDS::Face(F));
182 }
183}
184
185//=======================================================================
186//function : TopOpeBRepDS_FaceInterferenceTool
187//purpose :
188//=======================================================================
189TopOpeBRepDS_FaceInterferenceTool::TopOpeBRepDS_FaceInterferenceTool
190(const TopOpeBRepDS_PDataStructure& PBDS)
191: myPBDS(PBDS),myrefdef(Standard_False),myOnEdDef(Standard_False)
192{
193}
194
195//=======================================================================
196//function : Init
197//purpose : Initializes reference data for face/curve complex transition
198//=======================================================================
199void TopOpeBRepDS_FaceInterferenceTool::Init
200(const TopoDS_Shape& FFI,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin)
201{
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);
0797d9d3 205#ifdef OCCT_DEBUG
7fd59977 206// Standard_Integer iFI = myPBDS->Shape(FI);
207 // Standard_Boolean TRCFI = FTRCF(iFI);if (TRCFI) debredfac(iFI);
208#endif
209
210 // xpu150498
211 STATIC_TOREVERSE = Standard_False;
212 if (EEisnew) {
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;
217 } // xpu150498
218
219 myFaceOrientation = FI.Orientation();
220 myFaceOriented = I->Support();
221
222 myEdge = E;
223 // Get a middle point on <E>
224 // Geometric data is described locally around this point.
225 // initialize : isLine,myParOnEd,myPntOnEd,myTole,Tgt.
226
227 TopAbs_Orientation oEinFI; Standard_Boolean edonfa = FUN_tool_orientEinFFORWARD(E,FI,oEinFI);
228// isLine = FUN_tool_line(E);
229 isLine = Standard_False;
230
231 if (!myOnEdDef) {
232 Standard_Boolean ok = FUN_tool_findPinE(E,myPntOnEd,myParOnEd);
233 if (!ok) { FUN_RaiseError(); return;}
234 }
235
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;}
241
242 gp_Vec tmp; ok = TopOpeBRepTool_TOOL::TggeomE(myParOnEd,E,tmp);
243 if (!ok) { FUN_RaiseError(); return;}
244 gp_Dir Tgt(tmp);
245 gp_Dir Norm;
246 if(isLine) {
247 FUN_ComputeGeomData(FI,uv,Norm);
248 myTool.Reset(Tgt,Norm);
249 }
250 else {
251 gp_Dir D1,D2;
252 Standard_Real Cur1,Cur2;
253 FUN_ComputeGeomData(FI,uv,Norm,D1,D2,Cur1,Cur2);
254 myTool.Reset(Tgt,Norm,D1,D2,Cur1,Cur2);
255 }
256 myrefdef = Standard_True;
257}
258
259//=======================================================================
260//function : Add
261//purpose :
262//=======================================================================
263void 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)
265{
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);
0797d9d3 270#ifdef OCCT_DEBUG
7fd59977 271 Standard_Integer iFI =
272#endif
273 myPBDS->Shape(FI);
274// myPBDS->Shape(FT);
275
0797d9d3 276#ifdef OCCT_DEBUG
7fd59977 277 Standard_Boolean TRCFI = FTRCF(iFI);if (TRCFI) debredfac(iFI);
278#endif
279
280 if (!E.IsSame(myEdge)) {FUN_RaiseError();return;}
281
282 if (!myrefdef) {
283 Init(FI,E,EEisnew,I); // premiere interference sur face orientee : Init
284 return;
285 }
286
0797d9d3 287#ifdef OCCT_DEBUG
7fd59977 288// TopAbs_Orientation FTori = FT.Orientation();
289#endif
290 TopOpeBRepDS_Kind GT,ST; Standard_Integer G,S; FDS_data(I,GT,G,ST,S);
0797d9d3 291#ifdef OCCT_DEBUG
7fd59977 292// Standard_Boolean gisb = I->GBound();
293#endif
294 const TopoDS_Edge& EG = TopoDS::Edge(myPBDS->Shape(G));
0797d9d3 295#ifdef OCCT_DEBUG
7fd59977 296// Standard_Boolean ghassd3d =
297#endif
298 FDS_HasSameDomain3d(*myPBDS,EG);
0797d9d3 299#ifdef OCCT_DEBUG
7fd59977 300// Standard_Integer gr = myPBDS->SameDomainRef(G);
301// const TopoDS_Edge& ER = TopoDS::Edge(myPBDS->Shape(gr));
302// Standard_Integer gisr = (G == gr);
303#endif
304 Standard_Boolean same = !STATIC_TOREVERSE; // xpu150498
305
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.
310 // cto 016 E1
311 Standard_Boolean rev = !same && (M_FORWARD(oriloc) || M_REVERSED(oriloc)); //xpu150498
312 if (rev) oriloc = TopAbs::Complement(oriloc); //xpu150498
313
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);
317 if (egofft) {
318 oritan = oriEFT;
319 if (EEisnew && !same) oritan = TopAbs::Complement(oriEFT);
320 }
321 else if (egoffi) {
322 oritan = oriEFI;
323 if (EEisnew && !same) oritan = TopAbs::Complement(oriEFI);
324 }
325 else { FUN_RaiseError(); return; }
326
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;}
331
332 gp_Dir Norm;
333 if(isLine) {
334 FUN_ComputeGeomData(FT,uv,Norm);
335// if (Fori == TopAbs_REVERSED) Norm.Reverse();
336 myTool.Compare(myTole,Norm,oriloc,oritan);
337 }
338 else {
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);
343 }
344}
345
346//=======================================================================
347//function : Add
348//purpose :
349//=======================================================================
350void 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)& )
353{
354 // NYI
355}
356
357//=======================================================================
358//function : Transition
359//purpose :
360//=======================================================================
361void TopOpeBRepDS_FaceInterferenceTool::Transition(const Handle(TopOpeBRepDS_Interference)& I) const
362{
363 TopOpeBRepDS_Transition& T = I->ChangeTransition();
364
365 if (myFaceOrientation == TopAbs_INTERNAL) {
366 T.Set(TopAbs_IN,TopAbs_IN);
367 }
368 else if (myFaceOrientation == TopAbs_EXTERNAL) {
369 T.Set(TopAbs_OUT,TopAbs_OUT);
370 }
371 else {
372 I->Support(myFaceOriented);
373 TopAbs_State stb = myTool.StateBefore();
374 TopAbs_State sta = myTool.StateAfter();
375 T.Set(stb,sta);
376 //xpu150498
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);
380 T.Set(o);
381 //xpu150498
382 }
383}
384
385//=======================================================================
386//function : SetEdgePntPar
387//purpose :
388//=======================================================================
389void TopOpeBRepDS_FaceInterferenceTool::SetEdgePntPar(const gp_Pnt& P,const Standard_Real p)
390{
391 myPntOnEd = P;
392 myParOnEd = p;
393 myOnEdDef = Standard_True;
394}
395
396//=======================================================================
397//function : GetEdgePnt
398//purpose :
399//=======================================================================
400void TopOpeBRepDS_FaceInterferenceTool::GetEdgePntPar(gp_Pnt& P,Standard_Real& p) const
401{
402 if (!myOnEdDef) Standard_ProgramError::Raise("GetEdgePntPar");
403 P = myPntOnEd;
404 p = myParOnEd;
405}
406
407//=======================================================================
408//function : IsEdgePnt
409//purpose :
410//=======================================================================
411
412Standard_Boolean TopOpeBRepDS_FaceInterferenceTool::IsEdgePntParDef() const
413{
414 return myOnEdDef;
415}