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 <BOPTools_AlgoTools2D.hxx>
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <Geom2d_Curve.hxx>
22 #include <Geom2d_Line.hxx>
23 #include <Geom2dAdaptor_Curve.hxx>
24 #include <Geom2dInt_GInter.hxx>
25 #include <Geom_Plane.hxx>
26 #include <Geom_RectangularTrimmedSurface.hxx>
27 #include <Geom_Surface.hxx>
28 #include <GeomAdaptor_Surface.hxx>
29 #include <gp_Dir2d.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <gp_Vec2d.hxx>
32 #include <IntRes2d_Domain.hxx>
33 #include <IntRes2d_IntersectionPoint.hxx>
34 #include <Precision.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopLoc_Location.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Iterator.hxx>
42 #include <TopoDS_Vertex.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <TopTools_ShapeMapHasher.hxx>
45 #include <Geom2dLProp_CLProps2d.hxx>
46 #include <TColgp_SequenceOfPnt2d.hxx>
47 #include <TColStd_SequenceOfReal.hxx>
48 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
49 #include <TopTools_ListOfShape.hxx>
50 #include <TopTools_MapOfShape.hxx>
51 #include <TopTools_SequenceOfShape.hxx>
53 typedef NCollection_DataMap \
54 <TopoDS_Shape, Standard_Boolean, TopTools_ShapeMapHasher> \
55 MyDataMapOfShapeBoolean;
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 MyDataMapOfShapeBoolean& aVertMap,
98 const TopoDS_Vertex& aVa,
99 const TopoDS_Edge& aEOuta,
100 BOPAlgo_EdgeInfo& anEdgeInfo,
101 TopTools_SequenceOfShape& aLS,
102 TopTools_SequenceOfShape& aVertVa,
103 TColgp_SequenceOfPnt2d& aCoordVa,
104 BOPTools_ConnexityBlock& aCB,
105 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap);
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 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo&,
126 const Handle(IntTools_Context)&);
130 void RefineAngles(const TopoDS_Vertex& ,
132 BOPAlgo_ListOfEdgeInfo&,
133 const Handle(IntTools_Context)&);
136 Standard_Boolean RefineAngle2D(const TopoDS_Vertex& ,
139 const Standard_Real ,
140 const Standard_Real ,
143 const Handle(IntTools_Context)& );
145 //=======================================================================
146 //function : SplitBlock
148 //=======================================================================
149 void BOPAlgo_WireSplitter::SplitBlock(const TopoDS_Face& myFace,
150 BOPTools_ConnexityBlock& aCB,
151 const Handle(IntTools_Context)& theContext)
153 Standard_Boolean bNothingToDo, bIsClosed, bIsIN;
154 Standard_Integer aIx, aNb, i, aCntIn, aCntOut;
155 Standard_Real aAngle;
156 TopAbs_Orientation aOr;
157 TopoDS_Iterator aItS;
160 TopTools_ListIteratorOfListOfShape aIt;
161 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
163 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo mySmartMap(100);
164 MyDataMapOfShapeBoolean aVertMap;
166 const TopTools_ListOfShape& myEdges=aCB.Shapes();
168 TopTools_MapOfShape aMS;
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);
181 if (!aMS.Add (aE) && !bIsClosed)
186 for(i = 0; aItS.More(); aItS.Next(), ++i) {
187 const TopoDS_Shape& aV = aItS.Value();
188 aIx = mySmartMap.FindIndex(aV);
190 BOPAlgo_ListOfEdgeInfo aLEIx;
191 aIx = mySmartMap.Add(aV, aLEIx);
194 BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap(aIx);
195 BOPAlgo_EdgeInfo aEI;
198 aOr = aV.Orientation();
199 bIsIN = (aOr == TopAbs_REVERSED);
200 aEI.SetInFlag(bIsIN);
206 bIsClosed = bIsClosed || aV1.IsSame(aV);
209 if (aVertMap.IsBound(aV)) {
211 aVertMap.ChangeFind(aV) = bIsClosed;
214 aVertMap.Bind(aV, bIsClosed);
219 aNb=mySmartMap.Extent();
221 bNothingToDo=Standard_True;
222 for (i=1; i<=aNb; i++) {
225 const BOPAlgo_ListOfEdgeInfo& aLEInfo = mySmartMap(i);
226 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt(aLEInfo);
227 for (; anIt.More(); anIt.Next()) {
228 const BOPAlgo_EdgeInfo& aEI=anIt.Value();
236 if (aCntIn!=1 || aCntOut!=1) {
237 bNothingToDo=Standard_False;
242 // Each vertex has one edge In and one - Out. Good. But it is not enought
243 // to consider that nothing to do with this. We must check edges on TShape
244 // coinsidence. If there are such edges there is something to do with.
246 Standard_Integer aNbE, aNbMapEE;
247 Standard_Boolean bFlag;
249 TopTools_IndexedDataMapOfShapeListOfShape aMapEE(100);
250 aNbE=myEdges.Extent();
252 aIt.Initialize(myEdges);
253 for (; aIt.More(); aIt.Next()) {
254 const TopoDS_Shape& aE = aIt.Value();
255 if (!aMapEE.Contains(aE)) {
256 TopTools_ListOfShape aLEx;
258 aMapEE.Add(aE, aLEx);
261 TopTools_ListOfShape& aLEx=aMapEE.ChangeFromKey(aE);
267 aNbMapEE=aMapEE.Extent();
268 for (i=1; i<=aNbMapEE; ++i) {
269 const TopTools_ListOfShape& aLEx=aMapEE(i);
271 if (aNbE==1) {// usual case
275 const TopoDS_Shape& aE1=aLEx.First();
276 const TopoDS_Shape& aE2=aLEx.Last();
277 if (aE1.IsSame(aE2)) {
278 bFlag=Standard_False;
283 bFlag=Standard_False;
287 bNothingToDo=bNothingToDo && bFlag;
288 } // if (bNothingToDo) {
292 TopTools_ListOfShape& aLECB=aCB.ChangeShapes();
293 BOPAlgo_WireSplitter::MakeWire(aLECB, aW);
294 TopTools_ListOfShape& aLoops=aCB.ChangeLoops();
300 // 3. Angles in mySmartMap
301 const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(myFace);
302 const GeomAdaptor_Surface& aGAS=aBAS.Surface();
304 for (i=1; i<=aNb; i++) {
305 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
306 const BOPAlgo_ListOfEdgeInfo& aLEI= mySmartMap(i);
307 aItLEI.Initialize(aLEI);
308 for (; aItLEI.More(); aItLEI.Next()) {
309 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
310 const TopoDS_Edge& aE=aEI.Edge();
311 aEI.SetIsInside (!aMS.Contains (aE));
315 aOr = bIsIN ? TopAbs_REVERSED : TopAbs_FORWARD;
316 aVV.Orientation(aOr);
317 aAngle = Angle2D(aVV, aE, myFace, aGAS, bIsIN, theContext);
318 aEI.SetAngle(aAngle);
320 }// for (i=1; i<=aNb; i++) {
322 //Theme: The treatment p-curves convergent in node.
323 //The refining the angles of p-curves taking into account
324 //bounding curves if exist.
325 RefineAngles(myFace, mySmartMap, theContext);
329 Standard_Boolean bIsOut, bIsNotPassed;
330 TopTools_SequenceOfShape aLS, aVertVa;
331 TColgp_SequenceOfPnt2d aCoordVa;
333 for (i=1; i<=aNb; ++i) {
334 const TopoDS_Vertex& aVa=(*(TopoDS_Vertex *)(&mySmartMap.FindKey(i)));
335 const BOPAlgo_ListOfEdgeInfo& aLEI=mySmartMap(i);
336 aItLEI.Initialize(aLEI);
337 for (; aItLEI.More(); aItLEI.Next()) {
338 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
339 const TopoDS_Edge& aEOuta=aEI.Edge();
342 bIsNotPassed=!aEI.Passed();
343 if (bIsOut && bIsNotPassed) {
349 Path(aGAS, myFace, aVertMap, aVa, aEOuta, aEI, aLS,
350 aVertVa, aCoordVa, aCB, mySmartMap);
353 }// for (i=1; i<=aNb; ++i) {
355 //=======================================================================
358 //=======================================================================
359 void Path (const GeomAdaptor_Surface& aGAS,
360 const TopoDS_Face& myFace,
361 const MyDataMapOfShapeBoolean& aVertMap,
362 const TopoDS_Vertex& aVFirst,
363 const TopoDS_Edge& aEFirst,
364 BOPAlgo_EdgeInfo& aEIFirst,
365 TopTools_SequenceOfShape& aLS,
366 TopTools_SequenceOfShape& aVertVa,
367 TColgp_SequenceOfPnt2d& aCoordVa,
368 BOPTools_ConnexityBlock& aCB,
369 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap)
371 Standard_Integer i, j, aNb, aNbj;
372 Standard_Real anAngleIn, anAngleOut, anAngle, aMinAngle;
373 Standard_Real aTol2D, aTol2D2, aD2, aTwoPI;
374 Standard_Boolean anIsSameV2d, anIsSameV, anIsOut, anIsNotPassed;
375 Standard_Boolean bIsClosed;
376 TopoDS_Vertex aVa, aVb;
378 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
379 Standard_Real eps = Epsilon(1.);
383 BOPAlgo_EdgeInfo* anEdgeInfo = &aEIFirst;
385 aTwoPI = M_PI + M_PI;
387 NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeq;
392 // Do not escape through edge from which you enter
395 const TopoDS_Shape& anEPrev=aLS(aNb);
396 if (anEPrev.IsSame(aEOuta)) {
401 anEdgeInfo->SetPassed(Standard_True);
404 anInfoSeq.Append (anEdgeInfo);
406 TopoDS_Vertex pVa=aVa;
407 pVa.Orientation(TopAbs_FORWARD);
408 gp_Pnt2d aPa=Coord2d(pVa, aEOuta, myFace);
409 aCoordVa.Append(aPa);
411 GetNextVertex (pVa, aEOuta, aVb);
413 gp_Pnt2d aPb=Coord2d(aVb, aEOuta, myFace);
415 const BOPAlgo_ListOfEdgeInfo& aLEInfo=mySmartMap.FindFromKey(aVb);
417 aTol2D = 2.*Tolerance2D(aVb, aGAS);
418 aTol2D2 = aTol2D * aTol2D;
420 bIsClosed = aVertMap.Find(aVb);
422 TopTools_ListOfShape aBuf;
423 Standard_Boolean bHasEdge = Standard_False;
426 for (i = aNb; i>0; --i) {
427 const TopoDS_Shape& aVPrev=aVertVa(i);
428 const gp_Pnt2d& aPaPrev=aCoordVa(i);
429 const TopoDS_Edge& aEPrev = TopoDS::Edge(aLS(i));
433 bHasEdge = !BRep_Tool::Degenerated(aEPrev);
434 // do not create wire from degenerated edges only
440 anIsSameV = aVPrev.IsSame(aVb);
441 anIsSameV2d = anIsSameV;
444 aD2 = aPaPrev.SquareDistance(aPb);
445 anIsSameV2d = aD2 < aTol2D2;
447 Standard_Real udist = fabs(aPaPrev.X() - aPb.X());
448 Standard_Real vdist = fabs(aPaPrev.Y() - aPb.Y());
449 Standard_Real aTolU = 2.*UTolerance2D(aVb, aGAS);
450 Standard_Real aTolV = 2.*VTolerance2D(aVb, aGAS);
452 if((udist > aTolU) || (vdist > aTolV)) {
453 anIsSameV2d = Standard_False;
459 if (anIsSameV && anIsSameV2d) {
460 Standard_Integer iPriz;
462 if (aBuf.Extent()==2) {
463 if(aBuf.First().IsSame(aBuf.Last())) {
469 BOPAlgo_WireSplitter::MakeWire(aBuf, aW);
470 aCB.ChangeLoops().Append(aW);
483 TopTools_SequenceOfShape aLSt, aVertVat;
484 TColgp_SequenceOfPnt2d aCoordVat;
485 NCollection_Sequence <BOPAlgo_EdgeInfo*> anInfoSeqTmp;
487 aVb=(*(TopoDS_Vertex *)(&aVertVa(i)));
489 for (j=1; j<=aNbj; ++j) {
491 aVertVat.Append(aVertVa(j));
492 aCoordVat.Append(aCoordVa(j));
493 anInfoSeqTmp.Append (anInfoSeq (j));
499 anInfoSeq = anInfoSeqTmp;
501 aEOuta = TopoDS::Edge (aLS.Last());
502 anEdgeInfo = anInfoSeq.Last();
510 BOPAlgo_EdgeInfo *pEdgeInfo=NULL;
512 anAngleIn = AngleIn(aEOuta, aLEInfo);
514 Standard_Integer iCnt = NbWaysOut(aLEInfo);
516 Standard_Boolean isBoundary = !anEdgeInfo->IsInside();
517 Standard_Integer aNbWaysInside = 0;
518 BOPAlgo_EdgeInfo *pOnlyWayIn = NULL;
520 Standard_Integer aCurIndexE = 0;
521 anIt.Initialize(aLEInfo);
522 for (; anIt.More(); anIt.Next()) {
523 BOPAlgo_EdgeInfo& anEI=anIt.ChangeValue();
524 const TopoDS_Edge& aE=anEI.Edge();
525 anIsOut=!anEI.IsIn();
526 anIsNotPassed=!anEI.Passed();
528 if (anIsOut && anIsNotPassed) {
531 // Is there one way to go out of the vertex
532 // we have to use it only.
535 // no way to go . (Error)
540 // the one and only way to go out .
545 if (aE.IsSame(aEOuta)) {
552 aP2Dx = Coord2dVf(aE, myFace);
554 aD2 = aP2Dx.SquareDistance(aPb);
560 // Look for minimal angle and make the choice.
561 anAngleOut=anEI.Angle();
562 anAngle=ClockWiseAngle(anAngleIn, anAngleOut);
565 if (isBoundary && anEI.IsInside())
571 if (anAngle < aMinAngle - eps) {
576 } // for (; anIt.More(); anIt.Next())
577 if (aNbWaysInside == 1)
579 pEdgeInfo = pOnlyWayIn;
583 // no way to go . (Error)
588 aEOuta = pEdgeInfo->Edge();
589 anEdgeInfo = pEdgeInfo;
592 //=======================================================================
593 // function: ClockWiseAngle
595 //=======================================================================
596 Standard_Real ClockWiseAngle(const Standard_Real aAngleIn,
597 const Standard_Real aAngleOut)
599 Standard_Real aTwoPi=M_PI+M_PI;
600 Standard_Real dA, A1, A2, AIn, AOut ;
608 if (AOut >= aTwoPi) {
625 //else if (dA <= 1.e-15) {
626 else if (dA <= 1.e-14) {
631 //=======================================================================
634 //=======================================================================
635 gp_Pnt2d Coord2d (const TopoDS_Vertex& aV1,
636 const TopoDS_Edge& aE1,
637 const TopoDS_Face& aF)
639 Standard_Real aT, aFirst, aLast;
640 Handle(Geom2d_Curve) aC2D;
643 aT=BRep_Tool::Parameter (aV1, aE1, aF);
644 aC2D=BRep_Tool::CurveOnSurface(aE1, aF, aFirst, aLast);
645 aC2D->D0 (aT, aP2D1);
649 //=======================================================================
650 // function: Coord2dVf
652 //=======================================================================
653 gp_Pnt2d Coord2dVf (const TopoDS_Edge& aE,
654 const TopoDS_Face& aF)
656 Standard_Real aCoord=99.;
657 gp_Pnt2d aP2D1(aCoord, aCoord);
661 for (; aIt.More(); aIt.Next()) {
662 const TopoDS_Shape& aVx=aIt.Value();
663 if (aVx.Orientation()==TopAbs_FORWARD) {
665 const TopoDS_Vertex& aVxx=(*(TopoDS_Vertex *)(&aVx));// TopoDS::Vertex(aVx);
666 aP2D1=Coord2d(aVxx, aE, aF);
673 //=======================================================================
674 // function: NbWaysOut
676 //=======================================================================
677 Standard_Integer NbWaysOut(const BOPAlgo_ListOfEdgeInfo& aLEInfo)
679 Standard_Boolean bIsOut, bIsNotPassed;
680 Standard_Integer iCnt=0;
681 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
683 anIt.Initialize(aLEInfo);
684 for (; anIt.More(); anIt.Next()) {
685 const BOPAlgo_EdgeInfo& anEI=anIt.Value();
688 bIsNotPassed=!anEI.Passed();
689 if (bIsOut && bIsNotPassed) {
696 //=======================================================================
699 //=======================================================================
700 Standard_Real AngleIn(const TopoDS_Edge& aEIn,
701 const BOPAlgo_ListOfEdgeInfo& aLEInfo)
703 Standard_Real anAngleIn;
704 Standard_Boolean anIsIn;
705 BOPAlgo_ListIteratorOfListOfEdgeInfo anIt;
707 anIt.Initialize(aLEInfo);
708 for (; anIt.More(); anIt.Next()) {
709 const BOPAlgo_EdgeInfo& anEdgeInfo=anIt.Value();
710 const TopoDS_Edge& aE=anEdgeInfo.Edge();
711 anIsIn=anEdgeInfo.IsIn();
713 if (anIsIn && aE==aEIn) {
714 anAngleIn=anEdgeInfo.Angle();
721 //=======================================================================
722 // function: GetNextVertex
724 //=======================================================================
725 void GetNextVertex(const TopoDS_Vertex& aV,
726 const TopoDS_Edge& aE,
732 for (; aIt.More(); aIt.Next()) {
733 const TopoDS_Shape& aVx=aIt.Value();
734 if (!aVx.IsEqual(aV)) {
735 aV1=(*(TopoDS_Vertex *)(&aVx));
741 //=======================================================================
744 //=======================================================================
745 Standard_Real Angle2D (const TopoDS_Vertex& aV,
746 const TopoDS_Edge& anEdge,
747 const TopoDS_Face& myFace,
748 const GeomAdaptor_Surface& aGAS,
749 const Standard_Boolean bIsIN,
750 const Handle(IntTools_Context)& theContext)
752 Standard_Real aFirst, aLast, aToler, dt, aTV, aTV1, anAngle, aTX;
755 Handle(Geom2d_Curve) aC2D;
757 aTV=BRep_Tool::Parameter (aV, anEdge, myFace);
758 if (Precision::IsInfinite(aTV)) {
762 BOPTools_AlgoTools2D::CurveOnSurface (anEdge, myFace, aC2D,
763 aFirst, aLast, aToler, theContext);
764 Standard_Real tol2d =2.*Tolerance2D(aV, aGAS);
766 GeomAbs_CurveType aType;
767 Geom2dAdaptor_Curve aGAC2D(aC2D);
769 dt = Max(aGAC2D.Resolution(tol2d), Precision::PConfusion());
771 aType=aGAC2D.GetType();
772 if (aType != GeomAbs_Line )
774 Geom2dLProp_CLProps2d LProp(aC2D, aTV, 2, Precision::PConfusion());
775 if(LProp.IsTangentDefined())
777 Standard_Real R = LProp.Curvature();
778 if(R > Precision::PConfusion())
781 Standard_Real cosphi = R / (R + tol2d);
782 dt = Max(dt, ACos(cosphi)); //to avoid small dt for big R.
786 //for case chl/927/r9
787 aTX=0.05*(aLast - aFirst);//aTX=0.25*(aLast - aFirst);
792 // to save direction of the curve as much as it possible
793 // in the case of big tolerances
797 if (fabs (aTV-aFirst) < fabs(aTV - aLast)) {
804 aGAC2D.D0 (aTV1, aPV1);
805 aGAC2D.D0 (aTV, aPV);
807 aV2D = bIsIN ? gp_Vec2d(aPV1, aPV) : gp_Vec2d(aPV, aPV1);
809 gp_Dir2d aDir2D(aV2D);
810 anAngle=Angle(aDir2D);
814 //=======================================================================
817 //=======================================================================
818 Standard_Real Angle (const gp_Dir2d& aDir2D)
820 gp_Dir2d aRefDir(1., 0.);
821 Standard_Real anAngle;
823 anAngle = aRefDir.Angle(aDir2D);
825 anAngle += M_PI + M_PI;
828 //=======================================================================
829 // function: Tolerance2D
831 //=======================================================================
832 Standard_Real Tolerance2D (const TopoDS_Vertex& aV,
833 const GeomAdaptor_Surface& aGAS)
835 Standard_Real aTol2D, anUr, aVr, aTolV3D;
836 GeomAbs_SurfaceType aType;
838 aType=aGAS.GetType();
839 aTolV3D=BRep_Tool::Tolerance(aV);
841 anUr=aGAS.UResolution(aTolV3D);
842 aVr =aGAS.VResolution(aTolV3D);
843 aTol2D=(aVr>anUr) ? aVr : anUr;
845 if (aTol2D < aTolV3D) {
848 if (aType==GeomAbs_BSplineSurface) {
855 //=======================================================================
856 //function : UTolerance2D
858 //=======================================================================
859 Standard_Real UTolerance2D (const TopoDS_Vertex& aV,
860 const GeomAdaptor_Surface& aGAS)
862 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
863 const Standard_Real anUr = aGAS.UResolution(aTolV3D);
868 //=======================================================================
869 //function : VTolerance2D
871 //=======================================================================
872 Standard_Real VTolerance2D (const TopoDS_Vertex& aV,
873 const GeomAdaptor_Surface& aGAS)
875 const Standard_Real aTolV3D = BRep_Tool::Tolerance(aV);
876 const Standard_Real anVr = aGAS.VResolution(aTolV3D);
881 //=======================================================================
882 //function : RefineAngles
884 //=======================================================================
885 void RefineAngles(const TopoDS_Face& myFace,
886 BOPAlgo_IndexedDataMapOfShapeListOfEdgeInfo& mySmartMap,
887 const Handle(IntTools_Context)& theContext)
889 const Standard_Integer aNb = mySmartMap.Extent();
890 for (Standard_Integer i = 1; i <= aNb; ++i)
892 const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&mySmartMap.FindKey (i));
893 BOPAlgo_ListOfEdgeInfo& aLEI = mySmartMap (i);
894 RefineAngles(aV, myFace, aLEI, theContext);
897 //=======================================================================
898 typedef NCollection_DataMap \
899 <TopoDS_Shape, Standard_Real, TopTools_ShapeMapHasher> \
900 TopTools_DataMapOfShapeReal;
901 typedef TopTools_DataMapOfShapeReal::Iterator \
902 TopTools_DataMapIteratorOfDataMapOfShapeReal;
904 //=======================================================================
905 //function : RefineAngles
907 //=======================================================================
908 void RefineAngles(const TopoDS_Vertex& aV,
909 const TopoDS_Face& myFace,
910 BOPAlgo_ListOfEdgeInfo& aLEI,
911 const Handle(IntTools_Context)& theContext)
913 Standard_Boolean bIsIn, bIsBoundary, bRefined;
914 Standard_Integer iCntBnd, iCntInt;
915 Standard_Real aA, aA1, aA2;
916 TopTools_DataMapOfShapeReal aDMSR;
917 BOPAlgo_ListIteratorOfListOfEdgeInfo aItLEI;
919 aA1=0.; // angle of outgoing edge
920 aA2=0.; // angle of incoming edge
923 aItLEI.Initialize(aLEI);
924 for (; aItLEI.More(); aItLEI.Next()) {
925 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
929 if (!aEI.IsInside()) {
947 Standard_Real aDelta = ClockWiseAngle(aA2, aA1);
948 aItLEI.Initialize(aLEI);
949 for (; aItLEI.More(); aItLEI.Next()) {
950 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
951 const TopoDS_Edge& aE=aEI.Edge();
953 bIsBoundary=!aEI.IsInside();
955 if (bIsBoundary || bIsIn) {
960 Standard_Real aDA = ClockWiseAngle(aA2, aA);
962 continue; // already inside
965 bRefined=RefineAngle2D(aV, aE, myFace, aA1, aA2, aDelta, aA, theContext);
969 else if (iCntInt == 2) {
970 aA = (aA <= aA1) ? (aA1 + Precision::Angular()) :
971 (aA2 - Precision::Angular());
976 if (aDMSR.IsEmpty()) {
981 aItLEI.Initialize(aLEI);
982 for (; aItLEI.More(); aItLEI.Next()) {
983 BOPAlgo_EdgeInfo& aEI=aItLEI.ChangeValue();
984 const TopoDS_Edge& aE=aEI.Edge();
987 if (!aDMSR.IsBound(aE)) {
999 //=======================================================================
1000 //function : RefineAngle2D
1002 //=======================================================================
1003 Standard_Boolean RefineAngle2D(const TopoDS_Vertex& aV,
1004 const TopoDS_Edge& aE,
1005 const TopoDS_Face& myFace,
1006 const Standard_Real aA1,
1007 const Standard_Real aA2,
1008 const Standard_Real aDelta,
1010 const Handle(IntTools_Context)& theContext)
1012 Standard_Boolean bRet;
1013 Standard_Integer i, j, aNbP;
1014 Standard_Real aTV, aTol, aT1, aT2, dT, aAngle, aT, aTOp;
1015 Standard_Real aTolInt, aAi, aXi, aYi, aT1j, aT2j, aT1max, aT2max, aCf;
1016 gp_Pnt2d aPV, aP, aP1, aP2;
1017 Handle(Geom2d_Curve) aC2D;
1018 Handle(Geom2d_Line) aLi;
1019 Geom2dAdaptor_Curve aGAC1, aGAC2;
1020 Geom2dInt_GInter aGInter;
1021 IntRes2d_Domain aDomain1, aDomain2;
1027 BOPTools_AlgoTools2D::CurveOnSurface(aE, myFace, aC2D, aT1, aT2, aTol, theContext);
1028 aGAC1.Load(aC2D, aT1, aT2);
1030 aTV=BRep_Tool::Parameter (aV, aE, myFace);
1033 aTOp = (fabs(aTV-aT1) < fabs(aTV-aT2)) ? aT2 : aT1;
1035 const Standard_Real MaxDT = 0.3 * (aT2 - aT1);
1038 aDomain1.SetValues(aP1, aT1, aTolInt, aP2, aT2, aTolInt);
1040 for (i=0; i<2; ++i) {
1041 aAi=(!i) ? aA1 : (aA2 + M_PI);
1044 gp_Dir2d aDiri(aXi, aYi);
1045 aLi=new Geom2d_Line(aPV, aDiri);
1049 aGInter.Perform(aGAC1, aDomain1, aGAC2, aDomain2, aTolInt, aTolInt);
1050 if (!aGInter.IsDone()) {
1054 aNbP = aGInter.NbPoints();
1057 for (j = 1; j <= aNbP; ++j) {
1058 const IntRes2d_IntersectionPoint& aIPj = aGInter.Point(j);
1059 aT1j = aIPj.ParamOnFirst();
1060 aT2j = aIPj.ParamOnSecond();
1062 if (aT2j > aT2max && Abs(aT1j - aTV) < MaxDT) {
1070 if (Abs(dT) < aTolInt) {
1074 aT = aT1max + aCf*dT;
1076 gp_Vec2d aV2D(aPV, aP);
1077 gp_Dir2d aDir2D(aV2D);
1079 aAngle = Angle(aDir2D);
1080 Standard_Real aDA = ClockWiseAngle(aA2, aAngle);
1086 }// for (i=0; i<2; ++i) {