1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 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 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
23 #include <BOPTools_AlgoTools.ixx>
25 #include <Precision.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <gp_Cylinder.hxx>
31 #include <gp_Cone.hxx>
32 #include <gp_Sphere.hxx>
33 #include <gp_Torus.hxx>
36 #include <Geom2d_Curve.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_Plane.hxx>
39 #include <Geom_TrimmedCurve.hxx>
40 #include <Geom_Curve.hxx>
41 #include <GeomAPI_ProjectPointOnSurf.hxx>
42 #include <Geom2dInt_Geom2dCurveTool.hxx>
44 #include <TopAbs_Orientation.hxx>
46 #include <TopoDS_Compound.hxx>
47 #include <TopoDS_CompSolid.hxx>
48 #include <TopoDS_Solid.hxx>
49 #include <TopoDS_Shell.hxx>
50 #include <TopoDS_Wire.hxx>
52 #include <BRep_Builder.hxx>
53 #include <BRep_Tool.hxx>
54 #include <BRepLib.hxx>
55 #include <BRepAdaptor_Curve2d.hxx>
56 #include <BRepAdaptor_Surface.hxx>
57 #include <BRepClass3d_SolidClassifier.hxx>
59 #include <TopExp_Explorer.hxx>
61 #include <IntTools_Tools.hxx>
63 #include <BOPTools.hxx>
64 #include <BOPTools_CoupleOfShape.hxx>
65 #include <BOPTools_ListOfCoupleOfShape.hxx>
66 #include <BOPTools_AlgoTools2D.hxx>
67 #include <BOPTools_AlgoTools3D.hxx>
69 #include <BOPCol_IndexedMapOfShape.hxx>
70 #include <BOPCol_MapOfShape.hxx>
72 #include <BOPInt_ShrunkRange.hxx>
76 Standard_Real AngleWithRef(const gp_Dir& theD1,
78 const gp_Dir& theDRef);
81 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
82 const BOPCol_ListOfShape& thLF,
83 BOPTools_ListOfCoupleOfShape& theLCFF,
84 Handle(BOPInt_Context)& theContext);
86 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
87 const TopoDS_Face& aF);
90 void GetFaceDir(const TopoDS_Edge& aE,
91 const TopoDS_Face& aF,
93 const Standard_Real aT,
97 Handle(BOPInt_Context)& theContext,
98 GeomAPI_ProjectPointOnSurf& aProjPL);
100 Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
101 const TopoDS_Face& aF,
105 Handle(BOPInt_Context)& theContext,
106 GeomAPI_ProjectPointOnSurf& aProjPL);
108 //=======================================================================
109 // function: MakeConnexityBlocks
111 //=======================================================================
112 void BOPTools_AlgoTools::MakeConnexityBlocks (const TopoDS_Shape& theS,
113 const TopAbs_ShapeEnum theType1,
114 const TopAbs_ShapeEnum theType2,
115 BOPCol_ListOfShape& theLCB)
117 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
121 TopExp_Explorer aExp;
122 BOPCol_MapOfShape aMP;
123 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
124 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
125 BOPCol_ListIteratorOfListOfShape aItLF;
128 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
131 aIt.Initialize(theS);
132 for (; aIt.More(); aIt.Next()) {
133 const TopoDS_Shape& aF1=aIt.Value();
134 if (aMP.Contains(aF1)) {
145 aNbAdd = aMAdd.Extent();
146 for (i=1; i<=aNbAdd; ++i) {
147 const TopoDS_Shape& aF=aMAdd(i);
149 aExp.Init(aF, theType1);
150 for (; aExp.More(); aExp.Next()) {
151 const TopoDS_Shape& aE=aExp.Current();
153 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
154 aItLF.Initialize(aLF);
155 for (; aItLF.More(); aItLF.Next()) {
156 const TopoDS_Shape& aFx=aItLF.Value();
157 if (aFx.IsSame(aF)) {
160 if (aMCB.Contains(aFx)) {
165 }//for (; aExp.More(); aExp.Next()){
167 }// for (i=1; i<=aNbAdd; ++i) {
169 aNbAdd1=aMAdd1.Extent();
171 break;// ->make new CB from aMCB
175 for (i=1; i<=aNbAdd1; ++i) {
176 const TopoDS_Shape& aFAdd = aMAdd1(i);
183 aBB.MakeCompound(aC);
185 for (i=1; i<=aNbF; ++i) {
186 const TopoDS_Shape& aF=aMCB(i);
192 }// for (; aIt.More(); aIt.Next())
194 //=======================================================================
195 // function: OrientFacesOnShell
197 //=======================================================================
198 void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
200 Standard_Boolean bIsProcessed1, bIsProcessed2;
201 Standard_Integer i, aNbE, aNbF, j;
202 TopAbs_Orientation anOrE1, anOrE2;
203 TopoDS_Face aF1x, aF2x;
204 TopoDS_Shape aShellNew;
205 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
206 BOPCol_IndexedMapOfShape aProcessedFaces;
209 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
211 BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aEFMap);
212 aNbE=aEFMap.Extent();
214 // One seam edge in aEFMap contains 2 equivalent faces.
215 for (i=1; i<=aNbE; ++i) {
216 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
219 BOPCol_ListOfShape aLFTmp;
220 BOPCol_IndexedMapOfShape aFM;
222 BOPCol_ListIteratorOfListOfShape anIt(aLF);
223 for (; anIt.More(); anIt.Next()) {
224 const TopoDS_Shape& aF=anIt.Value();
225 if (!aFM.Contains(aF)) {
236 for (i=1; i<=aNbE; ++i) {
237 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
238 if (BRep_Tool::Degenerated(aE)) {
242 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
248 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
249 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
251 bIsProcessed1=aProcessedFaces.Contains(aF1);
252 bIsProcessed2=aProcessedFaces.Contains(aF2);
253 if (bIsProcessed1 && bIsProcessed2) {
257 if (!bIsProcessed1 && !bIsProcessed2) {
258 aProcessedFaces.Add(aF1);
259 aBB.Add(aShellNew, aF1);
260 bIsProcessed1=!bIsProcessed1;
265 j=aProcessedFaces.FindIndex(aF1);
266 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
271 j=aProcessedFaces.FindIndex(aF2);
272 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
275 anOrE1=Orientation(aE, aF1x);
276 anOrE2=Orientation(aE, aF2x);
278 if (bIsProcessed1 && !bIsProcessed2) {
279 if (anOrE1==anOrE2) {
280 if (!BRep_Tool::IsClosed(aE, aF1) &&
281 !BRep_Tool::IsClosed(aE, aF2)) {
285 aProcessedFaces.Add(aF2);
286 aBB.Add(aShellNew, aF2);
288 else if (!bIsProcessed1 && bIsProcessed2) {
289 if (anOrE1==anOrE2) {
290 if (!BRep_Tool::IsClosed(aE, aF1) &&
291 !BRep_Tool::IsClosed(aE, aF2)) {
295 aProcessedFaces.Add(aF1);
296 aBB.Add(aShellNew, aF1);
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);
310 BOPCol_ListIteratorOfListOfShape anIt(aLF);
311 for(; anIt.More(); anIt.Next()) {
312 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
313 if (!aProcessedFaces.Contains(aF)) {
314 aProcessedFaces.Add(aF);
315 aBB.Add(aShellNew, aF);
322 //=======================================================================
323 //function : Orientation
325 //=======================================================================
326 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
327 const TopoDS_Face& aF)
329 TopAbs_Orientation anOr=TopAbs_INTERNAL;
331 TopExp_Explorer anExp;
332 anExp.Init(aF, TopAbs_EDGE);
333 for (; anExp.More(); anExp.Next()) {
334 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
335 if (anEF1.IsSame(anE)) {
336 anOr=anEF1.Orientation();
346 //=======================================================================
347 // function: MakeConnexityBlock.
349 //=======================================================================
350 void BOPTools_AlgoTools::MakeConnexityBlock (BOPCol_ListOfShape& theLFIn,
351 BOPCol_IndexedMapOfShape& theMEAvoid,
352 BOPCol_ListOfShape& theLCB,
353 const Handle(NCollection_BaseAllocator)& theAllocator)
355 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
356 TopExp_Explorer aExp;
357 BOPCol_ListIteratorOfListOfShape aIt;
359 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
360 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
361 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
362 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
365 aNbF=theLFIn.Extent();
366 aIt.Initialize(theLFIn);
367 for (; aIt.More(); aIt.Next()) {
368 const TopoDS_Shape& aF=aIt.Value();
369 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
373 const TopoDS_Shape& aF1=theLFIn.First();
378 aNbAdd = aMAdd.Extent();
379 for (i=1; i<=aNbAdd; ++i) {
380 const TopoDS_Shape& aF=aMAdd(i);
383 aExp.Init(aF, TopAbs_EDGE);
384 for (; aExp.More(); aExp.Next()) {
385 const TopoDS_Shape& aE=aExp.Current();
386 if (theMEAvoid.Contains(aE)){
390 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
392 for (; aIt.More(); aIt.Next()) {
393 const TopoDS_Shape& aFx=aIt.Value();
394 if (aFx.IsSame(aF)) {
397 if (aMCB.Contains(aFx)) {
402 }//for (; aExp.More(); aExp.Next()){
404 }// for (i=1; i<=aNbAdd; ++i) {
406 aNbAdd1=aMAdd1.Extent();
412 for (i=1; i<=aNbAdd1; ++i) {
413 const TopoDS_Shape& aFAdd=aMAdd1(i);
421 for (i=1; i<=aNbF; ++i) {
422 const TopoDS_Shape& aF=aMCB(i);
426 //=======================================================================
427 // function: ComputeStateByOnePoint
429 //=======================================================================
430 TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint(const TopoDS_Shape& theS,
431 const TopoDS_Solid& theRef,
432 const Standard_Real theTol,
433 Handle(BOPInt_Context)& theContext)
436 TopAbs_ShapeEnum aType;
438 aState=TopAbs_UNKNOWN;
439 aType=theS.ShapeType();
440 if (aType==TopAbs_VERTEX) {
441 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
442 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
444 else if (aType==TopAbs_EDGE) {
445 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
446 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
451 //=======================================================================
452 // function: ComputeState
454 //=======================================================================
455 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
456 const TopoDS_Solid& theRef,
457 const Standard_Real theTol,
458 BOPCol_IndexedMapOfShape& theBounds,
459 Handle(BOPInt_Context)& theContext)
462 TopExp_Explorer aExp;
467 aState=TopAbs_UNKNOWN;
469 aExp.Init(theF, TopAbs_EDGE);
470 for (; aExp.More(); aExp.Next()) {
471 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
472 if (BRep_Tool::Degenerated(aSE)) {
476 if (!theBounds.Contains(aSE)) {
477 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
478 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
482 aE1=(*(TopoDS_Edge*)(&aSE));
485 // !!<- process edges that are all on theRef
487 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, aP2D, aP3D, theContext);
488 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
493 //=======================================================================
494 // function: ComputeState
496 //=======================================================================
497 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Vertex& theV,
498 const TopoDS_Solid& theRef,
499 const Standard_Real theTol,
500 Handle(BOPInt_Context)& theContext)
505 aP3D=BRep_Tool::Pnt(theV);
506 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
509 //=======================================================================
510 // function: ComputeState
512 //=======================================================================
513 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE,
514 const TopoDS_Solid& theRef,
515 const Standard_Real theTol,
516 Handle(BOPInt_Context)& theContext)
518 Standard_Real aT1, aT2, aT = 0.;
520 Handle(Geom_Curve) aC3D;
523 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
526 //it means that we are in degenerated edge
527 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
529 return TopAbs_UNKNOWN;
531 aP3D=BRep_Tool::Pnt(aV);
534 Standard_Boolean bF2Inf, bL2Inf;
535 Standard_Real dT=10.;
537 bF2Inf = Precision::IsNegativeInfinite(aT1);
538 bL2Inf = Precision::IsPositiveInfinite(aT2);
540 if (bF2Inf && !bL2Inf) {
543 else if (!bF2Inf && bL2Inf) {
546 else if (bF2Inf && bL2Inf) {
550 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
555 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
559 //=======================================================================
560 // function: ComputeState
562 //=======================================================================
563 TopAbs_State BOPTools_AlgoTools::ComputeState(const gp_Pnt& theP,
564 const TopoDS_Solid& theRef,
565 const Standard_Real theTol,
566 Handle(BOPInt_Context)& theContext)
570 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
571 aSC.Perform(theP, theTol);
577 //=======================================================================
578 //function : IsInternalFace
580 //=======================================================================
581 Standard_Integer BOPTools_AlgoTools::IsInternalFace
582 (const TopoDS_Face& theFace,
583 const TopoDS_Solid& theSolid,
584 BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
585 const Standard_Real theTol,
586 Handle(BOPInt_Context)& theContext)
588 Standard_Boolean bDegenerated;
589 Standard_Integer aNbF, iRet, iFound;
590 TopAbs_Orientation aOr;
592 TopExp_Explorer aExp;
593 BOPCol_ListIteratorOfListOfShape aItF;
595 // For all invoked functions: [::IsInternalFace(...)]
596 // the returned value iRet means:
597 // iRet=0; - state is not IN
598 // iRet=1; - state is IN
599 // iRet=2; - state can not be found by the method of angles
601 // For this function the returned value iRet means:
602 // iRet=0; - state is not IN
603 // iRet=1; - state is IN
606 // 1 Try to find an edge from theFace in theMEF
608 aExp.Init(theFace, TopAbs_EDGE);
609 for(; aExp.More(); aExp.Next()) {
610 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
611 if (!theMEF.Contains(aE)) {
617 aOr=aE.Orientation();
618 if (aOr==TopAbs_INTERNAL) {
621 bDegenerated=BRep_Tool::Degenerated(aE);
626 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
629 return iRet; // it can not be so
633 // aE is internal edge on aLF.First()
634 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
635 BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1);
636 if (aE1.Orientation()!=TopAbs_INTERNAL) {
641 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1, theContext);
646 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
647 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
649 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
650 // treat as it was for 1 face
651 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2, theContext);
658 return iRet; // it can not be so
660 else { // aNbF=2,4,6,8,...
661 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, theContext);
664 }//for(; aExp.More(); aExp.Next()) {
667 // the face has no shared edges with the solid
675 //========================================
676 // 2. Classify face using classifier
679 BOPCol_IndexedMapOfShape aBounds;
681 BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
683 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid, theTol, aBounds, theContext);
685 iRet=(aState==TopAbs_IN)? 1 : 0;
689 //=======================================================================
690 //function : IsInternalFace
692 //=======================================================================
693 Standard_Integer BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace,
694 const TopoDS_Edge& theEdge,
695 BOPCol_ListOfShape& theLF,
696 Handle(BOPInt_Context)& theContext)
698 Standard_Integer aNbF, iRet;
704 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
705 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
706 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
711 BOPTools_ListOfCoupleOfShape aLCFF;
712 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
714 FindFacePairs(theEdge, theLF, aLCFF, theContext);
716 aIt.Initialize(aLCFF);
717 for (; aIt.More(); aIt.Next()) {
718 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
720 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
721 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
722 iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
730 //=======================================================================
731 //function : IsInternalFace
733 //=======================================================================
734 Standard_Integer BOPTools_AlgoTools::IsInternalFace
735 (const TopoDS_Face& theFace,
736 const TopoDS_Edge& theEdge,
737 const TopoDS_Face& theFace1,
738 const TopoDS_Face& theFace2,
739 Handle(BOPInt_Context)& theContext)
741 Standard_Boolean bRet;
742 Standard_Integer iRet;
743 TopoDS_Edge aE1, aE2;
745 BOPTools_ListOfCoupleOfShape theLCSOff;
746 BOPTools_CoupleOfShape aCS1, aCS2;
748 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
749 if (aE1.Orientation()==TopAbs_INTERNAL) {
751 aE1.Orientation(TopAbs_FORWARD);
752 aE2.Orientation(TopAbs_REVERSED);
754 else if (theFace1==theFace2) {
756 aE1.Orientation(TopAbs_FORWARD);
757 aE2.Orientation(TopAbs_REVERSED);
760 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
763 aCS1.SetShape1(theEdge);
764 aCS1.SetShape2(theFace);
765 theLCSOff.Append(aCS1);
768 aCS2.SetShape2(theFace2);
769 theLCSOff.Append(aCS2);
771 bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
773 iRet=0; // theFace is not internal
774 if (theFace.IsEqual(aFOff)) {
775 // theFace is internal
778 // theFace seems to be internal
784 //=======================================================================
785 //function : GetFaceOff
787 //=======================================================================
788 Standard_Boolean BOPTools_AlgoTools::GetFaceOff
789 (const TopoDS_Edge& theE1,
790 const TopoDS_Face& theF1,
791 BOPTools_ListOfCoupleOfShape& theLCSOff,
792 TopoDS_Face& theFOff,
793 Handle(BOPInt_Context)& theContext)
795 Standard_Boolean bRet;
796 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
797 Standard_Real aUmin, aUsup, aVmin, aVsup;
798 gp_Pnt aPn1, aPn2, aPx;
799 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
801 TopAbs_Orientation aOr;
802 Handle(Geom_Curve)aC3D;
803 Handle(Geom_Plane) aPL;
804 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
805 GeomAPI_ProjectPointOnSurf aProjPL;
809 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
810 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
813 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
814 gp_Dir aDTgt(aVTgt), aDTgt2;
815 aOr = theE1.Orientation();
817 aPL = new Geom_Plane(aPx, aDTgt);
818 aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
819 aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
821 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext, aProjPL);
826 aIt.Initialize(theLCSOff);
827 for (; aIt.More(); aIt.Next()) {
828 const BOPTools_CoupleOfShape& aCS=aIt.Value();
829 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
830 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
832 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
833 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext, aProjPL);
835 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
838 aAngle=aTwoPI+aAngle;
841 if (aAngle<Precision::Angular()) {
845 else if (aF2.IsSame(theF1)) {
850 if (aAngle<aAngleMin){
854 else if (aAngle==aAngleMin) {
855 // the minimal angle can not be found
861 //=======================================================================
862 //function : GetEdgeOff
864 //=======================================================================
865 Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
866 const TopoDS_Face& theF2,
869 Standard_Boolean bFound;
870 TopAbs_Orientation aOr1, aOr1C, aOr2;
871 TopExp_Explorer anExp;
873 bFound=Standard_False;
874 aOr1=theE1.Orientation();
875 aOr1C=TopAbs::Reverse(aOr1);
877 anExp.Init(theF2, TopAbs_EDGE);
878 for (; anExp.More(); anExp.Next()) {
879 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
880 if (aEF2.IsSame(theE1)) {
881 aOr2=aEF2.Orientation();
892 //=======================================================================
893 //function : AreFacesSameDomain
895 //=======================================================================
896 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1,
897 const TopoDS_Face& theF2,
898 Handle(BOPInt_Context)& theContext)
900 Standard_Boolean bFlag;
901 Standard_Integer iErr;
902 Standard_Real aTolF1, aTolF2, aTol;
905 TopoDS_Face aF1, aF2;
907 TopExp_Explorer aExp;
909 bFlag=Standard_False;
912 aF1.Orientation(TopAbs_FORWARD);
914 aF2.Orientation(TopAbs_FORWARD);
916 aTolF1=BRep_Tool::Tolerance(aF1);
918 aExp.Init(aF1, TopAbs_EDGE);
919 for (; aExp.More(); aExp.Next()) {
920 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
921 if (!BRep_Tool::Degenerated(aE1)) {
922 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
923 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
927 aTolF2=BRep_Tool::Tolerance(aF2);
930 iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D, theContext);
932 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
938 //=======================================================================
939 //function : CheckSameGeom
941 //=======================================================================
942 Standard_Boolean BOPTools_AlgoTools::CheckSameGeom(const TopoDS_Face& theF1,
943 const TopoDS_Face& theF2,
944 Handle(BOPInt_Context)& theContext)
946 Standard_Boolean bRet;
947 Standard_Real aTolF1, aTolF2, aTol;
950 TopExp_Explorer aExp;
953 aExp.Init(theF1, TopAbs_EDGE);
954 for (; aExp.More(); aExp.Next()) {
955 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
956 if (!BRep_Tool::Degenerated(aE)) {
957 aTolF1=BRep_Tool::Tolerance(theF1);
958 aTolF2=BRep_Tool::Tolerance(theF2);
960 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
961 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
967 //=======================================================================
970 //=======================================================================
971 Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
972 const TopoDS_Face& theF2)
974 Standard_Integer iSense=0;
976 TopoDS_Edge aE1, aE2;
977 TopExp_Explorer aExp;
979 aExp.Init(theF1, TopAbs_EDGE);
980 for (; aExp.More(); aExp.Next()) {
981 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
982 if (!BRep_Tool::Degenerated(aE1)) {
983 if (!BRep_Tool::IsClosed(aE1, theF1)) {
989 aExp.Init(theF2, TopAbs_EDGE);
990 for (; aExp.More(); aExp.Next()) {
991 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
992 if (!BRep_Tool::Degenerated(aE2)) {
993 if (!BRep_Tool::IsClosed(aE2, theF2)) {
994 if (aE2.IsSame(aE1)) {
1006 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
1007 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
1009 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
1013 //=======================================================================
1014 // function: IsSplitToReverse
1016 //=======================================================================
1017 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Shape& theSp,
1018 const TopoDS_Shape& theSr,
1019 Handle(BOPInt_Context)& theContext)
1021 Standard_Boolean bRet;
1022 TopAbs_ShapeEnum aType;
1024 bRet=Standard_False;
1026 aType=theSp.ShapeType();
1029 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
1030 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
1031 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
1036 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
1037 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
1038 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
1047 //=======================================================================
1048 //function :IsSplitToReverse
1050 //=======================================================================
1051 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
1052 const TopoDS_Face& theFSr,
1053 Handle(BOPInt_Context)& theContext)
1055 Standard_Boolean bRet, bFound, bInFace;
1056 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1057 gp_Pnt aPFSp, aPFSr;
1060 Handle(Geom_Surface) aSr, aSp;
1061 TopAbs_Orientation aOrSr, aOrSp;
1062 TopExp_Explorer anExp;
1065 bRet=Standard_False;
1067 aSr=BRep_Tool::Surface(theFSr);
1068 aSp=BRep_Tool::Surface(theFSp);
1070 aOrSr=theFSr.Orientation();
1071 aOrSp=theFSp.Orientation();
1072 bRet=(aOrSr!=aOrSp);
1076 bFound=Standard_False;
1077 anExp.Init(theFSp, TopAbs_EDGE);
1078 for (; anExp.More(); anExp.Next()) {
1079 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1080 if (!BRep_Tool::Degenerated(aESp)) {
1081 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1088 Standard_Boolean bFlag;
1089 Standard_Integer iErr;
1092 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp, theContext);
1097 aP2DFSp.Coord(aU, aV);
1098 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1104 BRep_Tool::Range(aESp, aT1, aT2);
1105 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
1106 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp, theContext);
1109 // Parts of theContext->ComputeVS(..)
1110 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1111 aProjector.Perform(aPFSp);
1112 if (!aProjector.IsDone()) {
1116 aProjector.LowerDistanceParameters(aU, aV);
1117 gp_Pnt2d aP2D(aU, aV);
1118 bInFace=theContext->IsPointInFace (theFSr, aP2D);
1123 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1126 gp_Dir aDNFSr=aDD1U^aDD1V;
1127 if (theFSr.Orientation()==TopAbs_REVERSED){
1131 aScPr=aDNFSp*aDNFSr;
1136 //=======================================================================
1137 //function :IsSplitToReverse
1139 //=======================================================================
1140 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Edge& aEF1,
1141 const TopoDS_Edge& aEF2,
1142 Handle(BOPInt_Context)& theContext)
1144 Standard_Boolean bRet, bIsDegenerated;
1146 bRet=Standard_False;
1147 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1148 BRep_Tool::Degenerated(aEF2));
1149 if (bIsDegenerated) {
1154 TopAbs_Orientation aOrE, aOrSp;
1155 Handle(Geom_Curve)aC1, aC2;
1157 aC2=BRep_Tool::Curve(aEF2, a, b);
1158 aC1=BRep_Tool::Curve(aEF1, a, b);
1161 aOrE=aEF2.Orientation();
1162 aOrSp=aEF1.Orientation();
1167 Standard_Real aT1, aT2, aScPr;
1171 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1173 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1176 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1178 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1187 //=======================================================================
1190 //=======================================================================
1191 Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1192 const TopoDS_Shape& aFace)
1194 Standard_Boolean bIsHole;
1195 Standard_Integer i, aNbS;
1196 Standard_Real aT1, aT2, aS;
1197 Standard_Real aU1, aU2, aU, dU;
1198 Standard_Real aX1, aY1, aX0, aY0;
1199 TopAbs_Orientation aOr;
1201 gp_Pnt2d aP2D0, aP2D1;
1202 Handle(Geom2d_Curve) aC2D;
1203 TopoDS_Face aF, aFF;
1204 TopoDS_Iterator aItW;
1206 bIsHole=Standard_False;
1208 aF=(*(TopoDS_Face *)(&aFace));
1210 aFF.Orientation(TopAbs_FORWARD);
1213 aItW.Initialize(aW);
1214 for (; aItW.More(); aItW.Next()) {
1215 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1216 aOr=aE.Orientation();
1217 if (!(aOr==TopAbs_FORWARD ||
1218 aOr==TopAbs_REVERSED)) {
1222 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1223 if (aC2D.IsNull()) {
1227 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1228 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1233 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1237 if (aOr==TopAbs_REVERSED) {
1244 aC2D->D0(aU, aP2D0);
1245 for(i=2; i<=aNbS; i++) {
1247 aC2D->D0(aU, aP2D1);
1248 aP2D0.Coord(aX0, aY0);
1249 aP2D1.Coord(aX1, aY1);
1251 aS=aS+(aY0+aY1)*(aX1-aX0);
1255 }//for (; aItW.More(); aItW.Next()) {
1260 //=======================================================================
1261 // function: MakeContainer
1263 //=======================================================================
1264 void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1270 case TopAbs_COMPOUND:{
1272 aBB.MakeCompound(aC);
1277 case TopAbs_COMPSOLID:{
1278 TopoDS_CompSolid aCS;
1279 aBB.MakeCompSolid(aCS);
1285 TopoDS_Solid aSolid;
1286 aBB.MakeSolid(aSolid);
1293 TopoDS_Shell aShell;
1294 aBB.MakeShell(aShell);
1301 aBB.MakeWire(aWire);
1310 //=======================================================================
1311 // function: MakePCurve
1313 //=======================================================================
1314 void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1315 const TopoDS_Face& aF1,
1316 const TopoDS_Face& aF2,
1317 const IntTools_Curve& aIC,
1318 const Standard_Boolean bPC1,
1319 const Standard_Boolean bPC2)
1323 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1324 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1327 Standard_Boolean bPC;
1329 aTolE=BRep_Tool::Tolerance(aE);
1331 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
1332 Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aT1, aT2);
1334 for (i=0; i<2; ++i) {
1335 bPC = !i ? bPC1 : bPC2;
1342 aC2Dx1=aIC.FirstCurve2d();
1346 aC2Dx1=aIC.SecondCurve2d();
1349 aFFWD.Orientation(TopAbs_FORWARD);
1352 if (aC2D.IsNull()) {
1353 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1354 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1355 aOutFirst, aOutLast,
1359 if (aC3DE->IsPeriodic()) {
1360 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D, aC2DA);
1363 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA);
1366 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1367 //BRepLib::SameParameter(aE);
1369 BRepLib::SameParameter(aE);
1371 //=======================================================================
1372 // function: MakeEdge
1374 //=======================================================================
1375 void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1376 const TopoDS_Vertex& theV1,
1377 const Standard_Real theT1,
1378 const TopoDS_Vertex& theV2,
1379 const Standard_Real theT2,
1380 const Standard_Real theTolR3D,
1383 Standard_Real aTolV;
1386 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2, theE);
1388 aBB.UpdateEdge(theE, theTolR3D);
1390 aTolV=BRep_Tool::Tolerance(theV1);
1391 if (aTolV<theTolR3D) {
1392 aBB.UpdateVertex(theV1, theTolR3D);
1395 aTolV=BRep_Tool::Tolerance(theV2);
1396 if (aTolV<theTolR3D) {
1397 aBB.UpdateVertex(theV2, theTolR3D);
1400 //=======================================================================
1401 // function: ComputeVV
1403 //=======================================================================
1404 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1406 const Standard_Real aTolP2)
1408 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1411 aTolV1=BRep_Tool::Tolerance(aV1);
1413 aTolSum=aTolV1+aTolP2;
1414 aTolSum2=aTolSum*aTolSum;
1416 aP1=BRep_Tool::Pnt(aV1);
1418 aD2=aP1.SquareDistance(aP2);
1424 //=======================================================================
1425 // function: ComputeVV
1427 //=======================================================================
1428 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1429 const TopoDS_Vertex& aV2)
1431 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1434 aTolV1=BRep_Tool::Tolerance(aV1);
1435 aTolV2=BRep_Tool::Tolerance(aV2);
1436 aTolSum=aTolV1+aTolV2;
1437 aTolSum2=aTolSum*aTolSum;
1439 aP1=BRep_Tool::Pnt(aV1);
1440 aP2=BRep_Tool::Pnt(aV2);
1442 aD2=aP1.SquareDistance(aP2);
1448 //=======================================================================
1449 // function: MakeVertex
1451 //=======================================================================
1452 void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
1453 TopoDS_Vertex& aVnew)
1455 Standard_Integer aNb;
1456 Standard_Real aTi, aDi, aDmax;
1458 gp_XYZ aXYZ(0.,0.,0.), aXYZi;
1459 BOPCol_ListIteratorOfListOfShape aIt;
1463 aIt.Initialize(aLV);
1464 for (; aIt.More(); aIt.Next()) {
1465 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1466 aPi=BRep_Tool::Pnt(aVi);
1471 aXYZ.Divide((Standard_Real)aNb);
1475 aIt.Initialize(aLV);
1476 for (; aIt.More(); aIt.Next()) {
1477 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1478 aPi=BRep_Tool::Pnt(aVi);
1479 aTi=BRep_Tool::Tolerance(aVi);
1480 aDi=aP.SquareDistance(aPi);
1489 aBB.MakeVertex (aVnew, aP, aDmax);
1492 //=======================================================================
1493 //function : GetEdgeOnFace
1495 //=======================================================================
1496 Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace(const TopoDS_Edge& theE1,
1497 const TopoDS_Face& theF2,
1500 Standard_Boolean bFound;
1501 TopoDS_Iterator aItF, aItW;
1503 bFound=Standard_False;
1505 aItF.Initialize(theF2);
1506 for (; aItF.More(); aItF.Next()) {
1507 const TopoDS_Shape& aW=aItF.Value();
1508 aItW.Initialize(aW);
1509 for (; aItW.More(); aItW.Next()) {
1510 const TopoDS_Shape& aE=aItW.Value();
1511 if (aE.IsSame(theE1)) {
1512 theE2=(*(TopoDS_Edge*)(&aE));
1520 //=======================================================================
1521 //function : FindFacePairs
1523 //=======================================================================
1524 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1525 const BOPCol_ListOfShape& thLF,
1526 BOPTools_ListOfCoupleOfShape& theLCFF,
1527 Handle(BOPInt_Context)& theContext)
1529 Standard_Boolean bFound;
1530 Standard_Integer i, aNbCEF;
1531 TopAbs_Orientation aOr, aOrC = TopAbs_FORWARD;
1532 BOPCol_MapOfShape aMFP;
1533 TopoDS_Face aF1, aF2;
1534 TopoDS_Edge aEL, aE1;
1535 BOPCol_ListIteratorOfListOfShape aItLF;
1536 BOPTools_CoupleOfShape aCEF, aCFF;
1537 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1538 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1540 bFound=Standard_True;
1543 aItLF.Initialize(thLF);
1544 for (; aItLF.More(); aItLF.Next()) {
1545 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1547 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1549 return bFound; // it can not be so
1552 aCEF.SetShape1(aEL);
1553 aCEF.SetShape2(aFL);
1557 aNbCEF=aLCEF.Extent();
1562 aIt.Initialize(aLCEF);
1563 for (i=0; aIt.More(); aIt.Next(), ++i) {
1564 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1565 const TopoDS_Shape& aEx=aCSx.Shape1();
1566 const TopoDS_Shape& aFx=aCSx.Shape2();
1568 aOr=aEx.Orientation();
1571 aOrC=TopAbs::Reverse(aOr);
1572 aE1=(*(TopoDS_Edge*)(&aEx));
1573 aF1=(*(TopoDS_Face*)(&aFx));
1579 aLCEFx.Append(aCSx);
1585 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1587 aCFF.SetShape1(aF1);
1588 aCFF.SetShape2(aF2);
1589 theLCFF.Append(aCFF);
1598 aIt.Initialize(aLCEFx);
1599 for (; aIt.More(); aIt.Next()) {
1600 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1601 const TopoDS_Shape& aFx=aCSx.Shape2();
1602 if (!aMFP.Contains(aFx)) {
1607 aNbCEF=aLCEF.Extent();
1612 //=======================================================================
1613 //function : AngleWithRef
1615 //=======================================================================
1616 Standard_Real AngleWithRef(const gp_Dir& theD1,
1617 const gp_Dir& theD2,
1618 const gp_Dir& theDRef)
1620 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1625 const gp_XYZ& aXYZ1=theD1.XYZ();
1626 const gp_XYZ& aXYZ2=theD2.XYZ();
1627 aXYZ=aXYZ1.Crossed(aXYZ2);
1628 aSinus=aXYZ.Modulus();
1629 aCosinus=theD1*theD2;
1633 aBeta=aHalfPI*(1.-aCosinus);
1636 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1639 aScPr=aXYZ.Dot(theDRef.XYZ());
1645 //=======================================================================
1646 // function: IsBlockInOnFace
1648 //=======================================================================
1649 Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShrR,
1650 const TopoDS_Face& aF,
1651 const TopoDS_Edge& aE1,
1652 Handle(BOPInt_Context)& aContext)
1654 Standard_Boolean bFlag;
1655 Standard_Real f1, l1, ULD, VLD;
1659 aShrR.Range(f1, l1);
1660 Standard_Real dt=0.0075, k;//dt=0.001, k;
1666 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1668 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1669 aProjector.Perform(aP11);
1671 bFlag=aProjector.IsDone();
1676 aProjector.LowerDistanceParameters(ULD, VLD);
1677 aP2D.SetCoord(ULD, VLD);
1679 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1686 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1688 aProjector.Perform(aP12);
1690 bFlag=aProjector.IsDone();
1695 aProjector.LowerDistanceParameters(ULD, VLD);
1696 aP2D.SetCoord(ULD, VLD);
1698 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1704 // Treatment intemediate
1705 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1706 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1707 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1709 aProjector.Perform(aP12);
1711 bFlag=aProjector.IsDone();
1716 aTolE=BRep_Tool::Tolerance(aE1);
1717 aTolF=BRep_Tool::Tolerance(aF);
1719 aDist=aProjector.LowerDistance();
1721 return Standard_False;
1724 aProjector.LowerDistanceParameters(ULD, VLD);
1725 aP2D.SetCoord(ULD, VLD);
1727 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1735 //=======================================================================
1736 //function : IsMicroEdge
1738 //=======================================================================
1739 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge(const TopoDS_Edge& aE,
1740 const Handle(BOPInt_Context)& aCtx)
1742 Standard_Boolean bRet;
1743 Standard_Integer iErr;
1744 Standard_Real aT1, aT2, aTmp;
1745 Handle(Geom_Curve) aC3D;
1746 TopoDS_Vertex aV1, aV2;
1748 bRet=(BRep_Tool::Degenerated(aE) ||
1749 !BRep_Tool::IsGeometric(aE));
1754 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1755 TopExp::Vertices(aE, aV1, aV2);
1756 aT1=BRep_Tool::Parameter(aV1, aE);
1757 aT2=BRep_Tool::Parameter(aV2, aE);
1764 BOPInt_ShrunkRange aSR;
1765 aSR.SetData(aE, aT1, aT2, aV1, aV2, aCtx);
1767 iErr=aSR.ErrorStatus();
1773 //=======================================================================
1774 //function : GetFaceDir
1775 //purpose : Get binormal direction for the face in the point aP
1776 //=======================================================================
1777 void GetFaceDir(const TopoDS_Edge& aE,
1778 const TopoDS_Face& aF,
1780 const Standard_Real aT,
1781 const gp_Dir& aDTgt,
1784 Handle(BOPInt_Context)& theContext,
1785 GeomAPI_ProjectPointOnSurf& aProjPL)
1787 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1788 if (aF.Orientation()==TopAbs_REVERSED){
1794 if (!FindPointInFace(aE, aF, aP, aDB, aPx, theContext, aProjPL)) {
1795 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx, aDN, theContext);
1796 aProjPL.Perform(aPx);
1797 aPx = aProjPL.NearestPoint();
1798 gp_Vec aVec(aP, aPx);
1799 aDB.SetXYZ(aVec.XYZ());
1803 //=======================================================================
1804 //function : FindPointInFace
1805 //purpose : Find a point in the face in direction of <aDB>
1806 //=======================================================================
1807 Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
1808 const TopoDS_Face& aF,
1812 Handle(BOPInt_Context)& theContext,
1813 GeomAPI_ProjectPointOnSurf& aProjPL)
1815 Standard_Integer aNbItMax;
1816 Standard_Real aDt, aDtMin, aTolE, aTolF, aDist;
1817 Standard_Boolean bRet;
1819 BRepAdaptor_Surface aBAS;
1821 bRet = Standard_False;
1822 aTolE = BRep_Tool::Tolerance(aE);
1823 aTolF = BRep_Tool::Tolerance(aF);
1824 aDt = 2*(aTolE+aTolF);
1825 aBAS.Initialize(aF, Standard_False);
1830 GeomAbs_SurfaceType aSType=aBAS.GetType();
1832 case GeomAbs_Cylinder:
1833 aR = aBAS.Cylinder().Radius();
1835 case GeomAbs_Cone: {
1836 gp_Lin aL(aBAS.Cone().Axis());
1837 aR = aL.Distance(aP);
1840 case GeomAbs_Sphere:
1841 aR = aBAS.Sphere().Radius();
1844 aR = aBAS.Torus().MinorRadius();
1846 case GeomAbs_SurfaceOfRevolution:
1855 else if (aR > 100.) {
1863 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1867 aP1.SetCoord(aP.X()+aDt*aDB.X(),
1869 aP.Z()+aDt*aDB.Z());
1872 if (!aProj.IsDone()) {
1875 aPOut = aProj.NearestPoint();
1876 aDist = aProj.LowerDistance();
1878 aProjPL.Perform(aPOut);
1879 aPOut = aProjPL.NearestPoint();
1881 gp_Vec aV(aP, aPOut);
1882 aDB.SetXYZ(aV.XYZ());
1883 } while (aDist>Precision::Angular() && --aNbItMax);
1885 bRet = aDist < Precision::Angular();