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>
23 #include <Geom_Surface.hxx>
24 #include <Geom_Plane.hxx>
25 #include <Geom_RectangularTrimmedSurface.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_Line.hxx>
28 #include <GeomAdaptor_Surface.hxx>
29 #include <Geom2dAdaptor_Curve.hxx>
31 #include <Geom2dInt_GInter.hxx>
32 #include <IntRes2d_Domain.hxx>
33 #include <IntRes2d_IntersectionPoint.hxx>
35 #include <TopLoc_Location.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopoDS_Iterator.hxx>
41 #include <BRep_Tool.hxx>
42 #include <BRep_Builder.hxx>
44 #include <TopTools_ShapeMapHasher.hxx>
46 #include <TopExp_Explorer.hxx>
48 #include <BRepAdaptor_Surface.hxx>
50 #include <BOPCol_ListOfShape.hxx>
51 #include <BOPCol_SequenceOfShape.hxx>
52 #include <BOPCol_SequenceOfPnt2d.hxx>
53 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
54 #include <BOPCol_SequenceOfReal.hxx>
55 #include <BOPCol_DataMapOfShapeInteger.hxx>
56 #include <BOPCol_MapOfShape.hxx>
58 #include <BOPTools_AlgoTools2D.hxx>
61 Standard_Real Angle (const gp_Dir2d& aDir2D);
64 Standard_Real Angle2D (const TopoDS_Vertex& aV,
65 const TopoDS_Edge& anEdge,
66 const TopoDS_Face& myFace,
67 const GeomAdaptor_Surface& aGAS,
68 const Standard_Boolean aFlag);
71 void GetNextVertex(const TopoDS_Vertex& aV,
72 const TopoDS_Edge& aE,
76 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
77 const BOPAlgo_ListOfEdgeInfo& aLEInfo);
80 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo);
83 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
84 const TopoDS_Face& aF);
87 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
88 const TopoDS_Edge& aE1,
89 const TopoDS_Face& aF);
93 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
94 const Standard_Real aAngleOut);
97 void Path (const GeomAdaptor_Surface& aGAS,
98 const TopoDS_Face& myFace,
99 const TopoDS_Vertex& aVa,
100 const TopoDS_Edge& aEOuta,
101 BOPAlgo_EdgeInfo& anEdgeInfo,
102 BOPCol_SequenceOfShape& aLS,
103 BOPCol_SequenceOfShape& aVertVa,
104 BOPCol_SequenceOfPnt2d& aCoordVa,
105 BOPTools_ConnexityBlock& aCB,
106 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap);
109 Standard_Real Angle2D (const TopoDS_Vertex& aV,
110 const TopoDS_Edge& anEdge,
111 const TopoDS_Face& myFace,
112 const GeomAdaptor_Surface& aGAS,
113 const Standard_Boolean aFlag);
115 Standard_Real Angle (const gp_Dir2d& aDir2D);
118 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
119 const GeomAdaptor_Surface& aGAS);
124 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
125 const GeomAdaptor_Surface& aGAS);
127 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
128 const GeomAdaptor_Surface& aGAS);
131 Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo,
132 const TopoDS_Face& theFace,
133 const gp_Pnt2d& thePb,
134 const TopoDS_Vertex& theVb,
135 const GeomAdaptor_Surface& theGAS,
136 const TopoDS_Edge& theEOuta,
137 const Standard_Boolean& bHasClosed,
138 const Standard_Real& theTol2D,
139 BOPCol_SequenceOfReal& theRecomputedAngles);
142 void RefineAngles(const TopoDS_Face& myFace,
143 const BOPCol_ListOfShape&,
144 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo&);
148 void RefineAngles(const TopoDS_Vertex& ,
150 const BOPCol_MapOfShape& ,
151 BOPAlgo_ListOfEdgeInfo& );
154 Standard_Boolean RefineAngle2D(const TopoDS_Vertex& ,
157 const Standard_Real ,
158 const Standard_Real ,
161 //=======================================================================
162 //function : SplitBlock
164 //=======================================================================
165 void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
166 BOPTools_ConnexityBlock& aCB)
168 Standard_Boolean bNothingToDo;
169 Standard_Integer aIx, aNb, i, aCntIn, aCntOut;
170 Standard_Real aAngle;
171 TopAbs_Orientation aOr;
172 TopoDS_Iterator aItS;
174 BOPCol_ListIteratorOfListOfShape aIt;
175 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
177 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100);
179 const BOPCol_ListOfShape& myEdges=aCB.Shapes();
181 // 1.Filling mySmartMap
182 BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane(myEdges, myFace);
184 aIt.Initialize(myEdges);
185 for(; aIt.More(); aIt.Next()) {
186 const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
187 if (!BOPTools_AlgoTools2D::HasCurveOnSurface (aE, myFace)) {
192 for(; aItS.More(); aItS.Next()) {
193 const TopoDS_Shape& aV=aItS.Value();
194 aIx=mySmartMap.FindIndex(aV);
196 BOPAlgo_ListOfEdgeInfo aLEIx;
197 aIx=mySmartMap.Add(aV, aLEIx);
200 BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(aIx);
202 BOPAlgo_EdgeInfo aEI;
205 aOr=aV.Orientation();
206 if (aOr==TopAbs_FORWARD) {
207 aEI.SetInFlag(Standard_False);
209 else if (aOr==TopAbs_REVERSED) {
210 aEI.SetInFlag(Standard_True);
216 aNb=mySmartMap.Extent();
218 bNothingToDo=Standard_True;
219 for (i=1; i<=aNb; i++) {
222 const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
223 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
224 for (; anIt.More(); anIt.Next()) {
225 const BOPAlgo_EdgeInfo& aEI=anIt.Value();
233 if (aCntIn!=1 || aCntOut!=1) {
234 bNothingToDo=Standard_False;
239 // Each vertex has one edge In and one - Out. Good. But it is not enought
240 // to consider that nothing to do with this. We must check edges on TShape
241 // coinsidence. If there are such edges there is something to do with.
243 Standard_Integer aNbE, aNbMapEE;
244 Standard_Boolean bFlag;
246 BOPCol_IndexedDataMapOfShapeListOfShape aMapEE(100);
247 aNbE=myEdges.Extent();
249 aIt.Initialize(myEdges);
250 for (; aIt.More(); aIt.Next()) {
251 const TopoDS_Shape& aE = aIt.Value();
252 if (!aMapEE.Contains(aE)) {
253 BOPCol_ListOfShape aLEx;
255 aMapEE.Add(aE, aLEx);
258 BOPCol_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
264 aNbMapEE=aMapEE.Extent();
265 for (i=1; i<=aNbMapEE; ++i) {
266 const BOPCol_ListOfShape& aLEx=aMapEE(i);
268 if (aNbE==1) {// usual case
272 const TopoDS_Shape& aE1=aLEx.First();
273 const TopoDS_Shape& aE2=aLEx.Last();
274 if (aE1.IsSame(aE2)) {
275 bFlag=Standard_False;
280 bFlag=Standard_False;
284 bNothingToDo=bNothingToDo && bFlag;
285 } // if (bNothingToDo) {
289 BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
290 BOPAlgo_WireSplitter::MakeWire(aLECB, aW);
291 BOPCol_ListOfShape& aLoops=aCB.ChangeLoops();
297 // 3. Angles in mySmartMap
298 BRepAdaptor_Surface aBAS(myFace);
299 const GeomAdaptor_Surface& aGAS=aBAS.Surface();
301 for (i=1; i<=aNb; i++) {
302 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
303 const BOPAlgo_ListOfEdgeInfo& aLEI= mySmartMap(i);
305 aItLEI.Initialize(aLEI);
306 for (; aItLEI.More(); aItLEI.Next()) {
307 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
308 const TopoDS_Edge& aE=aEI.Edge();
312 aVV.Orientation(TopAbs_REVERSED);
313 aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_True);
316 aVV.Orientation(TopAbs_FORWARD);
317 aAngle=Angle2D (aVV, aE, myFace, aGAS, Standard_False);
319 aEI.SetAngle(aAngle);
321 }// for (i=1; i<=aNb; i++) {
323 //Theme: The treatment p-curves convergent in node.
324 //The refining the angles of p-curves taking into account
325 //bounging curves if exist.
326 RefineAngles(myFace, myEdges, mySmartMap);
330 Standard_Boolean bIsOut, bIsNotPassed;
331 BOPCol_SequenceOfShape aLS, aVertVa;
332 BOPCol_SequenceOfPnt2d aCoordVa;
334 for (i=1; i<=aNb; ++i) {
335 const TopoDS_Vertex& aVa=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
336 const BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
337 aItLEI.Initialize(aLEI);
338 for (; aItLEI.More(); aItLEI.Next()) {
339 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
340 const TopoDS_Edge& aEOuta=aEI.Edge();
343 bIsNotPassed=!aEI.Passed();
344 if (bIsOut && bIsNotPassed) {
350 Path(aGAS, myFace, aVa, aEOuta, aEI, aLS,
351 aVertVa, aCoordVa, aCB, mySmartMap);
354 }// for (i=1; i<=aNb; ++i) {
356 //=======================================================================
359 //=======================================================================
360 void Path (const GeomAdaptor_Surface& aGAS,
361 const TopoDS_Face& myFace,
362 const TopoDS_Vertex& aVFirst,
363 const TopoDS_Edge& aEFirst,
364 BOPAlgo_EdgeInfo& aEIFirst,
365 BOPCol_SequenceOfShape& aLS,
366 BOPCol_SequenceOfShape& aVertVa,
367 BOPCol_SequenceOfPnt2d& aCoordVa,
368 BOPTools_ConnexityBlock& aCB,
369 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
372 Standard_Integer i, j, aNb, aNbj;
373 Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
374 Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
375 Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
376 Standard_Boolean bIsClosed, bRecomputeAngle;
377 TopoDS_Vertex aVa, aVb;
379 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
380 BOPCol_SequenceOfReal aRecomputedAngles;
384 BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
386 aTwoPI = M_PI + M_PI;
391 // Do not escape through edge from which you enter
394 const TopoDS_Shape& anEPrev=aLS(aNb);
395 if (anEPrev.IsSame(aEOuta)) {
400 anEdgeInfo->SetPassed(Standard_True);
404 TopoDS_Vertex pVa=aVa;
405 pVa.Orientation(TopAbs_FORWARD);
406 gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
407 aCoordVa.Append(aPa);
409 GetNextVertex (pVa, aEOuta, aVb);
411 gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
413 const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
415 aTol2D = 2.*Tolerance2D(aVb, aGAS);
416 aTol2D2 = aTol2D * aTol2D;
418 bIsClosed = BRep_Tool::Degenerated(aEOuta) ||
419 BRep_Tool::IsClosed(aEOuta, myFace) || aVa.IsSame(aVb);
421 TopoDS_Vertex aV1, aV2;
423 anIt.Initialize(aLEInfo);
424 for (; anIt.More() && !bIsClosed; anIt.Next()) {
425 const BOPAlgo_EdgeInfo& anEI = anIt.Value();
426 const TopoDS_Edge& aE = anEI.Edge();
428 bIsClosed = BRep_Tool::Degenerated(aE) || BRep_Tool::IsClosed(aE, myFace);
430 TopExp::Vertices(aE, aV1, aV2);
431 bIsClosed = aV1.IsNull() || aV2.IsNull() || aV1.IsSame(aV2);
439 BOPCol_ListOfShape aBuf;
441 for (i=aNb; i>0; --i) {
442 const TopoDS_Shape& aVPrev=aVertVa(i);
443 const gp_Pnt2d& aPaPrev=aCoordVa(i);
444 const TopoDS_Shape& aEPrev=aLS(i);
448 anIsSameV = aVPrev.IsSame(aVb);
449 anIsSameV2d = anIsSameV;
452 aD2 = aPaPrev.SquareDistance(aPb);
453 anIsSameV2d = aD2 < aTol2D2;
455 Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
456 Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
457 Standard_Real aTolU = 2.*UTolerance2D(aVb, aGAS);
458 Standard_Real aTolV = 2.*VTolerance2D(aVb, aGAS);
460 if((udist > aTolU) || (vdist > aTolV)) {
461 anIsSameV2d = Standard_False;
467 if (anIsSameV && anIsSameV2d) {
468 Standard_Integer iPriz;
470 if (aBuf.Extent()==2) {
471 if(aBuf.First().IsSame(aBuf.Last())) {
477 BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
478 aCB.ChangeLoops().Append(aW);
491 BOPCol_SequenceOfShape aLSt, aVertVat;
492 BOPCol_SequenceOfPnt2d aCoordVat;
494 aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
496 for (j=1; j<=aNbj; ++j) {
498 aVertVat.Append(aVertVa(j));
499 aCoordVat.Append(aCoordVa(j));
515 aRecomputedAngles.Clear();
517 RecomputeAngles(aLEInfo, myFace, aPb, aVb, aGAS, aEOuta,
518 bIsClosed, aTol2D, aRecomputedAngles);
521 BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
523 anAngleIn = AngleIn(aEOuta, aLEInfo);
525 anIsFound = Standard_False;
526 Standard_Integer aCurIndexE = 0;
527 anIt.Initialize(aLEInfo);
528 for (; anIt.More(); anIt.Next()) {
529 BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
530 const TopoDS_Edge& aE=anEI.Edge();
531 anIsOut=!anEI.IsIn();
532 anIsNotPassed=!anEI.Passed();
534 if (anIsOut && anIsNotPassed) {
537 // Is there one way to go out of the vertex
538 // we have to use it only.
539 Standard_Integer iCnt;
540 iCnt=NbWaysOut (aLEInfo);
543 // no way to go . (Error)
548 // the one and only way to go out .
550 anIsFound=Standard_True;
554 if (aE.IsSame(aEOuta)) {
561 aP2Dx = Coord2dVf(aE, myFace);
563 aD2 = aP2Dx.SquareDistance(aPb);
569 // Look for minimal angle and make the choice.
570 anAngleOut=anEI.Angle();
572 if(bRecomputeAngle) {
573 if(aCurIndexE <= aRecomputedAngles.Length()) {
574 anAngleOut = aRecomputedAngles.Value(aCurIndexE);
577 anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
579 if (anAngle < aMinAngle) {
582 anIsFound=Standard_True;
585 } // for (; anIt.More(); anIt.Next())
588 // no way to go . (Error)
593 aEOuta = pEdgeInfo->Edge();
594 anEdgeInfo = pEdgeInfo;
597 //=======================================================================
598 // function: ClockWiseAngle
600 //=======================================================================
601 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
602 const Standard_Real aAngleOut)
604 Standard_Real aTwoPi=M_PI+M_PI;
605 Standard_Real dA, A1, A2, AIn, AOut ;
613 if (AOut >= aTwoPi) {
630 //else if (dA <= 1.e-15) {
631 else if (dA <= 1.e-14) {
636 //=======================================================================
639 //=======================================================================
640 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
641 const TopoDS_Edge& aE1,
642 const TopoDS_Face& aF)
644 Standard_Real aT, aFirst, aLast;
645 Handle(Geom2d_Curve) aC2D;
648 aT=BRep_Tool::Parameter (aV1, aE1, aF);
649 aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
650 aC2D->D0 (aT, aP2D1);
654 //=======================================================================
655 // function: Coord2dVf
657 //=======================================================================
658 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
659 const TopoDS_Face& aF)
661 Standard_Real aCoord=99.;
662 gp_Pnt2d aP2D1(aCoord, aCoord);
666 for (; aIt.More(); aIt.Next()) {
667 const TopoDS_Shape& aVx=aIt.Value();
668 if (aVx.Orientation()==TopAbs_FORWARD) {
670 const TopoDS_Vertex& aVxx=(*(TopoDS_Vertex *)(&aVx));// TopoDS::Vertex(aVx);
671 aP2D1=Coord2d(aVxx, aE, aF);
678 //=======================================================================
679 // function: NbWaysOut
681 //=======================================================================
682 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
684 Standard_Boolean bIsOut, bIsNotPassed;
685 Standard_Integer iCnt=0;
686 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
688 anIt.Initialize(aLEInfo);
689 for (; anIt.More(); anIt.Next()) {
690 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
693 bIsNotPassed=!anEI.Passed();
694 if (bIsOut && bIsNotPassed) {
701 //=======================================================================
704 //=======================================================================
705 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
706 const BOPAlgo_ListOfEdgeInfo& aLEInfo)
708 Standard_Real anAngleIn;
709 Standard_Boolean anIsIn;
710 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
712 anIt.Initialize(aLEInfo);
713 for (; anIt.More(); anIt.Next()) {
714 const BOPAlgo_EdgeInfo& anEdgeInfo=anIt.Value();
715 const TopoDS_Edge& aE=anEdgeInfo.Edge();
716 anIsIn=anEdgeInfo.IsIn();
718 if (anIsIn && aE==aEIn) {
719 anAngleIn=anEdgeInfo.Angle();
726 //=======================================================================
727 // function: GetNextVertex
729 //=======================================================================
730 void GetNextVertex(const TopoDS_Vertex& aV,
731 const TopoDS_Edge& aE,
737 for (; aIt.More(); aIt.Next()) {
738 const TopoDS_Shape& aVx=aIt.Value();
739 if (!aVx.IsEqual(aV)) {
740 aV1=(*(TopoDS_Vertex *)(&aVx));
746 //=======================================================================
749 //=======================================================================
750 Standard_Real Angle2D (const TopoDS_Vertex& aV,
751 const TopoDS_Edge& anEdge,
752 const TopoDS_Face& myFace,
753 const GeomAdaptor_Surface& aGAS,
754 const Standard_Boolean aFlag)
756 Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
759 Handle(Geom2d_Curve) aC2D;
761 aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
762 if (Precision::IsInfinite(aTV)) {
766 BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D,
767 aFirst, aLast, aToler);
768 dt=2.*Tolerance2D(aV, aGAS);
770 //for case chl/927/r9
771 aTX=0.05*(aLast - aFirst);//aTX=0.25*(aLast - aFirst);
776 // to save direction of the curve as much as it possible
777 // in the case of big tolerances
781 GeomAbs_CurveType aType;
782 Geom2dAdaptor_Curve aGAC2D(aC2D);
783 aType=aGAC2D.GetType();
784 if (aType==GeomAbs_BSplineCurve || aType==GeomAbs_BezierCurve) {
787 if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
794 aC2D->D0 (aTV1, aPV1);
798 gp_Vec2d aV2DIn(aPV1, aPV);
802 gp_Vec2d aV2DOut(aPV, aPV1);
806 gp_Dir2d aDir2D(aV2D);
807 anAngle=Angle(aDir2D);
811 //=======================================================================
814 //=======================================================================
815 Standard_Real Angle (const gp_Dir2d& aDir2D)
817 gp_Dir2d aRefDir(1., 0.);
818 Standard_Real anAngle;
820 anAngle = aRefDir.Angle(aDir2D);
822 anAngle += M_PI + M_PI;
825 //=======================================================================
826 // function: Tolerance2D
828 //=======================================================================
829 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
830 const GeomAdaptor_Surface& aGAS)
832 Standard_Real aTol2D, anUr, aVr, aTolV3D;
833 GeomAbs_SurfaceType aType;
835 aType=aGAS.GetType();
836 aTolV3D=BRep_Tool::Tolerance(aV);
838 anUr=aGAS.UResolution(aTolV3D);
839 aVr =aGAS.VResolution(aTolV3D);
840 aTol2D=(aVr>anUr) ? aVr : anUr;
842 if (aTol2D < aTolV3D) {
845 if (aType==GeomAbs_BSplineSurface) {
852 //=======================================================================
853 //function : UTolerance2D
855 //=======================================================================
856 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
857 const GeomAdaptor_Surface& aGAS)
859 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
860 const Standard_Real anUr = aGAS.UResolution(aTolV3D);
865 //=======================================================================
866 //function : VTolerance2D
868 //=======================================================================
869 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
870 const GeomAdaptor_Surface& aGAS)
872 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
873 const Standard_Real anVr = aGAS.VResolution(aTolV3D);
878 //=======================================================================
879 // function: RecomputeAngles
881 //=======================================================================
882 Standard_Boolean RecomputeAngles(const BOPAlgo_ListOfEdgeInfo& aLEInfo,
883 const TopoDS_Face& theFace,
884 const gp_Pnt2d& thePb,
885 const TopoDS_Vertex& theVb,
886 const GeomAdaptor_Surface& theGAS,
887 const TopoDS_Edge& theEOuta,
888 const Standard_Boolean& bIsClosed,
889 const Standard_Real& theTol2D,
890 BOPCol_SequenceOfReal& theRecomputedAngles)
892 Standard_Boolean bRecomputeAngle = Standard_False;
893 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
894 anIt.Initialize(aLEInfo);
896 for (; anIt.More(); anIt.Next()) {
897 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
898 const TopoDS_Edge& aE=anEI.Edge();
899 Standard_Boolean anIsOut=!anEI.IsIn();
900 Standard_Boolean anIsNotPassed=!anEI.Passed();
902 if (anIsOut && anIsNotPassed) {
903 theRecomputedAngles.Append(anEI.Angle());
904 Standard_Integer acurindex = theRecomputedAngles.Length();
906 Standard_Boolean bRecomputeAngleLocal = Standard_False;
907 TopExp_Explorer anExp1(aE, TopAbs_VERTEX);
909 for(; anExp1.More(); anExp1.Next()) {
910 TopExp_Explorer anExp2(theEOuta, TopAbs_VERTEX);
911 Standard_Boolean existsInEdge = Standard_False;
913 for(; anExp2.More(); anExp2.Next()) {
914 if(anExp1.Current().IsSame(anExp2.Current())) {
915 existsInEdge = Standard_True;
921 bRecomputeAngleLocal = Standard_False;
924 bRecomputeAngleLocal = Standard_True;
926 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
928 if(!bRecomputeAngle) {
929 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt2(aLEInfo);
931 for(; anIt2.More(); anIt2.Next()) {
932 const BOPAlgo_EdgeInfo& anEI2=anIt2.Value();
933 const TopoDS_Edge& aE2=anEI2.Edge();
937 Standard_Boolean anIsOut2=!anEI2.IsIn();
938 Standard_Boolean anIsNotPassed2=!anEI2.Passed();
940 if (anIsOut2 && anIsNotPassed2) {
941 anExp1.Init(aE, TopAbs_VERTEX);
943 for(; anExp1.More(); anExp1.Next()) {
944 TopExp_Explorer anExp2(aE2, TopAbs_VERTEX);
945 Standard_Boolean existsInEdge = Standard_False;
947 for(; anExp2.More(); anExp2.Next()) {
948 if(anExp1.Current().IsSame(anExp2.Current())) {
949 existsInEdge = Standard_True;
955 bRecomputeAngleLocal = Standard_False;
958 bRecomputeAngleLocal = Standard_True;
960 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
965 bRecomputeAngle = bRecomputeAngle || bRecomputeAngleLocal;
967 if(bRecomputeAngle) {
970 aP2Dx=Coord2dVf(aE, theFace);
971 Standard_Real aD = aP2Dx.Distance(thePb);
974 TopExp_Explorer anExp(aE, TopAbs_VERTEX);
976 for (; anExp.More(); anExp.Next()) {
977 const TopoDS_Vertex& aVx=*(TopoDS_Vertex*)(&anExp.Current());
978 if (aVx.Orientation()==TopAbs_FORWARD) {
982 Standard_Boolean bIgnore = Standard_False;
984 if(bIsClosed || aVf.IsNull() || !aVf.IsSame(theVb)) {
985 bIgnore = (aD > theTol2D);
988 if(!bIgnore && (theTol2D > M_PI)) {
989 Standard_Real udist = fabs(aP2Dx.X() - thePb.X());
990 Standard_Real vdist = fabs(aP2Dx.Y() - thePb.Y());
991 Standard_Real aTolU = 2. * UTolerance2D(theVb, theGAS);
992 Standard_Real aTolV = 2. * VTolerance2D(theVb, theGAS);
994 if((udist > aTolU) ||
996 bIgnore = Standard_True;
1000 if((aD > Precision::Confusion()) && !bIgnore) {
1001 Standard_Real f1, l1;
1002 Handle(Geom2d_Curve) ac1 = BRep_Tool::CurveOnSurface(aE, theFace, f1, l1);
1004 Standard_Real aTV1 = BRep_Tool::Parameter (aVf, aE, theFace);
1005 Standard_Real aTV12 = 0.;
1006 Standard_Real dt1 = (l1 - f1) * 0.5;
1008 if (fabs (aTV1-f1) < fabs(aTV1 - l1)) {
1015 gp_Pnt2d aPointNew = ac1->Value(aTV12);
1016 gp_Vec2d aV2DOut(thePb, aPointNew);
1018 gp_Dir2d aDir2D(aV2DOut);
1019 Standard_Real anAngleOut = Angle(aDir2D);
1020 theRecomputedAngles.ChangeValue(acurindex) = anAngleOut;
1025 return bRecomputeAngle;
1027 //=======================================================================
1028 //function : RefineAngles
1030 //=======================================================================
1031 void RefineAngles(const TopoDS_Face& myFace,
1032 const BOPCol_ListOfShape& myEdges,
1033 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
1035 Standard_Integer aNb, i;
1036 BOPCol_DataMapOfShapeInteger aMSI;
1037 BOPCol_DataMapIteratorOfDataMapOfShapeInteger aItMSI;
1038 BOPCol_MapOfShape aMBE;
1039 BOPCol_ListIteratorOfListOfShape aIt;
1041 // 1. Boundary Edges
1042 aIt.Initialize(myEdges);
1043 for(; aIt.More(); aIt.Next()) {
1044 const TopoDS_Shape& aE=aIt.Value();
1045 if(aMSI.IsBound(aE)) {
1046 Standard_Integer& iCnt=aMSI.ChangeFind(aE);
1050 Standard_Integer iCnt=1;
1051 aMSI.Bind(aE, iCnt);
1055 aItMSI.Initialize(aMSI);
1056 for(; aItMSI.More(); aItMSI.Next()) {
1057 Standard_Integer iCnt;
1059 const TopoDS_Shape& aE=aItMSI.Key();
1060 iCnt=aItMSI.Value();
1069 aNb=mySmartMap.Extent();
1070 for (i=1; i<=aNb; ++i) {
1071 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&mySmartMap.FindKey(i));
1072 BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
1074 RefineAngles(aV, myFace, aMBE, aLEI);
1077 //=======================================================================
1078 typedef NCollection_DataMap \
1079 <TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> \
1080 BOPCol_DataMapOfShapeReal;
1081 typedef BOPCol_DataMapOfShapeReal::Iterator \
1082 BOPCol_DataMapIteratorOfDataMapOfShapeReal;
1084 //=======================================================================
1085 //function : RefineAngles
1087 //=======================================================================
1088 void RefineAngles(const TopoDS_Vertex& aV,
1089 const TopoDS_Face& myFace,
1090 const BOPCol_MapOfShape& aMBE,
1091 BOPAlgo_ListOfEdgeInfo& aLEI)
1093 Standard_Boolean bIsIn, bIsBoundary, bRefined;
1094 Standard_Integer iCnt;
1095 Standard_Real aA, aA1, aA2;
1096 BOPCol_DataMapOfShapeReal aDMSR;
1097 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
1102 aItLEI.Initialize(aLEI);
1103 for (; aItLEI.More(); aItLEI.Next()) {
1104 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
1105 const TopoDS_Edge& aE=aEI.Edge();
1109 if (aMBE.Contains(aE)) {
1124 aItLEI.Initialize(aLEI);
1125 for (; aItLEI.More(); aItLEI.Next()) {
1126 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
1127 const TopoDS_Edge& aE=aEI.Edge();
1129 bIsBoundary=aMBE.Contains(aE);
1131 if (bIsBoundary || bIsIn) {
1136 if (!(aA<aA1 || aA>aA2)) {
1140 bRefined=RefineAngle2D(aV, aE, myFace, aA1, aA2, aA);
1146 if (aDMSR.IsEmpty()) {
1151 aItLEI.Initialize(aLEI);
1152 for (; aItLEI.More(); aItLEI.Next()) {
1153 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
1154 const TopoDS_Edge& aE=aEI.Edge();
1157 if (!aDMSR.IsBound(aE)) {
1169 //=======================================================================
1170 //function : RefineAngle2D
1172 //=======================================================================
1173 Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
1174 const TopoDS_Edge& aE,
1175 const TopoDS_Face& myFace,
1176 const Standard_Real aA1,
1177 const Standard_Real aA2,
1180 Standard_Boolean bRet;
1181 Standard_Integer i, j, aNbP, iSign;
1182 Standard_Real aTV, aTol, aT1, aT2, dT, aAngle, aT;
1183 Standard_Real aTolInt, aAi, aXi, aYi, aT1j, aT2j, aT1max, aT2max, aCf;
1184 gp_Pnt2d aPV, aP, aP1, aP2;
1185 Handle(Geom2d_Curve) aC2D;
1186 Handle(Geom2d_Line) aLi;
1187 Geom2dAdaptor_Curve aGAC1, aGAC2;
1188 Geom2dInt_GInter aGInter;
1189 IntRes2d_Domain aDomain1, aDomain2;
1195 BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol);
1197 aTV=BRep_Tool::Parameter (aV, aE, myFace);
1200 iSign=(fabs(aTV-aT1) < fabs(aTV-aT2)) ? 1 : -1;
1202 aGAC1.Load(aC2D, aT1, aT2);
1205 aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
1207 for (i=0; i<2; ++i) {
1208 aAi=(!i) ? aA1 : aA2;
1211 gp_Dir2d aDiri(aXi, aYi);
1212 aLi=new Geom2d_Line(aPV, aDiri);
1215 aDomain2.SetValues(aPV, 0., aTolInt, Standard_True);
1217 aGInter.Perform(aGAC1, aDomain1, aGAC2, aDomain2, aTolInt, aTolInt);
1218 if (!aGInter.IsDone()) {
1222 aNbP=aGInter.NbPoints();
1229 for (j=1; j<=aNbP; ++j) {
1230 const IntRes2d_IntersectionPoint& aIPj=aGInter.Point(j);
1231 aT1j=aIPj.ParamOnFirst();
1232 aT2j=aIPj.ParamOnSecond();
1234 if (aT2j > aT2max) {
1240 dT=(iSign==1) ? aT2-aT1max : aT1max-aT1;
1244 gp_Vec2d aV2D(aPV, aP);
1245 gp_Dir2d aDir2D(aV2D);
1247 aAngle=Angle(aDir2D);
1248 if (aAngle>aA1 && aAngle<aA2) {
1252 }// for (i=0; i<2; ++i) {