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
10 // under the terms of the GNU Lesser General Public version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <BOPTools_AlgoTools.ixx>
20 #include <Precision.hxx>
24 #include <gp_Pnt2d.hxx>
25 #include <gp_Cylinder.hxx>
26 #include <gp_Cone.hxx>
27 #include <gp_Sphere.hxx>
28 #include <gp_Torus.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom_Surface.hxx>
33 #include <Geom_Plane.hxx>
34 #include <Geom_TrimmedCurve.hxx>
35 #include <Geom_Curve.hxx>
36 #include <GeomAPI_ProjectPointOnSurf.hxx>
37 #include <Geom2dInt_Geom2dCurveTool.hxx>
39 #include <TopAbs_Orientation.hxx>
41 #include <TopoDS_Compound.hxx>
42 #include <TopoDS_CompSolid.hxx>
43 #include <TopoDS_Solid.hxx>
44 #include <TopoDS_Shell.hxx>
45 #include <TopoDS_Wire.hxx>
47 #include <BRep_Builder.hxx>
48 #include <BRep_Tool.hxx>
49 #include <BRepLib.hxx>
50 #include <BRepAdaptor_Curve2d.hxx>
51 #include <BRepAdaptor_Surface.hxx>
52 #include <BRepClass3d_SolidClassifier.hxx>
54 #include <TopExp_Explorer.hxx>
56 #include <IntTools_Tools.hxx>
58 #include <BOPTools.hxx>
59 #include <BOPTools_CoupleOfShape.hxx>
60 #include <BOPTools_ListOfCoupleOfShape.hxx>
61 #include <BOPTools_AlgoTools2D.hxx>
62 #include <BOPTools_AlgoTools3D.hxx>
64 #include <BOPCol_IndexedMapOfShape.hxx>
65 #include <BOPCol_MapOfShape.hxx>
67 #include <BOPInt_ShrunkRange.hxx>
71 Standard_Real AngleWithRef(const gp_Dir& theD1,
73 const gp_Dir& theDRef);
76 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
77 const BOPCol_ListOfShape& thLF,
78 BOPTools_ListOfCoupleOfShape& theLCFF,
79 Handle(BOPInt_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(BOPInt_Context)& theContext,
93 GeomAPI_ProjectPointOnSurf& aProjPL);
95 Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
96 const TopoDS_Face& aF,
100 Handle(BOPInt_Context)& theContext,
101 GeomAPI_ProjectPointOnSurf& aProjPL);
103 //=======================================================================
104 // function: MakeConnexityBlocks
106 //=======================================================================
107 void BOPTools_AlgoTools::MakeConnexityBlocks (const TopoDS_Shape& theS,
108 const TopAbs_ShapeEnum theType1,
109 const TopAbs_ShapeEnum theType2,
110 BOPCol_ListOfShape& theLCB)
112 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
116 TopExp_Explorer aExp;
117 BOPCol_MapOfShape aMP;
118 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
119 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
120 BOPCol_ListIteratorOfListOfShape aItLF;
123 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
126 aIt.Initialize(theS);
127 for (; aIt.More(); aIt.Next()) {
128 const TopoDS_Shape& aF1=aIt.Value();
129 if (aMP.Contains(aF1)) {
140 aNbAdd = aMAdd.Extent();
141 for (i=1; i<=aNbAdd; ++i) {
142 const TopoDS_Shape& aF=aMAdd(i);
144 aExp.Init(aF, theType1);
145 for (; aExp.More(); aExp.Next()) {
146 const TopoDS_Shape& aE=aExp.Current();
148 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
149 aItLF.Initialize(aLF);
150 for (; aItLF.More(); aItLF.Next()) {
151 const TopoDS_Shape& aFx=aItLF.Value();
152 if (aFx.IsSame(aF)) {
155 if (aMCB.Contains(aFx)) {
160 }//for (; aExp.More(); aExp.Next()){
162 }// for (i=1; i<=aNbAdd; ++i) {
164 aNbAdd1=aMAdd1.Extent();
166 break;// ->make new CB from aMCB
170 for (i=1; i<=aNbAdd1; ++i) {
171 const TopoDS_Shape& aFAdd = aMAdd1(i);
178 aBB.MakeCompound(aC);
180 for (i=1; i<=aNbF; ++i) {
181 const TopoDS_Shape& aF=aMCB(i);
187 }// for (; aIt.More(); aIt.Next())
189 //=======================================================================
190 // function: OrientFacesOnShell
192 //=======================================================================
193 void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
195 Standard_Boolean bIsProcessed1, bIsProcessed2;
196 Standard_Integer i, aNbE, aNbF, j;
197 TopAbs_Orientation anOrE1, anOrE2;
198 TopoDS_Face aF1x, aF2x;
199 TopoDS_Shape aShellNew;
200 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
201 BOPCol_IndexedMapOfShape aProcessedFaces;
204 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
206 BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aEFMap);
207 aNbE=aEFMap.Extent();
209 // One seam edge in aEFMap contains 2 equivalent faces.
210 for (i=1; i<=aNbE; ++i) {
211 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
214 BOPCol_ListOfShape aLFTmp;
215 BOPCol_IndexedMapOfShape aFM;
217 BOPCol_ListIteratorOfListOfShape anIt(aLF);
218 for (; anIt.More(); anIt.Next()) {
219 const TopoDS_Shape& aF=anIt.Value();
220 if (!aFM.Contains(aF)) {
231 for (i=1; i<=aNbE; ++i) {
232 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
233 if (BRep_Tool::Degenerated(aE)) {
237 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
243 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
244 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
246 bIsProcessed1=aProcessedFaces.Contains(aF1);
247 bIsProcessed2=aProcessedFaces.Contains(aF2);
248 if (bIsProcessed1 && bIsProcessed2) {
252 if (!bIsProcessed1 && !bIsProcessed2) {
253 aProcessedFaces.Add(aF1);
254 aBB.Add(aShellNew, aF1);
255 bIsProcessed1=!bIsProcessed1;
260 j=aProcessedFaces.FindIndex(aF1);
261 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
266 j=aProcessedFaces.FindIndex(aF2);
267 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
270 anOrE1=Orientation(aE, aF1x);
271 anOrE2=Orientation(aE, aF2x);
273 if (bIsProcessed1 && !bIsProcessed2) {
274 if (anOrE1==anOrE2) {
275 if (!BRep_Tool::IsClosed(aE, aF1) &&
276 !BRep_Tool::IsClosed(aE, aF2)) {
280 aProcessedFaces.Add(aF2);
281 aBB.Add(aShellNew, aF2);
283 else if (!bIsProcessed1 && bIsProcessed2) {
284 if (anOrE1==anOrE2) {
285 if (!BRep_Tool::IsClosed(aE, aF1) &&
286 !BRep_Tool::IsClosed(aE, aF2)) {
290 aProcessedFaces.Add(aF1);
291 aBB.Add(aShellNew, aF1);
296 for (i=1; i<=aNbE; ++i) {
297 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
298 if (BRep_Tool::Degenerated(aE)) {
302 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
305 BOPCol_ListIteratorOfListOfShape anIt(aLF);
306 for(; anIt.More(); anIt.Next()) {
307 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
308 if (!aProcessedFaces.Contains(aF)) {
309 aProcessedFaces.Add(aF);
310 aBB.Add(aShellNew, aF);
317 //=======================================================================
318 //function : Orientation
320 //=======================================================================
321 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
322 const TopoDS_Face& aF)
324 TopAbs_Orientation anOr=TopAbs_INTERNAL;
326 TopExp_Explorer anExp;
327 anExp.Init(aF, TopAbs_EDGE);
328 for (; anExp.More(); anExp.Next()) {
329 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
330 if (anEF1.IsSame(anE)) {
331 anOr=anEF1.Orientation();
341 //=======================================================================
342 // function: MakeConnexityBlock.
344 //=======================================================================
345 void BOPTools_AlgoTools::MakeConnexityBlock (BOPCol_ListOfShape& theLFIn,
346 BOPCol_IndexedMapOfShape& theMEAvoid,
347 BOPCol_ListOfShape& theLCB,
348 const Handle(NCollection_BaseAllocator)& theAllocator)
350 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
351 TopExp_Explorer aExp;
352 BOPCol_ListIteratorOfListOfShape aIt;
354 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
355 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
356 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
357 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
360 aNbF=theLFIn.Extent();
361 aIt.Initialize(theLFIn);
362 for (; aIt.More(); aIt.Next()) {
363 const TopoDS_Shape& aF=aIt.Value();
364 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
368 const TopoDS_Shape& aF1=theLFIn.First();
373 aNbAdd = aMAdd.Extent();
374 for (i=1; i<=aNbAdd; ++i) {
375 const TopoDS_Shape& aF=aMAdd(i);
378 aExp.Init(aF, TopAbs_EDGE);
379 for (; aExp.More(); aExp.Next()) {
380 const TopoDS_Shape& aE=aExp.Current();
381 if (theMEAvoid.Contains(aE)){
385 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
387 for (; aIt.More(); aIt.Next()) {
388 const TopoDS_Shape& aFx=aIt.Value();
389 if (aFx.IsSame(aF)) {
392 if (aMCB.Contains(aFx)) {
397 }//for (; aExp.More(); aExp.Next()){
399 }// for (i=1; i<=aNbAdd; ++i) {
401 aNbAdd1=aMAdd1.Extent();
407 for (i=1; i<=aNbAdd1; ++i) {
408 const TopoDS_Shape& aFAdd=aMAdd1(i);
416 for (i=1; i<=aNbF; ++i) {
417 const TopoDS_Shape& aF=aMCB(i);
421 //=======================================================================
422 // function: ComputeStateByOnePoint
424 //=======================================================================
425 TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint(const TopoDS_Shape& theS,
426 const TopoDS_Solid& theRef,
427 const Standard_Real theTol,
428 Handle(BOPInt_Context)& theContext)
431 TopAbs_ShapeEnum aType;
433 aState=TopAbs_UNKNOWN;
434 aType=theS.ShapeType();
435 if (aType==TopAbs_VERTEX) {
436 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
437 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
439 else if (aType==TopAbs_EDGE) {
440 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
441 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
446 //=======================================================================
447 // function: ComputeState
449 //=======================================================================
450 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
451 const TopoDS_Solid& theRef,
452 const Standard_Real theTol,
453 BOPCol_IndexedMapOfShape& theBounds,
454 Handle(BOPInt_Context)& theContext)
457 TopExp_Explorer aExp;
462 aState=TopAbs_UNKNOWN;
464 aExp.Init(theF, TopAbs_EDGE);
465 for (; aExp.More(); aExp.Next()) {
466 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
467 if (BRep_Tool::Degenerated(aSE)) {
471 if (!theBounds.Contains(aSE)) {
472 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
473 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
477 aE1=(*(TopoDS_Edge*)(&aSE));
480 // !!<- process edges that are all on theRef
482 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, aP2D, aP3D, theContext);
483 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
488 //=======================================================================
489 // function: ComputeState
491 //=======================================================================
492 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Vertex& theV,
493 const TopoDS_Solid& theRef,
494 const Standard_Real theTol,
495 Handle(BOPInt_Context)& theContext)
500 aP3D=BRep_Tool::Pnt(theV);
501 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
504 //=======================================================================
505 // function: ComputeState
507 //=======================================================================
508 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE,
509 const TopoDS_Solid& theRef,
510 const Standard_Real theTol,
511 Handle(BOPInt_Context)& theContext)
513 Standard_Real aT1, aT2, aT = 0.;
515 Handle(Geom_Curve) aC3D;
518 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
521 //it means that we are in degenerated edge
522 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
524 return TopAbs_UNKNOWN;
526 aP3D=BRep_Tool::Pnt(aV);
529 Standard_Boolean bF2Inf, bL2Inf;
530 Standard_Real dT=10.;
532 bF2Inf = Precision::IsNegativeInfinite(aT1);
533 bL2Inf = Precision::IsPositiveInfinite(aT2);
535 if (bF2Inf && !bL2Inf) {
538 else if (!bF2Inf && bL2Inf) {
541 else if (bF2Inf && bL2Inf) {
545 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
550 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
554 //=======================================================================
555 // function: ComputeState
557 //=======================================================================
558 TopAbs_State BOPTools_AlgoTools::ComputeState(const gp_Pnt& theP,
559 const TopoDS_Solid& theRef,
560 const Standard_Real theTol,
561 Handle(BOPInt_Context)& theContext)
565 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
566 aSC.Perform(theP, theTol);
572 //=======================================================================
573 //function : IsInternalFace
575 //=======================================================================
576 Standard_Integer BOPTools_AlgoTools::IsInternalFace
577 (const TopoDS_Face& theFace,
578 const TopoDS_Solid& theSolid,
579 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
580 const Standard_Real theTol,
581 Handle(BOPInt_Context)& theContext)
583 Standard_Boolean bDegenerated;
584 Standard_Integer aNbF, iRet, iFound;
585 TopAbs_Orientation aOr;
587 TopExp_Explorer aExp;
588 BOPCol_ListIteratorOfListOfShape aItF;
590 // For all invoked functions: [::IsInternalFace(...)]
591 // the returned value iRet means:
592 // iRet=0; - state is not IN
593 // iRet=1; - state is IN
594 // iRet=2; - state can not be found by the method of angles
596 // For this function the returned value iRet means:
597 // iRet=0; - state is not IN
598 // iRet=1; - state is IN
601 // 1 Try to find an edge from theFace in theMEF
603 aExp.Init(theFace, TopAbs_EDGE);
604 for(; aExp.More(); aExp.Next()) {
605 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
606 if (!theMEF.Contains(aE)) {
612 aOr=aE.Orientation();
613 if (aOr==TopAbs_INTERNAL) {
616 bDegenerated=BRep_Tool::Degenerated(aE);
621 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
624 return iRet; // it can not be so
628 // aE is internal edge on aLF.First()
629 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
630 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
631 if (aE1.Orientation()!=TopAbs_INTERNAL) {
636 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1, theContext);
641 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
642 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
644 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
645 // treat as it was for 1 face
646 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2, theContext);
653 return iRet; // it can not be so
655 else { // aNbF=2,4,6,8,...
656 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, theContext);
659 }//for(; aExp.More(); aExp.Next()) {
662 // the face has no shared edges with the solid
670 //========================================
671 // 2. Classify face using classifier
674 BOPCol_IndexedMapOfShape aBounds;
676 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
678 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid, theTol, aBounds, theContext);
680 iRet=(aState==TopAbs_IN)? 1 : 0;
684 //=======================================================================
685 //function : IsInternalFace
687 //=======================================================================
688 Standard_Integer BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace,
689 const TopoDS_Edge& theEdge,
690 BOPCol_ListOfShape& theLF,
691 Handle(BOPInt_Context)& theContext)
693 Standard_Integer aNbF, iRet;
699 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
700 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
701 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
706 BOPTools_ListOfCoupleOfShape aLCFF;
707 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
709 FindFacePairs(theEdge, theLF, aLCFF, theContext);
711 aIt.Initialize(aLCFF);
712 for (; aIt.More(); aIt.Next()) {
713 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
715 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
716 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
717 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
725 //=======================================================================
726 //function : IsInternalFace
728 //=======================================================================
729 Standard_Integer BOPTools_AlgoTools::IsInternalFace
730 (const TopoDS_Face& theFace,
731 const TopoDS_Edge& theEdge,
732 const TopoDS_Face& theFace1,
733 const TopoDS_Face& theFace2,
734 Handle(BOPInt_Context)& theContext)
736 Standard_Boolean bRet;
737 Standard_Integer iRet;
738 TopoDS_Edge aE1, aE2;
740 BOPTools_ListOfCoupleOfShape theLCSOff;
741 BOPTools_CoupleOfShape aCS1, aCS2;
743 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
744 if (aE1.Orientation()==TopAbs_INTERNAL) {
746 aE1.Orientation(TopAbs_FORWARD);
747 aE2.Orientation(TopAbs_REVERSED);
749 else if (theFace1==theFace2) {
751 aE1.Orientation(TopAbs_FORWARD);
752 aE2.Orientation(TopAbs_REVERSED);
755 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
758 aCS1.SetShape1(theEdge);
759 aCS1.SetShape2(theFace);
760 theLCSOff.Append(aCS1);
763 aCS2.SetShape2(theFace2);
764 theLCSOff.Append(aCS2);
766 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
768 iRet=0; // theFace is not internal
769 if (theFace.IsEqual(aFOff)) {
770 // theFace is internal
773 // theFace seems to be internal
779 //=======================================================================
780 //function : GetFaceOff
782 //=======================================================================
783 Standard_Boolean BOPTools_AlgoTools::GetFaceOff
784 (const TopoDS_Edge& theE1,
785 const TopoDS_Face& theF1,
786 BOPTools_ListOfCoupleOfShape& theLCSOff,
787 TopoDS_Face& theFOff,
788 Handle(BOPInt_Context)& theContext)
790 Standard_Boolean bRet;
791 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
792 Standard_Real aUmin, aUsup, aVmin, aVsup;
793 gp_Pnt aPn1, aPn2, aPx;
794 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
796 TopAbs_Orientation aOr;
797 Handle(Geom_Curve)aC3D;
798 Handle(Geom_Plane) aPL;
799 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
800 GeomAPI_ProjectPointOnSurf aProjPL;
804 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
805 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
808 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
809 gp_Dir aDTgt(aVTgt), aDTgt2;
810 aOr = theE1.Orientation();
812 aPL = new Geom_Plane(aPx, aDTgt);
813 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
814 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
816 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext, aProjPL);
821 aIt.Initialize(theLCSOff);
822 for (; aIt.More(); aIt.Next()) {
823 const BOPTools_CoupleOfShape& aCS=aIt.Value();
824 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
825 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
827 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
828 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext, aProjPL);
830 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
833 aAngle=aTwoPI+aAngle;
836 if (aAngle<Precision::Angular()) {
840 else if (aF2.IsSame(theF1)) {
845 if (aAngle<aAngleMin){
849 else if (aAngle==aAngleMin) {
850 // the minimal angle can not be found
856 //=======================================================================
857 //function : GetEdgeOff
859 //=======================================================================
860 Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
861 const TopoDS_Face& theF2,
864 Standard_Boolean bFound;
865 TopAbs_Orientation aOr1, aOr1C, aOr2;
866 TopExp_Explorer anExp;
868 bFound=Standard_False;
869 aOr1=theE1.Orientation();
870 aOr1C=TopAbs::Reverse(aOr1);
872 anExp.Init(theF2, TopAbs_EDGE);
873 for (; anExp.More(); anExp.Next()) {
874 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
875 if (aEF2.IsSame(theE1)) {
876 aOr2=aEF2.Orientation();
887 //=======================================================================
888 //function : AreFacesSameDomain
890 //=======================================================================
891 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1,
892 const TopoDS_Face& theF2,
893 Handle(BOPInt_Context)& theContext)
895 Standard_Boolean bFlag;
896 Standard_Integer iErr;
897 Standard_Real aTolF1, aTolF2, aTol;
900 TopoDS_Face aF1, aF2;
902 TopExp_Explorer aExp;
904 bFlag=Standard_False;
907 aF1.Orientation(TopAbs_FORWARD);
909 aF2.Orientation(TopAbs_FORWARD);
911 aTolF1=BRep_Tool::Tolerance(aF1);
913 aExp.Init(aF1, TopAbs_EDGE);
914 for (; aExp.More(); aExp.Next()) {
915 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
916 if (!BRep_Tool::Degenerated(aE1)) {
917 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
918 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
922 aTolF2=BRep_Tool::Tolerance(aF2);
925 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D, theContext);
927 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
933 //=======================================================================
934 //function : CheckSameGeom
936 //=======================================================================
937 Standard_Boolean BOPTools_AlgoTools::CheckSameGeom(const TopoDS_Face& theF1,
938 const TopoDS_Face& theF2,
939 Handle(BOPInt_Context)& theContext)
941 Standard_Boolean bRet;
942 Standard_Real aTolF1, aTolF2, aTol;
945 TopExp_Explorer aExp;
948 aExp.Init(theF1, TopAbs_EDGE);
949 for (; aExp.More(); aExp.Next()) {
950 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
951 if (!BRep_Tool::Degenerated(aE)) {
952 aTolF1=BRep_Tool::Tolerance(theF1);
953 aTolF2=BRep_Tool::Tolerance(theF2);
955 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
956 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
962 //=======================================================================
965 //=======================================================================
966 Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
967 const TopoDS_Face& theF2)
969 Standard_Integer iSense=0;
971 TopoDS_Edge aE1, aE2;
972 TopExp_Explorer aExp;
974 aExp.Init(theF1, TopAbs_EDGE);
975 for (; aExp.More(); aExp.Next()) {
976 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
977 if (!BRep_Tool::Degenerated(aE1)) {
978 if (!BRep_Tool::IsClosed(aE1, theF1)) {
984 aExp.Init(theF2, TopAbs_EDGE);
985 for (; aExp.More(); aExp.Next()) {
986 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
987 if (!BRep_Tool::Degenerated(aE2)) {
988 if (!BRep_Tool::IsClosed(aE2, theF2)) {
989 if (aE2.IsSame(aE1)) {
1001 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
1002 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
1004 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1008 //=======================================================================
1009 // function: IsSplitToReverse
1011 //=======================================================================
1012 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Shape& theSp,
1013 const TopoDS_Shape& theSr,
1014 Handle(BOPInt_Context)& theContext)
1016 Standard_Boolean bRet;
1017 TopAbs_ShapeEnum aType;
1019 bRet=Standard_False;
1021 aType=theSp.ShapeType();
1024 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1025 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1026 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1031 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1032 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1033 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1042 //=======================================================================
1043 //function :IsSplitToReverse
1045 //=======================================================================
1046 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
1047 const TopoDS_Face& theFSr,
1048 Handle(BOPInt_Context)& theContext)
1050 Standard_Boolean bRet, bFound, bInFace;
1051 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1052 gp_Pnt aPFSp, aPFSr;
1055 Handle(Geom_Surface) aSr, aSp;
1056 TopAbs_Orientation aOrSr, aOrSp;
1057 TopExp_Explorer anExp;
1060 bRet=Standard_False;
1062 aSr=BRep_Tool::Surface(theFSr);
1063 aSp=BRep_Tool::Surface(theFSp);
1065 aOrSr=theFSr.Orientation();
1066 aOrSp=theFSp.Orientation();
1067 bRet=(aOrSr!=aOrSp);
1071 bFound=Standard_False;
1072 anExp.Init(theFSp, TopAbs_EDGE);
1073 for (; anExp.More(); anExp.Next()) {
1074 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1075 if (!BRep_Tool::Degenerated(aESp)) {
1076 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1083 Standard_Boolean bFlag;
1084 Standard_Integer iErr;
1087 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp, theContext);
1092 aP2DFSp.Coord(aU, aV);
1093 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1099 BRep_Tool::Range(aESp, aT1, aT2);
1100 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
1101 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp, theContext);
1104 // Parts of theContext->ComputeVS(..)
1105 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1106 aProjector.Perform(aPFSp);
1107 if (!aProjector.IsDone()) {
1111 aProjector.LowerDistanceParameters(aU, aV);
1112 gp_Pnt2d aP2D(aU, aV);
1113 bInFace=theContext->IsPointInFace (theFSr, aP2D);
1118 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1121 gp_Dir aDNFSr=aDD1U^aDD1V;
1122 if (theFSr.Orientation()==TopAbs_REVERSED){
1126 aScPr=aDNFSp*aDNFSr;
1131 //=======================================================================
1132 //function :IsSplitToReverse
1134 //=======================================================================
1135 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Edge& aEF1,
1136 const TopoDS_Edge& aEF2,
1137 Handle(BOPInt_Context)& theContext)
1139 Standard_Boolean bRet, bIsDegenerated;
1141 bRet=Standard_False;
1142 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1143 BRep_Tool::Degenerated(aEF2));
1144 if (bIsDegenerated) {
1149 TopAbs_Orientation aOrE, aOrSp;
1150 Handle(Geom_Curve)aC1, aC2;
1152 aC2=BRep_Tool::Curve(aEF2, a, b);
1153 aC1=BRep_Tool::Curve(aEF1, a, b);
1156 aOrE=aEF2.Orientation();
1157 aOrSp=aEF1.Orientation();
1162 Standard_Real aT1, aT2, aScPr;
1166 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1168 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1171 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1173 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1182 //=======================================================================
1185 //=======================================================================
1186 Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1187 const TopoDS_Shape& aFace)
1189 Standard_Boolean bIsHole;
1190 Standard_Integer i, aNbS;
1191 Standard_Real aT1, aT2, aS;
1192 Standard_Real aU1, aU2, aU, dU;
1193 Standard_Real aX1, aY1, aX0, aY0;
1194 TopAbs_Orientation aOr;
1196 gp_Pnt2d aP2D0, aP2D1;
1197 Handle(Geom2d_Curve) aC2D;
1198 TopoDS_Face aF, aFF;
1199 TopoDS_Iterator aItW;
1201 bIsHole=Standard_False;
1203 aF=(*(TopoDS_Face *)(&aFace));
1205 aFF.Orientation(TopAbs_FORWARD);
1208 aItW.Initialize(aW);
1209 for (; aItW.More(); aItW.Next()) {
1210 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1211 aOr=aE.Orientation();
1212 if (!(aOr==TopAbs_FORWARD ||
1213 aOr==TopAbs_REVERSED)) {
1217 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1218 if (aC2D.IsNull()) {
1222 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1223 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1228 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1232 if (aOr==TopAbs_REVERSED) {
1239 aC2D->D0(aU, aP2D0);
1240 for(i=2; i<=aNbS; i++) {
1242 aC2D->D0(aU, aP2D1);
1243 aP2D0.Coord(aX0, aY0);
1244 aP2D1.Coord(aX1, aY1);
1246 aS=aS+(aY0+aY1)*(aX1-aX0);
1250 }//for (; aItW.More(); aItW.Next()) {
1255 //=======================================================================
1256 // function: MakeContainer
1258 //=======================================================================
1259 void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1265 case TopAbs_COMPOUND:{
1267 aBB.MakeCompound(aC);
1272 case TopAbs_COMPSOLID:{
1273 TopoDS_CompSolid aCS;
1274 aBB.MakeCompSolid(aCS);
1280 TopoDS_Solid aSolid;
1281 aBB.MakeSolid(aSolid);
1288 TopoDS_Shell aShell;
1289 aBB.MakeShell(aShell);
1296 aBB.MakeWire(aWire);
1305 //=======================================================================
1306 // function: MakePCurve
1308 //=======================================================================
1309 void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1310 const TopoDS_Face& aF1,
1311 const TopoDS_Face& aF2,
1312 const IntTools_Curve& aIC,
1313 const Standard_Boolean bPC1,
1314 const Standard_Boolean bPC2)
1318 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1319 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1322 Standard_Boolean bPC;
1324 aTolE=BRep_Tool::Tolerance(aE);
1326 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
1327 Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aT1, aT2);
1329 for (i=0; i<2; ++i) {
1330 bPC = !i ? bPC1 : bPC2;
1337 aC2Dx1=aIC.FirstCurve2d();
1341 aC2Dx1=aIC.SecondCurve2d();
1344 aFFWD.Orientation(TopAbs_FORWARD);
1347 if (aC2D.IsNull()) {
1348 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1349 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1350 aOutFirst, aOutLast,
1354 if (aC3DE->IsPeriodic()) {
1355 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D, aC2DA);
1358 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA);
1361 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1362 //BRepLib::SameParameter(aE);
1364 BRepLib::SameParameter(aE);
1366 //=======================================================================
1367 // function: MakeEdge
1369 //=======================================================================
1370 void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1371 const TopoDS_Vertex& theV1,
1372 const Standard_Real theT1,
1373 const TopoDS_Vertex& theV2,
1374 const Standard_Real theT2,
1375 const Standard_Real theTolR3D,
1378 Standard_Real aTolV;
1381 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2, theE);
1383 aBB.UpdateEdge(theE, theTolR3D);
1385 aTolV=BRep_Tool::Tolerance(theV1);
1386 if (aTolV<theTolR3D) {
1387 aBB.UpdateVertex(theV1, theTolR3D);
1390 aTolV=BRep_Tool::Tolerance(theV2);
1391 if (aTolV<theTolR3D) {
1392 aBB.UpdateVertex(theV2, theTolR3D);
1395 //=======================================================================
1396 // function: ComputeVV
1398 //=======================================================================
1399 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1401 const Standard_Real aTolP2)
1403 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1406 aTolV1=BRep_Tool::Tolerance(aV1);
1408 aTolSum=aTolV1+aTolP2;
1409 aTolSum2=aTolSum*aTolSum;
1411 aP1=BRep_Tool::Pnt(aV1);
1413 aD2=aP1.SquareDistance(aP2);
1419 //=======================================================================
1420 // function: ComputeVV
1422 //=======================================================================
1423 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1424 const TopoDS_Vertex& aV2)
1426 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1429 aTolV1=BRep_Tool::Tolerance(aV1);
1430 aTolV2=BRep_Tool::Tolerance(aV2);
1431 aTolSum=aTolV1+aTolV2;
1432 aTolSum2=aTolSum*aTolSum;
1434 aP1=BRep_Tool::Pnt(aV1);
1435 aP2=BRep_Tool::Pnt(aV2);
1437 aD2=aP1.SquareDistance(aP2);
1443 //=======================================================================
1444 // function: MakeVertex
1446 //=======================================================================
1447 void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
1448 TopoDS_Vertex& aVnew)
1450 Standard_Integer aNb;
1451 Standard_Real aTi, aDi, aDmax;
1453 gp_XYZ aXYZ(0.,0.,0.), aXYZi;
1454 BOPCol_ListIteratorOfListOfShape aIt;
1458 aIt.Initialize(aLV);
1459 for (; aIt.More(); aIt.Next()) {
1460 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1461 aPi=BRep_Tool::Pnt(aVi);
1466 aXYZ.Divide((Standard_Real)aNb);
1470 aIt.Initialize(aLV);
1471 for (; aIt.More(); aIt.Next()) {
1472 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1473 aPi=BRep_Tool::Pnt(aVi);
1474 aTi=BRep_Tool::Tolerance(aVi);
1475 aDi=aP.SquareDistance(aPi);
1484 aBB.MakeVertex (aVnew, aP, aDmax);
1487 //=======================================================================
1488 //function : GetEdgeOnFace
1490 //=======================================================================
1491 Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace(const TopoDS_Edge& theE1,
1492 const TopoDS_Face& theF2,
1495 Standard_Boolean bFound;
1496 TopoDS_Iterator aItF, aItW;
1498 bFound=Standard_False;
1500 aItF.Initialize(theF2);
1501 for (; aItF.More(); aItF.Next()) {
1502 const TopoDS_Shape& aW=aItF.Value();
1503 aItW.Initialize(aW);
1504 for (; aItW.More(); aItW.Next()) {
1505 const TopoDS_Shape& aE=aItW.Value();
1506 if (aE.IsSame(theE1)) {
1507 theE2=(*(TopoDS_Edge*)(&aE));
1515 //=======================================================================
1516 //function : FindFacePairs
1518 //=======================================================================
1519 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1520 const BOPCol_ListOfShape& thLF,
1521 BOPTools_ListOfCoupleOfShape& theLCFF,
1522 Handle(BOPInt_Context)& theContext)
1524 Standard_Boolean bFound;
1525 Standard_Integer i, aNbCEF;
1526 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
1527 BOPCol_MapOfShape aMFP;
1528 TopoDS_Face aF1, aF2;
1529 TopoDS_Edge aEL, aE1;
1530 BOPCol_ListIteratorOfListOfShape aItLF;
1531 BOPTools_CoupleOfShape aCEF, aCFF;
1532 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1533 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1535 bFound=Standard_True;
1538 aItLF.Initialize(thLF);
1539 for (; aItLF.More(); aItLF.Next()) {
1540 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1542 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1544 return bFound; // it can not be so
1547 aCEF.SetShape1(aEL);
1548 aCEF.SetShape2(aFL);
1552 aNbCEF=aLCEF.Extent();
1557 aIt.Initialize(aLCEF);
1558 for (i=0; aIt.More(); aIt.Next(), ++i) {
1559 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1560 const TopoDS_Shape& aEx=aCSx.Shape1();
1561 const TopoDS_Shape& aFx=aCSx.Shape2();
1563 aOr=aEx.Orientation();
1566 aOrC=TopAbs::Reverse(aOr);
1567 aE1=(*(TopoDS_Edge*)(&aEx));
1568 aF1=(*(TopoDS_Face*)(&aFx));
1574 aLCEFx.Append(aCSx);
1580 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1582 aCFF.SetShape1(aF1);
1583 aCFF.SetShape2(aF2);
1584 theLCFF.Append(aCFF);
1593 aIt.Initialize(aLCEFx);
1594 for (; aIt.More(); aIt.Next()) {
1595 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1596 const TopoDS_Shape& aFx=aCSx.Shape2();
1597 if (!aMFP.Contains(aFx)) {
1602 aNbCEF=aLCEF.Extent();
1607 //=======================================================================
1608 //function : AngleWithRef
1610 //=======================================================================
1611 Standard_Real AngleWithRef(const gp_Dir& theD1,
1612 const gp_Dir& theD2,
1613 const gp_Dir& theDRef)
1615 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1620 const gp_XYZ& aXYZ1=theD1.XYZ();
1621 const gp_XYZ& aXYZ2=theD2.XYZ();
1622 aXYZ=aXYZ1.Crossed(aXYZ2);
1623 aSinus=aXYZ.Modulus();
1624 aCosinus=theD1*theD2;
1628 aBeta=aHalfPI*(1.-aCosinus);
1631 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1634 aScPr=aXYZ.Dot(theDRef.XYZ());
1640 //=======================================================================
1641 // function: IsBlockInOnFace
1643 //=======================================================================
1644 Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShrR,
1645 const TopoDS_Face& aF,
1646 const TopoDS_Edge& aE1,
1647 Handle(BOPInt_Context)& aContext)
1649 Standard_Boolean bFlag;
1650 Standard_Real f1, l1, ULD, VLD;
1654 aShrR.Range(f1, l1);
1655 Standard_Real dt=0.0075, k;//dt=0.001, k;
1661 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1663 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1664 aProjector.Perform(aP11);
1666 bFlag=aProjector.IsDone();
1671 aProjector.LowerDistanceParameters(ULD, VLD);
1672 aP2D.SetCoord(ULD, VLD);
1674 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1681 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1683 aProjector.Perform(aP12);
1685 bFlag=aProjector.IsDone();
1690 aProjector.LowerDistanceParameters(ULD, VLD);
1691 aP2D.SetCoord(ULD, VLD);
1693 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1699 // Treatment intemediate
1700 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1701 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1702 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1704 aProjector.Perform(aP12);
1706 bFlag=aProjector.IsDone();
1711 aTolE=BRep_Tool::Tolerance(aE1);
1712 aTolF=BRep_Tool::Tolerance(aF);
1714 aDist=aProjector.LowerDistance();
1716 return Standard_False;
1719 aProjector.LowerDistanceParameters(ULD, VLD);
1720 aP2D.SetCoord(ULD, VLD);
1722 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1730 //=======================================================================
1731 //function : IsMicroEdge
1733 //=======================================================================
1734 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge(const TopoDS_Edge& aE,
1735 const Handle(BOPInt_Context)& aCtx)
1737 Standard_Boolean bRet;
1738 Standard_Integer iErr;
1739 Standard_Real aT1, aT2, aTmp;
1740 Handle(Geom_Curve) aC3D;
1741 TopoDS_Vertex aV1, aV2;
1743 bRet=(BRep_Tool::Degenerated(aE) ||
1744 !BRep_Tool::IsGeometric(aE));
1749 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1750 TopExp::Vertices(aE, aV1, aV2);
1751 aT1=BRep_Tool::Parameter(aV1, aE);
1752 aT2=BRep_Tool::Parameter(aV2, aE);
1759 BOPInt_ShrunkRange aSR;
1760 aSR.SetData(aE, aT1, aT2, aV1, aV2, aCtx);
1762 iErr=aSR.ErrorStatus();
1768 //=======================================================================
1769 //function : GetFaceDir
1770 //purpose : Get binormal direction for the face in the point aP
1771 //=======================================================================
1772 void GetFaceDir(const TopoDS_Edge& aE,
1773 const TopoDS_Face& aF,
1775 const Standard_Real aT,
1776 const gp_Dir& aDTgt,
1779 Handle(BOPInt_Context)& theContext,
1780 GeomAPI_ProjectPointOnSurf& aProjPL)
1782 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1783 if (aF.Orientation()==TopAbs_REVERSED){
1789 if (!FindPointInFace(aE, aF, aP, aDB, aPx, theContext, aProjPL)) {
1790 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx, aDN, theContext);
1791 aProjPL.Perform(aPx);
1792 aPx = aProjPL.NearestPoint();
1793 gp_Vec aVec(aP, aPx);
1794 aDB.SetXYZ(aVec.XYZ());
1798 //=======================================================================
1799 //function : FindPointInFace
1800 //purpose : Find a point in the face in direction of <aDB>
1801 //=======================================================================
1802 Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
1803 const TopoDS_Face& aF,
1807 Handle(BOPInt_Context)& theContext,
1808 GeomAPI_ProjectPointOnSurf& aProjPL)
1810 Standard_Integer aNbItMax;
1811 Standard_Real aDt, aDtMin, aTolE, aTolF, aDist;
1812 Standard_Boolean bRet;
1814 BRepAdaptor_Surface aBAS;
1816 bRet = Standard_False;
1817 aTolE = BRep_Tool::Tolerance(aE);
1818 aTolF = BRep_Tool::Tolerance(aF);
1819 aDt = 2*(aTolE+aTolF);
1820 aBAS.Initialize(aF, Standard_False);
1825 GeomAbs_SurfaceType aSType=aBAS.GetType();
1827 case GeomAbs_Cylinder:
1828 aR = aBAS.Cylinder().Radius();
1830 case GeomAbs_Cone: {
1831 gp_Lin aL(aBAS.Cone().Axis());
1832 aR = aL.Distance(aP);
1835 case GeomAbs_Sphere:
1836 aR = aBAS.Sphere().Radius();
1839 aR = aBAS.Torus().MinorRadius();
1841 case GeomAbs_SurfaceOfRevolution:
1850 else if (aR > 100.) {
1858 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1862 aP1.SetCoord(aP.X()+aDt*aDB.X(),
1864 aP.Z()+aDt*aDB.Z());
1867 if (!aProj.IsDone()) {
1870 aPOut = aProj.NearestPoint();
1871 aDist = aProj.LowerDistance();
1873 aProjPL.Perform(aPOut);
1874 aPOut = aProjPL.NearestPoint();
1876 gp_Vec aV(aP, aPOut);
1877 aDB.SetXYZ(aV.XYZ());
1878 } while (aDist>Precision::Angular() && --aNbItMax);
1880 bRet = aDist < Precision::Angular();
1883 //=======================================================================
1884 //function : IsOpenShell
1886 //=======================================================================
1888 BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
1890 Standard_Boolean bRet;
1891 Standard_Integer i, aNbE, aNbF;
1892 TopAbs_Orientation aOrF;
1893 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
1894 BOPCol_ListIteratorOfListOfShape aItLS;
1896 bRet=Standard_False;
1898 BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF);
1901 for (i=1; i<=aNbE; ++i) {
1902 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i));
1903 if (BRep_Tool::Degenerated(aE)) {
1908 const BOPCol_ListOfShape& aLF=aMEF(i);
1909 aItLS.Initialize(aLF);
1910 for (; aItLS.More(); aItLS.Next()) {
1911 const TopoDS_Shape& aF=aItLS.Value();
1912 aOrF=aF.Orientation();
1913 if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
1927 //=======================================================================
1928 //function : IsInvertedSolid
1930 //=======================================================================
1932 BOPTools_AlgoTools::IsInvertedSolid(const TopoDS_Solid& aSolid)
1934 Standard_Real aTolS;
1935 TopAbs_State aState;
1936 BRepClass3d_SolidClassifier aSC(aSolid);
1939 aSC.PerformInfinitePoint(aTolS);
1941 return (aState==TopAbs_IN);