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 <BOPCol_MapOfOrientedShape.hxx>
22 #include <BOPTools.hxx>
23 #include <BOPTools_AlgoTools.hxx>
24 #include <BOPTools_AlgoTools2D.hxx>
25 #include <BOPTools_AlgoTools3D.hxx>
26 #include <BOPTools_CoupleOfShape.hxx>
27 #include <BOPTools_ListOfCoupleOfShape.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAdaptor_Curve2d.hxx>
31 #include <BRepAdaptor_Surface.hxx>
32 #include <BRepClass3d_SolidClassifier.hxx>
33 #include <BRepLib.hxx>
34 #include <Geom2d_Curve.hxx>
35 #include <Geom2dInt_Geom2dCurveTool.hxx>
36 #include <Geom_Curve.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_Surface.hxx>
39 #include <Geom_TrimmedCurve.hxx>
40 #include <GeomAPI_ProjectPointOnSurf.hxx>
41 #include <gp_Cone.hxx>
42 #include <gp_Cylinder.hxx>
45 #include <gp_Pnt2d.hxx>
46 #include <gp_Sphere.hxx>
47 #include <gp_Torus.hxx>
49 #include <IntTools_Context.hxx>
50 #include <IntTools_Curve.hxx>
51 #include <IntTools_Range.hxx>
52 #include <IntTools_ShrunkRange.hxx>
53 #include <IntTools_Tools.hxx>
54 #include <Precision.hxx>
55 #include <TopAbs_Orientation.hxx>
57 #include <TopExp_Explorer.hxx>
59 #include <TopoDS_Compound.hxx>
60 #include <TopoDS_CompSolid.hxx>
61 #include <TopoDS_Edge.hxx>
62 #include <TopoDS_Face.hxx>
63 #include <TopoDS_Shape.hxx>
64 #include <TopoDS_Shell.hxx>
65 #include <TopoDS_Solid.hxx>
66 #include <TopoDS_Vertex.hxx>
67 #include <TopoDS_Wire.hxx>
68 #include <NCollection_Array1.hxx>
73 Standard_Real AngleWithRef(const gp_Dir& theD1,
75 const gp_Dir& theDRef);
78 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
79 const BOPCol_ListOfShape& thLF,
80 BOPTools_ListOfCoupleOfShape& theLCFF,
81 Handle(IntTools_Context)& theContext);
83 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
84 const TopoDS_Face& aF);
87 Standard_Boolean GetFaceDir(const TopoDS_Edge& aE,
88 const TopoDS_Face& aF,
90 const Standard_Real aT,
92 const Standard_Boolean theSmallFaces,
95 Handle(IntTools_Context)& theContext,
96 GeomAPI_ProjectPointOnSurf& aProjPL,
97 const Standard_Real aDt);
99 Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
103 Handle(IntTools_Context)& theContext,
104 GeomAPI_ProjectPointOnSurf& aProjPL,
105 const Standard_Real aDt,
106 const Standard_Real aTolE);
108 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
109 const TopoDS_Face& theF1,
110 const BOPTools_ListOfCoupleOfShape& theLCS,
112 Handle(IntTools_Context)& theContext,
113 Standard_Boolean& theSmallFaces);
117 //=======================================================================
118 // function: MakeConnexityBlocks
120 //=======================================================================
121 void BOPTools_AlgoTools::MakeConnexityBlocks
122 (const TopoDS_Shape& theS,
123 const TopAbs_ShapeEnum theType1,
124 const TopAbs_ShapeEnum theType2,
125 BOPCol_ListOfShape& theLCB)
127 // Map shapes to find connected elements
128 BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS;
129 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aDMSLS);
131 BOPCol_MapOfShape aMFence;
135 TopExp_Explorer aExp(theS, theType2);
136 for (; aExp.More(); aExp.Next()) {
137 const TopoDS_Shape& aS = aExp.Current();
138 if (!aMFence.Add(aS)) {
142 BOPCol_IndexedMapOfShape aMBlock;
143 TopoDS_Compound aBlock;
144 aBB.MakeCompound(aBlock);
148 // Look for connected parts
149 for (i = 1; i <= aMBlock.Extent(); ++i) {
150 const TopoDS_Shape& aS1 = aMBlock(i);
151 TopExp_Explorer aExpSS(aS1, theType1);
152 for (; aExpSS.More(); aExpSS.Next()) {
153 const TopoDS_Shape& aSubS = aExpSS.Current();
154 const BOPCol_ListOfShape& aLS = aDMSLS.FindFromKey(aSubS);
155 BOPCol_ListIteratorOfListOfShape aItLS(aLS);
156 for (; aItLS.More(); aItLS.Next()) {
157 const TopoDS_Shape& aS2 = aItLS.Value();
158 if (aMFence.Add(aS2)) {
160 aBB.Add(aBlock, aS2);
165 // Add the block into result
166 theLCB.Append(aBlock);
169 //=======================================================================
170 // function: OrientEdgesOnWire
171 // purpose: Reorient edges on wire for correct ordering
172 //=======================================================================
173 void BOPTools_AlgoTools::OrientEdgesOnWire(TopoDS_Shape& theWire)
175 // make vertex-edges connexity map
176 BOPCol_IndexedDataMapOfShapeListOfShape aVEMap;
177 BOPTools::MapShapesAndAncestors(theWire, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
179 if (aVEMap.IsEmpty()) {
188 BOPCol_MapOfOrientedShape aMFence;
190 TopoDS_Iterator aIt(theWire);
191 for (; aIt.More(); aIt.Next()) {
192 const TopoDS_Edge& aEC = TopoDS::Edge(aIt.Value());
193 if (!aMFence.Add(aEC)) {
197 // add edge to a wire as it is
200 TopoDS_Vertex aV1, aV2;
201 TopExp::Vertices(aEC, aV1, aV2, Standard_True);
203 if (aV1.IsSame(aV2)) {
204 // closed edge, go to the next edge
208 // orient the adjacent edges
209 for (Standard_Integer i = 0; i < 2; ++i) {
210 TopoDS_Shape aVC = !i ? aV1 : aV2;
213 const BOPCol_ListOfShape& aLE = aVEMap.FindFromKey(aVC);
214 if (aLE.Extent() != 2) {
215 // free vertex or multi-connexity, go to the next edge
219 Standard_Boolean bStop = Standard_True;
221 BOPCol_ListIteratorOfListOfShape aItLE(aLE);
222 for (; aItLE.More(); aItLE.Next()) {
223 const TopoDS_Edge& aEN = TopoDS::Edge(aItLE.Value());
224 if (aMFence.Contains(aEN)) {
228 TopoDS_Vertex aVN1, aVN2;
229 TopExp::Vertices(aEN, aVN1, aVN2, Standard_True);
230 if (aVN1.IsSame(aVN2)) {
231 // closed edge, go to the next edge
235 // change orientation if necessary and go to the next edges
236 if ((!i && aVC.IsSame(aVN2)) || (i && aVC.IsSame(aVN1))) {
240 aBB.Add(aWire, aEN.Reversed());
243 aVC = aVC.IsSame(aVN1) ? aVN2 : aVN1;
244 bStop = Standard_False;
257 //=======================================================================
258 // function: OrientFacesOnShell
260 //=======================================================================
261 void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
263 Standard_Boolean bIsProcessed1, bIsProcessed2;
264 Standard_Integer i, aNbE, aNbF, j;
265 TopAbs_Orientation anOrE1, anOrE2;
266 TopoDS_Face aF1x, aF2x;
267 TopoDS_Shape aShellNew;
268 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
269 BOPCol_IndexedMapOfShape aProcessedFaces;
272 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
274 BOPTools::MapShapesAndAncestors(aShell,
275 TopAbs_EDGE, TopAbs_FACE,
277 aNbE=aEFMap.Extent();
279 // One seam edge in aEFMap contains 2 equivalent faces.
280 for (i=1; i<=aNbE; ++i) {
281 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
284 BOPCol_ListOfShape aLFTmp;
285 BOPCol_IndexedMapOfShape aFM;
287 BOPCol_ListIteratorOfListOfShape anIt(aLF);
288 for (; anIt.More(); anIt.Next()) {
289 const TopoDS_Shape& aF=anIt.Value();
290 if (!aFM.Contains(aF)) {
301 for (i=1; i<=aNbE; ++i) {
302 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
303 if (BRep_Tool::Degenerated(aE)) {
307 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
313 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
314 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
316 bIsProcessed1=aProcessedFaces.Contains(aF1);
317 bIsProcessed2=aProcessedFaces.Contains(aF2);
318 if (bIsProcessed1 && bIsProcessed2) {
322 if (!bIsProcessed1 && !bIsProcessed2) {
323 aProcessedFaces.Add(aF1);
324 aBB.Add(aShellNew, aF1);
325 bIsProcessed1=!bIsProcessed1;
330 j=aProcessedFaces.FindIndex(aF1);
331 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
336 j=aProcessedFaces.FindIndex(aF2);
337 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
340 anOrE1=Orientation(aE, aF1x);
341 anOrE2=Orientation(aE, aF2x);
343 if (bIsProcessed1 && !bIsProcessed2) {
344 if (anOrE1==anOrE2) {
345 if (!BRep_Tool::IsClosed(aE, aF1) &&
346 !BRep_Tool::IsClosed(aE, aF2)) {
350 aProcessedFaces.Add(aF2);
351 aBB.Add(aShellNew, aF2);
353 else if (!bIsProcessed1 && bIsProcessed2) {
354 if (anOrE1==anOrE2) {
355 if (!BRep_Tool::IsClosed(aE, aF1) &&
356 !BRep_Tool::IsClosed(aE, aF2)) {
360 aProcessedFaces.Add(aF1);
361 aBB.Add(aShellNew, aF1);
366 for (i=1; i<=aNbE; ++i) {
367 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
368 if (BRep_Tool::Degenerated(aE)) {
372 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
375 BOPCol_ListIteratorOfListOfShape anIt(aLF);
376 for(; anIt.More(); anIt.Next()) {
377 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
378 if (!aProcessedFaces.Contains(aF)) {
379 aProcessedFaces.Add(aF);
380 aBB.Add(aShellNew, aF);
387 //=======================================================================
388 //function : Orientation
390 //=======================================================================
391 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
392 const TopoDS_Face& aF)
394 TopAbs_Orientation anOr=TopAbs_INTERNAL;
396 TopExp_Explorer anExp;
397 anExp.Init(aF, TopAbs_EDGE);
398 for (; anExp.More(); anExp.Next()) {
399 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
400 if (anEF1.IsSame(anE)) {
401 anOr=anEF1.Orientation();
407 //=======================================================================
408 // function: MakeConnexityBlock.
410 //=======================================================================
411 void BOPTools_AlgoTools::MakeConnexityBlock
412 (BOPCol_ListOfShape& theLFIn,
413 BOPCol_IndexedMapOfShape& theMEAvoid,
414 BOPCol_ListOfShape& theLCB,
415 const Handle(NCollection_BaseAllocator)& theAllocator)
417 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
418 TopExp_Explorer aExp;
419 BOPCol_ListIteratorOfListOfShape aIt;
421 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
422 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
423 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
424 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
427 aNbF=theLFIn.Extent();
428 aIt.Initialize(theLFIn);
429 for (; aIt.More(); aIt.Next()) {
430 const TopoDS_Shape& aF=aIt.Value();
431 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
435 const TopoDS_Shape& aF1=theLFIn.First();
440 aNbAdd = aMAdd.Extent();
441 for (i=1; i<=aNbAdd; ++i) {
442 const TopoDS_Shape& aF=aMAdd(i);
445 aExp.Init(aF, TopAbs_EDGE);
446 for (; aExp.More(); aExp.Next()) {
447 const TopoDS_Shape& aE=aExp.Current();
448 if (theMEAvoid.Contains(aE)){
452 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
454 for (; aIt.More(); aIt.Next()) {
455 const TopoDS_Shape& aFx=aIt.Value();
456 if (aFx.IsSame(aF)) {
459 if (aMCB.Contains(aFx)) {
464 }//for (; aExp.More(); aExp.Next()){
466 }// for (i=1; i<=aNbAdd; ++i) {
468 aNbAdd1=aMAdd1.Extent();
474 for (i=1; i<=aNbAdd1; ++i) {
475 const TopoDS_Shape& aFAdd=aMAdd1(i);
483 for (i=1; i<=aNbF; ++i) {
484 const TopoDS_Shape& aF=aMCB(i);
488 //=======================================================================
489 // function: ComputeStateByOnePoint
491 //=======================================================================
492 TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
493 (const TopoDS_Shape& theS,
494 const TopoDS_Solid& theRef,
495 const Standard_Real theTol,
496 Handle(IntTools_Context)& theContext)
499 TopAbs_ShapeEnum aType;
501 aState=TopAbs_UNKNOWN;
502 aType=theS.ShapeType();
503 if (aType==TopAbs_VERTEX) {
504 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
505 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
507 else if (aType==TopAbs_EDGE) {
508 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
509 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
514 //=======================================================================
515 // function: ComputeState
517 //=======================================================================
518 TopAbs_State BOPTools_AlgoTools::ComputeState
519 (const TopoDS_Face& theF,
520 const TopoDS_Solid& theRef,
521 const Standard_Real theTol,
522 BOPCol_IndexedMapOfShape& theBounds,
523 Handle(IntTools_Context)& theContext)
526 TopExp_Explorer aExp;
531 aState=TopAbs_UNKNOWN;
533 aExp.Init(theF, TopAbs_EDGE);
534 for (; aExp.More(); aExp.Next()) {
535 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
536 if (BRep_Tool::Degenerated(aSE)) {
540 if (!theBounds.Contains(aSE)) {
541 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
542 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol,
547 aE1=(*(TopoDS_Edge*)(&aSE));
550 // !!<- process edges that are all on theRef
552 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF,
553 aP2D, aP3D, theContext);
554 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
560 //=======================================================================
561 // function: ComputeState
563 //=======================================================================
564 TopAbs_State BOPTools_AlgoTools::ComputeState
565 (const TopoDS_Vertex& theV,
566 const TopoDS_Solid& theRef,
567 const Standard_Real theTol,
568 Handle(IntTools_Context)& theContext)
573 aP3D=BRep_Tool::Pnt(theV);
574 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
578 //=======================================================================
579 // function: ComputeState
581 //=======================================================================
582 TopAbs_State BOPTools_AlgoTools::ComputeState
583 (const TopoDS_Edge& theE,
584 const TopoDS_Solid& theRef,
585 const Standard_Real theTol,
586 Handle(IntTools_Context)& theContext)
588 Standard_Real aT1, aT2, aT = 0.;
590 Handle(Geom_Curve) aC3D;
593 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
596 //it means that we are in degenerated edge
597 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
599 return TopAbs_UNKNOWN;
601 aP3D=BRep_Tool::Pnt(aV);
604 Standard_Boolean bF2Inf, bL2Inf;
605 Standard_Real dT=10.;
607 bF2Inf = Precision::IsNegativeInfinite(aT1);
608 bL2Inf = Precision::IsPositiveInfinite(aT2);
610 if (bF2Inf && !bL2Inf) {
613 else if (!bF2Inf && bL2Inf) {
616 else if (bF2Inf && bL2Inf) {
620 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
625 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol,
630 //=======================================================================
631 // function: ComputeState
633 //=======================================================================
634 TopAbs_State BOPTools_AlgoTools::ComputeState
636 const TopoDS_Solid& theRef,
637 const Standard_Real theTol,
638 Handle(IntTools_Context)& theContext)
642 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
643 aSC.Perform(theP, theTol);
649 //=======================================================================
650 //function : IsInternalFace
652 //=======================================================================
653 Standard_Boolean BOPTools_AlgoTools::IsInternalFace
654 (const TopoDS_Face& theFace,
655 const TopoDS_Solid& theSolid,
656 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
657 const Standard_Real theTol,
658 Handle(IntTools_Context)& theContext)
660 Standard_Boolean bDegenerated;
661 Standard_Integer aNbF, iRet, iFound;
662 TopAbs_Orientation aOr;
664 TopExp_Explorer aExp;
665 BOPCol_ListIteratorOfListOfShape aItF;
667 // For all invoked functions: [::IsInternalFace(...)]
668 // the returned value iRet means:
669 // iRet=0; - state is not IN
670 // iRet=1; - state is IN
671 // iRet=2; - state can not be found by the method of angles
673 // For this function the returned value iRet means:
674 // iRet=0; - state is not IN
675 // iRet=1; - state is IN
678 // 1 Try to find an edge from theFace in theMEF
680 aExp.Init(theFace, TopAbs_EDGE);
681 for(; aExp.More(); aExp.Next()) {
682 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
683 if (!theMEF.Contains(aE)) {
689 aOr=aE.Orientation();
690 if (aOr==TopAbs_INTERNAL) {
693 bDegenerated=BRep_Tool::Degenerated(aE);
698 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
701 return iRet != 0; // it can not be so
705 // aE is internal edge on aLF.First()
706 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
707 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
708 if (aE1.Orientation()!=TopAbs_INTERNAL) {
713 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1,
719 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
720 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
722 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
723 // treat as it was for 1 face
724 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2,
731 return Standard_False; // it can not be so
733 else { // aNbF=2,4,6,8,...
734 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF,
738 }//for(; aExp.More(); aExp.Next()) {
741 // the face has no shared edges with the solid
749 //========================================
750 // 2. Classify face using classifier
753 BOPCol_IndexedMapOfShape aBounds;
755 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
757 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid,
758 theTol, aBounds, theContext);
759 return aState == TopAbs_IN;
761 //=======================================================================
762 //function : IsInternalFace
764 //=======================================================================
765 Standard_Integer BOPTools_AlgoTools::IsInternalFace
766 (const TopoDS_Face& theFace,
767 const TopoDS_Edge& theEdge,
768 BOPCol_ListOfShape& theLF,
769 Handle(IntTools_Context)& theContext)
771 Standard_Integer aNbF, iRet;
777 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
778 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
779 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
785 BOPTools_ListOfCoupleOfShape aLCFF;
786 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
788 FindFacePairs(theEdge, theLF, aLCFF, theContext);
790 aIt.Initialize(aLCFF);
791 for (; aIt.More(); aIt.Next()) {
792 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
794 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
795 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
796 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2,
805 //=======================================================================
806 //function : IsInternalFace
808 //=======================================================================
809 Standard_Integer BOPTools_AlgoTools::IsInternalFace
810 (const TopoDS_Face& theFace,
811 const TopoDS_Edge& theEdge,
812 const TopoDS_Face& theFace1,
813 const TopoDS_Face& theFace2,
814 Handle(IntTools_Context)& theContext)
816 Standard_Boolean bRet;
817 Standard_Integer iRet;
818 TopoDS_Edge aE1, aE2;
820 BOPTools_ListOfCoupleOfShape theLCSOff;
821 BOPTools_CoupleOfShape aCS1, aCS2;
823 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
824 if (aE1.Orientation()==TopAbs_INTERNAL) {
826 aE1.Orientation(TopAbs_FORWARD);
827 aE2.Orientation(TopAbs_REVERSED);
829 else if (theFace1==theFace2) {
831 aE1.Orientation(TopAbs_FORWARD);
832 aE2.Orientation(TopAbs_REVERSED);
835 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
838 aCS1.SetShape1(theEdge);
839 aCS1.SetShape2(theFace);
840 theLCSOff.Append(aCS1);
843 aCS2.SetShape2(theFace2);
844 theLCSOff.Append(aCS2);
846 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
848 iRet=0; // theFace is not internal
849 if (theFace.IsEqual(aFOff)) {
850 // theFace is internal
853 // theFace seems to be internal
859 //=======================================================================
860 //function : GetFaceOff
862 //=======================================================================
863 Standard_Boolean BOPTools_AlgoTools::GetFaceOff
864 (const TopoDS_Edge& theE1,
865 const TopoDS_Face& theF1,
866 BOPTools_ListOfCoupleOfShape& theLCSOff,
867 TopoDS_Face& theFOff,
868 Handle(IntTools_Context)& theContext)
870 Standard_Boolean bRet, bIsComputed;
871 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
872 Standard_Real aUmin, aUsup, aVmin, aVsup, aPA;
873 gp_Pnt aPn1, aPn2, aPx;
874 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
876 TopAbs_Orientation aOr;
877 Handle(Geom_Curve)aC3D;
878 Handle(Geom_Plane) aPL;
879 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
880 GeomAPI_ProjectPointOnSurf aProjPL;
882 aPA=Precision::Angular();
885 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
886 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
889 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
890 gp_Dir aDTgt(aVTgt), aDTgt2;
891 aOr = theE1.Orientation();
893 aPL = new Geom_Plane(aPx, aDTgt);
894 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
895 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
897 Standard_Boolean bSmallFaces = Standard_False;
898 aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx, theContext, bSmallFaces);
899 bIsComputed = GetFaceDir(theE1, theF1, aPx, aT, aDTgt, bSmallFaces,
900 aDN1, aDBF, theContext, aProjPL, aDt3D);
903 cout << "BOPTools_AlgoTools::GetFaceOff(): incorrect computation of bi-normal direction." << endl;
910 aIt.Initialize(theLCSOff);
911 for (; aIt.More(); aIt.Next()) {
912 const BOPTools_CoupleOfShape& aCS=aIt.Value();
913 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
914 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
916 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
917 bIsComputed = GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, bSmallFaces, aDN2,
918 aDBF2, theContext, aProjPL, aDt3D);
921 cout << "BOPTools_AlgoTools::GetFaceOff(): incorrect computation of bi-normal direction." << endl;
925 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
928 aAngle=aTwoPI+aAngle;
935 else if (aF2.IsSame(theF1)) {
940 if (fabs(aAngle-aAngleMin)<aPA) {
941 // the minimal angle can not be found
945 if (aAngle<aAngleMin){
949 else if (aAngle==aAngleMin) {
950 // the minimal angle can not be found
956 //=======================================================================
957 //function : GetEdgeOff
959 //=======================================================================
960 Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
961 const TopoDS_Face& theF2,
964 Standard_Boolean bFound;
965 TopAbs_Orientation aOr1, aOr1C, aOr2;
966 TopExp_Explorer anExp;
968 bFound=Standard_False;
969 aOr1=theE1.Orientation();
970 aOr1C=TopAbs::Reverse(aOr1);
972 anExp.Init(theF2, TopAbs_EDGE);
973 for (; anExp.More(); anExp.Next()) {
974 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
975 if (aEF2.IsSame(theE1)) {
976 aOr2=aEF2.Orientation();
987 //=======================================================================
988 //function : AreFacesSameDomain
990 //=======================================================================
991 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
992 (const TopoDS_Face& theF1,
993 const TopoDS_Face& theF2,
994 Handle(IntTools_Context)& theContext,
995 const Standard_Real theFuzz)
997 Standard_Boolean bFlag;
998 Standard_Integer iErr;
999 Standard_Real aTolF1, aTolF2, aTol;
1002 TopoDS_Face aF1, aF2;
1004 TopExp_Explorer aExp;
1005 Standard_Real aFuzz1 = (theFuzz > Precision::Confusion() ? theFuzz : Precision::Confusion());
1007 bFlag=Standard_False;
1010 aF1.Orientation(TopAbs_FORWARD);
1012 aF2.Orientation(TopAbs_FORWARD);
1014 aTolF1=BRep_Tool::Tolerance(aF1);
1016 aExp.Init(aF1, TopAbs_EDGE);
1017 for (; aExp.More(); aExp.Next()) {
1018 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
1019 if (!BRep_Tool::Degenerated(aE1)) {
1020 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
1021 if (aTolE > aTolF1) {
1027 aTolF2=BRep_Tool::Tolerance(aF2);
1028 aTol = aTolF1 + aTolF2 + aFuzz1;
1030 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
1033 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
1039 //=======================================================================
1040 //function : CheckSameGeom
1042 //=======================================================================
1043 Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
1044 (const TopoDS_Face& theF1,
1045 const TopoDS_Face& theF2,
1046 Handle(IntTools_Context)& theContext)
1048 Standard_Boolean bRet;
1049 Standard_Real aTolF1, aTolF2, aTol;
1052 TopExp_Explorer aExp;
1054 bRet=Standard_False;
1055 aExp.Init(theF1, TopAbs_EDGE);
1056 for (; aExp.More(); aExp.Next()) {
1057 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
1058 if (!BRep_Tool::Degenerated(aE)) {
1059 aTolF1=BRep_Tool::Tolerance(theF1);
1060 aTolF2=BRep_Tool::Tolerance(theF2);
1062 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
1063 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
1069 //=======================================================================
1072 //=======================================================================
1073 Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
1074 const TopoDS_Face& theF2,
1075 const Handle(IntTools_Context)& theContext)
1077 Standard_Integer iSense=0;
1078 gp_Dir aDNF1, aDNF2;
1079 TopoDS_Edge aE1, aE2;
1080 TopExp_Explorer aExp;
1082 aExp.Init(theF1, TopAbs_EDGE);
1083 for (; aExp.More(); aExp.Next()) {
1084 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
1085 if (!BRep_Tool::Degenerated(aE1)) {
1086 if (!BRep_Tool::IsClosed(aE1, theF1)) {
1092 aExp.Init(theF2, TopAbs_EDGE);
1093 for (; aExp.More(); aExp.Next()) {
1094 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
1095 if (!BRep_Tool::Degenerated(aE2)) {
1096 if (!BRep_Tool::IsClosed(aE2, theF2)) {
1097 if (aE2.IsSame(aE1)) {
1109 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1, theContext);
1110 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2, theContext);
1112 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1116 //=======================================================================
1117 // function: IsSplitToReverse
1119 //=======================================================================
1120 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1121 (const TopoDS_Shape& theSp,
1122 const TopoDS_Shape& theSr,
1123 Handle(IntTools_Context)& theContext)
1125 Standard_Boolean bRet;
1126 TopAbs_ShapeEnum aType;
1128 bRet=Standard_False;
1130 aType=theSp.ShapeType();
1133 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1134 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1135 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1140 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1141 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1142 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1151 //=======================================================================
1152 //function :IsSplitToReverse
1154 //=======================================================================
1155 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1156 (const TopoDS_Face& theFSp,
1157 const TopoDS_Face& theFSr,
1158 Handle(IntTools_Context)& theContext)
1161 Handle(Geom_Surface) aSFSp = BRep_Tool::Surface(theFSp);
1162 Handle(Geom_Surface) aSFOr = BRep_Tool::Surface(theFSr);
1163 if (aSFSp == aSFOr) {
1164 return theFSp.Orientation() != theFSr.Orientation();
1167 Standard_Boolean bDone = Standard_False;
1168 // Find the point inside the split face
1173 Standard_Integer iErr;
1174 // Use the hatcher to find the point in the middle of the face
1175 iErr = BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp, theContext);
1177 // Hatcher has failed to find a point.
1178 // Try to get the point near some not closed and
1179 // not degenerated edge on the split face.
1180 TopExp_Explorer anExp(theFSp, TopAbs_EDGE);
1181 for (; anExp.More(); anExp.Next()) {
1182 const TopoDS_Edge& aESp = (*(TopoDS_Edge*)(&anExp.Current()));
1183 if (!BRep_Tool::Degenerated(aESp) && !BRep_Tool::IsClosed(aESp, theFSp)) {
1184 iErr = BOPTools_AlgoTools3D::PointNearEdge
1185 (aESp, theFSp, aP2DFSp, aPFSp, theContext);
1192 if (!anExp.More()) {
1193 // The point has not been found.
1198 // Compute normal direction of the split face
1200 bDone = BOPTools_AlgoTools3D::GetNormalToSurface
1201 (aSFSp, aP2DFSp.X(), aP2DFSp.Y(), aDNFSp);
1206 if (theFSp.Orientation() == TopAbs_REVERSED){
1210 // Project the point from the split face on the original face
1211 // to find its UV coordinates
1212 GeomAPI_ProjectPointOnSurf& aProjector = theContext->ProjPS(theFSr);
1213 aProjector.Perform(aPFSp);
1214 bDone = (aProjector.NbPoints() > 0);
1218 // UV coordinates of the point on the original face
1219 Standard_Real aU, aV;
1220 aProjector.LowerDistanceParameters(aU, aV);
1222 // Compute normal direction for the original face in this point
1224 bDone = BOPTools_AlgoTools3D::GetNormalToSurface(aSFOr, aU, aV, aDNFOr);
1229 if (theFSr.Orientation() == TopAbs_REVERSED) {
1233 // compare the normals
1234 Standard_Real aCos = aDNFSp*aDNFOr;
1237 //=======================================================================
1238 //function :IsSplitToReverse
1240 //=======================================================================
1241 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
1242 (const TopoDS_Edge& aEF1,
1243 const TopoDS_Edge& aEF2,
1244 Handle(IntTools_Context)& theContext)
1246 Standard_Boolean bRet, bIsDegenerated;
1248 bRet=Standard_False;
1249 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1250 BRep_Tool::Degenerated(aEF2));
1251 if (bIsDegenerated) {
1256 TopAbs_Orientation aOrE, aOrSp;
1257 Handle(Geom_Curve)aC1, aC2;
1259 aC2=BRep_Tool::Curve(aEF2, a, b);
1260 aC1=BRep_Tool::Curve(aEF1, a, b);
1263 aOrE=aEF2.Orientation();
1264 aOrSp=aEF1.Orientation();
1269 Standard_Real aT1, aT2, aScPr;
1273 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1275 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1278 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1280 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1289 //=======================================================================
1292 //=======================================================================
1293 Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1294 const TopoDS_Shape& aFace)
1296 Standard_Boolean bIsHole;
1297 Standard_Integer i, aNbS;
1298 Standard_Real aT1, aT2, aS;
1299 Standard_Real aU1, aU, dU;
1300 Standard_Real aX1, aY1, aX0, aY0;
1301 TopAbs_Orientation aOr;
1303 gp_Pnt2d aP2D0, aP2D1;
1304 Handle(Geom2d_Curve) aC2D;
1305 TopoDS_Face aF, aFF;
1306 TopoDS_Iterator aItW;
1308 bIsHole=Standard_False;
1310 aF=(*(TopoDS_Face *)(&aFace));
1312 aFF.Orientation(TopAbs_FORWARD);
1315 aItW.Initialize(aW);
1316 for (; aItW.More(); aItW.Next()) {
1317 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1318 aOr=aE.Orientation();
1319 if (!(aOr==TopAbs_FORWARD ||
1320 aOr==TopAbs_REVERSED)) {
1324 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1325 if (aC2D.IsNull()) {
1329 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1330 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1335 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1338 if (aOr==TopAbs_REVERSED) {
1344 aBAC2D.D0(aU, aP2D0);
1345 for(i=2; i<=aNbS; i++) {
1347 aBAC2D.D0(aU, aP2D1);
1348 aP2D0.Coord(aX0, aY0);
1349 aP2D1.Coord(aX1, aY1);
1351 aS=aS+(aY0+aY1)*(aX1-aX0);
1355 }//for (; aItW.More(); aItW.Next()) {
1360 //=======================================================================
1361 // function: MakeContainer
1363 //=======================================================================
1364 void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1370 case TopAbs_COMPOUND:{
1372 aBB.MakeCompound(aC);
1377 case TopAbs_COMPSOLID:{
1378 TopoDS_CompSolid aCS;
1379 aBB.MakeCompSolid(aCS);
1385 TopoDS_Solid aSolid;
1386 aBB.MakeSolid(aSolid);
1393 TopoDS_Shell aShell;
1394 aBB.MakeShell(aShell);
1401 aBB.MakeWire(aWire);
1410 //=======================================================================
1411 // function: MakePCurve
1413 //=======================================================================
1414 void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1415 const TopoDS_Face& aF1,
1416 const TopoDS_Face& aF2,
1417 const IntTools_Curve& aIC,
1418 const Standard_Boolean bPC1,
1419 const Standard_Boolean bPC2,
1420 const Handle(IntTools_Context)& theContext)
1424 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1425 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1428 Standard_Boolean bPC;
1430 aTolE=BRep_Tool::Tolerance(aE);
1432 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
1433 Handle(Geom_TrimmedCurve)aC3DETrim=
1434 new Geom_TrimmedCurve(aC3DE, aT1, aT2);
1436 for (i=0; i<2; ++i) {
1437 bPC = !i ? bPC1 : bPC2;
1444 aC2Dx1=aIC.FirstCurve2d();
1448 aC2Dx1=aIC.SecondCurve2d();
1451 aFFWD.Orientation(TopAbs_FORWARD);
1454 if (aC2D.IsNull()) {
1455 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD, theContext);
1456 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1457 aOutFirst, aOutLast,
1458 aOutTol, theContext);
1461 if (aC3DE->IsPeriodic()) {
1462 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D,
1466 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D,
1470 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1471 //BRepLib::SameParameter(aE);
1473 BRepLib::SameParameter(aE);
1475 //=======================================================================
1476 // function: MakeEdge
1478 //=======================================================================
1479 void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1480 const TopoDS_Vertex& theV1,
1481 const Standard_Real theT1,
1482 const TopoDS_Vertex& theV2,
1483 const Standard_Real theT2,
1484 const Standard_Real theTolR3D,
1488 Standard_Real aNeedTol = theTolR3D + 1e-12;
1490 aBB.UpdateVertex(theV1, aNeedTol);
1491 aBB.UpdateVertex(theV2, aNeedTol);
1493 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2,
1496 aBB.UpdateEdge(theE, theTolR3D);
1498 //=======================================================================
1499 // function: ComputeVV
1501 //=======================================================================
1502 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1504 const Standard_Real aTolP2)
1506 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1509 aTolV1=BRep_Tool::Tolerance(aV1);
1511 aTolSum = aTolV1 + aTolP2 + Precision::Confusion();
1512 aTolSum2=aTolSum*aTolSum;
1514 aP1=BRep_Tool::Pnt(aV1);
1516 aD2=aP1.SquareDistance(aP2);
1522 //=======================================================================
1523 // function: ComputeVV
1525 //=======================================================================
1526 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1527 const TopoDS_Vertex& aV2,
1528 const Standard_Real aFuzz)
1530 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1532 Standard_Real aFuzz1 = (aFuzz > Precision::Confusion() ? aFuzz : Precision::Confusion());
1534 aTolV1=BRep_Tool::Tolerance(aV1);
1535 aTolV2=BRep_Tool::Tolerance(aV2);
1536 aTolSum=aTolV1+aTolV2+aFuzz1;
1537 aTolSum2=aTolSum*aTolSum;
1539 aP1=BRep_Tool::Pnt(aV1);
1540 aP2=BRep_Tool::Pnt(aV2);
1542 aD2=aP1.SquareDistance(aP2);
1548 //=======================================================================
1549 // function: MakeVertex
1551 //=======================================================================
1552 void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
1553 TopoDS_Vertex& aVnew)
1555 Standard_Integer aNb = aLV.Extent();
1557 aVnew=*((TopoDS_Vertex*)(&aLV.First()));
1560 Standard_Real aNTol;
1562 BRepLib::BoundingVertex(aLV, aNC, aNTol);
1564 aBB.MakeVertex(aVnew, aNC, aNTol);
1567 //=======================================================================
1568 //function : GetEdgeOnFace
1570 //=======================================================================
1571 Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
1572 (const TopoDS_Edge& theE1,
1573 const TopoDS_Face& theF2,
1576 Standard_Boolean bFound;
1577 TopoDS_Iterator aItF, aItW;
1579 bFound=Standard_False;
1581 aItF.Initialize(theF2);
1582 for (; aItF.More(); aItF.Next()) {
1583 const TopoDS_Shape& aW=aItF.Value();
1584 aItW.Initialize(aW);
1585 for (; aItW.More(); aItW.Next()) {
1586 const TopoDS_Shape& aE=aItW.Value();
1587 if (aE.IsSame(theE1)) {
1588 theE2=(*(TopoDS_Edge*)(&aE));
1596 //=======================================================================
1597 //function : FindFacePairs
1599 //=======================================================================
1600 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1601 const BOPCol_ListOfShape& thLF,
1602 BOPTools_ListOfCoupleOfShape& theLCFF,
1603 Handle(IntTools_Context)& theContext)
1605 Standard_Boolean bFound;
1606 Standard_Integer i, aNbCEF;
1607 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
1608 BOPCol_MapOfShape aMFP;
1609 TopoDS_Face aF1, aF2;
1610 TopoDS_Edge aEL, aE1;
1611 BOPCol_ListIteratorOfListOfShape aItLF;
1612 BOPTools_CoupleOfShape aCEF, aCFF;
1613 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1614 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1616 bFound=Standard_True;
1619 aItLF.Initialize(thLF);
1620 for (; aItLF.More(); aItLF.Next()) {
1621 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1623 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1625 return bFound; // it can not be so
1628 aCEF.SetShape1(aEL);
1629 aCEF.SetShape2(aFL);
1633 aNbCEF=aLCEF.Extent();
1638 aIt.Initialize(aLCEF);
1639 for (i=0; aIt.More(); aIt.Next(), ++i) {
1640 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1641 const TopoDS_Shape& aEx=aCSx.Shape1();
1642 const TopoDS_Shape& aFx=aCSx.Shape2();
1644 aOr=aEx.Orientation();
1647 aOrC=TopAbs::Reverse(aOr);
1648 aE1=(*(TopoDS_Edge*)(&aEx));
1649 aF1=(*(TopoDS_Face*)(&aFx));
1655 aLCEFx.Append(aCSx);
1661 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1663 aCFF.SetShape1(aF1);
1664 aCFF.SetShape2(aF2);
1665 theLCFF.Append(aCFF);
1674 aIt.Initialize(aLCEFx);
1675 for (; aIt.More(); aIt.Next()) {
1676 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1677 const TopoDS_Shape& aFx=aCSx.Shape2();
1678 if (!aMFP.Contains(aFx)) {
1683 aNbCEF=aLCEF.Extent();
1688 //=======================================================================
1689 //function : AngleWithRef
1691 //=======================================================================
1692 Standard_Real AngleWithRef(const gp_Dir& theD1,
1693 const gp_Dir& theD2,
1694 const gp_Dir& theDRef)
1696 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1701 const gp_XYZ& aXYZ1=theD1.XYZ();
1702 const gp_XYZ& aXYZ2=theD2.XYZ();
1703 aXYZ=aXYZ1.Crossed(aXYZ2);
1704 aSinus=aXYZ.Modulus();
1705 aCosinus=theD1*theD2;
1709 aBeta=aHalfPI*(1.-aCosinus);
1712 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1715 aScPr=aXYZ.Dot(theDRef.XYZ());
1721 //=======================================================================
1722 // function: IsBlockInOnFace
1724 //=======================================================================
1725 Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
1726 (const IntTools_Range& aShrR,
1727 const TopoDS_Face& aF,
1728 const TopoDS_Edge& aE1,
1729 Handle(IntTools_Context)& aContext)
1731 Standard_Boolean bFlag;
1732 Standard_Real f1, l1, ULD, VLD;
1736 aShrR.Range(f1, l1);
1737 Standard_Real dt=0.0075, k;//dt=0.001, k;
1743 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1745 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1746 aProjector.Perform(aP11);
1748 bFlag=aProjector.IsDone();
1753 aProjector.LowerDistanceParameters(ULD, VLD);
1754 aP2D.SetCoord(ULD, VLD);
1756 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1763 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1765 aProjector.Perform(aP12);
1767 bFlag=aProjector.IsDone();
1772 aProjector.LowerDistanceParameters(ULD, VLD);
1773 aP2D.SetCoord(ULD, VLD);
1775 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1781 // Treatment intemediate
1782 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1783 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1784 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1786 aProjector.Perform(aP12);
1788 bFlag=aProjector.IsDone();
1793 aTolE=BRep_Tool::Tolerance(aE1);
1794 aTolF=BRep_Tool::Tolerance(aF);
1796 aDist=aProjector.LowerDistance();
1798 return Standard_False;
1801 aProjector.LowerDistanceParameters(ULD, VLD);
1802 aP2D.SetCoord(ULD, VLD);
1804 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1812 //=======================================================================
1813 //function : IsMicroEdge
1815 //=======================================================================
1816 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
1817 (const TopoDS_Edge& aE,
1818 const Handle(IntTools_Context)& aCtx,
1819 const Standard_Boolean bCheckSplittable)
1821 Standard_Boolean bRet;
1822 Standard_Real aT1, aT2, aTmp;
1823 Handle(Geom_Curve) aC3D;
1824 TopoDS_Vertex aV1, aV2;
1826 bRet=(BRep_Tool::Degenerated(aE) ||
1827 !BRep_Tool::IsGeometric(aE));
1832 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1833 TopExp::Vertices(aE, aV1, aV2);
1834 aT1=BRep_Tool::Parameter(aV1, aE);
1835 aT2=BRep_Tool::Parameter(aV2, aE);
1842 IntTools_ShrunkRange aSR;
1843 aSR.SetContext(aCtx);
1844 aSR.SetData(aE, aT1, aT2, aV1, aV2);
1846 bRet = !aSR.IsDone();
1847 if (!bRet && bCheckSplittable) {
1848 bRet = !aSR.IsSplittable();
1854 //=======================================================================
1855 //function : GetFaceDir
1856 //purpose : Get binormal direction for the face in the point aP
1857 //=======================================================================
1858 Standard_Boolean GetFaceDir(const TopoDS_Edge& aE,
1859 const TopoDS_Face& aF,
1861 const Standard_Real aT,
1862 const gp_Dir& aDTgt,
1863 const Standard_Boolean theSmallFaces,
1866 Handle(IntTools_Context)& theContext,
1867 GeomAPI_ProjectPointOnSurf& aProjPL,
1868 const Standard_Real aDt)
1870 Standard_Real aTolE;
1873 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN, theContext);
1874 if (aF.Orientation()==TopAbs_REVERSED){
1878 aTolE=BRep_Tool::Tolerance(aE);
1881 // do not try to look for the point in the small face by intersecting
1882 // it with the circle because, most likely, the intersection point will
1883 // be out of the face
1884 Standard_Boolean bFound = !theSmallFaces &&
1885 FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt, aTolE);
1887 // if the first method did not succeed, try to use hatcher to find the point
1888 bFound = BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
1889 (aE, aF, aT, aDt, aPx, aDN, theContext);
1890 aProjPL.Perform(aPx);
1891 aPx = aProjPL.NearestPoint();
1892 gp_Vec aVec(aP, aPx);
1893 aDB.SetXYZ(aVec.XYZ());
1898 //=======================================================================
1899 //function : FindPointInFace
1900 //purpose : Find a point in the face in direction of <aDB>.
1901 // To get this point the method intersects the circle with radius
1902 // <aDt> built in point <aP> with normal perpendicular to <aDB>.
1903 //=======================================================================
1904 Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
1908 Handle(IntTools_Context)& theContext,
1909 GeomAPI_ProjectPointOnSurf& aProjPL,
1910 const Standard_Real aDt,
1911 const Standard_Real aTolE)
1913 Standard_Integer aNbItMax;
1914 Standard_Real aDist, aDTol, aPM, anEps;
1915 Standard_Boolean bRet;
1918 aDTol = Precision::Angular();
1919 aPM = aP.XYZ().Modulus();
1921 aDTol = 5.e-16 * aPM;
1923 bRet = Standard_False;
1925 anEps = Precision::SquareConfusion();
1927 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1931 if (!aProj.IsDone()) {
1934 aPS=aProj.NearestPoint();
1935 aProjPL.Perform(aPS);
1936 aPS=aProjPL.NearestPoint();
1938 aPS.SetXYZ(aPS.XYZ()+2.*aTolE*aDB.XYZ());
1940 if (!aProj.IsDone()) {
1943 aPS=aProj.NearestPoint();
1944 aProjPL.Perform(aPS);
1945 aPS=aProjPL.NearestPoint();
1948 aP1.SetXYZ(aPS.XYZ()+aDt*aDB.XYZ());
1951 if (!aProj.IsDone()) {
1954 aPOut = aProj.NearestPoint();
1955 aDist = aProj.LowerDistance();
1957 aProjPL.Perform(aPOut);
1958 aPOut = aProjPL.NearestPoint();
1960 gp_Vec aV(aPS, aPOut);
1961 if (aV.SquareMagnitude() < anEps) {
1964 aDB.SetXYZ(aV.XYZ());
1965 } while (aDist > aDTol && --aNbItMax);
1967 bRet = aDist < aDTol;
1970 //=======================================================================
1971 //function : MinStep3D
1973 //=======================================================================
1974 Standard_Real MinStep3D(const TopoDS_Edge& theE1,
1975 const TopoDS_Face& theF1,
1976 const BOPTools_ListOfCoupleOfShape& theLCS,
1978 Handle(IntTools_Context)& theContext,
1979 Standard_Boolean& theSmallFaces)
1981 Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin;
1983 // add the current pair of edge/face for checking as well
1984 BOPTools_CoupleOfShape aCS1;
1985 aCS1.SetShape1(theE1);
1986 aCS1.SetShape2(theF1);
1988 BOPTools_ListOfCoupleOfShape aLCS = theLCS;
1991 aTolE = BRep_Tool::Tolerance(theE1);
1995 BOPTools_ListIteratorOfListOfCoupleOfShape aIt(aLCS);
1996 for (; aIt.More(); aIt.Next()) {
1997 const BOPTools_CoupleOfShape& aCS = aIt.Value();
1998 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2()));
2000 aTolF = BRep_Tool::Tolerance(aF);
2001 aDt = 2*(aTolE + aTolF);
2006 // try to compute the minimal 3D step
2007 const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(aF);
2008 Standard_Real aR = 0.;
2009 GeomAbs_SurfaceType aSType = aBAS.GetType();
2011 case GeomAbs_Cylinder: {
2012 aR = aBAS.Cylinder().Radius();
2015 case GeomAbs_Cone: {
2016 gp_Lin aL(aBAS.Cone().Axis());
2017 aR = aL.Distance(aP);
2020 case GeomAbs_Sphere: {
2021 aDtMin = Max(aDtMin, 5.e-4);
2022 aR = aBAS.Sphere().Radius();
2025 case GeomAbs_Torus: {
2026 aR = aBAS.Torus().MajorRadius();
2030 aDtMin = Max(aDtMin, 5.e-4);
2035 Standard_Real d = 10*Precision::PConfusion();
2036 aDtMin = Max(aDtMin, sqrt(d*d + 2*d*aR));
2040 if (aDtMax < aDtMin) {
2044 // check if the computed 3D step is too big for any of the faces in the list
2045 aIt.Initialize(aLCS);
2046 for (; aIt.More(); aIt.Next()) {
2047 const BOPTools_CoupleOfShape& aCS = aIt.Value();
2048 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2()));
2050 const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(aF);
2052 Standard_Real aUMin, aUMax, aVMin, aVMax;
2053 theContext->UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
2055 Standard_Real aDU = aUMax - aUMin;
2057 Standard_Real aURes = aBAS.UResolution(aDtMax);
2058 if (2*aURes > aDU) {
2063 Standard_Real aDV = aVMax - aVMin;
2065 Standard_Real aVRes = aBAS.VResolution(aDtMax);
2066 if (2*aVRes > aDV) {
2072 theSmallFaces = aIt.More();
2076 //=======================================================================
2077 //function : IsOpenShell
2079 //=======================================================================
2080 Standard_Boolean BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
2082 Standard_Boolean bRet;
2083 Standard_Integer i, aNbE, aNbF;
2084 TopAbs_Orientation aOrF;
2085 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
2086 BOPCol_ListIteratorOfListOfShape aItLS;
2088 bRet=Standard_False;
2090 BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF);
2093 for (i=1; i<=aNbE; ++i) {
2094 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i));
2095 if (BRep_Tool::Degenerated(aE)) {
2100 const BOPCol_ListOfShape& aLF=aMEF(i);
2101 aItLS.Initialize(aLF);
2102 for (; aItLS.More(); aItLS.Next()) {
2103 const TopoDS_Shape& aF=aItLS.Value();
2104 aOrF=aF.Orientation();
2105 if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
2119 //=======================================================================
2120 //function : IsInvertedSolid
2122 //=======================================================================
2123 Standard_Boolean BOPTools_AlgoTools::IsInvertedSolid
2124 (const TopoDS_Solid& aSolid)
2126 Standard_Real aTolS;
2127 TopAbs_State aState;
2128 BRepClass3d_SolidClassifier aSC(aSolid);
2131 aSC.PerformInfinitePoint(aTolS);
2133 return (aState==TopAbs_IN);