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);
104 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
105 const TopoDS_Face& theF1,
106 const BOPTools_ListOfCoupleOfShape& theLCS,
109 //=======================================================================
110 // function: MakeConnexityBlocks
112 //=======================================================================
113 void BOPTools_AlgoTools::MakeConnexityBlocks
114 (const TopoDS_Shape& theS,
115 const TopAbs_ShapeEnum theType1,
116 const TopAbs_ShapeEnum theType2,
117 BOPCol_ListOfShape& theLCB)
119 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
123 TopExp_Explorer aExp;
124 BOPCol_MapOfShape aMP;
125 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
126 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
127 BOPCol_ListIteratorOfListOfShape aItLF;
130 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
133 aIt.Initialize(theS);
134 for (; aIt.More(); aIt.Next()) {
135 const TopoDS_Shape& aF1=aIt.Value();
136 if (aMP.Contains(aF1)) {
147 aNbAdd = aMAdd.Extent();
148 for (i=1; i<=aNbAdd; ++i) {
149 const TopoDS_Shape& aF=aMAdd(i);
151 aExp.Init(aF, theType1);
152 for (; aExp.More(); aExp.Next()) {
153 const TopoDS_Shape& aE=aExp.Current();
155 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
156 aItLF.Initialize(aLF);
157 for (; aItLF.More(); aItLF.Next()) {
158 const TopoDS_Shape& aFx=aItLF.Value();
159 if (aFx.IsSame(aF)) {
162 if (aMCB.Contains(aFx)) {
167 }//for (; aExp.More(); aExp.Next()){
169 }// for (i=1; i<=aNbAdd; ++i) {
171 aNbAdd1=aMAdd1.Extent();
173 break;// ->make new CB from aMCB
177 for (i=1; i<=aNbAdd1; ++i) {
178 const TopoDS_Shape& aFAdd = aMAdd1(i);
185 aBB.MakeCompound(aC);
187 for (i=1; i<=aNbF; ++i) {
188 const TopoDS_Shape& aF=aMCB(i);
194 }// for (; aIt.More(); aIt.Next())
196 //=======================================================================
197 // function: OrientFacesOnShell
199 //=======================================================================
200 void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
202 Standard_Boolean bIsProcessed1, bIsProcessed2;
203 Standard_Integer i, aNbE, aNbF, j;
204 TopAbs_Orientation anOrE1, anOrE2;
205 TopoDS_Face aF1x, aF2x;
206 TopoDS_Shape aShellNew;
207 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
208 BOPCol_IndexedMapOfShape aProcessedFaces;
211 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
213 BOPTools::MapShapesAndAncestors(aShell,
214 TopAbs_EDGE, TopAbs_FACE,
216 aNbE=aEFMap.Extent();
218 // One seam edge in aEFMap contains 2 equivalent faces.
219 for (i=1; i<=aNbE; ++i) {
220 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
223 BOPCol_ListOfShape aLFTmp;
224 BOPCol_IndexedMapOfShape aFM;
226 BOPCol_ListIteratorOfListOfShape anIt(aLF);
227 for (; anIt.More(); anIt.Next()) {
228 const TopoDS_Shape& aF=anIt.Value();
229 if (!aFM.Contains(aF)) {
240 for (i=1; i<=aNbE; ++i) {
241 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
242 if (BRep_Tool::Degenerated(aE)) {
246 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
252 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
253 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
255 bIsProcessed1=aProcessedFaces.Contains(aF1);
256 bIsProcessed2=aProcessedFaces.Contains(aF2);
257 if (bIsProcessed1 && bIsProcessed2) {
261 if (!bIsProcessed1 && !bIsProcessed2) {
262 aProcessedFaces.Add(aF1);
263 aBB.Add(aShellNew, aF1);
264 bIsProcessed1=!bIsProcessed1;
269 j=aProcessedFaces.FindIndex(aF1);
270 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
275 j=aProcessedFaces.FindIndex(aF2);
276 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
279 anOrE1=Orientation(aE, aF1x);
280 anOrE2=Orientation(aE, aF2x);
282 if (bIsProcessed1 && !bIsProcessed2) {
283 if (anOrE1==anOrE2) {
284 if (!BRep_Tool::IsClosed(aE, aF1) &&
285 !BRep_Tool::IsClosed(aE, aF2)) {
289 aProcessedFaces.Add(aF2);
290 aBB.Add(aShellNew, aF2);
292 else if (!bIsProcessed1 && bIsProcessed2) {
293 if (anOrE1==anOrE2) {
294 if (!BRep_Tool::IsClosed(aE, aF1) &&
295 !BRep_Tool::IsClosed(aE, aF2)) {
299 aProcessedFaces.Add(aF1);
300 aBB.Add(aShellNew, aF1);
305 for (i=1; i<=aNbE; ++i) {
306 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
307 if (BRep_Tool::Degenerated(aE)) {
311 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
314 BOPCol_ListIteratorOfListOfShape anIt(aLF);
315 for(; anIt.More(); anIt.Next()) {
316 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
317 if (!aProcessedFaces.Contains(aF)) {
318 aProcessedFaces.Add(aF);
319 aBB.Add(aShellNew, aF);
326 //=======================================================================
327 //function : Orientation
329 //=======================================================================
330 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
331 const TopoDS_Face& aF)
333 TopAbs_Orientation anOr=TopAbs_INTERNAL;
335 TopExp_Explorer anExp;
336 anExp.Init(aF, TopAbs_EDGE);
337 for (; anExp.More(); anExp.Next()) {
338 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
339 if (anEF1.IsSame(anE)) {
340 anOr=anEF1.Orientation();
346 //=======================================================================
347 // function: MakeConnexityBlock.
349 //=======================================================================
350 void BOPTools_AlgoTools::MakeConnexityBlock
351 (BOPCol_ListOfShape& theLFIn,
352 BOPCol_IndexedMapOfShape& theMEAvoid,
353 BOPCol_ListOfShape& theLCB,
354 const Handle(NCollection_BaseAllocator)& theAllocator)
356 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
357 TopExp_Explorer aExp;
358 BOPCol_ListIteratorOfListOfShape aIt;
360 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
361 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
362 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
363 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
366 aNbF=theLFIn.Extent();
367 aIt.Initialize(theLFIn);
368 for (; aIt.More(); aIt.Next()) {
369 const TopoDS_Shape& aF=aIt.Value();
370 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
374 const TopoDS_Shape& aF1=theLFIn.First();
379 aNbAdd = aMAdd.Extent();
380 for (i=1; i<=aNbAdd; ++i) {
381 const TopoDS_Shape& aF=aMAdd(i);
384 aExp.Init(aF, TopAbs_EDGE);
385 for (; aExp.More(); aExp.Next()) {
386 const TopoDS_Shape& aE=aExp.Current();
387 if (theMEAvoid.Contains(aE)){
391 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
393 for (; aIt.More(); aIt.Next()) {
394 const TopoDS_Shape& aFx=aIt.Value();
395 if (aFx.IsSame(aF)) {
398 if (aMCB.Contains(aFx)) {
403 }//for (; aExp.More(); aExp.Next()){
405 }// for (i=1; i<=aNbAdd; ++i) {
407 aNbAdd1=aMAdd1.Extent();
413 for (i=1; i<=aNbAdd1; ++i) {
414 const TopoDS_Shape& aFAdd=aMAdd1(i);
422 for (i=1; i<=aNbF; ++i) {
423 const TopoDS_Shape& aF=aMCB(i);
427 //=======================================================================
428 // function: ComputeStateByOnePoint
430 //=======================================================================
431 TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
432 (const TopoDS_Shape& theS,
433 const TopoDS_Solid& theRef,
434 const Standard_Real theTol,
435 Handle(IntTools_Context)& theContext)
438 TopAbs_ShapeEnum aType;
440 aState=TopAbs_UNKNOWN;
441 aType=theS.ShapeType();
442 if (aType==TopAbs_VERTEX) {
443 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
444 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
446 else if (aType==TopAbs_EDGE) {
447 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
448 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
453 //=======================================================================
454 // function: ComputeState
456 //=======================================================================
457 TopAbs_State BOPTools_AlgoTools::ComputeState
458 (const TopoDS_Face& theF,
459 const TopoDS_Solid& theRef,
460 const Standard_Real theTol,
461 BOPCol_IndexedMapOfShape& theBounds,
462 Handle(IntTools_Context)& theContext)
465 TopExp_Explorer aExp;
470 aState=TopAbs_UNKNOWN;
472 aExp.Init(theF, TopAbs_EDGE);
473 for (; aExp.More(); aExp.Next()) {
474 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
475 if (BRep_Tool::Degenerated(aSE)) {
479 if (!theBounds.Contains(aSE)) {
480 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
481 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol,
486 aE1=(*(TopoDS_Edge*)(&aSE));
489 // !!<- process edges that are all on theRef
491 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
492 aP2D, aP3D, theContext);
493 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
499 //=======================================================================
500 // function: ComputeState
502 //=======================================================================
503 TopAbs_State BOPTools_AlgoTools::ComputeState
504 (const TopoDS_Vertex& theV,
505 const TopoDS_Solid& theRef,
506 const Standard_Real theTol,
507 Handle(IntTools_Context)& theContext)
512 aP3D=BRep_Tool::Pnt(theV);
513 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
517 //=======================================================================
518 // function: ComputeState
520 //=======================================================================
521 TopAbs_State BOPTools_AlgoTools::ComputeState
522 (const TopoDS_Edge& theE,
523 const TopoDS_Solid& theRef,
524 const Standard_Real theTol,
525 Handle(IntTools_Context)& theContext)
527 Standard_Real aT1, aT2, aT = 0.;
529 Handle(Geom_Curve) aC3D;
532 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
535 //it means that we are in degenerated edge
536 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
538 return TopAbs_UNKNOWN;
540 aP3D=BRep_Tool::Pnt(aV);
543 Standard_Boolean bF2Inf, bL2Inf;
544 Standard_Real dT=10.;
546 bF2Inf = Precision::IsNegativeInfinite(aT1);
547 bL2Inf = Precision::IsPositiveInfinite(aT2);
549 if (bF2Inf && !bL2Inf) {
552 else if (!bF2Inf && bL2Inf) {
555 else if (bF2Inf && bL2Inf) {
559 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
564 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
569 //=======================================================================
570 // function: ComputeState
572 //=======================================================================
573 TopAbs_State BOPTools_AlgoTools::ComputeState
575 const TopoDS_Solid& theRef,
576 const Standard_Real theTol,
577 Handle(IntTools_Context)& theContext)
581 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
582 aSC.Perform(theP, theTol);
588 //=======================================================================
589 //function : IsInternalFace
591 //=======================================================================
592 Standard_Integer BOPTools_AlgoTools::IsInternalFace
593 (const TopoDS_Face& theFace,
594 const TopoDS_Solid& theSolid,
595 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
596 const Standard_Real theTol,
597 Handle(IntTools_Context)& theContext)
599 Standard_Boolean bDegenerated;
600 Standard_Integer aNbF, iRet, iFound;
601 TopAbs_Orientation aOr;
603 TopExp_Explorer aExp;
604 BOPCol_ListIteratorOfListOfShape aItF;
606 // For all invoked functions: [::IsInternalFace(...)]
607 // the returned value iRet means:
608 // iRet=0; - state is not IN
609 // iRet=1; - state is IN
610 // iRet=2; - state can not be found by the method of angles
612 // For this function the returned value iRet means:
613 // iRet=0; - state is not IN
614 // iRet=1; - state is IN
617 // 1 Try to find an edge from theFace in theMEF
619 aExp.Init(theFace, TopAbs_EDGE);
620 for(; aExp.More(); aExp.Next()) {
621 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
622 if (!theMEF.Contains(aE)) {
628 aOr=aE.Orientation();
629 if (aOr==TopAbs_INTERNAL) {
632 bDegenerated=BRep_Tool::Degenerated(aE);
637 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
640 return iRet; // it can not be so
644 // aE is internal edge on aLF.First()
645 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
646 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
647 if (aE1.Orientation()!=TopAbs_INTERNAL) {
652 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1,
658 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
659 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
661 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
662 // treat as it was for 1 face
663 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
671 return iRet; // it can not be so
673 else { // aNbF=2,4,6,8,...
674 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF,
678 }//for(; aExp.More(); aExp.Next()) {
681 // the face has no shared edges with the solid
689 //========================================
690 // 2. Classify face using classifier
693 BOPCol_IndexedMapOfShape aBounds;
695 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
697 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid,
698 theTol, aBounds, theContext);
700 iRet=(aState==TopAbs_IN)? 1 : 0;
704 //=======================================================================
705 //function : IsInternalFace
707 //=======================================================================
708 Standard_Integer BOPTools_AlgoTools::IsInternalFace
709 (const TopoDS_Face& theFace,
710 const TopoDS_Edge& theEdge,
711 BOPCol_ListOfShape& theLF,
712 Handle(IntTools_Context)& theContext)
714 Standard_Integer aNbF, iRet;
720 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
721 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
722 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
728 BOPTools_ListOfCoupleOfShape aLCFF;
729 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
731 FindFacePairs(theEdge, theLF, aLCFF, theContext);
733 aIt.Initialize(aLCFF);
734 for (; aIt.More(); aIt.Next()) {
735 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
737 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
738 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
739 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
748 //=======================================================================
749 //function : IsInternalFace
751 //=======================================================================
752 Standard_Integer BOPTools_AlgoTools::IsInternalFace
753 (const TopoDS_Face& theFace,
754 const TopoDS_Edge& theEdge,
755 const TopoDS_Face& theFace1,
756 const TopoDS_Face& theFace2,
757 Handle(IntTools_Context)& theContext)
759 Standard_Boolean bRet;
760 Standard_Integer iRet;
761 TopoDS_Edge aE1, aE2;
763 BOPTools_ListOfCoupleOfShape theLCSOff;
764 BOPTools_CoupleOfShape aCS1, aCS2;
766 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
767 if (aE1.Orientation()==TopAbs_INTERNAL) {
769 aE1.Orientation(TopAbs_FORWARD);
770 aE2.Orientation(TopAbs_REVERSED);
772 else if (theFace1==theFace2) {
774 aE1.Orientation(TopAbs_FORWARD);
775 aE2.Orientation(TopAbs_REVERSED);
778 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
781 aCS1.SetShape1(theEdge);
782 aCS1.SetShape2(theFace);
783 theLCSOff.Append(aCS1);
786 aCS2.SetShape2(theFace2);
787 theLCSOff.Append(aCS2);
789 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
791 iRet=0; // theFace is not internal
792 if (theFace.IsEqual(aFOff)) {
793 // theFace is internal
796 // theFace seems to be internal
802 //=======================================================================
803 //function : GetFaceOff
805 //=======================================================================
806 Standard_Boolean BOPTools_AlgoTools::GetFaceOff
807 (const TopoDS_Edge& theE1,
808 const TopoDS_Face& theF1,
809 BOPTools_ListOfCoupleOfShape& theLCSOff,
810 TopoDS_Face& theFOff,
811 Handle(IntTools_Context)& theContext)
813 Standard_Boolean bRet;
814 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
815 Standard_Real aUmin, aUsup, aVmin, aVsup;
816 gp_Pnt aPn1, aPn2, aPx;
817 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
819 TopAbs_Orientation aOr;
820 Handle(Geom_Curve)aC3D;
821 Handle(Geom_Plane) aPL;
822 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
823 GeomAPI_ProjectPointOnSurf aProjPL;
827 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
828 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
831 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
832 gp_Dir aDTgt(aVTgt), aDTgt2;
833 aOr = theE1.Orientation();
835 aPL = new Geom_Plane(aPx, aDTgt);
836 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
837 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
839 aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx);
840 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext,
846 aIt.Initialize(theLCSOff);
847 for (; aIt.More(); aIt.Next()) {
848 const BOPTools_CoupleOfShape& aCS=aIt.Value();
849 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
850 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
852 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
853 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext,
856 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
859 aAngle=aTwoPI+aAngle;
862 if (aAngle<Precision::Angular()) {
866 else if (aF2.IsSame(theF1)) {
871 if (aAngle<aAngleMin){
875 else if (aAngle==aAngleMin) {
876 // the minimal angle can not be found
882 //=======================================================================
883 //function : GetEdgeOff
885 //=======================================================================
886 Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
887 const TopoDS_Face& theF2,
890 Standard_Boolean bFound;
891 TopAbs_Orientation aOr1, aOr1C, aOr2;
892 TopExp_Explorer anExp;
894 bFound=Standard_False;
895 aOr1=theE1.Orientation();
896 aOr1C=TopAbs::Reverse(aOr1);
898 anExp.Init(theF2, TopAbs_EDGE);
899 for (; anExp.More(); anExp.Next()) {
900 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
901 if (aEF2.IsSame(theE1)) {
902 aOr2=aEF2.Orientation();
913 //=======================================================================
914 //function : AreFacesSameDomain
916 //=======================================================================
917 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
918 (const TopoDS_Face& theF1,
919 const TopoDS_Face& theF2,
920 Handle(IntTools_Context)& theContext)
922 Standard_Boolean bFlag;
923 Standard_Integer iErr;
924 Standard_Real aTolF1, aTolF2, aTol;
927 TopoDS_Face aF1, aF2;
929 TopExp_Explorer aExp;
931 bFlag=Standard_False;
934 aF1.Orientation(TopAbs_FORWARD);
936 aF2.Orientation(TopAbs_FORWARD);
938 aTolF1=BRep_Tool::Tolerance(aF1);
940 aExp.Init(aF1, TopAbs_EDGE);
941 for (; aExp.More(); aExp.Next()) {
942 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
943 if (!BRep_Tool::Degenerated(aE1)) {
944 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
945 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
949 aTolF2=BRep_Tool::Tolerance(aF2);
952 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
955 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
961 //=======================================================================
962 //function : CheckSameGeom
964 //=======================================================================
965 Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
966 (const TopoDS_Face& theF1,
967 const TopoDS_Face& theF2,
968 Handle(IntTools_Context)& theContext)
970 Standard_Boolean bRet;
971 Standard_Real aTolF1, aTolF2, aTol;
974 TopExp_Explorer aExp;
977 aExp.Init(theF1, TopAbs_EDGE);
978 for (; aExp.More(); aExp.Next()) {
979 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
980 if (!BRep_Tool::Degenerated(aE)) {
981 aTolF1=BRep_Tool::Tolerance(theF1);
982 aTolF2=BRep_Tool::Tolerance(theF2);
984 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
985 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
991 //=======================================================================
994 //=======================================================================
995 Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
996 const TopoDS_Face& theF2)
998 Standard_Integer iSense=0;
1000 TopoDS_Edge aE1, aE2;
1001 TopExp_Explorer aExp;
1003 aExp.Init(theF1, TopAbs_EDGE);
1004 for (; aExp.More(); aExp.Next()) {
1005 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
1006 if (!BRep_Tool::Degenerated(aE1)) {
1007 if (!BRep_Tool::IsClosed(aE1, theF1)) {
1013 aExp.Init(theF2, TopAbs_EDGE);
1014 for (; aExp.More(); aExp.Next()) {
1015 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
1016 if (!BRep_Tool::Degenerated(aE2)) {
1017 if (!BRep_Tool::IsClosed(aE2, theF2)) {
1018 if (aE2.IsSame(aE1)) {
1030 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
1031 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
1033 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1037 //=======================================================================
1038 // function: IsSplitToReverse
1040 //=======================================================================
1041 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1042 (const TopoDS_Shape& theSp,
1043 const TopoDS_Shape& theSr,
1044 Handle(IntTools_Context)& theContext)
1046 Standard_Boolean bRet;
1047 TopAbs_ShapeEnum aType;
1049 bRet=Standard_False;
1051 aType=theSp.ShapeType();
1054 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1055 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1056 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1061 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1062 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1063 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1072 //=======================================================================
1073 //function :IsSplitToReverse
1075 //=======================================================================
1076 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1077 (const TopoDS_Face& theFSp,
1078 const TopoDS_Face& theFSr,
1079 Handle(IntTools_Context)& theContext)
1081 Standard_Boolean bRet, bFound, bInFace;
1082 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1083 gp_Pnt aPFSp, aPFSr;
1086 Handle(Geom_Surface) aSr, aSp;
1087 TopAbs_Orientation aOrSr, aOrSp;
1088 TopExp_Explorer anExp;
1091 bRet=Standard_False;
1093 aSr=BRep_Tool::Surface(theFSr);
1094 aSp=BRep_Tool::Surface(theFSp);
1096 aOrSr=theFSr.Orientation();
1097 aOrSp=theFSp.Orientation();
1098 bRet=(aOrSr!=aOrSp);
1102 bFound=Standard_False;
1103 anExp.Init(theFSp, TopAbs_EDGE);
1104 for (; anExp.More(); anExp.Next()) {
1105 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1106 if (!BRep_Tool::Degenerated(aESp)) {
1107 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1114 Standard_Boolean bFlag;
1115 Standard_Integer iErr;
1118 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp,
1124 aP2DFSp.Coord(aU, aV);
1125 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1130 if (theFSp.Orientation()==TopAbs_REVERSED){
1135 BRep_Tool::Range(aESp, aT1, aT2);
1136 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
1137 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT,
1142 // Parts of theContext->ComputeVS(..)
1143 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1144 aProjector.Perform(aPFSp);
1145 if (!aProjector.IsDone()) {
1149 aProjector.LowerDistanceParameters(aU, aV);
1150 gp_Pnt2d aP2D(aU, aV);
1151 bInFace=theContext->IsPointInFace (theFSr, aP2D);
1156 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1159 gp_Dir aDNFSr=aDD1U^aDD1V;
1160 if (theFSr.Orientation()==TopAbs_REVERSED){
1164 aScPr=aDNFSp*aDNFSr;
1169 //=======================================================================
1170 //function :IsSplitToReverse
1172 //=======================================================================
1173 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1174 (const TopoDS_Edge& aEF1,
1175 const TopoDS_Edge& aEF2,
1176 Handle(IntTools_Context)& theContext)
1178 Standard_Boolean bRet, bIsDegenerated;
1180 bRet=Standard_False;
1181 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1182 BRep_Tool::Degenerated(aEF2));
1183 if (bIsDegenerated) {
1188 TopAbs_Orientation aOrE, aOrSp;
1189 Handle(Geom_Curve)aC1, aC2;
1191 aC2=BRep_Tool::Curve(aEF2, a, b);
1192 aC1=BRep_Tool::Curve(aEF1, a, b);
1195 aOrE=aEF2.Orientation();
1196 aOrSp=aEF1.Orientation();
1201 Standard_Real aT1, aT2, aScPr;
1205 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1207 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1210 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1212 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1221 //=======================================================================
1224 //=======================================================================
1225 Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1226 const TopoDS_Shape& aFace)
1228 Standard_Boolean bIsHole;
1229 Standard_Integer i, aNbS;
1230 Standard_Real aT1, aT2, aS;
1231 Standard_Real aU1, aU, dU;
1232 Standard_Real aX1, aY1, aX0, aY0;
1233 TopAbs_Orientation aOr;
1235 gp_Pnt2d aP2D0, aP2D1;
1236 Handle(Geom2d_Curve) aC2D;
1237 TopoDS_Face aF, aFF;
1238 TopoDS_Iterator aItW;
1240 bIsHole=Standard_False;
1242 aF=(*(TopoDS_Face *)(&aFace));
1244 aFF.Orientation(TopAbs_FORWARD);
1247 aItW.Initialize(aW);
1248 for (; aItW.More(); aItW.Next()) {
1249 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1250 aOr=aE.Orientation();
1251 if (!(aOr==TopAbs_FORWARD ||
1252 aOr==TopAbs_REVERSED)) {
1256 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1257 if (aC2D.IsNull()) {
1261 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1262 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1267 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1270 if (aOr==TopAbs_REVERSED) {
1276 aC2D->D0(aU, aP2D0);
1277 for(i=2; i<=aNbS; i++) {
1279 aC2D->D0(aU, aP2D1);
1280 aP2D0.Coord(aX0, aY0);
1281 aP2D1.Coord(aX1, aY1);
1283 aS=aS+(aY0+aY1)*(aX1-aX0);
1287 }//for (; aItW.More(); aItW.Next()) {
1292 //=======================================================================
1293 // function: MakeContainer
1295 //=======================================================================
1296 void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1302 case TopAbs_COMPOUND:{
1304 aBB.MakeCompound(aC);
1309 case TopAbs_COMPSOLID:{
1310 TopoDS_CompSolid aCS;
1311 aBB.MakeCompSolid(aCS);
1317 TopoDS_Solid aSolid;
1318 aBB.MakeSolid(aSolid);
1325 TopoDS_Shell aShell;
1326 aBB.MakeShell(aShell);
1333 aBB.MakeWire(aWire);
1342 //=======================================================================
1343 // function: MakePCurve
1345 //=======================================================================
1346 void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1347 const TopoDS_Face& aF1,
1348 const TopoDS_Face& aF2,
1349 const IntTools_Curve& aIC,
1350 const Standard_Boolean bPC1,
1351 const Standard_Boolean bPC2)
1355 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1356 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1359 Standard_Boolean bPC;
1361 aTolE=BRep_Tool::Tolerance(aE);
1363 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
1364 Handle(Geom_TrimmedCurve)aC3DETrim=
1365 new Geom_TrimmedCurve(aC3DE, aT1, aT2);
1367 for (i=0; i<2; ++i) {
1368 bPC = !i ? bPC1 : bPC2;
1375 aC2Dx1=aIC.FirstCurve2d();
1379 aC2Dx1=aIC.SecondCurve2d();
1382 aFFWD.Orientation(TopAbs_FORWARD);
1385 if (aC2D.IsNull()) {
1386 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1387 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1388 aOutFirst, aOutLast,
1392 if (aC3DE->IsPeriodic()) {
1393 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D,
1397 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D,
1401 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1402 //BRepLib::SameParameter(aE);
1404 BRepLib::SameParameter(aE);
1406 //=======================================================================
1407 // function: MakeEdge
1409 //=======================================================================
1410 void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1411 const TopoDS_Vertex& theV1,
1412 const Standard_Real theT1,
1413 const TopoDS_Vertex& theV2,
1414 const Standard_Real theT2,
1415 const Standard_Real theTolR3D,
1418 Standard_Real aTolV;
1421 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2,
1424 aBB.UpdateEdge(theE, theTolR3D);
1426 aTolV=BRep_Tool::Tolerance(theV1);
1427 if (aTolV<theTolR3D) {
1428 aBB.UpdateVertex(theV1, theTolR3D);
1431 aTolV=BRep_Tool::Tolerance(theV2);
1432 if (aTolV<theTolR3D) {
1433 aBB.UpdateVertex(theV2, theTolR3D);
1436 //=======================================================================
1437 // function: ComputeVV
1439 //=======================================================================
1440 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1442 const Standard_Real aTolP2)
1444 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1447 aTolV1=BRep_Tool::Tolerance(aV1);
1449 aTolSum=aTolV1+aTolP2;
1450 aTolSum2=aTolSum*aTolSum;
1452 aP1=BRep_Tool::Pnt(aV1);
1454 aD2=aP1.SquareDistance(aP2);
1460 //=======================================================================
1461 // function: ComputeVV
1463 //=======================================================================
1464 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1465 const TopoDS_Vertex& aV2)
1467 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1470 aTolV1=BRep_Tool::Tolerance(aV1);
1471 aTolV2=BRep_Tool::Tolerance(aV2);
1472 aTolSum=aTolV1+aTolV2;
1473 aTolSum2=aTolSum*aTolSum;
1475 aP1=BRep_Tool::Pnt(aV1);
1476 aP2=BRep_Tool::Pnt(aV2);
1478 aD2=aP1.SquareDistance(aP2);
1484 //=======================================================================
1485 // function: MakeVertex
1487 //=======================================================================
1488 void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
1489 TopoDS_Vertex& aVnew)
1491 Standard_Integer aNb;
1492 Standard_Real aTi, aDi, aDmax;
1494 gp_XYZ aXYZ(0.,0.,0.), aXYZi;
1495 BOPCol_ListIteratorOfListOfShape aIt;
1499 aIt.Initialize(aLV);
1500 for (; aIt.More(); aIt.Next()) {
1501 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1502 aPi=BRep_Tool::Pnt(aVi);
1507 aXYZ.Divide((Standard_Real)aNb);
1511 aIt.Initialize(aLV);
1512 for (; aIt.More(); aIt.Next()) {
1513 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1514 aPi=BRep_Tool::Pnt(aVi);
1515 aTi=BRep_Tool::Tolerance(aVi);
1516 aDi=aP.SquareDistance(aPi);
1525 aBB.MakeVertex (aVnew, aP, aDmax);
1528 //=======================================================================
1529 //function : GetEdgeOnFace
1531 //=======================================================================
1532 Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
1533 (const TopoDS_Edge& theE1,
1534 const TopoDS_Face& theF2,
1537 Standard_Boolean bFound;
1538 TopoDS_Iterator aItF, aItW;
1540 bFound=Standard_False;
1542 aItF.Initialize(theF2);
1543 for (; aItF.More(); aItF.Next()) {
1544 const TopoDS_Shape& aW=aItF.Value();
1545 aItW.Initialize(aW);
1546 for (; aItW.More(); aItW.Next()) {
1547 const TopoDS_Shape& aE=aItW.Value();
1548 if (aE.IsSame(theE1)) {
1549 theE2=(*(TopoDS_Edge*)(&aE));
1557 //=======================================================================
1558 //function : FindFacePairs
1560 //=======================================================================
1561 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1562 const BOPCol_ListOfShape& thLF,
1563 BOPTools_ListOfCoupleOfShape& theLCFF,
1564 Handle(IntTools_Context)& theContext)
1566 Standard_Boolean bFound;
1567 Standard_Integer i, aNbCEF;
1568 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
1569 BOPCol_MapOfShape aMFP;
1570 TopoDS_Face aF1, aF2;
1571 TopoDS_Edge aEL, aE1;
1572 BOPCol_ListIteratorOfListOfShape aItLF;
1573 BOPTools_CoupleOfShape aCEF, aCFF;
1574 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1575 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1577 bFound=Standard_True;
1580 aItLF.Initialize(thLF);
1581 for (; aItLF.More(); aItLF.Next()) {
1582 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1584 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1586 return bFound; // it can not be so
1589 aCEF.SetShape1(aEL);
1590 aCEF.SetShape2(aFL);
1594 aNbCEF=aLCEF.Extent();
1599 aIt.Initialize(aLCEF);
1600 for (i=0; aIt.More(); aIt.Next(), ++i) {
1601 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1602 const TopoDS_Shape& aEx=aCSx.Shape1();
1603 const TopoDS_Shape& aFx=aCSx.Shape2();
1605 aOr=aEx.Orientation();
1608 aOrC=TopAbs::Reverse(aOr);
1609 aE1=(*(TopoDS_Edge*)(&aEx));
1610 aF1=(*(TopoDS_Face*)(&aFx));
1616 aLCEFx.Append(aCSx);
1622 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1624 aCFF.SetShape1(aF1);
1625 aCFF.SetShape2(aF2);
1626 theLCFF.Append(aCFF);
1635 aIt.Initialize(aLCEFx);
1636 for (; aIt.More(); aIt.Next()) {
1637 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1638 const TopoDS_Shape& aFx=aCSx.Shape2();
1639 if (!aMFP.Contains(aFx)) {
1644 aNbCEF=aLCEF.Extent();
1649 //=======================================================================
1650 //function : AngleWithRef
1652 //=======================================================================
1653 Standard_Real AngleWithRef(const gp_Dir& theD1,
1654 const gp_Dir& theD2,
1655 const gp_Dir& theDRef)
1657 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1662 const gp_XYZ& aXYZ1=theD1.XYZ();
1663 const gp_XYZ& aXYZ2=theD2.XYZ();
1664 aXYZ=aXYZ1.Crossed(aXYZ2);
1665 aSinus=aXYZ.Modulus();
1666 aCosinus=theD1*theD2;
1670 aBeta=aHalfPI*(1.-aCosinus);
1673 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1676 aScPr=aXYZ.Dot(theDRef.XYZ());
1682 //=======================================================================
1683 // function: IsBlockInOnFace
1685 //=======================================================================
1686 Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
1687 (const IntTools_Range& aShrR,
1688 const TopoDS_Face& aF,
1689 const TopoDS_Edge& aE1,
1690 Handle(IntTools_Context)& aContext)
1692 Standard_Boolean bFlag;
1693 Standard_Real f1, l1, ULD, VLD;
1697 aShrR.Range(f1, l1);
1698 Standard_Real dt=0.0075, k;//dt=0.001, k;
1704 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1706 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1707 aProjector.Perform(aP11);
1709 bFlag=aProjector.IsDone();
1714 aProjector.LowerDistanceParameters(ULD, VLD);
1715 aP2D.SetCoord(ULD, VLD);
1717 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1724 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1726 aProjector.Perform(aP12);
1728 bFlag=aProjector.IsDone();
1733 aProjector.LowerDistanceParameters(ULD, VLD);
1734 aP2D.SetCoord(ULD, VLD);
1736 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1742 // Treatment intemediate
1743 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1744 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1745 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1747 aProjector.Perform(aP12);
1749 bFlag=aProjector.IsDone();
1754 aTolE=BRep_Tool::Tolerance(aE1);
1755 aTolF=BRep_Tool::Tolerance(aF);
1757 aDist=aProjector.LowerDistance();
1759 return Standard_False;
1762 aProjector.LowerDistanceParameters(ULD, VLD);
1763 aP2D.SetCoord(ULD, VLD);
1765 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1773 //=======================================================================
1774 //function : IsMicroEdge
1776 //=======================================================================
1777 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
1778 (const TopoDS_Edge& aE,
1779 const Handle(IntTools_Context)& aCtx)
1781 Standard_Boolean bRet;
1782 Standard_Integer iErr;
1783 Standard_Real aT1, aT2, aTmp;
1784 Handle(Geom_Curve) aC3D;
1785 TopoDS_Vertex aV1, aV2;
1787 bRet=(BRep_Tool::Degenerated(aE) ||
1788 !BRep_Tool::IsGeometric(aE));
1793 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1794 TopExp::Vertices(aE, aV1, aV2);
1795 aT1=BRep_Tool::Parameter(aV1, aE);
1796 aT2=BRep_Tool::Parameter(aV2, aE);
1803 IntTools_ShrunkRange aSR;
1804 aSR.SetContext(aCtx);
1805 aSR.SetData(aE, aT1, aT2, aV1, aV2);
1807 iErr=aSR.ErrorStatus();
1813 //=======================================================================
1814 //function : GetFaceDir
1815 //purpose : Get binormal direction for the face in the point aP
1816 //=======================================================================
1817 void GetFaceDir(const TopoDS_Edge& aE,
1818 const TopoDS_Face& aF,
1820 const Standard_Real aT,
1821 const gp_Dir& aDTgt,
1824 Handle(IntTools_Context)& theContext,
1825 GeomAPI_ProjectPointOnSurf& aProjPL,
1826 const Standard_Real aDt)
1828 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1829 if (aF.Orientation()==TopAbs_REVERSED){
1835 if (!FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt)) {
1836 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx,
1838 aProjPL.Perform(aPx);
1839 aPx = aProjPL.NearestPoint();
1840 gp_Vec aVec(aP, aPx);
1841 aDB.SetXYZ(aVec.XYZ());
1845 //=======================================================================
1846 //function : FindPointInFace
1847 //purpose : Find a point in the face in direction of <aDB>
1848 //=======================================================================
1849 Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
1853 Handle(IntTools_Context)& theContext,
1854 GeomAPI_ProjectPointOnSurf& aProjPL,
1855 const Standard_Real aDt)
1857 Standard_Integer aNbItMax;
1858 Standard_Real aDist, aDTol, aPM;
1859 Standard_Boolean bRet;
1862 aDTol = Precision::Angular();
1863 aPM = aP.XYZ().Modulus();
1865 aDTol = 5.e-16 * aPM;
1867 bRet = Standard_False;
1870 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1873 aP1.SetCoord(aP.X()+aDt*aDB.X(),
1875 aP.Z()+aDt*aDB.Z());
1878 if (!aProj.IsDone()) {
1881 aPOut = aProj.NearestPoint();
1882 aDist = aProj.LowerDistance();
1884 aProjPL.Perform(aPOut);
1885 aPOut = aProjPL.NearestPoint();
1887 gp_Vec aV(aP, aPOut);
1888 aDB.SetXYZ(aV.XYZ());
1889 } while (aDist > aDTol && --aNbItMax);
1891 bRet = aDist < aDTol;
1894 //=======================================================================
1895 //function : MinStep3D
1897 //=======================================================================
1898 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
1899 const TopoDS_Face& theF1,
1900 const BOPTools_ListOfCoupleOfShape& theLCS,
1903 Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin, aR;
1904 BOPTools_CoupleOfShape aCS1;
1905 BOPTools_ListOfCoupleOfShape aLCS;
1906 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1907 BRepAdaptor_Surface aBAS;
1910 aCS1.SetShape1(theE1);
1911 aCS1.SetShape2(theF1);
1914 aTolE = BRep_Tool::Tolerance(theE1);
1918 aIt.Initialize(aLCS);
1919 for (; aIt.More(); aIt.Next()) {
1920 const BOPTools_CoupleOfShape& aCS = aIt.Value();
1921 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2()));
1923 aTolF = BRep_Tool::Tolerance(aF);
1924 aDt = 2*(aTolE + aTolF);
1927 aBAS.Initialize(aF, Standard_False);
1928 GeomAbs_SurfaceType aSType = aBAS.GetType();
1929 if (aSType == GeomAbs_Cylinder) {
1930 aR = aBAS.Cylinder().Radius();
1932 else if (aSType == GeomAbs_Cone) {
1933 gp_Lin aL(aBAS.Cone().Axis());
1934 aR = aL.Distance(aP);
1936 else if (aSType == GeomAbs_Sphere) {
1937 aR = aBAS.Sphere().Radius();
1939 else if (aSType == GeomAbs_Torus) {
1940 aR = aBAS.Torus().MajorRadius();
1942 else if (aSType == GeomAbs_SurfaceOfRevolution) {
1947 Standard_Real d = Precision::PConfusion();
1948 aDtMin = sqrt(d*d + 2*d*aR);
1956 if (aDtMax < aDtMin) {
1962 //=======================================================================
1963 //function : IsOpenShell
1965 //=======================================================================
1966 Standard_Boolean BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
1968 Standard_Boolean bRet;
1969 Standard_Integer i, aNbE, aNbF;
1970 TopAbs_Orientation aOrF;
1971 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
1972 BOPCol_ListIteratorOfListOfShape aItLS;
1974 bRet=Standard_False;
1976 BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF);
1979 for (i=1; i<=aNbE; ++i) {
1980 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i));
1981 if (BRep_Tool::Degenerated(aE)) {
1986 const BOPCol_ListOfShape& aLF=aMEF(i);
1987 aItLS.Initialize(aLF);
1988 for (; aItLS.More(); aItLS.Next()) {
1989 const TopoDS_Shape& aF=aItLS.Value();
1990 aOrF=aF.Orientation();
1991 if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
2005 //=======================================================================
2006 //function : IsInvertedSolid
2008 //=======================================================================
2010 BOPTools_AlgoTools::IsInvertedSolid(const TopoDS_Solid& aSolid)
2012 Standard_Real aTolS;
2013 TopAbs_State aState;
2014 BRepClass3d_SolidClassifier aSC(aSolid);
2017 aSC.PerformInfinitePoint(aTolS);
2019 return (aState==TopAbs_IN);