From 9c1519c4c5fdb04bbc6520fe2e1299e281f84cb8 Mon Sep 17 00:00:00 2001 From: ifv Date: Mon, 25 Jan 2016 16:35:17 +0300 Subject: [PATCH] 0027108: GCPnt_TangentialDeflection does not respect linear deflection Modification of algorithm in order to prevent violation of angular and curvature deflection condition for smooth intervals of curve. Modification of algorithm for calculation of maximal deflection in command crvtpoints, crvpoints (CR25649) Elementary bug fixing in algorithm GCPnts_UniformDeflection.gxx Modification of test cases in order to set new reference parameters of shape triangulations Some tests: bugs modalg_2 bug397 mesh standard_incmesh C7, V3 mesh standard_incmesh_parallel C7, V3 mesh standard_mesh C7, V3 mesh standard_shading V3 were modified by TODO with reference bug 27226, because some problems in meshing algorithm (package BRepMesh) were discovered when tessellation of edges was changed. These problems cannot be solved by modification of GCPnts_TangentialDeflection algorithm. New issue #27226 was created, see bugtracker for details. Correction of test data Test case for issue #27108 Modification of algorithm for improving performance Correction of test cases --- src/GCPnts/FILES | 4 + src/GCPnts/GCPnts_DistFunction.cxx | 73 +++++++ src/GCPnts/GCPnts_DistFunction.hxx | 67 +++++++ src/GCPnts/GCPnts_DistFunction2d.cxx | 76 ++++++++ src/GCPnts/GCPnts_DistFunction2d.hxx | 68 +++++++ src/GCPnts/GCPnts_TangentialDeflection.cxx | 28 ++- src/GCPnts/GCPnts_TangentialDeflection.gxx | 116 ++++++++++- src/GCPnts/GCPnts_TangentialDeflection.hxx | 18 +- src/GCPnts/GCPnts_UniformDeflection.gxx | 2 +- .../GeometryTest_CurveCommands.cxx | 184 +++++++----------- tests/bugs/iges/buc60820_2 | 2 +- tests/bugs/iges/buc60823 | 2 +- tests/bugs/iges/bug306 | 2 +- tests/bugs/mesh/bug24127 | 2 +- tests/bugs/mesh/bug24938 | 1 + tests/bugs/mesh/bug25519 | 2 +- tests/bugs/modalg_2/bug397 | 3 + tests/bugs/moddata_2/fra62476_2 | 2 +- tests/bugs/moddata_3/bug25207 | 8 +- tests/bugs/moddata_3/bug25737_1 | 2 +- tests/bugs/moddata_3/bug27108 | 27 +++ tests/bugs/vis/bug288_5 | 2 +- tests/mesh/data/advanced/A7 | 2 +- tests/mesh/data/advanced/B1 | 2 +- tests/mesh/data/advanced/B7 | 1 + tests/mesh/data/standard/C7 | 11 +- tests/mesh/data/standard/L6 | 2 +- tests/mesh/data/standard/O5 | 1 + tests/mesh/data/standard/U2 | 6 +- tests/mesh/data/standard/V3 | 2 + tests/mesh/data/standard/W4 | 2 +- tests/mesh/data/standard/W7 | 7 +- 32 files changed, 576 insertions(+), 151 deletions(-) create mode 100644 src/GCPnts/GCPnts_DistFunction.cxx create mode 100644 src/GCPnts/GCPnts_DistFunction.hxx create mode 100644 src/GCPnts/GCPnts_DistFunction2d.cxx create mode 100644 src/GCPnts/GCPnts_DistFunction2d.hxx create mode 100644 tests/bugs/moddata_3/bug27108 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"