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