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 |
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); |
7fd59977 |
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); |
47 | } |
48 | //unreferenced function, commented |
49 | /* |
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); |
55 | }*/ |
1d0a9d4d |
56 | extern void debredfac(const Standard_Integer I); |
7fd59977 |
57 | #endif |
58 | |
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) |
62 | |
63 | //------------------------------------------------------ |
64 | static void FUN_RaiseError(){Standard_ProgramError::Raise("TopOpeBRepDS_FaceInterferenceTool");} |
65 | |
66 | //------------------------------------------------------ |
67 | Standard_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 |
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) |
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 | //------------------------------------------------------ |
108 | Standard_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 | //------------------------------------------------------ |
116 | static 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 |
126 | static 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 | //------------------------------------------------------ |
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) |
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 | //======================================================================= |
189 | TopOpeBRepDS_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 | //======================================================================= |
199 | void TopOpeBRepDS_FaceInterferenceTool::Init |
200 | (const TopoDS_Shape& FFI,const TopoDS_Shape& EE,const Standard_Boolean EEisnew,const Handle(TopOpeBRepDS_Interference)& Iin) |
201 | { |
c5f3a425 |
202 | Handle(TopOpeBRepDS_ShapeShapeInterference) I (Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin)); if (I.IsNull()) return; |
7fd59977 |
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 | //======================================================================= |
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) |
265 | { |
c5f3a425 |
266 | Handle(TopOpeBRepDS_ShapeShapeInterference) I (Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(Iin)); if (I.IsNull()) return; |
7fd59977 |
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 | //======================================================================= |
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)& ) |
353 | { |
354 | // NYI |
355 | } |
356 | |
357 | //======================================================================= |
358 | //function : Transition |
359 | //purpose : |
360 | //======================================================================= |
361 | void 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 | //======================================================================= |
389 | void 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 | //======================================================================= |
400 | void 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 | |
412 | Standard_Boolean TopOpeBRepDS_FaceInterferenceTool::IsEdgePntParDef() const |
413 | { |
414 | return myOnEdDef; |
415 | } |