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 <BOPTools_AlgoTools.ixx>
18 #include <gp_Pnt2d.hxx>
20 #include <Adaptor3d_HCurve.hxx>
21 #include <Adaptor3d_CurveOnSurface.hxx>
22 #include <Adaptor3d_HCurveOnSurface.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_Surface.hxx>
26 #include <Geom_Plane.hxx>
27 #include <Geom_TrimmedCurve.hxx>
28 #include <Geom_RectangularTrimmedSurface.hxx>
30 #include <GeomAdaptor_Surface.hxx>
31 #include <GeomAdaptor_Curve.hxx>
32 #include <GeomAdaptor_HCurve.hxx>
33 #include <GeomAdaptor_HSurface.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom2dInt_GInter.hxx>
37 #include <Geom2dAdaptor_Curve.hxx>
38 #include <Geom2dAdaptor_HCurve.hxx>
39 #include <Geom2dAdaptor.hxx>
41 #include <GeomProjLib.hxx>
43 #include <ProjLib_ProjectedCurve.hxx>
44 #include <Extrema_LocateExtPC.hxx>
46 #include <IntRes2d_Domain.hxx>
47 #include <IntRes2d_IntersectionPoint.hxx>
49 #include <TopLoc_Location.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Vertex.hxx>
54 #include <TopoDS_Face.hxx>
55 #include <TopoDS_Iterator.hxx>
56 #include <TopoDS_Wire.hxx>
58 #include <BRep_TVertex.hxx>
59 #include <BRep_TEdge.hxx>
60 #include <BRep_TFace.hxx>
61 #include <BRep_Tool.hxx>
62 #include <BRep_GCurve.hxx>
63 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
64 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
65 #include <BRep_CurveRepresentation.hxx>
66 #include <BRep_PointRepresentation.hxx>
67 #include <BRep_Builder.hxx>
69 #include <BRepAdaptor_Surface.hxx>
71 #include <BRepTools_WireExplorer.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_IndexedMapOfShape.hxx>
76 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
77 #include <TopTools_ListOfShape.hxx>
78 #include <TopTools_ListIteratorOfListOfShape.hxx>
80 #include <BOPCol_NCVector.hxx>
81 #include <BOPCol_TBB.hxx>
84 void CheckEdge (const TopoDS_Edge& E,
85 const Standard_Real aMaxTol);
87 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
89 const Standard_Real aMaxTol);
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);
101 void CorrectWires(const TopoDS_Face& aF);
106 void UpdateEdges(const TopoDS_Face& aF);
109 Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
110 const TopoDS_Face& aF,
111 const Handle(Geom_Surface)& aS,
112 const TopoDS_Edge& aE1,
113 const TopoDS_Edge& aE2);
117 //=======================================================================
118 //class : BOPTools_CPC
120 //=======================================================================
130 void SetEdge(const TopoDS_Edge& aE) {
134 const TopoDS_Edge& Edge()const {
138 void SetMaxTol(const Standard_Real aMaxTol) {
142 Standard_Real MaxTol()const {
147 CheckEdge(myEdge, myMaxTol);
151 Standard_Real myMaxTol;
155 //=======================================================================
156 typedef BOPCol_NCVector<BOPTools_CPC> BOPTools_VectorOfCPC;
158 typedef BOPCol_TBBFunctor
160 BOPTools_VectorOfCPC> BOPTools_CPCFunctor;
162 typedef BOPCol_TBBCnt
163 <BOPTools_CPCFunctor,
164 BOPTools_VectorOfCPC> BOPTools_CPCCnt;
166 //=======================================================================
167 //class : BOPTools_CWT
169 //=======================================================================
178 void SetFace(const TopoDS_Face& aF) {
183 CorrectWires(myFace);
189 //=======================================================================
190 typedef BOPCol_NCVector<BOPTools_CWT> BOPTools_VectorOfCWT;
192 typedef BOPCol_TBBFunctor
194 BOPTools_VectorOfCWT> BOPTools_CWTFunctor;
196 typedef BOPCol_TBBCnt
197 <BOPTools_CWTFunctor,
198 BOPTools_VectorOfCWT> BOPTools_CWTCnt;
200 //=======================================================================
201 //class : BOPTools_CDT
203 //=======================================================================
213 void SetEdge(const TopoDS_Edge& aE) {
217 void SetFace(const TopoDS_Face& aF) {
221 void SetMaxTol(const Standard_Real aMaxTol) {
226 CorrectEdgeTolerance (myEdge, myFace, myMaxTol);
230 Standard_Real myMaxTol;
234 //=======================================================================
235 typedef BOPCol_NCVector<BOPTools_CDT> BOPTools_VectorOfCDT;
237 typedef BOPCol_TBBFunctor
239 BOPTools_VectorOfCDT> BOPTools_CDTFunctor;
241 typedef BOPCol_TBBCnt
242 <BOPTools_CDTFunctor,
243 BOPTools_VectorOfCDT> BOPTools_CDTCnt;
245 //=======================================================================
246 //class : BOPTools_CVT
248 //=======================================================================
257 void SetEdge(const TopoDS_Edge& aE) {
262 CorrectVertexTolerance(myEdge);
269 //=======================================================================
270 typedef BOPCol_NCVector<BOPTools_CVT> BOPTools_VectorOfCVT;
272 typedef BOPCol_TBBFunctor
274 BOPTools_VectorOfCVT> BOPTools_CVTFunctor;
276 typedef BOPCol_TBBCnt
277 <BOPTools_CVTFunctor,
278 BOPTools_VectorOfCVT> BOPTools_CVTCnt;
280 //=======================================================================
281 //class : BOPTools_CET
283 //=======================================================================
292 void SetFace(const TopoDS_Face& aF) {
303 //=======================================================================
304 typedef BOPCol_NCVector<BOPTools_CET> BOPTools_VectorOfCET;
306 typedef BOPCol_TBBFunctor
308 BOPTools_VectorOfCET> BOPTools_CETFunctor;
310 typedef BOPCol_TBBCnt
311 <BOPTools_CETFunctor,
312 BOPTools_VectorOfCET> BOPTools_CETCnt;
315 //=======================================================================
316 //class : BOPTools_CheckCurveOnSurface
317 //purpose : it is used to check the curve on the surface
318 //=======================================================================
319 #include <math_GlobOptMin.hxx>
320 #include <math_MultipleVarFunctionWithHessian.hxx>
321 #include <math_Matrix.hxx>
322 #include <Geom2d_TrimmedCurve.hxx>
324 class BOPTools_CheckCurveOnSurface :
325 public math_MultipleVarFunctionWithHessian
328 BOPTools_CheckCurveOnSurface(BOPTools_CheckCurveOnSurface&);
329 BOPTools_CheckCurveOnSurface(const Handle(Geom_Curve)& theC3D,
330 const Handle(Geom2d_Curve)& theC2D,
331 const Handle(Geom_Surface)& theSurf)
339 virtual Standard_Integer NbVariables() const {
343 virtual Standard_Boolean Value(const math_Vector& theX,
344 Standard_Real& theFVal) {
346 const Standard_Real aPar = theX(1);
349 my3DCurve->D0(aPar, aP1);
350 my2DCurve->D0(aPar, aP2d);
351 mySurf->D0(aP2d.X(), aP2d.Y(), aP2);
353 theFVal = -1.0*aP1.SquareDistance(aP2);
356 return Standard_False;
359 return Standard_True;
362 virtual Standard_Integer GetStateNumber() {
366 virtual Standard_Boolean Gradient(const math_Vector& theX,
367 math_Vector& theGrad) {
369 const Standard_Real aPar = theX(1);
372 gp_Vec aDC3D, aDSU, aDSV;
376 my3DCurve->D1(aPar, aP1, aDC3D);
377 my2DCurve->D1(aPar, aP2d, aDC2D);
378 mySurf->D1(aP2d.X(), aP2d.Y(), aP2, aDSU, aDSV);
380 aP1.SetXYZ(aP1.XYZ() - aP2.XYZ());
381 aP2.SetXYZ(aDC3D.XYZ() - aDC2D.X()*aDSU.XYZ() - aDC2D.Y()*aDSV.XYZ());
383 theGrad(1) = -2.0*aP1.XYZ().Dot(aP2.XYZ());
386 return Standard_False;
389 return Standard_True;
392 virtual Standard_Boolean Values(const math_Vector& theX,
393 Standard_Real& theVal,
394 math_Vector& theGrad) {
395 if(!Value(theX, theVal))
396 return Standard_False;
398 if(!Gradient(theX, theGrad))
399 return Standard_False;
401 return Standard_True;
404 virtual Standard_Boolean Values(const math_Vector& theX,
405 Standard_Real& theVal,
406 math_Vector& theGrad,
407 math_Matrix& theHessian) {
408 if(!Value(theX, theVal))
409 return Standard_False;
411 if(!Gradient(theX, theGrad))
412 return Standard_False;
414 theHessian(1,1) = theGrad(1);
416 return Standard_True;
420 Handle(Geom_Curve) my3DCurve;
421 Handle(Geom2d_Curve) my2DCurve;
422 Handle(Geom_Surface) mySurf;
424 //=======================================================================
426 //=======================================================================
427 // Function : CorrectTolerances
429 //=======================================================================
430 void BOPTools_AlgoTools::CorrectTolerances
431 (const TopoDS_Shape& aShape,
432 const Standard_Real aMaxTol,
433 const Standard_Boolean bRunParallel)
435 BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol, bRunParallel);
436 BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol, bRunParallel);
439 //=======================================================================
440 // Function : CorrectPointOnCurve
442 //=======================================================================
443 void BOPTools_AlgoTools::CorrectPointOnCurve
444 (const TopoDS_Shape& aS,
445 const Standard_Real aMaxTol,
446 const Standard_Boolean bRunParallel)
448 TopExp_Explorer aExp;
449 BOPTools_VectorOfCPC aVCPC;
451 aExp.Init(aS, TopAbs_EDGE);
452 for(; aExp.More(); aExp.Next()) {
453 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
454 BOPTools_CPC& aCPC=aVCPC.Append1();
456 aCPC.SetMaxTol(aMaxTol);
459 //======================================================
460 BOPTools_CPCCnt::Perform(bRunParallel, aVCPC);
461 //======================================================
463 //=======================================================================
464 // Function : CorrectCurveOnSurface
466 //=======================================================================
467 void BOPTools_AlgoTools::CorrectCurveOnSurface
468 (const TopoDS_Shape& aS,
469 const Standard_Real aMaxTol,
470 const Standard_Boolean bRunParallel)
472 TopExp_Explorer aExpF, aExpE;
473 BOPTools_VectorOfCWT aVCWT;
474 BOPTools_VectorOfCDT aVCDT;
476 aExpF.Init(aS, TopAbs_FACE);
477 for (; aExpF.More(); aExpF.Next()) {
478 const TopoDS_Face& aF=*((TopoDS_Face*)&aExpF.Current());
480 BOPTools_CWT& aCWT=aVCWT.Append1();
483 aExpE.Init(aF, TopAbs_EDGE);
484 for (; aExpE.More(); aExpE.Next()) {
485 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExpE.Current());
487 BOPTools_CDT& aCDT=aVCDT.Append1();
490 aCDT.SetMaxTol(aMaxTol);
494 //======================================================
495 BOPTools_CWTCnt::Perform(bRunParallel, aVCWT);
496 //======================================================
497 BOPTools_CDTCnt::Perform(bRunParallel, aVCDT);
498 //======================================================
500 //=======================================================================
501 // Function : CorrectShapeTolerances
503 //=======================================================================
504 void BOPTools_AlgoTools::CorrectShapeTolerances
505 (const TopoDS_Shape& aShape,
506 const Standard_Boolean bRunParallel)
508 TopExp_Explorer aExp;
509 BOPTools_VectorOfCVT aVCVT;
510 BOPTools_VectorOfCET aVCET;
512 aExp.Init(aShape, TopAbs_EDGE);
513 for (; aExp.More(); aExp.Next()) {
514 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
515 BOPTools_CVT& aCVT=aVCVT.Append1();
519 //======================================================
520 BOPTools_CVTCnt::Perform(bRunParallel, aVCVT);
521 //======================================================
523 aExp.Init(aShape, TopAbs_FACE);
524 for (; aExp.More(); aExp.Next()) {
525 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
526 BOPTools_CET& aCET=aVCET.Append1();
530 //======================================================
531 BOPTools_CETCnt::Perform(bRunParallel, aVCET);
532 //======================================================
535 //=======================================================================
536 // Function : CheckEdge
537 // purpose : Correct tolerances for Vertices on Edge
538 //=======================================================================
539 void CheckEdge (const TopoDS_Edge& Ed,
540 const Standard_Real aMaxTol)
542 Standard_Real aTolE, aTol, aD2, aNewTolerance, dd;
547 TopoDS_Iterator aItS;
549 TopAbs_Orientation aOrV;
550 BRep_ListIteratorOfListOfPointRepresentation aItPR;
551 BRep_ListIteratorOfListOfCurveRepresentation aItCR;
554 aE.Orientation(TopAbs_FORWARD);
555 aTolE=BRep_Tool::Tolerance(aE);
557 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
560 for (; aItS.More(); aItS.Next()) {
561 aV= TopoDS::Vertex(aItS.Value());
563 Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
564 const gp_Pnt& aPV = TV->Pnt();
566 aTol=BRep_Tool::Tolerance(aV);
567 aTol=Max(aTol, aTolE);
571 const TopLoc_Location& Eloc = aE.Location();
573 aItCR.Initialize(TE->Curves());
574 while (aItCR.More()) {
575 const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
576 const TopLoc_Location& loc = aCR->Location();
577 L = (Eloc * loc).Predivided(aV.Location());
579 if (aCR->IsCurve3D()) {
580 const Handle(Geom_Curve)& aC = aCR->Curve3D();
582 aItPR.Initialize(TV->Points());
583 while (aItPR.More()) {
584 const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
585 if (aPR->IsPointOnCurve(aC, L)) {
586 aPC = aC->Value(aPR->Parameter());
587 aPC.Transform(L.Transformation());
588 aD2=aPV.SquareDistance(aPC);
590 aNewTolerance=sqrt(aD2)+dd;
591 if (aNewTolerance<aMaxTol)
592 TV->UpdateTolerance(aNewTolerance);
598 aOrV=aV.Orientation();
599 if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
600 const Handle(BRep_GCurve)& aGC=*((Handle(BRep_GCurve)*)&aCR);
602 if (aOrV==TopAbs_FORWARD) {
603 aPC=aC->Value(aGC->First());
606 aPC=aC->Value(aGC->Last());
608 aPC.Transform(L.Transformation());
610 aD2=aPV.SquareDistance(aPC);
612 aNewTolerance=sqrt(aD2)+dd;
613 if (aNewTolerance<aMaxTol)
614 TV->UpdateTolerance(aNewTolerance);
620 }// while (itcr.More()) {
621 } // for (; aVExp.More(); aVExp.Next()) {
623 //=======================================================================
624 // Function : CorrectWires
626 //=======================================================================
627 void CorrectWires(const TopoDS_Face& aFx)
629 Standard_Boolean bIsPeriodic;
630 Standard_Integer i, aNbV;
631 Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
635 TopoDS_Vertex aV11, aV12, aV21, aV22;;
636 TopTools_IndexedDataMapOfShapeListOfShape aMVE;
637 TopTools_ListIteratorOfListOfShape aIt, aIt1;
640 aF.Orientation(TopAbs_FORWARD);
641 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
642 GeomAdaptor_Surface aGAS (aS);
644 bIsPeriodic=(aGAS.IsUPeriodic() || aGAS.IsVPeriodic());
646 TopExp::MapShapesAndAncestors(aF,
651 for (i=1; i<=aNbV; ++i) {
652 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
653 aPV=BRep_Tool::Pnt(aV);
654 aTol=BRep_Tool::Tolerance(aV);
658 const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
660 for (; aIt.More(); aIt.Next()) {
661 const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
662 const Handle(Geom2d_Curve)& aC2D=
663 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
664 aT=BRep_Tool::Parameter(aV, aE);
667 aS->D0(aP2D.X(), aP2D.Y(), aP);
668 aD2=aPV.SquareDistance(aP);
672 //check self interference
681 TopExp::Vertices(aE, aV11, aV12);
685 for (; aIt1.More(); aIt1.Next()) {
686 const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
688 //do not perform check for edges that have two common vertices
689 TopExp::Vertices(aE1, aV21, aV22);
690 if ((aV11.IsSame(aV21) && aV12.IsSame(aV22)) ||
691 (aV12.IsSame(aV21) && aV11.IsSame(aV22))) {
695 aD2=IntersectCurves2d(aPV, aF, aS, aE, aE1);
699 }// for (; aIt1.More(); aIt1.Next()) {
700 }// for (; aIt.More(); aIt.Next()) {
705 aBB.UpdateVertex(aV, aTol);
707 }// for (i=1; i<=aNbV; ++i) {
709 //=======================================================================
710 // Function : IntersectCurves2d
711 // purpose : Intersect 2d curves of edges
712 //=======================================================================
713 Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
714 const TopoDS_Face& aF,
715 const Handle(Geom_Surface)& aS,
716 const TopoDS_Edge& aE1,
717 const TopoDS_Edge& aE2)
719 Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d;
720 Standard_Integer j, aNbPnt;
721 Geom2dInt_GInter aInter;
726 aTol2d = Precision::Confusion();
728 const Handle(Geom2d_Curve)& aC2D1=
729 BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
730 const Handle(Geom2d_Curve)& aC2D2=
731 BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
733 Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
734 IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d,
735 aC2D1->Value(aT12), aT12, aTol2d);
736 IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d,
737 aC2D2->Value(aT22), aT22, aTol2d);
739 aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
740 if (aInter.IsDone()) {
741 if (aInter.NbSegments()) {
744 aNbPnt = aInter.NbPoints();
746 aDist = Precision::Infinite();
747 for (j = 1; j <= aNbPnt; ++j) {
748 aP2D = aInter.Point(j).Value();
749 aS->D0(aP2D.X(), aP2D.Y(), aP);
750 aD=aPV.SquareDistance(aP);
759 //=======================================================================
760 // Function : CorrectEdgeTolerance
761 // purpose : Correct tolerances for Edge
762 //=======================================================================
763 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
764 const TopoDS_Face& S,
765 const Standard_Real aMaxTol)
768 // 1. Minimum of conditions to Perform
769 Handle (BRep_CurveRepresentation) myCref;
770 Handle (Adaptor3d_HCurve) myHCurve;
774 Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
775 BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
776 Standard_Boolean Degenerated, SameParameterx, SameRangex;
778 Standard_Integer unique = 0;
780 Degenerated = TEx->Degenerated();
781 SameParameterx = TEx->SameParameter();
782 SameRangex = TEx->SameRange();
784 if (!SameRangex && SameParameterx) {
788 Handle(Geom_Curve) C3d;
789 while (itcrx.More()) {
790 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
791 if (cr->IsCurve3D()) {
793 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
801 return;//...No3DCurve
804 return;//...Multiple3DCurve;
807 if (myCref.IsNull() && !Degenerated) {
808 itcrx.Initialize(TEx->Curves());
809 while (itcrx.More()) {
810 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
811 if (cr->IsCurveOnSurface()) {
819 else if (!myCref.IsNull() && Degenerated){
820 return ;//...InvalidDegeneratedFlag;
823 if (!myCref.IsNull()) {
824 const Handle(BRep_GCurve)& GCref =
825 *((Handle(BRep_GCurve)*)&myCref);
826 Standard_Real First,Last;
827 GCref->Range(First,Last);
830 return ;//InvalidRange;
834 if (myCref->IsCurve3D()) {
835 Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
836 (myCref->Curve3D()->Transformed
837 (myCref->Location().Transformation()));
838 GeomAdaptor_Curve GAC3d(C3dx, First, Last);
839 myHCurve = new GeomAdaptor_HCurve(GAC3d);
841 else { // curve on surface
842 Handle(Geom_Surface) Sref = myCref->Surface();
843 Sref = Handle(Geom_Surface)::
844 DownCast(Sref->Transformed(myCref->Location().Transformation()));
845 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
846 Handle(GeomAdaptor_HSurface) GAHSref =
847 new GeomAdaptor_HSurface(Sref);
848 Handle(Geom2dAdaptor_HCurve) GHPCref =
849 new Geom2dAdaptor_HCurve(PCref, First, Last);
850 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
851 myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
856 //===============================================
857 // 2. Tolerances in InContext
861 Standard_Boolean ok=Standard_True;;
863 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
864 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
865 Standard_Real aNewTol=Tol;
867 Standard_Boolean SameParameter = TE->SameParameter();
868 Standard_Boolean SameRange = TE->SameRange();
869 Standard_Real First = myHCurve->FirstParameter();
870 Standard_Real Last = myHCurve->LastParameter();
871 Standard_Real Delta =1.e-12;
873 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
874 const TopLoc_Location& Floc = S.Location();
875 const TopLoc_Location& TFloc = TF->Location();
876 const Handle(Geom_Surface)& Su = TF->Surface();
877 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
878 Standard_Boolean pcurvefound = Standard_False;
880 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
881 while (itcr.More()) {
882 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
883 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
884 pcurvefound = Standard_True;
885 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
888 if (SameRange && (f != First || l != Last)) {
889 return ;//BRepCheck_InvalidSameRangeFlag;
892 Handle(Geom_Surface) Sb = cr->Surface();
893 Sb = Handle(Geom_Surface)::
894 DownCast (Su->Transformed(L.Transformation()));
895 Handle(Geom2d_Curve) PC = cr->PCurve();
896 Handle(GeomAdaptor_HSurface) GAHS =
897 new GeomAdaptor_HSurface(Sb);
898 Handle(Geom2dAdaptor_HCurve) GHPC =
899 new Geom2dAdaptor_HCurve(PC,f,l);
900 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
901 ok = Validate(myHCurve->Curve(), ACS,
902 Tol, SameParameter, aNewTol);
904 if (aNewTol<aMaxTol) {
905 TE->UpdateTolerance(aNewTol+Delta);
907 CorrectVertexTolerance(myShape);
911 if (cr->IsCurveOnClosedSurface()) {
912 //checkclosed = Standard_True;
913 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
914 ACS.Load(GAHS); // sans doute inutile
915 ACS.Load(GHPC); // meme remarque...
916 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
918 if (aNewTol<aMaxTol) {
919 TE->UpdateTolerance(aNewTol+Delta);
920 CorrectVertexTolerance(myShape);
929 Handle(Geom_Plane) P;
930 Handle(Standard_Type) styp = Su->DynamicType();
931 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
932 P = Handle(Geom_Plane)::
933 DownCast(Handle(Geom_RectangularTrimmedSurface)::
934 DownCast(Su)->BasisSurface());
937 P = Handle(Geom_Plane)::DownCast(Su);
939 if (P.IsNull()) { // not a plane
943 else {// on fait la projection a la volee, comme BRep_Tool
944 P = Handle(Geom_Plane)::
945 DownCast(P->Transformed(L.Transformation()));
946 //on projette Cref sur ce plan
947 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
949 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
950 GeomAdaptor_Curve& Gac =
951 Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
952 Handle(Geom_Curve) C3dx = Gac.Curve();
953 Handle(Geom_Curve) ProjOnPlane =
954 GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3dx,First,Last),
956 P->Position().Direction(),
959 Handle(GeomAdaptor_HCurve) aHCurve =
960 new GeomAdaptor_HCurve(ProjOnPlane);
962 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
963 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
964 Handle(Geom2dAdaptor_HCurve) GHPC =
965 new Geom2dAdaptor_HCurve(PC,
966 myHCurve->FirstParameter(),
967 myHCurve->LastParameter());
969 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
971 Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
972 Tol,Standard_True, aNewTol);
974 if (aNewTol<aMaxTol) {
975 TE->UpdateTolerance(aNewTol+Delta);
976 CorrectVertexTolerance(myShape);
980 }//end of if (!pcurvefound) {
981 } // end of 2. Tolerances in InContext
983 //=======================================================================
984 //function : CorrectVertexTolerance
986 //=======================================================================
987 void CorrectVertexTolerance(const TopoDS_Edge& aE)
989 Standard_Real aTolE, aTolV;
992 aTolE=BRep_Tool::Tolerance(aE);
994 for(; aIt.More(); aIt.Next()) {
995 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aIt.Value());
996 aTolV=BRep_Tool::Tolerance(aV);
998 Handle(BRep_TVertex)& aTV= *((Handle(BRep_TVertex)*)&aV.TShape());
999 aTV->UpdateTolerance(aTolE);
1003 //=======================================================================
1004 //function : Validate
1006 //=======================================================================
1007 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
1008 const Adaptor3d_Curve& Other,
1009 const Standard_Real Tol,
1010 const Standard_Boolean SameParameter,
1011 Standard_Real& aNewTolerance)
1013 Standard_Real First, Last, MaxDistance, aD, Tol2;
1015 First = CRef.FirstParameter();
1016 Last = CRef.LastParameter();
1020 Standard_Integer NCONTROL=23;
1021 Standard_Integer i, aNC1=NCONTROL-1;
1023 Standard_Boolean aFlag=Standard_False;
1024 Standard_Boolean proj = (!SameParameter ||
1025 First != Other.FirstParameter() ||
1026 Last != Other.LastParameter());
1030 for (i = 0; i < NCONTROL; i++) {
1031 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
1032 gp_Pnt pref = CRef.Value(prm);
1033 gp_Pnt pother = Other.Value(prm);
1035 aD=pref.SquareDistance(pother);
1038 if (aD>MaxDistance) {
1041 aFlag=Standard_True;
1046 aNewTolerance=sqrt(MaxDistance);
1054 Extrema_LocateExtPC refd,otherd;
1055 Standard_Real OFirst, OLast;
1056 OFirst = Other.FirstParameter();
1057 OLast = Other.LastParameter();
1059 gp_Pnt pd = CRef.Value(First);
1060 gp_Pnt pdo = Other.Value(OFirst);
1062 aD = pd.SquareDistance(pdo);
1064 if (aD>MaxDistance) {
1067 aFlag=Standard_True;
1070 pd = CRef.Value(Last);
1071 pdo = Other.Value(OLast);
1072 aD = pd.SquareDistance(pdo);
1073 if (aD > Tol2 && aD > MaxDistance) {
1075 aFlag=Standard_True;
1078 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
1079 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
1081 for (i = 2; i< aNC1; i++) {
1082 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
1083 gp_Pnt pref = CRef.Value(rprm);
1085 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
1086 gp_Pnt pother = Other.Value(oprm);
1088 refd.Perform(pother,rprm);
1089 if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
1090 if (refd.IsDone()) {
1091 aD=refd.SquareDistance();
1092 if (aD > Tol2 && aD>MaxDistance) {
1093 aFlag=Standard_True;
1099 otherd.Perform(pref,oprm);
1100 if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
1102 if (otherd.IsDone()) {
1103 aD=otherd.SquareDistance();
1104 if (aD > Tol2 && aD>MaxDistance) {
1105 aFlag=Standard_True;
1113 aD=sqrt (MaxDistance);
1117 //=======================================================================
1118 // Function : UpdateEdges
1120 //=======================================================================
1121 void UpdateEdges(const TopoDS_Face& aF)
1123 Standard_Real aTolF, aTolE, aTolV;
1124 TopoDS_Iterator aItF, aItW, aItE;
1127 aTolE=aTolF= BRep_Tool::Tolerance(aF);
1128 aItF.Initialize(aF);
1129 for (; aItF.More(); aItF.Next()) {
1130 const TopoDS_Shape& aS = aItF.Value();
1131 if (aS.ShapeType()==TopAbs_WIRE) {
1132 aItW.Initialize(aS);
1133 for (; aItW.More(); aItW.Next()) {
1134 const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
1135 aTolE = BRep_Tool::Tolerance(aE);
1136 if (aTolE < aTolF) {
1137 aBB.UpdateEdge(aE, aTolF);
1140 //UpdateVertices(aE);
1144 const TopoDS_Vertex& aV=*(TopoDS_Vertex*)&aItF.Value();
1145 aTolV = BRep_Tool::Tolerance(aV);
1146 if (aTolV < aTolE) {
1147 aBB.UpdateVertex(aV, aTolF);
1152 //=======================================================================
1153 // Function : MinComputing
1155 //=======================================================================
1156 static Standard_Boolean MinComputing( BOPTools_CheckCurveOnSurface& theFunction,
1157 const Standard_Real theFirst,
1158 const Standard_Real theLast,
1159 const Standard_Real theEpsilon, //1.0e-3
1160 Standard_Real & theBestValue,
1161 Standard_Real & theBestParameter)
1163 //Standard_Real aPrevValue = theBestValue;
1164 const Standard_Real aStepMin = 1.0e-2;
1165 math_Vector aFirstV(1, 1), aLastV(1, 1), anOutputParam(1, 1);
1166 aFirstV(1) = theFirst;
1167 aLastV(1) = theLast;
1169 math_GlobOptMin aFinder(&theFunction, aFirstV, aLastV);
1170 aFinder.SetTol(aStepMin, theEpsilon);
1173 const Standard_Integer aNbExtr = aFinder.NbExtrema();
1174 for(Standard_Integer i = 1; i <= aNbExtr; i++)
1176 Standard_Real aValue = 0.0;
1177 aFinder.Points(i, anOutputParam);
1178 theFunction.Value(anOutputParam, aValue);
1180 if(aValue < theBestValue)
1182 theBestValue = aValue;
1183 theBestParameter = anOutputParam(1);
1187 return Standard_True;
1190 //=======================================================================
1191 // Function : ComputeTolerance
1193 //=======================================================================
1194 Standard_Boolean BOPTools_AlgoTools::
1195 ComputeTolerance( const Handle(Geom_Curve)& theCurve3D,
1196 const Handle(Geom2d_Curve)& theCurve2D,
1197 const Handle(Geom_Surface)& theSurf,
1198 Standard_Real& theMaxDist,
1199 Standard_Real& theMaxPar)
1201 if (theCurve3D.IsNull() ||
1202 theCurve2D.IsNull() ||
1204 return Standard_False;
1207 const Standard_Real anEpsilonRange = 1.0e-3, aMinDelta = 1.0e-5;
1211 Standard_Real aFirst = theCurve3D->FirstParameter(),
1212 aLast = theCurve3D->LastParameter();
1214 BOPTools_CheckCurveOnSurface aFunc(theCurve3D, theCurve2D, theSurf);
1216 math_Vector anOutputParam(1, 1);
1217 anOutputParam(1) = theMaxPar = aFirst;
1220 MinComputing(aFunc, aFirst, aLast, anEpsilonRange, theMaxDist, theMaxPar);
1222 Standard_Integer aNbIteration = 100;
1223 Standard_Boolean aStatus = Standard_True;
1224 while((aNbIteration-- >= 0) && aStatus)
1226 Standard_Real aValue = theMaxDist, aParam = theMaxPar;
1227 Standard_Real aBP = theMaxPar - aMinDelta;
1228 MinComputing(aFunc, aFirst, aBP, anEpsilonRange, theMaxDist, theMaxPar);
1230 if(theMaxDist < aValue)
1233 aStatus = Standard_True;
1237 theMaxDist = aValue;
1239 aStatus = Standard_False;
1244 aBP = theMaxPar + aMinDelta;
1245 MinComputing(aFunc, aBP, aLast, 1.0e-3, theMaxDist, theMaxPar);
1247 if(theMaxDist < aValue)
1250 aStatus = Standard_True;
1254 theMaxDist = aValue;
1256 aStatus = Standard_False;
1261 theMaxDist = sqrt(Abs(theMaxDist));
1264 return Standard_False;
1267 return Standard_True;
1270 //=======================================================================
1271 // Function : ComputeTolerance
1273 //=======================================================================
1274 Standard_Boolean BOPTools_AlgoTools::ComputeTolerance
1275 (const TopoDS_Face& theFace,
1276 const TopoDS_Edge& theEdge,
1277 Standard_Real& theMaxDist,
1278 Standard_Real& theParameter)
1280 Standard_Boolean bRet;
1281 Standard_Real aT, aD, aFirst, aLast;
1282 TopLoc_Location aLocC, aLocS;
1286 bRet = Standard_False;
1288 const Handle(BRep_TEdge)& aTE = *((Handle(BRep_TEdge)*)&theEdge.TShape());
1289 //The edge is considered to be same range and not degenerated
1290 if ((!aTE->SameRange() && aTE->SameParameter()) ||
1291 aTE->Degenerated()) {
1295 Handle(Geom_Curve) aC = Handle(Geom_Curve)::
1296 DownCast(BRep_Tool::Curve(theEdge, aLocC, aFirst, aLast)->Copy());
1297 aC = new Geom_TrimmedCurve(aC, aFirst, aLast);
1298 aC->Transform(aLocC.Transformation());
1300 const Handle(Geom_Surface)& aSurfF = BRep_Tool::Surface(theFace, aLocS);
1301 const Handle(Geom_Surface)& aSurf = Handle(Geom_Surface)::
1302 DownCast(aSurfF->Copy()->Transformed(aLocS.Transformation()));
1304 Standard_Boolean isPCurveFound = Standard_False;
1305 BRep_ListIteratorOfListOfCurveRepresentation itcr(aTE->Curves());
1306 for (; itcr.More(); itcr.Next()) {
1307 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
1308 if (!(cr->IsCurveOnSurface(aSurfF, aLocS.Predivided(theEdge.Location())))) {
1311 isPCurveFound = Standard_True;
1313 Handle(Geom2d_Curve) aC2d = Handle(Geom2d_Curve)::
1314 DownCast(cr->PCurve()->Copy());
1315 aC2d = new Geom2d_TrimmedCurve(aC2d, aFirst, aLast);
1317 if(BOPTools_AlgoTools::ComputeTolerance
1318 (aC, aC2d, aSurf, aD, aT)) {
1319 bRet = Standard_True;
1320 if (aD > theMaxDist) {
1326 if (cr->IsCurveOnClosedSurface()) {
1327 Handle(Geom2d_Curve) aC2d = Handle(Geom2d_Curve)::
1328 DownCast(cr->PCurve2()->Copy());
1329 aC2d = new Geom2d_TrimmedCurve(aC2d, aFirst, aLast);
1331 if(BOPTools_AlgoTools::ComputeTolerance
1332 (aC, aC2d, aSurf, aD, aT)) {
1333 bRet = Standard_True;
1334 if (aD > theMaxDist) {
1342 if (isPCurveFound) {
1346 Handle(Geom_Plane) aPlane;
1347 Handle(Standard_Type) dtyp = aSurf->DynamicType();
1349 if (dtyp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1350 aPlane = Handle(Geom_Plane)::
1351 DownCast(Handle(Geom_RectangularTrimmedSurface)::
1352 DownCast(aSurf)->BasisSurface()->Copy());
1355 aPlane = Handle(Geom_Plane)::DownCast(aSurf->Copy());
1358 if (aPlane.IsNull()) { // not a plane
1362 aPlane = Handle(Geom_Plane)::DownCast(aPlane);//
1364 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aPlane);
1365 Handle(Geom_Curve) ProjOnPlane =
1366 GeomProjLib::ProjectOnPlane (new Geom_TrimmedCurve(aC, aFirst, aLast),
1367 aPlane, aPlane->Position().Direction(),
1369 Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
1371 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
1372 Handle(Geom2d_Curve) aC2d = Geom2dAdaptor::MakeCurve(proj);
1373 aC2d = new Geom2d_TrimmedCurve(aC2d, aFirst, aLast);
1375 if(BOPTools_AlgoTools::ComputeTolerance
1376 (aC, aC2d, aPlane, aD, aT)) {
1377 bRet = Standard_True;
1378 if (aD > theMaxDist) {