1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <BOPAlgo_WireSplitter.ixx>
17 #include <Precision.hxx>
19 #include <gp_Pnt2d.hxx>
20 #include <gp_Vec2d.hxx>
21 #include <gp_Dir2d.hxx>
22 #include <Geom2d_Curve.hxx>
23 #include <GeomAdaptor_Surface.hxx>
25 #include <TopoDS_Edge.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopoDS_Wire.hxx>
28 #include <TopoDS_Iterator.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRepAdaptor_Surface.hxx>
32 #include <BOPCol_ListOfShape.hxx>
33 #include <BOPCol_SequenceOfShape.hxx>
34 #include <BOPCol_SequenceOfPnt2d.hxx>
35 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_Plane.hxx>
39 #include <Geom_RectangularTrimmedSurface.hxx>
40 #include <Geom_RectangularTrimmedSurface.hxx>
41 #include <BOPTools_AlgoTools2D.hxx>
42 #include <TopLoc_Location.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BOPCol_SequenceOfReal.hxx>
46 #include <TopExp_Explorer.hxx>
47 #include <BOPTools_AlgoTools2D.hxx>
48 #include <Geom2dAdaptor_Curve.hxx>
52 Standard_Real Angle (const gp_Dir2d& aDir2D);
55 Standard_Real Angle2D (const TopoDS_Vertex& aV,
56 const TopoDS_Edge& anEdge,
57 const TopoDS_Face& myFace,
58 const GeomAdaptor_Surface& aGAS,
59 const Standard_Boolean aFlag);
62 void GetNextVertex(const TopoDS_Vertex& aV,
63 const TopoDS_Edge& aE,
67 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
68 const BOPAlgo_ListOfEdgeInfo& aLEInfo);
71 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo);
74 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
75 const TopoDS_Face& aF);
78 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
79 const TopoDS_Edge& aE1,
80 const TopoDS_Face& aF);
84 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
85 const Standard_Real aAngleOut);
88 void Path (const GeomAdaptor_Surface& aGAS,
89 const TopoDS_Face& myFace,
90 const TopoDS_Vertex& aVa,
91 const TopoDS_Edge& aEOuta,
92 BOPAlgo_EdgeInfo& anEdgeInfo,
93 BOPCol_SequenceOfShape& aLS,
94 BOPCol_SequenceOfShape& aVertVa,
95 BOPCol_SequenceOfPnt2d& aCoordVa,
96 BOPTools_ConnexityBlock& aCB,
97 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap);
100 Standard_Real Angle2D (const TopoDS_Vertex& aV,
101 const TopoDS_Edge& anEdge,
102 const TopoDS_Face& myFace,
103 const GeomAdaptor_Surface& aGAS,
104 const Standard_Boolean aFlag);
106 Standard_Real Angle (const gp_Dir2d& aDir2D);
109 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
110 const GeomAdaptor_Surface& aGAS);
115 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
116 const GeomAdaptor_Surface& aGAS);
118 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
119 const GeomAdaptor_Surface& aGAS);
122 Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo,
123 const TopoDS_Face& theFace,
124 const gp_Pnt2d& thePb,
125 const TopoDS_Vertex& theVb,
126 const GeomAdaptor_Surface& theGAS,
127 const TopoDS_Edge& theEOuta,
128 const Standard_Boolean& bHasClosed,
129 const Standard_Real& theTol2D,
130 BOPCol_SequenceOfReal& theRecomputedAngles);
132 //=======================================================================
133 //function : SplitBlock
135 //=======================================================================
136 void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
137 BOPTools_ConnexityBlock& aCB)
139 Standard_Boolean bNothingToDo;
140 Standard_Integer aIx, aNb, i, aCntIn, aCntOut;
141 Standard_Real aAngle;
142 TopAbs_Orientation aOr;
143 TopoDS_Iterator aItS;
145 BOPCol_ListIteratorOfListOfShape aIt;
146 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
148 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100);
150 const BOPCol_ListOfShape& myEdges=aCB.Shapes();
152 // 1.Filling mySmartMap
153 BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(myEdges, myFace);
155 aIt.Initialize(myEdges);
156 for(; aIt.More(); aIt.Next()) {
157 const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
158 if (!BOPTools_AlgoTools2D::HasCurveOnSurface (aE, myFace)) {
163 for(; aItS.More(); aItS.Next()) {
164 const TopoDS_Shape& aV=aItS.Value();
165 aIx=mySmartMap.FindIndex(aV);
167 BOPAlgo_ListOfEdgeInfo aLEIx;
168 aIx=mySmartMap.Add(aV, aLEIx);
171 BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(aIx);
173 BOPAlgo_EdgeInfo aEI;
176 aOr=aV.Orientation();
177 if (aOr==TopAbs_FORWARD) {
178 aEI.SetInFlag(Standard_False);
180 else if (aOr==TopAbs_REVERSED) {
181 aEI.SetInFlag(Standard_True);
187 aNb=mySmartMap.Extent();
189 bNothingToDo=Standard_True;
190 for (i=1; i<=aNb; i++) {
193 const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
194 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
195 for (; anIt.More(); anIt.Next()) {
196 const BOPAlgo_EdgeInfo& aEI=anIt.Value();
204 if (aCntIn!=1 || aCntOut!=1) {
205 bNothingToDo=Standard_False;
210 // Each vertex has one edge In and one - Out. Good. But it is not enought
211 // to consider that nothing to do with this. We must check edges on TShape
212 // coinsidence. If there are such edges there is something to do with.
214 Standard_Integer aNbE, aNbMapEE;
215 Standard_Boolean bFlag;
217 BOPCol_IndexedDataMapOfShapeListOfShape aMapEE(100);
218 aNbE=myEdges.Extent();
220 aIt.Initialize(myEdges);
221 for (; aIt.More(); aIt.Next()) {
222 const TopoDS_Shape& aE = aIt.Value();
223 if (!aMapEE.Contains(aE)) {
224 BOPCol_ListOfShape aLEx;
226 aMapEE.Add(aE, aLEx);
229 BOPCol_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
235 aNbMapEE=aMapEE.Extent();
236 for (i=1; i<=aNbMapEE; ++i) {
237 const BOPCol_ListOfShape& aLEx=aMapEE(i);
239 if (aNbE==1) {// usual case
243 const TopoDS_Shape& aE1=aLEx.First();
244 const TopoDS_Shape& aE2=aLEx.Last();
245 if (aE1.IsSame(aE2)) {
246 bFlag=Standard_False;
251 bFlag=Standard_False;
255 bNothingToDo=bNothingToDo && bFlag;
256 } // if (bNothingToDo) {
260 BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
261 BOPAlgo_WireSplitter::MakeWire(aLECB, aW);
262 BOPCol_ListOfShape& aLoops=aCB.ChangeLoops();
268 // 3. Angles in mySmartMap
269 BRepAdaptor_Surface aBAS(myFace);
270 const GeomAdaptor_Surface& aGAS=aBAS.Surface();
272 for (i=1; i<=aNb; i++) {
273 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
274 const BOPAlgo_ListOfEdgeInfo& aLEI= mySmartMap(i);
276 aItLEI.Initialize(aLEI);
277 for (; aItLEI.More(); aItLEI.Next()) {
278 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
279 const TopoDS_Edge& aE=aEI.Edge();
283 aVV.Orientation(TopAbs_REVERSED);
284 aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True);
287 aVV.Orientation(TopAbs_FORWARD);
288 aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False);
290 aEI.SetAngle(aAngle);
292 }// for (i=1; i<=aNb; i++) {
296 Standard_Boolean bIsOut, bIsNotPassed;
297 BOPCol_SequenceOfShape aLS, aVertVa;
298 BOPCol_SequenceOfPnt2d aCoordVa;
300 for (i=1; i<=aNb; ++i) {
301 const TopoDS_Vertex& aVa=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
302 const BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
303 aItLEI.Initialize(aLEI);
304 for (; aItLEI.More(); aItLEI.Next()) {
305 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
306 const TopoDS_Edge& aEOuta=aEI.Edge();
309 bIsNotPassed=!aEI.Passed();
310 if (bIsOut && bIsNotPassed) {
316 Path(aGAS, myFace, aVa, aEOuta, aEI, aLS,
317 aVertVa, aCoordVa, aCB, mySmartMap);
320 }// for (i=1; i<=aNb; ++i) {
322 //=======================================================================
325 //=======================================================================
326 void Path (const GeomAdaptor_Surface& aGAS,
327 const TopoDS_Face& myFace,
328 const TopoDS_Vertex& aVFirst,
329 const TopoDS_Edge& aEFirst,
330 BOPAlgo_EdgeInfo& aEIFirst,
331 BOPCol_SequenceOfShape& aLS,
332 BOPCol_SequenceOfShape& aVertVa,
333 BOPCol_SequenceOfPnt2d& aCoordVa,
334 BOPTools_ConnexityBlock& aCB,
335 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
338 Standard_Integer i, j, aNb, aNbj;
339 Standard_Real aTol, anAngleIn, anAngleOut, anAngle, aMinAngle;
340 Standard_Real aTol2D, aTol2D2;
341 Standard_Real aTol2, aD2, aTwoPI;
342 Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
343 TopoDS_Vertex aVa, aVb;
345 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
349 BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
351 aTwoPI = M_PI + M_PI;
357 // Do not escape through edge from which you enter
360 const TopoDS_Shape& anEPrev=aLS(aNb);
361 if (anEPrev.IsSame(aEOuta)) {
366 anEdgeInfo->SetPassed(Standard_True);
370 TopoDS_Vertex pVa=aVa;
371 pVa.Orientation(TopAbs_FORWARD);
372 gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
373 aCoordVa.Append(aPa);
375 GetNextVertex (pVa, aEOuta, aVb);
377 gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
379 const BOPAlgo_ListOfEdgeInfo& aLEInfoVb=mySmartMap.FindFromKey(aVb);
381 aTol=2.*Tolerance2D(aVb, aGAS);
384 TopoDS_Vertex aV1, aV2;
385 TopExp::Vertices(aEOuta, aV1, aV2);
386 Standard_Boolean bIsClosedEdge = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
387 Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aEOuta);
388 Standard_Boolean bIsSeam = BRep_Tool::IsClosed(aEOuta, myFace);
390 anIt.Initialize(aLEInfoVb);
391 for (; anIt.More(); anIt.Next()) {
392 const BOPAlgo_EdgeInfo& anEI = anIt.Value();
393 const TopoDS_Edge& aE = anEI.Edge();
394 bIsDegenerated = bIsDegenerated || BRep_Tool::Degenerated(aE);
395 bIsSeam = bIsSeam || BRep_Tool::IsClosed(aE, myFace);
398 TopExp::Vertices(aE, aV1, aV2);
399 bIsClosedEdge = bIsClosedEdge || aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
405 BOPCol_ListOfShape aBuf;
407 for (i=aNb; i>0; --i) {
408 const TopoDS_Shape& aVPrev=aVertVa(i);
409 const gp_Pnt2d& aPaPrev=aCoordVa(i);
410 const TopoDS_Shape& aEPrev=aLS(i);
414 anIsSameV=aVPrev.IsSame(aVb);
415 anIsSameV2d=Standard_False;
418 anIsSameV2d = Standard_True;
420 aD2=aPaPrev.SquareDistance(aPb);
421 anIsSameV2d =aD2<aTol2;
423 (bIsDegenerated || bIsSeam || bIsClosedEdge)) {
424 Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
425 Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
426 Standard_Real aTolU = 2. * UTolerance2D(aVb, aGAS);
427 Standard_Real aTolV = 2. * VTolerance2D(aVb, aGAS);
429 if((udist > aTolU) ||
431 anIsSameV2d = Standard_False;
436 if (anIsSameV && anIsSameV2d) {
437 Standard_Integer iPriz;
439 if (aBuf.Extent()==2) {
440 if(aBuf.First().IsSame(aBuf.Last())) {
446 BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
447 aCB.ChangeLoops().Append(aW);
460 BOPCol_SequenceOfShape aLSt, aVertVat;
461 BOPCol_SequenceOfPnt2d aCoordVat;
463 aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
465 for (j=1; j<=aNbj; ++j) {
467 aVertVat.Append(aVertVa(j));
468 aCoordVat.Append(aCoordVa(j));
484 aTol2D=2.*Tolerance2D(aVb, aGAS);
485 aTol2D2=1000.*aTol2D*aTol2D;//100.*aTol2D*aTol2D;
487 // anAngleIn in Vb from edge aEOuta
488 const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
490 anAngleIn=AngleIn(aEOuta, aLEInfo);
491 BOPCol_SequenceOfReal aRecomputedAngles;
493 Standard_Boolean bRecomputeAngle =
494 RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta,
495 (bIsDegenerated || bIsSeam || bIsClosedEdge),
496 aTol2D, aRecomputedAngles);
500 BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
503 anIsFound=Standard_False;
504 Standard_Integer aCurIndexE = 0;
505 anIt.Initialize(aLEInfo);
506 for (; anIt.More(); anIt.Next()) {
507 BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
508 const TopoDS_Edge& aE=anEI.Edge();
509 anIsOut=!anEI.IsIn();
510 anIsNotPassed=!anEI.Passed();
512 if (anIsOut && anIsNotPassed) {
515 // Is there one way to go out of the vertex
516 // we have to use it only.
517 Standard_Integer iCnt;
518 iCnt=NbWaysOut (aLEInfo);
521 // no way to go . (Error)
526 // the one and only way to go out .
528 anIsFound=Standard_True;
532 if (aE.IsSame(aEOuta)) {
535 // Look for minimal angle and make the choice.
538 aP2Dx=Coord2dVf(aE, myFace);
540 aD2=aP2Dx.SquareDistance(aPb);
546 anAngleOut=anEI.Angle();
548 if(bRecomputeAngle) {
549 if(aCurIndexE <= aRecomputedAngles.Length()) {
550 anAngleOut = aRecomputedAngles.Value(aCurIndexE);
553 anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
555 if (anAngle < aMinAngle) {
558 anIsFound=Standard_True;
561 } // for (; anIt.More(); anIt.Next())
564 // no way to go . (Error)
569 aEOuta = pEdgeInfo->Edge();
570 anEdgeInfo = pEdgeInfo;
573 //=======================================================================
574 // function: ClockWiseAngle
576 //=======================================================================
577 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
578 const Standard_Real aAngleOut)
580 Standard_Real aTwoPi=M_PI+M_PI;
581 Standard_Real dA, A1, A2, AIn, AOut ;
589 if (AOut >= aTwoPi) {
606 //else if (dA <= 1.e-15) {
607 else if (dA <= 1.e-14) {
612 //=======================================================================
615 //=======================================================================
616 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
617 const TopoDS_Edge& aE1,
618 const TopoDS_Face& aF)
620 Standard_Real aT, aFirst, aLast;
621 Handle(Geom2d_Curve) aC2D;
624 aT=BRep_Tool::Parameter (aV1, aE1, aF);
625 aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
626 aC2D->D0 (aT, aP2D1);
630 //=======================================================================
631 // function: Coord2dVf
633 //=======================================================================
634 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
635 const TopoDS_Face& aF)
637 Standard_Real aCoord=99.;
638 gp_Pnt2d aP2D1(aCoord, aCoord);
642 for (; aIt.More(); aIt.Next()) {
643 const TopoDS_Shape& aVx=aIt.Value();
644 if (aVx.Orientation()==TopAbs_FORWARD) {
646 const TopoDS_Vertex& aVxx=(*(TopoDS_Vertex *)(&aVx));// TopoDS::Vertex(aVx);
647 aP2D1=Coord2d(aVxx, aE, aF);
654 //=======================================================================
655 // function: NbWaysOut
657 //=======================================================================
658 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
660 Standard_Boolean bIsOut, bIsNotPassed;
661 Standard_Integer iCnt=0;
662 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
664 anIt.Initialize(aLEInfo);
665 for (; anIt.More(); anIt.Next()) {
666 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
669 bIsNotPassed=!anEI.Passed();
670 if (bIsOut && bIsNotPassed) {
677 //=======================================================================
680 //=======================================================================
681 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
682 const BOPAlgo_ListOfEdgeInfo& aLEInfo)
684 Standard_Real anAngleIn;
685 Standard_Boolean anIsIn;
686 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
688 anIt.Initialize(aLEInfo);
689 for (; anIt.More(); anIt.Next()) {
690 const BOPAlgo_EdgeInfo& anEdgeInfo=anIt.Value();
691 const TopoDS_Edge& aE=anEdgeInfo.Edge();
692 anIsIn=anEdgeInfo.IsIn();
694 if (anIsIn && aE==aEIn) {
695 anAngleIn=anEdgeInfo.Angle();
702 //=======================================================================
703 // function: GetNextVertex
705 //=======================================================================
706 void GetNextVertex(const TopoDS_Vertex& aV,
707 const TopoDS_Edge& aE,
713 for (; aIt.More(); aIt.Next()) {
714 const TopoDS_Shape& aVx=aIt.Value();
715 if (!aVx.IsEqual(aV)) {
716 aV1=(*(TopoDS_Vertex *)(&aVx));
722 //=======================================================================
725 //=======================================================================
726 Standard_Real Angle2D (const TopoDS_Vertex& aV,
727 const TopoDS_Edge& anEdge,
728 const TopoDS_Face& myFace,
729 const GeomAdaptor_Surface& aGAS,
730 const Standard_Boolean aFlag)
732 Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
735 Handle(Geom2d_Curve) aC2D;
737 aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
738 if (Precision::IsInfinite(aTV)) {
742 BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D,
743 aFirst, aLast, aToler);
744 dt=2.*Tolerance2D(aV, aGAS);
746 //for case chl/927/r9
747 aTX=0.05*(aLast - aFirst);//aTX=0.25*(aLast - aFirst);
752 // to save direction of the curve as much as it possible
753 // in the case of big tolerances
757 GeomAbs_CurveType aType;
758 Geom2dAdaptor_Curve aGAC2D(aC2D);
759 aType=aGAC2D.GetType();
760 if (aType==GeomAbs_BSplineCurve || aType==GeomAbs_BezierCurve) {
763 if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
770 aC2D->D0 (aTV1, aPV1);
774 gp_Vec2d aV2DIn(aPV1, aPV);
778 gp_Vec2d aV2DOut(aPV, aPV1);
782 gp_Dir2d aDir2D(aV2D);
783 anAngle=Angle(aDir2D);
787 //=======================================================================
790 //=======================================================================
791 Standard_Real Angle (const gp_Dir2d& aDir2D)
793 gp_Dir2d aRefDir(1., 0.);
794 Standard_Real anAngle;
796 anAngle = aRefDir.Angle(aDir2D);
798 anAngle += M_PI + M_PI;
801 //=======================================================================
802 // function: Tolerance2D
804 //=======================================================================
805 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
806 const GeomAdaptor_Surface& aGAS)
808 Standard_Real aTol2D, anUr, aVr, aTolV3D;
809 GeomAbs_SurfaceType aType;
811 aType=aGAS.GetType();
812 aTolV3D=BRep_Tool::Tolerance(aV);
814 anUr=aGAS.UResolution(aTolV3D);
815 aVr =aGAS.VResolution(aTolV3D);
816 aTol2D=(aVr>anUr) ? aVr : anUr;
818 if (aTol2D < aTolV3D) {
821 if (aType==GeomAbs_BSplineSurface) {
828 //=======================================================================
829 //function : UTolerance2D
831 //=======================================================================
832 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
833 const GeomAdaptor_Surface& aGAS)
835 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
836 const Standard_Real anUr = aGAS.UResolution(aTolV3D);
841 //=======================================================================
842 //function : VTolerance2D
844 //=======================================================================
845 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
846 const GeomAdaptor_Surface& aGAS)
848 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
849 const Standard_Real anVr = aGAS.VResolution(aTolV3D);
854 //=======================================================================
855 // function: RecomputeAngles
857 //=======================================================================
858 Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo,
859 const TopoDS_Face& theFace,
860 const gp_Pnt2d& thePb,
861 const TopoDS_Vertex& theVb,
862 const GeomAdaptor_Surface& theGAS,
863 const TopoDS_Edge& theEOuta,
864 const Standard_Boolean& bIsClosed,
865 const Standard_Real& theTol2D,
866 BOPCol_SequenceOfReal& theRecomputedAngles)
868 Standard_Boolean bRecomputeAngle = Standard_False;
869 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
870 anIt.Initialize(aLEInfo);
872 for (; anIt.More(); anIt.Next()) {
873 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
874 const TopoDS_Edge& aE=anEI.Edge();
875 Standard_Boolean anIsOut=!anEI.IsIn();
876 Standard_Boolean anIsNotPassed=!anEI.Passed();
878 if (anIsOut && anIsNotPassed) {
879 theRecomputedAngles.Append(anEI.Angle());
880 Standard_Integer acurindex = theRecomputedAngles.Length();
882 Standard_Boolean bRecomputeAngleLocal = Standard_False;
883 TopExp_Explorer anExp1(aE, TopAbs_VERTEX);
885 for(; anExp1.More(); anExp1.Next()) {
886 TopExp_Explorer anExp2(theEOuta, TopAbs_VERTEX);
887 Standard_Boolean existsInEdge = Standard_False;
889 for(; anExp2.More(); anExp2.Next()) {
890 if(anExp1.Current().IsSame(anExp2.Current())) {
891 existsInEdge = Standard_True;
897 bRecomputeAngleLocal = Standard_False;
900 bRecomputeAngleLocal = Standard_True;
902 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
904 if(!bRecomputeAngle) {
905 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt2(aLEInfo);
907 for(; anIt2.More(); anIt2.Next()) {
908 const BOPAlgo_EdgeInfo& anEI2=anIt2.Value();
909 const TopoDS_Edge& aE2=anEI2.Edge();
913 Standard_Boolean anIsOut2=!anEI2.IsIn();
914 Standard_Boolean anIsNotPassed2=!anEI2.Passed();
916 if (anIsOut2 && anIsNotPassed2) {
917 anExp1.Init(aE, TopAbs_VERTEX);
919 for(; anExp1.More(); anExp1.Next()) {
920 TopExp_Explorer anExp2(aE2, TopAbs_VERTEX);
921 Standard_Boolean existsInEdge = Standard_False;
923 for(; anExp2.More(); anExp2.Next()) {
924 if(anExp1.Current().IsSame(anExp2.Current())) {
925 existsInEdge = Standard_True;
931 bRecomputeAngleLocal = Standard_False;
934 bRecomputeAngleLocal = Standard_True;
936 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
941 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
943 if(bRecomputeAngle) {
946 aP2Dx=Coord2dVf(aE, theFace);
947 Standard_Real aD = aP2Dx.Distance(thePb);
950 TopExp_Explorer anExp(aE, TopAbs_VERTEX);
952 for (; anExp.More(); anExp.Next()) {
953 const TopoDS_Vertex& aVx=*(TopoDS_Vertex*)(&anExp.Current());
954 if (aVx.Orientation()==TopAbs_FORWARD) {
958 Standard_Boolean bIgnore = Standard_False;
960 if(bIsClosed || aVf.IsNull() || !aVf.IsSame(theVb)) {
961 bIgnore = (aD > theTol2D);
964 if(!bIgnore && (theTol2D > M_PI)) {
965 Standard_Real udist = fabs(aP2Dx.X() - thePb.X());
966 Standard_Real vdist = fabs(aP2Dx.Y() - thePb.Y());
967 Standard_Real aTolU = 2. * UTolerance2D(theVb, theGAS);
968 Standard_Real aTolV = 2. * VTolerance2D(theVb, theGAS);
970 if((udist > aTolU) ||
972 bIgnore = Standard_True;
976 if((aD > Precision::Confusion()) && !bIgnore) {
977 Standard_Real f1, l1;
978 Handle(Geom2d_Curve) ac1 = BRep_Tool::CurveOnSurface(aE, theFace, f1, l1);
980 Standard_Real aTV1 = BRep_Tool::Parameter (aVf, aE, theFace);
981 Standard_Real aTV12 = 0.;
982 Standard_Real dt1 = (l1 - f1) * 0.5;
984 if (fabs (aTV1-f1) < fabs(aTV1 - l1)) {
991 gp_Pnt2d aPointNew = ac1->Value(aTV12);
992 gp_Vec2d aV2DOut(thePb, aPointNew);
994 gp_Dir2d aDir2D(aV2DOut);
995 Standard_Real anAngleOut = Angle(aDir2D);
996 theRecomputedAngles.ChangeValue(acurindex) = anAngleOut;
1001 return bRecomputeAngle;