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.
16 #include <Adaptor3d_CurveOnSurface.hxx>
17 #include <Adaptor3d_HCurve.hxx>
18 #include <Adaptor3d_HCurveOnSurface.hxx>
19 #include <BOPTools_AlgoTools.hxx>
20 #include <BOPTools_Parallel.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRep_CurveRepresentation.hxx>
23 #include <BRep_GCurve.hxx>
24 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
25 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
26 #include <BRep_PointRepresentation.hxx>
27 #include <BRep_TEdge.hxx>
28 #include <BRep_TFace.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRep_TVertex.hxx>
31 #include <BRepAdaptor_Surface.hxx>
32 #include <BRepAdaptor_Curve.hxx>
33 #include <BRepLib_CheckCurveOnSurface.hxx>
34 #include <BRepTools_WireExplorer.hxx>
35 #include <Extrema_LocateExtPC.hxx>
36 #include <Geom2d_Curve.hxx>
37 #include <Geom2dAdaptor.hxx>
38 #include <Geom2dAdaptor_Curve.hxx>
39 #include <Geom2dAdaptor_HCurve.hxx>
40 #include <Geom2dInt_GInter.hxx>
41 #include <Geom_Curve.hxx>
42 #include <Geom_Plane.hxx>
43 #include <Geom_RectangularTrimmedSurface.hxx>
44 #include <Geom_Surface.hxx>
45 #include <Geom_TrimmedCurve.hxx>
46 #include <GeomAdaptor_Curve.hxx>
47 #include <GeomAdaptor_HCurve.hxx>
48 #include <GeomAdaptor_HSurface.hxx>
49 #include <GeomAdaptor_Surface.hxx>
50 #include <GeomProjLib.hxx>
51 #include <GCPnts_AbscissaPoint.hxx>
53 #include <gp_Pnt2d.hxx>
54 #include <IntRes2d_Domain.hxx>
55 #include <IntRes2d_IntersectionPoint.hxx>
56 #include <IntRes2d_IntersectionSegment.hxx>
57 #include <IntTools_Context.hxx>
58 #include <IntTools_Curve.hxx>
59 #include <IntTools_Range.hxx>
60 #include <IntTools_Tools.hxx>
61 #include <NCollection_Vector.hxx>
62 #include <ProjLib_ProjectedCurve.hxx>
64 #include <TopExp_Explorer.hxx>
65 #include <TopLoc_Location.hxx>
67 #include <TopoDS_Edge.hxx>
68 #include <TopoDS_Face.hxx>
69 #include <TopoDS_Iterator.hxx>
70 #include <TopoDS_Shape.hxx>
71 #include <TopoDS_Shell.hxx>
72 #include <TopoDS_Solid.hxx>
73 #include <TopoDS_Vertex.hxx>
74 #include <TopoDS_Wire.hxx>
75 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
76 #include <TopTools_IndexedMapOfShape.hxx>
77 #include <TopTools_ListIteratorOfListOfShape.hxx>
78 #include <TopTools_ListOfShape.hxx>
82 void CheckEdge (const TopoDS_Edge& E,
83 const Standard_Real aMaxTol,
84 const TopTools_IndexedMapOfShape& aMapToAvoid);
86 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
88 const Standard_Real aMaxTol,
89 const TopTools_IndexedMapOfShape& aMapToAvoid);
91 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
92 const Adaptor3d_Curve& Other,
93 const Standard_Real Tol,
94 const Standard_Boolean SameParameter,
95 Standard_Real& aNewTolerance);
98 void CorrectVertexTolerance(const TopoDS_Edge& aE,
99 const TopTools_IndexedMapOfShape& aMapToAvoid);
102 void CorrectWires(const TopoDS_Face& aF,
103 const TopTools_IndexedMapOfShape& aMapToAvoid);
108 void UpdateEdges(const TopoDS_Face& aF,
109 const TopTools_IndexedMapOfShape& aMapToAvoid);
112 void UpdateShape(const TopoDS_Shape& aS,
113 const Standard_Real aTol,
114 const TopTools_IndexedMapOfShape& aMapToAvoid);
116 //=======================================================================
117 //class : BOPTools_CPC
119 //=======================================================================
123 : myMaxTol(1.e-7), mypMapToAvoid(0L) {
129 void SetEdge(const TopoDS_Edge& aE) {
133 const TopoDS_Edge& Edge()const {
137 void SetMaxTol(const Standard_Real aMaxTol) {
141 Standard_Real MaxTol()const {
145 void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
146 mypMapToAvoid = &aMapToAvoid;
150 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
151 CheckEdge(myEdge, myMaxTol, *mypMapToAvoid);
155 Standard_Real myMaxTol;
157 const TopTools_IndexedMapOfShape* mypMapToAvoid;
160 //=======================================================================
161 typedef NCollection_Vector<BOPTools_CPC> BOPTools_VectorOfCPC;
163 //=======================================================================
164 //class : BOPTools_CWT
166 //=======================================================================
169 BOPTools_CWT() : mypMapToAvoid(0L) {
175 void SetFace(const TopoDS_Face& aF) {
179 void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
180 mypMapToAvoid = &aMapToAvoid;
184 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
185 CorrectWires(myFace, *mypMapToAvoid);
190 const TopTools_IndexedMapOfShape* mypMapToAvoid;
192 //=======================================================================
193 typedef NCollection_Vector<BOPTools_CWT> BOPTools_VectorOfCWT;
195 //=======================================================================
196 //class : BOPTools_CDT
198 //=======================================================================
202 : myMaxTol(1.e-7), mypMapToAvoid(0L) {
208 void SetEdge(const TopoDS_Edge& aE) {
212 void SetFace(const TopoDS_Face& aF) {
216 void SetMaxTol(const Standard_Real aMaxTol) {
220 void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
221 mypMapToAvoid = &aMapToAvoid;
225 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
226 CorrectEdgeTolerance (myEdge, myFace, myMaxTol, *mypMapToAvoid);
230 Standard_Real myMaxTol;
233 const TopTools_IndexedMapOfShape* mypMapToAvoid;
235 //=======================================================================
236 typedef NCollection_Vector<BOPTools_CDT> BOPTools_VectorOfCDT;
238 //=======================================================================
239 //class : BOPTools_CVT
241 //=======================================================================
244 BOPTools_CVT() : mypMapToAvoid(0L) {
250 void SetEdge(const TopoDS_Edge& aE) {
254 void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
255 mypMapToAvoid = &aMapToAvoid;
259 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
260 CorrectVertexTolerance(myEdge, *mypMapToAvoid);
265 const TopTools_IndexedMapOfShape* mypMapToAvoid;
268 //=======================================================================
269 typedef NCollection_Vector<BOPTools_CVT> BOPTools_VectorOfCVT;
271 //=======================================================================
272 //class : BOPTools_CET
274 //=======================================================================
277 BOPTools_CET() : mypMapToAvoid(0L) {
283 void SetFace(const TopoDS_Face& aF) {
287 void SetMapToAvoid(const TopTools_IndexedMapOfShape& aMapToAvoid) {
288 mypMapToAvoid = &aMapToAvoid;
292 Standard_ProgramError_Raise_if(!mypMapToAvoid, "mypMapToAvoid is null");
293 UpdateEdges(myFace, *mypMapToAvoid);
298 const TopTools_IndexedMapOfShape* mypMapToAvoid;
300 //=======================================================================
301 typedef NCollection_Vector<BOPTools_CET> BOPTools_VectorOfCET;
303 //=======================================================================
304 // Function : CorrectTolerances
306 //=======================================================================
307 void BOPTools_AlgoTools::CorrectTolerances
308 (const TopoDS_Shape& aShape,
309 const TopTools_IndexedMapOfShape& aMapToAvoid,
310 const Standard_Real aMaxTol,
311 const Standard_Boolean bRunParallel)
313 BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMapToAvoid, aMaxTol, bRunParallel);
314 BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMapToAvoid, aMaxTol, bRunParallel);
317 //=======================================================================
318 // Function : CorrectPointOnCurve
320 //=======================================================================
321 void BOPTools_AlgoTools::CorrectPointOnCurve
322 (const TopoDS_Shape& aS,
323 const TopTools_IndexedMapOfShape& aMapToAvoid,
324 const Standard_Real aMaxTol,
325 const Standard_Boolean bRunParallel)
327 TopExp_Explorer aExp;
328 BOPTools_VectorOfCPC aVCPC;
330 aExp.Init(aS, TopAbs_EDGE);
331 for(; aExp.More(); aExp.Next()) {
332 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
333 BOPTools_CPC& aCPC=aVCPC.Appended();
335 aCPC.SetMaxTol(aMaxTol);
336 aCPC.SetMapToAvoid(aMapToAvoid);
339 //======================================================
340 BOPTools_Parallel::Perform (bRunParallel, aVCPC);
341 //======================================================
343 //=======================================================================
344 // Function : CorrectCurveOnSurface
346 //=======================================================================
347 void BOPTools_AlgoTools::CorrectCurveOnSurface
348 (const TopoDS_Shape& aS,
349 const TopTools_IndexedMapOfShape& aMapToAvoid,
350 const Standard_Real aMaxTol,
351 const Standard_Boolean bRunParallel)
353 TopExp_Explorer aExpF, aExpE;
354 BOPTools_VectorOfCWT aVCWT;
355 BOPTools_VectorOfCDT aVCDT;
357 aExpF.Init(aS, TopAbs_FACE);
358 for (; aExpF.More(); aExpF.Next()) {
359 const TopoDS_Face& aF=*((TopoDS_Face*)&aExpF.Current());
361 BOPTools_CWT& aCWT=aVCWT.Appended();
363 aCWT.SetMapToAvoid(aMapToAvoid);
365 aExpE.Init(aF, TopAbs_EDGE);
366 for (; aExpE.More(); aExpE.Next()) {
367 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExpE.Current());
369 BOPTools_CDT& aCDT=aVCDT.Appended();
372 aCDT.SetMaxTol(aMaxTol);
373 aCDT.SetMapToAvoid(aMapToAvoid);
377 //======================================================
378 BOPTools_Parallel::Perform (bRunParallel, aVCWT);
379 //======================================================
380 BOPTools_Parallel::Perform (bRunParallel, aVCDT);
381 //======================================================
383 //=======================================================================
384 // Function : CorrectShapeTolerances
386 //=======================================================================
387 void BOPTools_AlgoTools::CorrectShapeTolerances
388 (const TopoDS_Shape& aShape,
389 const TopTools_IndexedMapOfShape& aMapToAvoid,
390 const Standard_Boolean bRunParallel)
392 TopExp_Explorer aExp;
393 BOPTools_VectorOfCVT aVCVT;
394 BOPTools_VectorOfCET aVCET;
396 aExp.Init(aShape, TopAbs_EDGE);
397 for (; aExp.More(); aExp.Next()) {
398 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
399 BOPTools_CVT& aCVT=aVCVT.Appended();
401 aCVT.SetMapToAvoid(aMapToAvoid);
404 //======================================================
405 BOPTools_Parallel::Perform (bRunParallel, aVCVT);
406 //======================================================
408 aExp.Init(aShape, TopAbs_FACE);
409 for (; aExp.More(); aExp.Next()) {
410 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
411 BOPTools_CET& aCET=aVCET.Appended();
413 aCET.SetMapToAvoid(aMapToAvoid);
416 //======================================================
417 BOPTools_Parallel::Perform (bRunParallel, aVCET);
418 //======================================================
421 //=======================================================================
422 // Function : CheckEdge
423 // purpose : Correct tolerances for Vertices on Edge
424 //=======================================================================
425 void CheckEdge (const TopoDS_Edge& Ed,
426 const Standard_Real aMaxTol,
427 const TopTools_IndexedMapOfShape& aMapToAvoid)
430 aE.Orientation(TopAbs_FORWARD);
431 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
433 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
435 const TopLoc_Location& Eloc = aE.Location();
437 TopoDS_Iterator aItS(aE);
438 for (; aItS.More(); aItS.Next()) {
439 const TopoDS_Vertex& aV= TopoDS::Vertex(aItS.Value());
441 Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
442 const gp_Pnt& aPV = TV->Pnt();
444 Standard_Real aTol=BRep_Tool::Tolerance(aV);
445 aTol=Max(aTol, aTolE);
446 Standard_Real dd=0.1*aTol;
449 BRep_ListIteratorOfListOfCurveRepresentation aItCR(TE->Curves());
450 while (aItCR.More()) {
451 const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
453 if (aCR->IsCurve3D()) {
454 const Handle(Geom_Curve)& aC = aCR->Curve3D();
456 TopLoc_Location L = (Eloc * aCR->Location()).Predivided(aV.Location());
457 BRep_ListIteratorOfListOfPointRepresentation aItPR(TV->Points());
458 while (aItPR.More()) {
459 const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
460 if (aPR->IsPointOnCurve(aC, L)) {
461 gp_Pnt aPC = aC->Value(aPR->Parameter());
462 aPC.Transform(L.Transformation());
463 Standard_Real aD2=aPV.SquareDistance(aPC);
465 Standard_Real aNewTolerance=sqrt(aD2)+dd;
466 if (aNewTolerance<aMaxTol)
467 UpdateShape(aV, aNewTolerance, aMapToAvoid);
473 TopAbs_Orientation aOrV=aV.Orientation();
474 if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
475 Handle(BRep_GCurve) aGC (Handle(BRep_GCurve)::DownCast (aCR));
477 if (aOrV==TopAbs_FORWARD) {
478 aPC=aC->Value(aGC->First());
481 aPC=aC->Value(aGC->Last());
483 aPC.Transform(L.Transformation());
485 Standard_Real aD2=aPV.SquareDistance(aPC);
487 Standard_Real aNewTolerance=sqrt(aD2)+dd;
488 if (aNewTolerance<aMaxTol)
489 UpdateShape(aV, aNewTolerance, aMapToAvoid);
495 }// while (itcr.More()) {
496 } // for (; aVExp.More(); aVExp.Next()) {
499 //=======================================================================
500 // Function : MapEdgeLength
501 // purpose : Compute edge length and cache it in the map
502 //=======================================================================
503 static Standard_Real MapEdgeLength(const TopoDS_Edge& theEdge,
504 NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
506 const Standard_Real* pLen = theMapEdgeLen.Seek(theEdge);
509 Standard_Real aLen = 0.;
510 if (!BRep_Tool::Degenerated(theEdge))
512 BRepAdaptor_Curve aCurve(theEdge);
513 aLen = GCPnts_AbscissaPoint::Length(aCurve);
515 pLen = theMapEdgeLen.Bound(theEdge, aLen);
520 //=======================================================================
521 // Function : EdgeData
522 // purpose : Structure to store edge data
523 //=======================================================================
526 const TopoDS_Edge* Edge; // Edge
527 Standard_Real VParameter; // Parameter of the vertex on the edge
528 Standard_Boolean IsClosed; // Closed flag of the edge
529 Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
530 Standard_Real First; // First parameter in the range
531 Standard_Real Last; // Last parameter in the rage
534 //=======================================================================
535 // Function : IntersectCurves2d
536 // purpose : Intersect 2d curves of edges
537 //=======================================================================
539 Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
540 const Handle(Geom_Surface)& theS,
541 const EdgeData& theEData1,
542 const EdgeData& theEData2,
543 NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
545 Geom2dInt_GInter anInter;
546 // Range of the first edge
547 Standard_Real aT11 = theEData1.First;
548 Standard_Real aT12 = theEData1.Last;
549 // Range of the second edge
550 Standard_Real aT21 = theEData2.First;
551 Standard_Real aT22 = theEData2.Last;
553 Standard_Real aMaxDist = 0.;
554 Standard_Real aTol2d = 1.e-10;
556 IntRes2d_Domain aDom1(theEData1.GAdaptor.Value(aT11), aT11, aTol2d,
557 theEData1.GAdaptor.Value(aT12), aT12, aTol2d);
558 IntRes2d_Domain aDom2(theEData2.GAdaptor.Value(aT21), aT21, aTol2d,
559 theEData2.GAdaptor.Value(aT22), aT22, aTol2d);
561 anInter.Perform(theEData1.GAdaptor, aDom1, theEData2.GAdaptor, aDom2, aTol2d, aTol2d);
562 if (!anInter.IsDone() || (!anInter.NbSegments() && !anInter.NbPoints())) {
566 Standard_Real aT1, aT2, aTint1, aTint2, aHalfR1, aHalfR2, aDist;
567 Standard_Integer i, aNb;
570 NCollection_List<IntRes2d_IntersectionPoint> aLP;
571 NCollection_List<IntRes2d_IntersectionPoint>::Iterator aItLP;
573 aPV = BRep_Tool::Pnt(theV);
574 aT1 = theEData1.VParameter;
575 aT2 = theEData2.VParameter;
577 aHalfR1 = (aT12 - aT11) / 2.;
578 aHalfR2 = (aT22 - aT21) / 2.;
582 aNb = anInter.NbSegments();
583 for (i = 1; i <= aNb; ++i) {
584 const IntRes2d_IntersectionSegment& aSeg = anInter.Segment(i);
585 aLP.Append(aSeg.FirstPoint());
586 aLP.Append(aSeg.LastPoint());
589 aNb = anInter.NbPoints();
590 for (i = 1; i <= aNb; ++i) {
591 const IntRes2d_IntersectionPoint& aPnt = anInter.Point(i);
595 // evaluate the length of the smallest edge, so that not to return too large distance
596 Standard_Real aLen1 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
597 Standard_Real aLen2 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
598 const Standard_Real MaxEdgePartCoveredByVertex = 0.3;
599 Standard_Real aMaxThresDist = Min(aLen1, aLen2) * MaxEdgePartCoveredByVertex;
600 aMaxThresDist *= aMaxThresDist;
601 aItLP.Initialize(aLP);
602 for (; aItLP.More(); aItLP.Next()) {
603 const IntRes2d_IntersectionPoint& aPnt = aItLP.Value();
605 aTint1 = aPnt.ParamOnFirst();
606 aTint2 = aPnt.ParamOnSecond();
608 if ((aTint1 < aT11 || aTint1 > aT12) ||
609 (aTint2 < aT21 || aTint2 > aT22)) {
614 if ((!theEData1.IsClosed && Abs (aTint1 - aT1) > aHalfR1) ||
615 (!theEData2.IsClosed && Abs (aTint2 - aT2) > aHalfR2)) {
616 // intersection is on the other end of the edge
621 theS->D0(aP2d.X(), aP2d.Y(), aP);
622 aDist = aPV.SquareDistance(aP);
623 if (aDist > aMaxDist && aDist < aMaxThresDist) {
630 //=======================================================================
631 // Function : CorrectWires
633 //=======================================================================
634 void CorrectWires(const TopoDS_Face& aFx,
635 const TopTools_IndexedMapOfShape& aMapToAvoid)
637 Standard_Integer i, aNbV;
638 Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2;
642 TopTools_IndexedDataMapOfShapeListOfShape aMVE;
643 TopTools_ListIteratorOfListOfShape aIt;
646 aF.Orientation(TopAbs_FORWARD);
647 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
649 TopExp::MapShapesAndUniqueAncestors (aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE, Standard_True);
651 NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
653 for (i=1; i<=aNbV; ++i) {
654 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
655 aPV=BRep_Tool::Pnt(aV);
656 aTol=BRep_Tool::Tolerance(aV);
660 // Save edge's data to avoid its recalculation during intersection of 2d curves
661 NCollection_List<EdgeData> aLEPars;
662 const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
664 for (; aIt.More(); aIt.Next()) {
665 const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
666 const Handle(Geom2d_Curve)& aC2D=
667 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
668 Standard_Real aT = BRep_Tool::Parameter (aV, aE);
669 Standard_Boolean isClosed = Standard_False;
671 TopoDS_Vertex aV1, aV2;
672 TopExp::Vertices (aE, aV1, aV2);
673 isClosed = aV1.IsSame (aV2);
677 aS->D0(aP2D.X(), aP2D.Y(), aP);
678 aD2=aPV.SquareDistance(aP);
682 EdgeData anEData = {&aE, aT, isClosed, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
683 aLEPars.Append(anEData);
686 //check wires on self interference by intersecting 2d curves of the edges
687 NCollection_List<EdgeData>::Iterator aItE1(aLEPars);
688 for (; aItE1.More(); aItE1.Next()) {
689 const EdgeData& aEData1 = aItE1.Value();
690 const TopoDS_Shape& aE1 = *aEData1.Edge;
692 NCollection_List<EdgeData>::Iterator aItE2 = aItE1;
693 for (aItE2.Next(); aItE2.More(); aItE2.Next()) {
694 const EdgeData& aEData2 = aItE2.Value();
695 const TopoDS_Shape& aE2 = *aEData2.Edge;
700 aD2 = IntersectCurves2d(aV, aS, aEData1, aEData2, aMapEdgeLen);
708 aTol = 1.01 * sqrt(aD2max);
709 UpdateShape(aV, aTol, aMapToAvoid);
711 }// for (i=1; i<=aNbV; ++i) {
714 //=======================================================================
715 // Function : CorrectEdgeTolerance
716 // purpose : Correct tolerances for Edge
717 //=======================================================================
718 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
719 const TopoDS_Face& S,
720 const Standard_Real aMaxTol,
721 const TopTools_IndexedMapOfShape& aMapToAvoid)
724 // 1. Minimum of conditions to Perform
725 Handle (BRep_CurveRepresentation) myCref;
726 Handle (Adaptor3d_HCurve) myHCurve;
730 Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
731 BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
732 Standard_Boolean Degenerated, SameParameterx, SameRangex;
734 Standard_Integer unique = 0;
736 Degenerated = TEx->Degenerated();
737 SameParameterx = TEx->SameParameter();
738 SameRangex = TEx->SameRange();
740 if (!SameRangex && SameParameterx) {
744 Handle(Geom_Curve) C3d;
745 while (itcrx.More()) {
746 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
747 if (cr->IsCurve3D()) {
749 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
757 return;//...No3DCurve
760 return;//...Multiple3DCurve;
763 if (myCref.IsNull() && !Degenerated) {
764 itcrx.Initialize(TEx->Curves());
765 while (itcrx.More()) {
766 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
767 if (cr->IsCurveOnSurface()) {
775 else if (!myCref.IsNull() && Degenerated){
776 return ;//...InvalidDegeneratedFlag;
779 if (!myCref.IsNull()) {
780 Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref));
781 Standard_Real First,Last;
782 GCref->Range(First,Last);
785 return ;//InvalidRange;
789 if (myCref->IsCurve3D()) {
790 Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
791 (myCref->Curve3D()->Transformed
792 (myCref->Location().Transformation()));
793 GeomAdaptor_Curve GAC3d(C3dx, First, Last);
794 myHCurve = new GeomAdaptor_HCurve(GAC3d);
796 else { // curve on surface
797 Handle(Geom_Surface) Sref = myCref->Surface();
798 Sref = Handle(Geom_Surface)::
799 DownCast(Sref->Transformed(myCref->Location().Transformation()));
800 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
801 Handle(GeomAdaptor_HSurface) GAHSref =
802 new GeomAdaptor_HSurface(Sref);
803 Handle(Geom2dAdaptor_HCurve) GHPCref =
804 new Geom2dAdaptor_HCurve(PCref, First, Last);
805 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
806 myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
811 //===============================================
812 // 2. Tolerances in InContext
816 Standard_Boolean ok = Standard_True;
818 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
819 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
820 Standard_Real aNewTol=Tol;
822 Standard_Boolean SameParameter = TE->SameParameter();
823 Standard_Boolean SameRange = TE->SameRange();
824 Standard_Real First = myHCurve->FirstParameter();
825 Standard_Real Last = myHCurve->LastParameter();
826 Standard_Real Delta =1.e-12;
828 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
829 const TopLoc_Location& Floc = S.Location();
830 const TopLoc_Location& TFloc = TF->Location();
831 const Handle(Geom_Surface)& Su = TF->Surface();
832 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
833 Standard_Boolean pcurvefound = Standard_False;
835 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
836 while (itcr.More()) {
837 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
838 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
839 pcurvefound = Standard_True;
840 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
843 if (SameRange && (f != First || l != Last)) {
844 return ;//BRepCheck_InvalidSameRangeFlag;
847 Handle(Geom_Surface) Sb = cr->Surface();
848 Sb = Handle(Geom_Surface)::
849 DownCast (Su->Transformed(L.Transformation()));
850 Handle(Geom2d_Curve) PC = cr->PCurve();
851 Handle(GeomAdaptor_HSurface) GAHS =
852 new GeomAdaptor_HSurface(Sb);
853 Handle(Geom2dAdaptor_HCurve) GHPC =
854 new Geom2dAdaptor_HCurve(PC,f,l);
855 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
856 ok = Validate(myHCurve->Curve(), ACS,
857 Tol, SameParameter, aNewTol);
859 if (aNewTol<aMaxTol) {
860 UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
861 CorrectVertexTolerance(myShape, aMapToAvoid);
865 if (cr->IsCurveOnClosedSurface()) {
866 //checkclosed = Standard_True;
867 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
868 ACS.Load(GHPC, GAHS); // sans doute inutile
869 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
871 if (aNewTol<aMaxTol) {
872 UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
873 CorrectVertexTolerance(myShape, aMapToAvoid);
882 Handle(Geom_Plane) P;
883 Handle(Standard_Type) styp = Su->DynamicType();
884 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
885 P = Handle(Geom_Plane)::
886 DownCast(Handle(Geom_RectangularTrimmedSurface)::
887 DownCast(Su)->BasisSurface());
890 P = Handle(Geom_Plane)::DownCast(Su);
892 if (P.IsNull()) { // not a plane
896 else {// on fait la projection a la volee, comme BRep_Tool
897 P = Handle(Geom_Plane)::
898 DownCast(P->Transformed(L.Transformation()));
899 //on projette Cref sur ce plan
900 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
902 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
903 GeomAdaptor_Curve& Gac =
904 Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
905 Handle(Geom_Curve) C3dx = Gac.Curve();
906 Handle(Geom_Curve) ProjOnPlane =
907 GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3dx,First,Last),
909 P->Position().Direction(),
912 Handle(GeomAdaptor_HCurve) aHCurve =
913 new GeomAdaptor_HCurve(ProjOnPlane);
915 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
916 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
917 Handle(Geom2dAdaptor_HCurve) GHPC =
918 new Geom2dAdaptor_HCurve(PC,
919 myHCurve->FirstParameter(),
920 myHCurve->LastParameter());
922 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
924 Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
925 Tol,Standard_True, aNewTol);
927 if (aNewTol<aMaxTol) {
928 UpdateShape(myShape, aNewTol+Delta, aMapToAvoid);
929 CorrectVertexTolerance(myShape, aMapToAvoid);
933 }//end of if (!pcurvefound) {
934 } // end of 2. Tolerances in InContext
936 //=======================================================================
937 //function : CorrectVertexTolerance
939 //=======================================================================
940 void CorrectVertexTolerance(const TopoDS_Edge& aE,
941 const TopTools_IndexedMapOfShape& aMapToAvoid)
943 Standard_Real aTolE, aTolV;
946 aTolE=BRep_Tool::Tolerance(aE);
948 for(; aIt.More(); aIt.Next()) {
949 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aIt.Value());
950 aTolV=BRep_Tool::Tolerance(aV);
952 UpdateShape(aV, aTolE, aMapToAvoid);
956 //=======================================================================
957 //function : Validate
959 //=======================================================================
960 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
961 const Adaptor3d_Curve& Other,
962 const Standard_Real Tol,
963 const Standard_Boolean SameParameter,
964 Standard_Real& aNewTolerance)
966 Standard_Real First, Last, MaxDistance, aD, Tol2;
968 First = CRef.FirstParameter();
969 Last = CRef.LastParameter();
973 Standard_Integer NCONTROL=23;
974 Standard_Integer i, aNC1=NCONTROL-1;
976 Standard_Boolean aFlag=Standard_False;
977 Standard_Boolean proj = (!SameParameter ||
978 First != Other.FirstParameter() ||
979 Last != Other.LastParameter());
983 for (i = 0; i < NCONTROL; i++) {
984 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
985 gp_Pnt pref = CRef.Value(prm);
986 gp_Pnt pother = Other.Value(prm);
988 aD=pref.SquareDistance(pother);
991 if (aD>MaxDistance) {
999 aNewTolerance=sqrt(MaxDistance);
1007 Extrema_LocateExtPC refd,otherd;
1008 Standard_Real OFirst, OLast;
1009 OFirst = Other.FirstParameter();
1010 OLast = Other.LastParameter();
1012 gp_Pnt pd = CRef.Value(First);
1013 gp_Pnt pdo = Other.Value(OFirst);
1015 aD = pd.SquareDistance(pdo);
1017 if (aD>MaxDistance) {
1020 aFlag=Standard_True;
1023 pd = CRef.Value(Last);
1024 pdo = Other.Value(OLast);
1025 aD = pd.SquareDistance(pdo);
1026 if (aD > Tol2 && aD > MaxDistance) {
1028 aFlag=Standard_True;
1031 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
1032 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
1034 for (i = 2; i< aNC1; i++) {
1035 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
1036 gp_Pnt pref = CRef.Value(rprm);
1038 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
1039 gp_Pnt pother = Other.Value(oprm);
1041 refd.Perform(pother,rprm);
1042 if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
1043 if (refd.IsDone()) {
1044 aD=refd.SquareDistance();
1045 if (aD > Tol2 && aD>MaxDistance) {
1046 aFlag=Standard_True;
1052 otherd.Perform(pref,oprm);
1053 if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
1055 if (otherd.IsDone()) {
1056 aD=otherd.SquareDistance();
1057 if (aD > Tol2 && aD>MaxDistance) {
1058 aFlag=Standard_True;
1066 aD=sqrt (MaxDistance);
1070 //=======================================================================
1071 // Function : UpdateEdges
1073 //=======================================================================
1074 void UpdateEdges(const TopoDS_Face& aF,
1075 const TopTools_IndexedMapOfShape& aMapToAvoid)
1077 Standard_Real aTolF, aTolE, aTolV;
1078 TopoDS_Iterator aItF, aItW, aItE;
1080 aTolE=aTolF= BRep_Tool::Tolerance(aF);
1081 aItF.Initialize(aF);
1082 for (; aItF.More(); aItF.Next()) {
1083 const TopoDS_Shape& aS = aItF.Value();
1084 if (aS.ShapeType()==TopAbs_WIRE) {
1085 aItW.Initialize(aS);
1086 for (; aItW.More(); aItW.Next()) {
1087 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
1088 aTolE = BRep_Tool::Tolerance(aE);
1089 if (aTolE < aTolF) {
1090 UpdateShape(aE, aTolF, aMapToAvoid);
1096 const TopoDS_Vertex& aV=*(TopoDS_Vertex*)&aItF.Value();
1097 aTolV = BRep_Tool::Tolerance(aV);
1098 if (aTolV < aTolE) {
1099 UpdateShape(aV, aTolF, aMapToAvoid);
1104 //=======================================================================
1105 //function : UpdateShape
1107 //=======================================================================
1108 void UpdateShape(const TopoDS_Shape& aS,
1109 const Standard_Real aTol,
1110 const TopTools_IndexedMapOfShape& aMapToAvoid)
1112 if (aMapToAvoid.Contains(aS)) {
1116 TopAbs_ShapeEnum aType;
1119 aType=aS.ShapeType();
1120 if (aType==TopAbs_EDGE) {
1121 const TopoDS_Edge& aE = *((TopoDS_Edge*)&aS);
1122 aBB.UpdateEdge(aE, aTol);
1124 else if (aType==TopAbs_VERTEX) {
1125 const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&aS);
1126 aBB.UpdateVertex(aV, aTol);
1129 //=======================================================================
1130 // Function : ComputeTolerance
1132 //=======================================================================
1133 Standard_Boolean BOPTools_AlgoTools::ComputeTolerance
1134 (const TopoDS_Face& theFace,
1135 const TopoDS_Edge& theEdge,
1136 Standard_Real& theMaxDist,
1137 Standard_Real& theMaxPar)
1139 BRepLib_CheckCurveOnSurface aCS;
1141 aCS.Init(theEdge, theFace);
1143 if (!aCS.IsDone()) {
1144 return Standard_False;
1147 theMaxDist = aCS.MaxDistance();
1148 theMaxPar = aCS.MaxParameter();
1150 return Standard_True;