Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2001-04-05 |
2 | // Created by: Peter KURNEV | |
3 | // Copyright (c) 2001-2012 OPEN CASCADE SAS | |
4 | // | |
5 | // The content of this file is subject to the Open CASCADE Technology Public | |
6 | // License Version 6.5 (the "License"). You may not use the content of this file | |
7 | // except in compliance with the License. Please obtain a copy of the License | |
8 | // at http://www.opencascade.org and read it completely before using this file. | |
9 | // | |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
12 | // | |
13 | // The Original Code and all software distributed under the License is | |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
15 | // Initial Developer hereby disclaims all such warranties, including without | |
16 | // limitation, any warranties of merchantability, fitness for a particular | |
17 | // purpose or non-infringement. Please see the License for the specific terms | |
18 | // and conditions governing the rights and limitations under the License. | |
19 | ||
7fd59977 | 20 | |
21 | #include <BOPTools_Tools3D.ixx> | |
22 | ||
23 | #include <TopExp.hxx> | |
24 | #include <TopExp_Explorer.hxx> | |
25 | ||
26 | #include <TopoDS.hxx> | |
27 | #include <TopoDS_Shape.hxx> | |
28 | #include <TopoDS_Edge.hxx> | |
29 | #include <TopoDS_Face.hxx> | |
30 | #include <TopoDS_Vertex.hxx> | |
31 | ||
32 | #include <TopTools_MapOfShape.hxx> | |
33 | #include <TopTools_MapIteratorOfMapOfShape.hxx> | |
34 | #include <TopTools_ListOfShape.hxx> | |
35 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
36 | #include <TopTools_IndexedMapOfShape.hxx> | |
37 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
38 | ||
39 | #include <BRep_Builder.hxx> | |
40 | #include <BRep_Tool.hxx> | |
41 | #include <BRepTools.hxx> | |
42 | #include <BRepAdaptor_Surface.hxx> | |
43 | ||
44 | #include <gp_Vec2d.hxx> | |
45 | #include <gp_Pnt2d.hxx> | |
46 | #include <gp_Lin2d.hxx> | |
47 | #include <gp_Dir2d.hxx> | |
48 | #include <gp_Vec.hxx> | |
49 | #include <gp_Dir.hxx> | |
50 | #include <gp_Pln.hxx> | |
51 | ||
52 | #include <Geom2d_Curve.hxx> | |
53 | #include <Geom2d_TrimmedCurve.hxx> | |
54 | #include <Geom2d_Line.hxx> | |
55 | ||
56 | #include <Geom_Curve.hxx> | |
57 | #include <Geom_Surface.hxx> | |
58 | #include <Geom_BSplineSurface.hxx> | |
59 | #include <Geom_BezierSurface.hxx> | |
60 | ||
61 | #include <GeomAdaptor_Surface.hxx> | |
62 | ||
63 | #include <IntTools_Tools.hxx> | |
64 | ||
65 | #include <BOPTools_Tools2D.hxx> | |
66 | ||
67 | #include <GProp_GProps.hxx> | |
68 | #include <BRepGProp.hxx> | |
69 | #include <BRepBndLib.hxx> | |
70 | #include <Bnd_Box.hxx> | |
71 | ||
72 | ||
73 | ||
74 | static | |
75 | void PointNearE (const TopoDS_Edge& aE, | |
76 | const TopoDS_Face& aF, | |
77 | const Standard_Real aT, | |
78 | gp_Pnt& aPInFace, | |
79 | const Standard_Boolean aSt); | |
80 | ||
81 | static Standard_Boolean CheckKeepArguments(const TopoDS_Face& F1, | |
82 | const TopoDS_Face& F2, | |
83 | const TopoDS_Face& F3); | |
84 | ||
85 | //======================================================================= | |
86 | //function : RemoveSims | |
87 | //purpose : | |
88 | //======================================================================= | |
89 | void BOPTools_Tools3D::RemoveSims (const TopoDS_Shape& aS, | |
4f189102 | 90 | const Handle(IntTools_Context)& aContext) |
7fd59977 | 91 | { |
92 | TopExp_Explorer anExp(aS, TopAbs_FACE); | |
93 | for (; anExp.More(); anExp.Next()) { | |
94 | const TopoDS_Face& aF=TopoDS::Face(anExp.Current()); | |
95 | // | |
96 | BOPTools_Tools3D::RemoveSims (aF, aContext); | |
97 | } | |
98 | } | |
99 | ||
100 | //======================================================================= | |
101 | //function : RemoveSims | |
102 | //purpose : | |
103 | //======================================================================= | |
104 | void BOPTools_Tools3D::RemoveSims (const TopoDS_Face& aFF, | |
4f189102 | 105 | const Handle(IntTools_Context)& aContext) |
7fd59977 | 106 | { |
107 | Standard_Boolean anIsClosed, anIsPointInFace1, anIsPointInFace2; | |
108 | Standard_Real aT1, aT2, aT, aX, aY, dt=1.e-7, aTol; | |
109 | BRep_Builder BB; | |
110 | gp_Vec2d aV2D, aV2Dx; | |
111 | gp_Pnt2d aP2D, aP2Dx; | |
112 | TopAbs_Orientation anOri; | |
113 | Handle(Geom2d_Curve) aC2Dx; | |
114 | // | |
115 | TopoDS_Face aF=aFF; | |
116 | aF.Orientation(TopAbs_FORWARD); | |
117 | // | |
118 | TopExp_Explorer anExpW (aF, TopAbs_WIRE); | |
119 | for (; anExpW.More(); anExpW.Next()) { | |
120 | ||
121 | TopTools_MapOfShape aMap, aMapToAdd, aMapToRemove; | |
122 | const TopoDS_Shape& aW=anExpW.Current(); | |
123 | ||
124 | TopExp_Explorer anExp(aW, TopAbs_EDGE); | |
125 | for (; anExp.More(); anExp.Next()) { | |
126 | const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current()); | |
127 | // | |
128 | if (BRep_Tool::Degenerated(aE)){ | |
129 | continue; | |
130 | } | |
131 | // | |
132 | anIsClosed=BRep_Tool::IsClosed(aE, aF); | |
133 | if (anIsClosed) { | |
134 | if (aMap.Contains(aE)) { | |
135 | continue; | |
136 | } | |
137 | aMap.Add(aE); | |
138 | aTol=BRep_Tool::Tolerance(aE); | |
139 | ||
140 | Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); | |
141 | aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); | |
142 | aC2D-> D1(aT, aP2D, aV2D); | |
143 | ||
144 | anOri=aE.Orientation(); | |
145 | if (anOri==TopAbs_REVERSED) { | |
146 | aV2D.Reverse(); | |
147 | } | |
148 | ||
149 | aV2D.Normalize(); | |
150 | aX=aV2D.X(); | |
151 | aY=aV2D.Y(); | |
152 | aV2Dx.SetCoord(-aY, aX); | |
153 | ||
154 | aP2Dx.SetX(aP2D.X()+dt*aV2Dx.X()); | |
155 | aP2Dx.SetY(aP2D.Y()+dt*aV2Dx.Y()); | |
156 | // | |
4f189102 | 157 | anIsPointInFace1=aContext->IsPointInFace(aF, aP2Dx); |
7fd59977 | 158 | // |
159 | aP2Dx.SetX(aP2D.X()-dt*aV2Dx.X()); | |
160 | aP2Dx.SetY(aP2D.Y()-dt*aV2Dx.Y()); | |
161 | // | |
4f189102 | 162 | anIsPointInFace2=aContext->IsPointInFace(aF, aP2Dx); |
7fd59977 | 163 | // |
164 | ||
165 | if (anIsPointInFace1 && anIsPointInFace2) { | |
166 | continue; | |
167 | } | |
168 | // | |
169 | TopoDS_Edge aEx=aE; | |
170 | ||
171 | aEx.EmptyCopy(); | |
172 | TopExp_Explorer anExpV(aE, TopAbs_VERTEX); | |
173 | for (; anExpV.More(); anExpV.Next()) { | |
174 | const TopoDS_Shape& aVx=anExpV.Current(); | |
175 | BB.Add (aEx, aVx); | |
176 | } | |
177 | ||
178 | BB.UpdateEdge(aEx, aTol); | |
179 | // | |
180 | if (anIsPointInFace1) { | |
181 | if (anOri==TopAbs_REVERSED) { | |
182 | // Remove Forward | |
183 | BB.UpdateEdge(aEx, aC2Dx, aF, aTol); | |
184 | BB.UpdateEdge(aEx, aC2D , aF, aTol); | |
185 | aEx.Orientation(TopAbs_REVERSED); | |
186 | } | |
187 | else { | |
188 | // Remove Reversed | |
189 | BB.UpdateEdge(aEx, aC2Dx, aF, aTol); | |
190 | BB.UpdateEdge(aEx, aC2D , aF, aTol); | |
191 | aEx.Orientation(TopAbs_FORWARD); | |
192 | } | |
193 | aMapToAdd.Add(aEx); | |
194 | aMapToRemove.Add(aE); | |
195 | } | |
196 | } | |
197 | }// next Edge | |
198 | // | |
199 | TopoDS_Shape* pW= (TopoDS_Shape*)&aW; | |
200 | pW->Free(Standard_True); | |
201 | ||
202 | TopTools_MapIteratorOfMapOfShape anIt(aMapToRemove); | |
203 | for (; anIt.More(); anIt.Next()) { | |
204 | const TopoDS_Shape& aSR=anIt.Key(); | |
205 | BB.Remove(*pW, aSR); | |
206 | } | |
207 | anIt.Initialize(aMapToAdd); | |
208 | for (; anIt.More(); anIt.Next()) { | |
209 | const TopoDS_Shape& aSA=anIt.Key(); | |
210 | BB.Add(*pW, aSA); | |
211 | } | |
212 | ||
213 | }// next Wire | |
214 | } | |
215 | ||
216 | //======================================================================= | |
217 | //function : SubShapesAmount | |
218 | //purpose : | |
219 | //======================================================================= | |
220 | Standard_Integer BOPTools_Tools3D::SubShapesAmount (const TopoDS_Shape& aS, | |
221 | const TopAbs_ShapeEnum aType) | |
222 | { | |
223 | Standard_Integer aNb; | |
224 | TopTools_IndexedMapOfShape aM; | |
225 | TopExp::MapShapes(aS, aType, aM); | |
226 | aNb=aM.Extent(); | |
227 | return aNb; | |
228 | } | |
229 | ||
230 | //======================================================================= | |
231 | //function : IsConvexWire | |
232 | //purpose : | |
233 | //======================================================================= | |
234 | Standard_Boolean BOPTools_Tools3D::IsConvexWire (const TopoDS_Wire& aW) | |
235 | { | |
236 | Standard_Boolean aFlag; | |
237 | Standard_Integer aNbV, aNbE; | |
238 | ||
239 | aNbV=BOPTools_Tools3D::SubShapesAmount(aW, TopAbs_VERTEX); | |
240 | aNbE=BOPTools_Tools3D::SubShapesAmount(aW, TopAbs_EDGE); | |
241 | aFlag=aNbV <= aNbE; | |
242 | return aFlag; | |
243 | } | |
244 | ||
245 | //======================================================================= | |
246 | //function : DoSplitSEAMOnFace | |
247 | //purpose : | |
248 | //======================================================================= | |
249 | void BOPTools_Tools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit, | |
250 | const TopoDS_Face& aF) | |
251 | { | |
252 | Standard_Boolean bIsUPeriodic, bIsLeft; | |
253 | Standard_Real aTol, a, b, anUPeriod, aT, anU, dU=1.e-7, anU1; | |
254 | Standard_Real aScPr; | |
255 | gp_Pnt2d aP2D; | |
256 | gp_Vec2d aVec2D; | |
257 | Handle(Geom2d_Curve) aTmpC1, aTmpC2; | |
258 | Handle(Geom2d_Curve) C2D1; | |
259 | Handle(Geom2d_Line) aLD1; | |
260 | Handle(Geom_Surface) aS; | |
261 | BRep_Builder BB; | |
262 | TopoDS_Edge aSp; | |
263 | // | |
264 | aSp=aSplit; | |
265 | aSp.Orientation(TopAbs_FORWARD); | |
266 | ||
267 | aTol=BRep_Tool::Tolerance(aSp); | |
268 | ||
269 | aS=BRep_Tool::Surface(aF); | |
270 | bIsUPeriodic=aS->IsUPeriodic(); | |
271 | ||
272 | anUPeriod=0.; | |
273 | if (bIsUPeriodic) { | |
274 | anUPeriod=aS->UPeriod(); | |
275 | } | |
276 | else { | |
277 | //modified by NIZNHY-PKV Fri Jul 11 09:54:43 2008f | |
278 | Standard_Boolean bIsUClosed; | |
279 | Standard_Real aUmin, aUmax, aVmin, aVmax; | |
280 | Handle(Geom_BSplineSurface) aBS; | |
281 | Handle(Geom_BezierSurface) aBZ; | |
282 | // | |
283 | bIsUClosed=Standard_False; | |
284 | aBS=Handle(Geom_BSplineSurface)::DownCast(aS); | |
285 | aBZ=Handle(Geom_BezierSurface) ::DownCast(aS); | |
286 | // | |
287 | if (!aBS.IsNull()) { | |
288 | bIsUClosed=aBS->IsUClosed(); | |
289 | aBS->Bounds(aUmin, aUmax, aVmin, aVmax); | |
290 | } | |
291 | else if (!aBZ.IsNull()) { | |
292 | bIsUClosed=aBZ->IsUClosed(); | |
293 | aBZ->Bounds(aUmin, aUmax, aVmin, aVmax); | |
294 | } | |
295 | if (!bIsUClosed) { | |
296 | return; | |
297 | } | |
298 | // | |
299 | anUPeriod=aUmax-aUmin; | |
300 | //modified by NIZNHY-PKV Fri Jul 11 09:54:49 2008t | |
301 | } | |
302 | // | |
303 | C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b); | |
304 | //modified by NIZNHY-PKV Fri Jul 11 09:55:10 2008f | |
305 | /* | |
306 | aLD1=Handle(Geom2d_Line)::DownCast(C2D1); | |
307 | if (aLD1.IsNull()) { | |
308 | return; | |
309 | } | |
310 | */ | |
311 | //modified by NIZNHY-PKV Fri Jul 11 09:55:14 2008t | |
312 | // | |
313 | aT=BOPTools_Tools2D::IntermediatePoint(a, b); | |
314 | C2D1->D1(aT, aP2D, aVec2D); | |
315 | gp_Dir2d aDir2D1(aVec2D); | |
316 | ||
317 | // | |
318 | gp_Dir2d aDOY(0.,1.); | |
319 | aScPr=aDir2D1*aDOY; | |
320 | // | |
321 | // | |
322 | anU=aP2D.X(); | |
323 | if (fabs (anU) < dU) { | |
324 | bIsLeft=Standard_True; | |
325 | anU1=anU+anUPeriod; | |
326 | } | |
327 | else if (fabs (anU-anUPeriod) < dU) { | |
328 | bIsLeft=Standard_False; | |
329 | anU1=anU-anUPeriod; | |
330 | } | |
331 | else { | |
332 | return; | |
333 | } | |
334 | // | |
335 | ||
336 | ||
337 | aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy()); | |
338 | Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, a, b); | |
339 | ||
340 | aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy()); | |
341 | Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, a, b); | |
342 | gp_Vec2d aTrV(anU1-anU, 0.); | |
343 | aC2->Translate(aTrV); | |
344 | // | |
345 | if (!bIsLeft) { | |
346 | if (aScPr<0.) { | |
347 | BB.UpdateEdge(aSp, aC2, aC1, aF, aTol); | |
348 | } | |
349 | else { | |
350 | BB.UpdateEdge(aSp, aC1, aC2, aF, aTol); | |
351 | } | |
352 | } | |
353 | else { | |
354 | if (aScPr<0.) { | |
355 | BB.UpdateEdge(aSp, aC1, aC2, aF, aTol); | |
356 | } | |
357 | else { | |
358 | BB.UpdateEdge(aSp, aC2, aC1, aF, aTol); | |
359 | } | |
360 | } | |
361 | // | |
362 | } | |
363 | //======================================================================= | |
364 | //function : DoSplitSEAMOnFace | |
365 | //purpose : | |
366 | //======================================================================= | |
367 | Standard_Boolean BOPTools_Tools3D::DoSplitSEAMOnFace(const TopoDS_Edge& theSplit, | |
368 | const TopoDS_Edge& theSeam, | |
369 | const TopoDS_Face& theFace, | |
370 | Standard_Boolean& IsReversed) | |
371 | { | |
372 | Standard_Real aTol, f, l, a, b, aPeriod, aT, aParTolerance = 1.e-07; | |
373 | Standard_Boolean bIsUPeriodic = Standard_False; | |
374 | Standard_Boolean bIsVPeriodic = Standard_False; | |
375 | BRep_Builder BB; | |
376 | gp_Pnt2d aP2D; | |
377 | gp_Vec2d aVec2D; | |
378 | ||
379 | ||
380 | TopoDS_Edge aSp = theSplit; | |
381 | aSp.Orientation(TopAbs_FORWARD); | |
382 | TopoDS_Edge aSeamF = theSeam; | |
383 | aSeamF.Orientation(TopAbs_FORWARD); | |
384 | TopoDS_Edge aSeamR = theSeam; | |
385 | aSeamR.Orientation(TopAbs_REVERSED); | |
386 | ||
387 | aTol=BRep_Tool::Tolerance(aSp); | |
388 | ||
389 | Handle(Geom2d_Curve) C2D1 = BRep_Tool::CurveOnSurface(aSp, theFace, f, l); | |
390 | Handle(Geom2d_Curve) C2D2 = BRep_Tool::CurveOnSurface(aSeamF, theFace, a, b); | |
391 | Handle(Geom2d_Curve) C2D3 = BRep_Tool::CurveOnSurface(aSeamR, theFace, a, b); | |
392 | // | |
393 | Handle(Geom2d_TrimmedCurve) atr = Handle(Geom2d_TrimmedCurve)::DownCast(C2D1); | |
394 | Handle(Geom2d_Line) aLD1; | |
395 | ||
396 | if(!atr.IsNull()) { | |
397 | aLD1 = Handle(Geom2d_Line)::DownCast(atr->BasisCurve()); | |
398 | } | |
399 | else { | |
400 | aLD1 = Handle(Geom2d_Line)::DownCast(C2D1); | |
401 | } | |
402 | ||
403 | if (aLD1.IsNull()) { | |
404 | return Standard_False; | |
405 | } | |
406 | aT = BOPTools_Tools2D::IntermediatePoint(f, l); | |
407 | C2D1->D1(aT, aP2D, aVec2D); | |
408 | gp_Dir2d aDir2D(aVec2D); | |
409 | ||
410 | gp_Vec2d aVec2D1, aVec2D2; | |
411 | gp_Pnt2d aP2D1, aP2D2; | |
412 | C2D2->D1(((a+b) * 0.5), aP2D1, aVec2D1); | |
413 | C2D3->D1(((a+b) * 0.5), aP2D2, aVec2D2); | |
414 | ||
415 | Handle(Geom_Surface) aS=BRep_Tool::Surface(theFace); | |
416 | bIsUPeriodic = aS->IsUPeriodic(); | |
417 | bIsVPeriodic = aS->IsVPeriodic(); | |
418 | ||
419 | for(Standard_Integer i = 0; i < 2; i++) { | |
420 | Standard_Boolean bIsPeriodic = (i == 0) ? bIsUPeriodic : bIsVPeriodic; | |
421 | ||
422 | if(!bIsPeriodic) | |
423 | continue; | |
424 | ||
425 | aPeriod = (i == 0) ? aS->UPeriod() : aS->VPeriod(); | |
426 | ||
427 | Standard_Real aParameter = (i == 0) ? aP2D.X() : aP2D.Y(); | |
428 | Standard_Real aParameter1 = (i == 0) ? aP2D1.X() : aP2D1.Y(); | |
429 | Standard_Real aParameter2 = (i == 0) ? aP2D2.X() : aP2D2.Y(); | |
430 | ||
431 | Standard_Boolean bIsLower = Standard_False, found = Standard_False; | |
432 | Standard_Boolean bIsFirst = Standard_False; | |
433 | Standard_Real aScPr = 0.; | |
434 | ||
435 | if (fabs (aParameter - aParameter1) < aParTolerance) { | |
436 | bIsLower = (aParameter < aParameter2); | |
437 | bIsFirst = Standard_True; | |
438 | aScPr = aDir2D * aVec2D1; | |
439 | } | |
440 | else if (fabs (aParameter - aParameter2) < aParTolerance) { | |
441 | bIsLower = (aParameter < aParameter1); | |
442 | bIsFirst = Standard_False; | |
443 | aScPr = aDir2D * aVec2D2; | |
444 | } | |
445 | found = (fabs(aScPr) > aParTolerance); | |
446 | ||
447 | if(found) { | |
448 | Handle(Geom2d_Curve) aTmpC1, aTmpC2; | |
449 | ||
450 | aTmpC1 = Handle(Geom2d_Curve)::DownCast(C2D1->Copy()); | |
451 | Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, f, l); | |
452 | ||
453 | aTmpC2 = Handle(Geom2d_Curve)::DownCast(C2D1->Copy()); | |
454 | Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, f, l); | |
455 | gp_Vec2d aTrV; | |
456 | ||
457 | if(i == 0) { | |
458 | if(bIsLower) | |
459 | aTrV.SetX(aPeriod); | |
460 | else | |
461 | aTrV.SetX(-aPeriod); | |
462 | aTrV.SetY(0.); | |
463 | } | |
464 | else { | |
465 | if(bIsLower) | |
466 | aTrV.SetY(aPeriod); | |
467 | else | |
468 | aTrV.SetY(-aPeriod); | |
469 | aTrV.SetX(0.); | |
470 | } | |
471 | aC2->Translate(aTrV); | |
472 | // | |
473 | IsReversed = (aScPr < 0.); | |
474 | Standard_Boolean bIsReverseOrder = (!IsReversed) ? !bIsFirst : bIsFirst; | |
475 | ||
476 | if(bIsReverseOrder) { | |
477 | BB.UpdateEdge(aSp, aC2, aC1, theFace, aTol); | |
478 | } | |
479 | else { | |
480 | BB.UpdateEdge(aSp, aC1, aC2, theFace, aTol); | |
481 | } | |
482 | return Standard_True; | |
483 | } | |
484 | } | |
485 | return Standard_False; | |
486 | } | |
487 | //======================================================================= | |
488 | //function :IsSplitToReverse1 | |
489 | //purpose : | |
490 | //======================================================================= | |
491 | Standard_Boolean BOPTools_Tools3D::IsSplitToReverse1 (const TopoDS_Edge& aEF1, | |
492 | const TopoDS_Edge& aEF2, | |
4f189102 | 493 | const Handle(IntTools_Context)& aContext) |
7fd59977 | 494 | { |
495 | Standard_Boolean aFlag; | |
496 | Standard_Real aT1, aT2, aScPr, a, b; | |
497 | gp_Vec aV1, aV2; | |
498 | gp_Pnt aP; | |
499 | ||
500 | ||
501 | Handle(Geom_Curve)aC1=BRep_Tool::Curve(aEF1, a, b); | |
502 | aT1=BOPTools_Tools2D::IntermediatePoint(a, b); | |
503 | aC1->D0(aT1, aP); | |
504 | aFlag=BOPTools_Tools2D::EdgeTangent(aEF1, aT1, aV1); | |
505 | ||
506 | if(!aFlag) { | |
507 | return Standard_False; | |
508 | } | |
509 | ||
510 | gp_Dir aDT1(aV1); | |
511 | // | |
4f189102 | 512 | aFlag=aContext->ProjectPointOnEdge(aP, aEF2, aT2); |
8fb480b3 P |
513 | if(!aFlag) { |
514 | return Standard_False; | |
515 | } | |
7fd59977 | 516 | // |
517 | aFlag=BOPTools_Tools2D::EdgeTangent(aEF2, aT2, aV2); | |
518 | if(!aFlag) { | |
519 | return Standard_False; | |
520 | } | |
521 | ||
522 | gp_Dir aDT2(aV2); | |
523 | ||
524 | aScPr=aDT1*aDT2; | |
525 | ||
526 | return (aScPr<0.); | |
527 | } | |
528 | ||
529 | //======================================================================= | |
530 | //function : EdgeOrientation | |
531 | //purpose : | |
532 | //======================================================================= | |
533 | TopAbs_Orientation BOPTools_Tools3D::EdgeOrientation (const TopoDS_Edge& aE, | |
534 | const TopoDS_Face& aF1, | |
535 | const TopoDS_Face& aF2) | |
536 | { | |
537 | Standard_Real aScPr; | |
538 | gp_Dir aDTE, aDNF1, aDNF2, aDTN; | |
539 | ||
540 | BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF1, aDNF1); | |
541 | BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF2, aDNF2); | |
542 | ||
543 | aDTN=aDNF1^aDNF2; | |
544 | ||
545 | BOPTools_Tools2D::TangentOnEdge(aE, aDTE); | |
546 | ||
547 | aScPr=aDTN*aDTE; | |
548 | ||
549 | TopAbs_Orientation anOr; | |
550 | ||
551 | anOr=TopAbs_FORWARD; | |
552 | if (aScPr<0.) { | |
553 | anOr=TopAbs_REVERSED; | |
554 | } | |
555 | return anOr; | |
556 | } | |
557 | //======================================================================= | |
558 | //function : IsTouchCase | |
559 | //purpose : | |
560 | //======================================================================= | |
561 | Standard_Boolean BOPTools_Tools3D::IsTouchCase(const TopoDS_Edge& aE, | |
562 | const TopoDS_Face& aF1, | |
563 | const TopoDS_Face& aF2) | |
564 | { | |
565 | gp_Dir aDNF1, aDNF2; | |
566 | ||
567 | ||
568 | BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF1, aDNF1); | |
569 | BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF2, aDNF2); | |
570 | ||
571 | Standard_Boolean bIsDirsCoinside; | |
572 | bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2); | |
573 | return bIsDirsCoinside; | |
574 | } | |
575 | //======================================================================= | |
576 | //function : GetNormalToFaceOnEdge | |
577 | //purpose : | |
578 | //======================================================================= | |
579 | void BOPTools_Tools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE, | |
580 | const TopoDS_Face& aF, | |
581 | gp_Dir& aDNF) | |
582 | { | |
583 | Standard_Real aT, aT1, aT2; | |
584 | ||
585 | BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); | |
586 | aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); | |
587 | ||
588 | BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF); | |
589 | ||
590 | if (aF.Orientation()==TopAbs_REVERSED){ | |
591 | aDNF.Reverse(); | |
592 | } | |
593 | } | |
594 | ||
595 | //======================================================================= | |
596 | //function : GetNormalToFaceOnEdge | |
597 | //purpose : | |
598 | //======================================================================= | |
599 | void BOPTools_Tools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE, | |
600 | const TopoDS_Face& aF1, | |
601 | const Standard_Real aT, | |
602 | gp_Dir& aDNF1) | |
603 | { | |
604 | Standard_Real U, V, aTolPC; | |
605 | gp_Pnt2d aP2D; | |
606 | gp_Pnt aP; | |
607 | gp_Vec aD1U, aD1V; | |
608 | ||
609 | Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1); | |
610 | ||
611 | Handle(Geom2d_Curve)aC2D1; | |
612 | BOPTools_Tools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC, Standard_True); | |
613 | ||
614 | aC2D1->D0(aT, aP2D); | |
615 | U=aP2D.X(); | |
616 | V=aP2D.Y(); | |
617 | ||
618 | aS1->D1(U, V, aP, aD1U, aD1V); | |
619 | gp_Dir aDD1U(aD1U); | |
620 | gp_Dir aDD1V(aD1V); | |
621 | ||
622 | aDNF1=aDD1U^aDD1V; | |
623 | } | |
624 | ||
625 | //======================================================================= | |
626 | //function : GetBiNormal | |
627 | //purpose : | |
628 | //======================================================================= | |
629 | void BOPTools_Tools3D::GetBiNormal(const TopoDS_Edge& aE, | |
630 | const TopoDS_Face& aF, | |
631 | const Standard_Real aT, | |
632 | gp_Dir& aDB) | |
633 | { | |
634 | gp_Dir aDNF, aDT; | |
635 | // | |
636 | // Normal to the face aF at parameter aT | |
637 | BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF); | |
638 | if (aF.Orientation()==TopAbs_REVERSED){ | |
639 | aDNF.Reverse(); | |
640 | } | |
641 | // | |
642 | // Split tangent on aF at parameter aT | |
643 | BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDT); | |
644 | ||
645 | if (aF.Orientation()==TopAbs_REVERSED){ | |
646 | aDT.Reverse(); | |
647 | } | |
648 | // Binormal | |
649 | aDB=aDNF^aDT; | |
650 | } | |
651 | ||
652 | //======================================================================= | |
653 | //function : :GetBiNormal | |
654 | //purpose : | |
655 | //======================================================================= | |
656 | void BOPTools_Tools3D::GetBiNormal(const TopoDS_Edge& aSp, | |
657 | const TopoDS_Face& aF, | |
658 | gp_Dir& aDB) | |
659 | { | |
660 | gp_Dir aDNF, aDD1Sp; | |
661 | // | |
662 | // Normal to the face aF at parameter aT | |
663 | BOPTools_Tools3D::GetNormalToFaceOnEdge (aSp, aF, aDNF); | |
664 | // | |
665 | // Split tangent on aF at parameter aT | |
666 | BOPTools_Tools3D::GetTangentToEdge(aSp, aDD1Sp); | |
667 | ||
668 | if (aF.Orientation()==TopAbs_REVERSED){ | |
669 | aDD1Sp.Reverse(); | |
670 | } | |
671 | // Binormal | |
672 | aDB=aDNF^aDD1Sp; | |
673 | } | |
674 | //======================================================================= | |
675 | //function : GetTangentToEdge | |
676 | //purpose : | |
677 | //======================================================================= | |
678 | Standard_Boolean BOPTools_Tools3D::GetTangentToEdge(const TopoDS_Edge& anEdge, | |
679 | gp_Dir& aDT) | |
680 | { | |
681 | Standard_Boolean isdgE; | |
682 | ||
683 | Standard_Real aT1, aT2, aT; | |
684 | ||
685 | isdgE = BRep_Tool::Degenerated(anEdge); | |
686 | if (isdgE) { | |
687 | return Standard_False; | |
688 | } | |
689 | ||
690 | Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, aT1, aT2); | |
691 | aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); | |
692 | ||
693 | BOPTools_Tools3D::GetTangentToEdge(anEdge, aT, aDT); | |
694 | ||
695 | return Standard_True; | |
696 | } | |
697 | //======================================================================= | |
698 | //function : GetTangentToEdge | |
699 | //purpose : | |
700 | //======================================================================= | |
701 | Standard_Boolean BOPTools_Tools3D::GetTangentToEdge(const TopoDS_Edge& anEdge, | |
702 | const Standard_Real aT, | |
703 | gp_Dir& aDT) | |
704 | { | |
705 | Standard_Boolean isdgE; | |
706 | Standard_Real first, last; | |
707 | ||
708 | isdgE = BRep_Tool::Degenerated(anEdge); | |
709 | if (isdgE) { | |
710 | return Standard_False; | |
711 | } | |
712 | ||
713 | Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last); | |
714 | gp_Pnt aP; | |
715 | gp_Vec aTau; | |
716 | aC->D1(aT, aP, aTau); | |
717 | gp_Dir aD(aTau); | |
718 | if (anEdge.Orientation() == TopAbs_REVERSED){ | |
719 | aD.Reverse(); | |
720 | } | |
721 | aDT=aD; | |
722 | ||
723 | return Standard_True; | |
724 | } | |
725 | //======================================================================= | |
726 | //function : :IsSplitToReverse | |
727 | //purpose : | |
728 | //======================================================================= | |
729 | Standard_Boolean BOPTools_Tools3D:: IsSplitToReverse(const TopoDS_Edge& aE, | |
730 | const TopoDS_Edge& aSp) | |
731 | { | |
732 | Standard_Real t1, t2, aT; | |
733 | ||
734 | Handle(Geom_Curve)aCE=BRep_Tool::Curve(aE, t1, t2); | |
735 | Handle(Geom_Curve)aCSp=BRep_Tool::Curve(aSp,t1, t2); | |
736 | ||
737 | aT=BOPTools_Tools2D::IntermediatePoint(t1, t2); | |
738 | ||
739 | gp_Vec aD1E, aD1Sp; | |
740 | gp_Pnt aP; | |
741 | ||
742 | aCE->D1 (aT, aP, aD1E); | |
743 | aCSp->D1(aT, aP, aD1Sp); | |
744 | ||
745 | gp_Dir aDD1E (aD1E); | |
746 | gp_Dir aDD1Sp(aD1Sp); | |
747 | ||
748 | if (aE.Orientation()==TopAbs_REVERSED) { | |
749 | aDD1E.Reverse(); | |
750 | } | |
751 | if (aSp.Orientation()==TopAbs_REVERSED) { | |
752 | aDD1Sp.Reverse(); | |
753 | } | |
754 | ||
755 | aT=aDD1E*aDD1Sp; | |
756 | ||
757 | return (aT<0.); | |
758 | } | |
759 | ||
760 | //======================================================================= | |
761 | //function : GetAdjacentFace | |
762 | //purpose : | |
763 | //======================================================================= | |
764 | Standard_Boolean BOPTools_Tools3D::GetAdjacentFace(const TopoDS_Face& aFaceObj, | |
765 | const TopoDS_Edge& anEObj, | |
766 | const TopTools_IndexedDataMapOfShapeListOfShape& anEdgeFaceMap, | |
767 | TopoDS_Face& anAdjF) | |
768 | { | |
769 | const TopTools_ListOfShape& aListOfAdjFaces=anEdgeFaceMap.FindFromKey(anEObj); | |
770 | TopTools_ListIteratorOfListOfShape anIt(aListOfAdjFaces); | |
771 | TopoDS_Shape anAdjShape; | |
772 | for (; anIt.More(); anIt.Next()) { | |
773 | if (anIt.Value()!=aFaceObj) { | |
774 | anAdjShape=anIt.Value(); | |
775 | break; | |
776 | } | |
777 | } | |
778 | ||
779 | if (!anAdjShape.IsNull()) { | |
780 | anAdjF=TopoDS::Face(anAdjShape); | |
781 | return Standard_True; | |
782 | } | |
783 | else { | |
784 | return Standard_False; | |
785 | } | |
786 | } | |
787 | //======================================================================= | |
788 | //function : IsKeepTwice | |
789 | //purpose : | |
790 | //======================================================================= | |
791 | Standard_Boolean BOPTools_Tools3D::IsKeepTwice(const TopoDS_Face& aF1, | |
792 | const TopoDS_Face& aF2, | |
793 | const TopoDS_Face& aF2Adj, | |
794 | const TopoDS_Edge& aSpEF2) | |
795 | { | |
796 | if( !CheckKeepArguments(aF1, aF2, aF2Adj) ) { | |
797 | return Standard_False; | |
798 | } | |
799 | ||
800 | Standard_Real aT1, aT2, aT, dt=1.e-7, A, B, C, D, d2, d2Adj; | |
801 | gp_Dir aDNF1, aDNF2, DBF2, aDNF2Adj, DBF2Adj; | |
802 | gp_Vec aD1Sp; | |
803 | gp_Pnt aP, aPF2, aPF2Adj; | |
804 | ||
805 | Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aSpEF2, aT1, aT2); | |
806 | aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); | |
807 | BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF1, aT, aDNF1); | |
808 | ||
809 | // | |
810 | // Split tangent on F2 | |
811 | aC3D->D1(aT, aP, aD1Sp); | |
812 | gp_Dir aDD1Sp(aD1Sp); | |
813 | ||
814 | if (aSpEF2.Orientation()==TopAbs_REVERSED) { | |
815 | aDD1Sp.Reverse(); | |
816 | } | |
817 | // Split Normal on F2 | |
818 | BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2, aT, aDNF2); | |
819 | if (aF2.Orientation()==TopAbs_REVERSED) { | |
820 | aDNF2.Reverse(); | |
821 | } | |
822 | // Binormal on F2 | |
823 | DBF2=aDNF2^aDD1Sp; | |
824 | ||
825 | // Point near aP | |
826 | aPF2.SetCoord(aP.X()+dt*DBF2.X(), | |
827 | aP.Y()+dt*DBF2.Y(), | |
828 | aP.Z()+dt*DBF2.Z()); | |
829 | ||
830 | ||
831 | // | |
832 | // Split tangent on F2Adj | |
833 | aDD1Sp.Reverse(); | |
834 | // Split Normal on F2Adj | |
835 | BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2Adj, aT, aDNF2Adj); | |
836 | if (aF2Adj.Orientation()==TopAbs_REVERSED) { | |
837 | aDNF2Adj.Reverse(); | |
838 | } | |
839 | // Binormal on F2Adj | |
840 | DBF2Adj=aDNF2Adj^aDD1Sp; | |
841 | ||
842 | // Point near aP | |
843 | aPF2Adj.SetCoord(aP.X()+dt*DBF2Adj.X(), | |
844 | aP.Y()+dt*DBF2Adj.Y(), | |
845 | aP.Z()+dt*DBF2Adj.Z()); | |
846 | // | |
847 | // Tangent Plane on F1 | |
848 | gp_Pln aPlnN1(aP, aDNF1); | |
849 | aPlnN1.Coefficients(A, B, C, D); | |
850 | // | |
851 | d2 = A*aPF2.X() + B*aPF2.Y() + C*aPF2.Z() + D; | |
852 | d2Adj= A*aPF2Adj.X() + B*aPF2Adj.Y()+ C*aPF2Adj.Z() + D; | |
853 | // | |
854 | if (fabs(d2)<1.e-10) { | |
855 | d2=0.; | |
856 | } | |
857 | if (fabs(d2Adj)<1.e-10) { | |
858 | d2Adj=0.; | |
859 | } | |
860 | // | |
861 | aT=d2*d2Adj; | |
862 | // | |
863 | return (aT >= 0.); | |
864 | } | |
865 | ||
866 | //======================================================================= | |
867 | //function : SenseFlag | |
868 | //purpose : | |
869 | //======================================================================= | |
870 | Standard_Integer BOPTools_Tools3D::SenseFlag (const gp_Dir& aDNF1, | |
871 | const gp_Dir& aDNF2) | |
872 | { | |
873 | Standard_Boolean bIsDirsCoinside; | |
874 | bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2); | |
875 | if (!bIsDirsCoinside) { | |
876 | return 0; | |
877 | } | |
878 | ||
879 | Standard_Real aScPr; | |
880 | ||
881 | aScPr=aDNF1*aDNF2; | |
882 | if (aScPr<0.) { | |
883 | return -1; | |
884 | } | |
885 | else if (aScPr>0.) { | |
886 | return 1; | |
887 | } | |
888 | return -1; | |
889 | } | |
890 | ||
891 | //======================================================================= | |
892 | //function : GetNormalToSurface | |
893 | //purpose : | |
894 | //======================================================================= | |
895 | Standard_Boolean BOPTools_Tools3D::GetNormalToSurface (const Handle(Geom_Surface)& aS, | |
896 | const Standard_Real U, | |
897 | const Standard_Real V, | |
898 | gp_Dir& aDNS) | |
899 | { | |
900 | Standard_Boolean bFlag; | |
901 | ||
902 | gp_Pnt aP; | |
903 | gp_Vec aD1U, aD1V; | |
904 | ||
905 | aS->D1(U, V, aP, aD1U, aD1V); | |
906 | ||
907 | gp_Dir aDD1U(aD1U); | |
908 | gp_Dir aDD1V(aD1V); | |
909 | ||
910 | bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U); | |
911 | if (!bFlag) { | |
912 | return bFlag; | |
913 | } | |
914 | ||
915 | aDNS=aDD1U^aDD1V; | |
916 | return bFlag; | |
917 | } | |
918 | ||
919 | //======================================================================= | |
920 | //function : GetNormalToSurface | |
921 | //purpose : local modification | |
922 | //======================================================================= | |
923 | ||
924 | static void GetApproxNormalToFaceOnEdgeEx(const TopoDS_Edge& aE, | |
925 | const TopoDS_Face& aF, | |
926 | const Standard_Real aT, | |
927 | const Standard_Real aDT, | |
928 | gp_Pnt& aPNear, | |
929 | gp_Dir& aDNF) | |
930 | { | |
931 | Standard_Real aFirst, aLast; | |
932 | Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast); | |
933 | ||
934 | if (aC2D.IsNull()) { | |
935 | return; | |
936 | } | |
937 | ||
938 | //gp_Pnt aPNear; | |
939 | gp_Pnt2d aPx2DNear; | |
940 | BOPTools_Tools3D::PointNearEdge (aE, aF, aT, aDT, aPx2DNear, aPNear); | |
941 | ||
942 | Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); | |
943 | ||
944 | BOPTools_Tools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); | |
945 | ||
946 | if (aF.Orientation()==TopAbs_REVERSED){ | |
947 | aDNF.Reverse(); | |
948 | } | |
949 | } | |
950 | ||
951 | //======================================================================= | |
952 | //function : GetPlanes | |
953 | //purpose : | |
954 | //======================================================================= | |
955 | void BOPTools_Tools3D::GetPlanes (const TopoDS_Edge& aSpx, | |
956 | const TopoDS_Edge& anEx, | |
957 | const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx, | |
958 | const TopoDS_Edge& anE1, | |
959 | const TopoDS_Face& aF1, | |
960 | TopAbs_State& aStPF1, | |
4f189102 | 961 | const Handle(IntTools_Context)& aContext) |
7fd59977 | 962 | { |
963 | Standard_Boolean bIsAdjExists; | |
964 | ||
965 | Standard_Real aT, aT1, aT2; | |
966 | gp_Dir aDNFx1, aDNFx2; | |
967 | gp_Pnt aPx, aPx1, aPx2, aPF1; | |
968 | TopoDS_Face aFx1, aFx2; | |
969 | // | |
970 | // Point | |
971 | Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpx, aT1, aT2); | |
972 | aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); | |
973 | ||
974 | aC3D->D0(aT, aPx); | |
975 | // | |
976 | // 1.1. Fx1, Fx2 and theirs normals | |
977 | TopAbs_Orientation anOrEx, anOr; | |
978 | anOrEx=anEx.Orientation(); | |
979 | ||
980 | TopoDS_Edge aSpxSimm=anEx; | |
981 | if (anOrEx==TopAbs_FORWARD) { | |
982 | aSpxSimm.Orientation(TopAbs_REVERSED); | |
983 | } | |
984 | else if (anOrEx==TopAbs_REVERSED){ | |
985 | aSpxSimm.Orientation(TopAbs_FORWARD); | |
986 | } | |
987 | // | |
988 | ||
989 | const TopTools_ListOfShape& aLF=anEFMapx.FindFromKey(anEx); | |
990 | TopTools_ListIteratorOfListOfShape anIt(aLF); | |
991 | ||
992 | for (; anIt.More(); anIt.Next()) { | |
993 | const TopoDS_Shape& aFE=anIt.Value(); | |
994 | aFx1=TopoDS::Face(aFE); | |
995 | anOr=BOPTools_Tools3D::Orientation(anEx, aFx1); | |
996 | if (anOr==anOrEx){ | |
997 | break; | |
998 | } | |
999 | } | |
1000 | ||
1001 | //-- EJG | |
1002 | Standard_Boolean aMoreShift = Standard_False; | |
1003 | Standard_Real aF2Tol = BRep_Tool::Tolerance(aFx1); | |
1004 | Standard_Real aF1Tol = BRep_Tool::Tolerance(aF1); | |
1005 | Standard_Real aETol = BRep_Tool::Tolerance(anEx); | |
1006 | if( aETol > 1.e-5 && (aF2Tol > 1.e-5 && aF1Tol > 1.e-5) ) | |
1007 | aMoreShift = Standard_True; | |
1008 | Standard_Real aDT = 9.1e-5; | |
1009 | if( aMoreShift ) { | |
1010 | GetApproxNormalToFaceOnEdgeEx(anEx, aFx1, aT, aDT, aPx1, aDNFx1); | |
1011 | } | |
1012 | else { | |
1013 | //-- EJG | |
1014 | BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (anEx, aFx1, aT, aPx1, aDNFx1); | |
1015 | } | |
1016 | ||
1017 | bIsAdjExists=BOPTools_Tools3D::GetAdjacentFace (aFx1, anEx, anEFMapx, aFx2); | |
1018 | ||
1019 | if (!bIsAdjExists) { | |
1020 | //-- EJG | |
1021 | if( aMoreShift ) { | |
1022 | GetApproxNormalToFaceOnEdgeEx(aSpxSimm, aFx1, aT, aDT, aPx2, aDNFx2); | |
1023 | } | |
1024 | else { | |
1025 | //-- EJG | |
1026 | BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx1, aT, aPx2, aDNFx2); | |
1027 | } | |
1028 | ||
4f189102 | 1029 | aContext->ProjectPointOnEdge(aPx, anE1, aT1); |
7fd59977 | 1030 | PointNearE (anE1, aF1, aT1, aPF1, aMoreShift); |
1031 | } | |
1032 | ||
1033 | else {// if (bIsAdjExists) | |
1034 | BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx2, aT, aPx2, aDNFx2); | |
1035 | // | |
4f189102 | 1036 | aContext->ProjectPointOnEdge(aPx, anE1, aT1); |
7fd59977 | 1037 | PointNearE (anE1, aF1, aT1, aPF1, aMoreShift); |
1038 | } | |
1039 | ||
1040 | { | |
1041 | Standard_Real d12, d1, anAlfa12, anAlfa1, aTwoPI; | |
1042 | ||
c6541a0c | 1043 | aTwoPI = M_PI + M_PI; |
7fd59977 | 1044 | |
1045 | gp_Vec aVx1(aPx, aPx1); | |
1046 | gp_Dir aDBx1 (aVx1); | |
1047 | gp_Pln aPlnToCompare (aPx, aDNFx1); | |
1048 | ||
1049 | gp_Vec aVx2(aPx, aPx2); | |
1050 | gp_Dir aDBx2 (aVx2); | |
1051 | ||
1052 | anAlfa12=aDBx1.Angle(aDBx2); | |
1053 | d12=BOPTools_Tools3D::SignDistance(aPx2, aPlnToCompare); | |
1054 | if (d12 < 0.) { | |
1055 | anAlfa12=aTwoPI-anAlfa12; | |
1056 | } | |
1057 | ||
1058 | gp_Vec aVF1(aPx, aPF1); | |
1059 | gp_Dir aDBF1 (aVF1); | |
1060 | anAlfa1=aDBx1.Angle(aDBF1); | |
1061 | d1=BOPTools_Tools3D::SignDistance(aPF1, aPlnToCompare); | |
1062 | if (d1 < 0.) { | |
1063 | anAlfa1=aTwoPI-anAlfa1; | |
1064 | } | |
1065 | ||
1066 | aStPF1=TopAbs_OUT; | |
1067 | if (anAlfa1 > anAlfa12) { | |
1068 | aStPF1=TopAbs_IN; | |
1069 | } | |
1070 | } | |
1071 | } | |
1072 | ||
1073 | //======================================================================= | |
1074 | //function : Orientation | |
1075 | //purpose : | |
1076 | //======================================================================= | |
1077 | TopAbs_Orientation BOPTools_Tools3D::Orientation(const TopoDS_Edge& anE, | |
1078 | const TopoDS_Face& aF) | |
1079 | { | |
1080 | TopAbs_Orientation anOr=TopAbs_INTERNAL; | |
1081 | ||
1082 | TopExp_Explorer anExp; | |
1083 | anExp.Init(aF, TopAbs_EDGE); | |
1084 | for (; anExp.More(); anExp.Next()) { | |
1085 | const TopoDS_Edge& anEF1=TopoDS::Edge(anExp.Current()); | |
1086 | if (anEF1.IsEqual(anE)) { | |
1087 | anOr=anEF1.Orientation(); | |
1088 | break; | |
1089 | } | |
1090 | } | |
1091 | return anOr; | |
1092 | } | |
1093 | ||
1094 | //======================================================================= | |
1095 | //function : SignDistance | |
1096 | //purpose : | |
1097 | //======================================================================= | |
1098 | Standard_Real BOPTools_Tools3D::SignDistance(const gp_Pnt& aP, | |
1099 | const gp_Pln& aPln) | |
1100 | { | |
1101 | Standard_Real A, B, C, D, d; | |
1102 | aPln.Coefficients(A, B, C, D); | |
1103 | // | |
1104 | d = A*aP.X() + B*aP.Y() + C*aP.Z() + D; | |
1105 | ||
1106 | return d; | |
1107 | } | |
1108 | ||
1109 | //======================================================================= | |
1110 | // function: IsValidArea | |
1111 | // purpose: | |
1112 | //======================================================================= | |
1113 | Standard_Boolean BOPTools_Tools3D::IsValidArea (const TopoDS_Face& aF, | |
1114 | Standard_Boolean& bNegativeFlag) | |
1115 | ||
1116 | { | |
1117 | Standard_Boolean bFlag; | |
1118 | Standard_Real aMass, dM=1.e-16; | |
1119 | GProp_GProps G; | |
1120 | BRepGProp::SurfaceProperties(aF,G); | |
1121 | aMass=G.Mass(); | |
1122 | // | |
1123 | bFlag=(fabs(aMass)-dM > 0.); | |
1124 | bNegativeFlag=(aMass < dM); | |
1125 | ||
1126 | if( bNegativeFlag ) { | |
1127 | Bnd_Box boxF; | |
1128 | BRepBndLib::AddClose(aF, boxF); | |
1129 | Standard_Real aXmin = 0, aYmin = 0., aZmin = 0., aXmax = 0., aYmax = 0., aZmax = 0.; | |
1130 | boxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); | |
1131 | Standard_Boolean bigX = (fabs(aXmax-aXmin) >= 1.e+10); | |
1132 | Standard_Boolean bigY = (fabs(aYmax-aYmin) >= 1.e+10); | |
1133 | Standard_Boolean bigZ = (fabs(aZmax-aZmin) >= 1.e+10); | |
1134 | if( !bigX && (!bigY && !bigZ) ) { | |
1135 | TopExp_Explorer anExp; | |
1136 | Standard_Integer nbW = 0; | |
1137 | for(anExp.Init(aF, TopAbs_WIRE); anExp.More(); anExp.Next()) { | |
1138 | const TopoDS_Wire& aW = TopoDS::Wire(anExp.Current()); | |
1139 | nbW++; | |
1140 | } | |
1141 | if( nbW == 1 ) { | |
1142 | TopTools_IndexedDataMapOfShapeListOfShape mapVE; | |
1143 | mapVE.Clear(); | |
1144 | TopExp::MapShapesAndAncestors(aF,TopAbs_VERTEX,TopAbs_EDGE,mapVE); | |
1145 | Standard_Integer nbKeys = mapVE.Extent(), iKey = 0; | |
1146 | Standard_Boolean changeFlag = Standard_True; | |
1147 | for( iKey = 1; iKey <= nbKeys; iKey++ ) { | |
1148 | const TopoDS_Vertex& iV = TopoDS::Vertex(mapVE.FindKey(iKey)); | |
1149 | if( iV.IsNull() ) continue; | |
6e6cd5d9 | 1150 | //Standard_Real TolV = BRep_Tool::Tolerance(iV); |
7fd59977 | 1151 | const TopTools_ListOfShape& iLE = mapVE.FindFromIndex(iKey); |
1152 | Standard_Integer nbE = iLE.Extent(); | |
1153 | if( nbE != 2 ) { | |
1154 | changeFlag = Standard_False; | |
1155 | break; | |
1156 | } | |
1157 | const TopoDS_Edge& iE1 = TopoDS::Edge(iLE.First()); | |
1158 | const TopoDS_Edge& iE2 = TopoDS::Edge(iLE.Last()); | |
1159 | if(BRep_Tool::Degenerated(iE1) || | |
1160 | BRep_Tool::Degenerated(iE2) ) continue; | |
1161 | Standard_Real iPE1 = BRep_Tool::Parameter(iV,iE1); | |
1162 | Standard_Real iPE2 = BRep_Tool::Parameter(iV,iE2); | |
1163 | Standard_Real pF1 = 0., pL1 = 0., pF2 = 0., pL2 = 0.; | |
1164 | Handle(Geom_Curve) aC3D1 = BRep_Tool::Curve(iE1,pF1,pL1); | |
1165 | Handle(Geom_Curve) aC3D2 = BRep_Tool::Curve(iE2,pF2,pL2); | |
1166 | if( aC3D1.IsNull() || aC3D2.IsNull() ) { | |
1167 | changeFlag = Standard_False; | |
1168 | break; | |
1169 | } | |
1170 | if( Abs(Abs(pL1-pF1)-Abs(pL2-pF2)) <= 1.e-10 ) { | |
1171 | changeFlag = Standard_False; | |
1172 | break; | |
1173 | } | |
1174 | gp_Pnt aPnt1 = aC3D1->Value(iPE1); | |
1175 | gp_Pnt aPnt2 = aC3D2->Value(iPE2); | |
1176 | Standard_Real dist = aPnt1.Distance(aPnt2); | |
1177 | Standard_Real TolE1 = BRep_Tool::Tolerance(iE1); | |
1178 | Standard_Real TolE2 = BRep_Tool::Tolerance(iE2); | |
1179 | if( dist > (/*TolV+*/TolE1+TolE2) ) { | |
1180 | changeFlag = Standard_False; | |
1181 | break; | |
1182 | } | |
1183 | } | |
1184 | if( changeFlag ) bNegativeFlag = 0; | |
1185 | } | |
1186 | } | |
1187 | } | |
1188 | ||
1189 | // | |
1190 | return bFlag; | |
1191 | } | |
1192 | ||
1193 | //======================================================================= | |
1194 | // function: PointNearE | |
1195 | // purpose: | |
1196 | //======================================================================= | |
1197 | void PointNearE (const TopoDS_Edge& aE, | |
1198 | const TopoDS_Face& aF, | |
1199 | const Standard_Real aT, | |
1200 | gp_Pnt& aPInFace, | |
1201 | const Standard_Boolean aSt) | |
1202 | { | |
1203 | Standard_Real aT1, aT2; | |
1204 | // | |
1205 | // 1. a Point on Edge aPOnEdge | |
1206 | Handle(Geom_Curve)aC=BRep_Tool::Curve(aE, aT1, aT2); | |
1207 | gp_Pnt aPOnEdge; | |
1208 | gp_Pnt2d aPInFace2D; | |
1209 | // | |
1210 | aC->D0 (aT, aPOnEdge); | |
1211 | // | |
1212 | // 2. a Point inside Face near aPOnEdge aPInFace; | |
1213 | TopoDS_Face aFF=aF; | |
1214 | TopoDS_Edge aERight; | |
1215 | aFF.Orientation(TopAbs_FORWARD); | |
1216 | BOPTools_Tools3D::OrientEdgeOnFace (aE, aFF, aERight); | |
1217 | // | |
1218 | // | |
1219 | Standard_Real aTolE, aDt2D; | |
1220 | GeomAbs_SurfaceType aType; | |
1221 | { | |
1222 | aDt2D=BOPTools_Tools3D::MinStepIn2d(); | |
1223 | // | |
1224 | Handle(Geom_Surface) aS=BRep_Tool::Surface(aFF); | |
1225 | GeomAdaptor_Surface aGASF(aS); | |
1226 | aType=aGASF.GetType(); | |
1227 | if (aType==GeomAbs_Plane) { | |
1228 | aTolE=BRep_Tool::Tolerance(aE); | |
1229 | if (aTolE>aDt2D) { | |
1230 | aDt2D=aTolE; | |
1231 | } | |
1232 | } | |
1233 | ||
1234 | } | |
1235 | ||
1236 | //-- EJG | |
1237 | if( aSt ) | |
1238 | if( aDt2D < 1.e-4) | |
1239 | aDt2D *= 10.; | |
1240 | //-- EJG | |
1241 | ||
1242 | // | |
1243 | BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aDt2D, aPInFace2D, aPInFace); | |
1244 | // | |
1245 | if (BRep_Tool::IsClosed(aE, aF)) { | |
1246 | Standard_Real X, Y, UMin, UMax, VMin, VMax; | |
1247 | X=aPInFace2D.X(); | |
1248 | Y=aPInFace2D.Y(); | |
1249 | BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax); | |
1250 | if (!(X >= UMin && X <= UMax && Y >= VMin && Y <= VMax)) { | |
1251 | aERight.Reverse(); | |
1252 | BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace); | |
1253 | } | |
1254 | } | |
1255 | ||
1256 | } | |
1257 | ||
1258 | static Standard_Boolean PseudoSDFaces(const BRepAdaptor_Surface& BS1, | |
1259 | const BRepAdaptor_Surface& BS2) | |
1260 | { | |
1261 | Standard_Real TolF1 = BS1.Tolerance(); | |
1262 | Standard_Real TolF2 = BS2.Tolerance(); | |
1263 | ||
1264 | gp_Pln Pln1 = BS1.Plane(); | |
1265 | gp_Pln Pln2 = BS2.Plane(); | |
1266 | ||
1267 | TopExp_Explorer anExpE; | |
1268 | Standard_Real pF = 0., pL = 0.; | |
1269 | ||
1270 | ||
1271 | const TopoDS_Face& aF1 = BS1.Face(); | |
6e6cd5d9 | 1272 | Standard_Real maxTolE1 = 1.e-7; |
7fd59977 | 1273 | Standard_Integer nbE1 = 0, nbOnE1 = 0; |
1274 | for(anExpE.Init(aF1, TopAbs_EDGE); anExpE.More(); anExpE.Next()) { | |
1275 | const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current()); | |
1276 | nbE1++; | |
1277 | Standard_Real aTolE = BRep_Tool::Tolerance(aE); | |
1278 | if( aTolE > maxTolE1 ) maxTolE1 = aTolE; | |
1279 | Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, pF, pL); | |
1280 | if( !aC3D.IsNull() ) { | |
1281 | Standard_Real pM = BOPTools_Tools2D::IntermediatePoint(pF, pL); | |
1282 | gp_Pnt mPnt = aC3D->Value(pM); | |
1283 | Standard_Real distMP = Pln2.Distance(mPnt); | |
1284 | ||
1285 | if( distMP <= aTolE ) | |
1286 | nbOnE1++; | |
1287 | else { | |
1288 | TopoDS_Vertex Vf, Vl; | |
1289 | TopExp::Vertices(aE,Vf,Vl); | |
1290 | if( !Vf.IsNull() && !Vl.IsNull() ) { | |
1291 | Standard_Real aTolVf = BRep_Tool::Tolerance(Vf); | |
1292 | Standard_Real aTolVl = BRep_Tool::Tolerance(Vl); | |
1293 | gp_Pnt aPntF = BRep_Tool::Pnt(Vf); | |
1294 | gp_Pnt aPntL = BRep_Tool::Pnt(Vl); | |
1295 | Standard_Real distF = Pln2.Distance(aPntF); | |
1296 | Standard_Real distL = Pln2.Distance(aPntL); | |
1297 | if( distF <= aTolVf && distL <= aTolVl ) | |
1298 | nbOnE1++; | |
1299 | } | |
1300 | else if( !Vf.IsNull() && Vl.IsNull() ) { | |
1301 | Standard_Real aTolVf = BRep_Tool::Tolerance(Vf); | |
1302 | gp_Pnt aPntF = BRep_Tool::Pnt(Vf); | |
1303 | Standard_Real distF = Pln2.Distance(aPntF); | |
1304 | if( distF <= aTolVf ) | |
1305 | nbOnE1++; | |
1306 | } | |
1307 | else if( Vf.IsNull() && !Vl.IsNull() ) { | |
1308 | Standard_Real aTolVl = BRep_Tool::Tolerance(Vl); | |
1309 | gp_Pnt aPntL = BRep_Tool::Pnt(Vl); | |
1310 | Standard_Real distL = Pln2.Distance(aPntL); | |
1311 | if( distL <= aTolVl ) | |
1312 | nbOnE1++; | |
1313 | } | |
1314 | else | |
1315 | continue; | |
1316 | } | |
1317 | } | |
1318 | } | |
1319 | ||
1320 | Standard_Boolean procF1 = ((maxTolE1/TolF1) >= 1000. || | |
1321 | (TolF1/maxTolE1) >= 1000.) ? Standard_True : Standard_False; | |
1322 | procF1 = (procF1 && (nbE1 > 1 && nbOnE1 > 1) ); | |
1323 | ||
1324 | if( !procF1 ) | |
1325 | return Standard_False; | |
1326 | ||
1327 | const TopoDS_Face& aF2 = BS1.Face(); | |
6e6cd5d9 | 1328 | Standard_Real maxTolE2 = 1.e-7; |
7fd59977 | 1329 | Standard_Integer nbE2 = 0, nbOnE2 = 0; |
1330 | for(anExpE.Init(aF2, TopAbs_EDGE); anExpE.More(); anExpE.Next()) { | |
1331 | const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current()); | |
1332 | nbE2++; | |
1333 | Standard_Real aTolE = BRep_Tool::Tolerance(aE); | |
1334 | if( aTolE > maxTolE2 ) maxTolE2 = aTolE; | |
1335 | Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, pF, pL); | |
1336 | if( !aC3D.IsNull() ) { | |
1337 | Standard_Real pM = BOPTools_Tools2D::IntermediatePoint(pF, pL); | |
1338 | gp_Pnt mPnt = aC3D->Value(pM); | |
1339 | Standard_Real distMP = Pln1.Distance(mPnt); | |
1340 | if( distMP <= aTolE ) | |
1341 | nbOnE2++; | |
1342 | else { | |
1343 | TopoDS_Vertex Vf, Vl; | |
1344 | TopExp::Vertices(aE,Vf,Vl); | |
1345 | if( !Vf.IsNull() && !Vl.IsNull() ) { | |
1346 | Standard_Real aTolVf = BRep_Tool::Tolerance(Vf); | |
1347 | Standard_Real aTolVl = BRep_Tool::Tolerance(Vl); | |
1348 | gp_Pnt aPntF = BRep_Tool::Pnt(Vf); | |
1349 | gp_Pnt aPntL = BRep_Tool::Pnt(Vl); | |
1350 | Standard_Real distF = Pln1.Distance(aPntF); | |
1351 | Standard_Real distL = Pln1.Distance(aPntL); | |
1352 | if( distF <= aTolVf && distL <= aTolVl ) | |
1353 | nbOnE2++; | |
1354 | } | |
1355 | else if( !Vf.IsNull() && Vl.IsNull() ) { | |
1356 | Standard_Real aTolVf = BRep_Tool::Tolerance(Vf); | |
1357 | gp_Pnt aPntF = BRep_Tool::Pnt(Vf); | |
1358 | Standard_Real distF = Pln1.Distance(aPntF); | |
1359 | if( distF <= aTolVf ) | |
1360 | nbOnE2++; | |
1361 | } | |
1362 | else if( Vf.IsNull() && !Vl.IsNull() ) { | |
1363 | Standard_Real aTolVl = BRep_Tool::Tolerance(Vl); | |
1364 | gp_Pnt aPntL = BRep_Tool::Pnt(Vl); | |
1365 | Standard_Real distL = Pln1.Distance(aPntL); | |
1366 | if( distL <= aTolVl ) | |
1367 | nbOnE2++; | |
1368 | } | |
1369 | else | |
1370 | continue; | |
1371 | } | |
1372 | } | |
1373 | } | |
1374 | ||
1375 | Standard_Boolean procF2 = ((maxTolE2/TolF2) >= 1000. || | |
1376 | (TolF2/maxTolE2) >= 1000.) ? Standard_True : Standard_False; | |
1377 | procF2 = (procF2 && (nbE2 > 1 && nbOnE2 > 1) ); | |
1378 | ||
1379 | return (procF1 && procF2); | |
1380 | ||
1381 | } | |
1382 | ||
1383 | Standard_Boolean CheckKeepArguments(const TopoDS_Face& F1, | |
1384 | const TopoDS_Face& F2, | |
1385 | const TopoDS_Face& F3) | |
1386 | { | |
1387 | BRepAdaptor_Surface aBS1(F1); | |
1388 | BRepAdaptor_Surface aBS2(F2); | |
1389 | BRepAdaptor_Surface aBS3(F3); | |
1390 | ||
1391 | GeomAbs_SurfaceType aT1 = aBS1.GetType(); | |
1392 | GeomAbs_SurfaceType aT2 = aBS2.GetType(); | |
1393 | GeomAbs_SurfaceType aT3 = aBS3.GetType(); | |
1394 | ||
1395 | if(aT1 == GeomAbs_Cylinder || | |
1396 | aT1 == GeomAbs_Cone || | |
1397 | aT1 == GeomAbs_Sphere || | |
1398 | aT1 == GeomAbs_Torus ) return Standard_True; | |
1399 | ||
1400 | if(aT2 == GeomAbs_Cylinder || | |
1401 | aT2 == GeomAbs_Cone || | |
1402 | aT3 == GeomAbs_Sphere || | |
1403 | aT3 == GeomAbs_Torus ) return Standard_True; | |
1404 | ||
1405 | if(aT3 == GeomAbs_Cylinder || | |
1406 | aT3 == GeomAbs_Cone || | |
1407 | aT3 == GeomAbs_Sphere || | |
1408 | aT3 == GeomAbs_Torus ) return Standard_True; | |
1409 | ||
1410 | if( aT1 == GeomAbs_Plane && aT2 == GeomAbs_Plane ) { | |
1411 | if( PseudoSDFaces(aBS1, aBS2) ) | |
1412 | return Standard_False; | |
1413 | } | |
1414 | else if( aT1 == GeomAbs_Plane && aT3 == GeomAbs_Plane ) { | |
1415 | if( PseudoSDFaces(aBS1, aBS3) ) | |
1416 | return Standard_False; | |
1417 | } | |
1418 | else if( aT2 == GeomAbs_Plane && aT3 == GeomAbs_Plane ) { | |
1419 | if( PseudoSDFaces(aBS2, aBS3) ) | |
1420 | return Standard_False; | |
1421 | } | |
1422 | else | |
1423 | return Standard_True; | |
1424 | return Standard_True; | |
1425 | } |