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_WireEdgeSet.hxx>
16 #include <BOPAlgo_WireSplitter.hxx>
17 #include <BOPCol_IndexedDataMapOfShapeInteger.hxx>
18 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
19 #include <BOPCol_ListOfShape.hxx>
20 #include <BOPCol_MapOfShape.hxx>
21 #include <BOPCol_SequenceOfPnt2d.hxx>
22 #include <BOPCol_SequenceOfReal.hxx>
23 #include <BOPCol_SequenceOfShape.hxx>
24 #include <BOPTools_AlgoTools2D.hxx>
25 #include <BRep_Builder.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRepAdaptor_Surface.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2dAdaptor_Curve.hxx>
31 #include <Geom2dInt_GInter.hxx>
32 #include <Geom_Plane.hxx>
33 #include <Geom_RectangularTrimmedSurface.hxx>
34 #include <Geom_Surface.hxx>
35 #include <GeomAdaptor_Surface.hxx>
36 #include <gp_Dir2d.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <gp_Vec2d.hxx>
39 #include <IntRes2d_Domain.hxx>
40 #include <IntRes2d_IntersectionPoint.hxx>
41 #include <Precision.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopLoc_Location.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Iterator.hxx>
49 #include <TopoDS_Vertex.hxx>
50 #include <TopoDS_Wire.hxx>
51 #include <TopTools_ShapeMapHasher.hxx>
52 #include <Geom2dLProp_CLProps2d.hxx>
53 typedef NCollection_DataMap \
54 <TopoDS_Shape, Standard_Boolean, TopTools_ShapeMapHasher> \
55 BOPCol_DataMapOfShapeBoolean;
59 Standard_Real Angle (const gp_Dir2d& aDir2D);
62 Standard_Real Angle2D (const TopoDS_Vertex& aV,
63 const TopoDS_Edge& anEdge,
64 const TopoDS_Face& myFace,
65 const GeomAdaptor_Surface& aGAS,
66 const Standard_Boolean aFlag,
67 const Handle(IntTools_Context)& theContext);
70 void GetNextVertex(const TopoDS_Vertex& aV,
71 const TopoDS_Edge& aE,
75 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
76 const BOPAlgo_ListOfEdgeInfo& aLEInfo);
79 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo);
82 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
83 const TopoDS_Face& aF);
86 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
87 const TopoDS_Edge& aE1,
88 const TopoDS_Face& aF);
91 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
92 const Standard_Real aAngleOut);
95 void Path (const GeomAdaptor_Surface& aGAS,
96 const TopoDS_Face& myFace,
97 const TopoDS_Vertex& aVa,
98 const TopoDS_Edge& aEOuta,
99 BOPAlgo_EdgeInfo& anEdgeInfo,
100 BOPCol_SequenceOfShape& aLS,
101 BOPCol_SequenceOfShape& aVertVa,
102 BOPCol_SequenceOfPnt2d& aCoordVa,
103 BOPTools_ConnexityBlock& aCB,
104 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
105 BOPCol_DataMapOfShapeBoolean aVertMap);
108 Standard_Real Angle (const gp_Dir2d& aDir2D);
111 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
112 const GeomAdaptor_Surface& aGAS);
117 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
118 const GeomAdaptor_Surface& aGAS);
120 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
121 const GeomAdaptor_Surface& aGAS);
124 void RefineAngles(const TopoDS_Face& myFace,
125 const BOPCol_ListOfShape&,
126 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo&,
127 const Handle(IntTools_Context)&);
131 void RefineAngles(const TopoDS_Vertex& ,
133 const BOPCol_MapOfShape& ,
134 BOPAlgo_ListOfEdgeInfo&,
135 const Handle(IntTools_Context)&);
138 Standard_Boolean RefineAngle2D(const TopoDS_Vertex& ,
141 const Standard_Real ,
142 const Standard_Real ,
145 const Handle(IntTools_Context)& );
147 //=======================================================================
148 //function : SplitBlock
150 //=======================================================================
151 void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
152 BOPTools_ConnexityBlock& aCB,
153 const Handle(IntTools_Context)& theContext)
155 Standard_Boolean bNothingToDo, bIsClosed, bIsIN;
156 Standard_Integer aIx, aNb, i, aCntIn, aCntOut;
157 Standard_Real aAngle;
158 TopAbs_Orientation aOr;
159 TopoDS_Iterator aItS;
162 BOPCol_ListIteratorOfListOfShape aIt;
163 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
165 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100);
166 BOPCol_DataMapOfShapeBoolean aVertMap;
168 const BOPCol_ListOfShape& myEdges=aCB.Shapes();
170 // 1.Filling mySmartMap
171 aIt.Initialize(myEdges);
172 for(; aIt.More(); aIt.Next()) {
173 const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
174 if (!BOPTools_AlgoTools2D::HasCurveOnSurface (aE, myFace)) {
178 bIsClosed = BRep_Tool::Degenerated(aE) ||
179 BRep_Tool::IsClosed(aE, myFace);
182 for(i = 0; aItS.More(); aItS.Next(), ++i) {
183 const TopoDS_Shape& aV = aItS.Value();
184 aIx = mySmartMap.FindIndex(aV);
186 BOPAlgo_ListOfEdgeInfo aLEIx;
187 aIx = mySmartMap.Add(aV, aLEIx);
190 BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap(aIx);
191 BOPAlgo_EdgeInfo aEI;
194 aOr = aV.Orientation();
195 bIsIN = (aOr == TopAbs_REVERSED);
196 aEI.SetInFlag(bIsIN);
202 bIsClosed = bIsClosed || aV1.IsSame(aV);
205 if (aVertMap.IsBound(aV)) {
207 aVertMap.ChangeFind(aV) = bIsClosed;
210 aVertMap.Bind(aV, bIsClosed);
215 aNb=mySmartMap.Extent();
217 bNothingToDo=Standard_True;
218 for (i=1; i<=aNb; i++) {
221 const BOPAlgo_ListOfEdgeInfo& aLEInfo= mySmartMap(i);
222 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
223 for (; anIt.More(); anIt.Next()) {
224 const BOPAlgo_EdgeInfo& aEI=anIt.Value();
232 if (aCntIn!=1 || aCntOut!=1) {
233 bNothingToDo=Standard_False;
238 // Each vertex has one edge In and one - Out. Good. But it is not enought
239 // to consider that nothing to do with this. We must check edges on TShape
240 // coinsidence. If there are such edges there is something to do with.
242 Standard_Integer aNbE, aNbMapEE;
243 Standard_Boolean bFlag;
245 BOPCol_IndexedDataMapOfShapeListOfShape aMapEE(100);
246 aNbE=myEdges.Extent();
248 aIt.Initialize(myEdges);
249 for (; aIt.More(); aIt.Next()) {
250 const TopoDS_Shape& aE = aIt.Value();
251 if (!aMapEE.Contains(aE)) {
252 BOPCol_ListOfShape aLEx;
254 aMapEE.Add(aE, aLEx);
257 BOPCol_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
263 aNbMapEE=aMapEE.Extent();
264 for (i=1; i<=aNbMapEE; ++i) {
265 const BOPCol_ListOfShape& aLEx=aMapEE(i);
267 if (aNbE==1) {// usual case
271 const TopoDS_Shape& aE1=aLEx.First();
272 const TopoDS_Shape& aE2=aLEx.Last();
273 if (aE1.IsSame(aE2)) {
274 bFlag=Standard_False;
279 bFlag=Standard_False;
283 bNothingToDo=bNothingToDo && bFlag;
284 } // if (bNothingToDo) {
288 BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
289 BOPAlgo_WireSplitter::MakeWire(aLECB, aW);
290 BOPCol_ListOfShape& aLoops=aCB.ChangeLoops();
296 // 3. Angles in mySmartMap
297 const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(myFace);
298 const GeomAdaptor_Surface& aGAS=aBAS.Surface();
300 for (i=1; i<=aNb; i++) {
301 const TopoDS_Vertex& aV = (*(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& aE=aEI.Edge();
310 aOr = bIsIN ? TopAbs_REVERSED : TopAbs_FORWARD;
311 aVV.Orientation(aOr);
312 aAngle = Angle2D(aVV, aE, myFace, aGAS, bIsIN, theContext);
313 aEI.SetAngle(aAngle);
315 }// for (i=1; i<=aNb; i++) {
317 //Theme: The treatment p-curves convergent in node.
318 //The refining the angles of p-curves taking into account
319 //bounding curves if exist.
320 RefineAngles(myFace, myEdges, mySmartMap, theContext);
324 Standard_Boolean bIsOut, bIsNotPassed;
325 BOPCol_SequenceOfShape aLS, aVertVa;
326 BOPCol_SequenceOfPnt2d aCoordVa;
328 for (i=1; i<=aNb; ++i) {
329 const TopoDS_Vertex& aVa=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
330 const BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
331 aItLEI.Initialize(aLEI);
332 for (; aItLEI.More(); aItLEI.Next()) {
333 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
334 const TopoDS_Edge& aEOuta=aEI.Edge();
337 bIsNotPassed=!aEI.Passed();
338 if (bIsOut && bIsNotPassed) {
344 Path(aGAS, myFace, aVa, aEOuta, aEI, aLS,
345 aVertVa, aCoordVa, aCB, mySmartMap, aVertMap);
348 }// for (i=1; i<=aNb; ++i) {
350 //=======================================================================
353 //=======================================================================
354 void Path (const GeomAdaptor_Surface& aGAS,
355 const TopoDS_Face& myFace,
356 const TopoDS_Vertex& aVFirst,
357 const TopoDS_Edge& aEFirst,
358 BOPAlgo_EdgeInfo& aEIFirst,
359 BOPCol_SequenceOfShape& aLS,
360 BOPCol_SequenceOfShape& aVertVa,
361 BOPCol_SequenceOfPnt2d& aCoordVa,
362 BOPTools_ConnexityBlock& aCB,
363 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
364 BOPCol_DataMapOfShapeBoolean aVertMap)
367 Standard_Integer i, j, aNb, aNbj;
368 Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
369 Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
370 Standard_Boolean anIsSameV2d, anIsSameV, anIsFound, anIsOut, anIsNotPassed;
371 Standard_Boolean bIsClosed;
372 TopoDS_Vertex aVa, aVb;
374 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
375 Standard_Real eps = Epsilon(1.);
379 BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
381 aTwoPI = M_PI + M_PI;
386 // Do not escape through edge from which you enter
389 const TopoDS_Shape& anEPrev=aLS(aNb);
390 if (anEPrev.IsSame(aEOuta)) {
395 anEdgeInfo->SetPassed(Standard_True);
399 TopoDS_Vertex pVa=aVa;
400 pVa.Orientation(TopAbs_FORWARD);
401 gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
402 aCoordVa.Append(aPa);
404 GetNextVertex (pVa, aEOuta, aVb);
406 gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
408 const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
410 aTol2D = 2.*Tolerance2D(aVb, aGAS);
411 aTol2D2 = aTol2D * aTol2D;
413 bIsClosed = aVertMap.Find(aVb);
415 BOPCol_ListOfShape aBuf;
416 Standard_Boolean bHasEdge = Standard_False;
419 for (i = aNb; i>0; --i) {
420 const TopoDS_Shape& aVPrev=aVertVa(i);
421 const gp_Pnt2d& aPaPrev=aCoordVa(i);
422 const TopoDS_Edge& aEPrev = TopoDS::Edge(aLS(i));
426 bHasEdge = !BRep_Tool::Degenerated(aEPrev);
427 // do not create wire from degenerated edges only
433 anIsSameV = aVPrev.IsSame(aVb);
434 anIsSameV2d = anIsSameV;
437 aD2 = aPaPrev.SquareDistance(aPb);
438 anIsSameV2d = aD2 < aTol2D2;
440 Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
441 Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
442 Standard_Real aTolU = 2.*UTolerance2D(aVb, aGAS);
443 Standard_Real aTolV = 2.*VTolerance2D(aVb, aGAS);
445 if((udist > aTolU) || (vdist > aTolV)) {
446 anIsSameV2d = Standard_False;
452 if (anIsSameV && anIsSameV2d) {
453 Standard_Integer iPriz;
455 if (aBuf.Extent()==2) {
456 if(aBuf.First().IsSame(aBuf.Last())) {
462 BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
463 aCB.ChangeLoops().Append(aW);
476 BOPCol_SequenceOfShape aLSt, aVertVat;
477 BOPCol_SequenceOfPnt2d aCoordVat;
479 aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
481 for (j=1; j<=aNbj; ++j) {
483 aVertVat.Append(aVertVa(j));
484 aCoordVat.Append(aCoordVa(j));
501 BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
503 anAngleIn = AngleIn(aEOuta, aLEInfo);
505 anIsFound = Standard_False;
506 Standard_Integer iCnt = NbWaysOut(aLEInfo);
507 Standard_Integer aCurIndexE = 0;
508 anIt.Initialize(aLEInfo);
509 for (; anIt.More(); anIt.Next()) {
510 BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
511 const TopoDS_Edge& aE=anEI.Edge();
512 anIsOut=!anEI.IsIn();
513 anIsNotPassed=!anEI.Passed();
515 if (anIsOut && anIsNotPassed) {
518 // Is there one way to go out of the vertex
519 // we have to use it only.
522 // no way to go . (Error)
527 // the one and only way to go out .
529 anIsFound=Standard_True;
533 if (aE.IsSame(aEOuta)) {
540 aP2Dx = Coord2dVf(aE, myFace);
542 aD2 = aP2Dx.SquareDistance(aPb);
548 // Look for minimal angle and make the choice.
549 anAngleOut=anEI.Angle();
550 anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
552 if (anAngle < aMinAngle - eps) {
555 anIsFound=Standard_True;
558 } // for (; anIt.More(); anIt.Next())
561 // no way to go . (Error)
566 aEOuta = pEdgeInfo->Edge();
567 anEdgeInfo = pEdgeInfo;
570 //=======================================================================
571 // function: ClockWiseAngle
573 //=======================================================================
574 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
575 const Standard_Real aAngleOut)
577 Standard_Real aTwoPi=M_PI+M_PI;
578 Standard_Real dA, A1, A2, AIn, AOut ;
586 if (AOut >= aTwoPi) {
603 //else if (dA <= 1.e-15) {
604 else if (dA <= 1.e-14) {
609 //=======================================================================
612 //=======================================================================
613 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
614 const TopoDS_Edge& aE1,
615 const TopoDS_Face& aF)
617 Standard_Real aT, aFirst, aLast;
618 Handle(Geom2d_Curve) aC2D;
621 aT=BRep_Tool::Parameter (aV1, aE1, aF);
622 aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
623 aC2D->D0 (aT, aP2D1);
627 //=======================================================================
628 // function: Coord2dVf
630 //=======================================================================
631 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
632 const TopoDS_Face& aF)
634 Standard_Real aCoord=99.;
635 gp_Pnt2d aP2D1(aCoord, aCoord);
639 for (; aIt.More(); aIt.Next()) {
640 const TopoDS_Shape& aVx=aIt.Value();
641 if (aVx.Orientation()==TopAbs_FORWARD) {
643 const TopoDS_Vertex& aVxx=(*(TopoDS_Vertex *)(&aVx));// TopoDS::Vertex(aVx);
644 aP2D1=Coord2d(aVxx, aE, aF);
651 //=======================================================================
652 // function: NbWaysOut
654 //=======================================================================
655 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
657 Standard_Boolean bIsOut, bIsNotPassed;
658 Standard_Integer iCnt=0;
659 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
661 anIt.Initialize(aLEInfo);
662 for (; anIt.More(); anIt.Next()) {
663 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
666 bIsNotPassed=!anEI.Passed();
667 if (bIsOut && bIsNotPassed) {
674 //=======================================================================
677 //=======================================================================
678 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
679 const BOPAlgo_ListOfEdgeInfo& aLEInfo)
681 Standard_Real anAngleIn;
682 Standard_Boolean anIsIn;
683 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
685 anIt.Initialize(aLEInfo);
686 for (; anIt.More(); anIt.Next()) {
687 const BOPAlgo_EdgeInfo& anEdgeInfo=anIt.Value();
688 const TopoDS_Edge& aE=anEdgeInfo.Edge();
689 anIsIn=anEdgeInfo.IsIn();
691 if (anIsIn && aE==aEIn) {
692 anAngleIn=anEdgeInfo.Angle();
699 //=======================================================================
700 // function: GetNextVertex
702 //=======================================================================
703 void GetNextVertex(const TopoDS_Vertex& aV,
704 const TopoDS_Edge& aE,
710 for (; aIt.More(); aIt.Next()) {
711 const TopoDS_Shape& aVx=aIt.Value();
712 if (!aVx.IsEqual(aV)) {
713 aV1=(*(TopoDS_Vertex *)(&aVx));
719 //=======================================================================
722 //=======================================================================
723 Standard_Real Angle2D (const TopoDS_Vertex& aV,
724 const TopoDS_Edge& anEdge,
725 const TopoDS_Face& myFace,
726 const GeomAdaptor_Surface& aGAS,
727 const Standard_Boolean bIsIN,
728 const Handle(IntTools_Context)& theContext)
730 Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
733 Handle(Geom2d_Curve) aC2D;
735 aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
736 if (Precision::IsInfinite(aTV)) {
740 BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D,
741 aFirst, aLast, aToler, theContext);
742 Standard_Real tol2d =2.*Tolerance2D(aV, aGAS);
744 GeomAbs_CurveType aType;
745 Geom2dAdaptor_Curve aGAC2D(aC2D);
747 dt = Max(aGAC2D.Resolution(tol2d), Precision::PConfusion());
749 aType=aGAC2D.GetType();
750 if (aType != GeomAbs_Line )
752 Geom2dLProp_CLProps2d LProp(aC2D, aTV, 2, Precision::PConfusion());
753 if(LProp.IsTangentDefined())
755 Standard_Real R = LProp.Curvature();
756 if(R > Precision::PConfusion())
759 Standard_Real cosphi = R / (R + tol2d);
760 dt = Max(dt, ACos(cosphi)); //to avoid small dt for big R.
764 //for case chl/927/r9
765 aTX=0.05*(aLast - aFirst);//aTX=0.25*(aLast - aFirst);
770 // to save direction of the curve as much as it possible
771 // in the case of big tolerances
775 if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
782 aGAC2D.D0 (aTV1, aPV1);
783 aGAC2D.D0 (aTV, aPV);
785 aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1);
787 gp_Dir2d aDir2D(aV2D);
788 anAngle=Angle(aDir2D);
792 //=======================================================================
795 //=======================================================================
796 Standard_Real Angle (const gp_Dir2d& aDir2D)
798 gp_Dir2d aRefDir(1., 0.);
799 Standard_Real anAngle;
801 anAngle = aRefDir.Angle(aDir2D);
803 anAngle += M_PI + M_PI;
806 //=======================================================================
807 // function: Tolerance2D
809 //=======================================================================
810 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
811 const GeomAdaptor_Surface& aGAS)
813 Standard_Real aTol2D, anUr, aVr, aTolV3D;
814 GeomAbs_SurfaceType aType;
816 aType=aGAS.GetType();
817 aTolV3D=BRep_Tool::Tolerance(aV);
819 anUr=aGAS.UResolution(aTolV3D);
820 aVr =aGAS.VResolution(aTolV3D);
821 aTol2D=(aVr>anUr) ? aVr : anUr;
823 if (aTol2D < aTolV3D) {
826 if (aType==GeomAbs_BSplineSurface) {
833 //=======================================================================
834 //function : UTolerance2D
836 //=======================================================================
837 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
838 const GeomAdaptor_Surface& aGAS)
840 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
841 const Standard_Real anUr = aGAS.UResolution(aTolV3D);
846 //=======================================================================
847 //function : VTolerance2D
849 //=======================================================================
850 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
851 const GeomAdaptor_Surface& aGAS)
853 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
854 const Standard_Real anVr = aGAS.VResolution(aTolV3D);
859 //=======================================================================
860 //function : RefineAngles
862 //=======================================================================
863 void RefineAngles(const TopoDS_Face& myFace,
864 const BOPCol_ListOfShape& myEdges,
865 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
866 const Handle(IntTools_Context)& theContext)
868 Standard_Integer aNb, i;
869 BOPCol_IndexedDataMapOfShapeInteger aMSI;
870 BOPCol_MapOfShape aMBE;
871 BOPCol_ListIteratorOfListOfShape aIt;
874 aIt.Initialize(myEdges);
875 for(; aIt.More(); aIt.Next()) {
876 const TopoDS_Shape& aE=aIt.Value();
877 if(aMSI.Contains(aE)) {
878 Standard_Integer& iCnt = aMSI.ChangeFromKey(aE);
882 Standard_Integer iCnt = 1;
888 for (i = 1; i <= aNb; ++i) {
889 Standard_Integer iCnt = aMSI(i);
891 const TopoDS_Shape& aE = aMSI.FindKey(i);
898 aNb = mySmartMap.Extent();
899 for (i = 1; i <= aNb; ++i) {
900 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&mySmartMap.FindKey(i));
901 BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
903 RefineAngles(aV, myFace, aMBE, aLEI, theContext);
906 //=======================================================================
907 typedef NCollection_DataMap \
908 <TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> \
909 BOPCol_DataMapOfShapeReal;
910 typedef BOPCol_DataMapOfShapeReal::Iterator \
911 BOPCol_DataMapIteratorOfDataMapOfShapeReal;
913 //=======================================================================
914 //function : RefineAngles
916 //=======================================================================
917 void RefineAngles(const TopoDS_Vertex& aV,
918 const TopoDS_Face& myFace,
919 const BOPCol_MapOfShape& aMBE,
920 BOPAlgo_ListOfEdgeInfo& aLEI,
921 const Handle(IntTools_Context)& theContext)
923 Standard_Boolean bIsIn, bIsBoundary, bRefined;
924 Standard_Integer iCntBnd, iCntInt;
925 Standard_Real aA, aA1, aA2;
926 BOPCol_DataMapOfShapeReal aDMSR;
927 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
929 aA1=0.; // angle of outgoing edge
930 aA2=0.; // angle of incoming edge
933 aItLEI.Initialize(aLEI);
934 for (; aItLEI.More(); aItLEI.Next()) {
935 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
936 const TopoDS_Edge& aE=aEI.Edge();
940 if (aMBE.Contains(aE)) {
958 Standard_Real aDelta = ClockWiseAngle(aA2, aA1);
959 aItLEI.Initialize(aLEI);
960 for (; aItLEI.More(); aItLEI.Next()) {
961 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
962 const TopoDS_Edge& aE=aEI.Edge();
964 bIsBoundary=aMBE.Contains(aE);
966 if (bIsBoundary || bIsIn) {
971 Standard_Real aDA = ClockWiseAngle(aA2, aA);
973 continue; // already inside
976 bRefined=RefineAngle2D(aV, aE, myFace, aA1, aA2, aDelta, aA, theContext);
980 else if (iCntInt == 2) {
981 aA = (aA <= aA1) ? (aA1 + Precision::Angular()) :
982 (aA2 - Precision::Angular());
987 if (aDMSR.IsEmpty()) {
992 aItLEI.Initialize(aLEI);
993 for (; aItLEI.More(); aItLEI.Next()) {
994 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
995 const TopoDS_Edge& aE=aEI.Edge();
998 if (!aDMSR.IsBound(aE)) {
1010 //=======================================================================
1011 //function : RefineAngle2D
1013 //=======================================================================
1014 Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
1015 const TopoDS_Edge& aE,
1016 const TopoDS_Face& myFace,
1017 const Standard_Real aA1,
1018 const Standard_Real aA2,
1019 const Standard_Real aDelta,
1021 const Handle(IntTools_Context)& theContext)
1023 Standard_Boolean bRet;
1024 Standard_Integer i, j, aNbP;
1025 Standard_Real aTV, aTol, aT1, aT2, dT, aAngle, aT, aTOp;
1026 Standard_Real aTolInt, aAi, aXi, aYi, aT1j, aT2j, aT1max, aT2max, aCf;
1027 gp_Pnt2d aPV, aP, aP1, aP2;
1028 Handle(Geom2d_Curve) aC2D;
1029 Handle(Geom2d_Line) aLi;
1030 Geom2dAdaptor_Curve aGAC1, aGAC2;
1031 Geom2dInt_GInter aGInter;
1032 IntRes2d_Domain aDomain1, aDomain2;
1038 BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol, theContext);
1039 aGAC1.Load(aC2D, aT1, aT2);
1041 aTV=BRep_Tool::Parameter (aV, aE, myFace);
1044 aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1;
1046 const Standard_Real MaxDT = 0.3 * (aT2 - aT1);
1049 aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
1051 for (i=0; i<2; ++i) {
1052 aAi=(!i) ? aA1 : (aA2 + M_PI);
1055 gp_Dir2d aDiri(aXi, aYi);
1056 aLi=new Geom2d_Line(aPV, aDiri);
1060 aGInter.Perform(aGAC1, aDomain1, aGAC2, aDomain2, aTolInt, aTolInt);
1061 if (!aGInter.IsDone()) {
1065 aNbP = aGInter.NbPoints();
1068 for (j = 1; j <= aNbP; ++j) {
1069 const IntRes2d_IntersectionPoint& aIPj = aGInter.Point(j);
1070 aT1j = aIPj.ParamOnFirst();
1071 aT2j = aIPj.ParamOnSecond();
1073 if (aT2j > aT2max && Abs(aT1j - aTV) < MaxDT) {
1081 if (Abs(dT) < aTolInt) {
1085 aT = aT1max + aCf*dT;
1087 gp_Vec2d aV2D(aPV, aP);
1088 gp_Dir2d aDir2D(aV2D);
1090 aAngle = Angle(aDir2D);
1091 Standard_Real aDA = ClockWiseAngle(aA2, aAngle);
1097 }// for (i=0; i<2; ++i) {