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.
19 #include <BOPCol_IndexedMapOfShape.hxx>
20 #include <BOPCol_MapOfShape.hxx>
21 #include <BOPTools.hxx>
22 #include <BOPTools_AlgoTools.hxx>
23 #include <BOPTools_AlgoTools2D.hxx>
24 #include <BOPTools_AlgoTools3D.hxx>
25 #include <BOPTools_CoupleOfShape.hxx>
26 #include <BOPTools_ListOfCoupleOfShape.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRepAdaptor_Curve2d.hxx>
30 #include <BRepAdaptor_Surface.hxx>
31 #include <BRepClass3d_SolidClassifier.hxx>
32 #include <BRepLib.hxx>
33 #include <Geom2d_Curve.hxx>
34 #include <Geom2dInt_Geom2dCurveTool.hxx>
35 #include <Geom_Curve.hxx>
36 #include <Geom_Plane.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <GeomAPI_ProjectPointOnSurf.hxx>
40 #include <gp_Cone.hxx>
41 #include <gp_Cylinder.hxx>
44 #include <gp_Pnt2d.hxx>
45 #include <gp_Sphere.hxx>
46 #include <gp_Torus.hxx>
48 #include <IntTools_Context.hxx>
49 #include <IntTools_Curve.hxx>
50 #include <IntTools_Range.hxx>
51 #include <IntTools_ShrunkRange.hxx>
52 #include <IntTools_Tools.hxx>
53 #include <Precision.hxx>
54 #include <TopAbs_Orientation.hxx>
56 #include <TopExp_Explorer.hxx>
57 #include <TopoDS_Compound.hxx>
58 #include <TopoDS_CompSolid.hxx>
59 #include <TopoDS_Edge.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Shape.hxx>
62 #include <TopoDS_Shell.hxx>
63 #include <TopoDS_Solid.hxx>
64 #include <TopoDS_Vertex.hxx>
65 #include <TopoDS_Wire.hxx>
66 #include <NCollection_Array1.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: BOPTools_AlgoTools_ComparePoints
112 // purpose: implementation of IsLess() function for two points
113 //=======================================================================
114 struct BOPTools_AlgoTools_ComparePoints {
115 bool operator()(const gp_Pnt& theP1, const gp_Pnt& theP2)
117 for (Standard_Integer i = 1; i <= 3; ++i) {
118 if (theP1.Coord(i) < theP2.Coord(i)) {
119 return Standard_True;
121 else if (theP1.Coord(i) > theP2.Coord(i)) {
122 return Standard_False;
125 return Standard_False;
129 //=======================================================================
130 // function: MakeConnexityBlocks
132 //=======================================================================
133 void BOPTools_AlgoTools::MakeConnexityBlocks
134 (const TopoDS_Shape& theS,
135 const TopAbs_ShapeEnum theType1,
136 const TopAbs_ShapeEnum theType2,
137 BOPCol_ListOfShape& theLCB)
139 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
143 TopExp_Explorer aExp;
144 BOPCol_MapOfShape aMP;
145 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
146 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
147 BOPCol_ListIteratorOfListOfShape aItLF;
150 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
153 aIt.Initialize(theS);
154 for (; aIt.More(); aIt.Next()) {
155 const TopoDS_Shape& aF1=aIt.Value();
156 if (aMP.Contains(aF1)) {
167 aNbAdd = aMAdd.Extent();
168 for (i=1; i<=aNbAdd; ++i) {
169 const TopoDS_Shape& aF=aMAdd(i);
171 aExp.Init(aF, theType1);
172 for (; aExp.More(); aExp.Next()) {
173 const TopoDS_Shape& aE=aExp.Current();
175 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
176 aItLF.Initialize(aLF);
177 for (; aItLF.More(); aItLF.Next()) {
178 const TopoDS_Shape& aFx=aItLF.Value();
179 if (aFx.IsSame(aF)) {
182 if (aMCB.Contains(aFx)) {
187 }//for (; aExp.More(); aExp.Next()){
189 }// for (i=1; i<=aNbAdd; ++i) {
191 aNbAdd1=aMAdd1.Extent();
193 break;// ->make new CB from aMCB
197 for (i=1; i<=aNbAdd1; ++i) {
198 const TopoDS_Shape& aFAdd = aMAdd1(i);
205 aBB.MakeCompound(aC);
207 for (i=1; i<=aNbF; ++i) {
208 const TopoDS_Shape& aF=aMCB(i);
214 }// for (; aIt.More(); aIt.Next())
216 //=======================================================================
217 // function: OrientFacesOnShell
219 //=======================================================================
220 void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
222 Standard_Boolean bIsProcessed1, bIsProcessed2;
223 Standard_Integer i, aNbE, aNbF, j;
224 TopAbs_Orientation anOrE1, anOrE2;
225 TopoDS_Face aF1x, aF2x;
226 TopoDS_Shape aShellNew;
227 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
228 BOPCol_IndexedMapOfShape aProcessedFaces;
231 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
233 BOPTools::MapShapesAndAncestors(aShell,
234 TopAbs_EDGE, TopAbs_FACE,
236 aNbE=aEFMap.Extent();
238 // One seam edge in aEFMap contains 2 equivalent faces.
239 for (i=1; i<=aNbE; ++i) {
240 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
243 BOPCol_ListOfShape aLFTmp;
244 BOPCol_IndexedMapOfShape aFM;
246 BOPCol_ListIteratorOfListOfShape anIt(aLF);
247 for (; anIt.More(); anIt.Next()) {
248 const TopoDS_Shape& aF=anIt.Value();
249 if (!aFM.Contains(aF)) {
260 for (i=1; i<=aNbE; ++i) {
261 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
262 if (BRep_Tool::Degenerated(aE)) {
266 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
272 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
273 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
275 bIsProcessed1=aProcessedFaces.Contains(aF1);
276 bIsProcessed2=aProcessedFaces.Contains(aF2);
277 if (bIsProcessed1 && bIsProcessed2) {
281 if (!bIsProcessed1 && !bIsProcessed2) {
282 aProcessedFaces.Add(aF1);
283 aBB.Add(aShellNew, aF1);
284 bIsProcessed1=!bIsProcessed1;
289 j=aProcessedFaces.FindIndex(aF1);
290 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
295 j=aProcessedFaces.FindIndex(aF2);
296 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
299 anOrE1=Orientation(aE, aF1x);
300 anOrE2=Orientation(aE, aF2x);
302 if (bIsProcessed1 && !bIsProcessed2) {
303 if (anOrE1==anOrE2) {
304 if (!BRep_Tool::IsClosed(aE, aF1) &&
305 !BRep_Tool::IsClosed(aE, aF2)) {
309 aProcessedFaces.Add(aF2);
310 aBB.Add(aShellNew, aF2);
312 else if (!bIsProcessed1 && bIsProcessed2) {
313 if (anOrE1==anOrE2) {
314 if (!BRep_Tool::IsClosed(aE, aF1) &&
315 !BRep_Tool::IsClosed(aE, aF2)) {
319 aProcessedFaces.Add(aF1);
320 aBB.Add(aShellNew, aF1);
325 for (i=1; i<=aNbE; ++i) {
326 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
327 if (BRep_Tool::Degenerated(aE)) {
331 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
334 BOPCol_ListIteratorOfListOfShape anIt(aLF);
335 for(; anIt.More(); anIt.Next()) {
336 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
337 if (!aProcessedFaces.Contains(aF)) {
338 aProcessedFaces.Add(aF);
339 aBB.Add(aShellNew, aF);
346 //=======================================================================
347 //function : Orientation
349 //=======================================================================
350 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
351 const TopoDS_Face& aF)
353 TopAbs_Orientation anOr=TopAbs_INTERNAL;
355 TopExp_Explorer anExp;
356 anExp.Init(aF, TopAbs_EDGE);
357 for (; anExp.More(); anExp.Next()) {
358 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
359 if (anEF1.IsSame(anE)) {
360 anOr=anEF1.Orientation();
366 //=======================================================================
367 // function: MakeConnexityBlock.
369 //=======================================================================
370 void BOPTools_AlgoTools::MakeConnexityBlock
371 (BOPCol_ListOfShape& theLFIn,
372 BOPCol_IndexedMapOfShape& theMEAvoid,
373 BOPCol_ListOfShape& theLCB,
374 const Handle(NCollection_BaseAllocator)& theAllocator)
376 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
377 TopExp_Explorer aExp;
378 BOPCol_ListIteratorOfListOfShape aIt;
380 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
381 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
382 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
383 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
386 aNbF=theLFIn.Extent();
387 aIt.Initialize(theLFIn);
388 for (; aIt.More(); aIt.Next()) {
389 const TopoDS_Shape& aF=aIt.Value();
390 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
394 const TopoDS_Shape& aF1=theLFIn.First();
399 aNbAdd = aMAdd.Extent();
400 for (i=1; i<=aNbAdd; ++i) {
401 const TopoDS_Shape& aF=aMAdd(i);
404 aExp.Init(aF, TopAbs_EDGE);
405 for (; aExp.More(); aExp.Next()) {
406 const TopoDS_Shape& aE=aExp.Current();
407 if (theMEAvoid.Contains(aE)){
411 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
413 for (; aIt.More(); aIt.Next()) {
414 const TopoDS_Shape& aFx=aIt.Value();
415 if (aFx.IsSame(aF)) {
418 if (aMCB.Contains(aFx)) {
423 }//for (; aExp.More(); aExp.Next()){
425 }// for (i=1; i<=aNbAdd; ++i) {
427 aNbAdd1=aMAdd1.Extent();
433 for (i=1; i<=aNbAdd1; ++i) {
434 const TopoDS_Shape& aFAdd=aMAdd1(i);
442 for (i=1; i<=aNbF; ++i) {
443 const TopoDS_Shape& aF=aMCB(i);
447 //=======================================================================
448 // function: ComputeStateByOnePoint
450 //=======================================================================
451 TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
452 (const TopoDS_Shape& theS,
453 const TopoDS_Solid& theRef,
454 const Standard_Real theTol,
455 Handle(IntTools_Context)& theContext)
458 TopAbs_ShapeEnum aType;
460 aState=TopAbs_UNKNOWN;
461 aType=theS.ShapeType();
462 if (aType==TopAbs_VERTEX) {
463 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
464 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
466 else if (aType==TopAbs_EDGE) {
467 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
468 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
473 //=======================================================================
474 // function: ComputeState
476 //=======================================================================
477 TopAbs_State BOPTools_AlgoTools::ComputeState
478 (const TopoDS_Face& theF,
479 const TopoDS_Solid& theRef,
480 const Standard_Real theTol,
481 BOPCol_IndexedMapOfShape& theBounds,
482 Handle(IntTools_Context)& theContext)
485 TopExp_Explorer aExp;
490 aState=TopAbs_UNKNOWN;
492 aExp.Init(theF, TopAbs_EDGE);
493 for (; aExp.More(); aExp.Next()) {
494 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
495 if (BRep_Tool::Degenerated(aSE)) {
499 if (!theBounds.Contains(aSE)) {
500 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
501 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol,
506 aE1=(*(TopoDS_Edge*)(&aSE));
509 // !!<- process edges that are all on theRef
511 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
512 aP2D, aP3D, theContext);
513 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
519 //=======================================================================
520 // function: ComputeState
522 //=======================================================================
523 TopAbs_State BOPTools_AlgoTools::ComputeState
524 (const TopoDS_Vertex& theV,
525 const TopoDS_Solid& theRef,
526 const Standard_Real theTol,
527 Handle(IntTools_Context)& theContext)
532 aP3D=BRep_Tool::Pnt(theV);
533 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
537 //=======================================================================
538 // function: ComputeState
540 //=======================================================================
541 TopAbs_State BOPTools_AlgoTools::ComputeState
542 (const TopoDS_Edge& theE,
543 const TopoDS_Solid& theRef,
544 const Standard_Real theTol,
545 Handle(IntTools_Context)& theContext)
547 Standard_Real aT1, aT2, aT = 0.;
549 Handle(Geom_Curve) aC3D;
552 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
555 //it means that we are in degenerated edge
556 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
558 return TopAbs_UNKNOWN;
560 aP3D=BRep_Tool::Pnt(aV);
563 Standard_Boolean bF2Inf, bL2Inf;
564 Standard_Real dT=10.;
566 bF2Inf = Precision::IsNegativeInfinite(aT1);
567 bL2Inf = Precision::IsPositiveInfinite(aT2);
569 if (bF2Inf && !bL2Inf) {
572 else if (!bF2Inf && bL2Inf) {
575 else if (bF2Inf && bL2Inf) {
579 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
584 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
589 //=======================================================================
590 // function: ComputeState
592 //=======================================================================
593 TopAbs_State BOPTools_AlgoTools::ComputeState
595 const TopoDS_Solid& theRef,
596 const Standard_Real theTol,
597 Handle(IntTools_Context)& theContext)
601 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
602 aSC.Perform(theP, theTol);
608 //=======================================================================
609 //function : IsInternalFace
611 //=======================================================================
612 Standard_Integer BOPTools_AlgoTools::IsInternalFace
613 (const TopoDS_Face& theFace,
614 const TopoDS_Solid& theSolid,
615 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
616 const Standard_Real theTol,
617 Handle(IntTools_Context)& theContext)
619 Standard_Boolean bDegenerated;
620 Standard_Integer aNbF, iRet, iFound;
621 TopAbs_Orientation aOr;
623 TopExp_Explorer aExp;
624 BOPCol_ListIteratorOfListOfShape aItF;
626 // For all invoked functions: [::IsInternalFace(...)]
627 // the returned value iRet means:
628 // iRet=0; - state is not IN
629 // iRet=1; - state is IN
630 // iRet=2; - state can not be found by the method of angles
632 // For this function the returned value iRet means:
633 // iRet=0; - state is not IN
634 // iRet=1; - state is IN
637 // 1 Try to find an edge from theFace in theMEF
639 aExp.Init(theFace, TopAbs_EDGE);
640 for(; aExp.More(); aExp.Next()) {
641 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
642 if (!theMEF.Contains(aE)) {
648 aOr=aE.Orientation();
649 if (aOr==TopAbs_INTERNAL) {
652 bDegenerated=BRep_Tool::Degenerated(aE);
657 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
660 return iRet; // it can not be so
664 // aE is internal edge on aLF.First()
665 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
666 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
667 if (aE1.Orientation()!=TopAbs_INTERNAL) {
672 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1,
678 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
679 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
681 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
682 // treat as it was for 1 face
683 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
691 return iRet; // it can not be so
693 else { // aNbF=2,4,6,8,...
694 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF,
698 }//for(; aExp.More(); aExp.Next()) {
701 // the face has no shared edges with the solid
709 //========================================
710 // 2. Classify face using classifier
713 BOPCol_IndexedMapOfShape aBounds;
715 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
717 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid,
718 theTol, aBounds, theContext);
720 iRet=(aState==TopAbs_IN)? 1 : 0;
724 //=======================================================================
725 //function : IsInternalFace
727 //=======================================================================
728 Standard_Integer BOPTools_AlgoTools::IsInternalFace
729 (const TopoDS_Face& theFace,
730 const TopoDS_Edge& theEdge,
731 BOPCol_ListOfShape& theLF,
732 Handle(IntTools_Context)& theContext)
734 Standard_Integer aNbF, iRet;
740 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
741 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
742 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
748 BOPTools_ListOfCoupleOfShape aLCFF;
749 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
751 FindFacePairs(theEdge, theLF, aLCFF, theContext);
753 aIt.Initialize(aLCFF);
754 for (; aIt.More(); aIt.Next()) {
755 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
757 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
758 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
759 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
768 //=======================================================================
769 //function : IsInternalFace
771 //=======================================================================
772 Standard_Integer BOPTools_AlgoTools::IsInternalFace
773 (const TopoDS_Face& theFace,
774 const TopoDS_Edge& theEdge,
775 const TopoDS_Face& theFace1,
776 const TopoDS_Face& theFace2,
777 Handle(IntTools_Context)& theContext)
779 Standard_Boolean bRet;
780 Standard_Integer iRet;
781 TopoDS_Edge aE1, aE2;
783 BOPTools_ListOfCoupleOfShape theLCSOff;
784 BOPTools_CoupleOfShape aCS1, aCS2;
786 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
787 if (aE1.Orientation()==TopAbs_INTERNAL) {
789 aE1.Orientation(TopAbs_FORWARD);
790 aE2.Orientation(TopAbs_REVERSED);
792 else if (theFace1==theFace2) {
794 aE1.Orientation(TopAbs_FORWARD);
795 aE2.Orientation(TopAbs_REVERSED);
798 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
801 aCS1.SetShape1(theEdge);
802 aCS1.SetShape2(theFace);
803 theLCSOff.Append(aCS1);
806 aCS2.SetShape2(theFace2);
807 theLCSOff.Append(aCS2);
809 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
811 iRet=0; // theFace is not internal
812 if (theFace.IsEqual(aFOff)) {
813 // theFace is internal
816 // theFace seems to be internal
822 //=======================================================================
823 //function : GetFaceOff
825 //=======================================================================
826 Standard_Boolean BOPTools_AlgoTools::GetFaceOff
827 (const TopoDS_Edge& theE1,
828 const TopoDS_Face& theF1,
829 BOPTools_ListOfCoupleOfShape& theLCSOff,
830 TopoDS_Face& theFOff,
831 Handle(IntTools_Context)& theContext)
833 Standard_Boolean bRet;
834 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
835 Standard_Real aUmin, aUsup, aVmin, aVsup, aPA;
836 gp_Pnt aPn1, aPn2, aPx;
837 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
839 TopAbs_Orientation aOr;
840 Handle(Geom_Curve)aC3D;
841 Handle(Geom_Plane) aPL;
842 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
843 GeomAPI_ProjectPointOnSurf aProjPL;
845 aPA=Precision::Angular();
848 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
849 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
852 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
853 gp_Dir aDTgt(aVTgt), aDTgt2;
854 aOr = theE1.Orientation();
856 aPL = new Geom_Plane(aPx, aDTgt);
857 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
858 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
860 aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx);
861 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext,
867 aIt.Initialize(theLCSOff);
868 for (; aIt.More(); aIt.Next()) {
869 const BOPTools_CoupleOfShape& aCS=aIt.Value();
870 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
871 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
873 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
874 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext,
877 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
880 aAngle=aTwoPI+aAngle;
887 else if (aF2.IsSame(theF1)) {
892 if (fabs(aAngle-aAngleMin)<aPA) {
893 // the minimal angle can not be found
897 if (aAngle<aAngleMin){
901 else if (aAngle==aAngleMin) {
902 // the minimal angle can not be found
908 //=======================================================================
909 //function : GetEdgeOff
911 //=======================================================================
912 Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
913 const TopoDS_Face& theF2,
916 Standard_Boolean bFound;
917 TopAbs_Orientation aOr1, aOr1C, aOr2;
918 TopExp_Explorer anExp;
920 bFound=Standard_False;
921 aOr1=theE1.Orientation();
922 aOr1C=TopAbs::Reverse(aOr1);
924 anExp.Init(theF2, TopAbs_EDGE);
925 for (; anExp.More(); anExp.Next()) {
926 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
927 if (aEF2.IsSame(theE1)) {
928 aOr2=aEF2.Orientation();
939 //=======================================================================
940 //function : AreFacesSameDomain
942 //=======================================================================
943 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
944 (const TopoDS_Face& theF1,
945 const TopoDS_Face& theF2,
946 Handle(IntTools_Context)& theContext)
948 Standard_Boolean bFlag;
949 Standard_Integer iErr;
950 Standard_Real aTolF1, aTolF2, aTol;
953 TopoDS_Face aF1, aF2;
955 TopExp_Explorer aExp;
957 bFlag=Standard_False;
960 aF1.Orientation(TopAbs_FORWARD);
962 aF2.Orientation(TopAbs_FORWARD);
964 aTolF1=BRep_Tool::Tolerance(aF1);
966 aExp.Init(aF1, TopAbs_EDGE);
967 for (; aExp.More(); aExp.Next()) {
968 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
969 if (!BRep_Tool::Degenerated(aE1)) {
970 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
971 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
975 aTolF2=BRep_Tool::Tolerance(aF2);
976 aTol = aTolF1 + aTolF2 + Precision::Confusion();
978 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
981 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
987 //=======================================================================
988 //function : CheckSameGeom
990 //=======================================================================
991 Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
992 (const TopoDS_Face& theF1,
993 const TopoDS_Face& theF2,
994 Handle(IntTools_Context)& theContext)
996 Standard_Boolean bRet;
997 Standard_Real aTolF1, aTolF2, aTol;
1000 TopExp_Explorer aExp;
1002 bRet=Standard_False;
1003 aExp.Init(theF1, TopAbs_EDGE);
1004 for (; aExp.More(); aExp.Next()) {
1005 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
1006 if (!BRep_Tool::Degenerated(aE)) {
1007 aTolF1=BRep_Tool::Tolerance(theF1);
1008 aTolF2=BRep_Tool::Tolerance(theF2);
1010 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
1011 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
1017 //=======================================================================
1020 //=======================================================================
1021 Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
1022 const TopoDS_Face& theF2)
1024 Standard_Integer iSense=0;
1025 gp_Dir aDNF1, aDNF2;
1026 TopoDS_Edge aE1, aE2;
1027 TopExp_Explorer aExp;
1029 aExp.Init(theF1, TopAbs_EDGE);
1030 for (; aExp.More(); aExp.Next()) {
1031 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
1032 if (!BRep_Tool::Degenerated(aE1)) {
1033 if (!BRep_Tool::IsClosed(aE1, theF1)) {
1039 aExp.Init(theF2, TopAbs_EDGE);
1040 for (; aExp.More(); aExp.Next()) {
1041 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
1042 if (!BRep_Tool::Degenerated(aE2)) {
1043 if (!BRep_Tool::IsClosed(aE2, theF2)) {
1044 if (aE2.IsSame(aE1)) {
1056 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
1057 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
1059 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1063 //=======================================================================
1064 // function: IsSplitToReverse
1066 //=======================================================================
1067 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1068 (const TopoDS_Shape& theSp,
1069 const TopoDS_Shape& theSr,
1070 Handle(IntTools_Context)& theContext)
1072 Standard_Boolean bRet;
1073 TopAbs_ShapeEnum aType;
1075 bRet=Standard_False;
1077 aType=theSp.ShapeType();
1080 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1081 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1082 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1087 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1088 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1089 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1098 //=======================================================================
1099 //function :IsSplitToReverse
1101 //=======================================================================
1102 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1103 (const TopoDS_Face& theFSp,
1104 const TopoDS_Face& theFSr,
1105 Handle(IntTools_Context)& theContext)
1107 Standard_Boolean bRet, bFound, bInFace;
1108 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1109 gp_Pnt aPFSp, aPFSr;
1112 Handle(Geom_Surface) aSr, aSp;
1113 TopAbs_Orientation aOrSr, aOrSp;
1114 TopExp_Explorer anExp;
1117 bRet=Standard_False;
1119 aSr=BRep_Tool::Surface(theFSr);
1120 aSp=BRep_Tool::Surface(theFSp);
1122 aOrSr=theFSr.Orientation();
1123 aOrSp=theFSp.Orientation();
1124 bRet=(aOrSr!=aOrSp);
1128 bFound=Standard_False;
1129 anExp.Init(theFSp, TopAbs_EDGE);
1130 for (; anExp.More(); anExp.Next()) {
1131 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1132 if (!BRep_Tool::Degenerated(aESp)) {
1133 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1140 Standard_Boolean bFlag;
1141 Standard_Integer iErr;
1144 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp,
1150 aP2DFSp.Coord(aU, aV);
1151 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1156 if (theFSp.Orientation()==TopAbs_REVERSED){
1161 BRep_Tool::Range(aESp, aT1, aT2);
1162 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
1163 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT,
1168 // Parts of theContext->ComputeVS(..)
1169 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1170 aProjector.Perform(aPFSp);
1171 if (!aProjector.IsDone()) {
1175 aProjector.LowerDistanceParameters(aU, aV);
1176 gp_Pnt2d aP2D(aU, aV);
1177 bInFace=theContext->IsPointInOnFace (theFSr, aP2D);
1182 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1185 gp_Dir aDNFSr=aDD1U^aDD1V;
1186 if (theFSr.Orientation()==TopAbs_REVERSED){
1190 aScPr=aDNFSp*aDNFSr;
1195 //=======================================================================
1196 //function :IsSplitToReverse
1198 //=======================================================================
1199 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1200 (const TopoDS_Edge& aEF1,
1201 const TopoDS_Edge& aEF2,
1202 Handle(IntTools_Context)& theContext)
1204 Standard_Boolean bRet, bIsDegenerated;
1206 bRet=Standard_False;
1207 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1208 BRep_Tool::Degenerated(aEF2));
1209 if (bIsDegenerated) {
1214 TopAbs_Orientation aOrE, aOrSp;
1215 Handle(Geom_Curve)aC1, aC2;
1217 aC2=BRep_Tool::Curve(aEF2, a, b);
1218 aC1=BRep_Tool::Curve(aEF1, a, b);
1221 aOrE=aEF2.Orientation();
1222 aOrSp=aEF1.Orientation();
1227 Standard_Real aT1, aT2, aScPr;
1231 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1233 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1236 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1238 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1247 //=======================================================================
1250 //=======================================================================
1251 Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1252 const TopoDS_Shape& aFace)
1254 Standard_Boolean bIsHole;
1255 Standard_Integer i, aNbS;
1256 Standard_Real aT1, aT2, aS;
1257 Standard_Real aU1, aU, dU;
1258 Standard_Real aX1, aY1, aX0, aY0;
1259 TopAbs_Orientation aOr;
1261 gp_Pnt2d aP2D0, aP2D1;
1262 Handle(Geom2d_Curve) aC2D;
1263 TopoDS_Face aF, aFF;
1264 TopoDS_Iterator aItW;
1266 bIsHole=Standard_False;
1268 aF=(*(TopoDS_Face *)(&aFace));
1270 aFF.Orientation(TopAbs_FORWARD);
1273 aItW.Initialize(aW);
1274 for (; aItW.More(); aItW.Next()) {
1275 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1276 aOr=aE.Orientation();
1277 if (!(aOr==TopAbs_FORWARD ||
1278 aOr==TopAbs_REVERSED)) {
1282 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1283 if (aC2D.IsNull()) {
1287 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1288 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1293 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1296 if (aOr==TopAbs_REVERSED) {
1302 aBAC2D.D0(aU, aP2D0);
1303 for(i=2; i<=aNbS; i++) {
1305 aBAC2D.D0(aU, aP2D1);
1306 aP2D0.Coord(aX0, aY0);
1307 aP2D1.Coord(aX1, aY1);
1309 aS=aS+(aY0+aY1)*(aX1-aX0);
1313 }//for (; aItW.More(); aItW.Next()) {
1318 //=======================================================================
1319 // function: MakeContainer
1321 //=======================================================================
1322 void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1328 case TopAbs_COMPOUND:{
1330 aBB.MakeCompound(aC);
1335 case TopAbs_COMPSOLID:{
1336 TopoDS_CompSolid aCS;
1337 aBB.MakeCompSolid(aCS);
1343 TopoDS_Solid aSolid;
1344 aBB.MakeSolid(aSolid);
1351 TopoDS_Shell aShell;
1352 aBB.MakeShell(aShell);
1359 aBB.MakeWire(aWire);
1368 //=======================================================================
1369 // function: MakePCurve
1371 //=======================================================================
1372 void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1373 const TopoDS_Face& aF1,
1374 const TopoDS_Face& aF2,
1375 const IntTools_Curve& aIC,
1376 const Standard_Boolean bPC1,
1377 const Standard_Boolean bPC2)
1381 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1382 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1385 Standard_Boolean bPC;
1387 aTolE=BRep_Tool::Tolerance(aE);
1389 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
1390 Handle(Geom_TrimmedCurve)aC3DETrim=
1391 new Geom_TrimmedCurve(aC3DE, aT1, aT2);
1393 for (i=0; i<2; ++i) {
1394 bPC = !i ? bPC1 : bPC2;
1401 aC2Dx1=aIC.FirstCurve2d();
1405 aC2Dx1=aIC.SecondCurve2d();
1408 aFFWD.Orientation(TopAbs_FORWARD);
1411 if (aC2D.IsNull()) {
1412 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1413 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1414 aOutFirst, aOutLast,
1418 if (aC3DE->IsPeriodic()) {
1419 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D,
1423 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D,
1427 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1428 //BRepLib::SameParameter(aE);
1430 BRepLib::SameParameter(aE);
1432 //=======================================================================
1433 // function: MakeEdge
1435 //=======================================================================
1436 void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1437 const TopoDS_Vertex& theV1,
1438 const Standard_Real theT1,
1439 const TopoDS_Vertex& theV2,
1440 const Standard_Real theT2,
1441 const Standard_Real theTolR3D,
1444 Standard_Real aTolV;
1447 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2,
1450 aBB.UpdateEdge(theE, theTolR3D);
1452 aTolV=BRep_Tool::Tolerance(theV1);
1453 if (aTolV<theTolR3D) {
1454 aBB.UpdateVertex(theV1, theTolR3D);
1457 aTolV=BRep_Tool::Tolerance(theV2);
1458 if (aTolV<theTolR3D) {
1459 aBB.UpdateVertex(theV2, theTolR3D);
1462 //=======================================================================
1463 // function: ComputeVV
1465 //=======================================================================
1466 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1468 const Standard_Real aTolP2)
1470 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1473 aTolV1=BRep_Tool::Tolerance(aV1);
1475 aTolSum = aTolV1 + aTolP2 + Precision::Confusion();
1476 aTolSum2=aTolSum*aTolSum;
1478 aP1=BRep_Tool::Pnt(aV1);
1480 aD2=aP1.SquareDistance(aP2);
1486 //=======================================================================
1487 // function: ComputeVV
1489 //=======================================================================
1490 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1491 const TopoDS_Vertex& aV2)
1493 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1496 aTolV1=BRep_Tool::Tolerance(aV1);
1497 aTolV2=BRep_Tool::Tolerance(aV2);
1498 aTolSum = aTolV1 + aTolV2 + Precision::Confusion();
1499 aTolSum2=aTolSum*aTolSum;
1501 aP1=BRep_Tool::Pnt(aV1);
1502 aP2=BRep_Tool::Pnt(aV2);
1504 aD2=aP1.SquareDistance(aP2);
1510 //=======================================================================
1511 // function: MakeVertex
1513 //=======================================================================
1514 void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
1515 TopoDS_Vertex& aVnew)
1517 Standard_Integer aNb;
1525 aVnew=*((TopoDS_Vertex*)(&aLV.First()));
1530 Standard_Integer m, n;
1531 Standard_Real aR[2], dR, aD, aEps;
1532 TopoDS_Vertex aV[2];
1537 for (m=0; m<aNb; ++m) {
1539 *((TopoDS_Vertex*)(&aLV.First())):
1540 *((TopoDS_Vertex*)(&aLV.Last()));
1541 aP[m]=BRep_Tool::Pnt(aV[m]);
1542 aR[m]=BRep_Tool::Tolerance(aV[m]);
1552 dR=aR[m]-aR[n]; // dR >= 0.
1553 gp_Vec aVD(aP[m], aP[n]);
1556 if (aD<=dR || aD<aEps) {
1557 aBB.MakeVertex (aVnew, aP[m], aR[m]);
1564 aRr=0.5*(aR[m]+aR[n]+aD);
1565 aXYZr=0.5*(aP[m].XYZ()+aP[n].XYZ()-aVD.XYZ()*(dR/aD));
1568 aBB.MakeVertex (aVnew, aPr, aRr);
1571 }// else if (aNb==2) {
1573 else { // if (aNb>2)
1574 // compute the point
1576 // issue 0027540 - sum of doubles may depend on the order
1577 // of addition, thus sort the coordinates for stable result
1579 NCollection_Array1<gp_Pnt> aPoints(0, aNb-1);
1580 BOPCol_ListIteratorOfListOfShape aIt(aLV);
1581 for (i = 0; aIt.More(); aIt.Next(), ++i) {
1582 const TopoDS_Vertex& aVi = *((TopoDS_Vertex*)(&aIt.Value()));
1583 gp_Pnt aPi = BRep_Tool::Pnt(aVi);
1587 std::sort(aPoints.begin(), aPoints.end(), BOPTools_AlgoTools_ComparePoints());
1589 gp_XYZ aXYZ(0., 0., 0.);
1590 for (i = 0; i < aNb; ++i) {
1591 aXYZ += aPoints(i).XYZ();
1593 aXYZ.Divide((Standard_Real)aNb);
1597 // compute the tolerance for the new vertex
1598 Standard_Real aTi, aDi, aDmax;
1601 aIt.Initialize(aLV);
1602 for (; aIt.More(); aIt.Next()) {
1603 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1604 gp_Pnt aPi=BRep_Tool::Pnt(aVi);
1605 aTi=BRep_Tool::Tolerance(aVi);
1606 aDi=aP.SquareDistance(aPi);
1615 aBB.MakeVertex (aVnew, aP, aDmax);
1618 //=======================================================================
1619 //function : GetEdgeOnFace
1621 //=======================================================================
1622 Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
1623 (const TopoDS_Edge& theE1,
1624 const TopoDS_Face& theF2,
1627 Standard_Boolean bFound;
1628 TopoDS_Iterator aItF, aItW;
1630 bFound=Standard_False;
1632 aItF.Initialize(theF2);
1633 for (; aItF.More(); aItF.Next()) {
1634 const TopoDS_Shape& aW=aItF.Value();
1635 aItW.Initialize(aW);
1636 for (; aItW.More(); aItW.Next()) {
1637 const TopoDS_Shape& aE=aItW.Value();
1638 if (aE.IsSame(theE1)) {
1639 theE2=(*(TopoDS_Edge*)(&aE));
1647 //=======================================================================
1648 //function : FindFacePairs
1650 //=======================================================================
1651 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1652 const BOPCol_ListOfShape& thLF,
1653 BOPTools_ListOfCoupleOfShape& theLCFF,
1654 Handle(IntTools_Context)& theContext)
1656 Standard_Boolean bFound;
1657 Standard_Integer i, aNbCEF;
1658 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
1659 BOPCol_MapOfShape aMFP;
1660 TopoDS_Face aF1, aF2;
1661 TopoDS_Edge aEL, aE1;
1662 BOPCol_ListIteratorOfListOfShape aItLF;
1663 BOPTools_CoupleOfShape aCEF, aCFF;
1664 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1665 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1667 bFound=Standard_True;
1670 aItLF.Initialize(thLF);
1671 for (; aItLF.More(); aItLF.Next()) {
1672 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1674 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1676 return bFound; // it can not be so
1679 aCEF.SetShape1(aEL);
1680 aCEF.SetShape2(aFL);
1684 aNbCEF=aLCEF.Extent();
1689 aIt.Initialize(aLCEF);
1690 for (i=0; aIt.More(); aIt.Next(), ++i) {
1691 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1692 const TopoDS_Shape& aEx=aCSx.Shape1();
1693 const TopoDS_Shape& aFx=aCSx.Shape2();
1695 aOr=aEx.Orientation();
1698 aOrC=TopAbs::Reverse(aOr);
1699 aE1=(*(TopoDS_Edge*)(&aEx));
1700 aF1=(*(TopoDS_Face*)(&aFx));
1706 aLCEFx.Append(aCSx);
1712 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1714 aCFF.SetShape1(aF1);
1715 aCFF.SetShape2(aF2);
1716 theLCFF.Append(aCFF);
1725 aIt.Initialize(aLCEFx);
1726 for (; aIt.More(); aIt.Next()) {
1727 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1728 const TopoDS_Shape& aFx=aCSx.Shape2();
1729 if (!aMFP.Contains(aFx)) {
1734 aNbCEF=aLCEF.Extent();
1739 //=======================================================================
1740 //function : AngleWithRef
1742 //=======================================================================
1743 Standard_Real AngleWithRef(const gp_Dir& theD1,
1744 const gp_Dir& theD2,
1745 const gp_Dir& theDRef)
1747 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1752 const gp_XYZ& aXYZ1=theD1.XYZ();
1753 const gp_XYZ& aXYZ2=theD2.XYZ();
1754 aXYZ=aXYZ1.Crossed(aXYZ2);
1755 aSinus=aXYZ.Modulus();
1756 aCosinus=theD1*theD2;
1760 aBeta=aHalfPI*(1.-aCosinus);
1763 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1766 aScPr=aXYZ.Dot(theDRef.XYZ());
1772 //=======================================================================
1773 // function: IsBlockInOnFace
1775 //=======================================================================
1776 Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
1777 (const IntTools_Range& aShrR,
1778 const TopoDS_Face& aF,
1779 const TopoDS_Edge& aE1,
1780 Handle(IntTools_Context)& aContext)
1782 Standard_Boolean bFlag;
1783 Standard_Real f1, l1, ULD, VLD;
1787 aShrR.Range(f1, l1);
1788 Standard_Real dt=0.0075, k;//dt=0.001, k;
1794 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1796 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1797 aProjector.Perform(aP11);
1799 bFlag=aProjector.IsDone();
1804 aProjector.LowerDistanceParameters(ULD, VLD);
1805 aP2D.SetCoord(ULD, VLD);
1807 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1814 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1816 aProjector.Perform(aP12);
1818 bFlag=aProjector.IsDone();
1823 aProjector.LowerDistanceParameters(ULD, VLD);
1824 aP2D.SetCoord(ULD, VLD);
1826 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1832 // Treatment intemediate
1833 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1834 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1835 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1837 aProjector.Perform(aP12);
1839 bFlag=aProjector.IsDone();
1844 aTolE=BRep_Tool::Tolerance(aE1);
1845 aTolF=BRep_Tool::Tolerance(aF);
1847 aDist=aProjector.LowerDistance();
1849 return Standard_False;
1852 aProjector.LowerDistanceParameters(ULD, VLD);
1853 aP2D.SetCoord(ULD, VLD);
1855 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1863 //=======================================================================
1864 //function : IsMicroEdge
1866 //=======================================================================
1867 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
1868 (const TopoDS_Edge& aE,
1869 const Handle(IntTools_Context)& aCtx,
1870 const Standard_Boolean bCheckSplittable)
1872 Standard_Boolean bRet;
1873 Standard_Real aT1, aT2, aTmp;
1874 Handle(Geom_Curve) aC3D;
1875 TopoDS_Vertex aV1, aV2;
1877 bRet=(BRep_Tool::Degenerated(aE) ||
1878 !BRep_Tool::IsGeometric(aE));
1883 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1884 TopExp::Vertices(aE, aV1, aV2);
1885 aT1=BRep_Tool::Parameter(aV1, aE);
1886 aT2=BRep_Tool::Parameter(aV2, aE);
1893 IntTools_ShrunkRange aSR;
1894 aSR.SetContext(aCtx);
1895 aSR.SetData(aE, aT1, aT2, aV1, aV2);
1897 bRet = !aSR.IsDone();
1898 if (!bRet && bCheckSplittable) {
1899 bRet = !aSR.IsSplittable();
1905 //=======================================================================
1906 //function : GetFaceDir
1907 //purpose : Get binormal direction for the face in the point aP
1908 //=======================================================================
1909 void GetFaceDir(const TopoDS_Edge& aE,
1910 const TopoDS_Face& aF,
1912 const Standard_Real aT,
1913 const gp_Dir& aDTgt,
1916 Handle(IntTools_Context)& theContext,
1917 GeomAPI_ProjectPointOnSurf& aProjPL,
1918 const Standard_Real aDt)
1920 Standard_Real aTolE;
1923 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1924 if (aF.Orientation()==TopAbs_REVERSED){
1928 aTolE=BRep_Tool::Tolerance(aE);
1931 if (!FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt, aTolE)) {
1932 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx,
1934 aProjPL.Perform(aPx);
1935 aPx = aProjPL.NearestPoint();
1936 gp_Vec aVec(aP, aPx);
1937 aDB.SetXYZ(aVec.XYZ());
1940 //=======================================================================
1941 //function : FindPointInFace
1942 //purpose : Find a point in the face in direction of <aDB>
1943 //=======================================================================
1944 Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
1948 Handle(IntTools_Context)& theContext,
1949 GeomAPI_ProjectPointOnSurf& aProjPL,
1950 const Standard_Real aDt,
1951 const Standard_Real aTolE)
1953 Standard_Integer aNbItMax;
1954 Standard_Real aDist, aDTol, aPM, anEps;
1955 Standard_Boolean bRet;
1958 aDTol = Precision::Angular();
1959 aPM = aP.XYZ().Modulus();
1961 aDTol = 5.e-16 * aPM;
1963 bRet = Standard_False;
1965 anEps = Precision::SquareConfusion();
1967 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1971 if (!aProj.IsDone()) {
1974 aPS=aProj.NearestPoint();
1975 aProjPL.Perform(aPS);
1976 aPS=aProjPL.NearestPoint();
1978 aPS.SetXYZ(aPS.XYZ()+2.*aTolE*aDB.XYZ());
1980 if (!aProj.IsDone()) {
1983 aPS=aProj.NearestPoint();
1984 aProjPL.Perform(aPS);
1985 aPS=aProjPL.NearestPoint();
1988 aP1.SetXYZ(aPS.XYZ()+aDt*aDB.XYZ());
1991 if (!aProj.IsDone()) {
1994 aPOut = aProj.NearestPoint();
1995 aDist = aProj.LowerDistance();
1997 aProjPL.Perform(aPOut);
1998 aPOut = aProjPL.NearestPoint();
2000 gp_Vec aV(aPS, aPOut);
2001 if (aV.SquareMagnitude() < anEps) {
2004 aDB.SetXYZ(aV.XYZ());
2005 } while (aDist > aDTol && --aNbItMax);
2007 bRet = aDist < aDTol;
2010 //=======================================================================
2011 //function : MinStep3D
2013 //=======================================================================
2014 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
2015 const TopoDS_Face& theF1,
2016 const BOPTools_ListOfCoupleOfShape& theLCS,
2019 Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin, aR;
2020 BOPTools_CoupleOfShape aCS1;
2021 BOPTools_ListOfCoupleOfShape aLCS;
2022 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
2023 BRepAdaptor_Surface aBAS;
2026 aCS1.SetShape1(theE1);
2027 aCS1.SetShape2(theF1);
2030 aTolE = BRep_Tool::Tolerance(theE1);
2034 aIt.Initialize(aLCS);
2035 for (; aIt.More(); aIt.Next()) {
2036 const BOPTools_CoupleOfShape& aCS = aIt.Value();
2037 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2()));
2039 aTolF = BRep_Tool::Tolerance(aF);
2040 aDt = 2*(aTolE + aTolF);
2043 aBAS.Initialize(aF, Standard_False);
2044 GeomAbs_SurfaceType aSType = aBAS.GetType();
2046 case GeomAbs_Cylinder: {
2047 aR = aBAS.Cylinder().Radius();
2050 case GeomAbs_Cone: {
2051 gp_Lin aL(aBAS.Cone().Axis());
2052 aR = aL.Distance(aP);
2055 case GeomAbs_Sphere: {
2056 aDtMin = Max(aDtMin, 5.e-4);
2057 aR = aBAS.Sphere().Radius();
2060 case GeomAbs_Torus: {
2061 aR = aBAS.Torus().MajorRadius();
2065 aDtMin = Max(aDtMin, 5.e-4);
2070 Standard_Real d = 10*Precision::PConfusion();
2071 aDtMin = Max(aDtMin, sqrt(d*d + 2*d*aR));
2079 if (aDtMax < aDtMin) {
2085 //=======================================================================
2086 //function : IsOpenShell
2088 //=======================================================================
2089 Standard_Boolean BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
2091 Standard_Boolean bRet;
2092 Standard_Integer i, aNbE, aNbF;
2093 TopAbs_Orientation aOrF;
2094 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
2095 BOPCol_ListIteratorOfListOfShape aItLS;
2097 bRet=Standard_False;
2099 BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF);
2102 for (i=1; i<=aNbE; ++i) {
2103 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i));
2104 if (BRep_Tool::Degenerated(aE)) {
2109 const BOPCol_ListOfShape& aLF=aMEF(i);
2110 aItLS.Initialize(aLF);
2111 for (; aItLS.More(); aItLS.Next()) {
2112 const TopoDS_Shape& aF=aItLS.Value();
2113 aOrF=aF.Orientation();
2114 if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
2128 //=======================================================================
2129 //function : IsInvertedSolid
2131 //=======================================================================
2132 Standard_Boolean BOPTools_AlgoTools::IsInvertedSolid
2133 (const TopoDS_Solid& aSolid)
2135 Standard_Real aTolS;
2136 TopAbs_State aState;
2137 BRepClass3d_SolidClassifier aSC(aSolid);
2140 aSC.PerformInfinitePoint(aTolS);
2142 return (aState==TopAbs_IN);