0024832: Performance of new boolean operations has become worse
[occt.git] / src / BOPTools / BOPTools_AlgoTools.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 OPEN CASCADE SAS
4e57c75e 3// Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4// Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5// EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6//
973c2be1 7// This file is part of Open CASCADE Technology software library.
4e57c75e 8//
d5f74e42 9// This library is free software; you can redistribute it and/or modify it under
10// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 11// by the Free Software Foundation, with special exception defined in the file
12// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13// distribution for complete text of the license and disclaimer of any warranty.
4e57c75e 14//
973c2be1 15// Alternatively, this file may be used under the terms of Open CASCADE
16// commercial license or contractual agreement.
4e57c75e 17
18#include <BOPTools_AlgoTools.ixx>
19//
20#include <Precision.hxx>
21//
22#include <gp_Pnt.hxx>
23#include <gp_XYZ.hxx>
24#include <gp_Pnt2d.hxx>
df017cc9 25#include <gp_Cylinder.hxx>
26#include <gp_Cone.hxx>
27#include <gp_Sphere.hxx>
28#include <gp_Torus.hxx>
b92a64cc 29#include <gp_Lin.hxx>
4e57c75e 30//
31#include <Geom2d_Curve.hxx>
32#include <Geom_Surface.hxx>
df017cc9 33#include <Geom_Plane.hxx>
4e57c75e 34#include <Geom_TrimmedCurve.hxx>
35#include <Geom_Curve.hxx>
36#include <GeomAPI_ProjectPointOnSurf.hxx>
37#include <Geom2dInt_Geom2dCurveTool.hxx>
38//
39#include <TopAbs_Orientation.hxx>
40//
41#include <TopoDS_Compound.hxx>
42#include <TopoDS_CompSolid.hxx>
43#include <TopoDS_Solid.hxx>
44#include <TopoDS_Shell.hxx>
45#include <TopoDS_Wire.hxx>
46//
47#include <BRep_Builder.hxx>
48#include <BRep_Tool.hxx>
49#include <BRepLib.hxx>
50#include <BRepAdaptor_Curve2d.hxx>
bb58e462 51#include <BRepAdaptor_Surface.hxx>
4e57c75e 52#include <BRepClass3d_SolidClassifier.hxx>
53#include <TopExp.hxx>
54#include <TopExp_Explorer.hxx>
55//
56#include <IntTools_Tools.hxx>
57//
df017cc9 58#include <BOPTools.hxx>
59#include <BOPTools_CoupleOfShape.hxx>
60#include <BOPTools_ListOfCoupleOfShape.hxx>
4e57c75e 61#include <BOPTools_AlgoTools2D.hxx>
62#include <BOPTools_AlgoTools3D.hxx>
63//
64#include <BOPCol_IndexedMapOfShape.hxx>
65#include <BOPCol_MapOfShape.hxx>
66//
4e57c75e 67#include <BOPInt_ShrunkRange.hxx>
df017cc9 68//
4e57c75e 69
70static
71 Standard_Real AngleWithRef(const gp_Dir& theD1,
72 const gp_Dir& theD2,
73 const gp_Dir& theDRef);
4e57c75e 74
75static
76 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
77 const BOPCol_ListOfShape& thLF,
78 BOPTools_ListOfCoupleOfShape& theLCFF,
79 Handle(BOPInt_Context)& theContext);
80static
81 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
82 const TopoDS_Face& aF);
83
bb58e462 84static
df017cc9 85 void GetFaceDir(const TopoDS_Edge& aE,
86 const TopoDS_Face& aF,
87 const gp_Pnt& aP,
88 const Standard_Real aT,
89 const gp_Dir& aDTgt,
90 gp_Dir& aDN,
91 gp_Dir& aDB,
bb58e462 92 Handle(BOPInt_Context)& theContext,
93 GeomAPI_ProjectPointOnSurf& aProjPL);
94static
df017cc9 95 Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
96 const TopoDS_Face& aF,
97 const gp_Pnt& aP,
df017cc9 98 gp_Dir& aDB,
99 gp_Pnt& aPOut,
100 Handle(BOPInt_Context)& theContext,
bb58e462 101 GeomAPI_ProjectPointOnSurf& aProjPL);
4e57c75e 102
103//=======================================================================
104// function: MakeConnexityBlocks
105// purpose:
106//=======================================================================
505abfb8 107void BOPTools_AlgoTools::MakeConnexityBlocks
108 (const TopoDS_Shape& theS,
109 const TopAbs_ShapeEnum theType1,
110 const TopAbs_ShapeEnum theType2,
111 BOPCol_ListOfShape& theLCB)
4e57c75e 112{
113 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
114 BRep_Builder aBB;
115 TopoDS_Compound aC;
116 TopoDS_Iterator aIt;
117 TopExp_Explorer aExp;
118 BOPCol_MapOfShape aMP;
119 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
120 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
121 BOPCol_ListIteratorOfListOfShape aItLF;
122 //
123 // 1. aMEF
124 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
125 //
126 // 2. aMCB
127 aIt.Initialize(theS);
128 for (; aIt.More(); aIt.Next()) {
129 const TopoDS_Shape& aF1=aIt.Value();
130 if (aMP.Contains(aF1)) {
131 continue;
132 }
133 //
134 aMCB.Clear();
135 aMAdd.Clear();
136 aMAdd.Add(aF1);
137 //
302f96fb 138 for(;;) {
4e57c75e 139 aMAdd1.Clear();
140 //
141 aNbAdd = aMAdd.Extent();
142 for (i=1; i<=aNbAdd; ++i) {
143 const TopoDS_Shape& aF=aMAdd(i);
144 //
145 aExp.Init(aF, theType1);
146 for (; aExp.More(); aExp.Next()) {
147 const TopoDS_Shape& aE=aExp.Current();
148 //
149 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
150 aItLF.Initialize(aLF);
151 for (; aItLF.More(); aItLF.Next()) {
152 const TopoDS_Shape& aFx=aItLF.Value();
153 if (aFx.IsSame(aF)) {
154 continue;
155 }
156 if (aMCB.Contains(aFx)) {
157 continue;
158 }
159 aMAdd1.Add(aFx);
160 }
161 }//for (; aExp.More(); aExp.Next()){
162 aMCB.Add(aF);
163 }// for (i=1; i<=aNbAdd; ++i) {
164 //
165 aNbAdd1=aMAdd1.Extent();
166 if (!aNbAdd1) {
167 break;// ->make new CB from aMCB
168 }
169 //
170 aMAdd.Clear();
171 for (i=1; i<=aNbAdd1; ++i) {
172 const TopoDS_Shape& aFAdd = aMAdd1(i);
173 aMAdd.Add(aFAdd);
174 }
175 }//while(1) {
176 //
177 aNbF=aMCB.Extent();
178 if (aNbF) {
179 aBB.MakeCompound(aC);
180 //
181 for (i=1; i<=aNbF; ++i) {
182 const TopoDS_Shape& aF=aMCB(i);
183 aBB.Add(aC, aF);
184 aMP.Add(aF);
185 }
186 theLCB.Append(aC);
187 }
188 }// for (; aIt.More(); aIt.Next())
189}
190//=======================================================================
191// function: OrientFacesOnShell
192// purpose:
193//=======================================================================
744511c8 194void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
4e57c75e 195{
196 Standard_Boolean bIsProcessed1, bIsProcessed2;
197 Standard_Integer i, aNbE, aNbF, j;
198 TopAbs_Orientation anOrE1, anOrE2;
199 TopoDS_Face aF1x, aF2x;
200 TopoDS_Shape aShellNew;
201 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
202 BOPCol_IndexedMapOfShape aProcessedFaces;
203 BRep_Builder aBB;
204 //
205 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
206 //
505abfb8 207 BOPTools::MapShapesAndAncestors(aShell,
208 TopAbs_EDGE, TopAbs_FACE,
209 aEFMap);
4e57c75e 210 aNbE=aEFMap.Extent();
211 //
212 // One seam edge in aEFMap contains 2 equivalent faces.
213 for (i=1; i<=aNbE; ++i) {
214 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
215 aNbF=aLF.Extent();
216 if (aNbF>1) {
217 BOPCol_ListOfShape aLFTmp;
218 BOPCol_IndexedMapOfShape aFM;
219 //
220 BOPCol_ListIteratorOfListOfShape anIt(aLF);
221 for (; anIt.More(); anIt.Next()) {
222 const TopoDS_Shape& aF=anIt.Value();
223 if (!aFM.Contains(aF)) {
224 aFM.Add(aF);
225 aLFTmp.Append(aF);
226 }
227 }
228 aLF.Clear();
229 aLF=aLFTmp;
230 }
231 }
232 //
233 // Do
234 for (i=1; i<=aNbE; ++i) {
235 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
236 if (BRep_Tool::Degenerated(aE)) {
237 continue;
238 }
239 //
240 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
241 aNbF=aLF.Extent();
242 if (aNbF!=2) {
243 continue;
244 }
245 //
246 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
247 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
248 //
249 bIsProcessed1=aProcessedFaces.Contains(aF1);
250 bIsProcessed2=aProcessedFaces.Contains(aF2);
251 if (bIsProcessed1 && bIsProcessed2) {
252 continue;
253 }
254
255 if (!bIsProcessed1 && !bIsProcessed2) {
256 aProcessedFaces.Add(aF1);
257 aBB.Add(aShellNew, aF1);
258 bIsProcessed1=!bIsProcessed1;
259 }
260 //
261 aF1x=aF1;
262 if (bIsProcessed1) {
263 j=aProcessedFaces.FindIndex(aF1);
264 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
265 }
266 //
267 aF2x=aF2;
268 if (bIsProcessed2) {
269 j=aProcessedFaces.FindIndex(aF2);
270 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
271 }
272 //
273 anOrE1=Orientation(aE, aF1x);
274 anOrE2=Orientation(aE, aF2x);
275 //
276 if (bIsProcessed1 && !bIsProcessed2) {
277 if (anOrE1==anOrE2) {
278 if (!BRep_Tool::IsClosed(aE, aF1) &&
279 !BRep_Tool::IsClosed(aE, aF2)) {
280 aF2.Reverse();
281 }
282 }
283 aProcessedFaces.Add(aF2);
284 aBB.Add(aShellNew, aF2);
285 }
286 else if (!bIsProcessed1 && bIsProcessed2) {
287 if (anOrE1==anOrE2) {
288 if (!BRep_Tool::IsClosed(aE, aF1) &&
289 !BRep_Tool::IsClosed(aE, aF2)) {
290 aF1.Reverse();
291 }
292 }
293 aProcessedFaces.Add(aF1);
294 aBB.Add(aShellNew, aF1);
295 }
296 }
297 //
298 //
299 for (i=1; i<=aNbE; ++i) {
300 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
301 if (BRep_Tool::Degenerated(aE)) {
302 continue;
303 }
304 //
305 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
306 aNbF=aLF.Extent();
307 if (aNbF!=2) {
308 BOPCol_ListIteratorOfListOfShape anIt(aLF);
309 for(; anIt.More(); anIt.Next()) {
310 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
311 if (!aProcessedFaces.Contains(aF)) {
312 aProcessedFaces.Add(aF);
313 aBB.Add(aShellNew, aF);
314 }
315 }
316 }
317 }
318 aShell=aShellNew;
319}
320//=======================================================================
321//function : Orientation
322//purpose :
323//=======================================================================
744511c8 324TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
bb58e462 325 const TopoDS_Face& aF)
4e57c75e 326{
327 TopAbs_Orientation anOr=TopAbs_INTERNAL;
328
329 TopExp_Explorer anExp;
330 anExp.Init(aF, TopAbs_EDGE);
331 for (; anExp.More(); anExp.Next()) {
332 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
333 if (anEF1.IsSame(anE)) {
334 anOr=anEF1.Orientation();
335 break;
336 }
337 }
338 return anOr;
339}
4e57c75e 340//=======================================================================
341// function: MakeConnexityBlock.
342// purpose:
343//=======================================================================
505abfb8 344void BOPTools_AlgoTools::MakeConnexityBlock
345 (BOPCol_ListOfShape& theLFIn,
346 BOPCol_IndexedMapOfShape& theMEAvoid,
347 BOPCol_ListOfShape& theLCB,
348 const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 349{
350 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
351 TopExp_Explorer aExp;
352 BOPCol_ListIteratorOfListOfShape aIt;
353 //
354 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
355 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
356 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
357 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
358 //
359 // 1. aMEF
360 aNbF=theLFIn.Extent();
361 aIt.Initialize(theLFIn);
362 for (; aIt.More(); aIt.Next()) {
363 const TopoDS_Shape& aF=aIt.Value();
364 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
365 }
366 //
367 // 2. aMCB
368 const TopoDS_Shape& aF1=theLFIn.First();
369 aMAdd.Add(aF1);
370 //
302f96fb 371 for(;;) {
4e57c75e 372 aMAdd1.Clear();
373 aNbAdd = aMAdd.Extent();
374 for (i=1; i<=aNbAdd; ++i) {
375 const TopoDS_Shape& aF=aMAdd(i);
376 //
377 //aMAdd1.Clear();
378 aExp.Init(aF, TopAbs_EDGE);
379 for (; aExp.More(); aExp.Next()) {
380 const TopoDS_Shape& aE=aExp.Current();
381 if (theMEAvoid.Contains(aE)){
382 continue;
383 }
384 //
385 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
386 aIt.Initialize(aLF);
387 for (; aIt.More(); aIt.Next()) {
388 const TopoDS_Shape& aFx=aIt.Value();
389 if (aFx.IsSame(aF)) {
390 continue;
391 }
392 if (aMCB.Contains(aFx)) {
393 continue;
394 }
395 aMAdd1.Add(aFx);
396 }
397 }//for (; aExp.More(); aExp.Next()){
398 aMCB.Add(aF);
399 }// for (i=1; i<=aNbAdd; ++i) {
400 //
401 aNbAdd1=aMAdd1.Extent();
402 if (!aNbAdd1) {
403 break;
404 }
405 //
406 aMAdd.Clear();
407 for (i=1; i<=aNbAdd1; ++i) {
408 const TopoDS_Shape& aFAdd=aMAdd1(i);
409 aMAdd.Add(aFAdd);
410 }
411 //
412 }//while(1) {
413
414 //
415 aNbF=aMCB.Extent();
416 for (i=1; i<=aNbF; ++i) {
417 const TopoDS_Shape& aF=aMCB(i);
418 theLCB.Append(aF);
419 }
420}
421//=======================================================================
422// function: ComputeStateByOnePoint
423// purpose:
424//=======================================================================
505abfb8 425TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
426 (const TopoDS_Shape& theS,
427 const TopoDS_Solid& theRef,
428 const Standard_Real theTol,
429 Handle(BOPInt_Context)& theContext)
4e57c75e 430{
431 TopAbs_State aState;
432 TopAbs_ShapeEnum aType;
433 //
434 aState=TopAbs_UNKNOWN;
435 aType=theS.ShapeType();
436 if (aType==TopAbs_VERTEX) {
437 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
438 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
439 }
440 else if (aType==TopAbs_EDGE) {
441 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
442 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
443 }
444 return aState;
445}
446
447//=======================================================================
448// function: ComputeState
449// purpose:
450//=======================================================================
505abfb8 451TopAbs_State BOPTools_AlgoTools::ComputeState
452 (const TopoDS_Face& theF,
453 const TopoDS_Solid& theRef,
454 const Standard_Real theTol,
455 BOPCol_IndexedMapOfShape& theBounds,
456 Handle(BOPInt_Context)& theContext)
4e57c75e 457{
458 TopAbs_State aState;
459 TopExp_Explorer aExp;
460 TopoDS_Edge aE1;
461 gp_Pnt2d aP2D;
462 gp_Pnt aP3D;
463 //
464 aState=TopAbs_UNKNOWN;
465 //
466 aExp.Init(theF, TopAbs_EDGE);
467 for (; aExp.More(); aExp.Next()) {
468 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
469 if (BRep_Tool::Degenerated(aSE)) {
470 continue;
471 }
472 //
473 if (!theBounds.Contains(aSE)) {
474 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
505abfb8 475 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol,
476 theContext);
4e57c75e 477 return aState;
478 }
479 if (aE1.IsNull()) {
480 aE1=(*(TopoDS_Edge*)(&aSE));
481 }
482 }
483 // !!<- process edges that are all on theRef
484 if (!aE1.IsNull()) {
505abfb8 485 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
486 aP2D, aP3D, theContext);
487 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
488 theContext);
4e57c75e 489 }
490 //
491 return aState;
492}
493//=======================================================================
494// function: ComputeState
495// purpose:
496//=======================================================================
505abfb8 497TopAbs_State BOPTools_AlgoTools::ComputeState
498 (const TopoDS_Vertex& theV,
499 const TopoDS_Solid& theRef,
500 const Standard_Real theTol,
501 Handle(BOPInt_Context)& theContext)
4e57c75e 502{
503 TopAbs_State aState;
504 gp_Pnt aP3D;
505 //
506 aP3D=BRep_Tool::Pnt(theV);
505abfb8 507 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
508 theContext);
4e57c75e 509 return aState;
510}
511//=======================================================================
512// function: ComputeState
513// purpose:
514//=======================================================================
505abfb8 515TopAbs_State BOPTools_AlgoTools::ComputeState
516 (const TopoDS_Edge& theE,
517 const TopoDS_Solid& theRef,
518 const Standard_Real theTol,
519 Handle(BOPInt_Context)& theContext)
4e57c75e 520{
521 Standard_Real aT1, aT2, aT = 0.;
522 TopAbs_State aState;
523 Handle(Geom_Curve) aC3D;
524 gp_Pnt aP3D;
525 //
526 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
527 //
528 if(aC3D.IsNull()) {
529 //it means that we are in degenerated edge
530 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
531 if(aV.IsNull()){
532 return TopAbs_UNKNOWN;
533 }
534 aP3D=BRep_Tool::Pnt(aV);
535 }
536 else {//usual case
537 Standard_Boolean bF2Inf, bL2Inf;
538 Standard_Real dT=10.;
539 //
540 bF2Inf = Precision::IsNegativeInfinite(aT1);
541 bL2Inf = Precision::IsPositiveInfinite(aT2);
542 //
543 if (bF2Inf && !bL2Inf) {
544 aT=aT2-dT;
545 }
546 else if (!bF2Inf && bL2Inf) {
547 aT=aT1+dT;
548 }
549 else if (bF2Inf && bL2Inf) {
550 aT=0.;
551 }
552 else {
553 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
554 }
555 aC3D->D0(aT, aP3D);
556 }
557 //
505abfb8 558 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
559 theContext);
4e57c75e 560 //
561 return aState;
562}
563//=======================================================================
564// function: ComputeState
565// purpose:
566//=======================================================================
505abfb8 567TopAbs_State BOPTools_AlgoTools::ComputeState
568 (const gp_Pnt& theP,
569 const TopoDS_Solid& theRef,
570 const Standard_Real theTol,
571 Handle(BOPInt_Context)& theContext)
4e57c75e 572{
573 TopAbs_State aState;
574 //
575 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
576 aSC.Perform(theP, theTol);
577 //
578 aState=aSC.State();
579 //
580 return aState;
581}
582//=======================================================================
583//function : IsInternalFace
584//purpose :
585//=======================================================================
744511c8 586Standard_Integer BOPTools_AlgoTools::IsInternalFace
587 (const TopoDS_Face& theFace,
588 const TopoDS_Solid& theSolid,
589 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
590 const Standard_Real theTol,
591 Handle(BOPInt_Context)& theContext)
4e57c75e 592{
744511c8 593 Standard_Boolean bDegenerated;
594 Standard_Integer aNbF, iRet, iFound;
4e57c75e 595 TopAbs_Orientation aOr;
744511c8 596 TopoDS_Edge aE1;
4e57c75e 597 TopExp_Explorer aExp;
598 BOPCol_ListIteratorOfListOfShape aItF;
599 //
744511c8 600 // For all invoked functions: [::IsInternalFace(...)]
601 // the returned value iRet means:
602 // iRet=0; - state is not IN
603 // iRet=1; - state is IN
604 // iRet=2; - state can not be found by the method of angles
605 //
606 // For this function the returned value iRet means:
607 // iRet=0; - state is not IN
608 // iRet=1; - state is IN
4e57c75e 609 //
744511c8 610 iRet=0;
4e57c75e 611 // 1 Try to find an edge from theFace in theMEF
744511c8 612 iFound=0;
4e57c75e 613 aExp.Init(theFace, TopAbs_EDGE);
614 for(; aExp.More(); aExp.Next()) {
615 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
616 if (!theMEF.Contains(aE)) {
617 continue;
618 }
619 //
744511c8 620 ++iFound;
621 //
4e57c75e 622 aOr=aE.Orientation();
623 if (aOr==TopAbs_INTERNAL) {
624 continue;
625 }
626 bDegenerated=BRep_Tool::Degenerated(aE);
627 if (bDegenerated){
628 continue;
629 }
630 // aE
631 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
632 aNbF=aLF.Extent();
633 if (!aNbF) {
744511c8 634 return iRet; // it can not be so
4e57c75e 635 }
744511c8 636 //
4e57c75e 637 else if (aNbF==1) {
638 // aE is internal edge on aLF.First()
639 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
744511c8 640 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
641 if (aE1.Orientation()!=TopAbs_INTERNAL) {
bb58e462 642 iRet=2;
643 break;
744511c8 644 }
645 //
505abfb8 646 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1,
647 theContext);
744511c8 648 break;
4e57c75e 649 }
744511c8 650 //
4e57c75e 651 else if (aNbF==2) {
652 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
653 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
654 //
655 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
656 // treat as it was for 1 face
505abfb8 657 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
658 theContext);
bb58e462 659 break;
4e57c75e 660 }
661 }
744511c8 662 //
4e57c75e 663 if (aNbF%2) {
744511c8 664 iRet=0;
665 return iRet; // it can not be so
4e57c75e 666 }
667 else { // aNbF=2,4,6,8,...
505abfb8 668 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF,
669 theContext);
744511c8 670 break;
4e57c75e 671 }
672 }//for(; aExp.More(); aExp.Next()) {
673 //
744511c8 674 if (!iFound) {
675 // the face has no shared edges with the solid
676 iRet=2;
677 }
678 //
679 if (iRet!=2) {
680 return iRet;
681 }
682 //
4e57c75e 683 //========================================
684 // 2. Classify face using classifier
685 //
686 TopAbs_State aState;
687 BOPCol_IndexedMapOfShape aBounds;
688 //
744511c8 689 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
690 //
505abfb8 691 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid,
692 theTol, aBounds, theContext);
4e57c75e 693 //
744511c8 694 iRet=(aState==TopAbs_IN)? 1 : 0;
695 //
696 return iRet;
4e57c75e 697}
698//=======================================================================
699//function : IsInternalFace
700//purpose :
701//=======================================================================
505abfb8 702Standard_Integer BOPTools_AlgoTools::IsInternalFace
703 (const TopoDS_Face& theFace,
704 const TopoDS_Edge& theEdge,
705 BOPCol_ListOfShape& theLF,
706 Handle(BOPInt_Context)& theContext)
4e57c75e 707{
744511c8 708 Standard_Integer aNbF, iRet;
4e57c75e 709 //
744511c8 710 iRet=0;
4e57c75e 711 //
712 aNbF=theLF.Extent();
713 if (aNbF==2) {
714 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
715 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
505abfb8 716 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
717 theContext);
744511c8 718 return iRet;
4e57c75e 719 }
720 //
721 else {
722 BOPTools_ListOfCoupleOfShape aLCFF;
723 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
724 //
725 FindFacePairs(theEdge, theLF, aLCFF, theContext);
726 //
727 aIt.Initialize(aLCFF);
728 for (; aIt.More(); aIt.Next()) {
729 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
730 //
731 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
732 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
505abfb8 733 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
734 theContext);
744511c8 735 if (iRet) {
736 return iRet;
4e57c75e 737 }
738 }
739 }
744511c8 740 return iRet;
4e57c75e 741}
742//=======================================================================
743//function : IsInternalFace
744//purpose :
745//=======================================================================
744511c8 746Standard_Integer BOPTools_AlgoTools::IsInternalFace
747 (const TopoDS_Face& theFace,
748 const TopoDS_Edge& theEdge,
749 const TopoDS_Face& theFace1,
750 const TopoDS_Face& theFace2,
751 Handle(BOPInt_Context)& theContext)
4e57c75e 752{
753 Standard_Boolean bRet;
744511c8 754 Standard_Integer iRet;
4e57c75e 755 TopoDS_Edge aE1, aE2;
756 TopoDS_Face aFOff;
757 BOPTools_ListOfCoupleOfShape theLCSOff;
758 BOPTools_CoupleOfShape aCS1, aCS2;
759 //
760 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
761 if (aE1.Orientation()==TopAbs_INTERNAL) {
762 aE2=aE1;
763 aE1.Orientation(TopAbs_FORWARD);
764 aE2.Orientation(TopAbs_REVERSED);
765 }
766 else if (theFace1==theFace2) {
767 aE2=aE1;
768 aE1.Orientation(TopAbs_FORWARD);
769 aE2.Orientation(TopAbs_REVERSED);
770 }
771 else {
772 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
773 }
774 //
775 aCS1.SetShape1(theEdge);
776 aCS1.SetShape2(theFace);
777 theLCSOff.Append(aCS1);
778 //
779 aCS2.SetShape1(aE2);
780 aCS2.SetShape2(theFace2);
781 theLCSOff.Append(aCS2);
782 //
744511c8 783 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
4e57c75e 784 //
744511c8 785 iRet=0; // theFace is not internal
786 if (theFace.IsEqual(aFOff)) {
787 // theFace is internal
788 iRet=1;
789 if (!bRet) {
790 // theFace seems to be internal
791 iRet=2;
792 }
793 }
794 return iRet;
4e57c75e 795}
796//=======================================================================
797//function : GetFaceOff
798//purpose :
799//=======================================================================
744511c8 800Standard_Boolean BOPTools_AlgoTools::GetFaceOff
801 (const TopoDS_Edge& theE1,
802 const TopoDS_Face& theF1,
803 BOPTools_ListOfCoupleOfShape& theLCSOff,
804 TopoDS_Face& theFOff,
805 Handle(BOPInt_Context)& theContext)
4e57c75e 806{
744511c8 807 Standard_Boolean bRet;
4e57c75e 808 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
bb58e462 809 Standard_Real aUmin, aUsup, aVmin, aVsup;
4e57c75e 810 gp_Pnt aPn1, aPn2, aPx;
df017cc9 811 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
4e57c75e 812 gp_Vec aVTgt;
df017cc9 813 TopAbs_Orientation aOr;
4e57c75e 814 Handle(Geom_Curve)aC3D;
bb58e462 815 Handle(Geom_Plane) aPL;
4e57c75e 816 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
bb58e462 817 GeomAPI_ProjectPointOnSurf aProjPL;
4e57c75e 818 //
819 aAngleMin=100.;
820 aTwoPI=M_PI+M_PI;
821 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
4e57c75e 822 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
823 aC3D->D0(aT, aPx);
df017cc9 824 //
4e57c75e 825 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
df017cc9 826 gp_Dir aDTgt(aVTgt), aDTgt2;
827 aOr = theE1.Orientation();
828 //
bb58e462 829 aPL = new Geom_Plane(aPx, aDTgt);
830 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
831 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
832 //
505abfb8 833 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext,
834 aProjPL);
df017cc9 835 //
4e57c75e 836 aDTF=aDN1^aDBF;
837 //
744511c8 838 bRet=Standard_True;
4e57c75e 839 aIt.Initialize(theLCSOff);
840 for (; aIt.More(); aIt.Next()) {
841 const BOPTools_CoupleOfShape& aCS=aIt.Value();
842 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
843 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
844 //
df017cc9 845 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
505abfb8 846 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext,
847 aProjPL);
4e57c75e 848 //Angle
849 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
850 //
851 if(aAngle<0.) {
852 aAngle=aTwoPI+aAngle;
853 }
df017cc9 854 //
855 if (aAngle<Precision::Angular()) {
856 if (aF2==theF1) {
857 aAngle=M_PI;
858 }
859 else if (aF2.IsSame(theF1)) {
860 aAngle=aTwoPI;
861 }
862 }
863 //
4e57c75e 864 if (aAngle<aAngleMin){
865 aAngleMin=aAngle;
866 theFOff=aF2;
867 }
744511c8 868 else if (aAngle==aAngleMin) {
869 // the minimal angle can not be found
870 bRet=Standard_False;
871 }
4e57c75e 872 }
744511c8 873 return bRet;
4e57c75e 874}
875//=======================================================================
876//function : GetEdgeOff
877//purpose :
878//=======================================================================
bb58e462 879Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
880 const TopoDS_Face& theF2,
881 TopoDS_Edge& theE2)
4e57c75e 882{
883 Standard_Boolean bFound;
884 TopAbs_Orientation aOr1, aOr1C, aOr2;
885 TopExp_Explorer anExp;
886 //
887 bFound=Standard_False;
888 aOr1=theE1.Orientation();
889 aOr1C=TopAbs::Reverse(aOr1);
890 //
891 anExp.Init(theF2, TopAbs_EDGE);
892 for (; anExp.More(); anExp.Next()) {
893 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
894 if (aEF2.IsSame(theE1)) {
895 aOr2=aEF2.Orientation();
896 if (aOr2==aOr1C) {
897 theE2=aEF2;
898 bFound=!bFound;
899 return bFound;
900 }
901 }
902 }
903 return bFound;
904}
905
906//=======================================================================
907//function : AreFacesSameDomain
908//purpose :
909//=======================================================================
505abfb8 910Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
911 (const TopoDS_Face& theF1,
912 const TopoDS_Face& theF2,
913 Handle(BOPInt_Context)& theContext)
4e57c75e 914{
915 Standard_Boolean bFlag;
e656bcbe 916 Standard_Integer iErr;
4e57c75e 917 Standard_Real aTolF1, aTolF2, aTol;
918 gp_Pnt2d aP2D;
919 gp_Pnt aP;
920 TopoDS_Face aF1, aF2;
921 TopoDS_Edge aE1;
922 TopExp_Explorer aExp;
923 //
924 bFlag=Standard_False;
925 //
926 aF1=theF1;
927 aF1.Orientation(TopAbs_FORWARD);
928 aF2=theF2;
929 aF2.Orientation(TopAbs_FORWARD);
930 //
931 aTolF1=BRep_Tool::Tolerance(aF1);
932 // 1
4e57c75e 933 aExp.Init(aF1, TopAbs_EDGE);
934 for (; aExp.More(); aExp.Next()) {
935 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
936 if (!BRep_Tool::Degenerated(aE1)) {
4e57c75e 937 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
938 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
939 }
940 }
4e57c75e 941 // 2
942 aTolF2=BRep_Tool::Tolerance(aF2);
943 aTol=aTolF1+aTolF2;
944 //
505abfb8 945 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
946 theContext);
e656bcbe 947 if (!iErr) {
948 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
949 }
4e57c75e 950 //
951 return bFlag;
952}
953
954//=======================================================================
955//function : CheckSameGeom
956//purpose :
957//=======================================================================
505abfb8 958Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
959 (const TopoDS_Face& theF1,
960 const TopoDS_Face& theF2,
961 Handle(BOPInt_Context)& theContext)
4e57c75e 962{
963 Standard_Boolean bRet;
964 Standard_Real aTolF1, aTolF2, aTol;
965 gp_Pnt2d aP2D;
966 gp_Pnt aP;
967 TopExp_Explorer aExp;
968 //
969 bRet=Standard_False;
970 aExp.Init(theF1, TopAbs_EDGE);
971 for (; aExp.More(); aExp.Next()) {
972 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
973 if (!BRep_Tool::Degenerated(aE)) {
974 aTolF1=BRep_Tool::Tolerance(theF1);
975 aTolF2=BRep_Tool::Tolerance(theF2);
976 aTol=aTolF1+aTolF2;
977 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
978 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
979 break;
980 }
981 }
982 return bRet;
983}
984//=======================================================================
985// function: Sense
986// purpose:
987//=======================================================================
bb58e462 988Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
989 const TopoDS_Face& theF2)
4e57c75e 990{
991 Standard_Integer iSense=0;
992 gp_Dir aDNF1, aDNF2;
993 TopoDS_Edge aE1, aE2;
994 TopExp_Explorer aExp;
995 //
996 aExp.Init(theF1, TopAbs_EDGE);
997 for (; aExp.More(); aExp.Next()) {
998 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
999 if (!BRep_Tool::Degenerated(aE1)) {
1000 if (!BRep_Tool::IsClosed(aE1, theF1)) {
1001 break;
1002 }
1003 }
1004 }
1005 //
1006 aExp.Init(theF2, TopAbs_EDGE);
1007 for (; aExp.More(); aExp.Next()) {
1008 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
1009 if (!BRep_Tool::Degenerated(aE2)) {
1010 if (!BRep_Tool::IsClosed(aE2, theF2)) {
1011 if (aE2.IsSame(aE1)) {
1012 iSense=1;
1013 break;
1014 }
1015 }
1016 }
1017 }
1018 //
1019 if (!iSense) {
1020 return iSense;
1021 }
1022 //
1023 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
1024 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
1025 //
1026 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1027 //
1028 return iSense;
1029}
1030//=======================================================================
1031// function: IsSplitToReverse
1032// purpose:
1033//=======================================================================
505abfb8 1034Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1035 (const TopoDS_Shape& theSp,
1036 const TopoDS_Shape& theSr,
1037 Handle(BOPInt_Context)& theContext)
4e57c75e 1038{
1039 Standard_Boolean bRet;
1040 TopAbs_ShapeEnum aType;
1041 //
1042 bRet=Standard_False;
1043 //
1044 aType=theSp.ShapeType();
1045 switch (aType) {
1046 case TopAbs_EDGE: {
1047 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1048 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1049 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1050 }
1051 break;
1052 //
1053 case TopAbs_FACE: {
1054 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1055 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1056 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1057 }
1058 break;
1059 //
1060 default:
1061 break;
1062 }
1063 return bRet;
1064}
1065//=======================================================================
1066//function :IsSplitToReverse
1067//purpose :
1068//=======================================================================
505abfb8 1069Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1070 (const TopoDS_Face& theFSp,
1071 const TopoDS_Face& theFSr,
1072 Handle(BOPInt_Context)& theContext)
4e57c75e 1073{
1074 Standard_Boolean bRet, bFound, bInFace;
1075 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1076 gp_Pnt aPFSp, aPFSr;
1077 gp_Dir aDNFSp;
1078 gp_Vec aD1U, aD1V;
1079 Handle(Geom_Surface) aSr, aSp;
1080 TopAbs_Orientation aOrSr, aOrSp;
1081 TopExp_Explorer anExp;
1082 TopoDS_Edge aESp;
1083 //
1084 bRet=Standard_False;
1085 //
1086 aSr=BRep_Tool::Surface(theFSr);
1087 aSp=BRep_Tool::Surface(theFSp);
1088 if (aSr==aSp) {
1089 aOrSr=theFSr.Orientation();
1090 aOrSp=theFSp.Orientation();
1091 bRet=(aOrSr!=aOrSp);
1092 return bRet;
1093 }
1094 //
1095 bFound=Standard_False;
1096 anExp.Init(theFSp, TopAbs_EDGE);
1097 for (; anExp.More(); anExp.Next()) {
1098 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1099 if (!BRep_Tool::Degenerated(aESp)) {
1100 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1101 bFound=!bFound;
1102 break;
1103 }
1104 }
1105 }
1106 if (!bFound) {
1107 Standard_Boolean bFlag;
1108 Standard_Integer iErr;
1109 gp_Pnt2d aP2DFSp;
1110 //
505abfb8 1111 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp,
1112 theContext);
4e57c75e 1113 if (iErr) {
1114 return bRet;
1115 }
1116 //
1117 aP2DFSp.Coord(aU, aV);
1118 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1119 if (!bFlag) {
1120 return bRet;
1121 }
1122 }
1123 else {
1124 BRep_Tool::Range(aESp, aT1, aT2);
1125 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
505abfb8 1126 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT,
1127 aPFSp, aDNFSp,
1128 theContext);
4e57c75e 1129 }
1130 //
1131 // Parts of theContext->ComputeVS(..)
1132 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1133 aProjector.Perform(aPFSp);
1134 if (!aProjector.IsDone()) {
1135 return bRet;
1136 }
1137 //
1138 aProjector.LowerDistanceParameters(aU, aV);
1139 gp_Pnt2d aP2D(aU, aV);
1140 bInFace=theContext->IsPointInFace (theFSr, aP2D);
1141 if (!bInFace) {
1142 return bRet;
1143 }
1144 //
1145 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1146 gp_Dir aDD1U(aD1U);
1147 gp_Dir aDD1V(aD1V);
1148 gp_Dir aDNFSr=aDD1U^aDD1V;
1149 if (theFSr.Orientation()==TopAbs_REVERSED){
1150 aDNFSr.Reverse();
1151 }
1152 //
1153 aScPr=aDNFSp*aDNFSr;
1154 bRet=(aScPr<0.);
1155 //
1156 return bRet;
1157}
1158//=======================================================================
1159//function :IsSplitToReverse
1160//purpose :
1161//=======================================================================
505abfb8 1162Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1163 (const TopoDS_Edge& aEF1,
1164 const TopoDS_Edge& aEF2,
1165 Handle(BOPInt_Context)& theContext)
4e57c75e 1166{
1167 Standard_Boolean bRet, bIsDegenerated;
1168 //
1169 bRet=Standard_False;
1170 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1171 BRep_Tool::Degenerated(aEF2));
1172 if (bIsDegenerated) {
1173 return bRet;
1174 }
1175 //
1176 Standard_Real a, b;
1177 TopAbs_Orientation aOrE, aOrSp;
1178 Handle(Geom_Curve)aC1, aC2;
1179 //
1180 aC2=BRep_Tool::Curve(aEF2, a, b);
1181 aC1=BRep_Tool::Curve(aEF1, a, b);
1182 //
1183 if (aC1==aC2) {
1184 aOrE=aEF2.Orientation();
1185 aOrSp=aEF1.Orientation();
1186 bRet=(aOrE!=aOrSp);
1187 return bRet;
1188 }
1189 //
1190 Standard_Real aT1, aT2, aScPr;
1191 gp_Vec aV1, aV2;
1192 gp_Pnt aP;
1193 //
1194 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1195 aC1->D0(aT1, aP);
1196 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1197 gp_Dir aDT1(aV1);
1198 //
1199 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1200 //
1201 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1202 gp_Dir aDT2(aV2);
1203 //
1204 aScPr=aDT1*aDT2;
1205 bRet=(aScPr<0.);
1206 //
1207 return bRet;
1208}
1209
1210//=======================================================================
1211//function : IsHole
1212//purpose :
1213//=======================================================================
bb58e462 1214Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1215 const TopoDS_Shape& aFace)
4e57c75e 1216{
1217 Standard_Boolean bIsHole;
1218 Standard_Integer i, aNbS;
1219 Standard_Real aT1, aT2, aS;
96a95605 1220 Standard_Real aU1, aU, dU;
4e57c75e 1221 Standard_Real aX1, aY1, aX0, aY0;
1222 TopAbs_Orientation aOr;
1223
1224 gp_Pnt2d aP2D0, aP2D1;
1225 Handle(Geom2d_Curve) aC2D;
1226 TopoDS_Face aF, aFF;
1227 TopoDS_Iterator aItW;
1228 //
1229 bIsHole=Standard_False;
1230 //
1231 aF=(*(TopoDS_Face *)(&aFace));
1232 aFF=aF;
1233 aFF.Orientation(TopAbs_FORWARD);
1234 //
1235 aS=0.;
1236 aItW.Initialize(aW);
1237 for (; aItW.More(); aItW.Next()) {
1238 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1239 aOr=aE.Orientation();
1240 if (!(aOr==TopAbs_FORWARD ||
1241 aOr==TopAbs_REVERSED)) {
1242 continue;
1243 }
1244 //
1245 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1246 if (aC2D.IsNull()) {
1247 break; //xx
1248 }
1249 //
1250 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1251 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1252 if (aNbS>2) {
1253 aNbS*=4;
1254 }
1255 //
1256 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1257 aU =aT1;
1258 aU1=aT1;
4e57c75e 1259 if (aOr==TopAbs_REVERSED) {
1260 aU =aT2;
1261 aU1=aT2;
4e57c75e 1262 dU=-dU;
1263 }
1264 //
1265 aC2D->D0(aU, aP2D0);
1266 for(i=2; i<=aNbS; i++) {
1267 aU=aU1+(i-1)*dU;
1268 aC2D->D0(aU, aP2D1);
1269 aP2D0.Coord(aX0, aY0);
1270 aP2D1.Coord(aX1, aY1);
1271 //
1272 aS=aS+(aY0+aY1)*(aX1-aX0);
1273 //
1274 aP2D0=aP2D1;
1275 }
1276 }//for (; aItW.More(); aItW.Next()) {
1277 bIsHole=(aS>0.);
1278 return bIsHole;
1279}
1280
1281//=======================================================================
1282// function: MakeContainer
1283// purpose:
1284//=======================================================================
bb58e462 1285void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1286 TopoDS_Shape& theC)
4e57c75e 1287{
1288 BRep_Builder aBB;
1289 //
1290 switch(theType) {
1291 case TopAbs_COMPOUND:{
1292 TopoDS_Compound aC;
1293 aBB.MakeCompound(aC);
1294 theC=aC;
1295 }
1296 break;
1297 //
1298 case TopAbs_COMPSOLID:{
1299 TopoDS_CompSolid aCS;
1300 aBB.MakeCompSolid(aCS);
1301 theC=aCS;
1302 }
1303 break;
1304 //
1305 case TopAbs_SOLID:{
1306 TopoDS_Solid aSolid;
1307 aBB.MakeSolid(aSolid);
1308 theC=aSolid;
1309 }
1310 break;
1311 //
1312 //
1313 case TopAbs_SHELL:{
1314 TopoDS_Shell aShell;
1315 aBB.MakeShell(aShell);
1316 theC=aShell;
1317 }
1318 break;
1319 //
1320 case TopAbs_WIRE: {
1321 TopoDS_Wire aWire;
1322 aBB.MakeWire(aWire);
1323 theC=aWire;
1324 }
1325 break;
1326 //
1327 default:
1328 break;
1329 }
1330}
1331//=======================================================================
1332// function: MakePCurve
1333// purpose:
1334//=======================================================================
bb58e462 1335void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1336 const TopoDS_Face& aF1,
1337 const TopoDS_Face& aF2,
1338 const IntTools_Curve& aIC,
1339 const Standard_Boolean bPC1,
1340 const Standard_Boolean bPC2)
4e57c75e 1341
1342{
1343 Standard_Integer i;
1344 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1345 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1346 TopoDS_Face aFFWD;
1347 BRep_Builder aBB;
1348 Standard_Boolean bPC;
1349 //
1350 aTolE=BRep_Tool::Tolerance(aE);
1351 //
1352 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
505abfb8 1353 Handle(Geom_TrimmedCurve)aC3DETrim=
1354 new Geom_TrimmedCurve(aC3DE, aT1, aT2);
4e57c75e 1355 //
1356 for (i=0; i<2; ++i) {
1357 bPC = !i ? bPC1 : bPC2;
1358 if (!bPC) {
1359 continue;
1360 }
1361 //
1362 if (!i) {
1363 aFFWD=aF1;
1364 aC2Dx1=aIC.FirstCurve2d();
1365 }
1366 else {
1367 aFFWD=aF2;
1368 aC2Dx1=aIC.SecondCurve2d();
1369 }
1370 //
1371 aFFWD.Orientation(TopAbs_FORWARD);
1372 //
1373 aC2D=aC2Dx1;
1374 if (aC2D.IsNull()) {
1375 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1376 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1377 aOutFirst, aOutLast,
1378 aOutTol);
1379 }
1380 //
1381 if (aC3DE->IsPeriodic()) {
505abfb8 1382 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D,
1383 aC2DA);
4e57c75e 1384 }
1385 else {
505abfb8 1386 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D,
1387 aC2DA);
4e57c75e 1388 }
1389 //
1390 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1391 //BRepLib::SameParameter(aE);
1392 }
1393 BRepLib::SameParameter(aE);
1394}
1395//=======================================================================
1396// function: MakeEdge
1397// purpose:
1398//=======================================================================
bb58e462 1399void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1400 const TopoDS_Vertex& theV1,
1401 const Standard_Real theT1,
1402 const TopoDS_Vertex& theV2,
1403 const Standard_Real theT2,
1404 const Standard_Real theTolR3D,
1405 TopoDS_Edge& theE)
4e57c75e 1406{
1407 Standard_Real aTolV;
1408 BRep_Builder aBB;
1409 //
505abfb8 1410 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2,
1411 theE);
4e57c75e 1412 //
1413 aBB.UpdateEdge(theE, theTolR3D);
1414 //
1415 aTolV=BRep_Tool::Tolerance(theV1);
1416 if (aTolV<theTolR3D) {
1417 aBB.UpdateVertex(theV1, theTolR3D);
1418 }
1419 //
1420 aTolV=BRep_Tool::Tolerance(theV2);
1421 if (aTolV<theTolR3D) {
1422 aBB.UpdateVertex(theV2, theTolR3D);
1423 }
1424}
1425//=======================================================================
1426// function: ComputeVV
1427// purpose:
1428//=======================================================================
bb58e462 1429Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1430 const gp_Pnt& aP2,
1431 const Standard_Real aTolP2)
4e57c75e 1432{
1433 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1434 gp_Pnt aP1;
1435 //
1436 aTolV1=BRep_Tool::Tolerance(aV1);
1437
1438 aTolSum=aTolV1+aTolP2;
1439 aTolSum2=aTolSum*aTolSum;
1440 //
1441 aP1=BRep_Tool::Pnt(aV1);
1442 //
1443 aD2=aP1.SquareDistance(aP2);
1444 if (aD2>aTolSum2) {
1445 return 1;
1446 }
1447 return 0;
1448}
1449//=======================================================================
1450// function: ComputeVV
1451// purpose:
1452//=======================================================================
bb58e462 1453Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1454 const TopoDS_Vertex& aV2)
4e57c75e 1455{
1456 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1457 gp_Pnt aP1, aP2;
1458 //
1459 aTolV1=BRep_Tool::Tolerance(aV1);
1460 aTolV2=BRep_Tool::Tolerance(aV2);
1461 aTolSum=aTolV1+aTolV2;
1462 aTolSum2=aTolSum*aTolSum;
1463 //
1464 aP1=BRep_Tool::Pnt(aV1);
1465 aP2=BRep_Tool::Pnt(aV2);
1466 //
1467 aD2=aP1.SquareDistance(aP2);
1468 if (aD2>aTolSum2) {
1469 return 1;
1470 }
1471 return 0;
1472}
1473//=======================================================================
1474// function: MakeVertex
1475// purpose :
1476//=======================================================================
bb58e462 1477void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
1478 TopoDS_Vertex& aVnew)
4e57c75e 1479{
1480 Standard_Integer aNb;
1481 Standard_Real aTi, aDi, aDmax;
1482 gp_Pnt aPi, aP;
1483 gp_XYZ aXYZ(0.,0.,0.), aXYZi;
1484 BOPCol_ListIteratorOfListOfShape aIt;
1485 //
1486 aNb=aLV.Extent();
1487 if (aNb) {
1488 aIt.Initialize(aLV);
1489 for (; aIt.More(); aIt.Next()) {
1490 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1491 aPi=BRep_Tool::Pnt(aVi);
1492 aXYZi=aPi.XYZ();
1493 aXYZ=aXYZ+aXYZi;
1494 }
1495 //
1496 aXYZ.Divide((Standard_Real)aNb);
1497 aP.SetXYZ(aXYZ);
1498 //
1499 aDmax=-1.;
1500 aIt.Initialize(aLV);
1501 for (; aIt.More(); aIt.Next()) {
1502 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1503 aPi=BRep_Tool::Pnt(aVi);
1504 aTi=BRep_Tool::Tolerance(aVi);
1505 aDi=aP.SquareDistance(aPi);
4889b44e 1506 aDi=sqrt(aDi);
4e57c75e 1507 aDi=aDi+aTi;
1508 if (aDi > aDmax) {
1509 aDmax=aDi;
1510 }
1511 }
1512 //
1513 BRep_Builder aBB;
1514 aBB.MakeVertex (aVnew, aP, aDmax);
1515 }
1516}
1517//=======================================================================
1518//function : GetEdgeOnFace
1519//purpose :
1520//=======================================================================
505abfb8 1521Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
1522(const TopoDS_Edge& theE1,
1523 const TopoDS_Face& theF2,
1524 TopoDS_Edge& theE2)
4e57c75e 1525{
1526 Standard_Boolean bFound;
1527 TopoDS_Iterator aItF, aItW;
1528 //
1529 bFound=Standard_False;
1530 //
1531 aItF.Initialize(theF2);
1532 for (; aItF.More(); aItF.Next()) {
1533 const TopoDS_Shape& aW=aItF.Value();
1534 aItW.Initialize(aW);
1535 for (; aItW.More(); aItW.Next()) {
1536 const TopoDS_Shape& aE=aItW.Value();
1537 if (aE.IsSame(theE1)) {
1538 theE2=(*(TopoDS_Edge*)(&aE));
1539 bFound=!bFound;
1540 return bFound;
1541 }
1542 }
1543 }
1544 return bFound;
1545}
1546//=======================================================================
1547//function : FindFacePairs
1548//purpose :
1549//=======================================================================
1550Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1551 const BOPCol_ListOfShape& thLF,
1552 BOPTools_ListOfCoupleOfShape& theLCFF,
1553 Handle(BOPInt_Context)& theContext)
1554{
1555 Standard_Boolean bFound;
1556 Standard_Integer i, aNbCEF;
1d47d8d0 1557 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
4e57c75e 1558 BOPCol_MapOfShape aMFP;
1559 TopoDS_Face aF1, aF2;
1560 TopoDS_Edge aEL, aE1;
1561 BOPCol_ListIteratorOfListOfShape aItLF;
1562 BOPTools_CoupleOfShape aCEF, aCFF;
1563 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1564 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1565 //
1566 bFound=Standard_True;
1567 //
1568 // Preface aLCEF
1569 aItLF.Initialize(thLF);
1570 for (; aItLF.More(); aItLF.Next()) {
1571 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1572 //
1573 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1574 if (!bFound) {
1575 return bFound; // it can not be so
1576 }
1577 //
1578 aCEF.SetShape1(aEL);
1579 aCEF.SetShape2(aFL);
1580 aLCEF.Append(aCEF);
1581 }
1582 //
1583 aNbCEF=aLCEF.Extent();
1584 while(aNbCEF) {
1585 //
1586 // aLCEFx
1587 aLCEFx.Clear();
1588 aIt.Initialize(aLCEF);
1589 for (i=0; aIt.More(); aIt.Next(), ++i) {
1590 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1591 const TopoDS_Shape& aEx=aCSx.Shape1();
1592 const TopoDS_Shape& aFx=aCSx.Shape2();
1593 //
1594 aOr=aEx.Orientation();
1595 //
1596 if (!i) {
1597 aOrC=TopAbs::Reverse(aOr);
1598 aE1=(*(TopoDS_Edge*)(&aEx));
1599 aF1=(*(TopoDS_Face*)(&aFx));
1600 aMFP.Add(aFx);
1601 continue;
1602 }
1603 //
1604 if (aOr==aOrC) {
1605 aLCEFx.Append(aCSx);
1606 aMFP.Add(aFx);
1607 }
1608 }
1609 //
1610 // F2
1611 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1612 //
1613 aCFF.SetShape1(aF1);
1614 aCFF.SetShape2(aF2);
1615 theLCFF.Append(aCFF);
1616 //
1617 aMFP.Add(aF1);
1618 aMFP.Add(aF2);
1619 //
1620 // refine aLCEF
1621 aLCEFx.Clear();
1622 aLCEFx=aLCEF;
1623 aLCEF.Clear();
1624 aIt.Initialize(aLCEFx);
1625 for (; aIt.More(); aIt.Next()) {
1626 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1627 const TopoDS_Shape& aFx=aCSx.Shape2();
1628 if (!aMFP.Contains(aFx)) {
1629 aLCEF.Append(aCSx);
1630 }
1631 }
1632 //
1633 aNbCEF=aLCEF.Extent();
1634 }//while(aNbCEF) {
1635 //
1636 return bFound;
1637}
1638//=======================================================================
1639//function : AngleWithRef
1640//purpose :
1641//=======================================================================
1642Standard_Real AngleWithRef(const gp_Dir& theD1,
1643 const gp_Dir& theD2,
1644 const gp_Dir& theDRef)
1645{
1646 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1647 gp_XYZ aXYZ;
1648 //
1649 aHalfPI=0.5*M_PI;
1650 //
1651 const gp_XYZ& aXYZ1=theD1.XYZ();
1652 const gp_XYZ& aXYZ2=theD2.XYZ();
1653 aXYZ=aXYZ1.Crossed(aXYZ2);
1654 aSinus=aXYZ.Modulus();
1655 aCosinus=theD1*theD2;
1656 //
1657 aBeta=0.;
1658 if (aSinus>=0.) {
1659 aBeta=aHalfPI*(1.-aCosinus);
1660 }
1661 else {
1662 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1663 }
1664 //
1665 aScPr=aXYZ.Dot(theDRef.XYZ());
1666 if (aScPr<0.) {
1667 aBeta=-aBeta;
1668 }
1669 return aBeta;
1670}
4e57c75e 1671//=======================================================================
1672// function: IsBlockInOnFace
1673// purpose:
1674//=======================================================================
505abfb8 1675Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
1676 (const IntTools_Range& aShrR,
1677 const TopoDS_Face& aF,
1678 const TopoDS_Edge& aE1,
1679 Handle(BOPInt_Context)& aContext)
4e57c75e 1680{
1681 Standard_Boolean bFlag;
1682 Standard_Real f1, l1, ULD, VLD;
1683 gp_Pnt2d aP2D;
1684 gp_Pnt aP11, aP12;
1685 //
1686 aShrR.Range(f1, l1);
1687 Standard_Real dt=0.0075, k;//dt=0.001, k;
1688 k=dt*(l1-f1);
1689 f1=f1+k;
1690 l1=l1-k;
1691 //
1692 // Treatment P11
1693 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1694 //
1695 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1696 aProjector.Perform(aP11);
1697 //
1698 bFlag=aProjector.IsDone();
1699 if (!bFlag) {
1700 return bFlag;
1701 }
1702
1703 aProjector.LowerDistanceParameters(ULD, VLD);
1704 aP2D.SetCoord(ULD, VLD);
1705 //
1706 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1707 //
1708 if (!bFlag) {
1709 return bFlag;
1710 }
1711 //
1712 // Treatment P12
1713 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1714 //
1715 aProjector.Perform(aP12);
1716 //
1717 bFlag=aProjector.IsDone();
1718 if (!bFlag) {
1719 return bFlag;
1720 }
1721
1722 aProjector.LowerDistanceParameters(ULD, VLD);
1723 aP2D.SetCoord(ULD, VLD);
1724 //
1725 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1726 //
1727 if (!bFlag) {
1728 return bFlag;
1729 }
1730 //
1731 // Treatment intemediate
1732 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1733 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1734 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1735 //
1736 aProjector.Perform(aP12);
1737 //
1738 bFlag=aProjector.IsDone();
1739 if (!bFlag) {
1740 return bFlag;
1741 }
1742 //
1743 aTolE=BRep_Tool::Tolerance(aE1);
1744 aTolF=BRep_Tool::Tolerance(aF);
1745 aTol=aTolE+aTolF;
1746 aDist=aProjector.LowerDistance();
1747 if (aDist > aTol){
1748 return Standard_False;
1749 }
1750
1751 aProjector.LowerDistanceParameters(ULD, VLD);
1752 aP2D.SetCoord(ULD, VLD);
1753 //
1754 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1755 //
1756 if (!bFlag) {
1757 return bFlag;
1758 }
1759 return bFlag;
1760}
1761
4e57c75e 1762//=======================================================================
1763//function : IsMicroEdge
1764//purpose :
1765//=======================================================================
505abfb8 1766Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
1767 (const TopoDS_Edge& aE,
1768 const Handle(BOPInt_Context)& aCtx)
4e57c75e 1769{
1770 Standard_Boolean bRet;
1771 Standard_Integer iErr;
1772 Standard_Real aT1, aT2, aTmp;
1773 Handle(Geom_Curve) aC3D;
1774 TopoDS_Vertex aV1, aV2;
1775 //
1776 bRet=(BRep_Tool::Degenerated(aE) ||
1777 !BRep_Tool::IsGeometric(aE));
1778 if (bRet) {
1779 return bRet;
1780 }
1781 //
1782 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1783 TopExp::Vertices(aE, aV1, aV2);
1784 aT1=BRep_Tool::Parameter(aV1, aE);
1785 aT2=BRep_Tool::Parameter(aV2, aE);
1786 if (aT2<aT1) {
1787 aTmp=aT1;
1788 aT1=aT2;
1789 aT2=aTmp;
1790 }
1791 //
1792 BOPInt_ShrunkRange aSR;
505abfb8 1793 aSR.SetContext(aCtx);
1794 aSR.SetData(aE, aT1, aT2, aV1, aV2);
4e57c75e 1795 aSR.Perform();
1796 iErr=aSR.ErrorStatus();
1797 bRet = !(iErr==0);
1798 //
1799 return bRet;
1800}
1801
4e57c75e 1802//=======================================================================
df017cc9 1803//function : GetFaceDir
1804//purpose : Get binormal direction for the face in the point aP
1805//=======================================================================
bb58e462 1806void GetFaceDir(const TopoDS_Edge& aE,
1807 const TopoDS_Face& aF,
1808 const gp_Pnt& aP,
1809 const Standard_Real aT,
1810 const gp_Dir& aDTgt,
1811 gp_Dir& aDN,
1812 gp_Dir& aDB,
1813 Handle(BOPInt_Context)& theContext,
1814 GeomAPI_ProjectPointOnSurf& aProjPL)
df017cc9 1815{
1816 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1817 if (aF.Orientation()==TopAbs_REVERSED){
1818 aDN.Reverse();
1819 }
1820 aDB = aDN^aDTgt;
1821 //
bb58e462 1822 gp_Pnt aPx;
1823 if (!FindPointInFace(aE, aF, aP, aDB, aPx, theContext, aProjPL)) {
505abfb8 1824 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx,
1825 aDN, theContext);
bb58e462 1826 aProjPL.Perform(aPx);
1827 aPx = aProjPL.NearestPoint();
1828 gp_Vec aVec(aP, aPx);
1829 aDB.SetXYZ(aVec.XYZ());
4e57c75e 1830 }
df017cc9 1831}
1832
1833//=======================================================================
1834//function : FindPointInFace
1835//purpose : Find a point in the face in direction of <aDB>
1836//=======================================================================
bb58e462 1837Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
1838 const TopoDS_Face& aF,
1839 const gp_Pnt& aP,
1840 gp_Dir& aDB,
1841 gp_Pnt& aPOut,
1842 Handle(BOPInt_Context)& theContext,
1843 GeomAPI_ProjectPointOnSurf& aProjPL)
df017cc9 1844{
1845 Standard_Integer aNbItMax;
1846 Standard_Real aDt, aDtMin, aTolE, aTolF, aDist;
1847 Standard_Boolean bRet;
1848 gp_Pnt aP1;
bb58e462 1849 BRepAdaptor_Surface aBAS;
4e57c75e 1850 //
df017cc9 1851 bRet = Standard_False;
1852 aTolE = BRep_Tool::Tolerance(aE);
1853 aTolF = BRep_Tool::Tolerance(aF);
1854 aDt = 2*(aTolE+aTolF);
bb58e462 1855 aBAS.Initialize(aF, Standard_False);
df017cc9 1856 //
1857 aDtMin=5.e-4;
1858 if (aDt < aDtMin) {
1859 Standard_Real aR;
bb58e462 1860 GeomAbs_SurfaceType aSType=aBAS.GetType();
df017cc9 1861 switch (aSType) {
1862 case GeomAbs_Cylinder:
bb58e462 1863 aR = aBAS.Cylinder().Radius();
df017cc9 1864 break;
b92a64cc 1865 case GeomAbs_Cone: {
1866 gp_Lin aL(aBAS.Cone().Axis());
1867 aR = aL.Distance(aP);
df017cc9 1868 break;
b92a64cc 1869 }
df017cc9 1870 case GeomAbs_Sphere:
bb58e462 1871 aR = aBAS.Sphere().Radius();
df017cc9 1872 break;
1873 case GeomAbs_Torus:
bb58e462 1874 aR = aBAS.Torus().MinorRadius();
df017cc9 1875 break;
1876 case GeomAbs_SurfaceOfRevolution:
1877 aR=1.;
1878 break;
1879 default:
1880 aR=0.001;
1881 }
1882 if (aR < 0.01) {
1883 aDtMin=5.e-6;
1884 }
1885 else if (aR > 100.) {
1886 aDtMin*=10;
1887 }
1888 if (aDt < aDtMin) {
1889 aDt=aDtMin;
4e57c75e 1890 }
1891 }
1892 //
df017cc9 1893 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1894 aNbItMax = 15;
4e57c75e 1895 //
df017cc9 1896 do {
1897 aP1.SetCoord(aP.X()+aDt*aDB.X(),
1898 aP.Y()+aDt*aDB.Y(),
1899 aP.Z()+aDt*aDB.Z());
1900 //
1901 aProj.Perform(aP1);
1902 if (!aProj.IsDone()) {
1903 return bRet;
1904 }
1905 aPOut = aProj.NearestPoint();
1906 aDist = aProj.LowerDistance();
1907 //
bb58e462 1908 aProjPL.Perform(aPOut);
1909 aPOut = aProjPL.NearestPoint();
1910 //
df017cc9 1911 gp_Vec aV(aP, aPOut);
1912 aDB.SetXYZ(aV.XYZ());
1913 } while (aDist>Precision::Angular() && --aNbItMax);
4e57c75e 1914 //
df017cc9 1915 bRet = aDist < Precision::Angular();
1916 return bRet;
4e57c75e 1917}
30ecd5f8 1918//=======================================================================
1919//function : IsOpenShell
1920//purpose :
1921//=======================================================================
505abfb8 1922Standard_Boolean BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
30ecd5f8 1923{
1924 Standard_Boolean bRet;
1925 Standard_Integer i, aNbE, aNbF;
1926 TopAbs_Orientation aOrF;
1927 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
1928 BOPCol_ListIteratorOfListOfShape aItLS;
1929 //
1930 bRet=Standard_False;
1931 //
1932 BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF);
1933 //
1934 aNbE=aMEF.Extent();
1935 for (i=1; i<=aNbE; ++i) {
1936 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i));
1937 if (BRep_Tool::Degenerated(aE)) {
1938 continue;
1939 }
1940 //
1941 aNbF=0;
1942 const BOPCol_ListOfShape& aLF=aMEF(i);
1943 aItLS.Initialize(aLF);
1944 for (; aItLS.More(); aItLS.Next()) {
1945 const TopoDS_Shape& aF=aItLS.Value();
1946 aOrF=aF.Orientation();
1947 if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
505abfb8 1948 continue;
30ecd5f8 1949 }
1950 ++aNbF;
1951 }
1952 //
1953 if (aNbF==1) {
1954 bRet=!bRet; // True
1955 break;
1956 }
1957 }
1958 //
1959 return bRet;
1960}
1961//=======================================================================
1962//function : IsInvertedSolid
1963//purpose :
1964//=======================================================================
1965Standard_Boolean
1966 BOPTools_AlgoTools::IsInvertedSolid(const TopoDS_Solid& aSolid)
1967{
1968 Standard_Real aTolS;
1969 TopAbs_State aState;
1970 BRepClass3d_SolidClassifier aSC(aSolid);
1971 //
1972 aTolS=1.e-7;
1973 aSC.PerformInfinitePoint(aTolS);
1974 aState=aSC.State();
1975 return (aState==TopAbs_IN);
1976}