1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
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
7 // This file is part of Open CASCADE Technology software library.
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
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.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <BOPTools_AlgoTools.ixx>
20 #include <Precision.hxx>
24 #include <gp_Pnt2d.hxx>
25 #include <gp_Cylinder.hxx>
26 #include <gp_Cone.hxx>
27 #include <gp_Sphere.hxx>
28 #include <gp_Torus.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom_Plane.hxx>
34 #include <Geom_TrimmedCurve.hxx>
35 #include <Geom_Curve.hxx>
36 #include <GeomAPI_ProjectPointOnSurf.hxx>
37 #include <Geom2dInt_Geom2dCurveTool.hxx>
39 #include <TopAbs_Orientation.hxx>
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>
47 #include <BRep_Builder.hxx>
48 #include <BRep_Tool.hxx>
49 #include <BRepLib.hxx>
50 #include <BRepAdaptor_Curve2d.hxx>
51 #include <BRepAdaptor_Surface.hxx>
52 #include <BRepClass3d_SolidClassifier.hxx>
54 #include <TopExp_Explorer.hxx>
56 #include <IntTools_Tools.hxx>
58 #include <BOPTools.hxx>
59 #include <BOPTools_CoupleOfShape.hxx>
60 #include <BOPTools_ListOfCoupleOfShape.hxx>
61 #include <BOPTools_AlgoTools2D.hxx>
62 #include <BOPTools_AlgoTools3D.hxx>
64 #include <BOPCol_IndexedMapOfShape.hxx>
65 #include <BOPCol_MapOfShape.hxx>
67 #include <IntTools_ShrunkRange.hxx>
71 Standard_Real AngleWithRef(const gp_Dir& theD1,
73 const gp_Dir& theDRef);
76 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
77 const BOPCol_ListOfShape& thLF,
78 BOPTools_ListOfCoupleOfShape& theLCFF,
79 Handle(IntTools_Context)& theContext);
81 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
82 const TopoDS_Face& aF);
85 void GetFaceDir(const TopoDS_Edge& aE,
86 const TopoDS_Face& aF,
88 const Standard_Real aT,
92 Handle(IntTools_Context)& theContext,
93 GeomAPI_ProjectPointOnSurf& aProjPL,
94 const Standard_Real aDt);
96 Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
100 Handle(IntTools_Context)& theContext,
101 GeomAPI_ProjectPointOnSurf& aProjPL,
102 const Standard_Real aDt,
103 const Standard_Real aTolE);
105 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
106 const TopoDS_Face& theF1,
107 const BOPTools_ListOfCoupleOfShape& theLCS,
110 //=======================================================================
111 // function: MakeConnexityBlocks
113 //=======================================================================
114 void BOPTools_AlgoTools::MakeConnexityBlocks
115 (const TopoDS_Shape& theS,
116 const TopAbs_ShapeEnum theType1,
117 const TopAbs_ShapeEnum theType2,
118 BOPCol_ListOfShape& theLCB)
120 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
124 TopExp_Explorer aExp;
125 BOPCol_MapOfShape aMP;
126 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
127 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
128 BOPCol_ListIteratorOfListOfShape aItLF;
131 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
134 aIt.Initialize(theS);
135 for (; aIt.More(); aIt.Next()) {
136 const TopoDS_Shape& aF1=aIt.Value();
137 if (aMP.Contains(aF1)) {
148 aNbAdd = aMAdd.Extent();
149 for (i=1; i<=aNbAdd; ++i) {
150 const TopoDS_Shape& aF=aMAdd(i);
152 aExp.Init(aF, theType1);
153 for (; aExp.More(); aExp.Next()) {
154 const TopoDS_Shape& aE=aExp.Current();
156 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
157 aItLF.Initialize(aLF);
158 for (; aItLF.More(); aItLF.Next()) {
159 const TopoDS_Shape& aFx=aItLF.Value();
160 if (aFx.IsSame(aF)) {
163 if (aMCB.Contains(aFx)) {
168 }//for (; aExp.More(); aExp.Next()){
170 }// for (i=1; i<=aNbAdd; ++i) {
172 aNbAdd1=aMAdd1.Extent();
174 break;// ->make new CB from aMCB
178 for (i=1; i<=aNbAdd1; ++i) {
179 const TopoDS_Shape& aFAdd = aMAdd1(i);
186 aBB.MakeCompound(aC);
188 for (i=1; i<=aNbF; ++i) {
189 const TopoDS_Shape& aF=aMCB(i);
195 }// for (; aIt.More(); aIt.Next())
197 //=======================================================================
198 // function: OrientFacesOnShell
200 //=======================================================================
201 void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
203 Standard_Boolean bIsProcessed1, bIsProcessed2;
204 Standard_Integer i, aNbE, aNbF, j;
205 TopAbs_Orientation anOrE1, anOrE2;
206 TopoDS_Face aF1x, aF2x;
207 TopoDS_Shape aShellNew;
208 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
209 BOPCol_IndexedMapOfShape aProcessedFaces;
212 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
214 BOPTools::MapShapesAndAncestors(aShell,
215 TopAbs_EDGE, TopAbs_FACE,
217 aNbE=aEFMap.Extent();
219 // One seam edge in aEFMap contains 2 equivalent faces.
220 for (i=1; i<=aNbE; ++i) {
221 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
224 BOPCol_ListOfShape aLFTmp;
225 BOPCol_IndexedMapOfShape aFM;
227 BOPCol_ListIteratorOfListOfShape anIt(aLF);
228 for (; anIt.More(); anIt.Next()) {
229 const TopoDS_Shape& aF=anIt.Value();
230 if (!aFM.Contains(aF)) {
241 for (i=1; i<=aNbE; ++i) {
242 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
243 if (BRep_Tool::Degenerated(aE)) {
247 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
253 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
254 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
256 bIsProcessed1=aProcessedFaces.Contains(aF1);
257 bIsProcessed2=aProcessedFaces.Contains(aF2);
258 if (bIsProcessed1 && bIsProcessed2) {
262 if (!bIsProcessed1 && !bIsProcessed2) {
263 aProcessedFaces.Add(aF1);
264 aBB.Add(aShellNew, aF1);
265 bIsProcessed1=!bIsProcessed1;
270 j=aProcessedFaces.FindIndex(aF1);
271 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
276 j=aProcessedFaces.FindIndex(aF2);
277 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
280 anOrE1=Orientation(aE, aF1x);
281 anOrE2=Orientation(aE, aF2x);
283 if (bIsProcessed1 && !bIsProcessed2) {
284 if (anOrE1==anOrE2) {
285 if (!BRep_Tool::IsClosed(aE, aF1) &&
286 !BRep_Tool::IsClosed(aE, aF2)) {
290 aProcessedFaces.Add(aF2);
291 aBB.Add(aShellNew, aF2);
293 else if (!bIsProcessed1 && bIsProcessed2) {
294 if (anOrE1==anOrE2) {
295 if (!BRep_Tool::IsClosed(aE, aF1) &&
296 !BRep_Tool::IsClosed(aE, aF2)) {
300 aProcessedFaces.Add(aF1);
301 aBB.Add(aShellNew, aF1);
306 for (i=1; i<=aNbE; ++i) {
307 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
308 if (BRep_Tool::Degenerated(aE)) {
312 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
315 BOPCol_ListIteratorOfListOfShape anIt(aLF);
316 for(; anIt.More(); anIt.Next()) {
317 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
318 if (!aProcessedFaces.Contains(aF)) {
319 aProcessedFaces.Add(aF);
320 aBB.Add(aShellNew, aF);
327 //=======================================================================
328 //function : Orientation
330 //=======================================================================
331 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
332 const TopoDS_Face& aF)
334 TopAbs_Orientation anOr=TopAbs_INTERNAL;
336 TopExp_Explorer anExp;
337 anExp.Init(aF, TopAbs_EDGE);
338 for (; anExp.More(); anExp.Next()) {
339 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
340 if (anEF1.IsSame(anE)) {
341 anOr=anEF1.Orientation();
347 //=======================================================================
348 // function: MakeConnexityBlock.
350 //=======================================================================
351 void BOPTools_AlgoTools::MakeConnexityBlock
352 (BOPCol_ListOfShape& theLFIn,
353 BOPCol_IndexedMapOfShape& theMEAvoid,
354 BOPCol_ListOfShape& theLCB,
355 const Handle(NCollection_BaseAllocator)& theAllocator)
357 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
358 TopExp_Explorer aExp;
359 BOPCol_ListIteratorOfListOfShape aIt;
361 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
362 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
363 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
364 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
367 aNbF=theLFIn.Extent();
368 aIt.Initialize(theLFIn);
369 for (; aIt.More(); aIt.Next()) {
370 const TopoDS_Shape& aF=aIt.Value();
371 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
375 const TopoDS_Shape& aF1=theLFIn.First();
380 aNbAdd = aMAdd.Extent();
381 for (i=1; i<=aNbAdd; ++i) {
382 const TopoDS_Shape& aF=aMAdd(i);
385 aExp.Init(aF, TopAbs_EDGE);
386 for (; aExp.More(); aExp.Next()) {
387 const TopoDS_Shape& aE=aExp.Current();
388 if (theMEAvoid.Contains(aE)){
392 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
394 for (; aIt.More(); aIt.Next()) {
395 const TopoDS_Shape& aFx=aIt.Value();
396 if (aFx.IsSame(aF)) {
399 if (aMCB.Contains(aFx)) {
404 }//for (; aExp.More(); aExp.Next()){
406 }// for (i=1; i<=aNbAdd; ++i) {
408 aNbAdd1=aMAdd1.Extent();
414 for (i=1; i<=aNbAdd1; ++i) {
415 const TopoDS_Shape& aFAdd=aMAdd1(i);
423 for (i=1; i<=aNbF; ++i) {
424 const TopoDS_Shape& aF=aMCB(i);
428 //=======================================================================
429 // function: ComputeStateByOnePoint
431 //=======================================================================
432 TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
433 (const TopoDS_Shape& theS,
434 const TopoDS_Solid& theRef,
435 const Standard_Real theTol,
436 Handle(IntTools_Context)& theContext)
439 TopAbs_ShapeEnum aType;
441 aState=TopAbs_UNKNOWN;
442 aType=theS.ShapeType();
443 if (aType==TopAbs_VERTEX) {
444 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
445 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
447 else if (aType==TopAbs_EDGE) {
448 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
449 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
454 //=======================================================================
455 // function: ComputeState
457 //=======================================================================
458 TopAbs_State BOPTools_AlgoTools::ComputeState
459 (const TopoDS_Face& theF,
460 const TopoDS_Solid& theRef,
461 const Standard_Real theTol,
462 BOPCol_IndexedMapOfShape& theBounds,
463 Handle(IntTools_Context)& theContext)
466 TopExp_Explorer aExp;
471 aState=TopAbs_UNKNOWN;
473 aExp.Init(theF, TopAbs_EDGE);
474 for (; aExp.More(); aExp.Next()) {
475 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
476 if (BRep_Tool::Degenerated(aSE)) {
480 if (!theBounds.Contains(aSE)) {
481 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
482 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol,
487 aE1=(*(TopoDS_Edge*)(&aSE));
490 // !!<- process edges that are all on theRef
492 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
493 aP2D, aP3D, theContext);
494 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
500 //=======================================================================
501 // function: ComputeState
503 //=======================================================================
504 TopAbs_State BOPTools_AlgoTools::ComputeState
505 (const TopoDS_Vertex& theV,
506 const TopoDS_Solid& theRef,
507 const Standard_Real theTol,
508 Handle(IntTools_Context)& theContext)
513 aP3D=BRep_Tool::Pnt(theV);
514 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
518 //=======================================================================
519 // function: ComputeState
521 //=======================================================================
522 TopAbs_State BOPTools_AlgoTools::ComputeState
523 (const TopoDS_Edge& theE,
524 const TopoDS_Solid& theRef,
525 const Standard_Real theTol,
526 Handle(IntTools_Context)& theContext)
528 Standard_Real aT1, aT2, aT = 0.;
530 Handle(Geom_Curve) aC3D;
533 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
536 //it means that we are in degenerated edge
537 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
539 return TopAbs_UNKNOWN;
541 aP3D=BRep_Tool::Pnt(aV);
544 Standard_Boolean bF2Inf, bL2Inf;
545 Standard_Real dT=10.;
547 bF2Inf = Precision::IsNegativeInfinite(aT1);
548 bL2Inf = Precision::IsPositiveInfinite(aT2);
550 if (bF2Inf && !bL2Inf) {
553 else if (!bF2Inf && bL2Inf) {
556 else if (bF2Inf && bL2Inf) {
560 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
565 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
570 //=======================================================================
571 // function: ComputeState
573 //=======================================================================
574 TopAbs_State BOPTools_AlgoTools::ComputeState
576 const TopoDS_Solid& theRef,
577 const Standard_Real theTol,
578 Handle(IntTools_Context)& theContext)
582 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
583 aSC.Perform(theP, theTol);
589 //=======================================================================
590 //function : IsInternalFace
592 //=======================================================================
593 Standard_Integer BOPTools_AlgoTools::IsInternalFace
594 (const TopoDS_Face& theFace,
595 const TopoDS_Solid& theSolid,
596 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
597 const Standard_Real theTol,
598 Handle(IntTools_Context)& theContext)
600 Standard_Boolean bDegenerated;
601 Standard_Integer aNbF, iRet, iFound;
602 TopAbs_Orientation aOr;
604 TopExp_Explorer aExp;
605 BOPCol_ListIteratorOfListOfShape aItF;
607 // For all invoked functions: [::IsInternalFace(...)]
608 // the returned value iRet means:
609 // iRet=0; - state is not IN
610 // iRet=1; - state is IN
611 // iRet=2; - state can not be found by the method of angles
613 // For this function the returned value iRet means:
614 // iRet=0; - state is not IN
615 // iRet=1; - state is IN
618 // 1 Try to find an edge from theFace in theMEF
620 aExp.Init(theFace, TopAbs_EDGE);
621 for(; aExp.More(); aExp.Next()) {
622 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
623 if (!theMEF.Contains(aE)) {
629 aOr=aE.Orientation();
630 if (aOr==TopAbs_INTERNAL) {
633 bDegenerated=BRep_Tool::Degenerated(aE);
638 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
641 return iRet; // it can not be so
645 // aE is internal edge on aLF.First()
646 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
647 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
648 if (aE1.Orientation()!=TopAbs_INTERNAL) {
653 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1,
659 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
660 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
662 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
663 // treat as it was for 1 face
664 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
672 return iRet; // it can not be so
674 else { // aNbF=2,4,6,8,...
675 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF,
679 }//for(; aExp.More(); aExp.Next()) {
682 // the face has no shared edges with the solid
690 //========================================
691 // 2. Classify face using classifier
694 BOPCol_IndexedMapOfShape aBounds;
696 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
698 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid,
699 theTol, aBounds, theContext);
701 iRet=(aState==TopAbs_IN)? 1 : 0;
705 //=======================================================================
706 //function : IsInternalFace
708 //=======================================================================
709 Standard_Integer BOPTools_AlgoTools::IsInternalFace
710 (const TopoDS_Face& theFace,
711 const TopoDS_Edge& theEdge,
712 BOPCol_ListOfShape& theLF,
713 Handle(IntTools_Context)& theContext)
715 Standard_Integer aNbF, iRet;
721 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
722 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
723 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
729 BOPTools_ListOfCoupleOfShape aLCFF;
730 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
732 FindFacePairs(theEdge, theLF, aLCFF, theContext);
734 aIt.Initialize(aLCFF);
735 for (; aIt.More(); aIt.Next()) {
736 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
738 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
739 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
740 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
749 //=======================================================================
750 //function : IsInternalFace
752 //=======================================================================
753 Standard_Integer BOPTools_AlgoTools::IsInternalFace
754 (const TopoDS_Face& theFace,
755 const TopoDS_Edge& theEdge,
756 const TopoDS_Face& theFace1,
757 const TopoDS_Face& theFace2,
758 Handle(IntTools_Context)& theContext)
760 Standard_Boolean bRet;
761 Standard_Integer iRet;
762 TopoDS_Edge aE1, aE2;
764 BOPTools_ListOfCoupleOfShape theLCSOff;
765 BOPTools_CoupleOfShape aCS1, aCS2;
767 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
768 if (aE1.Orientation()==TopAbs_INTERNAL) {
770 aE1.Orientation(TopAbs_FORWARD);
771 aE2.Orientation(TopAbs_REVERSED);
773 else if (theFace1==theFace2) {
775 aE1.Orientation(TopAbs_FORWARD);
776 aE2.Orientation(TopAbs_REVERSED);
779 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
782 aCS1.SetShape1(theEdge);
783 aCS1.SetShape2(theFace);
784 theLCSOff.Append(aCS1);
787 aCS2.SetShape2(theFace2);
788 theLCSOff.Append(aCS2);
790 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
792 iRet=0; // theFace is not internal
793 if (theFace.IsEqual(aFOff)) {
794 // theFace is internal
797 // theFace seems to be internal
803 //=======================================================================
804 //function : GetFaceOff
806 //=======================================================================
807 Standard_Boolean BOPTools_AlgoTools::GetFaceOff
808 (const TopoDS_Edge& theE1,
809 const TopoDS_Face& theF1,
810 BOPTools_ListOfCoupleOfShape& theLCSOff,
811 TopoDS_Face& theFOff,
812 Handle(IntTools_Context)& theContext)
814 Standard_Boolean bRet;
815 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
816 Standard_Real aUmin, aUsup, aVmin, aVsup, aPA;
817 gp_Pnt aPn1, aPn2, aPx;
818 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
820 TopAbs_Orientation aOr;
821 Handle(Geom_Curve)aC3D;
822 Handle(Geom_Plane) aPL;
823 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
824 GeomAPI_ProjectPointOnSurf aProjPL;
826 aPA=Precision::Angular();
829 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
830 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
833 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
834 gp_Dir aDTgt(aVTgt), aDTgt2;
835 aOr = theE1.Orientation();
837 aPL = new Geom_Plane(aPx, aDTgt);
838 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
839 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
841 aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx);
842 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext,
848 aIt.Initialize(theLCSOff);
849 for (; aIt.More(); aIt.Next()) {
850 const BOPTools_CoupleOfShape& aCS=aIt.Value();
851 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
852 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
854 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
855 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext,
858 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
861 aAngle=aTwoPI+aAngle;
868 else if (aF2.IsSame(theF1)) {
873 if (fabs(aAngle-aAngleMin)<aPA) {
874 // the minimal angle can not be found
878 if (aAngle<aAngleMin){
882 else if (aAngle==aAngleMin) {
883 // the minimal angle can not be found
889 //=======================================================================
890 //function : GetEdgeOff
892 //=======================================================================
893 Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
894 const TopoDS_Face& theF2,
897 Standard_Boolean bFound;
898 TopAbs_Orientation aOr1, aOr1C, aOr2;
899 TopExp_Explorer anExp;
901 bFound=Standard_False;
902 aOr1=theE1.Orientation();
903 aOr1C=TopAbs::Reverse(aOr1);
905 anExp.Init(theF2, TopAbs_EDGE);
906 for (; anExp.More(); anExp.Next()) {
907 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
908 if (aEF2.IsSame(theE1)) {
909 aOr2=aEF2.Orientation();
920 //=======================================================================
921 //function : AreFacesSameDomain
923 //=======================================================================
924 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
925 (const TopoDS_Face& theF1,
926 const TopoDS_Face& theF2,
927 Handle(IntTools_Context)& theContext)
929 Standard_Boolean bFlag;
930 Standard_Integer iErr;
931 Standard_Real aTolF1, aTolF2, aTol;
934 TopoDS_Face aF1, aF2;
936 TopExp_Explorer aExp;
938 bFlag=Standard_False;
941 aF1.Orientation(TopAbs_FORWARD);
943 aF2.Orientation(TopAbs_FORWARD);
945 aTolF1=BRep_Tool::Tolerance(aF1);
947 aExp.Init(aF1, TopAbs_EDGE);
948 for (; aExp.More(); aExp.Next()) {
949 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
950 if (!BRep_Tool::Degenerated(aE1)) {
951 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
952 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
956 aTolF2=BRep_Tool::Tolerance(aF2);
959 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
962 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
968 //=======================================================================
969 //function : CheckSameGeom
971 //=======================================================================
972 Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
973 (const TopoDS_Face& theF1,
974 const TopoDS_Face& theF2,
975 Handle(IntTools_Context)& theContext)
977 Standard_Boolean bRet;
978 Standard_Real aTolF1, aTolF2, aTol;
981 TopExp_Explorer aExp;
984 aExp.Init(theF1, TopAbs_EDGE);
985 for (; aExp.More(); aExp.Next()) {
986 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
987 if (!BRep_Tool::Degenerated(aE)) {
988 aTolF1=BRep_Tool::Tolerance(theF1);
989 aTolF2=BRep_Tool::Tolerance(theF2);
991 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
992 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
998 //=======================================================================
1001 //=======================================================================
1002 Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
1003 const TopoDS_Face& theF2)
1005 Standard_Integer iSense=0;
1006 gp_Dir aDNF1, aDNF2;
1007 TopoDS_Edge aE1, aE2;
1008 TopExp_Explorer aExp;
1010 aExp.Init(theF1, TopAbs_EDGE);
1011 for (; aExp.More(); aExp.Next()) {
1012 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
1013 if (!BRep_Tool::Degenerated(aE1)) {
1014 if (!BRep_Tool::IsClosed(aE1, theF1)) {
1020 aExp.Init(theF2, TopAbs_EDGE);
1021 for (; aExp.More(); aExp.Next()) {
1022 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
1023 if (!BRep_Tool::Degenerated(aE2)) {
1024 if (!BRep_Tool::IsClosed(aE2, theF2)) {
1025 if (aE2.IsSame(aE1)) {
1037 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
1038 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
1040 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1044 //=======================================================================
1045 // function: IsSplitToReverse
1047 //=======================================================================
1048 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1049 (const TopoDS_Shape& theSp,
1050 const TopoDS_Shape& theSr,
1051 Handle(IntTools_Context)& theContext)
1053 Standard_Boolean bRet;
1054 TopAbs_ShapeEnum aType;
1056 bRet=Standard_False;
1058 aType=theSp.ShapeType();
1061 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1062 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1063 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1068 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1069 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1070 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1079 //=======================================================================
1080 //function :IsSplitToReverse
1082 //=======================================================================
1083 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1084 (const TopoDS_Face& theFSp,
1085 const TopoDS_Face& theFSr,
1086 Handle(IntTools_Context)& theContext)
1088 Standard_Boolean bRet, bFound, bInFace;
1089 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1090 gp_Pnt aPFSp, aPFSr;
1093 Handle(Geom_Surface) aSr, aSp;
1094 TopAbs_Orientation aOrSr, aOrSp;
1095 TopExp_Explorer anExp;
1098 bRet=Standard_False;
1100 aSr=BRep_Tool::Surface(theFSr);
1101 aSp=BRep_Tool::Surface(theFSp);
1103 aOrSr=theFSr.Orientation();
1104 aOrSp=theFSp.Orientation();
1105 bRet=(aOrSr!=aOrSp);
1109 bFound=Standard_False;
1110 anExp.Init(theFSp, TopAbs_EDGE);
1111 for (; anExp.More(); anExp.Next()) {
1112 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1113 if (!BRep_Tool::Degenerated(aESp)) {
1114 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1121 Standard_Boolean bFlag;
1122 Standard_Integer iErr;
1125 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp,
1131 aP2DFSp.Coord(aU, aV);
1132 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1137 if (theFSp.Orientation()==TopAbs_REVERSED){
1142 BRep_Tool::Range(aESp, aT1, aT2);
1143 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
1144 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT,
1149 // Parts of theContext->ComputeVS(..)
1150 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1151 aProjector.Perform(aPFSp);
1152 if (!aProjector.IsDone()) {
1156 aProjector.LowerDistanceParameters(aU, aV);
1157 gp_Pnt2d aP2D(aU, aV);
1158 bInFace=theContext->IsPointInFace (theFSr, aP2D);
1163 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1166 gp_Dir aDNFSr=aDD1U^aDD1V;
1167 if (theFSr.Orientation()==TopAbs_REVERSED){
1171 aScPr=aDNFSp*aDNFSr;
1176 //=======================================================================
1177 //function :IsSplitToReverse
1179 //=======================================================================
1180 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1181 (const TopoDS_Edge& aEF1,
1182 const TopoDS_Edge& aEF2,
1183 Handle(IntTools_Context)& theContext)
1185 Standard_Boolean bRet, bIsDegenerated;
1187 bRet=Standard_False;
1188 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1189 BRep_Tool::Degenerated(aEF2));
1190 if (bIsDegenerated) {
1195 TopAbs_Orientation aOrE, aOrSp;
1196 Handle(Geom_Curve)aC1, aC2;
1198 aC2=BRep_Tool::Curve(aEF2, a, b);
1199 aC1=BRep_Tool::Curve(aEF1, a, b);
1202 aOrE=aEF2.Orientation();
1203 aOrSp=aEF1.Orientation();
1208 Standard_Real aT1, aT2, aScPr;
1212 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1214 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1217 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1219 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1228 //=======================================================================
1231 //=======================================================================
1232 Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1233 const TopoDS_Shape& aFace)
1235 Standard_Boolean bIsHole;
1236 Standard_Integer i, aNbS;
1237 Standard_Real aT1, aT2, aS;
1238 Standard_Real aU1, aU, dU;
1239 Standard_Real aX1, aY1, aX0, aY0;
1240 TopAbs_Orientation aOr;
1242 gp_Pnt2d aP2D0, aP2D1;
1243 Handle(Geom2d_Curve) aC2D;
1244 TopoDS_Face aF, aFF;
1245 TopoDS_Iterator aItW;
1247 bIsHole=Standard_False;
1249 aF=(*(TopoDS_Face *)(&aFace));
1251 aFF.Orientation(TopAbs_FORWARD);
1254 aItW.Initialize(aW);
1255 for (; aItW.More(); aItW.Next()) {
1256 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1257 aOr=aE.Orientation();
1258 if (!(aOr==TopAbs_FORWARD ||
1259 aOr==TopAbs_REVERSED)) {
1263 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1264 if (aC2D.IsNull()) {
1268 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1269 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1274 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1277 if (aOr==TopAbs_REVERSED) {
1283 aC2D->D0(aU, aP2D0);
1284 for(i=2; i<=aNbS; i++) {
1286 aC2D->D0(aU, aP2D1);
1287 aP2D0.Coord(aX0, aY0);
1288 aP2D1.Coord(aX1, aY1);
1290 aS=aS+(aY0+aY1)*(aX1-aX0);
1294 }//for (; aItW.More(); aItW.Next()) {
1299 //=======================================================================
1300 // function: MakeContainer
1302 //=======================================================================
1303 void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1309 case TopAbs_COMPOUND:{
1311 aBB.MakeCompound(aC);
1316 case TopAbs_COMPSOLID:{
1317 TopoDS_CompSolid aCS;
1318 aBB.MakeCompSolid(aCS);
1324 TopoDS_Solid aSolid;
1325 aBB.MakeSolid(aSolid);
1332 TopoDS_Shell aShell;
1333 aBB.MakeShell(aShell);
1340 aBB.MakeWire(aWire);
1349 //=======================================================================
1350 // function: MakePCurve
1352 //=======================================================================
1353 void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1354 const TopoDS_Face& aF1,
1355 const TopoDS_Face& aF2,
1356 const IntTools_Curve& aIC,
1357 const Standard_Boolean bPC1,
1358 const Standard_Boolean bPC2)
1362 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1363 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1366 Standard_Boolean bPC;
1368 aTolE=BRep_Tool::Tolerance(aE);
1370 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
1371 Handle(Geom_TrimmedCurve)aC3DETrim=
1372 new Geom_TrimmedCurve(aC3DE, aT1, aT2);
1374 for (i=0; i<2; ++i) {
1375 bPC = !i ? bPC1 : bPC2;
1382 aC2Dx1=aIC.FirstCurve2d();
1386 aC2Dx1=aIC.SecondCurve2d();
1389 aFFWD.Orientation(TopAbs_FORWARD);
1392 if (aC2D.IsNull()) {
1393 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1394 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1395 aOutFirst, aOutLast,
1399 if (aC3DE->IsPeriodic()) {
1400 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D,
1404 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D,
1408 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1409 //BRepLib::SameParameter(aE);
1411 BRepLib::SameParameter(aE);
1413 //=======================================================================
1414 // function: MakeEdge
1416 //=======================================================================
1417 void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1418 const TopoDS_Vertex& theV1,
1419 const Standard_Real theT1,
1420 const TopoDS_Vertex& theV2,
1421 const Standard_Real theT2,
1422 const Standard_Real theTolR3D,
1425 Standard_Real aTolV;
1428 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2,
1431 aBB.UpdateEdge(theE, theTolR3D);
1433 aTolV=BRep_Tool::Tolerance(theV1);
1434 if (aTolV<theTolR3D) {
1435 aBB.UpdateVertex(theV1, theTolR3D);
1438 aTolV=BRep_Tool::Tolerance(theV2);
1439 if (aTolV<theTolR3D) {
1440 aBB.UpdateVertex(theV2, theTolR3D);
1443 //=======================================================================
1444 // function: ComputeVV
1446 //=======================================================================
1447 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1449 const Standard_Real aTolP2)
1451 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1454 aTolV1=BRep_Tool::Tolerance(aV1);
1456 aTolSum=aTolV1+aTolP2;
1457 aTolSum2=aTolSum*aTolSum;
1459 aP1=BRep_Tool::Pnt(aV1);
1461 aD2=aP1.SquareDistance(aP2);
1467 //=======================================================================
1468 // function: ComputeVV
1470 //=======================================================================
1471 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1472 const TopoDS_Vertex& aV2)
1474 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1477 aTolV1=BRep_Tool::Tolerance(aV1);
1478 aTolV2=BRep_Tool::Tolerance(aV2);
1479 aTolSum=aTolV1+aTolV2;
1480 aTolSum2=aTolSum*aTolSum;
1482 aP1=BRep_Tool::Pnt(aV1);
1483 aP2=BRep_Tool::Pnt(aV2);
1485 aD2=aP1.SquareDistance(aP2);
1491 //=======================================================================
1492 // function: MakeVertex
1494 //=======================================================================
1495 void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
1496 TopoDS_Vertex& aVnew)
1498 Standard_Integer aNb;
1499 Standard_Real aTi, aDi, aDmax;
1501 gp_XYZ aXYZ(0.,0.,0.), aXYZi;
1502 BOPCol_ListIteratorOfListOfShape aIt;
1506 aIt.Initialize(aLV);
1507 for (; aIt.More(); aIt.Next()) {
1508 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1509 aPi=BRep_Tool::Pnt(aVi);
1514 aXYZ.Divide((Standard_Real)aNb);
1518 aIt.Initialize(aLV);
1519 for (; aIt.More(); aIt.Next()) {
1520 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1521 aPi=BRep_Tool::Pnt(aVi);
1522 aTi=BRep_Tool::Tolerance(aVi);
1523 aDi=aP.SquareDistance(aPi);
1532 aBB.MakeVertex (aVnew, aP, aDmax);
1535 //=======================================================================
1536 //function : GetEdgeOnFace
1538 //=======================================================================
1539 Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
1540 (const TopoDS_Edge& theE1,
1541 const TopoDS_Face& theF2,
1544 Standard_Boolean bFound;
1545 TopoDS_Iterator aItF, aItW;
1547 bFound=Standard_False;
1549 aItF.Initialize(theF2);
1550 for (; aItF.More(); aItF.Next()) {
1551 const TopoDS_Shape& aW=aItF.Value();
1552 aItW.Initialize(aW);
1553 for (; aItW.More(); aItW.Next()) {
1554 const TopoDS_Shape& aE=aItW.Value();
1555 if (aE.IsSame(theE1)) {
1556 theE2=(*(TopoDS_Edge*)(&aE));
1564 //=======================================================================
1565 //function : FindFacePairs
1567 //=======================================================================
1568 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1569 const BOPCol_ListOfShape& thLF,
1570 BOPTools_ListOfCoupleOfShape& theLCFF,
1571 Handle(IntTools_Context)& theContext)
1573 Standard_Boolean bFound;
1574 Standard_Integer i, aNbCEF;
1575 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
1576 BOPCol_MapOfShape aMFP;
1577 TopoDS_Face aF1, aF2;
1578 TopoDS_Edge aEL, aE1;
1579 BOPCol_ListIteratorOfListOfShape aItLF;
1580 BOPTools_CoupleOfShape aCEF, aCFF;
1581 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1582 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1584 bFound=Standard_True;
1587 aItLF.Initialize(thLF);
1588 for (; aItLF.More(); aItLF.Next()) {
1589 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1591 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1593 return bFound; // it can not be so
1596 aCEF.SetShape1(aEL);
1597 aCEF.SetShape2(aFL);
1601 aNbCEF=aLCEF.Extent();
1606 aIt.Initialize(aLCEF);
1607 for (i=0; aIt.More(); aIt.Next(), ++i) {
1608 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1609 const TopoDS_Shape& aEx=aCSx.Shape1();
1610 const TopoDS_Shape& aFx=aCSx.Shape2();
1612 aOr=aEx.Orientation();
1615 aOrC=TopAbs::Reverse(aOr);
1616 aE1=(*(TopoDS_Edge*)(&aEx));
1617 aF1=(*(TopoDS_Face*)(&aFx));
1623 aLCEFx.Append(aCSx);
1629 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1631 aCFF.SetShape1(aF1);
1632 aCFF.SetShape2(aF2);
1633 theLCFF.Append(aCFF);
1642 aIt.Initialize(aLCEFx);
1643 for (; aIt.More(); aIt.Next()) {
1644 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1645 const TopoDS_Shape& aFx=aCSx.Shape2();
1646 if (!aMFP.Contains(aFx)) {
1651 aNbCEF=aLCEF.Extent();
1656 //=======================================================================
1657 //function : AngleWithRef
1659 //=======================================================================
1660 Standard_Real AngleWithRef(const gp_Dir& theD1,
1661 const gp_Dir& theD2,
1662 const gp_Dir& theDRef)
1664 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1669 const gp_XYZ& aXYZ1=theD1.XYZ();
1670 const gp_XYZ& aXYZ2=theD2.XYZ();
1671 aXYZ=aXYZ1.Crossed(aXYZ2);
1672 aSinus=aXYZ.Modulus();
1673 aCosinus=theD1*theD2;
1677 aBeta=aHalfPI*(1.-aCosinus);
1680 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1683 aScPr=aXYZ.Dot(theDRef.XYZ());
1689 //=======================================================================
1690 // function: IsBlockInOnFace
1692 //=======================================================================
1693 Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
1694 (const IntTools_Range& aShrR,
1695 const TopoDS_Face& aF,
1696 const TopoDS_Edge& aE1,
1697 Handle(IntTools_Context)& aContext)
1699 Standard_Boolean bFlag;
1700 Standard_Real f1, l1, ULD, VLD;
1704 aShrR.Range(f1, l1);
1705 Standard_Real dt=0.0075, k;//dt=0.001, k;
1711 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1713 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1714 aProjector.Perform(aP11);
1716 bFlag=aProjector.IsDone();
1721 aProjector.LowerDistanceParameters(ULD, VLD);
1722 aP2D.SetCoord(ULD, VLD);
1724 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1731 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1733 aProjector.Perform(aP12);
1735 bFlag=aProjector.IsDone();
1740 aProjector.LowerDistanceParameters(ULD, VLD);
1741 aP2D.SetCoord(ULD, VLD);
1743 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1749 // Treatment intemediate
1750 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1751 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1752 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1754 aProjector.Perform(aP12);
1756 bFlag=aProjector.IsDone();
1761 aTolE=BRep_Tool::Tolerance(aE1);
1762 aTolF=BRep_Tool::Tolerance(aF);
1764 aDist=aProjector.LowerDistance();
1766 return Standard_False;
1769 aProjector.LowerDistanceParameters(ULD, VLD);
1770 aP2D.SetCoord(ULD, VLD);
1772 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1780 //=======================================================================
1781 //function : IsMicroEdge
1783 //=======================================================================
1784 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
1785 (const TopoDS_Edge& aE,
1786 const Handle(IntTools_Context)& aCtx)
1788 Standard_Boolean bRet;
1789 Standard_Integer iErr;
1790 Standard_Real aT1, aT2, aTmp;
1791 Handle(Geom_Curve) aC3D;
1792 TopoDS_Vertex aV1, aV2;
1794 bRet=(BRep_Tool::Degenerated(aE) ||
1795 !BRep_Tool::IsGeometric(aE));
1800 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1801 TopExp::Vertices(aE, aV1, aV2);
1802 aT1=BRep_Tool::Parameter(aV1, aE);
1803 aT2=BRep_Tool::Parameter(aV2, aE);
1810 IntTools_ShrunkRange aSR;
1811 aSR.SetContext(aCtx);
1812 aSR.SetData(aE, aT1, aT2, aV1, aV2);
1814 iErr=aSR.ErrorStatus();
1820 //=======================================================================
1821 //function : GetFaceDir
1822 //purpose : Get binormal direction for the face in the point aP
1823 //=======================================================================
1824 void GetFaceDir(const TopoDS_Edge& aE,
1825 const TopoDS_Face& aF,
1827 const Standard_Real aT,
1828 const gp_Dir& aDTgt,
1831 Handle(IntTools_Context)& theContext,
1832 GeomAPI_ProjectPointOnSurf& aProjPL,
1833 const Standard_Real aDt)
1835 Standard_Real aTolE;
1838 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1839 if (aF.Orientation()==TopAbs_REVERSED){
1843 aTolE=BRep_Tool::Tolerance(aE);
1846 if (!FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt, aTolE)) {
1847 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx,
1849 aProjPL.Perform(aPx);
1850 aPx = aProjPL.NearestPoint();
1851 gp_Vec aVec(aP, aPx);
1852 aDB.SetXYZ(aVec.XYZ());
1855 //=======================================================================
1856 //function : FindPointInFace
1857 //purpose : Find a point in the face in direction of <aDB>
1858 //=======================================================================
1859 Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
1863 Handle(IntTools_Context)& theContext,
1864 GeomAPI_ProjectPointOnSurf& aProjPL,
1865 const Standard_Real aDt,
1866 const Standard_Real aTolE)
1868 Standard_Integer aNbItMax;
1869 Standard_Real aDist, aDTol, aPM, anEps;
1870 Standard_Boolean bRet;
1873 aDTol = Precision::Angular();
1874 aPM = aP.XYZ().Modulus();
1876 aDTol = 5.e-16 * aPM;
1878 bRet = Standard_False;
1880 anEps = Precision::SquareConfusion();
1882 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1886 if (!aProj.IsDone()) {
1889 aPS=aProj.NearestPoint();
1890 aProjPL.Perform(aPS);
1891 aPS=aProjPL.NearestPoint();
1893 aPS.SetXYZ(aPS.XYZ()+2.*aTolE*aDB.XYZ());
1895 if (!aProj.IsDone()) {
1898 aPS=aProj.NearestPoint();
1899 aProjPL.Perform(aPS);
1900 aPS=aProjPL.NearestPoint();
1903 aP1.SetXYZ(aPS.XYZ()+aDt*aDB.XYZ());
1906 if (!aProj.IsDone()) {
1909 aPOut = aProj.NearestPoint();
1910 aDist = aProj.LowerDistance();
1912 aProjPL.Perform(aPOut);
1913 aPOut = aProjPL.NearestPoint();
1915 gp_Vec aV(aPS, aPOut);
1916 if (aV.SquareMagnitude() < anEps) {
1919 aDB.SetXYZ(aV.XYZ());
1920 } while (aDist > aDTol && --aNbItMax);
1922 bRet = aDist < aDTol;
1925 //=======================================================================
1926 //function : MinStep3D
1928 //=======================================================================
1929 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
1930 const TopoDS_Face& theF1,
1931 const BOPTools_ListOfCoupleOfShape& theLCS,
1934 Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin, aR;
1935 BOPTools_CoupleOfShape aCS1;
1936 BOPTools_ListOfCoupleOfShape aLCS;
1937 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1938 BRepAdaptor_Surface aBAS;
1941 aCS1.SetShape1(theE1);
1942 aCS1.SetShape2(theF1);
1945 aTolE = BRep_Tool::Tolerance(theE1);
1949 aIt.Initialize(aLCS);
1950 for (; aIt.More(); aIt.Next()) {
1951 const BOPTools_CoupleOfShape& aCS = aIt.Value();
1952 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2()));
1954 aTolF = BRep_Tool::Tolerance(aF);
1955 aDt = 2*(aTolE + aTolF);
1958 aBAS.Initialize(aF, Standard_False);
1959 GeomAbs_SurfaceType aSType = aBAS.GetType();
1961 case GeomAbs_Cylinder: {
1962 aR = aBAS.Cylinder().Radius();
1965 case GeomAbs_Cone: {
1966 gp_Lin aL(aBAS.Cone().Axis());
1967 aR = aL.Distance(aP);
1970 case GeomAbs_Sphere: {
1971 aDtMin = Max(aDtMin, 5.e-4);
1972 aR = aBAS.Sphere().Radius();
1975 case GeomAbs_Torus: {
1976 aR = aBAS.Torus().MajorRadius();
1980 aDtMin = Max(aDtMin, 5.e-4);
1985 Standard_Real d = 10*Precision::PConfusion();
1986 aDtMin = Max(aDtMin, sqrt(d*d + 2*d*aR));
1994 if (aDtMax < aDtMin) {
2000 //=======================================================================
2001 //function : IsOpenShell
2003 //=======================================================================
2004 Standard_Boolean BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
2006 Standard_Boolean bRet;
2007 Standard_Integer i, aNbE, aNbF;
2008 TopAbs_Orientation aOrF;
2009 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
2010 BOPCol_ListIteratorOfListOfShape aItLS;
2012 bRet=Standard_False;
2014 BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF);
2017 for (i=1; i<=aNbE; ++i) {
2018 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i));
2019 if (BRep_Tool::Degenerated(aE)) {
2024 const BOPCol_ListOfShape& aLF=aMEF(i);
2025 aItLS.Initialize(aLF);
2026 for (; aItLS.More(); aItLS.Next()) {
2027 const TopoDS_Shape& aF=aItLS.Value();
2028 aOrF=aF.Orientation();
2029 if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
2043 //=======================================================================
2044 //function : IsInvertedSolid
2046 //=======================================================================
2047 Standard_Boolean BOPTools_AlgoTools::IsInvertedSolid
2048 (const TopoDS_Solid& aSolid)
2050 Standard_Real aTolS;
2051 TopAbs_State aState;
2052 BRepClass3d_SolidClassifier aSC(aSolid);
2055 aSC.PerformInfinitePoint(aTolS);
2057 return (aState==TopAbs_IN);