From c9337e33a6a382288926695961c3a88bcb455613 Mon Sep 17 00:00:00 2001 From: asuraven Date: Wed, 28 Apr 2021 12:06:39 +0300 Subject: [PATCH] 0029059: It is necessary to have a unique way of checking of the validity of the edge and its 2D curves Add new class BRepLib_ValidateEdge to use for edge checking instead of functions: - Validate() from BOPTools_AlgoTools.cxx - Validate() from BRepCheck_Edge.cxx - ShapeAnalysis_Edge::ComputeDeviation() --- src/BOPTools/BOPTools_AlgoTools_1.cxx | 160 +++------------ src/BRepCheck/BRepCheck_Edge.cxx | 206 ++----------------- src/BRepFill/BRepFill_AdvancedEvolved.cxx | 3 +- src/BRepLib/BRepLib_CheckCurveOnSurface.cxx | 10 +- src/BRepLib/BRepLib_CheckCurveOnSurface.hxx | 14 +- src/BRepLib/BRepLib_ValidateEdge.cxx | 214 ++++++++++++++++++++ src/BRepLib/BRepLib_ValidateEdge.hxx | 81 ++++++++ src/BRepLib/FILES | 2 + src/BRepOffset/BRepOffset_SimpleOffset.cxx | 18 +- src/GeomLib/GeomLib_CheckCurveOnSurface.cxx | 4 +- src/GeomLib/GeomLib_CheckCurveOnSurface.hxx | 5 +- src/IntTools/IntTools_Tools.cxx | 2 +- src/ShapeAnalysis/ShapeAnalysis_Edge.cxx | 88 ++------ src/ShapeAnalysis/ShapeAnalysis_Edge.hxx | 7 - 14 files changed, 385 insertions(+), 429 deletions(-) create mode 100644 src/BRepLib/BRepLib_ValidateEdge.cxx create mode 100644 src/BRepLib/BRepLib_ValidateEdge.hxx diff --git a/src/BOPTools/BOPTools_AlgoTools_1.cxx b/src/BOPTools/BOPTools_AlgoTools_1.cxx index d020740e1f..613af81479 100644 --- a/src/BOPTools/BOPTools_AlgoTools_1.cxx +++ b/src/BOPTools/BOPTools_AlgoTools_1.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -82,12 +83,6 @@ static const TopoDS_Face& S, const Standard_Real aMaxTol, const TopTools_IndexedMapOfShape& aMapToAvoid); -static - Standard_Boolean Validate(const Adaptor3d_Curve& CRef, - const Adaptor3d_Curve& Other, - const Standard_Real Tol, - const Standard_Boolean SameParameter, - Standard_Real& aNewTolerance); static void CorrectVertexTolerance(const TopoDS_Edge& aE, @@ -808,7 +803,6 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape, { if (myCref.IsNull()) return; - Standard_Boolean ok = Standard_True; Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape()); Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape)); @@ -818,7 +812,6 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape, Standard_Boolean SameRange = TE->SameRange(); Standard_Real First = myHCurve->FirstParameter(); Standard_Real Last = myHCurve->LastParameter(); - Standard_Real Delta = BOPTools_AlgoTools::DTolerance(); Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape()); const TopLoc_Location& Floc = S.Location(); @@ -847,23 +840,30 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape, new GeomAdaptor_Surface(Sb); Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(PC,f,l); - Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); - ok = Validate (*myHCurve, ACS, Tol, SameParameter, aNewTol); - if (ok) { + Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS); + + BRepLib_ValidateEdge aValidateEdge(myHCurve, ACS, SameParameter); + aValidateEdge.Process(); + aValidateEdge.UpdateTolerance(aNewTol); + if (aValidateEdge.IsDone() && !aValidateEdge.CheckTolerance(Tol)) + { if (aNewTolIsCurveOnClosedSurface()) { - //checkclosed = Standard_True; GHPC->Load(cr->PCurve2(),f,l); // same bounds - ACS.Load(GHPC, GAHS); // sans doute inutile - ok = Validate (*myHCurve, ACS, Tol, SameParameter, aNewTol); - if (ok) { + ACS->Load(GHPC, GAHS); // sans doute inutile + + BRepLib_ValidateEdge aValidateEdgeOnClosedSurf(myHCurve, ACS, SameParameter); + aValidateEdgeOnClosedSurf.Process(); + aValidateEdgeOnClosedSurf.UpdateTolerance(aNewTol); + if (aValidateEdgeOnClosedSurf.IsDone() && !aValidateEdgeOnClosedSurf.CheckTolerance(Tol)) + { if (aNewTolFirstParameter(), myHCurve->LastParameter()); - Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); + Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS); - Standard_Boolean okx = Validate(*myHCurve, ACS, - Tol,Standard_True, aNewTol); - if (okx) { + BRepLib_ValidateEdge aValidateProjEdge(myHCurve, ACS, Standard_True); + aValidateProjEdge.Process(); + aValidateProjEdge.UpdateTolerance(aNewTol); + if (aValidateProjEdge.IsDone() && !aValidateProjEdge.CheckTolerance(Tol)) + { if (aNewTol Tol2) { - if (aD>MaxDistance) { - MaxDistance=aD; - } - aFlag=Standard_True; - } - } - - if (aFlag) { - aNewTolerance=sqrt(MaxDistance); - } - return aFlag; - } - - // - // 2. - else { - Extrema_LocateExtPC refd,otherd; - Standard_Real OFirst, OLast; - OFirst = Other.FirstParameter(); - OLast = Other.LastParameter(); - - gp_Pnt pd = CRef.Value(First); - gp_Pnt pdo = Other.Value(OFirst); - - aD = pd.SquareDistance(pdo); - if (aD > Tol2) { - if (aD>MaxDistance) { - MaxDistance=aD; - } - aFlag=Standard_True; - } - - pd = CRef.Value(Last); - pdo = Other.Value(OLast); - aD = pd.SquareDistance(pdo); - if (aD > Tol2 && aD > MaxDistance) { - MaxDistance=aD; - aFlag=Standard_True; - } - - refd.Initialize(CRef, First, Last, CRef.Resolution(Tol)); - otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol)); - - for (i = 2; i< aNC1; i++) { - Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1; - gp_Pnt pref = CRef.Value(rprm); - - Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1; - gp_Pnt pother = Other.Value(oprm); - - refd.Perform(pother,rprm); - if (!refd.IsDone() || refd.SquareDistance() > Tol2) { - if (refd.IsDone()) { - aD=refd.SquareDistance(); - if (aD > Tol2 && aD>MaxDistance) { - aFlag=Standard_True; - MaxDistance=aD; - } - } - } - - otherd.Perform(pref,oprm); - if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) { - - if (otherd.IsDone()) { - aD=otherd.SquareDistance(); - if (aD > Tol2 && aD>MaxDistance) { - aFlag=Standard_True; - MaxDistance=aD; - } - } - } - } - } - - aD=sqrt (MaxDistance); - aNewTolerance=aD; - return aFlag; -} -//======================================================================= // Function : UpdateEdges // purpose : //======================================================================= diff --git a/src/BRepCheck/BRepCheck_Edge.cxx b/src/BRepCheck/BRepCheck_Edge.cxx index 72c322ab88..5b0e789af6 100644 --- a/src/BRepCheck/BRepCheck_Edge.cxx +++ b/src/BRepCheck/BRepCheck_Edge.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -63,27 +64,6 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Edge,BRepCheck_Result) -//modified by NIZNHY-PKV Thu May 05 09:01:57 2011f -static - Standard_Boolean Validate(const Adaptor3d_Curve&, - const Adaptor3d_CurveOnSurface&, - const Standard_Real, - const Standard_Boolean); -static - void PrintProblematicPoint(const gp_Pnt&, - const Standard_Real, - const Standard_Real); - -static - Standard_Real Prec(const Adaptor3d_Curve& aAC3D, - const Adaptor3d_CurveOnSurface& aACS); - -//static Standard_Boolean Validate(const Adaptor3d_Curve&, -// const Adaptor3d_Curve&, -// const Standard_Real, -// const Standard_Boolean); -//modified by NIZNHY-PKV Thu May 05 09:02:01 2011t - static const Standard_Integer NCONTROL=23; //======================================================================= @@ -397,9 +377,13 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) Handle(Geom2d_Curve) PC = cr->PCurve(); Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(Sb); Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(PC,f,l); - Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); - Standard_Boolean ok = Validate (*myHCurve, ACS, Tol, SameParameter); - if (!ok) { + Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS); + + BRepLib_ValidateEdge aValidateEdge(myHCurve, ACS, SameParameter); + aValidateEdge.SetExitIfToleranceExceeded(Tol); + aValidateEdge.Process(); + if (!aValidateEdge.IsDone() || !aValidateEdge.CheckTolerance(Tol)) + { if (cr->IsCurveOnClosedSurface()) { BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); } @@ -415,9 +399,13 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) } if (cr->IsCurveOnClosedSurface()) { GHPC->Load(cr->PCurve2(),f,l); // same bounds - ACS.Load(GHPC, GAHS); // sans doute inutile - ok = Validate(*myHCurve,ACS,Tol,SameParameter); - if (!ok) { + ACS->Load(GHPC, GAHS); // sans doute inutile + + BRepLib_ValidateEdge aValidateEdgeOnClosedSurf(myHCurve, ACS, SameParameter); + aValidateEdgeOnClosedSurf.SetExitIfToleranceExceeded(Tol); + aValidateEdgeOnClosedSurf.Process(); + if (!aValidateEdgeOnClosedSurf.IsDone() || !aValidateEdgeOnClosedSurf.CheckTolerance(Tol)) + { BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); // Modified by skv - Tue Apr 27 11:53:20 2004 Begin if (SameParameter) { @@ -470,10 +458,13 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) myHCurve->FirstParameter(), myHCurve->LastParameter()); - Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); + Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC,GAHS); - Standard_Boolean ok = Validate (*myHCurve, ACS, Tol,Standard_True); // voir dub... - if (!ok) { + BRepLib_ValidateEdge aValidateEdgeProj(myHCurve, ACS, SameParameter); + aValidateEdgeProj.SetExitIfToleranceExceeded(Tol); + aValidateEdgeProj.Process(); + if (!aValidateEdgeProj.IsDone() || !aValidateEdgeProj.CheckTolerance(Tol)) + { BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); } } @@ -778,158 +769,3 @@ BRepCheck_Status BRepCheck_Edge:: return BRepCheck_NoError; } -//======================================================================= -//function : Validate -//purpose : -//======================================================================= -Standard_Boolean Validate(const Adaptor3d_Curve& CRef, - const Adaptor3d_CurveOnSurface& Other, - const Standard_Real Tol, - const Standard_Boolean SameParameter) -{ - Standard_Boolean Status, proj; - Standard_Real aPC, First, Last, Error; - gp_Pnt problematic_point ; - // - Status = Standard_True; - Error = 0.; - First = CRef.FirstParameter(); - Last = CRef.LastParameter(); - - aPC=Precision::PConfusion(); - proj = (!SameParameter || - Abs(Other.FirstParameter()-First) > aPC || - Abs( Other.LastParameter()-Last) > aPC); - if (!proj) - { - Standard_Integer i; - Standard_Real Tol2, prm, dD; - gp_Pnt pref, pother; - //modified by NIZNHY-PKV Thu May 05 09:06:41 2011f - //OCC22428 - dD=Prec(CRef, Other);//3.e-15; - Tol2=Tol+dD; - Tol2=Tol2*Tol2; - //Tol2=Tol*Tol; - //modified by NIZNHY-PKV Thu May 05 09:06:47 2011t - - for (i = 0; i < NCONTROL; ++i) { - prm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1); - pref = CRef.Value(prm); - pother = Other.Value(prm); - if (pref.SquareDistance(pother) > Tol2) { - problematic_point = pref ; - Status = Standard_False; - Error = pref.Distance(pother); - PrintProblematicPoint(problematic_point, Error, Tol); - return Status; - //goto FINISH ; - } - } - } - else { - Extrema_LocateExtPC refd,otherd; - Standard_Real OFirst = Other.FirstParameter(); - Standard_Real OLast = Other.LastParameter(); - gp_Pnt pd = CRef.Value(First); - gp_Pnt pdo = Other.Value(OFirst); - Standard_Real distt = pd.SquareDistance(pdo); - if (distt > Tol*Tol) { - problematic_point = pd ; - Status = Standard_False ; - Error = Sqrt(distt); - PrintProblematicPoint(problematic_point, Error, Tol); - return Status; - //goto FINISH ; - } - pd = CRef.Value(Last); - pdo = Other.Value(OLast); - distt = pd.SquareDistance(pdo); - if (distt > Tol*Tol) { - problematic_point = pd ; - Status = Standard_False ; - Error = Sqrt(distt); - PrintProblematicPoint(problematic_point, Error, Tol); - return Status; - //goto FINISH ; - } - - refd.Initialize(CRef,First,Last,CRef.Resolution(Tol)); - otherd.Initialize(Other,OFirst,OLast,Other.Resolution(Tol)); - for (Standard_Integer i = 2; i< NCONTROL-1; i++) { - Standard_Real rprm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1); - gp_Pnt pref = CRef.Value(rprm); - Standard_Real oprm = ((NCONTROL-1-i)*OFirst + i*OLast)/(NCONTROL-1); - gp_Pnt pother = Other.Value(oprm); - refd.Perform(pother,rprm); - if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) { - problematic_point = pref ; - Status = Standard_False ; - if (refd.IsDone()) { - Error = sqrt (refd.SquareDistance()); - } - else { - Error = RealLast(); - } - PrintProblematicPoint(problematic_point, Error, Tol); - return Status; - //goto FINISH ; - } - otherd.Perform(pref,oprm); - if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) { - problematic_point = pref ; - Status = Standard_False ; - if (otherd.IsDone()) { - Error = sqrt (otherd.SquareDistance()); - } - else { - Error = RealLast(); - } - PrintProblematicPoint(problematic_point, Error, Tol); - return Status; - //goto FINISH ; - } - } - } - - return Status ; - -} - -//======================================================================= -//function : Prec -//purpose : -//======================================================================= -Standard_Real Prec(const Adaptor3d_Curve& aAC3D, - const Adaptor3d_CurveOnSurface& aACS) -{ - Standard_Real aXEmax, aXC, aXS; - const Handle(Adaptor3d_Surface)& aAHS = aACS.GetSurface(); - // - aXC = BRepCheck::PrecCurve(aAC3D); - aXS = BRepCheck::PrecSurface(aAHS); - aXEmax = (aXC>aXS) ? aXC: aXS; - return aXEmax; -} - -//======================================================================= -//function : PrintProblematicPoint -//purpose : -//======================================================================= -#ifdef OCCT_DEBUG -void PrintProblematicPoint(const gp_Pnt& problematic_point, - const Standard_Real Error, - const Standard_Real Tol) -{ - std::cout << " **** probleme de SameParameter au point :" << std::endl; - std::cout << " " << problematic_point.Coord(1) << " " - << problematic_point.Coord(2) << " " << problematic_point.Coord(3) << std::endl ; - std::cout << " Erreur detectee :" << Error << " Tolerance :" << Tol << std::endl; -} -#else -void PrintProblematicPoint(const gp_Pnt&, - const Standard_Real, - const Standard_Real) -{ -} -#endif diff --git a/src/BRepFill/BRepFill_AdvancedEvolved.cxx b/src/BRepFill/BRepFill_AdvancedEvolved.cxx index b5eb9b8fa2..70f4b2bb16 100644 --- a/src/BRepFill/BRepFill_AdvancedEvolved.cxx +++ b/src/BRepFill/BRepFill_AdvancedEvolved.cxx @@ -2007,7 +2007,8 @@ void ProcessVertex(const TopoDS_Vertex& aV, } // // Update Tolerance - TV->Tolerance(aTolMax2); + // with a small margin + TV->Tolerance(aTolMax2 + aTolMax2 * 0.0001); } //======================================================================= diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx index d14f2f17b4..c9a3257c81 100644 --- a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx +++ b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx @@ -79,10 +79,10 @@ void BRepLib_CheckCurveOnSurface::Init //function : Perform //purpose : if isTheMTDisabled == TRUE parallelization is not used //======================================================================= -void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled) +void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isMultiThread) { // Compute the max distance - Compute(myPCurve, isTheMTDisabled); + Compute(myPCurve, isMultiThread); if (ErrorStatus()) { return; @@ -92,7 +92,7 @@ void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled { // compute max distance for myPCurve2 // (for the second curve on closed surface) - Compute(myPCurve2, isTheMTDisabled); + Compute(myPCurve2, isMultiThread); } } @@ -101,7 +101,7 @@ void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled //purpose : if isTheMTDisabled == TRUE parallelization is not used //======================================================================= void BRepLib_CheckCurveOnSurface::Compute(const Handle(Geom2d_Curve)& thePCurve, - const Standard_Boolean isTheMTDisabled) + const Standard_Boolean isMultiThread) { - myCOnSurfGeom.Perform(thePCurve, isTheMTDisabled); + myCOnSurfGeom.Perform(thePCurve, isMultiThread); } diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx index 160ec35dd7..a30aae6521 100644 --- a/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx +++ b/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx @@ -17,8 +17,8 @@ #include -//! Computes the max distance between edge and its -//! 2d representation on the face. +//! Computes the max distance between edge and its 2d representation on the face. +//! This class is not intended to process non-sameparameter edges. class BRepLib_CheckCurveOnSurface { @@ -37,9 +37,8 @@ public: Standard_EXPORT void Init (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace); //! Performs the calculation - //! If isTheMultyTheadDisabled == TRUE then computation will be made - //! without any parallelization. - Standard_EXPORT void Perform (const Standard_Boolean isTheMultyTheradDisabled = Standard_False); + //! If isMultiThread == Standard_True then computation will be performed in parallel. + Standard_EXPORT void Perform(const Standard_Boolean isMultiThread = Standard_True); //! Returns source 3D-Curve const Handle(Geom_Curve)& Curve() const @@ -105,10 +104,9 @@ protected: //! Computes the max distance for the 3d curve of //! and 2d curve - //! If isTheMultyTheadDisabled == TRUE then computation will be made - //! without any parallelization. + //! If isMultiThread == Standard_True then computation will be performed in parallel. Standard_EXPORT void Compute (const Handle(Geom2d_Curve)& thePCurve, - const Standard_Boolean isTheMultyTheradDisabled); + const Standard_Boolean isMultiThread); private: diff --git a/src/BRepLib/BRepLib_ValidateEdge.cxx b/src/BRepLib/BRepLib_ValidateEdge.cxx new file mode 100644 index 0000000000..f97a13640e --- /dev/null +++ b/src/BRepLib/BRepLib_ValidateEdge.cxx @@ -0,0 +1,214 @@ +// Copyright (c) 2021 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include + +//============================================================================= +//function : BRepLib_ValidateEdge +//purpose : Constructor +//============================================================================= +BRepLib_ValidateEdge::BRepLib_ValidateEdge(Handle(Adaptor3d_Curve) theReferenceCurve, + Handle(Adaptor3d_CurveOnSurface) theOtherCurve, + Standard_Boolean theSameParameter): + myReferenceCurve(theReferenceCurve), + myOtherCurve(theOtherCurve), + mySameParameter(theSameParameter), + myControlPointsNumber(22), + myToleranceForChecking(0), + myCalculatedDistance(0), + myExitIfToleranceExceeded(Standard_False), + myIsDone(Standard_False) +{ } + +//============================================================================= +//function : CheckTolerance +//purpose : +//============================================================================= +Standard_Boolean BRepLib_ValidateEdge::CheckTolerance(Standard_Real theToleranceToCheck) +{ + return correctTolerance(theToleranceToCheck) > myCalculatedDistance; +} + +//============================================================================= +//function : GetMaxDistance +//purpose : +//============================================================================= +Standard_Real BRepLib_ValidateEdge::GetMaxDistance() +{ + Standard_Real aCorrectedTolerance = myCalculatedDistance * 1.00001; + return aCorrectedTolerance; +} + +//============================================================================= +//function : UpdateTolerance +//purpose : +//============================================================================= +void BRepLib_ValidateEdge::UpdateTolerance(Standard_Real& theToleranceToUpdate) +{ + Standard_Real aCorrectedTolerance = myCalculatedDistance * 1.00001; + if (aCorrectedTolerance > theToleranceToUpdate) + { + theToleranceToUpdate = aCorrectedTolerance; + } +} + +//============================================================================= +//function : correctTolerance +//purpose : +//============================================================================= +Standard_Real BRepLib_ValidateEdge::correctTolerance(Standard_Real theTolerance) +{ + const Handle(Adaptor3d_Surface)& aSurface = myOtherCurve->GetSurface(); + Standard_Real aCurvePrecision = BRepCheck::PrecCurve(*myReferenceCurve); + Standard_Real aSurfacePrecision = BRepCheck::PrecSurface(aSurface); + Standard_Real aToleranceDelta = (aCurvePrecision > aSurfacePrecision) ? aCurvePrecision : aSurfacePrecision; + Standard_Real aCorrectedTolerance = theTolerance + aToleranceDelta; + return aCorrectedTolerance; +} + +//============================================================================= +//function : SetExitIfToleranceExceeded +//purpose : +//============================================================================= +void BRepLib_ValidateEdge::SetExitIfToleranceExceeded(Standard_Real theToleranceForChecking) +{ + myExitIfToleranceExceeded = Standard_True; + myToleranceForChecking = correctTolerance(theToleranceForChecking); +} + +//============================================================================= +//function : Process +//purpose : +//============================================================================= +void BRepLib_ValidateEdge::Process() +{ + myIsDone = Standard_True; + Standard_Real aSquareToleranceForChecking = myToleranceForChecking * myToleranceForChecking; + Standard_Real aReferenceFirstParam = myReferenceCurve->FirstParameter(); + Standard_Real aReferenceLastParam = myReferenceCurve->LastParameter(); + Standard_Real anOtherFirstParam = myOtherCurve->FirstParameter(); + Standard_Real anOtherLastParam = myOtherCurve->LastParameter(); + Standard_Real aMaxSquareDistance = 0.; + + Standard_Integer aControlPointsNumber = (myControlPointsNumber < 1) ? 1 : myControlPointsNumber; + Standard_Boolean anIsProjection = (!mySameParameter || + Abs(anOtherFirstParam - aReferenceFirstParam) > Precision::PConfusion() || + Abs(anOtherLastParam - aReferenceLastParam) > Precision::PConfusion()); + + if (!anIsProjection) + { + for (Standard_Integer i = 0; i <= aControlPointsNumber; ++i) + { + Standard_Real aControlPointParam = + ((aControlPointsNumber - i) * aReferenceFirstParam + i * aReferenceLastParam) / aControlPointsNumber; + gp_Pnt aReferencePoint = myReferenceCurve->Value(aControlPointParam); + gp_Pnt anOtherPoint = myOtherCurve->Value(aControlPointParam); + Standard_Real aSquareDistance = aReferencePoint.SquareDistance(anOtherPoint); + if (aSquareDistance > aMaxSquareDistance) + { + aMaxSquareDistance = aSquareDistance; + } + // Stop process for best performance + if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking) + { + myCalculatedDistance = Sqrt(aMaxSquareDistance); + return; + } + } + } + else + { + gp_Pnt aReferencePoint = myReferenceCurve->Value(aReferenceFirstParam); + gp_Pnt anOtherPoint = myOtherCurve->Value(anOtherFirstParam); + Standard_Real aSquareDistance = aReferencePoint.SquareDistance(anOtherPoint); + if (aSquareDistance > aMaxSquareDistance) + { + aMaxSquareDistance = aSquareDistance; + } + if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking) + { + myCalculatedDistance = Sqrt(aMaxSquareDistance); + return; + } + + aReferencePoint = myReferenceCurve->Value(aReferenceLastParam); + anOtherPoint = myOtherCurve->Value(anOtherLastParam); + aSquareDistance = aReferencePoint.SquareDistance(anOtherPoint); + if (aSquareDistance > aMaxSquareDistance) + { + aMaxSquareDistance = aSquareDistance; + } + if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking) + { + myCalculatedDistance = Sqrt(aMaxSquareDistance); + return; + } + + Extrema_LocateExtPC aReferenceExtrema, anOtherExtrema; + aReferenceExtrema.Initialize(*myReferenceCurve, aReferenceFirstParam, aReferenceLastParam, myReferenceCurve->Resolution(Precision::Confusion())); + anOtherExtrema.Initialize(*myOtherCurve, anOtherFirstParam, anOtherLastParam, myOtherCurve->Resolution(Precision::Confusion())); + for (Standard_Integer i = 1; i < aControlPointsNumber; i++) + { + Standard_Real aReferenceParam = ((aControlPointsNumber - i) * aReferenceFirstParam + i * aReferenceLastParam) / aControlPointsNumber; + gp_Pnt aReferenceExtremaPoint = myReferenceCurve->Value(aReferenceParam); + Standard_Real anOtherParam = ((aControlPointsNumber - i) * anOtherFirstParam + i * anOtherLastParam) / aControlPointsNumber; + gp_Pnt anOtherExtremaPoint = myOtherCurve->Value(anOtherParam); + + aReferenceExtrema.Perform(anOtherExtremaPoint, aReferenceParam); + if (aReferenceExtrema.IsDone()) + { + if (aReferenceExtrema.SquareDistance() > aMaxSquareDistance) + { + aMaxSquareDistance = aReferenceExtrema.SquareDistance(); + } + if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking) + { + myCalculatedDistance = Sqrt(aMaxSquareDistance); + return; + } + } + else + { + myIsDone = Standard_False; + // Stop process for best performance + return; + } + + anOtherExtrema.Perform(aReferenceExtremaPoint, anOtherParam); + if (anOtherExtrema.IsDone()) + { + if (anOtherExtrema.SquareDistance() > aMaxSquareDistance) + { + aMaxSquareDistance = anOtherExtrema.SquareDistance(); + } + if (myExitIfToleranceExceeded && aMaxSquareDistance > aSquareToleranceForChecking) + { + myCalculatedDistance = Sqrt(aMaxSquareDistance); + return; + } + } + else + { + myIsDone = Standard_False; + // Stop process for best performance + return; + } + } + } + myCalculatedDistance = Sqrt(aMaxSquareDistance); +} diff --git a/src/BRepLib/BRepLib_ValidateEdge.hxx b/src/BRepLib/BRepLib_ValidateEdge.hxx new file mode 100644 index 0000000000..48fc25c7f2 --- /dev/null +++ b/src/BRepLib/BRepLib_ValidateEdge.hxx @@ -0,0 +1,81 @@ +// Copyright (c) 2021 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + + +#ifndef _BRepLib_ValidateEdge_HeaderFile +#define _BRepLib_ValidateEdge_HeaderFile + +#include +#include + +class Adaptor3d_Curve; +class Adaptor3d_CurveOnSurface; + +//! Computes the max distance between 3D-curve and curve on +//! surface in fixed points number +class BRepLib_ValidateEdge +{ +public: + //! Initialization constructor + Standard_EXPORT BRepLib_ValidateEdge(const Handle(Adaptor3d_Curve) theReferenceCurve, + const Handle(Adaptor3d_CurveOnSurface) theOtherCurve, + Standard_Boolean theSameParameter); + + //! Set control points number (if you need a value other than 22) + void SetControlPointsNumber(Standard_Integer theControlPointsNumber) + { + myControlPointsNumber = theControlPointsNumber; + } + + //! Sets the maximal allowed distance in the Process() function. If the distance greater than + //! theToleranceForChecking the Process() function stops. Use this for best performance + //! in case of checking of tolerance. + Standard_EXPORT void SetExitIfToleranceExceeded(Standard_Real theToleranceForChecking); + + //! Computes the max distance for the 3d curve + //! and curve on surface . If the SetExitIfToleranceExceeded() + //! function was called before contains first + //! greater than SetExitIfToleranceExceeded() parameter value + Standard_EXPORT void Process(); + + //! Returns true if the distance has been found for all points + Standard_Boolean IsDone() + { + return myIsDone; + } + + //! Returns true if computed distance is less than + Standard_EXPORT Standard_Boolean CheckTolerance(Standard_Real theToleranceToCheck); + + //! Returns max distance + Standard_EXPORT Standard_Real GetMaxDistance(); + + //! Increase if max distance is greater than + Standard_EXPORT void UpdateTolerance(Standard_Real& theToleranceToUpdate); + +private: + //! Adds some margin for distance checking + Standard_Real correctTolerance(Standard_Real theTolerance); + +private: + Handle(Adaptor3d_Curve) myReferenceCurve; + Handle(Adaptor3d_CurveOnSurface) myOtherCurve; + Standard_Boolean mySameParameter; + Standard_Integer myControlPointsNumber; + Standard_Real myToleranceForChecking; + Standard_Real myCalculatedDistance; + Standard_Boolean myExitIfToleranceExceeded; + Standard_Boolean myIsDone; +}; + +#endif // _BRepLib_ValidateEdge_HeaderFile \ No newline at end of file diff --git a/src/BRepLib/FILES b/src/BRepLib/FILES index 6d7d2f98c3..cf455709cf 100755 --- a/src/BRepLib/FILES +++ b/src/BRepLib/FILES @@ -32,4 +32,6 @@ BRepLib_MakeWire.hxx BRepLib_MakeWire_1.cxx BRepLib_ShapeModification.hxx BRepLib_ShellError.hxx +BRepLib_ValidateEdge.cxx +BRepLib_ValidateEdge.hxx BRepLib_WireError.hxx diff --git a/src/BRepOffset/BRepOffset_SimpleOffset.cxx b/src/BRepOffset/BRepOffset_SimpleOffset.cxx index 82689904f4..b8d804f7a7 100644 --- a/src/BRepOffset/BRepOffset_SimpleOffset.cxx +++ b/src/BRepOffset/BRepOffset_SimpleOffset.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -35,9 +36,6 @@ #include #include -static const Standard_Integer NCONTROL=22; - - //============================================================================= //function : BRepOffset_SimpleOffset //purpose : Constructor @@ -293,15 +291,19 @@ void BRepOffset_SimpleOffset::FillEdgeData(const TopoDS_Edge& theEdge, const Handle(Geom2d_Curve) aC2dNew = BRep_Tool::CurveOnSurface(theEdge, aCurFace, aF, aL); const Handle(Adaptor2d_Curve2d) aHCurve2d = new Geom2dAdaptor_Curve(aC2dNew, aF, aL); const Handle(Adaptor3d_Surface) aHSurface = new GeomAdaptor_Surface(myFaceInfo.Find(aCurFace).myOffsetS); - Adaptor3d_CurveOnSurface aCurveOnSurf(aHCurve2d, aHSurface); + const Handle(Adaptor3d_CurveOnSurface) aCurveOnSurf = new Adaptor3d_CurveOnSurface(aHCurve2d, aHSurface); // Extract 3d-curve (it is not null). - const GeomAdaptor_Curve aCurve3d(aNED.myOffsetC, aF, aL); + const Handle(Adaptor3d_Curve) aCurve3d = new GeomAdaptor_Curve(aNED.myOffsetC, aF, aL); // It is necessary to compute maximal deviation (tolerance). - Standard_Real aMaxTol = 0.0; - ShapeAnalysis_Edge::ComputeDeviation(aCurve3d, aCurveOnSurf, Standard_True, aMaxTol, NCONTROL); - anEdgeTol = Max (anEdgeTol, aMaxTol); + BRepLib_ValidateEdge aValidateEdge(aCurve3d, aCurveOnSurf, Standard_True); + aValidateEdge.Process(); + if (aValidateEdge.IsDone()) + { + Standard_Real aMaxTol1 = aValidateEdge.GetMaxDistance(); + anEdgeTol = Max (anEdgeTol, aMaxTol1); + } } aNED.myTol = Max(BRep_Tool::Tolerance(aNewEdge), anEdgeTol); diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx index c8ad876b1e..5693499324 100644 --- a/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx +++ b/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx @@ -391,7 +391,7 @@ void GeomLib_CheckCurveOnSurface::Init( const Handle(Geom_Curve)& theCurve, //purpose : //======================================================================= void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve, - const Standard_Boolean isTheMTDisabled) + const Standard_Boolean isMultiThread) { if( myCurve.IsNull() || mySurface.IsNull() || @@ -440,7 +440,7 @@ void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve, GeomLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve, mySurface, anIntervals, anEpsilonRange, aNbParticles); - OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled); + OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, !isMultiThread); aComp.OptimalValues(myMaxDistance, myMaxParameter); diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx index 6806b69aac..1e89a2191a 100644 --- a/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx +++ b/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx @@ -54,10 +54,9 @@ public: //! Computes the max distance for the 3d curve //! and 2d curve - //! If isTheMultyTheadDisabled == TRUE then computation will be made - //! without any parallelization. + //! If isMultiThread == Standard_True then computation will be performed in parallel. Standard_EXPORT void Perform(const Handle(Geom2d_Curve)& thePCurve, - const Standard_Boolean isTheMultyTheradDisabled = Standard_False); + const Standard_Boolean isMultiThread = Standard_True); //! Returns my3DCurve const Handle(Geom_Curve)& Curve() const diff --git a/src/IntTools/IntTools_Tools.cxx b/src/IntTools/IntTools_Tools.cxx index 5f3db88462..a50033b0a7 100644 --- a/src/IntTools/IntTools_Tools.cxx +++ b/src/IntTools/IntTools_Tools.cxx @@ -798,7 +798,7 @@ Standard_Boolean IntTools_Tools::ComputeTolerance GeomLib_CheckCurveOnSurface aCS; // aCS.Init(theCurve3D, theSurf, theFirst, theLast, theTolRange); - aCS.Perform (theCurve2D, !theToRunParallel); + aCS.Perform (theCurve2D, theToRunParallel); if (!aCS.IsDone()) { return Standard_False; } diff --git a/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx b/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx index 22d0addd5f..77c4b1d178 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -705,74 +706,6 @@ Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edg return Status ( ShapeExtend_DONE ); } - -//======================================================================= -//static : Validate -//purpose: For SameParameter: compute it for two curves -//note: This function is made from Validate() in BRepCheck_Edge.cxx -//======================================================================= - -Standard_Boolean ShapeAnalysis_Edge::ComputeDeviation (const Adaptor3d_Curve& CRef, - const Adaptor3d_Curve& Other, - const Standard_Boolean SameParameter, - Standard_Real &dev, - const Standard_Integer NCONTROL) -{ - Standard_Boolean OK = Standard_True; - Standard_Real dev2 = dev*dev; - - Standard_Real First = CRef.FirstParameter(), Last = CRef.LastParameter(); - Standard_Real OFirst = Other.FirstParameter(), OLast = Other.LastParameter(); //szv#4:S4163:12Mar99 moved - - Standard_Boolean proj = (!SameParameter || First != OFirst || Last != OLast); //szv#4:S4163:12Mar99 optimized - - Standard_Integer NCtrl = ( NCONTROL < 1 )? 1 : NCONTROL; //szv#4:S4163:12Mar99 anti-exception - - if (!proj) { - for (Standard_Integer i = 0; i <= NCtrl; i++) { - Standard_Real prm = ((NCtrl-i)*First + i*Last)/NCtrl; - gp_Pnt pref = CRef.Value(prm); - gp_Pnt pother = Other.Value(prm); - Standard_Real dist2 = pref.SquareDistance(pother); - if ( dev2 < dist2 ) dev2 = dist2; - } - dev = Sqrt ( dev2 ); - } - else { - gp_Pnt pd = CRef.Value(First); - gp_Pnt pdo = Other.Value(OFirst); - Standard_Real dist2 = pd.SquareDistance(pdo); - if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 ); - - pd = CRef.Value(Last); - pdo = Other.Value(OLast); - dist2 = pd.SquareDistance(pdo); - if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 ); - - Extrema_LocateExtPC refd, otherd; //szv#4:S4163:12Mar99 warning - refd.Initialize(CRef,First,Last,Precision::PConfusion()); - otherd.Initialize(Other,OFirst,OLast,Precision::PConfusion()); - - for (Standard_Integer i = 1; i < NCtrl; i++) { //szv#4:S4163:12Mar99 was bug - Standard_Real rprm = ((NCtrl-i)*First + i*Last)/NCtrl; - gp_Pnt pref = CRef.Value(rprm); - Standard_Real oprm = ((NCtrl-i)*OFirst + i*OLast)/NCtrl; - gp_Pnt pother = Other.Value(oprm); - - refd.Perform(pother,rprm); - if ( ! refd.IsDone() ) OK = Standard_False; - else if ( dev2 < refd.SquareDistance() ) {dev2 = refd.SquareDistance(); dev = sqrt (dev2);} - - otherd.Perform(pref,oprm); - if ( ! otherd.IsDone() ) OK = Standard_False; - else if ( dev2 < otherd.SquareDistance() ) {dev2 = otherd.SquareDistance(); dev = sqrt (dev2);} - } - } - dev *= 1.00001;//ims007 entity 8067 edge 3; 1e-07USA60022 (4255, 4-th edge) SA_Check and BRepCh find distinct points001; // ensure that dev*dev >= dev2 - - return OK; -} - //======================================================================= //function : CheckSameParameter //purpose : @@ -824,7 +757,7 @@ Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge } // Create adaptor for the curve - GeomAdaptor_Curve aGAC(aC3D, aFirst, aLast); + Handle(GeomAdaptor_Curve) aGAC = new GeomAdaptor_Curve(aC3D, aFirst, aLast); Handle(Geom_Surface) aFaceSurf; TopLoc_Location aFaceLoc; @@ -869,8 +802,13 @@ Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(aPC, f, l); Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST); - Adaptor3d_CurveOnSurface ACS(GHPC, GAHS); - if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1)) + Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS); + + BRepLib_ValidateEdge aValidateEdge(aGAC, ACS, SameParameter); + aValidateEdge.SetControlPointsNumber(NbControl-1); + aValidateEdge.Process(); + aValidateEdge.UpdateTolerance(maxdev); + if (!aValidateEdge.IsDone()) { myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); } @@ -890,9 +828,13 @@ Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge Handle(Geom_Surface)::DownCast(aFaceSurf->Transformed(aFaceLoc.Transformation())); Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(aST); - Adaptor3d_CurveOnSurface ACS(GHPC, GAHS); + Handle(Adaptor3d_CurveOnSurface) ACS = new Adaptor3d_CurveOnSurface(GHPC, GAHS); - if (!ComputeDeviation(aGAC, ACS, SameParameter, maxdev, NbControl - 1)) + BRepLib_ValidateEdge aValidateEdgeOnPlane(aGAC, ACS, SameParameter); + aValidateEdgeOnPlane.SetControlPointsNumber(NbControl - 1); + aValidateEdgeOnPlane.Process(); + aValidateEdgeOnPlane.UpdateTolerance(maxdev); + if (!aValidateEdgeOnPlane.IsDone()) { myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2); } diff --git a/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx b/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx index 7437b07d6d..392fc8ffc8 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx @@ -175,13 +175,6 @@ public: //! having respect to real first, last parameters of thePC Standard_EXPORT Standard_Boolean CheckPCurveRange (const Standard_Real theFirst, const Standard_Real theLast, const Handle(Geom2d_Curve)& thePC); - - //! Computes the maximal deviation between the two curve - //! representations. - //! dev is an input/output parameter and contains the computed - //! deviation (should be initialized with 0. for the first call). - //! Used by CheckSameParameter(). - Standard_EXPORT static Standard_Boolean ComputeDeviation (const Adaptor3d_Curve& CRef, const Adaptor3d_Curve& Other, const Standard_Boolean SameParameter, Standard_Real& dev, const Standard_Integer NCONTROL); //! Checks the first edge is overlapped with second edge. //! If distance between two edges is less then theTolOverlap