From 5adae760bffb0c28bf43274af572e0d68f579f70 Mon Sep 17 00:00:00 2001 From: nbv Date: Thu, 6 Aug 2015 12:13:41 +0300 Subject: [PATCH] 0026506: Change class BRepLib_CheckCurveOnSurface 1. Inline methods have been moved to hxx-file. 2. Geometric part of BRepLib_CheckCurveOnSurface has been moved to GeomLib_CheckCurveOnSurface. Move try/catch treatment to low level (from BRepLib_CheckCurveOnSurface to GeomLib_CheckCurveOnSurface). --- src/BRepLib/BRepLib_CheckCurveOnSurface.cxx | 667 +------------------- src/BRepLib/BRepLib_CheckCurveOnSurface.hxx | 152 ++--- src/BRepLib/BRepLib_CheckCurveOnSurface.lxx | 112 ---- src/BRepLib/FILES | 1 - src/GeomLib/FILES | 2 + src/GeomLib/GeomLib_CheckCurveOnSurface.cxx | 653 +++++++++++++++++++ src/GeomLib/GeomLib_CheckCurveOnSurface.hxx | 117 ++++ src/IntTools/IntTools_Tools.cxx | 6 +- 8 files changed, 860 insertions(+), 850 deletions(-) delete mode 100644 src/BRepLib/BRepLib_CheckCurveOnSurface.lxx create mode 100644 src/GeomLib/GeomLib_CheckCurveOnSurface.cxx create mode 100644 src/GeomLib/GeomLib_CheckCurveOnSurface.hxx diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx index 5c40e5b70b..3159c34cd1 100644 --- a/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx +++ b/src/BRepLib/BRepLib_CheckCurveOnSurface.cxx @@ -12,353 +12,25 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include #include -class BRepLib_CheckCurveOnSurface_TargetFunc; - -static -Standard_Boolean MinComputing( - BRepLib_CheckCurveOnSurface_TargetFunc& theFunction, - const Standard_Real theEpsilon, //1.0e-3 - const Standard_Integer theNbParticles, - Standard_Real& theBestValue, - Standard_Real& theBestParameter); - -static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d, - const Handle(Geom2d_Curve)& theCurve2d, - const Standard_Real theFirst, - const Standard_Real theLast, - Standard_Integer &theNbParticles, - TColStd_Array1OfReal* const theSubIntervals = 0); - -//======================================================================= -//class : BRepLib_CheckCurveOnSurface_TargetFunc -//purpose : Target function (to be minimized) -//======================================================================= -class BRepLib_CheckCurveOnSurface_TargetFunc : - public math_MultipleVarFunctionWithHessian -{ - public: - BRepLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D, - const Adaptor3d_Curve& theAdCS, - const Standard_Real theFirst, - const Standard_Real theLast): - myCurve1(theC3D), - myCurve2(theAdCS), - myFirst(theFirst), - myLast(theLast) - { - } - - //returns the number of parameters of the function - //(the function is one-dimension). - virtual Standard_Integer NbVariables() const { - return 1; - } - - //returns value of the function when parameters are equal to theX - virtual Standard_Boolean Value(const math_Vector& theX, - Standard_Real& theFVal) - { - return Value(theX(1), theFVal); - } - - //returns value of the one-dimension-function when parameter - //is equal to theX - Standard_Boolean Value( const Standard_Real theX, - Standard_Real& theFVal) const - { - try - { - OCC_CATCH_SIGNALS - if (!CheckParameter(theX)) - return Standard_False; - - const gp_Pnt aP1(myCurve1.Value(theX)), - aP2(myCurve2.Value(theX)); - - theFVal = -1.0*aP1.SquareDistance(aP2); - } - catch(Standard_Failure) { - return Standard_False; - } - // - return Standard_True; - } - - //see analogical method for abstract owner class math_MultipleVarFunction - virtual Standard_Integer GetStateNumber() - { - return 0; - } - - //returns the gradient of the function when parameters are - //equal to theX - virtual Standard_Boolean Gradient(const math_Vector& theX, - math_Vector& theGrad) - { - return Derive(theX(1), theGrad(1)); - } - - //returns 1st derivative of the the one-dimension-function when - //parameter is equal to theX - Standard_Boolean Derive(const Standard_Real theX, Standard_Real& theDeriv) const - { - try - { - OCC_CATCH_SIGNALS - if (!CheckParameter(theX)) - { - return Standard_False; - } - // - gp_Pnt aP1, aP2; - gp_Vec aDC1, aDC2; - // - myCurve1.D1(theX, aP1, aDC1); - myCurve2.D1(theX, aP2, aDC2); - - const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1); - // - theDeriv = -2.0*aVec1.Dot(aVec2); - } - catch(Standard_Failure) - { - return Standard_False; - } - - return Standard_True; - } - - //returns value and gradient - virtual Standard_Boolean Values(const math_Vector& theX, - Standard_Real& theVal, - math_Vector& theGrad) - { - if (!Value(theX, theVal)) - { - return Standard_False; - } - // - if (!Gradient(theX, theGrad)) { - return Standard_False; - } - // - return Standard_True; - } - - //returns value, gradient and hessian - virtual Standard_Boolean Values(const math_Vector& theX, - Standard_Real& theVal, - math_Vector& theGrad, - math_Matrix& theHessian) - { - if (!Value(theX, theVal)) - { - return Standard_False; - } - // - if (!Gradient(theX, theGrad)) - { - return Standard_False; - } - // - theHessian(1,1) = theGrad(1); - // - return Standard_True; - } - // - Standard_Real FirstParameter() const - { - return myFirst; - } - - // - Standard_Real LastParameter() const - { - return myLast; - } - - private: - BRepLib_CheckCurveOnSurface_TargetFunc operator=(BRepLib_CheckCurveOnSurface_TargetFunc&); - - //checks if the function can be computed when its parameter is - //equal to theParam - Standard_Boolean CheckParameter(const Standard_Real theParam) const - { - return ((myFirst <= theParam) && (theParam <= myLast)); - } - - const Adaptor3d_Curve& myCurve1; - const Adaptor3d_Curve& myCurve2; - const Standard_Real myFirst; - const Standard_Real myLast; -}; - -//======================================================================= -//class : BRepLib_CheckCurveOnSurface_Local -//purpose : Created for parallelization possibility only -//======================================================================= -class BRepLib_CheckCurveOnSurface_Local -{ -public: - BRepLib_CheckCurveOnSurface_Local( - const Handle(Geom_Curve)& theCurve3D, - const Handle(Geom2d_Curve)& theCurve2D, - const Handle(Geom_Surface)& theSurface, - const TColStd_Array1OfReal& theIntervalsArr, - const Standard_Real theEpsilonRange, - const Standard_Integer theNbParticles): - myCurve3D(theCurve3D), - myCurve2D(theCurve2D), - mySurface(theSurface), - mySubIntervals(theIntervalsArr), - myEpsilonRange(theEpsilonRange), - myNbParticles(theNbParticles), - myArrOfDist(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1), - myArrOfParam(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1) - { - } - - void operator()(const Standard_Integer& theIndex) const - { - //For every sub-interval (which is set by mySubIntervals array) this method - //computes optimal value of BRepLib_CheckCurveOnSurface_TargetFunc function. - //This optimal value will be put in corresponding (depending on theIndex - the - //identificator of the current interval in mySubIntervals array) cell of - //myArrOfDist and myArrOfParam arrays. - const GeomAdaptor_Curve anAC(myCurve3D); - const Handle(Adaptor2d_HCurve2d) anAd2dC = new Geom2dAdaptor_GHCurve(myCurve2D); - const Handle(Adaptor3d_HSurface) anAdS = new GeomAdaptor_HSurface(mySurface); - - const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS); - - BRepLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS, - mySubIntervals.Value(theIndex), - mySubIntervals.Value(theIndex+1)); - - Standard_Real aMinDist = RealLast(), aPar = 0.0; - if(!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar)) - { - myArrOfDist(theIndex) = RealLast(); - myArrOfParam(theIndex) = aFunc.FirstParameter(); - return; - } - - myArrOfDist(theIndex) = aMinDist; - myArrOfParam(theIndex) = aPar; - } - - //Returns optimal value (inverse of square of maximal distance) - void OptimalValues(Standard_Real& theMinimalValue, Standard_Real& theParameter) const - { - //This method looks for the minimal value of myArrOfDist. - - const Standard_Integer aStartInd = myArrOfDist.Lower(); - theMinimalValue = myArrOfDist(aStartInd); - theParameter = myArrOfParam(aStartInd); - for(Standard_Integer i = aStartInd + 1; i <= myArrOfDist.Upper(); i++) - { - if(myArrOfDist(i) < theMinimalValue) - { - theMinimalValue = myArrOfDist(i); - theParameter = myArrOfParam(i); - } - } - } - -private: - BRepLib_CheckCurveOnSurface_Local operator=(BRepLib_CheckCurveOnSurface_Local&); - const Handle(Geom_Curve)& myCurve3D; - const Handle(Geom2d_Curve)& myCurve2D; - const Handle(Geom_Surface)& mySurface; - - const TColStd_Array1OfReal& mySubIntervals; - const Standard_Real myEpsilonRange; - const Standard_Integer myNbParticles; - mutable NCollection_Array1 myArrOfDist; - mutable NCollection_Array1 myArrOfParam; -}; - -//======================================================================= -//function : BRepLib_CheckCurveOnSurface -//purpose : -//======================================================================= -BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface() -: - myFirst(0.), - myLast(0.), - myErrorStatus(0), - myMaxDistance(RealLast()), - myMaxParameter(0.) -{ -} - //======================================================================= //function : BRepLib_CheckCurveOnSurface //purpose : //======================================================================= BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface - (const TopoDS_Edge& theEdge, - const TopoDS_Face& theFace) -: - myErrorStatus(0), - myMaxDistance(RealLast()), - myMaxParameter(0.) + ( const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace) { Init(theEdge, theFace); } -//======================================================================= -//function : BRepLib_CheckCurveOnSurface -//purpose : -//======================================================================= -BRepLib_CheckCurveOnSurface::BRepLib_CheckCurveOnSurface - (const Handle(Geom_Curve)& the3DCurve, - const Handle(Geom2d_Curve)& the2DCurve, - const Handle(Geom_Surface)& theSurface, - const Standard_Real theFirst, - const Standard_Real theLast) -: - myErrorStatus(0), - myMaxDistance(RealLast()), - myMaxParameter(0.) -{ - Init(the3DCurve, the2DCurve, theSurface, theFirst, theLast); -} - //======================================================================= //function : Init //purpose : @@ -367,351 +39,68 @@ void BRepLib_CheckCurveOnSurface::Init (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace) { - myCurve.Nullify(); - myPCurve.Nullify(); - myPCurve2.Nullify(); - mySurface.Nullify(); - myErrorStatus = 0; - myMaxDistance = RealLast(); - myMaxParameter = 0.0; - myFirst = 0.0; - myLast = 0.0; + myCOnSurfGeom.Init(); - if (theEdge.IsNull() || theFace.IsNull()) { + if (theEdge.IsNull() || theFace.IsNull()) + { return; } // if (BRep_Tool::Degenerated(theEdge) || - !BRep_Tool::IsGeometric(theEdge)) { + !BRep_Tool::IsGeometric(theEdge)) + { return; } + // TopLoc_Location aLocE, aLocF, aLocC2D; + Standard_Real aFirst = 0.0, aLast = 0.0; // // 3D curve initialization - const Handle(Geom_Curve)& aC = BRep_Tool::Curve(theEdge, aLocE, myFirst, myLast); - myCurve = Handle(Geom_Curve)::DownCast(aC->Transformed(aLocE.Transformation())); + const Handle(Geom_Curve)& aC3dTmp = BRep_Tool::Curve(theEdge, aLocE, aFirst, aLast); + const Handle(Geom_Curve) aC3d(Handle(Geom_Curve)::DownCast(aC3dTmp->Transformed(aLocE.Transformation()))); // Surface initialization - const Handle(Geom_Surface)& aS = BRep_Tool::Surface(theFace, aLocF); - mySurface = Handle(Geom_Surface)::DownCast(aS->Transformed(aLocF.Transformation())); + const Handle(Geom_Surface)& aSTmp = BRep_Tool::Surface(theFace, aLocF); + const Handle(Geom_Surface) aS(Handle(Geom_Surface)::DownCast(aSTmp->Transformed(aLocF.Transformation()))); // // 2D curves initialization - myPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, myFirst, myLast); + myPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirst, aLast); if(BRep_Tool::IsClosed(theEdge, theFace)) myPCurve2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(theEdge.Reversed()), - theFace, myFirst, myLast); -} + theFace, aFirst, aLast); -//======================================================================= -//function : Init -//purpose : -//======================================================================= -void BRepLib_CheckCurveOnSurface::Init - (const Handle(Geom_Curve)& the3DCurve, - const Handle(Geom2d_Curve)& the2DCurve, - const Handle(Geom_Surface)& theSurface, - const Standard_Real theFirst, - const Standard_Real theLast) -{ - myCurve = the3DCurve; - myPCurve = the2DCurve; - myPCurve2.Nullify(); - mySurface = theSurface; - myFirst = theFirst; - myLast = theLast; - myErrorStatus = 0; - myMaxDistance = RealLast(); - myMaxParameter = 0.0; + myCOnSurfGeom.Init(aC3d, aS, aFirst, aLast); } //======================================================================= //function : Perform //purpose : if isTheMTDisabled == TRUE parallelization is not used //======================================================================= -#ifndef HAVE_TBB -//After fixing bug # 26365, this fragment should be deleted -//(together the text "#ifdef HAVE_TBB") - -void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean) -{ - const Standard_Boolean isTheMTDisabled = Standard_True; -#else void BRepLib_CheckCurveOnSurface::Perform(const Standard_Boolean isTheMTDisabled) { -#endif - try { - OCC_CATCH_SIGNALS - // - // 1. Check data - CheckData(); - if (myErrorStatus) { - return; - } - - // 2. Compute the max distance - Compute(myPCurve, isTheMTDisabled); - // - if (!myPCurve2.IsNull()) { - // compute max distance for myPCurve2 - // (for the second curve on closed surface) - Compute(myPCurve2, isTheMTDisabled); - } - } - catch (Standard_Failure) { - myErrorStatus = 3; - } -} - -//======================================================================= -//function : Compute -//purpose : if isTheMTDisabled == TRUE parallelization is not used -//======================================================================= -void BRepLib_CheckCurveOnSurface::Compute(const Handle(Geom2d_Curve)& thePCurve, - const Standard_Boolean isTheMTDisabled) -{ - const Standard_Real anEpsilonRange = 1.e-3; - - Standard_Integer aNbParticles = 3; - - //Polynomial function with degree n has not more than n-1 maxima and - //minima (degree of 1st derivative is equal to n-1 => 1st derivative has - //no greater than n-1 roots). Consequently, this function has - //maximum n monotonicity intervals. That is a good idea to try to put - //at least one particle in every monotonicity interval. Therefore, - //number of particles should be equal to n. - - const Standard_Integer aNbSubIntervals = - FillSubIntervals( myCurve, thePCurve, - myFirst, myLast, aNbParticles); - - if(!aNbSubIntervals) + // Compute the max distance + Compute(myPCurve, isTheMTDisabled); + if (ErrorStatus()) { - myErrorStatus = 3; return; } - - TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1); - FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals); - - BRepLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve, - mySurface, anIntervals, anEpsilonRange, aNbParticles); - - OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled); - - aComp.OptimalValues(myMaxDistance, myMaxParameter); - - myMaxDistance = sqrt(Abs(myMaxDistance)); -} - -//======================================================================= -// Function : FillSubIntervals -// purpose : Divides [theFirst, theLast] interval on parts -// in order to make searching-algorithm more precisely -// (fills theSubIntervals array). -// Returns number of subintervals. -//======================================================================= -Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d, - const Handle(Geom2d_Curve)& theCurve2d, - const Standard_Real theFirst, - const Standard_Real theLast, - Standard_Integer &theNbParticles, - TColStd_Array1OfReal* const theSubIntervals) -{ - const Standard_Real anArrTempC[2] = {theFirst, theLast}; - const TColStd_Array1OfReal anArrTemp(anArrTempC[0], 1, 2); - - theNbParticles = 3; - Handle(Geom2d_BSplineCurve) aBS2DCurv; - Handle(Geom_BSplineCurve) aBS3DCurv; - // - if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) - { - aBS3DCurv = Handle(Geom_BSplineCurve):: - DownCast(Handle(Geom_TrimmedCurve):: - DownCast(theCurve3d)->BasisCurve()); - } - else - { - aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d); - } - - - if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) + if (!myPCurve2.IsNull()) { - aBS2DCurv = Handle(Geom2d_BSplineCurve):: - DownCast(Handle(Geom2d_TrimmedCurve):: - DownCast(theCurve2d)->BasisCurve()); + // compute max distance for myPCurve2 + // (for the second curve on closed surface) + Compute(myPCurve2, isTheMTDisabled); } - else - { - aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d); - } - - const TColStd_Array1OfReal &anArrKnots3D = !aBS3DCurv.IsNull() ? - aBS3DCurv->Knots() : - anArrTemp; - const TColStd_Array1OfReal &anArrKnots2D = !aBS2DCurv.IsNull() ? - aBS2DCurv->Knots() : - anArrTemp; - - Standard_Integer aNbSubIntervals = 1; - - try - { - OCC_CATCH_SIGNALS - const Standard_Integer anIndMax3D = anArrKnots3D.Upper(), - anIndMax2D = anArrKnots2D.Upper(); - - Standard_Integer anIndex3D = anArrKnots3D.Lower(), - anIndex2D = anArrKnots2D.Lower(); - - if(theSubIntervals) - theSubIntervals->ChangeValue(aNbSubIntervals) = theFirst; - - while((anIndex3D <= anIndMax3D) && (anIndex2D <= anIndMax2D)) - { - const Standard_Real aVal3D = anArrKnots3D.Value(anIndex3D), - aVal2D = anArrKnots2D.Value(anIndex2D); - const Standard_Real aDelta = aVal3D - aVal2D; - - if(aDelta < Precision::PConfusion()) - {//aVal3D <= aVal2D - if((aVal3D > theFirst) && (aVal3D < theLast)) - { - aNbSubIntervals++; - - if(theSubIntervals) - theSubIntervals->ChangeValue(aNbSubIntervals) = aVal3D; - } - - anIndex3D++; - - if(-aDelta < Precision::PConfusion()) - {//aVal3D == aVal2D - anIndex2D++; - } - } - else - {//aVal2D < aVal3D - if((aVal2D > theFirst) && (aVal2D < theLast)) - { - aNbSubIntervals++; - - if(theSubIntervals) - theSubIntervals->ChangeValue(aNbSubIntervals) = aVal2D; - } - - anIndex2D++; - } - } - - if(theSubIntervals) - theSubIntervals->ChangeValue(aNbSubIntervals+1) = theLast; - - if(!aBS3DCurv.IsNull()) - { - theNbParticles = Max(theNbParticles, aBS3DCurv->Degree()); - } - - if(!aBS2DCurv.IsNull()) - { - theNbParticles = Max(theNbParticles, aBS2DCurv->Degree()); - } - } - catch(Standard_Failure) - { -#ifdef OCCT_DEBUG - cout << "ERROR! BRepLib_CheckCurveOnSurface.cxx, " - "FillSubIntervals(): Incorrect filling!" << endl; -#endif - - aNbSubIntervals = 0; - } - - return aNbSubIntervals; } //======================================================================= -//class : MinComputing -//purpose : Performs computing minimal value +//function : Compute +//purpose : if isTheMTDisabled == TRUE parallelization is not used //======================================================================= -Standard_Boolean MinComputing ( - BRepLib_CheckCurveOnSurface_TargetFunc& theFunction, - const Standard_Real theEpsilon, //1.0e-3 - const Standard_Integer theNbParticles, - Standard_Real& theBestValue, - Standard_Real& theBestParameter) +void BRepLib_CheckCurveOnSurface::Compute(const Handle(Geom2d_Curve)& thePCurve, + const Standard_Boolean isTheMTDisabled) { - try - { - OCC_CATCH_SIGNALS - - //They are used for finding a position of theNbParticles worst places - const Standard_Integer aNbControlPoints = 3*theNbParticles; - // - math_Vector aParInf(1, 1), aParSup(1, 1), anOutputParam(1, 1), aStepPar(1,1); - aParInf(1) = theFunction.FirstParameter(); - aParSup(1) = theFunction.LastParameter(); - theBestParameter = aParInf(1); - theBestValue = RealLast(); - - const Standard_Real aDeltaParam = aParSup(1) - aParInf(1); - if(aDeltaParam < Precision::PConfusion()) - return Standard_False; - - aStepPar(1) = theEpsilon*aDeltaParam; - - math_PSOParticlesPool aParticles(theNbParticles, 1); - - const Standard_Real aStep = aDeltaParam/(aNbControlPoints-1); - Standard_Integer aCount = 1; - for(Standard_Real aPrm = aParInf(1); aCount <= aNbControlPoints; aCount++, - aPrm = (aCount == aNbControlPoints)? aParSup(1) : aPrm+aStep) - { - Standard_Real aVal = RealLast(); - theFunction.Value(aPrm, aVal); - - PSO_Particle* aParticle = aParticles.GetWorstParticle(); - - if(aVal > aParticle->BestDistance) - continue; - - aParticle->Position[0] = aPrm; - aParticle->BestPosition[0] = aPrm; - aParticle->Distance = aVal; - aParticle->BestDistance = aVal; - } - - math_PSO aPSO(&theFunction, aParInf, aParSup, aStepPar); - aPSO.Perform(aParticles, theNbParticles, theBestValue, anOutputParam); - - //Here, anOutputParam contains parameter, which is near to optimal. - //It needs to be more precise. Precision is made by math_NewtonMinimum. - math_NewtonMinimum anA(theFunction); - anA.Perform(theFunction, anOutputParam); - - if(!anA.IsDone()) - { -#ifdef OCCT_DEBUG - cout << "BRepLib_CheckCurveOnSurface::Compute(): No solution found!" << endl; -#endif - return Standard_False; - } - - anA.Location(anOutputParam); - theBestParameter = anOutputParam(1); - theBestValue = anA.Minimum(); - } - catch(Standard_Failure) - { -#ifdef OCCT_DEBUG - cout << "BRepLib_CheckCurveOnSurface.cxx: Exception in MinComputing()!" << endl; -#endif - return Standard_False; - } - - return Standard_True; + myCOnSurfGeom.Perform(thePCurve, isTheMTDisabled); } diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx index 3f5b1f9c48..3d710092df 100644 --- a/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx +++ b/src/BRepLib/BRepLib_CheckCurveOnSurface.hxx @@ -15,144 +15,106 @@ #ifndef _BRepLib_CheckCurveOnSurface_HeaderFile #define _BRepLib_CheckCurveOnSurface_HeaderFile -#include -#include -#include - -#include -#include -#include -class Geom_Curve; -class Geom2d_Curve; -class Geom_Surface; -class TopoDS_Edge; -class TopoDS_Face; - - +#include //! Computes the max distance between edge and its //! 2d representation on the face. -//! -//! The algorithm can be initialized in the following ways: -//! 1. Input args are Edge and Face; -//! 2. Input args are 3D curve, 2d curve, Surface and -//! parametric range of the curve (first and last values). + class BRepLib_CheckCurveOnSurface { public: DEFINE_STANDARD_ALLOC + //! Default contructor + BRepLib_CheckCurveOnSurface() {} - - //! Empty contructor - Standard_EXPORT BRepLib_CheckCurveOnSurface(); - - //! Contructor - Standard_EXPORT BRepLib_CheckCurveOnSurface(const TopoDS_Edge& theEdge, const TopoDS_Face& theFace); + Standard_EXPORT BRepLib_CheckCurveOnSurface(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace); - - //! Contructor - Standard_EXPORT BRepLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve, const Handle(Geom2d_Curve)& thePCurve, const Handle(Geom_Surface)& theSurface, const Standard_Real theFirst, const Standard_Real theLast); - - //! Sets the data for the algorithm Standard_EXPORT void Init (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace); - - - //! Sets the data for the algorithm - Standard_EXPORT void Init (const Handle(Geom_Curve)& theCurve, const Handle(Geom2d_Curve)& thePCurve, const Handle(Geom_Surface)& theSurface, const Standard_Real theFirst, const Standard_Real theLast); - - - //! Returns my3DCurve - const Handle(Geom_Curve)& Curve() const; - - - //! Returns my2DCurve - const Handle(Geom2d_Curve)& PCurve() const; - - - //! Returns my2DCurve - const Handle(Geom2d_Curve)& PCurve2() const; - - - //! Returns mySurface - const Handle(Geom_Surface)& Surface() const; - - - //! Returns the range - void Range (Standard_Real& theFirst, Standard_Real& theLast); - //! Performs the calculation //! If isTheMultyTheadDisabled == TRUE then computation will be made //! without any parallelization. Standard_EXPORT void Perform (const Standard_Boolean isTheMultyTheradDisabled = Standard_False); - + //! Returns source 3D-Curve + const Handle(Geom_Curve)& Curve() const + { + return myCOnSurfGeom.Curve(); + } + + //! Returns mine 2D-Curve + const Handle(Geom2d_Curve)& PCurve() const + { + return myPCurve; + } + + //! Returns 2nd 2D-Curve (if it exists, e.g. for seam-edge) + const Handle(Geom2d_Curve)& PCurve2() const + { + return myPCurve2; + } + + //! Returns source surface + const Handle(Geom_Surface)& Surface() const + { + return myCOnSurfGeom.Surface(); + } + + //! Returns first and last parameter of the curves + //! (2D- and 3D-curves are considered to have same range) + void Range (Standard_Real& theFirst, Standard_Real& theLast) + { + myCOnSurfGeom.Range(theFirst, theLast); + } + //! Returns true if the max distance has been found - Standard_Boolean IsDone() const; + Standard_Boolean IsDone() const + { + return myCOnSurfGeom.ErrorStatus() == 0; + } - //! Returns error status //! The possible values are: //! 0 - OK; //! 1 - null curve or surface or 2d curve; //! 2 - invalid parametric range; //! 3 - error in calculations. - Standard_Integer ErrorStatus() const; + Standard_Integer ErrorStatus() const + { + return myCOnSurfGeom.ErrorStatus(); + } - //! Returns max distance - Standard_Real MaxDistance() const; + Standard_Real MaxDistance() const + { + return myCOnSurfGeom.MaxDistance(); + } - //! Returns parameter in which the distance is maximal - Standard_Real MaxParameter() const; - - - + Standard_Real MaxParameter() const + { + return myCOnSurfGeom.MaxParameter(); + } protected: - - - //! Checks the data - Standard_EXPORT void CheckData(); - - - //! Computes the max distance for the 3d curve + //! Computes the max distance for the 3d curve of //! and 2d curve //! If isTheMultyTheadDisabled == TRUE then computation will be made //! without any parallelization. - Standard_EXPORT void Compute (const Handle(Geom2d_Curve)& thePCurve, const Standard_Boolean isTheMultyTheradDisabled); - - - + Standard_EXPORT void Compute (const Handle(Geom2d_Curve)& thePCurve, + const Standard_Boolean isTheMultyTheradDisabled); private: - - - Handle(Geom_Curve) myCurve; + GeomLib_CheckCurveOnSurface myCOnSurfGeom; Handle(Geom2d_Curve) myPCurve; Handle(Geom2d_Curve) myPCurve2; - Handle(Geom_Surface) mySurface; - Standard_Real myFirst; - Standard_Real myLast; - Standard_Integer myErrorStatus; - Standard_Real myMaxDistance; - Standard_Real myMaxParameter; - - }; - -#include - - - - - #endif // _BRepLib_CheckCurveOnSurface_HeaderFile diff --git a/src/BRepLib/BRepLib_CheckCurveOnSurface.lxx b/src/BRepLib/BRepLib_CheckCurveOnSurface.lxx deleted file mode 100644 index cc9a13efae..0000000000 --- a/src/BRepLib/BRepLib_CheckCurveOnSurface.lxx +++ /dev/null @@ -1,112 +0,0 @@ -// Created by: Eugeny MALTCHIKOV -// Copyright (c) 2014 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 - -//======================================================================= -//function : Curve -//purpose : -//======================================================================= -inline const Handle(Geom_Curve)& BRepLib_CheckCurveOnSurface::Curve() const -{ - return myCurve; -} - -//======================================================================= -//function : PCurve -//purpose : -//======================================================================= -inline const Handle(Geom2d_Curve)& BRepLib_CheckCurveOnSurface::PCurve() const -{ - return myPCurve; -} - -//======================================================================= -//function : PCurve2 -//purpose : -//======================================================================= -inline const Handle(Geom2d_Curve)& BRepLib_CheckCurveOnSurface::PCurve2() const -{ - return myPCurve2; -} - -//======================================================================= -//function : Surface -//purpose : -//======================================================================= -inline const Handle(Geom_Surface)& BRepLib_CheckCurveOnSurface::Surface() const -{ - return mySurface; -} - -//======================================================================= -//function : Range -//purpose : -//======================================================================= -inline void BRepLib_CheckCurveOnSurface::Range - (Standard_Real& theFirst, - Standard_Real& theLast) -{ - theFirst = myFirst; - theLast = myLast; -} - -//======================================================================= -//function : CheckData -//purpose : -//======================================================================= -inline void BRepLib_CheckCurveOnSurface::CheckData() -{ - if (myCurve.IsNull() || - myPCurve.IsNull() || - mySurface.IsNull()) { - myErrorStatus = 1; - return; - } - // - if ((myCurve->FirstParameter() > myFirst) || - (myCurve->LastParameter() < myLast) || - (myPCurve->FirstParameter() > myFirst) || - (myPCurve->LastParameter() < myLast)) { - myErrorStatus = 2; - } -} - -//======================================================================= -//function : IsDone -//purpose : -//======================================================================= -inline Standard_Boolean BRepLib_CheckCurveOnSurface::IsDone() const -{ - return (myErrorStatus == 0); -} - -//======================================================================= -//function : MaxDistance -//purpose : -//======================================================================= -inline Standard_Real BRepLib_CheckCurveOnSurface::MaxDistance() const -{ - return myMaxDistance; -} - -//======================================================================= -//function : MaxParameter -//purpose : -//======================================================================= -inline Standard_Real BRepLib_CheckCurveOnSurface::MaxParameter() const -{ - return myMaxParameter; -} diff --git a/src/BRepLib/FILES b/src/BRepLib/FILES index 05545a9289..a123c7d20c 100755 --- a/src/BRepLib/FILES +++ b/src/BRepLib/FILES @@ -2,7 +2,6 @@ BRepLib.cxx BRepLib.hxx BRepLib_CheckCurveOnSurface.cxx BRepLib_CheckCurveOnSurface.hxx -BRepLib_CheckCurveOnSurface.lxx BRepLib_Command.cxx BRepLib_Command.hxx BRepLib_EdgeError.hxx diff --git a/src/GeomLib/FILES b/src/GeomLib/FILES index 918db03b30..2f8b58e27c 100755 --- a/src/GeomLib/FILES +++ b/src/GeomLib/FILES @@ -4,6 +4,8 @@ GeomLib_Array1OfMat.hxx GeomLib_Check2dBSplineCurve.cxx GeomLib_Check2dBSplineCurve.hxx GeomLib_Check2dBSplineCurve.lxx +GeomLib_CheckCurveOnSurface.cxx +GeomLib_CheckCurveOnSurface.hxx GeomLib_CheckBSplineCurve.cxx GeomLib_CheckBSplineCurve.hxx GeomLib_CheckBSplineCurve.lxx diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx new file mode 100644 index 0000000000..1fde4f57fa --- /dev/null +++ b/src/GeomLib/GeomLib_CheckCurveOnSurface.cxx @@ -0,0 +1,653 @@ +// Created by: Nikolai BUKHALOV +// Copyright (c) 2015 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class GeomLib_CheckCurveOnSurface_TargetFunc; + +static +Standard_Boolean MinComputing( + GeomLib_CheckCurveOnSurface_TargetFunc& theFunction, + const Standard_Real theEpsilon, //1.0e-3 + const Standard_Integer theNbParticles, + Standard_Real& theBestValue, + Standard_Real& theBestParameter); + +static Standard_Integer FillSubIntervals( const Handle(Geom_Curve)& theCurve3d, + const Handle(Geom2d_Curve)& theCurve2d, + const Standard_Real theFirst, + const Standard_Real theLast, + Standard_Integer &theNbParticles, + TColStd_Array1OfReal* const theSubIntervals = 0); + +//======================================================================= +//class : GeomLib_CheckCurveOnSurface_TargetFunc +//purpose : Target function (to be minimized) +//======================================================================= +class GeomLib_CheckCurveOnSurface_TargetFunc : + public math_MultipleVarFunctionWithHessian +{ + public: + GeomLib_CheckCurveOnSurface_TargetFunc( const Adaptor3d_Curve& theC3D, + const Adaptor3d_Curve& theAdCS, + const Standard_Real theFirst, + const Standard_Real theLast): + myCurve1(theC3D), + myCurve2(theAdCS), + myFirst(theFirst), + myLast(theLast) + { + } + + //returns the number of parameters of the function + //(the function is one-dimension). + virtual Standard_Integer NbVariables() const { + return 1; + } + + //returns value of the function when parameters are equal to theX + virtual Standard_Boolean Value(const math_Vector& theX, + Standard_Real& theFVal) + { + return Value(theX(1), theFVal); + } + + //returns value of the one-dimension-function when parameter + //is equal to theX + Standard_Boolean Value( const Standard_Real theX, + Standard_Real& theFVal) const + { + try + { + OCC_CATCH_SIGNALS + if (!CheckParameter(theX)) + return Standard_False; + + const gp_Pnt aP1(myCurve1.Value(theX)), + aP2(myCurve2.Value(theX)); + + theFVal = -1.0*aP1.SquareDistance(aP2); + } + catch(Standard_Failure) { + return Standard_False; + } + // + return Standard_True; + } + + //see analogical method for abstract owner class math_MultipleVarFunction + virtual Standard_Integer GetStateNumber() + { + return 0; + } + + //returns the gradient of the function when parameters are + //equal to theX + virtual Standard_Boolean Gradient(const math_Vector& theX, + math_Vector& theGrad) + { + return Derive(theX(1), theGrad(1)); + } + + //returns 1st derivative of the the one-dimension-function when + //parameter is equal to theX + Standard_Boolean Derive(const Standard_Real theX, Standard_Real& theDeriv) const + { + try + { + OCC_CATCH_SIGNALS + if (!CheckParameter(theX)) + { + return Standard_False; + } + // + gp_Pnt aP1, aP2; + gp_Vec aDC1, aDC2; + // + myCurve1.D1(theX, aP1, aDC1); + myCurve2.D1(theX, aP2, aDC2); + + const gp_Vec aVec1(aP1, aP2), aVec2(aDC2-aDC1); + // + theDeriv = -2.0*aVec1.Dot(aVec2); + } + catch(Standard_Failure) + { + return Standard_False; + } + + return Standard_True; + } + + //returns value and gradient + virtual Standard_Boolean Values(const math_Vector& theX, + Standard_Real& theVal, + math_Vector& theGrad) + { + if (!Value(theX, theVal)) + { + return Standard_False; + } + // + if (!Gradient(theX, theGrad)) { + return Standard_False; + } + // + return Standard_True; + } + + //returns value, gradient and hessian + virtual Standard_Boolean Values(const math_Vector& theX, + Standard_Real& theVal, + math_Vector& theGrad, + math_Matrix& theHessian) + { + if (!Value(theX, theVal)) + { + return Standard_False; + } + // + if (!Gradient(theX, theGrad)) + { + return Standard_False; + } + // + theHessian(1,1) = theGrad(1); + // + return Standard_True; + } + // + Standard_Real FirstParameter() const + { + return myFirst; + } + + // + Standard_Real LastParameter() const + { + return myLast; + } + + private: + GeomLib_CheckCurveOnSurface_TargetFunc operator=(GeomLib_CheckCurveOnSurface_TargetFunc&); + + //checks if the function can be computed when its parameter is + //equal to theParam + Standard_Boolean CheckParameter(const Standard_Real theParam) const + { + return ((myFirst <= theParam) && (theParam <= myLast)); + } + + const Adaptor3d_Curve& myCurve1; + const Adaptor3d_Curve& myCurve2; + const Standard_Real myFirst; + const Standard_Real myLast; +}; + +//======================================================================= +//class : GeomLib_CheckCurveOnSurface_Local +//purpose : Created for parallelization possibility only +//======================================================================= +class GeomLib_CheckCurveOnSurface_Local +{ +public: + GeomLib_CheckCurveOnSurface_Local( + const Handle(Geom_Curve)& theCurve3D, + const Handle(Geom2d_Curve)& theCurve2D, + const Handle(Geom_Surface)& theSurface, + const TColStd_Array1OfReal& theIntervalsArr, + const Standard_Real theEpsilonRange, + const Standard_Integer theNbParticles): + myCurve3D(theCurve3D), + myCurve2D(theCurve2D), + mySurface(theSurface), + mySubIntervals(theIntervalsArr), + myEpsilonRange(theEpsilonRange), + myNbParticles(theNbParticles), + myArrOfDist(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1), + myArrOfParam(theIntervalsArr.Lower(), theIntervalsArr.Upper()-1) + { + } + + void operator()(const Standard_Integer& theIndex) const + { + //For every sub-interval (which is set by mySubIntervals array) this method + //computes optimal value of GeomLib_CheckCurveOnSurface_TargetFunc function. + //This optimal value will be put in corresponding (depending on theIndex - the + //identificator of the current interval in mySubIntervals array) cell of + //myArrOfDist and myArrOfParam arrays. + const GeomAdaptor_Curve anAC(myCurve3D); + const Handle(Adaptor2d_HCurve2d) anAd2dC = new Geom2dAdaptor_GHCurve(myCurve2D); + const Handle(Adaptor3d_HSurface) anAdS = new GeomAdaptor_HSurface(mySurface); + + const Adaptor3d_CurveOnSurface anACS(anAd2dC, anAdS); + + GeomLib_CheckCurveOnSurface_TargetFunc aFunc( anAC, anACS, + mySubIntervals.Value(theIndex), + mySubIntervals.Value(theIndex+1)); + + Standard_Real aMinDist = RealLast(), aPar = 0.0; + if(!MinComputing(aFunc, myEpsilonRange, myNbParticles, aMinDist, aPar)) + { + myArrOfDist(theIndex) = RealLast(); + myArrOfParam(theIndex) = aFunc.FirstParameter(); + return; + } + + myArrOfDist(theIndex) = aMinDist; + myArrOfParam(theIndex) = aPar; + } + + //Returns optimal value (inverse of square of maximal distance) + void OptimalValues(Standard_Real& theMinimalValue, Standard_Real& theParameter) const + { + //This method looks for the minimal value of myArrOfDist. + + const Standard_Integer aStartInd = myArrOfDist.Lower(); + theMinimalValue = myArrOfDist(aStartInd); + theParameter = myArrOfParam(aStartInd); + for(Standard_Integer i = aStartInd + 1; i <= myArrOfDist.Upper(); i++) + { + if(myArrOfDist(i) < theMinimalValue) + { + theMinimalValue = myArrOfDist(i); + theParameter = myArrOfParam(i); + } + } + } + +private: + GeomLib_CheckCurveOnSurface_Local operator=(GeomLib_CheckCurveOnSurface_Local&); + const Handle(Geom_Curve)& myCurve3D; + const Handle(Geom2d_Curve)& myCurve2D; + const Handle(Geom_Surface)& mySurface; + + const TColStd_Array1OfReal& mySubIntervals; + const Standard_Real myEpsilonRange; + const Standard_Integer myNbParticles; + mutable NCollection_Array1 myArrOfDist; + mutable NCollection_Array1 myArrOfParam; +}; + +//======================================================================= +//function : GeomLib_CheckCurveOnSurface +//purpose : +//======================================================================= +GeomLib_CheckCurveOnSurface::GeomLib_CheckCurveOnSurface() +: + myFirst(0.), + myLast(0.), + myErrorStatus(0), + myMaxDistance(RealLast()), + myMaxParameter(0.) +{ +} + +//======================================================================= +//function : GeomLib_CheckCurveOnSurface +//purpose : +//======================================================================= +GeomLib_CheckCurveOnSurface:: + GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve, + const Handle(Geom_Surface)& theSurface, + const Standard_Real theFirst, + const Standard_Real theLast): + myCurve(theCurve), + mySurface(theSurface), + myFirst(theFirst), + myLast(theLast), + myErrorStatus(0), + myMaxDistance(RealLast()), + myMaxParameter(0.) +{ +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= +void GeomLib_CheckCurveOnSurface::Init() +{ + myCurve.Nullify(); + mySurface.Nullify(); + myFirst = 0.0; + myLast = 0.0; + myErrorStatus = 0; + myMaxDistance = RealLast(); + myMaxParameter = 0.0; +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= +void GeomLib_CheckCurveOnSurface::Init( const Handle(Geom_Curve)& theCurve, + const Handle(Geom_Surface)& theSurface, + const Standard_Real theFirst, + const Standard_Real theLast) +{ + myCurve = theCurve; + mySurface = theSurface; + myFirst = theFirst; + myLast = theLast; + myErrorStatus = 0; + myMaxDistance = RealLast(); + myMaxParameter = 0.0; +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= + +#ifndef HAVE_TBB +//After fixing bug # 26365, this fragment should be deleted +//(together the text "#ifdef HAVE_TBB") + +void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve, + const Standard_Boolean) +{ + const Standard_Boolean isTheMTDisabled = Standard_True; +#else +void GeomLib_CheckCurveOnSurface::Perform(const Handle(Geom2d_Curve)& thePCurve, + const Standard_Boolean isTheMTDisabled) +{ +#endif + if( myCurve.IsNull() || + mySurface.IsNull() || + thePCurve.IsNull()) + { + myErrorStatus = 1; + return; + } + + if( (myCurve->FirstParameter() > myFirst) || + (myCurve->LastParameter() < myLast) || + (thePCurve->FirstParameter() > myFirst) || + (thePCurve->LastParameter() < myLast)) + { + myErrorStatus = 2; + return; + } + + const Standard_Real anEpsilonRange = 1.e-3; + + Standard_Integer aNbParticles = 3; + + //Polynomial function with degree n has not more than n-1 maxima and + //minima (degree of 1st derivative is equal to n-1 => 1st derivative has + //no greater than n-1 roots). Consequently, this function has + //maximum n monotonicity intervals. That is a good idea to try to put + //at least one particle in every monotonicity interval. Therefore, + //number of particles should be equal to n. + + const Standard_Integer aNbSubIntervals = + FillSubIntervals( myCurve, thePCurve, + myFirst, myLast, aNbParticles); + + if(!aNbSubIntervals) + { + myErrorStatus = 3; + return; + } + + try { + OCC_CATCH_SIGNALS + + TColStd_Array1OfReal anIntervals(1, aNbSubIntervals+1); + FillSubIntervals(myCurve, thePCurve, myFirst, myLast, aNbParticles, &anIntervals); + + GeomLib_CheckCurveOnSurface_Local aComp(myCurve, thePCurve, + mySurface, anIntervals, anEpsilonRange, aNbParticles); + + OSD_Parallel::For(anIntervals.Lower(), anIntervals.Upper(), aComp, isTheMTDisabled); + + aComp.OptimalValues(myMaxDistance, myMaxParameter); + + myMaxDistance = sqrt(Abs(myMaxDistance)); + } + catch (Standard_Failure) { + myErrorStatus = 3; + } +} + +//======================================================================= +// Function : FillSubIntervals +// purpose : Divides [theFirst, theLast] interval on parts +// in order to make searching-algorithm more precisely +// (fills theSubIntervals array). +// Returns number of subintervals. +//======================================================================= +Standard_Integer FillSubIntervals(const Handle(Geom_Curve)& theCurve3d, + const Handle(Geom2d_Curve)& theCurve2d, + const Standard_Real theFirst, + const Standard_Real theLast, + Standard_Integer &theNbParticles, + TColStd_Array1OfReal* const theSubIntervals) +{ + const Standard_Real anArrTempC[2] = {theFirst, theLast}; + const TColStd_Array1OfReal anArrTemp(anArrTempC[0], 1, 2); + + theNbParticles = 3; + Handle(Geom2d_BSplineCurve) aBS2DCurv; + Handle(Geom_BSplineCurve) aBS3DCurv; + + // + if (theCurve3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + { + aBS3DCurv = Handle(Geom_BSplineCurve):: + DownCast(Handle(Geom_TrimmedCurve):: + DownCast(theCurve3d)->BasisCurve()); + } + else + { + aBS3DCurv = Handle(Geom_BSplineCurve)::DownCast(theCurve3d); + } + + if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) + { + aBS2DCurv = Handle(Geom2d_BSplineCurve):: + DownCast(Handle(Geom2d_TrimmedCurve):: + DownCast(theCurve2d)->BasisCurve()); + } + else + { + aBS2DCurv = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d); + } + + const TColStd_Array1OfReal &anArrKnots3D = !aBS3DCurv.IsNull() ? + aBS3DCurv->Knots() : + anArrTemp; + const TColStd_Array1OfReal &anArrKnots2D = !aBS2DCurv.IsNull() ? + aBS2DCurv->Knots() : + anArrTemp; + + Standard_Integer aNbSubIntervals = 1; + + try + { + OCC_CATCH_SIGNALS + const Standard_Integer anIndMax3D = anArrKnots3D.Upper(), + anIndMax2D = anArrKnots2D.Upper(); + + Standard_Integer anIndex3D = anArrKnots3D.Lower(), + anIndex2D = anArrKnots2D.Lower(); + + if(theSubIntervals) + theSubIntervals->ChangeValue(aNbSubIntervals) = theFirst; + + while((anIndex3D <= anIndMax3D) && (anIndex2D <= anIndMax2D)) + { + const Standard_Real aVal3D = anArrKnots3D.Value(anIndex3D), + aVal2D = anArrKnots2D.Value(anIndex2D); + const Standard_Real aDelta = aVal3D - aVal2D; + + if(aDelta < Precision::PConfusion()) + {//aVal3D <= aVal2D + if((aVal3D > theFirst) && (aVal3D < theLast)) + { + aNbSubIntervals++; + + if(theSubIntervals) + theSubIntervals->ChangeValue(aNbSubIntervals) = aVal3D; + } + + anIndex3D++; + + if(-aDelta < Precision::PConfusion()) + {//aVal3D == aVal2D + anIndex2D++; + } + } + else + {//aVal2D < aVal3D + if((aVal2D > theFirst) && (aVal2D < theLast)) + { + aNbSubIntervals++; + + if(theSubIntervals) + theSubIntervals->ChangeValue(aNbSubIntervals) = aVal2D; + } + + anIndex2D++; + } + } + + if(theSubIntervals) + theSubIntervals->ChangeValue(aNbSubIntervals+1) = theLast; + + if(!aBS3DCurv.IsNull()) + { + theNbParticles = Max(theNbParticles, aBS3DCurv->Degree()); + } + + if(!aBS2DCurv.IsNull()) + { + theNbParticles = Max(theNbParticles, aBS2DCurv->Degree()); + } + } + catch(Standard_Failure) + { +#ifdef OCCT_DEBUG + cout << "ERROR! BRepLib_CheckCurveOnSurface.cxx, " + "FillSubIntervals(): Incorrect filling!" << endl; +#endif + + aNbSubIntervals = 0; + } + + return aNbSubIntervals; +} + +//======================================================================= +//class : MinComputing +//purpose : Performs computing minimal value +//======================================================================= +Standard_Boolean MinComputing ( + GeomLib_CheckCurveOnSurface_TargetFunc& theFunction, + const Standard_Real theEpsilon, //1.0e-3 + const Standard_Integer theNbParticles, + Standard_Real& theBestValue, + Standard_Real& theBestParameter) +{ + try + { + OCC_CATCH_SIGNALS + + //They are used for finding a position of theNbParticles worst places + const Standard_Integer aNbControlPoints = 3*theNbParticles; + // + math_Vector aParInf(1, 1), aParSup(1, 1), anOutputParam(1, 1), aStepPar(1,1); + aParInf(1) = theFunction.FirstParameter(); + aParSup(1) = theFunction.LastParameter(); + theBestParameter = aParInf(1); + theBestValue = RealLast(); + + const Standard_Real aDeltaParam = aParSup(1) - aParInf(1); + if(aDeltaParam < Precision::PConfusion()) + return Standard_False; + + aStepPar(1) = theEpsilon*aDeltaParam; + + math_PSOParticlesPool aParticles(theNbParticles, 1); + + const Standard_Real aStep = aDeltaParam/(aNbControlPoints-1); + Standard_Integer aCount = 1; + for(Standard_Real aPrm = aParInf(1); aCount <= aNbControlPoints; aCount++, + aPrm = (aCount == aNbControlPoints)? aParSup(1) : aPrm+aStep) + { + Standard_Real aVal = RealLast(); + theFunction.Value(aPrm, aVal); + + PSO_Particle* aParticle = aParticles.GetWorstParticle(); + + if(aVal > aParticle->BestDistance) + continue; + + aParticle->Position[0] = aPrm; + aParticle->BestPosition[0] = aPrm; + aParticle->Distance = aVal; + aParticle->BestDistance = aVal; + } + + math_PSO aPSO(&theFunction, aParInf, aParSup, aStepPar); + aPSO.Perform(aParticles, theNbParticles, theBestValue, anOutputParam); + + //Here, anOutputParam contains parameter, which is near to optimal. + //It needs to be more precise. Precision is made by math_NewtonMinimum. + math_NewtonMinimum anA(theFunction); + anA.Perform(theFunction, anOutputParam); + + if(!anA.IsDone()) + { +#ifdef OCCT_DEBUG + cout << "BRepLib_CheckCurveOnSurface::Compute(): No solution found!" << endl; +#endif + return Standard_False; + } + + anA.Location(anOutputParam); + theBestParameter = anOutputParam(1); + theBestValue = anA.Minimum(); + } + catch(Standard_Failure) + { +#ifdef OCCT_DEBUG + cout << "BRepLib_CheckCurveOnSurface.cxx: Exception in MinComputing()!" << endl; +#endif + return Standard_False; + } + + return Standard_True; +} diff --git a/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx b/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx new file mode 100644 index 0000000000..f0ff6ad24b --- /dev/null +++ b/src/GeomLib/GeomLib_CheckCurveOnSurface.hxx @@ -0,0 +1,117 @@ +// Created by: Nikolai BUKHALOV +// Copyright (c) 2015 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 _GeomLib_CheckCurveOnSurface_HeaderFile +#define _GeomLib_CheckCurveOnSurface_HeaderFile + +#include +#include + +class Geom_Surface; +class Geom2d_Curve; + +//! Computes the max distance between 3D-curve and 2D-curve +//! in some surface. +class GeomLib_CheckCurveOnSurface +{ +public: + + DEFINE_STANDARD_ALLOC + + //! Default contructor + Standard_EXPORT GeomLib_CheckCurveOnSurface(void); + + //! Contructor + Standard_EXPORT GeomLib_CheckCurveOnSurface(const Handle(Geom_Curve)& theCurve, + const Handle(Geom_Surface)& theSurface, + const Standard_Real theFirst, + const Standard_Real theLast); + + //! Sets the data for the algorithm + Standard_EXPORT void Init (const Handle(Geom_Curve)& theCurve, + const Handle(Geom_Surface)& theSurface, + const Standard_Real theFirst, + const Standard_Real theLast); + + //! Initializes all members by dafault values + Standard_EXPORT void Init(); + + //! Computes the max distance for the 3d curve + //! and 2d curve + //! If isTheMultyTheadDisabled == TRUE then computation will be made + //! without any parallelization. + Standard_EXPORT void Perform(const Handle(Geom2d_Curve)& thePCurve, + const Standard_Boolean isTheMultyTheradDisabled = Standard_False); + + //! Returns my3DCurve + const Handle(Geom_Curve)& Curve() const + { + return myCurve; + } + + //! Returns mySurface + const Handle(Geom_Surface)& Surface() const + { + return mySurface; + } + + //! Returns first and last parameter of the curves + //! (2D- and 3D-curves are considered to have same range) + void Range (Standard_Real& theFirst, Standard_Real& theLast) + { + theFirst = myFirst; + theLast = myLast; + } + + //! Returns true if the max distance has been found + Standard_Boolean IsDone() const + { + return (myErrorStatus == 0); + } + + //! Returns error status + //! The possible values are: + //! 0 - OK; + //! 1 - null curve or surface or 2d curve; + //! 2 - invalid parametric range; + //! 3 - error in calculations. + Standard_Integer ErrorStatus() const + { + return myErrorStatus; + } + + //! Returns max distance + Standard_Real MaxDistance() const + { + return myMaxDistance; + } + + //! Returns parameter in which the distance is maximal + Standard_Real MaxParameter() const + { + return myMaxParameter; + } + +private: + + Handle(Geom_Curve) myCurve; + Handle(Geom_Surface) mySurface; + Standard_Real myFirst; + Standard_Real myLast; + Standard_Integer myErrorStatus; + Standard_Real myMaxDistance; + Standard_Real myMaxParameter; +}; + +#endif // _BRepLib_CheckCurveOnSurface_HeaderFile diff --git a/src/IntTools/IntTools_Tools.cxx b/src/IntTools/IntTools_Tools.cxx index 86c61df77e..f00026c816 100644 --- a/src/IntTools/IntTools_Tools.cxx +++ b/src/IntTools/IntTools_Tools.cxx @@ -789,10 +789,10 @@ Standard_Boolean IntTools_Tools::ComputeTolerance Standard_Real& theMaxDist, Standard_Real& theMaxPar) { - BRepLib_CheckCurveOnSurface aCS; + GeomLib_CheckCurveOnSurface aCS; // - aCS.Init(theCurve3D, theCurve2D, theSurf, theFirst, theLast); - aCS.Perform(); + aCS.Init(theCurve3D, theSurf, theFirst, theLast); + aCS.Perform(theCurve2D); if (!aCS.IsDone()) { return Standard_False; } -- 2.20.1