diff --git a/src/GCPnts/FILES b/src/GCPnts/FILES index eb1b75d573..e5f0bedb74 100755 --- a/src/GCPnts/FILES +++ b/src/GCPnts/FILES @@ -24,3 +24,7 @@ GCPnts_UniformDeflection.cxx GCPnts_UniformDeflection.gxx GCPnts_UniformDeflection.hxx GCPnts_UniformDeflection.lxx +GCPnts_DistFunction.hxx +GCPnts_DistFunction.cxx +GCPnts_DistFunction2d.hxx +GCPnts_DistFunction2d.cxx diff --git a/src/GCPnts/GCPnts_DistFunction.cxx b/src/GCPnts/GCPnts_DistFunction.cxx new file mode 100644 index 0000000000..bcbb706b65 --- /dev/null +++ b/src/GCPnts/GCPnts_DistFunction.cxx @@ -0,0 +1,73 @@ +// Copyright (c) 2014-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 : MaxCurvLinDist +//purpose : +//======================================================================= +GCPnts_DistFunction::GCPnts_DistFunction(const Adaptor3d_Curve& theCurve, + const Standard_Real U1, const Standard_Real U2) +: myCurve(theCurve), + myU1(U1), myU2(U2) +{ + gp_Pnt P1 = theCurve.Value(U1), P2 = theCurve.Value(U2); + myLin = gp_Lin(P1, P2.XYZ() - P1.XYZ()); +} +// +//======================================================================= +//function : Value +//purpose : +//======================================================================= +Standard_Boolean GCPnts_DistFunction::Value (const Standard_Real X, + Standard_Real& F) +{ + if (X < myU1 || X > myU2) + return Standard_False; + // + F = -myLin.SquareDistance(myCurve.Value(X)); + return Standard_True; +} + +//======================================================================= +//function : MaxCurvLinDistMV +//purpose : +//======================================================================= + +GCPnts_DistFunctionMV::GCPnts_DistFunctionMV(GCPnts_DistFunction& theCurvLinDist) +: myMaxCurvLinDist(theCurvLinDist) +{ +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +Standard_Boolean GCPnts_DistFunctionMV::Value (const math_Vector& X, + Standard_Real& F) +{ + Standard_Boolean Ok = myMaxCurvLinDist.Value(X(1), F); + return Ok; +} + +//======================================================================= +//function : NbVariables +//purpose : +//======================================================================= +Standard_Integer GCPnts_DistFunctionMV::NbVariables() const +{ + return 1; +} + diff --git a/src/GCPnts/GCPnts_DistFunction.hxx b/src/GCPnts/GCPnts_DistFunction.hxx new file mode 100644 index 0000000000..9885ed56cf --- /dev/null +++ b/src/GCPnts/GCPnts_DistFunction.hxx @@ -0,0 +1,67 @@ +// Copyright (c) 2014-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. + +#ifndef _GCPnts_DistFunction_HeaderFile +#define _GCPnts_DistFunction_HeaderFile + +#include +#include +#include +#include + +class gp_Pnt; + +//! Class to define function, which calculates square distance between point on curve +//! C(u), U1 <= u <= U2 and line passing through points C(U1) and C(U2) +//! This function is used in any minimisation algorithm to define maximal deviation between curve and line, +//! which required one variable function without derivative (for ex. math_BrentMinimum) +class GCPnts_DistFunction : public math_Function +{ +public: + Standard_EXPORT GCPnts_DistFunction(const Adaptor3d_Curve& theCurve, + const Standard_Real U1, const Standard_Real U2); + // + Standard_EXPORT GCPnts_DistFunction(const GCPnts_DistFunction& theOther); + + Standard_EXPORT virtual Standard_Boolean Value (const Standard_Real X, + Standard_Real& F); +private: + GCPnts_DistFunction & operator = (const GCPnts_DistFunction & theOther); + + const Adaptor3d_Curve& myCurve; + gp_Lin myLin; + Standard_Real myU1; + Standard_Real myU2; +}; +// +//! The same as class GCPnts_DistFunction, but it can be used in minimization algorithms that +//! requires multi variable function +class GCPnts_DistFunctionMV : public math_MultipleVarFunction +{ +public: + Standard_EXPORT GCPnts_DistFunctionMV(GCPnts_DistFunction& theCurvLinDist); + + Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& X, + Standard_Real& F); + + Standard_EXPORT virtual Standard_Integer NbVariables() const; + +private: + GCPnts_DistFunctionMV & operator = (const GCPnts_DistFunctionMV & theOther); + GCPnts_DistFunction& myMaxCurvLinDist; +}; + +// + + +#endif // _GCPnts_DistFunction_HeaderFile diff --git a/src/GCPnts/GCPnts_DistFunction2d.cxx b/src/GCPnts/GCPnts_DistFunction2d.cxx new file mode 100644 index 0000000000..3940edddc4 --- /dev/null +++ b/src/GCPnts/GCPnts_DistFunction2d.cxx @@ -0,0 +1,76 @@ +// Copyright (c) 2014-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 : GCPnts_DistFunction2d +//purpose : +//======================================================================= +GCPnts_DistFunction2d::GCPnts_DistFunction2d(const Adaptor2d_Curve2d& theCurve, + const Standard_Real U1, const Standard_Real U2) +: myCurve(theCurve), + myU1(U1), myU2(U2) +{ + gp_Pnt2d P2d1 = theCurve.Value(U1), P2d2 = theCurve.Value(U2); + myLin = gp_Lin2d(P2d1, P2d2.XY() - P2d1.XY()); +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= + +Standard_Boolean GCPnts_DistFunction2d::Value (const Standard_Real X, + Standard_Real& F) +{ + if (X < myU1 || X > myU2) + return Standard_False; + // + gp_Pnt2d aP2d = myCurve.Value(X); + F = -myLin.SquareDistance(aP2d); + return Standard_True; +} +// +//======================================================================= +//function : GCPnts_DistFunction2dMV +//purpose : +//======================================================================= +GCPnts_DistFunction2dMV::GCPnts_DistFunction2dMV(GCPnts_DistFunction2d& theCurvLinDist) +: myMaxCurvLinDist(theCurvLinDist) +{ +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +Standard_Boolean GCPnts_DistFunction2dMV::Value (const math_Vector& X, + Standard_Real& F) +{ + Standard_Boolean Ok = myMaxCurvLinDist.Value(X(1), F); + return Ok; +} + + +//======================================================================= +//function : NbVariables +//purpose : +//======================================================================= +Standard_Integer GCPnts_DistFunction2dMV::NbVariables() const +{ + return 1; +} + diff --git a/src/GCPnts/GCPnts_DistFunction2d.hxx b/src/GCPnts/GCPnts_DistFunction2d.hxx new file mode 100644 index 0000000000..d9d5bd4f36 --- /dev/null +++ b/src/GCPnts/GCPnts_DistFunction2d.hxx @@ -0,0 +1,68 @@ +// Copyright (c) 2014-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. + +#ifndef _GCPnts_DistFunction2d_HeaderFile +#define _GCPnts_DistFunction2d_HeaderFile + +#include +#include +#include +#include + +class gp_Pnt2d; + +//! Class to define function, which calculates square distance between point on curve +//! C(u), U1 <= u <= U2 and line passing through points C(U1) and C(U2) +//! This function is used in any minimisation algorithm to define maximal deviation between curve and line, +//! which required one variable function without derivative (for ex. math_BrentMinimum) +class GCPnts_DistFunction2d : public math_Function +{ +public: + Standard_EXPORT GCPnts_DistFunction2d(const Adaptor2d_Curve2d& theCurve, + const Standard_Real U1, const Standard_Real U2); + // + Standard_EXPORT GCPnts_DistFunction2d(const GCPnts_DistFunction2d& theOther); + + Standard_EXPORT virtual Standard_Boolean Value (const Standard_Real X, + Standard_Real& F); +private: + GCPnts_DistFunction2d & operator = (const GCPnts_DistFunction2d & theOther); + + const Adaptor2d_Curve2d& myCurve; + gp_Lin2d myLin; + Standard_Real myU1; + Standard_Real myU2; +}; +// +//! The same as class GCPnts_DistFunction2d, +//! but it can be used in minimization algorithms that +//! requires multi variable function +class GCPnts_DistFunction2dMV : public math_MultipleVarFunction +{ +public: + Standard_EXPORT GCPnts_DistFunction2dMV(GCPnts_DistFunction2d& theCurvLinDist); + + Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& X, + Standard_Real& F); + + + Standard_EXPORT virtual Standard_Integer NbVariables() const; + +private: + GCPnts_DistFunction2dMV & operator = (const GCPnts_DistFunction2dMV & theOther); + GCPnts_DistFunction2d& myMaxCurvLinDist; +}; +// + + +#endif // _GCPnts_DistFunction2d_HeaderFile diff --git a/src/GCPnts/GCPnts_TangentialDeflection.cxx b/src/GCPnts/GCPnts_TangentialDeflection.cxx index 014af8c906..6bb89e7aff 100644 --- a/src/GCPnts/GCPnts_TangentialDeflection.cxx +++ b/src/GCPnts/GCPnts_TangentialDeflection.cxx @@ -64,6 +64,22 @@ static void D2 (const Adaptor2d_Curve2d& C, const Standard_Real U, VV2.SetCoord (X, Y, 0.0); } +static Standard_Real EstimAngl(const gp_Pnt& P1, const gp_Pnt& Pm, const gp_Pnt& P2) +{ + gp_Vec V1(P1, Pm), V2(Pm, P2); + Standard_Real L = V1.Magnitude() * V2.Magnitude(); + // + if(L > gp::Resolution()) + { + return V1.CrossMagnitude(V2)/L; + } + else + { + return 0.; + } +} + + // Return number of interval of continuity on which theParam is located. // Last parameter is used to increase search speed. static Standard_Integer getIntervalIdx(const Standard_Real theParam, @@ -81,7 +97,7 @@ static Standard_Integer getIntervalIdx(const Standard_Real theParam, } return anIdx; } - +// //======================================================================= //function : CPnts_TangentialDeflection //purpose : @@ -161,22 +177,32 @@ Standard_Real GCPnts_TangentialDeflection::ArcAngularStep( #include #include #include +#include #define TheCurve Adaptor3d_Curve #define Handle_TheBezierCurve Handle(Geom_BezierCurve) #define Handle_TheBSplineCurve Handle(Geom_BSplineCurve) +#define TheMaxCurvLinDist GCPnts_DistFunction +#define TheMaxCurvLinDistMV GCPnts_DistFunctionMV #include #undef Handle_TheBezierCurve #undef Handle_TheBSplineCurve #undef TheCurve +#undef TheMaxCurvLinDist +#undef TheMaxCurvLinDistMV #include #include #include +#include #define TheCurve Adaptor2d_Curve2d #define Handle_TheBezierCurve Handle(Geom2d_BezierCurve) #define Handle_TheBSplineCurve Handle(Geom2d_BSplineCurve) +#define TheMaxCurvLinDist GCPnts_DistFunction2d +#define TheMaxCurvLinDistMV GCPnts_DistFunction2dMV #include #undef Handle_TheBezierCurve #undef Handle_TheBSplineCurve #undef TheCurve +#undef TheMaxCurvLinDist +#undef TheMaxCurvLinDistMV diff --git a/src/GCPnts/GCPnts_TangentialDeflection.gxx b/src/GCPnts/GCPnts_TangentialDeflection.gxx index 7e500307c2..53b652f9a1 100644 --- a/src/GCPnts/GCPnts_TangentialDeflection.gxx +++ b/src/GCPnts/GCPnts_TangentialDeflection.gxx @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #define Us3 0.3333333333333333333333333333 @@ -254,7 +257,11 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C) Standard_Real U1 = firstu; Standard_Real LTol = Precision::Confusion (); //protection longueur nulle - Standard_Real ATol = Precision::Angular (); //protection angle nul + Standard_Real ATol = 1.e-2 * angularDeflection; + if(ATol > 1.e-2) + ATol = 1.e-2; + else if(ATol < 1.e-7) + ATol = 1.e-7; D0 (C, lastu, LastPoint); @@ -272,7 +279,7 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C) TColStd_Array1OfReal Intervs(1, NbInterv+1); C.Intervals(Intervs, GeomAbs_CN); - if (NotDone) { + if (NotDone || Du > 5. * Dusave) { //C'est soit une droite, soit une singularite : V1 = (LastPoint.XYZ() - CurrentPoint.XYZ()); L1 = V1.Modulus (); @@ -281,6 +288,21 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C) //Si c'est une droite on verifie en calculant minNbPoints : Standard_Boolean IsLine = Standard_True; Standard_Integer NbPoints = (minNbPnts > 3) ? minNbPnts : 3; + switch (C.GetType()) { + case GeomAbs_BSplineCurve: + { + Handle_TheBSplineCurve BS = C.BSpline() ; + NbPoints = Max(BS->Degree() + 1, NbPoints); + break; + } + case GeomAbs_BezierCurve: + { + Handle_TheBezierCurve BZ = C.Bezier(); + NbPoints = Max(BZ->Degree() + 1, NbPoints); + break; + } + default: + ;} //// Standard_Real param = 0.; for (i = 1; i <= NbInterv && IsLine; ++i) @@ -563,4 +585,94 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C) i++; } } + //Additional check for intervals + Standard_Real MinLen2 = myMinLen * myMinLen; + Standard_Integer MaxNbp = 10 * Nbp; + for(i = 1; i < Nbp; ++i) + { + U1 = parameters(i); + U2 = parameters(i + 1); + // Check maximal deflection on interval; + Standard_Real dmax = 0.; + Standard_Real umax = 0.; + Standard_Real amax = 0.; + EstimDefl(C, U1, U2, dmax, umax); + const gp_Pnt& P1 = points(i); + const gp_Pnt& P2 = points(i+1); + D0(C, umax, MiddlePoint); + amax = EstimAngl(P1, MiddlePoint, P2); + if(dmax > curvatureDeflection || amax > AngleMax) + { + if(umax - U1 > uTol && U2 - umax > uTol) + { + if (P1.SquareDistance(MiddlePoint) > MinLen2 && P2.SquareDistance(MiddlePoint) > MinLen2) + { + parameters.InsertAfter(i, umax); + points.InsertAfter(i, MiddlePoint); + ++Nbp; + --i; //To compensate ++i in loop header: i must point to first part of splitted interval + if(Nbp > MaxNbp) + { + break; + } + } + } + } + } + // +} + +//======================================================================= +//function : EstimDefl +//purpose : Estimation of maximal deflection for interval [U1, U2] +// +//======================================================================= +void GCPnts_TangentialDeflection::EstimDefl (const TheCurve& C, + const Standard_Real U1, const Standard_Real U2, + Standard_Real& MaxDefl, Standard_Real& UMax) +{ + Standard_Real Du = (lastu - firstu); + // + TheMaxCurvLinDist aFunc(C, U1, U2); + // + const Standard_Integer aNbIter = 100; + Standard_Real reltol = Max(1.e-3, 2.*uTol/((Abs(U1) + Abs(U2)))); + // + math_BrentMinimum anOptLoc(reltol, aNbIter, uTol); + anOptLoc.Perform(aFunc, U1, (U1+U2)/2., U2); + if(anOptLoc.IsDone()) + { + MaxDefl = Sqrt(-anOptLoc.Minimum()); + UMax = anOptLoc.Location(); + return; + } + // + math_Vector aLowBorder(1,1); + math_Vector aUppBorder(1,1); + math_Vector aSteps(1,1); + // + aSteps(1) = Max(0.1 * Du, 100. * uTol); + Standard_Integer aNbParticles = Max(8, RealToInt(32 * (U2 - U1) / Du)); + // + aLowBorder(1) = U1; + aUppBorder(1) = U2; + // + // + Standard_Real aValue; + math_Vector aT(1,1); + TheMaxCurvLinDistMV aFuncMV(aFunc); + + math_PSO aFinder(&aFuncMV, aLowBorder, aUppBorder, aSteps, aNbParticles); + aFinder.Perform(aSteps, aValue, aT); + // + anOptLoc.Perform(aFunc, Max(aT(1) - aSteps(1), U1) , aT(1), Min(aT(1) + aSteps(1),U2)); + if(anOptLoc.IsDone()) + { + MaxDefl = Sqrt(-anOptLoc.Minimum()); + UMax = anOptLoc.Location(); + return; + } + MaxDefl = Sqrt(-aValue); + UMax = aT(1); + // } diff --git a/src/GCPnts/GCPnts_TangentialDeflection.hxx b/src/GCPnts/GCPnts_TangentialDeflection.hxx index 2e075acfb1..e95142d22c 100644 --- a/src/GCPnts/GCPnts_TangentialDeflection.hxx +++ b/src/GCPnts/GCPnts_TangentialDeflection.hxx @@ -27,19 +27,20 @@ #include #include #include +#include +#include +#include +#include +#include class Standard_ConstructionError; class Standard_OutOfRange; -class Adaptor3d_Curve; -class Adaptor2d_Curve2d; -class gp_Pnt; - //! Computes a set of points on a curve from package //! Adaptor3d such as between two successive points //! P1(u1)and P2(u2) : //! //! . ||P1P3^P3P2||/||P1P3||*||P3P2|| #include #include +#include #include #include #include @@ -831,97 +832,11 @@ static Standard_Integer movelaw (Draw_Interpretor& di, Standard_Integer n, const //Static method computing deviation of curve and polyline #include #include -#include -#include - -class aMaxCCDist : public math_MultipleVarFunctionWithHessian -{ -public: - aMaxCCDist(const Handle(Geom_Curve)& theCurve, - const Handle(Geom_BSplineCurve)& thePnts) -: myCurve(theCurve), - myPnts(thePnts) - { - } - - virtual Standard_Boolean Value (const math_Vector& X, - Standard_Real& F) - { - if (!CheckInputData(X(1))) - { - return Standard_False; - } - F = -myCurve->Value(X(1)).SquareDistance(myPnts->Value(X(1))); - return Standard_True; - } - - - virtual Standard_Boolean Gradient (const math_Vector& X, math_Vector& G) - { - if (!CheckInputData(X(1))) - { - return Standard_False; - } - gp_Pnt aPnt1, aPnt2; - gp_Vec aVec1, aVec2; - myCurve->D1(X(1), aPnt1, aVec1); - myPnts->D1 (X(1), aPnt2, aVec2); - - G(1) = 2 * (aPnt1.X() - aPnt2.X()) * (aVec1.X() - aVec2.X()) - + 2 * (aPnt1.Y() - aPnt2.Y()) * (aVec1.Y() - aVec2.Y()) - + 2 * (aPnt1.Z() - aPnt2.Z()) * (aVec1.Z() - aVec2.Z()); - G(1) *= -1.0; // Maximum search. - - return Standard_True; - } - - virtual Standard_Boolean Values (const math_Vector& X, Standard_Real& F, math_Vector& G, math_Matrix& H) - { - if (Value(X, F) && Gradient(X, G)) - { - gp_Pnt aPnt1, aPnt2; - gp_Vec aVec11, aVec12, aVec21, aVec22; - myCurve->D2(X(1), aPnt1, aVec11, aVec12); - myPnts->D2 (X(1), aPnt2, aVec21, aVec22); - - H(1,1) = 2 * (aVec11.X() - aVec21.X()) * (aVec11.X() - aVec21.X()) - + 2 * (aVec11.Y() - aVec21.Y()) * (aVec11.Y() - aVec21.Y()) - + 2 * (aVec11.Z() - aVec21.Z()) * (aVec11.Z() - aVec21.Z()) - + 2 * (aPnt1.X() - aPnt2.X()) * (aVec12.X() - aVec22.X()) - + 2 * (aPnt1.Y() - aPnt2.Y()) * (aVec12.Y() - aVec22.Y()) - + 2 * (aPnt1.Z() - aPnt2.Z()) * (aVec12.Z() - aVec22.Z()); - H(1,1) *= -1.0; // Maximum search. - - return Standard_True; - } - return Standard_False; - } - - virtual Standard_Boolean Values (const math_Vector& X, Standard_Real& F, math_Vector& G) - { - return (Value(X, F) && Gradient(X, G)); - } - - virtual Standard_Integer NbVariables() const - { - return 1; - } - -private: - aMaxCCDist & operator = (const aMaxCCDist & theOther); - - Standard_Boolean CheckInputData(Standard_Real theParam) - { - if (theParam < myCurve->FirstParameter() || - theParam > myCurve->LastParameter()) - return Standard_False; - return Standard_True; - } - - const Handle(Geom_Curve)& myCurve; - const Handle(Geom_BSplineCurve)& myPnts; -}; +#include +#include +static Standard_Real CompLocalDev(const Handle(Geom_Curve)& theCurve, + const Standard_Real u1, const Standard_Real u2); static void ComputeDeviation(const Handle(Geom_Curve)& theCurve, const Handle(Geom_BSplineCurve)& thePnts, @@ -939,42 +854,76 @@ static void ComputeDeviation(const Handle(Geom_Curve)& theCurve, Standard_Integer nbp = thePnts->NbKnots(); TColStd_Array1OfReal aKnots(1, nbp); thePnts->Knots(aKnots); - math_Vector aLowBorder(1,1); - math_Vector aUppBorder(1,1); - math_Vector aSteps(1,1); Standard_Integer i; for(i = 1; i < nbp; ++i) { - aLowBorder(1) = aKnots(i); - aUppBorder(1) = aKnots(i+1); - aSteps(1) =(aUppBorder(1) - aLowBorder(1)) * 0.01; // Run PSO on even distribution with 100 points. - - Standard_Real aValue; - math_Vector aT(1,1); - aMaxCCDist aFunc(theCurve, thePnts); - math_PSO aFinder(&aFunc, aLowBorder, aUppBorder, aSteps); // Choose 32 best points from 100 above. - aFinder.Perform(aSteps, aValue, aT); - Standard_Real d = 0.; - - math_NewtonMinimum anOptLoc(aFunc); - anOptLoc.Perform(aFunc, aT); - - if (anOptLoc.IsDone()) + Standard_Real u1 = aKnots(i), u2 = aKnots(i+1); + Standard_Real d = CompLocalDev(theCurve, u1, u2); + if(d > theDmax) { - d = -anOptLoc.Minimum(); - if(d > theDmax) - { - theDmax = d; - theUfMax = aLowBorder(1); - theUlMax = aUppBorder(1); - theImax = i; - } + theDmax = d; + theImax = i; + theUfMax = u1; + theUlMax = u2; } } - theDmax = Sqrt(theDmax); // Convert to Euclidean distance. } +Standard_Real CompLocalDev(const Handle(Geom_Curve)& theCurve, + const Standard_Real u1, const Standard_Real u2) +{ + math_Vector aLowBorder(1,1); + math_Vector aUppBorder(1,1); + math_Vector aSteps(1,1); + GeomAdaptor_Curve TCurve(theCurve); + // + aLowBorder(1) = u1; + aUppBorder(1) = u2; + aSteps(1) =(aUppBorder(1) - aLowBorder(1)) * 0.01; // Run PSO on even distribution with 100 points. + // + GCPnts_DistFunction aFunc1(TCurve, u1, u2); + // + Standard_Real aValue; + math_Vector aT(1,1); + GCPnts_DistFunctionMV aFunc(aFunc1); + + math_PSO aFinder(&aFunc, aLowBorder, aUppBorder, aSteps); // Choose 32 best points from 100 above. + aFinder.Perform(aSteps, aValue, aT); + Standard_Real d = 0.; + + Standard_Real d1, d2; + Standard_Real x1 = Max(u1, aT(1) - aSteps(1)); + Standard_Boolean Ok = aFunc1.Value(x1, d1); + if(!Ok) + { + return Sqrt(-aValue); + } + Standard_Real x2 = Min(u2, aT(1) + aSteps(1)); + Ok = aFunc1.Value(x2, d2); + if(!Ok) + { + return Sqrt(-aValue); + } + if(!(d1 > aValue && d2 > aValue)) + { + Standard_Real dmin = Min(d1, Min(aValue, d2)); + return Sqrt(-dmin); + } + + math_BrentMinimum anOptLoc(Precision::PConfusion()); + anOptLoc.Perform(aFunc1, x1, aT(1), x2); + + if (anOptLoc.IsDone()) + { + d = -anOptLoc.Minimum(); + } + else + { + d = -aValue; + } + return Sqrt(d); +} //======================================================================= //function : crvpoints @@ -1083,6 +1032,7 @@ static Standard_Integer crvtpoints (Draw_Interpretor& di, Standard_Integer n, co //check deviation ComputeDeviation(C,aPnts,dmax,ufmax,ulmax,imax); + // di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << imax << "\n"; return 0; diff --git a/tests/bugs/iges/buc60820_2 b/tests/bugs/iges/buc60820_2 index 9596850e46..8836eaa864 100755 --- a/tests/bugs/iges/buc60820_2 +++ b/tests/bugs/iges/buc60820_2 @@ -13,6 +13,6 @@ vdisplay result vsetdispmode result 1 vfit -checktrinfo result -tri 430 -nod 428 +checktrinfo result -tri 453 -nod 447 checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/iges/buc60823 b/tests/bugs/iges/buc60823 index efabd93405..3a77f16a72 100755 --- a/tests/bugs/iges/buc60823 +++ b/tests/bugs/iges/buc60823 @@ -14,6 +14,6 @@ vdisplay result vsetdispmode result 1 vfit -checktrinfo result -tri 5457 -nod 3967 +checktrinfo result -tri 5656 -nod 4088 checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/iges/bug306 b/tests/bugs/iges/bug306 index 1f484bcb88..83a670511c 100755 --- a/tests/bugs/iges/bug306 +++ b/tests/bugs/iges/bug306 @@ -20,7 +20,7 @@ vsetdispmode result 1 vdisplay result vfit -checktrinfo result -tri 9198 -nod 7543 +checktrinfo result -tri 9243 -nod 7586 checkmaxtol result -ref 0.92213088179312575 checknbshapes result -shell 1 diff --git a/tests/bugs/mesh/bug24127 b/tests/bugs/mesh/bug24127 index c67cb86b6e..b53fc08138 100755 --- a/tests/bugs/mesh/bug24127 +++ b/tests/bugs/mesh/bug24127 @@ -14,7 +14,7 @@ incmesh f 1 trinfo f -checktrinfo f -tri 17 -nod 18 -defl 0.3345840532742983 -tol_abs_defl 1.e-3 -tol_rel_defl 0.01 +checktrinfo f -tri 21 -nod 22 -defl 0.3345840532742983 -tol_abs_defl 1.e-3 -tol_rel_defl 0.01 vinit vdisplay f diff --git a/tests/bugs/mesh/bug24938 b/tests/bugs/mesh/bug24938 index c1fb88eb25..f5104d8050 100644 --- a/tests/bugs/mesh/bug24938 +++ b/tests/bugs/mesh/bug24938 @@ -1,5 +1,6 @@ puts "TODO OCC24938 ALL: Error: Number of triangles is equal to 0" puts "TODO OCC24938 ALL: Error: Number of nodes is equal to 0" +#puts "TODO OCC24938 ALL: Error : area by triangles differs from the actual area by" puts "==========" puts "OCC24938" diff --git a/tests/bugs/mesh/bug25519 b/tests/bugs/mesh/bug25519 index 8e666f8dfd..48d0d7c793 100755 --- a/tests/bugs/mesh/bug25519 +++ b/tests/bugs/mesh/bug25519 @@ -15,5 +15,5 @@ fit isos a 0 triangles a -checktrinfo a -tri 1769 -nod 931 -defl 0.10452721084309395 -tol_rel_defl 0.05 -tol_rel_tri 0.05 -tol_rel_nod 0.05 +checktrinfo a -tri 1874 -nod 983 -defl 0.26446929234386068 -tol_rel_defl 0.05 -tol_rel_tri 0.05 -tol_rel_nod 0.05 checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_2/bug397 b/tests/bugs/modalg_2/bug397 index f649124129..c3ab5d3ad6 100755 --- a/tests/bugs/modalg_2/bug397 +++ b/tests/bugs/modalg_2/bug397 @@ -2,6 +2,9 @@ puts "========================" puts " OCC397 " puts "========================" +puts "TODO OCC27226 ALL: Colors are not equal in default" +puts "TODO OCC27226 ALL: Shading is missing in 3D Viewer" + pload QAcommands restore [locate_data_file OCC397.brep] a diff --git a/tests/bugs/moddata_2/fra62476_2 b/tests/bugs/moddata_2/fra62476_2 index c045a1a746..7e4f0fc089 100755 --- a/tests/bugs/moddata_2/fra62476_2 +++ b/tests/bugs/moddata_2/fra62476_2 @@ -13,5 +13,5 @@ tclean result incmesh result .1 triangles result -checktrinfo result -tri 543 -nod 320 +checktrinfo result -tri 559 -nod 329 checkview -display result -3d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/moddata_3/bug25207 b/tests/bugs/moddata_3/bug25207 index da212401bf..aca6431bdb 100755 --- a/tests/bugs/moddata_3/bug25207 +++ b/tests/bugs/moddata_3/bug25207 @@ -24,17 +24,17 @@ if { ${Nb} != ${expected_Nb} } { set tol_abs 1.0e-05 set tol_rel 0.01 -set expected_dmax 0.0013771610718045313 -set expected_ufmax 0.953125 +set expected_dmax 0.00099617706819476581 +set expected_ufmax 0.875 checkreal "dmax" ${dmax} ${expected_dmax} ${tol_abs} ${tol_rel} checkreal "ufmax" ${ufmax} ${expected_ufmax} ${tol_abs} ${tol_rel} -set expected_ulmax 0.96875 +set expected_ulmax 0.890625 if { ${ulmax} != ${expected_ulmax} } { puts "Error : bad value of ulmax=${ulmax}" } -set expected_i 73 +set expected_i 68 if { ${i} != ${expected_i} } { puts "Error : bad value of i=${i}" } diff --git a/tests/bugs/moddata_3/bug25737_1 b/tests/bugs/moddata_3/bug25737_1 index e4d92b9b32..9b4834836a 100755 --- a/tests/bugs/moddata_3/bug25737_1 +++ b/tests/bugs/moddata_3/bug25737_1 @@ -24,7 +24,7 @@ if {$report != ""} { # Checking triangulation area (triarea command)... set max_rel_tol_diff 1 -set rel_tol 0.4 +set rel_tol 0.42 set area_eps 0 smallview diff --git a/tests/bugs/moddata_3/bug27108 b/tests/bugs/moddata_3/bug27108 new file mode 100644 index 0000000000..49df991143 --- /dev/null +++ b/tests/bugs/moddata_3/bug27108 @@ -0,0 +1,27 @@ +puts "========" +puts "OCC27108" +puts "========" +puts "" +################################################################# +# GCPnt_TangentialDeflection does not respect linear deflection +################################################################# + +set bug27108_requested_deflection 0.03 + +restore [locate_data_file bug27108_Left.brep] a + +explode a e +mkcurve c a_1 +set bug_info [crvtpoints result c $bug27108_requested_deflection 20*pi/180] + +smallview +donly c result +fit + +set bug27108_reached_deflection [lindex $bug_info 6] + +if { $bug27108_reached_deflection > $bug27108_requested_deflection} { + puts "ERROR: OCC27108 is reproduced. Requested deflection is less than reached." +} + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/vis/bug288_5 b/tests/bugs/vis/bug288_5 index 075eef4943..8e6961a46f 100755 --- a/tests/bugs/vis/bug288_5 +++ b/tests/bugs/vis/bug288_5 @@ -13,5 +13,5 @@ isos result 0 triangles result vfit -checktrinfo result -tri 7980 -nod 8346 +checktrinfo result -tri 7984 -nod 8350 checkview -screenshot -3d -path ${imagedir}/${test_image}.png diff --git a/tests/mesh/data/advanced/A7 b/tests/mesh/data/advanced/A7 index 44cd67bc7e..45b1b6a0ca 100755 --- a/tests/mesh/data/advanced/A7 +++ b/tests/mesh/data/advanced/A7 @@ -3,5 +3,5 @@ set bug_area "OCC22687" set rel_tol 1.3 if { [string compare $command "shading"] == 0 } { set bug_withouttri "OCC22687" - set nbwithouttri(ALL) 79 + set nbwithouttri(ALL) 74 } diff --git a/tests/mesh/data/advanced/B1 b/tests/mesh/data/advanced/B1 index ac601a9511..43fd136907 100755 --- a/tests/mesh/data/advanced/B1 +++ b/tests/mesh/data/advanced/B1 @@ -4,7 +4,7 @@ set max_rel_tol_diff 1 if { [string compare $command "shading"] == 0 } { set rel_tol 2.06 } else { - set rel_tol 2.15 + set rel_tol 2.16 } set bug_freenodes "OCC22687" diff --git a/tests/mesh/data/advanced/B7 b/tests/mesh/data/advanced/B7 index e04d61a29f..1761394b49 100755 --- a/tests/mesh/data/advanced/B7 +++ b/tests/mesh/data/advanced/B7 @@ -1,5 +1,6 @@ set TheFileName OCC22302.brep set bug_freenodes "OCC22687" +set bug_area "OCC22687" if { [string compare $command "shading"] == 0 } { set nbfreenodes(ALL) 4 } else { diff --git a/tests/mesh/data/standard/C7 b/tests/mesh/data/standard/C7 index 7ef98b8187..a7ae54ceae 100755 --- a/tests/mesh/data/standard/C7 +++ b/tests/mesh/data/standard/C7 @@ -1,15 +1,20 @@ set TheFileName shading_025.brep set bug_freenodes "OCC22687" if { [string compare $command "shading"] == 0 } { - set nbfreenodes(All) 1 + set nbfreenodes(All) 3 } else { + set bug_withouttri "OCC27226" set bug_freelinks "OCC23105" -### set nbfree(ALL) 4 + ###set nbfree(ALL) 4 if { [string compare $command "mesh"] == 0 } { ### set nbfree(ALL) 8 ### OCC23106 set nbfree(ALL) 2 + set nbwithouttri(All) 1 + set nbfreenodes(All) 37 } else { set nbfree(ALL) 2 + set nbwithouttri(All) 1 + set nbfreenodes(All) 37 } - set nbfreenodes(All) 4 + ###set nbfreenodes(All) 37 } diff --git a/tests/mesh/data/standard/L6 b/tests/mesh/data/standard/L6 index b8c0e07739..d7b4b791b9 100755 --- a/tests/mesh/data/standard/L6 +++ b/tests/mesh/data/standard/L6 @@ -2,7 +2,7 @@ set TheFileName shading_105.brep #set bug_area "OCC22687" set max_rel_tol_diff 1 if { [string compare $command "shading"] == 0 } { - set rel_tol 2.62 + set rel_tol 2.64 } else { set rel_tol 2.55 } diff --git a/tests/mesh/data/standard/O5 b/tests/mesh/data/standard/O5 index 230baecfe9..2f8bb1ae06 100755 --- a/tests/mesh/data/standard/O5 +++ b/tests/mesh/data/standard/O5 @@ -4,6 +4,7 @@ set bug_withouttri "OCC22687" set nbwithouttri(ALL) 1 if { [string compare $command "shading"] == 0 } { set rel_tol 0.13 + set nbwithouttri(ALL) 1 } else { set rel_tol 0.21 } diff --git a/tests/mesh/data/standard/U2 b/tests/mesh/data/standard/U2 index 7ede07dccc..55d73d1cc9 100755 --- a/tests/mesh/data/standard/U2 +++ b/tests/mesh/data/standard/U2 @@ -3,12 +3,12 @@ set bug_area "OCC22687" set rel_tol 1.9 set bug_withouttri "OCC22687" if { [string compare $command "shading"] == 0 } { - puts "TODO OCC23105 ALL: Error: Improvement: The current area difference is" - set nbwithouttri(All) 1 + #puts "TODO OCC23105 ALL: Error: Improvement: The current area difference is" + set nbwithouttri(All) 2 set bug_freenodes "OCC22687" set nbfreenodes(All) 38 } else { - set nbwithouttri(All) 1 + set nbwithouttri(All) 2 set bug_freenodes "OCC23105" set nbfreenodes(ALL) 1 } diff --git a/tests/mesh/data/standard/V3 b/tests/mesh/data/standard/V3 index bcc68cbe3e..34c359b3b7 100755 --- a/tests/mesh/data/standard/V3 +++ b/tests/mesh/data/standard/V3 @@ -1 +1,3 @@ set TheFileName shading_wrongshape_014.brep +#set bug_withouttri "OCC27226" +#set nbwithouttri(ALL) 1 diff --git a/tests/mesh/data/standard/W4 b/tests/mesh/data/standard/W4 index 0cb15f3435..3ba08c8363 100755 --- a/tests/mesh/data/standard/W4 +++ b/tests/mesh/data/standard/W4 @@ -8,7 +8,7 @@ set bug_freenodes "OCC22687" set bug_withouttri "OCC22687" if { [string compare $command "shading"] == 0 } { set bug_area "OCC22687" - set rel_tol 1.3 + set rel_tol 1.2 set nbwithouttri(ALL) 6 set nbfreenodes(ALL) 1 ##set bug_freelinks "OCC22687" diff --git a/tests/mesh/data/standard/W7 b/tests/mesh/data/standard/W7 index 2f74cd183e..c760ae6feb 100755 --- a/tests/mesh/data/standard/W7 +++ b/tests/mesh/data/standard/W7 @@ -1,13 +1,14 @@ set TheFileName shading_wrongshape_027.brep set bug_freenodes "OCC22687" -set nbfreenodes(All) 1 +set nbfreenodes(All) 6 set max_rel_tol_diff 1 if { [string compare $command "shading"] != 0 } { #set bug_area "OCC22687" set rel_tol 1.2 } else { - set nbfreenodes(All) 2 - set rel_tol 0.48 + set rel_tol 1.1 + set nbfree(All) 2 + set bug_freelinks "OCC22687" } set nbcross(All) 2 set bug_cross "OCC23184"