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>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <Geom_Curve.hxx>
40 #include <GeomAPI_ProjectPointOnSurf.hxx>
41 #include <Geom2dInt_Geom2dCurveTool.hxx>
42 #include <GeomAdaptor_Surface.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 <BRepClass3d_SolidClassifier.hxx>
58 #include <TopExp_Explorer.hxx>
60 #include <IntTools_Tools.hxx>
62 #include <BOPTools.hxx>
63 #include <BOPTools_CoupleOfShape.hxx>
64 #include <BOPTools_ListOfCoupleOfShape.hxx>
65 #include <BOPTools_AlgoTools2D.hxx>
66 #include <BOPTools_AlgoTools3D.hxx>
68 #include <BOPCol_IndexedMapOfShape.hxx>
69 #include <BOPCol_MapOfShape.hxx>
71 #include <BOPInt_ShrunkRange.hxx>
75 Standard_Real AngleWithRef(const gp_Dir& theD1,
77 const gp_Dir& theDRef);
79 inline Standard_Real fsqrt(Standard_Real val);
82 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
83 const BOPCol_ListOfShape& thLF,
84 BOPTools_ListOfCoupleOfShape& theLCFF,
85 Handle(BOPInt_Context)& theContext);
87 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
88 const TopoDS_Face& aF);
91 void GetFaceDir(const TopoDS_Edge& aE,
92 const TopoDS_Face& aF,
94 const Standard_Real aT,
98 Handle(BOPInt_Context)& theContext);
100 Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
101 const TopoDS_Face& aF,
103 const Standard_Real aT,
106 Handle(BOPInt_Context)& theContext,
107 const GeomAdaptor_Surface& aGAS);
109 //=======================================================================
110 // function: MakeConnexityBlocks
112 //=======================================================================
113 void BOPTools_AlgoTools::MakeConnexityBlocks (const TopoDS_Shape& theS,
114 const TopAbs_ShapeEnum theType1,
115 const TopAbs_ShapeEnum theType2,
116 BOPCol_ListOfShape& theLCB)
118 Standard_Integer aNbF, aNbAdd, aNbAdd1, i;
122 TopExp_Explorer aExp;
123 BOPCol_MapOfShape aMP;
124 BOPCol_IndexedMapOfShape aMCB, aMAdd, aMAdd1;
125 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
126 BOPCol_ListIteratorOfListOfShape aItLF;
129 BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aMEF);
132 aIt.Initialize(theS);
133 for (; aIt.More(); aIt.Next()) {
134 const TopoDS_Shape& aF1=aIt.Value();
135 if (aMP.Contains(aF1)) {
146 aNbAdd = aMAdd.Extent();
147 for (i=1; i<=aNbAdd; ++i) {
148 const TopoDS_Shape& aF=aMAdd(i);
150 aExp.Init(aF, theType1);
151 for (; aExp.More(); aExp.Next()) {
152 const TopoDS_Shape& aE=aExp.Current();
154 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
155 aItLF.Initialize(aLF);
156 for (; aItLF.More(); aItLF.Next()) {
157 const TopoDS_Shape& aFx=aItLF.Value();
158 if (aFx.IsSame(aF)) {
161 if (aMCB.Contains(aFx)) {
166 }//for (; aExp.More(); aExp.Next()){
168 }// for (i=1; i<=aNbAdd; ++i) {
170 aNbAdd1=aMAdd1.Extent();
172 break;// ->make new CB from aMCB
176 for (i=1; i<=aNbAdd1; ++i) {
177 const TopoDS_Shape& aFAdd = aMAdd1(i);
184 aBB.MakeCompound(aC);
186 for (i=1; i<=aNbF; ++i) {
187 const TopoDS_Shape& aF=aMCB(i);
193 }// for (; aIt.More(); aIt.Next())
195 //=======================================================================
196 // function: OrientFacesOnShell
198 //=======================================================================
199 void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
201 Standard_Boolean bIsProcessed1, bIsProcessed2;
202 Standard_Integer i, aNbE, aNbF, j;
203 TopAbs_Orientation anOrE1, anOrE2;
204 TopoDS_Face aF1x, aF2x;
205 TopoDS_Shape aShellNew;
206 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
207 BOPCol_IndexedMapOfShape aProcessedFaces;
210 BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
212 BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aEFMap);
213 aNbE=aEFMap.Extent();
215 // One seam edge in aEFMap contains 2 equivalent faces.
216 for (i=1; i<=aNbE; ++i) {
217 BOPCol_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
220 BOPCol_ListOfShape aLFTmp;
221 BOPCol_IndexedMapOfShape aFM;
223 BOPCol_ListIteratorOfListOfShape anIt(aLF);
224 for (; anIt.More(); anIt.Next()) {
225 const TopoDS_Shape& aF=anIt.Value();
226 if (!aFM.Contains(aF)) {
237 for (i=1; i<=aNbE; ++i) {
238 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
239 if (BRep_Tool::Degenerated(aE)) {
243 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
249 TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
250 TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
252 bIsProcessed1=aProcessedFaces.Contains(aF1);
253 bIsProcessed2=aProcessedFaces.Contains(aF2);
254 if (bIsProcessed1 && bIsProcessed2) {
258 if (!bIsProcessed1 && !bIsProcessed2) {
259 aProcessedFaces.Add(aF1);
260 aBB.Add(aShellNew, aF1);
261 bIsProcessed1=!bIsProcessed1;
266 j=aProcessedFaces.FindIndex(aF1);
267 aF1x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
272 j=aProcessedFaces.FindIndex(aF2);
273 aF2x=(*(TopoDS_Face*)(&aProcessedFaces.FindKey(j)));
276 anOrE1=Orientation(aE, aF1x);
277 anOrE2=Orientation(aE, aF2x);
279 if (bIsProcessed1 && !bIsProcessed2) {
280 if (anOrE1==anOrE2) {
281 if (!BRep_Tool::IsClosed(aE, aF1) &&
282 !BRep_Tool::IsClosed(aE, aF2)) {
286 aProcessedFaces.Add(aF2);
287 aBB.Add(aShellNew, aF2);
289 else if (!bIsProcessed1 && bIsProcessed2) {
290 if (anOrE1==anOrE2) {
291 if (!BRep_Tool::IsClosed(aE, aF1) &&
292 !BRep_Tool::IsClosed(aE, aF2)) {
296 aProcessedFaces.Add(aF1);
297 aBB.Add(aShellNew, aF1);
302 for (i=1; i<=aNbE; ++i) {
303 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aEFMap.FindKey(i)));
304 if (BRep_Tool::Degenerated(aE)) {
308 const BOPCol_ListOfShape& aLF=aEFMap.FindFromIndex(i);
311 BOPCol_ListIteratorOfListOfShape anIt(aLF);
312 for(; anIt.More(); anIt.Next()) {
313 const TopoDS_Face& aF=(*(TopoDS_Face*)(&anIt.Value()));
314 if (!aProcessedFaces.Contains(aF)) {
315 aProcessedFaces.Add(aF);
316 aBB.Add(aShellNew, aF);
323 //=======================================================================
324 //function : Orientation
326 //=======================================================================
327 TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
328 const TopoDS_Face& aF)
330 TopAbs_Orientation anOr=TopAbs_INTERNAL;
332 TopExp_Explorer anExp;
333 anExp.Init(aF, TopAbs_EDGE);
334 for (; anExp.More(); anExp.Next()) {
335 const TopoDS_Edge& anEF1=(*(TopoDS_Edge*)(&anExp.Current()));
336 if (anEF1.IsSame(anE)) {
337 anOr=anEF1.Orientation();
347 //=======================================================================
348 // function: MakeConnexityBlock.
350 //=======================================================================
351 void BOPTools_AlgoTools::MakeConnexityBlock (BOPCol_ListOfShape& theLFIn,
352 BOPCol_IndexedMapOfShape& theMEAvoid,
353 BOPCol_ListOfShape& theLCB,
354 const Handle(NCollection_BaseAllocator)& theAllocator)
356 Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
357 TopExp_Explorer aExp;
358 BOPCol_ListIteratorOfListOfShape aIt;
360 BOPCol_IndexedMapOfShape aMCB(100, theAllocator);
361 BOPCol_IndexedMapOfShape aMAdd(100, theAllocator);
362 BOPCol_IndexedMapOfShape aMAdd1(100, theAllocator);
363 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator);
366 aNbF=theLFIn.Extent();
367 aIt.Initialize(theLFIn);
368 for (; aIt.More(); aIt.Next()) {
369 const TopoDS_Shape& aF=aIt.Value();
370 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
374 const TopoDS_Shape& aF1=theLFIn.First();
379 aNbAdd = aMAdd.Extent();
380 for (i=1; i<=aNbAdd; ++i) {
381 const TopoDS_Shape& aF=aMAdd(i);
384 aExp.Init(aF, TopAbs_EDGE);
385 for (; aExp.More(); aExp.Next()) {
386 const TopoDS_Shape& aE=aExp.Current();
387 if (theMEAvoid.Contains(aE)){
391 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
393 for (; aIt.More(); aIt.Next()) {
394 const TopoDS_Shape& aFx=aIt.Value();
395 if (aFx.IsSame(aF)) {
398 if (aMCB.Contains(aFx)) {
403 }//for (; aExp.More(); aExp.Next()){
405 }// for (i=1; i<=aNbAdd; ++i) {
407 aNbAdd1=aMAdd1.Extent();
413 for (i=1; i<=aNbAdd1; ++i) {
414 const TopoDS_Shape& aFAdd=aMAdd1(i);
422 for (i=1; i<=aNbF; ++i) {
423 const TopoDS_Shape& aF=aMCB(i);
427 //=======================================================================
428 // function: ComputeStateByOnePoint
430 //=======================================================================
431 TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint(const TopoDS_Shape& theS,
432 const TopoDS_Solid& theRef,
433 const Standard_Real theTol,
434 Handle(BOPInt_Context)& theContext)
437 TopAbs_ShapeEnum aType;
439 aState=TopAbs_UNKNOWN;
440 aType=theS.ShapeType();
441 if (aType==TopAbs_VERTEX) {
442 const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&theS));
443 aState=BOPTools_AlgoTools::ComputeState(aV, theRef, theTol, theContext);
445 else if (aType==TopAbs_EDGE) {
446 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&theS));
447 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
452 //=======================================================================
453 // function: ComputeState
455 //=======================================================================
456 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
457 const TopoDS_Solid& theRef,
458 const Standard_Real theTol,
459 BOPCol_IndexedMapOfShape& theBounds,
460 Handle(BOPInt_Context)& theContext)
463 TopExp_Explorer aExp;
468 aState=TopAbs_UNKNOWN;
470 aExp.Init(theF, TopAbs_EDGE);
471 for (; aExp.More(); aExp.Next()) {
472 const TopoDS_Edge& aSE=(*(TopoDS_Edge*)(&aExp.Current()));
473 if (BRep_Tool::Degenerated(aSE)) {
477 if (!theBounds.Contains(aSE)) {
478 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
479 aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
483 aE1=(*(TopoDS_Edge*)(&aSE));
486 // !!<- process edges that are all on theRef
488 BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, aP2D, aP3D, theContext);
489 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
494 //=======================================================================
495 // function: ComputeState
497 //=======================================================================
498 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Vertex& theV,
499 const TopoDS_Solid& theRef,
500 const Standard_Real theTol,
501 Handle(BOPInt_Context)& theContext)
506 aP3D=BRep_Tool::Pnt(theV);
507 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
510 //=======================================================================
511 // function: ComputeState
513 //=======================================================================
514 TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE,
515 const TopoDS_Solid& theRef,
516 const Standard_Real theTol,
517 Handle(BOPInt_Context)& theContext)
519 Standard_Real aT1, aT2, aT = 0.;
521 Handle(Geom_Curve) aC3D;
524 aC3D = BRep_Tool::Curve(theE, aT1, aT2);
527 //it means that we are in degenerated edge
528 const TopoDS_Vertex& aV = TopExp::FirstVertex(theE);
530 return TopAbs_UNKNOWN;
532 aP3D=BRep_Tool::Pnt(aV);
535 Standard_Boolean bF2Inf, bL2Inf;
536 Standard_Real dT=10.;
538 bF2Inf = Precision::IsNegativeInfinite(aT1);
539 bL2Inf = Precision::IsPositiveInfinite(aT2);
541 if (bF2Inf && !bL2Inf) {
544 else if (!bF2Inf && bL2Inf) {
547 else if (bF2Inf && bL2Inf) {
551 aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
556 aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
560 //=======================================================================
561 // function: ComputeState
563 //=======================================================================
564 TopAbs_State BOPTools_AlgoTools::ComputeState(const gp_Pnt& theP,
565 const TopoDS_Solid& theRef,
566 const Standard_Real theTol,
567 Handle(BOPInt_Context)& theContext)
571 BRepClass3d_SolidClassifier& aSC=theContext->SolidClassifier(theRef);
572 aSC.Perform(theP, theTol);
578 //=======================================================================
579 //function : IsInternalFace
581 //=======================================================================
582 Standard_Boolean BOPTools_AlgoTools::IsInternalFace(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 bRet, bDegenerated;
589 Standard_Integer aNbF;
590 TopAbs_Orientation aOr;
592 TopExp_Explorer aExp;
593 BOPCol_ListIteratorOfListOfShape aItF;
597 // 1 Try to find an edge from theFace in theMEF
598 aExp.Init(theFace, TopAbs_EDGE);
599 for(; aExp.More(); aExp.Next()) {
600 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
601 if (!theMEF.Contains(aE)) {
605 aOr=aE.Orientation();
606 if (aOr==TopAbs_INTERNAL) {
609 bDegenerated=BRep_Tool::Degenerated(aE);
614 BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
617 return bRet; // it can not be so
620 // aE is internal edge on aLF.First()
621 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
622 bRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1, theContext);
626 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
627 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
629 if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
630 // treat as it was for 1 face
631 bRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2, theContext);
636 return bRet; // it can not be so
638 else { // aNbF=2,4,6,8,...
639 bRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, theContext);
642 }//for(; aExp.More(); aExp.Next()) {
644 //========================================
645 // 2. Classify face using classifier
648 BOPCol_IndexedMapOfShape aBounds;
650 aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid, theTol, aBounds, theContext);
651 bRet=(aState==TopAbs_IN);
655 //=======================================================================
656 //function : IsInternalFace
658 //=======================================================================
659 Standard_Boolean BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace,
660 const TopoDS_Edge& theEdge,
661 BOPCol_ListOfShape& theLF,
662 Handle(BOPInt_Context)& theContext)
664 Standard_Boolean bRet;
665 Standard_Boolean aNbF;
671 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
672 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
673 bRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
678 BOPTools_ListOfCoupleOfShape aLCFF;
679 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
681 FindFacePairs(theEdge, theLF, aLCFF, theContext);
683 aIt.Initialize(aLCFF);
684 for (; aIt.More(); aIt.Next()) {
685 BOPTools_CoupleOfShape& aCSFF=aIt.ChangeValue();
687 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
688 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
689 bRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
697 //=======================================================================
698 //function : IsInternalFace
700 //=======================================================================
701 Standard_Boolean BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace,
702 const TopoDS_Edge& theEdge,
703 const TopoDS_Face& theFace1,
704 const TopoDS_Face& theFace2,
705 Handle(BOPInt_Context)& theContext)
707 Standard_Boolean bRet;
708 TopoDS_Edge aE1, aE2;
710 BOPTools_ListOfCoupleOfShape theLCSOff;
711 BOPTools_CoupleOfShape aCS1, aCS2;
713 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace1, aE1);
714 if (aE1.Orientation()==TopAbs_INTERNAL) {
716 aE1.Orientation(TopAbs_FORWARD);
717 aE2.Orientation(TopAbs_REVERSED);
719 else if (theFace1==theFace2) {
721 aE1.Orientation(TopAbs_FORWARD);
722 aE2.Orientation(TopAbs_REVERSED);
725 BOPTools_AlgoTools::GetEdgeOnFace(theEdge, theFace2, aE2);
728 aCS1.SetShape1(theEdge);
729 aCS1.SetShape2(theFace);
730 theLCSOff.Append(aCS1);
733 aCS2.SetShape2(theFace2);
734 theLCSOff.Append(aCS2);
736 GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext);
738 bRet = theFace.IsEqual(aFOff);
741 //=======================================================================
742 //function : GetFaceOff
744 //=======================================================================
745 void BOPTools_AlgoTools::GetFaceOff(const TopoDS_Edge& theE1,
746 const TopoDS_Face& theF1,
747 BOPTools_ListOfCoupleOfShape& theLCSOff,
748 TopoDS_Face& theFOff,
749 Handle(BOPInt_Context)& theContext)
751 Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
752 gp_Pnt aPn1, aPn2, aPx;
753 gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
755 TopAbs_Orientation aOr;
756 Handle(Geom_Curve)aC3D;
757 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
761 aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
762 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
765 BOPTools_AlgoTools2D::EdgeTangent(theE1, aT, aVTgt);
766 gp_Dir aDTgt(aVTgt), aDTgt2;
767 aOr = theE1.Orientation();
769 GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext);
773 aIt.Initialize(theLCSOff);
774 for (; aIt.More(); aIt.Next()) {
775 const BOPTools_CoupleOfShape& aCS=aIt.Value();
776 const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&aCS.Shape1()));
777 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
779 aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
780 GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext);
782 aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
785 aAngle=aTwoPI+aAngle;
788 if (aAngle<Precision::Angular()) {
792 else if (aF2.IsSame(theF1)) {
797 if (aAngle<aAngleMin){
803 //=======================================================================
804 //function : GetEdgeOff
806 //=======================================================================
807 Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
808 const TopoDS_Face& theF2,
811 Standard_Boolean bFound;
812 TopAbs_Orientation aOr1, aOr1C, aOr2;
813 TopExp_Explorer anExp;
815 bFound=Standard_False;
816 aOr1=theE1.Orientation();
817 aOr1C=TopAbs::Reverse(aOr1);
819 anExp.Init(theF2, TopAbs_EDGE);
820 for (; anExp.More(); anExp.Next()) {
821 const TopoDS_Edge& aEF2=(*(TopoDS_Edge*)(&anExp.Current()));
822 if (aEF2.IsSame(theE1)) {
823 aOr2=aEF2.Orientation();
834 //=======================================================================
835 //function : AreFacesSameDomain
837 //=======================================================================
838 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1,
839 const TopoDS_Face& theF2,
840 Handle(BOPInt_Context)& theContext)
842 Standard_Boolean bFlag;
844 Standard_Real aTolF1, aTolF2, aTol;
847 TopoDS_Face aF1, aF2;
849 TopExp_Explorer aExp;
851 bFlag=Standard_False;
854 aF1.Orientation(TopAbs_FORWARD);
856 aF2.Orientation(TopAbs_FORWARD);
858 aTolF1=BRep_Tool::Tolerance(aF1);
861 aExp.Init(aF1, TopAbs_EDGE);
862 for (; aExp.More(); aExp.Next()) {
863 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
864 if (!BRep_Tool::Degenerated(aE1)) {
867 Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
868 aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
876 aTolF2=BRep_Tool::Tolerance(aF2);
879 BOPTools_AlgoTools3D::PointNearEdge(aE1, aF1, aP2D, aP, theContext);
880 bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
885 //=======================================================================
886 //function : CheckSameGeom
888 //=======================================================================
889 Standard_Boolean BOPTools_AlgoTools::CheckSameGeom(const TopoDS_Face& theF1,
890 const TopoDS_Face& theF2,
891 Handle(BOPInt_Context)& theContext)
893 Standard_Boolean bRet;
894 Standard_Real aTolF1, aTolF2, aTol;
897 TopExp_Explorer aExp;
900 aExp.Init(theF1, TopAbs_EDGE);
901 for (; aExp.More(); aExp.Next()) {
902 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
903 if (!BRep_Tool::Degenerated(aE)) {
904 aTolF1=BRep_Tool::Tolerance(theF1);
905 aTolF2=BRep_Tool::Tolerance(theF2);
907 BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
908 bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
914 //=======================================================================
917 //=======================================================================
918 Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
919 const TopoDS_Face& theF2)
921 Standard_Integer iSense=0;
923 TopoDS_Edge aE1, aE2;
924 TopExp_Explorer aExp;
926 aExp.Init(theF1, TopAbs_EDGE);
927 for (; aExp.More(); aExp.Next()) {
928 aE1=(*(TopoDS_Edge*)(&aExp.Current()));
929 if (!BRep_Tool::Degenerated(aE1)) {
930 if (!BRep_Tool::IsClosed(aE1, theF1)) {
936 aExp.Init(theF2, TopAbs_EDGE);
937 for (; aExp.More(); aExp.Next()) {
938 aE2=(*(TopoDS_Edge*)(&aExp.Current()));
939 if (!BRep_Tool::Degenerated(aE2)) {
940 if (!BRep_Tool::IsClosed(aE2, theF2)) {
941 if (aE2.IsSame(aE1)) {
953 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE1, theF1, aDNF1);
954 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE2, theF2, aDNF2);
956 iSense=BOPTools_AlgoTools3D::SenseFlag(aDNF1, aDNF2);
960 //=======================================================================
961 // function: IsSplitToReverse
963 //=======================================================================
964 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Shape& theSp,
965 const TopoDS_Shape& theSr,
966 Handle(BOPInt_Context)& theContext)
968 Standard_Boolean bRet;
969 TopAbs_ShapeEnum aType;
973 aType=theSp.ShapeType();
976 const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
977 const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
978 bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
983 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
984 const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
985 bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
994 //=======================================================================
995 //function :IsSplitToReverse
997 //=======================================================================
998 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
999 const TopoDS_Face& theFSr,
1000 Handle(BOPInt_Context)& theContext)
1002 Standard_Boolean bRet, bFound, bInFace;
1003 Standard_Real aT1, aT2, aT, aU, aV, aScPr;
1004 gp_Pnt aPFSp, aPFSr;
1007 Handle(Geom_Surface) aSr, aSp;
1008 TopAbs_Orientation aOrSr, aOrSp;
1009 TopExp_Explorer anExp;
1012 bRet=Standard_False;
1014 aSr=BRep_Tool::Surface(theFSr);
1015 aSp=BRep_Tool::Surface(theFSp);
1017 aOrSr=theFSr.Orientation();
1018 aOrSp=theFSp.Orientation();
1019 bRet=(aOrSr!=aOrSp);
1023 bFound=Standard_False;
1024 anExp.Init(theFSp, TopAbs_EDGE);
1025 for (; anExp.More(); anExp.Next()) {
1026 aESp=(*(TopoDS_Edge*)(&anExp.Current()));
1027 if (!BRep_Tool::Degenerated(aESp)) {
1028 if (!BRep_Tool::IsClosed(aESp, theFSp)) {
1035 Standard_Boolean bFlag;
1036 Standard_Integer iErr;
1039 iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp, theContext);
1044 aP2DFSp.Coord(aU, aV);
1045 bFlag=BOPTools_AlgoTools3D::GetNormalToSurface(aSp, aU, aV, aDNFSp);
1051 BRep_Tool::Range(aESp, aT1, aT2);
1052 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
1053 BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp, theContext);
1056 // Parts of theContext->ComputeVS(..)
1057 GeomAPI_ProjectPointOnSurf& aProjector=theContext->ProjPS(theFSr);
1058 aProjector.Perform(aPFSp);
1059 if (!aProjector.IsDone()) {
1063 aProjector.LowerDistanceParameters(aU, aV);
1064 gp_Pnt2d aP2D(aU, aV);
1065 bInFace=theContext->IsPointInFace (theFSr, aP2D);
1070 aSr->D1(aU, aV, aPFSr, aD1U, aD1V);
1073 gp_Dir aDNFSr=aDD1U^aDD1V;
1074 if (theFSr.Orientation()==TopAbs_REVERSED){
1078 aScPr=aDNFSp*aDNFSr;
1083 //=======================================================================
1084 //function :IsSplitToReverse
1086 //=======================================================================
1087 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Edge& aEF1,
1088 const TopoDS_Edge& aEF2,
1089 Handle(BOPInt_Context)& theContext)
1091 Standard_Boolean bRet, bIsDegenerated;
1093 bRet=Standard_False;
1094 bIsDegenerated=(BRep_Tool::Degenerated(aEF1) ||
1095 BRep_Tool::Degenerated(aEF2));
1096 if (bIsDegenerated) {
1101 TopAbs_Orientation aOrE, aOrSp;
1102 Handle(Geom_Curve)aC1, aC2;
1104 aC2=BRep_Tool::Curve(aEF2, a, b);
1105 aC1=BRep_Tool::Curve(aEF1, a, b);
1108 aOrE=aEF2.Orientation();
1109 aOrSp=aEF1.Orientation();
1114 Standard_Real aT1, aT2, aScPr;
1118 aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
1120 BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
1123 theContext->ProjectPointOnEdge(aP, aEF2, aT2);
1125 BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
1134 //=======================================================================
1137 //=======================================================================
1138 Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
1139 const TopoDS_Shape& aFace)
1141 Standard_Boolean bIsHole;
1142 Standard_Integer i, aNbS;
1143 Standard_Real aT1, aT2, aS;
1144 Standard_Real aU1, aU2, aU, dU;
1145 Standard_Real aX1, aY1, aX0, aY0;
1146 TopAbs_Orientation aOr;
1148 gp_Pnt2d aP2D0, aP2D1;
1149 Handle(Geom2d_Curve) aC2D;
1150 TopoDS_Face aF, aFF;
1151 TopoDS_Iterator aItW;
1153 bIsHole=Standard_False;
1155 aF=(*(TopoDS_Face *)(&aFace));
1157 aFF.Orientation(TopAbs_FORWARD);
1160 aItW.Initialize(aW);
1161 for (; aItW.More(); aItW.Next()) {
1162 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aItW.Value()));
1163 aOr=aE.Orientation();
1164 if (!(aOr==TopAbs_FORWARD ||
1165 aOr==TopAbs_REVERSED)) {
1169 aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
1170 if (aC2D.IsNull()) {
1174 BRepAdaptor_Curve2d aBAC2D(aE, aFF);
1175 aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
1180 dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
1184 if (aOr==TopAbs_REVERSED) {
1191 aC2D->D0(aU, aP2D0);
1192 for(i=2; i<=aNbS; i++) {
1194 aC2D->D0(aU, aP2D1);
1195 aP2D0.Coord(aX0, aY0);
1196 aP2D1.Coord(aX1, aY1);
1198 aS=aS+(aY0+aY1)*(aX1-aX0);
1202 }//for (; aItW.More(); aItW.Next()) {
1207 //=======================================================================
1208 // function: MakeContainer
1210 //=======================================================================
1211 void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
1217 case TopAbs_COMPOUND:{
1219 aBB.MakeCompound(aC);
1224 case TopAbs_COMPSOLID:{
1225 TopoDS_CompSolid aCS;
1226 aBB.MakeCompSolid(aCS);
1232 TopoDS_Solid aSolid;
1233 aBB.MakeSolid(aSolid);
1240 TopoDS_Shell aShell;
1241 aBB.MakeShell(aShell);
1248 aBB.MakeWire(aWire);
1257 //=======================================================================
1258 // function: MakePCurve
1260 //=======================================================================
1261 void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
1262 const TopoDS_Face& aF1,
1263 const TopoDS_Face& aF2,
1264 const IntTools_Curve& aIC,
1265 const Standard_Boolean bPC1,
1266 const Standard_Boolean bPC2)
1270 Standard_Real aTolE, aT1, aT2, aOutFirst, aOutLast, aOutTol;
1271 Handle(Geom2d_Curve) aC2D, aC2DA, aC2Dx1;
1274 Standard_Boolean bPC;
1276 aTolE=BRep_Tool::Tolerance(aE);
1278 const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
1279 Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aT1, aT2);
1281 for (i=0; i<2; ++i) {
1282 bPC = !i ? bPC1 : bPC2;
1289 aC2Dx1=aIC.FirstCurve2d();
1293 aC2Dx1=aIC.SecondCurve2d();
1296 aFFWD.Orientation(TopAbs_FORWARD);
1299 if (aC2D.IsNull()) {
1300 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aFFWD);
1301 BOPTools_AlgoTools2D::CurveOnSurface(aE, aFFWD, aC2D,
1302 aOutFirst, aOutLast,
1306 if (aC3DE->IsPeriodic()) {
1307 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2, aC2D, aC2DA);
1310 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA);
1313 aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
1314 //BRepLib::SameParameter(aE);
1316 BRepLib::SameParameter(aE);
1318 //=======================================================================
1319 // function: MakeEdge
1321 //=======================================================================
1322 void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
1323 const TopoDS_Vertex& theV1,
1324 const Standard_Real theT1,
1325 const TopoDS_Vertex& theV2,
1326 const Standard_Real theT2,
1327 const Standard_Real theTolR3D,
1330 Standard_Real aTolV;
1333 BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2, theE);
1335 aBB.UpdateEdge(theE, theTolR3D);
1337 aTolV=BRep_Tool::Tolerance(theV1);
1338 if (aTolV<theTolR3D) {
1339 aBB.UpdateVertex(theV1, theTolR3D);
1342 aTolV=BRep_Tool::Tolerance(theV2);
1343 if (aTolV<theTolR3D) {
1344 aBB.UpdateVertex(theV2, theTolR3D);
1347 //=======================================================================
1348 // function: ComputeVV
1350 //=======================================================================
1351 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1353 const Standard_Real aTolP2)
1355 Standard_Real aTolV1, aTolSum, aTolSum2, aD2;
1358 aTolV1=BRep_Tool::Tolerance(aV1);
1360 aTolSum=aTolV1+aTolP2;
1361 aTolSum2=aTolSum*aTolSum;
1363 aP1=BRep_Tool::Pnt(aV1);
1365 aD2=aP1.SquareDistance(aP2);
1371 //=======================================================================
1372 // function: ComputeVV
1374 //=======================================================================
1375 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
1376 const TopoDS_Vertex& aV2)
1378 Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
1381 aTolV1=BRep_Tool::Tolerance(aV1);
1382 aTolV2=BRep_Tool::Tolerance(aV2);
1383 aTolSum=aTolV1+aTolV2;
1384 aTolSum2=aTolSum*aTolSum;
1386 aP1=BRep_Tool::Pnt(aV1);
1387 aP2=BRep_Tool::Pnt(aV2);
1389 aD2=aP1.SquareDistance(aP2);
1395 //=======================================================================
1396 // function: MakeVertex
1398 //=======================================================================
1399 void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
1400 TopoDS_Vertex& aVnew)
1402 Standard_Integer aNb;
1403 Standard_Real aTi, aDi, aDmax;
1405 gp_XYZ aXYZ(0.,0.,0.), aXYZi;
1406 BOPCol_ListIteratorOfListOfShape aIt;
1410 aIt.Initialize(aLV);
1411 for (; aIt.More(); aIt.Next()) {
1412 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1413 aPi=BRep_Tool::Pnt(aVi);
1418 aXYZ.Divide((Standard_Real)aNb);
1422 aIt.Initialize(aLV);
1423 for (; aIt.More(); aIt.Next()) {
1424 TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
1425 aPi=BRep_Tool::Pnt(aVi);
1426 aTi=BRep_Tool::Tolerance(aVi);
1427 aDi=aP.SquareDistance(aPi);
1436 aBB.MakeVertex (aVnew, aP, aDmax);
1439 //=======================================================================
1440 //function : GetEdgeOnFace
1442 //=======================================================================
1443 Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace(const TopoDS_Edge& theE1,
1444 const TopoDS_Face& theF2,
1447 Standard_Boolean bFound;
1448 TopoDS_Iterator aItF, aItW;
1450 bFound=Standard_False;
1452 aItF.Initialize(theF2);
1453 for (; aItF.More(); aItF.Next()) {
1454 const TopoDS_Shape& aW=aItF.Value();
1455 aItW.Initialize(aW);
1456 for (; aItW.More(); aItW.Next()) {
1457 const TopoDS_Shape& aE=aItW.Value();
1458 if (aE.IsSame(theE1)) {
1459 theE2=(*(TopoDS_Edge*)(&aE));
1467 //=======================================================================
1468 //function : FindFacePairs
1470 //=======================================================================
1471 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
1472 const BOPCol_ListOfShape& thLF,
1473 BOPTools_ListOfCoupleOfShape& theLCFF,
1474 Handle(BOPInt_Context)& theContext)
1476 Standard_Boolean bFound;
1477 Standard_Integer i, aNbCEF;
1478 TopAbs_Orientation aOr, aOrC;
1479 BOPCol_MapOfShape aMFP;
1480 TopoDS_Face aF1, aF2;
1481 TopoDS_Edge aEL, aE1;
1482 BOPCol_ListIteratorOfListOfShape aItLF;
1483 BOPTools_CoupleOfShape aCEF, aCFF;
1484 BOPTools_ListOfCoupleOfShape aLCEF, aLCEFx;
1485 BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
1487 bFound=Standard_True;
1490 aItLF.Initialize(thLF);
1491 for (; aItLF.More(); aItLF.Next()) {
1492 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
1494 bFound=BOPTools_AlgoTools::GetEdgeOnFace(theE, aFL, aEL);
1496 return bFound; // it can not be so
1499 aCEF.SetShape1(aEL);
1500 aCEF.SetShape2(aFL);
1504 aNbCEF=aLCEF.Extent();
1509 aIt.Initialize(aLCEF);
1510 for (i=0; aIt.More(); aIt.Next(), ++i) {
1511 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1512 const TopoDS_Shape& aEx=aCSx.Shape1();
1513 const TopoDS_Shape& aFx=aCSx.Shape2();
1515 aOr=aEx.Orientation();
1518 aOrC=TopAbs::Reverse(aOr);
1519 aE1=(*(TopoDS_Edge*)(&aEx));
1520 aF1=(*(TopoDS_Face*)(&aFx));
1526 aLCEFx.Append(aCSx);
1532 BOPTools_AlgoTools::GetFaceOff(aE1, aF1, aLCEFx, aF2, theContext);
1534 aCFF.SetShape1(aF1);
1535 aCFF.SetShape2(aF2);
1536 theLCFF.Append(aCFF);
1545 aIt.Initialize(aLCEFx);
1546 for (; aIt.More(); aIt.Next()) {
1547 const BOPTools_CoupleOfShape& aCSx=aIt.Value();
1548 const TopoDS_Shape& aFx=aCSx.Shape2();
1549 if (!aMFP.Contains(aFx)) {
1554 aNbCEF=aLCEF.Extent();
1559 //=======================================================================
1560 //function : AngleWithRef
1562 //=======================================================================
1563 Standard_Real AngleWithRef(const gp_Dir& theD1,
1564 const gp_Dir& theD2,
1565 const gp_Dir& theDRef)
1567 Standard_Real aCosinus, aSinus, aBeta, aHalfPI, aScPr;
1572 const gp_XYZ& aXYZ1=theD1.XYZ();
1573 const gp_XYZ& aXYZ2=theD2.XYZ();
1574 aXYZ=aXYZ1.Crossed(aXYZ2);
1575 aSinus=aXYZ.Modulus();
1576 aCosinus=theD1*theD2;
1580 aBeta=aHalfPI*(1.-aCosinus);
1583 aBeta=2.*M_PI-aHalfPI*(3.+aCosinus);
1586 aScPr=aXYZ.Dot(theDRef.XYZ());
1592 //=======================================================================
1595 //=======================================================================
1596 Standard_Real fsqrt(Standard_Real val)
1604 u.tmp -= 1<<23; /* Remove last bit so 1.0 gives 1.0 */
1605 /* tmp is now an approximation to logbase2(val) */
1606 u.tmp >>= 1; /* divide by 2 */
1607 u.tmp += 1<<29; /* add 64 to exponent: (e+127)/2 =(e/2)+63, */
1608 /* that represents (e/2)-64 but we want e/2 */
1609 return (double)u.val;
1612 //=======================================================================
1613 // function: IsBlockInOnFace
1615 //=======================================================================
1616 Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShrR,
1617 const TopoDS_Face& aF,
1618 const TopoDS_Edge& aE1,
1619 Handle(BOPInt_Context)& aContext)
1621 Standard_Boolean bFlag;
1622 Standard_Real f1, l1, ULD, VLD;
1626 aShrR.Range(f1, l1);
1627 Standard_Real dt=0.0075, k;//dt=0.001, k;
1633 BOPTools_AlgoTools::PointOnEdge(aE1, f1, aP11);
1635 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
1636 aProjector.Perform(aP11);
1638 bFlag=aProjector.IsDone();
1643 aProjector.LowerDistanceParameters(ULD, VLD);
1644 aP2D.SetCoord(ULD, VLD);
1646 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1653 BOPTools_AlgoTools::PointOnEdge(aE1, l1, aP12);
1655 aProjector.Perform(aP12);
1657 bFlag=aProjector.IsDone();
1662 aProjector.LowerDistanceParameters(ULD, VLD);
1663 aP2D.SetCoord(ULD, VLD);
1665 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1671 // Treatment intemediate
1672 Standard_Real m1, aTolF, aTolE, aTol, aDist;
1673 m1=IntTools_Tools::IntermediatePoint(f1, l1);
1674 BOPTools_AlgoTools::PointOnEdge(aE1, m1, aP12);
1676 aProjector.Perform(aP12);
1678 bFlag=aProjector.IsDone();
1683 aTolE=BRep_Tool::Tolerance(aE1);
1684 aTolF=BRep_Tool::Tolerance(aF);
1686 aDist=aProjector.LowerDistance();
1688 return Standard_False;
1691 aProjector.LowerDistanceParameters(ULD, VLD);
1692 aP2D.SetCoord(ULD, VLD);
1694 bFlag=aContext->IsPointInOnFace (aF, aP2D);
1702 //=======================================================================
1703 //function : IsMicroEdge
1705 //=======================================================================
1706 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge(const TopoDS_Edge& aE,
1707 const Handle(BOPInt_Context)& aCtx)
1709 Standard_Boolean bRet;
1710 Standard_Integer iErr;
1711 Standard_Real aT1, aT2, aTmp;
1712 Handle(Geom_Curve) aC3D;
1713 TopoDS_Vertex aV1, aV2;
1715 bRet=(BRep_Tool::Degenerated(aE) ||
1716 !BRep_Tool::IsGeometric(aE));
1721 aC3D=BRep_Tool::Curve(aE, aT1, aT2);
1722 TopExp::Vertices(aE, aV1, aV2);
1723 aT1=BRep_Tool::Parameter(aV1, aE);
1724 aT2=BRep_Tool::Parameter(aV2, aE);
1731 BOPInt_ShrunkRange aSR;
1732 aSR.SetData(aE, aT1, aT2, aV1, aV2, aCtx);
1734 iErr=aSR.ErrorStatus();
1740 //=======================================================================
1741 //function : GetFaceDir
1742 //purpose : Get binormal direction for the face in the point aP
1743 //=======================================================================
1744 void GetFaceDir(const TopoDS_Edge& aE,
1745 const TopoDS_Face& aF,
1747 const Standard_Real aT,
1748 const gp_Dir& aDTgt,
1751 Handle(BOPInt_Context)& theContext)
1753 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
1754 if (aF.Orientation()==TopAbs_REVERSED){
1759 Handle(Geom_Surface) aS = BRep_Tool::Surface(aF);
1760 GeomAdaptor_Surface aGAS(aS);
1761 if (aGAS.GetType()!=GeomAbs_Plane) {
1763 if (!FindPointInFace(aE, aF, aP, aT, aDB, aPx, theContext, aGAS)) {
1765 Handle(Geom_Plane) aPL;
1766 GeomAPI_ProjectPointOnSurf aProj;
1768 BOPTools_AlgoTools3D::PointNearEdge(aE, aF, aT, aPx2D, aPx, theContext);
1769 aPL = new Geom_Plane(aP, aDTgt);
1770 aProj.Init(aPx, aPL);
1771 aPx = aProj.NearestPoint();
1772 gp_Vec aVec(aP, aPx);
1773 aDB.SetXYZ(aVec.XYZ());
1778 //=======================================================================
1779 //function : FindPointInFace
1780 //purpose : Find a point in the face in direction of <aDB>
1781 //=======================================================================
1782 Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
1783 const TopoDS_Face& aF,
1785 const Standard_Real aT,
1788 Handle(BOPInt_Context)& theContext,
1789 const GeomAdaptor_Surface& aGAS)
1791 Standard_Integer aNbItMax;
1792 Standard_Real aDt, aDtMin, aTolE, aTolF, aDist;
1793 Standard_Boolean bRet;
1796 bRet = Standard_False;
1797 aTolE = BRep_Tool::Tolerance(aE);
1798 aTolF = BRep_Tool::Tolerance(aF);
1799 aDt = 2*(aTolE+aTolF);
1804 GeomAbs_SurfaceType aSType=aGAS.GetType();
1806 case GeomAbs_Cylinder:
1807 aR = aGAS.Cylinder().Radius();
1810 aR = aGAS.Cone().RefRadius();
1812 case GeomAbs_Sphere:
1813 aR = aGAS.Sphere().Radius();
1816 aR = aGAS.Torus().MinorRadius();
1818 case GeomAbs_SurfaceOfRevolution:
1827 else if (aR > 100.) {
1835 GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
1839 aP1.SetCoord(aP.X()+aDt*aDB.X(),
1841 aP.Z()+aDt*aDB.Z());
1844 if (!aProj.IsDone()) {
1847 aPOut = aProj.NearestPoint();
1848 aDist = aProj.LowerDistance();
1850 gp_Vec aV(aP, aPOut);
1851 aDB.SetXYZ(aV.XYZ());
1852 } while (aDist>Precision::Angular() && --aNbItMax);
1854 bRet = aDist < Precision::Angular();