From: ifv Date: Mon, 11 Jul 2022 08:09:33 +0000 (+0300) Subject: 0032940: Canonical Recognition: Some surfaces are not recognized as cylindrical surfaces X-Git-Tag: V7_7_0_beta~43 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=b315a85dd706112461a23714c991d328b7e70d17;p=occt.git 0032940: Canonical Recognition: Some surfaces are not recognized as cylindrical surfaces New method for recognizing cylindrical surfaces based on analysis Gaussian field of initial surface is added in class GeomConvert_SurfToAnaSurf --- diff --git a/src/GeomConvert/FILES b/src/GeomConvert/FILES index 06ae4fe8f8..3589aa1b11 100755 --- a/src/GeomConvert/FILES +++ b/src/GeomConvert/FILES @@ -25,3 +25,9 @@ GeomConvert_CurveToAnaCurve.hxx GeomConvert_SurfToAnaSurf.cxx GeomConvert_SurfToAnaSurf.hxx GeomConvert_ConvType.hxx +GeomConvert_FuncSphereLSDist.cxx +GeomConvert_FuncSphereLSDist.hxx +GeomConvert_FuncCylinderLSDist.cxx +GeomConvert_FuncCylinderLSDist.hxx +GeomConvert_FuncConeLSDist.cxx +GeomConvert_FuncConeLSDist.hxx diff --git a/src/GeomConvert/GeomConvert_FuncConeLSDist.cxx b/src/GeomConvert/GeomConvert_FuncConeLSDist.cxx new file mode 100644 index 0000000000..6fc85d538b --- /dev/null +++ b/src/GeomConvert/GeomConvert_FuncConeLSDist.cxx @@ -0,0 +1,68 @@ +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2022 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 + +//======================================================================= +//function : GeomConvert_FuncConeLSDist +//purpose : +//======================================================================= +GeomConvert_FuncConeLSDist::GeomConvert_FuncConeLSDist( + const Handle(TColgp_HArray1OfXYZ)& thePoints, + const gp_Dir& theDir): + myPoints(thePoints), myDir(theDir) +{ +} + +//======================================================================= +//function : NbVariables +//purpose : +//======================================================================= +Standard_Integer GeomConvert_FuncConeLSDist::NbVariables () const +{ + return 5; +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +Standard_Boolean GeomConvert_FuncConeLSDist::Value(const math_Vector& X, Standard_Real& F) +{ + gp_Pnt aLoc(X(1), X(2), X(3)); + Standard_Real aSemiAngle = X(4), anR = X(5); + gp_Ax3 aPos(aLoc, myDir); + + F = 0.; + Standard_Integer i; + for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) + { + Standard_Real u, v; + gp_Pnt aPi(myPoints->Value(i)); + ElSLib::ConeParameters(aPos, anR, aSemiAngle, aPi, u, v); + gp_Pnt aPp; + ElSLib::ConeD0(u, v, aPos, anR, aSemiAngle, aPp); + F += aPi.SquareDistance(aPp); + } + + return Standard_True; +} + + diff --git a/src/GeomConvert/GeomConvert_FuncConeLSDist.hxx b/src/GeomConvert/GeomConvert_FuncConeLSDist.hxx new file mode 100644 index 0000000000..97c7fc4a24 --- /dev/null +++ b/src/GeomConvert/GeomConvert_FuncConeLSDist.hxx @@ -0,0 +1,66 @@ +// Copyright (c) 1991-1999 Matra Datavision +// Copyright (c) 1999-2022 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 _GeomConvert_FuncConeLSDist_HeaderFile +#define _GeomConvert_FuncConeLSDist_HeaderFile + +#include +#include + +#include +#include +#include +#include + +//! Function for search of Cone canonic parameters: coordinates of center local coordinate system, +//! direction of axis, radius and semi-angle from set of points +//! by least square method. +//! +//! +class GeomConvert_FuncConeLSDist : public math_MultipleVarFunction +{ +public: + + DEFINE_STANDARD_ALLOC + + //! Constructor. + Standard_EXPORT GeomConvert_FuncConeLSDist() {}; + + Standard_EXPORT GeomConvert_FuncConeLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints, + const gp_Dir& theDir); + + void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints) + { + myPoints = thePoints; + } + + void SetDir(const gp_Dir& theDir) + { + myDir = theDir; + } + + //! Number of variables. + Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE; + + //! Value. + Standard_EXPORT Standard_Boolean Value(const math_Vector& X,Standard_Real& F) Standard_OVERRIDE; + + +private: + + Handle(TColgp_HArray1OfXYZ) myPoints; + gp_Dir myDir; + +}; +#endif // _GeomConvert_FuncConeLSDist_HeaderFile diff --git a/src/GeomConvert/GeomConvert_FuncCylinderLSDist.cxx b/src/GeomConvert/GeomConvert_FuncCylinderLSDist.cxx new file mode 100644 index 0000000000..af9e83a9a3 --- /dev/null +++ b/src/GeomConvert/GeomConvert_FuncCylinderLSDist.cxx @@ -0,0 +1,140 @@ +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2022 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 + +//======================================================================= +//function : GeomConvert_FuncCylinderLSDist +//purpose : +//======================================================================= +GeomConvert_FuncCylinderLSDist::GeomConvert_FuncCylinderLSDist( + const Handle(TColgp_HArray1OfXYZ)& thePoints, + const gp_Dir& theDir): + myPoints(thePoints), myDir(theDir) +{ +} + +//======================================================================= +//function : NbVariables +//purpose : +//======================================================================= +Standard_Integer GeomConvert_FuncCylinderLSDist::NbVariables () const +{ + return 4; +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +Standard_Boolean GeomConvert_FuncCylinderLSDist::Value(const math_Vector& X,Standard_Real& F) +{ + gp_XYZ aLoc(X(1), X(2), X(3)); + Standard_Real anR2 = X(4)*X(4); + + F = 0.; + Standard_Integer i; + for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) + { + gp_Vec aV(myPoints->Value(i) - aLoc); + Standard_Real aD2 = aV.CrossSquareMagnitude(myDir); + Standard_Real d = aD2 - anR2; + F += d * d; + } + + return Standard_True; +} + +//======================================================================= +//function : Gradient +//purpose : +//======================================================================= +Standard_Boolean GeomConvert_FuncCylinderLSDist::Gradient(const math_Vector& X,math_Vector& G) + +{ + gp_XYZ aLoc(X(1), X(2), X(3)); + Standard_Real anR = X(4), anR2 = anR * anR; + Standard_Real x = myDir.X(), y = myDir.Y(), z = myDir.Z(); + G.Init(0.); + + Standard_Integer i; + for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) + { + gp_Vec aV(myPoints->Value(i) - aLoc); + Standard_Real aD2 = aV.CrossSquareMagnitude(myDir); + Standard_Real d = aD2 - anR2; + Standard_Real Dx0 = 2.*(aV.Z()*x - aV.X()*z)*z + -2.*(aV.X()*y - aV.Y()*x)*y; + Standard_Real Dy0 = -2.*(aV.Y()*z - aV.Z()*y)*z + +2.*(aV.X()*y - aV.Y()*x)*x; + Standard_Real Dz0 = 2.*(aV.Y()*z - aV.Z()*y)*y + -2.*(aV.Z()*x - aV.X()*z)*x; + + G(1) += d * Dx0; + G(2) += d * Dy0; + G(3) += d * Dz0; + // + G(4) += d; + } + + G *= 2; + G(6) *= -2.*anR; + + return Standard_True; +} + +//======================================================================= +//function : Values +//purpose : +//======================================================================= +Standard_Boolean GeomConvert_FuncCylinderLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G) +{ + gp_XYZ aLoc(X(1), X(2), X(3)); + Standard_Real anR = X(4), anR2 = anR * anR; + Standard_Real x = myDir.X(), y = myDir.Y(), z = myDir.Z(); + + F = 0.; + G.Init(0.); + Standard_Integer i; + for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) + { + gp_Vec aV(myPoints->Value(i) - aLoc); + Standard_Real aD2 = aV.CrossSquareMagnitude(myDir); + Standard_Real d = aD2 - anR2; + Standard_Real Dx0 = 2.*(aV.Z()*x - aV.X()*z)*z + - 2.*(aV.X()*y - aV.Y()*x)*y; + Standard_Real Dy0 = -2.*(aV.Y()*z - aV.Z()*y)*z + + 2.*(aV.X()*y - aV.Y()*x)*x; + Standard_Real Dz0 = 2.*(aV.Y()*z - aV.Z()*y)*y + - 2.*(aV.Z()*x - aV.X()*z)*x; + + G(1) += d * Dx0; + G(2) += d * Dy0; + G(3) += d * Dz0; + // + G(4) += d; + // + F += d * d; + } + + G *= 2; + G(4) *= -2.*anR; + + return true; +} + diff --git a/src/GeomConvert/GeomConvert_FuncCylinderLSDist.hxx b/src/GeomConvert/GeomConvert_FuncCylinderLSDist.hxx new file mode 100644 index 0000000000..7c308181e0 --- /dev/null +++ b/src/GeomConvert/GeomConvert_FuncCylinderLSDist.hxx @@ -0,0 +1,100 @@ +// Copyright (c) 1991-1999 Matra Datavision +// Copyright (c) 1999-2022 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 _GeomConvert_FuncCylinderLSDist_HeaderFile +#define _GeomConvert_FuncCylinderLSDist_HeaderFile + +#include +#include + +#include +#include +#include +#include + +//! Function for search of cylinder canonic parameters: coordinates of center local coordinate system, +//! direction of axis and radius from set of points +//! by least square method. +//! +//! The class inherits math_MultipleVarFunctionWithGradient and thus is intended +//! for use in math_BFGS algorithm. +//! +//! Parametrisation: +//! Cylinder is defined by its axis and radius. Axis is defined by 3 cartesian coordinats it location x0, y0, z0 +//! and direction, which is constant and set by user: +//! dir.x, dir.y, dir.z +//! The criteria is: +//! F(x0, y0, z0, theta, phi, R) = Sum[|(P(i) - Loc)^dir|^2 - R^2]^2 => min +//! P(i) is i-th sample point, Loc, dir - axis location and direction, R - radius +//! +//! The square vector product |(P(i) - Loc)^dir|^2 is: +//! +//! [(y - y0)*dir.z - (z - z0)*dir.y]^2 + +//! [(z - z0)*dir.x - (x - x0)*dir.z]^2 + +//! [(x - x0)*dir.y - (y - y0)*dir.x]^2 +//! +//! First derivative of square vector product are: +//! Dx0 = 2*[(z - z0)*dir.x - (x - x0)*dir.z]*dir.z +//! -2*[(x - x0)*dir.y - (y - y0)*dir.x]*dir.y +//! Dy0 = -2*[(y - y0)*dir.z - (z - z0)*dir.y]*dir.z +//! +2*[(x - x0)*dir.y - (y - y0)*dir.x]*dir.x +//! Dz0 = 2*[(y - y0)*dir.z - (z - z0)*dir.y]*dir.y +//! -2*[(z - z0)*dir.x - (x - x0)*dir.z]*dir.x +//! +//! dF/dx0 : G1(...) = 2*Sum{[...]*Dx0} +//! dF/dy0 : G2(...) = 2*Sum{[...]*Dy0} +//! dF/dz0 : G3(...) = 2*Sum{[...]*Dz0} +//! dF/dR : G4(...) = -4*R*Sum[...] +//! [...] = [|(P(i) - Loc)^dir|^2 - R^2] +class GeomConvert_FuncCylinderLSDist : public math_MultipleVarFunctionWithGradient +{ +public: + + DEFINE_STANDARD_ALLOC + + //! Constructor. + Standard_EXPORT GeomConvert_FuncCylinderLSDist() {}; + + Standard_EXPORT GeomConvert_FuncCylinderLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints, + const gp_Dir& theDir); + + void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints) + { + myPoints = thePoints; + } + + void SetDir(const gp_Dir& theDir) + { + myDir = theDir; + } + + //! Number of variables. + Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE; + + //! Value. + Standard_EXPORT Standard_Boolean Value(const math_Vector& X,Standard_Real& F) Standard_OVERRIDE; + + //! Gradient. + Standard_EXPORT Standard_Boolean Gradient(const math_Vector& X,math_Vector& G) Standard_OVERRIDE; + + //! Value and gradient. + Standard_EXPORT Standard_Boolean Values(const math_Vector& X,Standard_Real& F,math_Vector& G) Standard_OVERRIDE; + +private: + + Handle(TColgp_HArray1OfXYZ) myPoints; + gp_Dir myDir; + +}; +#endif // _GeomConvert_FuncCylinderLSDist_HeaderFile diff --git a/src/GeomConvert/GeomConvert_FuncSphereLSDist.cxx b/src/GeomConvert/GeomConvert_FuncSphereLSDist.cxx new file mode 100644 index 0000000000..c2a5fe9594 --- /dev/null +++ b/src/GeomConvert/GeomConvert_FuncSphereLSDist.cxx @@ -0,0 +1,115 @@ +// Created on: 2016-05-10 +// Created by: Alexander MALYSHEV +// Copyright (c) 1995-1999 Matra Datavision +// Copyright (c) 1999-2016 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 + +//======================================================================= +//function : GeomConvert_FuncSphereLSDist +//purpose : +//======================================================================= +GeomConvert_FuncSphereLSDist::GeomConvert_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints): + myPoints(thePoints) +{ +} + +//======================================================================= +//function : NbVariables +//purpose : +//======================================================================= +Standard_Integer GeomConvert_FuncSphereLSDist::NbVariables () const +{ + return 4; +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= +Standard_Boolean GeomConvert_FuncSphereLSDist::Value(const math_Vector& X,Standard_Real& F) +{ + gp_XYZ aLoc(X(1), X(2), X(3)); + Standard_Real anR2 = X(4)*X(4); + + F = 0.; + Standard_Integer i; + for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) + { + Standard_Real d = (myPoints->Value(i) - aLoc).SquareModulus() - anR2; + F += d * d; + } + + return Standard_True; +} + +//======================================================================= +//function : Gradient +//purpose : +//======================================================================= +Standard_Boolean GeomConvert_FuncSphereLSDist::Gradient(const math_Vector& X,math_Vector& G) + +{ + gp_XYZ aLoc(X(1), X(2), X(3)); + Standard_Real anR = X(4), anR2 = anR * anR; + + G.Init(0.); + Standard_Integer i; + for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) + { + gp_XYZ dLoc = myPoints->Value(i) - aLoc; + Standard_Real d = dLoc.SquareModulus() - anR2; + G(1) += d * dLoc.X(); + G(2) += d * dLoc.Y(); + G(3) += d * dLoc.Z(); + G(4) += d; + } + G *= -4; + G(4) *= anR; + + return Standard_True; +} + +//======================================================================= +//function : Values +//purpose : +//======================================================================= +Standard_Boolean GeomConvert_FuncSphereLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G) +{ + gp_XYZ aLoc(X(1), X(2), X(3)); + Standard_Real anR = X(4), anR2 = anR * anR; + + G.Init(0.); + F = 0.; + Standard_Integer i; + for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) + { + gp_XYZ dLoc = myPoints->Value(i) - aLoc; + Standard_Real d = dLoc.SquareModulus() - anR2; + G(1) += d * dLoc.X(); + G(2) += d * dLoc.Y(); + G(3) += d * dLoc.Z(); + G(4) += d; + F += d * d; + } + G *= -4; + G(4) *= anR; + + return true; +} + diff --git a/src/GeomConvert/GeomConvert_FuncSphereLSDist.hxx b/src/GeomConvert/GeomConvert_FuncSphereLSDist.hxx new file mode 100644 index 0000000000..f6743e0f9c --- /dev/null +++ b/src/GeomConvert/GeomConvert_FuncSphereLSDist.hxx @@ -0,0 +1,77 @@ + +// Copyright (c) 1991-1999 Matra Datavision +// Copyright (c) 1999-2022 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 _GeomConvert_FuncSphereLSDist_HeaderFile +#define _GeomConvert_FuncSphereLSDist_HeaderFile + +#include +#include + +#include +#include +#include + +//! Function for search of sphere canonic parameters: coordinates of center and radius from set of moints +//! by least square method. +//! //! +//! The class inherits math_MultipleVarFunctionWithGradient and thus is intended +//! for use in math_BFGS algorithm. +//! +//! The criteria is: +//! F(x0, y0, z0, R) = Sum[(x(i) - x0)^2 + (y(i) - y0)^2 + (z(i) - z0)^2 - R^2]^2 => min, +//! x(i), y(i), z(i) - coordinates of sample points, x0, y0, z0, R - coordinates of center and radius of sphere, +//! which must be defined +//! +//! The first derivative are: +//! dF/dx0 : G1(x0, y0, z0, R) = -4*Sum{[...]*(x(i) - x0)} +//! dF/dy0 : G2(x0, y0, z0, R) = -4*Sum{[...]*(y(i) - y0)} +//! dF/dz0 : G3(x0, y0, z0, R) = -4*Sum{[...]*(z(i) - z0)} +//! dF/dR : G4(x0, y0, z0, R) = -4*R*Sum[...] +//! [...] = [(x(i) - x0)^2 + (y(i) - y0)^2 + (z(i) - z0)^2 - R^2] +//! +class GeomConvert_FuncSphereLSDist : public math_MultipleVarFunctionWithGradient +{ +public: + + DEFINE_STANDARD_ALLOC + + //! Constructor. + Standard_EXPORT GeomConvert_FuncSphereLSDist() {}; + + Standard_EXPORT GeomConvert_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints); + + void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints) + { + myPoints = thePoints; + } + + //! Number of variables. + Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE; + + //! Value. + Standard_EXPORT Standard_Boolean Value(const math_Vector& X,Standard_Real& F) Standard_OVERRIDE; + + //! Gradient. + Standard_EXPORT Standard_Boolean Gradient(const math_Vector& X,math_Vector& G) Standard_OVERRIDE; + + //! Value and gradient. + Standard_EXPORT Standard_Boolean Values(const math_Vector& X,Standard_Real& F,math_Vector& G) Standard_OVERRIDE; + +private: + + Handle(TColgp_HArray1OfXYZ) myPoints; + +}; +#endif // _GeomConvert_FuncSphereLSDist_HeaderFile diff --git a/src/GeomConvert/GeomConvert_SurfToAnaSurf.cxx b/src/GeomConvert/GeomConvert_SurfToAnaSurf.cxx index 37ed349ebb..7e946956c3 100644 --- a/src/GeomConvert/GeomConvert_SurfToAnaSurf.cxx +++ b/src/GeomConvert/GeomConvert_SurfToAnaSurf.cxx @@ -47,10 +47,20 @@ #include #include #include +#include +#include +#include +#include +#include +#include +//======================================================================= +//function : CheckVTrimForRevSurf +//purpose : //static method for checking surface of revolution //To avoid two-parts cone-like surface -static void CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSurf, +//======================================================================= +void GeomConvert_SurfToAnaSurf::CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSurf, Standard_Real& V1, Standard_Real& V2) { const Handle(Geom_Curve)& aBC = aRevSurf->BasisCurve(); @@ -96,10 +106,369 @@ static void CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSur } } +//======================================================================= +//function : TryCylinderCone +//purpose : +//static method to try create cylindrical or conical surface +//======================================================================= +Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::TryCylinerCone(const Handle(Geom_Surface)& theSurf, const Standard_Boolean theVCase, + const Handle(Geom_Curve)& theUmidiso, const Handle(Geom_Curve)& theVmidiso, + const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2, + const Standard_Real theToler) +{ + Handle(Geom_Surface) aNewSurf; + Standard_Real param1, param2, cf1, cf2, cl1, cl2, aGap1, aGap2; + Handle(Geom_Curve) firstiso, lastiso; + Handle(Geom_Circle) firstisocirc, lastisocirc, midisocirc; + gp_Dir isoline; + if (theVCase) { + param1 = theU1; param2 = theU2; + firstiso = theSurf->VIso(theV1); + lastiso = theSurf->VIso(theV2); + midisocirc = Handle(Geom_Circle)::DownCast(theVmidiso); + isoline = Handle(Geom_Line)::DownCast(theUmidiso)->Lin().Direction(); + } + else { + param1 = theV1; param2 = theV2; + firstiso = theSurf->UIso(theU1); + lastiso = theSurf->UIso(theU2); + midisocirc = Handle(Geom_Circle)::DownCast(theUmidiso); + isoline = Handle(Geom_Line)::DownCast(theVmidiso)->Lin().Direction(); + } + firstisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(firstiso, theToler, + param1, param2, cf1, cl1, aGap1)); + lastisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(lastiso, theToler, + param1, param2, cf2, cl2, aGap2)); + if (!firstisocirc.IsNull() || !lastisocirc.IsNull()) { + Standard_Real R1, R2, R3; + gp_Pnt P1, P2, P3; + if (!firstisocirc.IsNull()) { + R1 = firstisocirc->Circ().Radius(); + P1 = firstisocirc->Circ().Location(); + } + else { + R1 = 0; + P1 = firstiso->Value((firstiso->LastParameter() - firstiso->FirstParameter()) / 2); + } + R2 = midisocirc->Circ().Radius(); + P2 = midisocirc->Circ().Location(); + if (!lastisocirc.IsNull()) { + R3 = lastisocirc->Circ().Radius(); + P3 = lastisocirc->Circ().Location(); + } + else { + R3 = 0; + P3 = lastiso->Value((lastiso->LastParameter() - lastiso->FirstParameter()) / 2); + } + //cylinder + if (((Abs(R2 - R1)) < theToler) && ((Abs(R3 - R1)) < theToler) && + ((Abs(R3 - R2)) < theToler)) { + gp_Ax3 Axes(P1, gp_Dir(gp_Vec(P1, P3))); + aNewSurf = new Geom_CylindricalSurface(Axes, R1); + } + //cone + else if ((((Abs(R1)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R3)))) || + (((Abs(R3)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R1))))) { + Standard_Real radius; + gp_Ax3 Axes; + Standard_Real semiangle = + gp_Vec(isoline).Angle(gp_Vec(P3, P1)); + if (semiangle > M_PI / 2) semiangle = M_PI - semiangle; + if (R1 > R3) { + radius = R3; + Axes = gp_Ax3(P3, gp_Dir(gp_Vec(P3, P1))); + } + else { + radius = R1; + Axes = gp_Ax3(P1, gp_Dir(gp_Vec(P1, P3))); + } + aNewSurf = new Geom_ConicalSurface(Axes, semiangle, radius); + } + } + return aNewSurf; +} + +//======================================================================= +//function : GetCylByLS +//purpose : +//static method to create cylinrical surface using least square method +//======================================================================= +static void GetLSGap(const Handle(TColgp_HArray1OfXYZ)& thePoints, const gp_Ax3& thePos, + const Standard_Real theR, Standard_Real& theGap) +{ + theGap = 0.; + Standard_Integer i; + gp_XYZ aLoc = thePos.Location().XYZ(); + gp_Dir aDir = thePos.Direction(); + for (i = thePoints->Lower(); i <= thePoints->Upper(); ++i) + { + gp_Vec aD(thePoints->Value(i) - aLoc); + aD.Cross(aDir); + theGap = Max(theGap, Abs((aD.Magnitude() - theR))); + } + +} +Standard_Boolean GeomConvert_SurfToAnaSurf::GetCylByLS(const Handle(TColgp_HArray1OfXYZ)& thePoints, + const Standard_Real theTol, + gp_Ax3& thePos, Standard_Real& theR, + Standard_Real& theGap) +{ + + GetLSGap(thePoints, thePos, theR, theGap); + if (theGap <= Precision::Confusion()) + { + return Standard_True; + } + + Standard_Integer i; + + Standard_Integer aNbVar = 4; + + math_Vector aFBnd(1, aNbVar), aLBnd(1, aNbVar), aStartPoint(1, aNbVar); + + Standard_Real aRelDev = 0.2; //Customer can set parameters of sample surface + // with relative precision about aRelDev. + // For example, if radius of sample surface is R, + // it means, that "exact" vaue is in interav + //[R - aRelDev*R, R + aRelDev*R]. This intrrval is set + // for R as boundary values for dptimization algo. + + aStartPoint(1) = thePos.Location().X(); + aStartPoint(2) = thePos.Location().Y(); + aStartPoint(3) = thePos.Location().Z(); + aStartPoint(4) = theR; + Standard_Real aDR = aRelDev * theR; + Standard_Real aDXYZ = aDR; + for (i = 1; i <= 3; ++i) + { + aFBnd(i) = aStartPoint(i) - aDXYZ; + aLBnd(i) = aStartPoint(i) + aDXYZ; + } + aFBnd(4) = aStartPoint(4) - aDR; + aLBnd(4) = aStartPoint(4) + aDR; + + // + Standard_Real aTol = Precision::Confusion(); + math_MultipleVarFunction* aPFunc; + GeomConvert_FuncCylinderLSDist aFuncCyl(thePoints, thePos.Direction()); + aPFunc = (math_MultipleVarFunction*)&aFuncCyl; + // + math_Vector aSteps(1, aNbVar); + Standard_Integer aNbInt = 10; + for (i = 1; i <= aNbVar; ++i) + { + aSteps(i) = (aLBnd(i) - aFBnd(i)) / aNbInt; + } + math_PSO aGlobSolver(aPFunc, aFBnd, aLBnd, aSteps); + Standard_Real aLSDist; + aGlobSolver.Perform(aSteps, aLSDist, aStartPoint); + // + gp_Pnt aLoc(aStartPoint(1), aStartPoint(2), aStartPoint(3)); + thePos.SetLocation(aLoc); + theR = aStartPoint(4); + + GetLSGap(thePoints, thePos, theR, theGap); + if (theGap <= aTol) + { + return Standard_True; + } + // + math_Matrix aDirMatrix(1, aNbVar, 1, aNbVar, 0.0); + for (i = 1; i <= aNbVar; i++) + aDirMatrix(i, i) = 1.0; + + //Set search direction for location to be perpendicular to axis to avoid + //seaching along axis + const gp_Dir aDir = thePos.Direction(); + gp_Pln aPln(thePos.Location(), aDir); + gp_Dir aUDir = aPln.Position().XDirection(); + gp_Dir aVDir = aPln.Position().YDirection(); + for (i = 1; i <= 3; ++i) + { + aDirMatrix(i, 1) = aUDir.Coord(i); + aDirMatrix(i, 2) = aVDir.Coord(i); + gp_Dir aUVDir(aUDir.XYZ() + aVDir.XYZ()); + aDirMatrix(i, 3) = aUVDir.Coord(i); + } + + math_Powell aSolver(*aPFunc, aTol); + aSolver.Perform(*aPFunc, aStartPoint, aDirMatrix); + + if (aSolver.IsDone()) + { + gp_Ax3 aPos2 = thePos; + aSolver.Location(aStartPoint); + aLoc.SetCoord(aStartPoint(1), aStartPoint(2), aStartPoint(3)); + aPos2.SetLocation(aLoc); + Standard_Real anR2 = aStartPoint(4), aGap2 = 0.; + // + GetLSGap(thePoints, aPos2, anR2, aGap2); + // + if (aGap2 < theGap) + { + theGap = aGap2; + thePos = aPos2; + theR = anR2; + } + } + if (theGap <= theTol) + { + return Standard_True; + } + return Standard_False; +} + +//======================================================================= +//function : TryCylinderByGaussField +//purpose : +//static method to try create cylinrical surface based on its Gauss field +//======================================================================= +Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::TryCylinderByGaussField(const Handle(Geom_Surface)& theSurf, + const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2, + const Standard_Real theToler, const Standard_Integer theNbU, const Standard_Integer theNbV, + const Standard_Boolean theLeastSquare) +{ + Handle(Geom_Surface) aNewSurf; + Standard_Real du = (theU2 - theU1) / theNbU, dv = (theV2 - theV1) / theNbV; + Standard_Real aSigmaR = 0.; + Standard_Real aTol = 100. * theToler; + TColStd_Array1OfReal anRs(1, theNbU*theNbV); + Handle(TColgp_HArray1OfXYZ) aPoints; + if (theLeastSquare) + { + aPoints = new TColgp_HArray1OfXYZ(1, theNbU*theNbU); + } + // + GeomLProp_SLProps aProps(theSurf, 2, Precision::Confusion()); + Standard_Real anAvMaxCurv = 0., anAvMinCurv = 0., anAvR = 0, aSign = 1.; + gp_XYZ anAvDir; + gp_Dir aMinD, aMaxD; + Standard_Integer i, j, n = 0; + Standard_Real anU, aV; + for (i = 1, anU = theU1 + du / 2.; i <= theNbU; ++i, anU += du) + { + for (j = 1, aV = theV1 + dv / 2.; j <= theNbV; ++j, aV += dv) + { + aProps.SetParameters(anU, aV); + if (!aProps.IsCurvatureDefined()) + { + return aNewSurf; + } + if (aProps.IsUmbilic()) + { + return aNewSurf; + } + ++n; + Standard_Real aMinCurv = aProps.MinCurvature(); + Standard_Real aMaxCurv = aProps.MaxCurvature(); + Standard_Real aGaussCurv = Abs(aProps.GaussianCurvature()); + Standard_Real aK1 = Sqrt(aGaussCurv); + if (aK1 > theToler ) + { + return aNewSurf; + } + gp_XYZ aD; + aProps.CurvatureDirections(aMaxD, aMinD); + aMinCurv = Abs(aMinCurv); + aMaxCurv = Abs(aMaxCurv); + if (aMinCurv > aMaxCurv) + { + //aMinCurv < 0; + aSign = -1.; + std::swap(aMinCurv, aMaxCurv); + gp_Dir aDummy = aMaxD; + aMaxD = aMinD; + aMinD = aDummy; + } + Standard_Real anR = 1. / aMaxCurv; + Standard_Real anR2 = anR * anR; + anRs(n) = anR; + // + if (n > 1) + { + if (Abs(aMaxCurv - anAvMaxCurv / (n - 1)) > aTol / anR2) + { + return aNewSurf; + } + if (Abs(aMinCurv - anAvMinCurv / (n - 1)) > aTol) + { + return aNewSurf; + } + } + aD = aMinD.XYZ(); + anAvR += anR; + anAvDir += aD; + anAvMaxCurv += aMaxCurv; + anAvMinCurv += aMinCurv; + if (theLeastSquare) + { + aPoints->SetValue(n, aProps.Value().XYZ()); + } + } + } + anAvMaxCurv /= n; + anAvMinCurv /= n; + anAvR /= n; + anAvDir /= n; + // + if (Abs(anAvMinCurv) > theToler) + { + return aNewSurf; + } + // + for (i = 1; i <= n; ++i) + { + Standard_Real d = (anRs(i) - anAvR); + aSigmaR += d * d; + } + aSigmaR = Sqrt(aSigmaR / n); + aTol = 3.*aSigmaR / Sqrt(n); + if (aTol > 100. * theToler) + { + return aNewSurf; + } + aProps.SetParameters(theU1, theV1); + if (!aProps.IsCurvatureDefined()) + { + return aNewSurf; + } + gp_Dir aNorm = aProps.Normal(); + gp_Pnt aLoc = aProps.Value(); + gp_Dir anAxD(anAvDir); + gp_Vec aT(aSign*anAvR*aNorm.XYZ()); + aLoc.Translate(aT); + gp_Ax1 anAx1(aLoc, anAxD); + gp_Cylinder aCyl; + aCyl.SetAxis(anAx1); + aCyl.SetRadius(anAvR); + + if (theLeastSquare) + { + gp_Ax3 aPos = aCyl.Position(); + Standard_Real anR = aCyl.Radius(); + Standard_Real aGap = 0.; + Standard_Boolean IsDone = GetCylByLS(aPoints, theToler, aPos, anR, aGap); + if (IsDone) + { + aCyl.SetPosition(aPos); + aCyl.SetRadius(anR); + } + } + + aNewSurf = new Geom_CylindricalSurface(aCyl); + + return aNewSurf; +} + +//======================================================================= +//function : TryTorusSphere +//purpose : // static method to try create toroidal surface. // In case = Standard_True try to use V isoline radius as minor radaius. -static Handle(Geom_Surface) TryTorusSphere(const Handle(Geom_Surface)& theSurf, +//======================================================================= + +Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::TryTorusSphere(const Handle(Geom_Surface)& theSurf, const Handle(Geom_Circle)& circle, const Handle(Geom_Circle)& otherCircle, const Standard_Real Param1, @@ -181,9 +550,14 @@ static Handle(Geom_Surface) TryTorusSphere(const Handle(Geom_Surface)& theSurf, return newSurface; } -static Standard_Real ComputeGap(const Handle(Geom_Surface)& theSurf, +//======================================================================= +//function : ComputeGap +//purpose : +//======================================================================= + +Standard_Real GeomConvert_SurfToAnaSurf::ComputeGap(const Handle(Geom_Surface)& theSurf, const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2, - const Handle(Geom_Surface) theNewSurf, const Standard_Real theTol = RealLast()) + const Handle(Geom_Surface) theNewSurf, const Standard_Real theTol) { GeomAdaptor_Surface aGAS(theNewSurf); GeomAbs_SurfaceType aSType = aGAS.GetType(); @@ -228,7 +602,7 @@ static Standard_Real ComputeGap(const Handle(Geom_Surface)& theSurf, Standard_Real DU2 = DU / 2., DV2 = DV / 2.; for (j = 1; (j < NP) && onSurface; j++) { Standard_Real V = theV1 + DV*(j - 1) + DV2; - for (i = 1; i <= NP; i++) { + for (i = 1; i < NP; i++) { Standard_Real U = theU1 + DU*(i - 1) + DU2; theSurf->D0(U, V, P3d); @@ -384,7 +758,9 @@ Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::ConvertToAnalytical(const Standa // Standard_Real toler = InitialToler; Handle(Geom_Surface) newSurf[5]; - Standard_Real dd[5] = { -1., -1., -1., -1., -1 }; + Standard_Real dd[5] = { RealLast(), RealLast(), RealLast(), RealLast(), RealLast() }; + GeomAbs_SurfaceType aSTypes[5] = { GeomAbs_Plane, GeomAbs_Cylinder, + GeomAbs_Cone, GeomAbs_Sphere, GeomAbs_Torus }; //Check boundaries Standard_Real U1, U2, V1, V2; @@ -481,183 +857,136 @@ Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::ConvertToAnalytical(const Standa //convert middle uiso and viso to canonical representation Standard_Real VMid = 0.5*(V1 + V2); Standard_Real UMid = 0.5*(U1 + U2); - Handle(Geom_Surface) TrSurf = aTempS; - if(!aDoSegment) - TrSurf = new Geom_RectangularTrimmedSurface(aTempS, U1, U2, V1, V2); + // Handle(Geom_Surface) TrSurf = aTempS; - Handle(Geom_Curve) UIso = TrSurf->UIso(UMid); - Handle(Geom_Curve) VIso = TrSurf->VIso(VMid); + Handle(Geom_Curve) UIso = aTempS->UIso(UMid); + Handle(Geom_Curve) VIso = aTempS->VIso(VMid); Standard_Real cuf, cul, cvf, cvl, aGap1, aGap2; Handle(Geom_Curve) umidiso = GeomConvert_CurveToAnaCurve::ComputeCurve(UIso, toler, V1, V2, cuf, cul, aGap1); Handle(Geom_Curve) vmidiso = GeomConvert_CurveToAnaCurve::ComputeCurve(VIso, toler, U1, U2, cvf, cvl, aGap2); - if (umidiso.IsNull() || vmidiso.IsNull()) { - return newSurf[isurf]; - } + if (!umidiso.IsNull() && !vmidiso.IsNull()) + { - // - Standard_Boolean VCase = Standard_False; + // + Standard_Boolean VCase = Standard_False; - if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle))) - { - aToroidSphere = Standard_True; - if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Cylinder || myTarget == GeomAbs_Cone)) + if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle))) { - isurf = 1; - myGap = dd[isurf]; - return newSurf[isurf]; + aToroidSphere = Standard_True; + if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Cylinder || myTarget == GeomAbs_Cone)) + { + isurf = 1; + myGap = dd[isurf]; + return newSurf[isurf]; + } + isurf = 3; // set sphere } - isurf = 3; // set sphere - } - else if (umidiso->IsKind(STANDARD_TYPE(Geom_Line)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle))) { - aCylinderConus = Standard_True; VCase = Standard_True; - if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus)) - { - isurf = 3; - myGap = dd[isurf]; - return newSurf[isurf]; + else if (umidiso->IsKind(STANDARD_TYPE(Geom_Line)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Circle))) { + aCylinderConus = Standard_True; VCase = Standard_True; + if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus)) + { + isurf = 3; + myGap = dd[isurf]; + return newSurf[isurf]; + } + isurf = 1;// set cylinder } - isurf = 1;// set cylinder - } - else if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Line))) - { - aCylinderConus = Standard_True; - if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus)) + else if (umidiso->IsKind(STANDARD_TYPE(Geom_Circle)) && vmidiso->IsKind(STANDARD_TYPE(Geom_Line))) { - isurf = 3; - myGap = dd[isurf]; - return newSurf[isurf]; + aCylinderConus = Standard_True; + if (myConvType == GeomConvert_Target && (myTarget == GeomAbs_Sphere || myTarget == GeomAbs_Torus)) + { + isurf = 3; + myGap = dd[isurf]; + return newSurf[isurf]; + } + isurf = 1;// set cylinder } - isurf = 1;// set cylinder - } - Standard_Real cl = 0.0; - //case of torus-sphere - if (aToroidSphere) { - isurf = 3; // Set spherical surface - Handle(Geom_Circle) Ucircle = Handle(Geom_Circle)::DownCast(umidiso); - Handle(Geom_Circle) Vcircle = Handle(Geom_Circle)::DownCast(vmidiso); - // torus - // try when V isolines is with same radius - Handle(Geom_Surface) anObject = - TryTorusSphere(mySurf, Vcircle, Ucircle, V1, V2, U1, U2, toler, Standard_True); - if (anObject.IsNull()) // try when U isolines is with same radius - anObject = TryTorusSphere(mySurf, Ucircle, Vcircle, U1, U2, V1, V2, toler, Standard_False); + //case of torus-sphere + if (aToroidSphere) { - if (!anObject.IsNull()) - { - if (anObject->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) + isurf = 3; // Set spherical surface + + Handle(Geom_Circle) Ucircle = Handle(Geom_Circle)::DownCast(umidiso); + Handle(Geom_Circle) Vcircle = Handle(Geom_Circle)::DownCast(vmidiso); + // torus + // try when V isolines is with same radius + Handle(Geom_Surface) anObject = + TryTorusSphere(mySurf, Vcircle, Ucircle, V1, V2, U1, U2, toler, Standard_True); + if (anObject.IsNull()) // try when U isolines is with same radius + anObject = TryTorusSphere(mySurf, Ucircle, Vcircle, U1, U2, V1, V2, toler, Standard_False); + + if (!anObject.IsNull()) { - isurf = 4; // set torus - } - newSurf[isurf] = anObject; - } - else - { - myGap = dd[isurf]; - } - } - //case of cone - cylinder - else if (aCylinderConus) { - Standard_Real param1, param2, cf1, cf2; - Handle(Geom_Curve) firstiso, lastiso; - Handle(Geom_Circle) firstisocirc, lastisocirc, midisocirc; - gp_Dir isoline; - if (VCase) { - param1 = U1; param2 = U2; - firstiso = TrSurf->VIso(V1); - lastiso = TrSurf->VIso(V2); - midisocirc = Handle(Geom_Circle)::DownCast(vmidiso); - isoline = Handle(Geom_Line)::DownCast(umidiso)->Lin().Direction(); - } - else { - param1 = V1; param2 = V2; - firstiso = TrSurf->UIso(U1); - lastiso = TrSurf->UIso(U2); - midisocirc = Handle(Geom_Circle)::DownCast(umidiso); - isoline = Handle(Geom_Line)::DownCast(vmidiso)->Lin().Direction(); - } - firstisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(firstiso, toler, param1, param2, cf1, cl, aGap1)); - lastisocirc = Handle(Geom_Circle)::DownCast(GeomConvert_CurveToAnaCurve::ComputeCurve(lastiso, toler, param1, param2, cf2, cl, aGap2)); - if (!firstisocirc.IsNull() || !lastisocirc.IsNull()) { - Standard_Real R1, R2, R3; - gp_Pnt P1, P2, P3; - if (!firstisocirc.IsNull()) { - R1 = firstisocirc->Circ().Radius(); - P1 = firstisocirc->Circ().Location(); - } - else { - R1 = 0; - P1 = firstiso->Value((firstiso->LastParameter() - firstiso->FirstParameter()) / 2); - } - R2 = midisocirc->Circ().Radius(); - P2 = midisocirc->Circ().Location(); - if (!lastisocirc.IsNull()) { - R3 = lastisocirc->Circ().Radius(); - P3 = lastisocirc->Circ().Location(); - } - else { - R3 = 0; - P3 = lastiso->Value((lastiso->LastParameter() - lastiso->FirstParameter()) / 2); - } - //cylinder - if (((Abs(R2 - R1)) < toler) && ((Abs(R3 - R1)) < toler) && - ((Abs(R3 - R2)) < toler)) { - isurf = 1; - gp_Ax3 Axes(P1, gp_Dir(gp_Vec(P1, P3))); - Handle(Geom_CylindricalSurface) anObject = - new Geom_CylindricalSurface(Axes, R1); - if (myConvType == GeomConvert_Target && myTarget != GeomAbs_Cylinder) + if (anObject->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) { - return newSurf[isurf]; + isurf = 4; // set torus } newSurf[isurf] = anObject; - } - //cone - else if ((((Abs(R1)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R3)))) || - (((Abs(R3)) > (Abs(R2))) && ((Abs(R2)) > (Abs(R1))))) { - Standard_Real radius; - gp_Ax3 Axes; - Standard_Real semiangle = - gp_Vec(isoline).Angle(gp_Vec(P3, P1)); - if (semiangle>M_PI / 2) semiangle = M_PI - semiangle; - if (R1 > R3) { - radius = R3; - Axes = gp_Ax3(P3, gp_Dir(gp_Vec(P3, P1))); + if (myConvType == GeomConvert_Target && (myTarget != aSTypes[isurf])) + { + myGap = RealLast(); + return NULL; } - else { - radius = R1; - Axes = gp_Ax3(P1, gp_Dir(gp_Vec(P1, P3))); + } + else + { + myGap = dd[isurf]; + } + } + //case of cone - cylinder + else if (aCylinderConus) { + isurf = 1; //set cylindrical surface + Handle(Geom_Surface) anObject = TryCylinerCone(aTempS, VCase, umidiso, vmidiso, + U1, U2, V1, V2, toler); + if (!anObject.IsNull()) + { + if (anObject->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) + { + isurf = 2; // set conical surface } - Handle(Geom_ConicalSurface) anObject = - new Geom_ConicalSurface(Axes, semiangle, radius); - isurf = 2; - if (myConvType == GeomConvert_Target && myTarget != GeomAbs_Cone) + if (myConvType == GeomConvert_Target && (myTarget != aSTypes[isurf])) { - return newSurf[isurf]; + myGap = RealLast(); + return NULL; } newSurf[isurf] = anObject; } + else + { + myGap = dd[isurf]; + } } - else + } + //Additional checking for case of cylinder + if (!aCylinderConus && !aToroidSphere) + { + //Try cylinder using Gauss field + Standard_Integer aNbU = 7, aNbV = 7; + Standard_Boolean aLeastSquare = Standard_True; + Handle(Geom_Surface) anObject = TryCylinderByGaussField(aTempS, U1, U2, V1, V2, toler, + aNbU, aNbV, aLeastSquare); + if (!anObject.IsNull()) { - myGap = dd[isurf]; + isurf = 1; + newSurf[isurf] = anObject; } } + // //--------------------------------------------------------------------- // verification //--------------------------------------------------------------------- - GeomAbs_SurfaceType aSTypes[5] = { GeomAbs_Plane, GeomAbs_Cylinder, - GeomAbs_Cone, GeomAbs_Sphere, GeomAbs_Torus }; Standard_Integer imin = -1; Standard_Real aDmin = RealLast(); for (isurf = 0; isurf < 5; ++isurf) { if (newSurf[isurf].IsNull()) continue; - dd[isurf] = ComputeGap(TrSurf, U1, U2, V1, V2, newSurf[isurf], toler); + dd[isurf] = ComputeGap(aTempS, U1, U2, V1, V2, newSurf[isurf], toler); if (dd[isurf] <= toler) { if (myConvType == GeomConvert_Simplest || (myConvType == GeomConvert_Target && myTarget == aSTypes[isurf])) @@ -682,7 +1011,7 @@ Handle(Geom_Surface) GeomConvert_SurfToAnaSurf::ConvertToAnalytical(const Standa return newSurf[imin]; } - return newSurf[0]; + return NULL; } //======================================================================= diff --git a/src/GeomConvert/GeomConvert_SurfToAnaSurf.hxx b/src/GeomConvert/GeomConvert_SurfToAnaSurf.hxx index 016956590e..ee333f54aa 100644 --- a/src/GeomConvert/GeomConvert_SurfToAnaSurf.hxx +++ b/src/GeomConvert/GeomConvert_SurfToAnaSurf.hxx @@ -25,8 +25,10 @@ #include #include #include +#include class Geom_Surface; - +class Geom_SurfaceOfRevolution; +class Geom_Circle; //! Converts a surface to the analitical form with given //! precision. Conversion is done only the surface is bspline @@ -75,6 +77,48 @@ public: //! Returns true, if surface is canonical Standard_EXPORT static Standard_Boolean IsCanonical (const Handle(Geom_Surface)& S); +private: + //!static method for checking surface of revolution + //!To avoid two-parts cone-like surface + static void CheckVTrimForRevSurf(const Handle(Geom_SurfaceOfRevolution)& aRevSurf, + Standard_Real& V1, Standard_Real& V2); + + //!static method to try create cylindrical or conical surface + static Handle(Geom_Surface) TryCylinerCone(const Handle(Geom_Surface)& theSurf, const Standard_Boolean theVCase, + const Handle(Geom_Curve)& theUmidiso, const Handle(Geom_Curve)& theVmidiso, + const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2, + const Standard_Real theToler); + + //!static method to try create cylinrical surface using least square method + static Standard_Boolean GetCylByLS(const Handle(TColgp_HArray1OfXYZ)& thePoints, + const Standard_Real theTol, + gp_Ax3& thePos, Standard_Real& theR, + Standard_Real& theGap); + + //!static method to try create cylinrical surface based on its Gauss field + static Handle(Geom_Surface) TryCylinderByGaussField(const Handle(Geom_Surface)& theSurf, + const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2, + const Standard_Real theToler, const Standard_Integer theNbU = 20, const Standard_Integer theNbV = 20, + const Standard_Boolean theLeastSquare = Standard_False); + + //! static method to try create toroidal surface. + //! In case = Standard_True try to use V isoline radius as minor radaius. + static Handle(Geom_Surface) TryTorusSphere(const Handle(Geom_Surface)& theSurf, + const Handle(Geom_Circle)& circle, + const Handle(Geom_Circle)& otherCircle, + const Standard_Real Param1, + const Standard_Real Param2, + const Standard_Real aParam1ToCrv, + const Standard_Real aParam2ToCrv, + const Standard_Real toler, + const Standard_Boolean isTryUMajor); + + static Standard_Real ComputeGap(const Handle(Geom_Surface)& theSurf, + const Standard_Real theU1, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV2, + const Handle(Geom_Surface) theNewSurf, const Standard_Real theTol = RealLast()); + + + protected: diff --git a/src/ShapeAnalysis/FILES b/src/ShapeAnalysis/FILES index d9510dcbe9..1b4ea4c918 100755 --- a/src/ShapeAnalysis/FILES +++ b/src/ShapeAnalysis/FILES @@ -46,9 +46,3 @@ ShapeAnalysis_WireVertex.cxx ShapeAnalysis_WireVertex.hxx ShapeAnalysis_CanonicalRecognition.cxx ShapeAnalysis_CanonicalRecognition.hxx -ShapeAnalysis_FuncSphereLSDist.cxx -ShapeAnalysis_FuncSphereLSDist.hxx -ShapeAnalysis_FuncCylinderLSDist.cxx -ShapeAnalysis_FuncCylinderLSDist.hxx -ShapeAnalysis_FuncConeLSDist.cxx -ShapeAnalysis_FuncConeLSDist.hxx diff --git a/src/ShapeAnalysis/ShapeAnalysis_CanonicalRecognition.cxx b/src/ShapeAnalysis/ShapeAnalysis_CanonicalRecognition.cxx index 3abf8c12b5..9fa226eb37 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_CanonicalRecognition.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_CanonicalRecognition.cxx @@ -51,9 +51,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -834,9 +834,9 @@ Standard_Boolean ShapeAnalysis_CanonicalRecognition::GetSurfaceByLS(const TopoDS // Standard_Real aTol = Precision::Confusion(); math_MultipleVarFunction* aPFunc; - ShapeAnalysis_FuncSphereLSDist aFuncSph(aPoints); - ShapeAnalysis_FuncCylinderLSDist aFuncCyl(aPoints, thePos.Direction()); - ShapeAnalysis_FuncConeLSDist aFuncCon(aPoints, thePos.Direction()); + GeomConvert_FuncSphereLSDist aFuncSph(aPoints); + GeomConvert_FuncCylinderLSDist aFuncCyl(aPoints, thePos.Direction()); + GeomConvert_FuncConeLSDist aFuncCon(aPoints, thePos.Direction()); if (theTarget == GeomAbs_Sphere) { aPFunc = (math_MultipleVarFunction*)&aFuncSph; diff --git a/src/ShapeAnalysis/ShapeAnalysis_FuncConeLSDist.cxx b/src/ShapeAnalysis/ShapeAnalysis_FuncConeLSDist.cxx deleted file mode 100644 index 865d9e872a..0000000000 --- a/src/ShapeAnalysis/ShapeAnalysis_FuncConeLSDist.cxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2022 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 - -//======================================================================= -//function : ShapeAnalysis_FuncConeLSDist -//purpose : -//======================================================================= -ShapeAnalysis_FuncConeLSDist::ShapeAnalysis_FuncConeLSDist( - const Handle(TColgp_HArray1OfXYZ)& thePoints, - const gp_Dir& theDir): - myPoints(thePoints), myDir(theDir) -{ -} - -//======================================================================= -//function : NbVariables -//purpose : -//======================================================================= -Standard_Integer ShapeAnalysis_FuncConeLSDist::NbVariables () const -{ - return 5; -} - -//======================================================================= -//function : Value -//purpose : -//======================================================================= -Standard_Boolean ShapeAnalysis_FuncConeLSDist::Value(const math_Vector& X, Standard_Real& F) -{ - gp_Pnt aLoc(X(1), X(2), X(3)); - Standard_Real aSemiAngle = X(4), anR = X(5); - gp_Ax3 aPos(aLoc, myDir); - - F = 0.; - Standard_Integer i; - for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) - { - Standard_Real u, v; - gp_Pnt aPi(myPoints->Value(i)); - ElSLib::ConeParameters(aPos, anR, aSemiAngle, aPi, u, v); - gp_Pnt aPp; - ElSLib::ConeD0(u, v, aPos, anR, aSemiAngle, aPp); - F += aPi.SquareDistance(aPp); - } - - return Standard_True; -} - - diff --git a/src/ShapeAnalysis/ShapeAnalysis_FuncConeLSDist.hxx b/src/ShapeAnalysis/ShapeAnalysis_FuncConeLSDist.hxx deleted file mode 100644 index 381b86cc3f..0000000000 --- a/src/ShapeAnalysis/ShapeAnalysis_FuncConeLSDist.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 1991-1999 Matra Datavision -// Copyright (c) 1999-2022 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 _ShapeAnalysis_FuncConeLSDist_HeaderFile -#define _ShapeAnalysis_FuncConeLSDist_HeaderFile - -#include -#include - -#include -#include -#include -#include - -//! Function for search of Cone canonic parameters: coordinates of center local coordinate system, -//! direction of axis, radius and semi-angle from set of points -//! by least square method. -//! -//! -class ShapeAnalysis_FuncConeLSDist : public math_MultipleVarFunction -{ -public: - - DEFINE_STANDARD_ALLOC - - //! Constructor. - Standard_EXPORT ShapeAnalysis_FuncConeLSDist() {}; - - Standard_EXPORT ShapeAnalysis_FuncConeLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints, - const gp_Dir& theDir); - - void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints) - { - myPoints = thePoints; - } - - void SetDir(const gp_Dir& theDir) - { - myDir = theDir; - } - - //! Number of variables. - Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE; - - //! Value. - Standard_EXPORT Standard_Boolean Value(const math_Vector& X,Standard_Real& F) Standard_OVERRIDE; - - -private: - - Handle(TColgp_HArray1OfXYZ) myPoints; - gp_Dir myDir; - -}; -#endif // _ShapeAnalysis_FuncConeLSDist_HeaderFile diff --git a/src/ShapeAnalysis/ShapeAnalysis_FuncCylinderLSDist.cxx b/src/ShapeAnalysis/ShapeAnalysis_FuncCylinderLSDist.cxx deleted file mode 100644 index 681bef12f2..0000000000 --- a/src/ShapeAnalysis/ShapeAnalysis_FuncCylinderLSDist.cxx +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2022 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 - -//======================================================================= -//function : ShapeAnalysis_FuncCylinderLSDist -//purpose : -//======================================================================= -ShapeAnalysis_FuncCylinderLSDist::ShapeAnalysis_FuncCylinderLSDist( - const Handle(TColgp_HArray1OfXYZ)& thePoints, - const gp_Dir& theDir): - myPoints(thePoints), myDir(theDir) -{ -} - -//======================================================================= -//function : NbVariables -//purpose : -//======================================================================= -Standard_Integer ShapeAnalysis_FuncCylinderLSDist::NbVariables () const -{ - return 4; -} - -//======================================================================= -//function : Value -//purpose : -//======================================================================= -Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Value(const math_Vector& X,Standard_Real& F) -{ - gp_XYZ aLoc(X(1), X(2), X(3)); - Standard_Real anR2 = X(4)*X(4); - - F = 0.; - Standard_Integer i; - for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) - { - gp_Vec aV(myPoints->Value(i) - aLoc); - Standard_Real aD2 = aV.CrossSquareMagnitude(myDir); - Standard_Real d = aD2 - anR2; - F += d * d; - } - - return Standard_True; -} - -//======================================================================= -//function : Gradient -//purpose : -//======================================================================= -Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Gradient(const math_Vector& X,math_Vector& G) - -{ - gp_XYZ aLoc(X(1), X(2), X(3)); - Standard_Real anR = X(4), anR2 = anR * anR; - Standard_Real x = myDir.X(), y = myDir.Y(), z = myDir.Z(); - G.Init(0.); - - Standard_Integer i; - for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) - { - gp_Vec aV(myPoints->Value(i) - aLoc); - Standard_Real aD2 = aV.CrossSquareMagnitude(myDir); - Standard_Real d = aD2 - anR2; - Standard_Real Dx0 = 2.*(aV.Z()*x - aV.X()*z)*z - -2.*(aV.X()*y - aV.Y()*x)*y; - Standard_Real Dy0 = -2.*(aV.Y()*z - aV.Z()*y)*z - +2.*(aV.X()*y - aV.Y()*x)*x; - Standard_Real Dz0 = 2.*(aV.Y()*z - aV.Z()*y)*y - -2.*(aV.Z()*x - aV.X()*z)*x; - - G(1) += d * Dx0; - G(2) += d * Dy0; - G(3) += d * Dz0; - // - G(4) += d; - } - - G *= 2; - G(6) *= -2.*anR; - - return Standard_True; -} - -//======================================================================= -//function : Values -//purpose : -//======================================================================= -Standard_Boolean ShapeAnalysis_FuncCylinderLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G) -{ - gp_XYZ aLoc(X(1), X(2), X(3)); - Standard_Real anR = X(4), anR2 = anR * anR; - Standard_Real x = myDir.X(), y = myDir.Y(), z = myDir.Z(); - - F = 0.; - G.Init(0.); - Standard_Integer i; - for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) - { - gp_Vec aV(myPoints->Value(i) - aLoc); - Standard_Real aD2 = aV.CrossSquareMagnitude(myDir); - Standard_Real d = aD2 - anR2; - Standard_Real Dx0 = 2.*(aV.Z()*x - aV.X()*z)*z - - 2.*(aV.X()*y - aV.Y()*x)*y; - Standard_Real Dy0 = -2.*(aV.Y()*z - aV.Z()*y)*z - + 2.*(aV.X()*y - aV.Y()*x)*x; - Standard_Real Dz0 = 2.*(aV.Y()*z - aV.Z()*y)*y - - 2.*(aV.Z()*x - aV.X()*z)*x; - - G(1) += d * Dx0; - G(2) += d * Dy0; - G(3) += d * Dz0; - // - G(4) += d; - // - F += d * d; - } - - G *= 2; - G(4) *= -2.*anR; - - return true; -} - diff --git a/src/ShapeAnalysis/ShapeAnalysis_FuncCylinderLSDist.hxx b/src/ShapeAnalysis/ShapeAnalysis_FuncCylinderLSDist.hxx deleted file mode 100644 index 3375e522e7..0000000000 --- a/src/ShapeAnalysis/ShapeAnalysis_FuncCylinderLSDist.hxx +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 1991-1999 Matra Datavision -// Copyright (c) 1999-2022 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 _ShapeAnalysis_FuncCylinderLSDist_HeaderFile -#define _ShapeAnalysis_FuncCylinderLSDist_HeaderFile - -#include -#include - -#include -#include -#include -#include - -//! Function for search of cylinder canonic parameters: coordinates of center local coordinate system, -//! direction of axis and radius from set of points -//! by least square method. -//! -//! The class inherits math_MultipleVarFunctionWithGradient and thus is intended -//! for use in math_BFGS algorithm. -//! -//! Parametrisation: -//! Cylinder is defined by its axis and radius. Axis is defined by 3 cartesian coordinats it location x0, y0, z0 -//! and direction, which is constant and set by user: -//! dir.x, dir.y, dir.z -//! The criteria is: -//! F(x0, y0, z0, theta, phi, R) = Sum[|(P(i) - Loc)^dir|^2 - R^2]^2 => min -//! P(i) is i-th sample point, Loc, dir - axis location and direction, R - radius -//! -//! The square vector product |(P(i) - Loc)^dir|^2 is: -//! -//! [(y - y0)*dir.z - (z - z0)*dir.y]^2 + -//! [(z - z0)*dir.x - (x - x0)*dir.z]^2 + -//! [(x - x0)*dir.y - (y - y0)*dir.x]^2 -//! -//! First derivative of square vector product are: -//! Dx0 = 2*[(z - z0)*dir.x - (x - x0)*dir.z]*dir.z -//! -2*[(x - x0)*dir.y - (y - y0)*dir.x]*dir.y -//! Dy0 = -2*[(y - y0)*dir.z - (z - z0)*dir.y]*dir.z -//! +2*[(x - x0)*dir.y - (y - y0)*dir.x]*dir.x -//! Dz0 = 2*[(y - y0)*dir.z - (z - z0)*dir.y]*dir.y -//! -2*[(z - z0)*dir.x - (x - x0)*dir.z]*dir.x -//! -//! dF/dx0 : G1(...) = 2*Sum{[...]*Dx0} -//! dF/dy0 : G2(...) = 2*Sum{[...]*Dy0} -//! dF/dz0 : G3(...) = 2*Sum{[...]*Dz0} -//! dF/dR : G4(...) = -4*R*Sum[...] -//! [...] = [|(P(i) - Loc)^dir|^2 - R^2] -class ShapeAnalysis_FuncCylinderLSDist : public math_MultipleVarFunctionWithGradient -{ -public: - - DEFINE_STANDARD_ALLOC - - //! Constructor. - Standard_EXPORT ShapeAnalysis_FuncCylinderLSDist() {}; - - Standard_EXPORT ShapeAnalysis_FuncCylinderLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints, - const gp_Dir& theDir); - - void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints) - { - myPoints = thePoints; - } - - void SetDir(const gp_Dir& theDir) - { - myDir = theDir; - } - - //! Number of variables. - Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE; - - //! Value. - Standard_EXPORT Standard_Boolean Value(const math_Vector& X,Standard_Real& F) Standard_OVERRIDE; - - //! Gradient. - Standard_EXPORT Standard_Boolean Gradient(const math_Vector& X,math_Vector& G) Standard_OVERRIDE; - - //! Value and gradient. - Standard_EXPORT Standard_Boolean Values(const math_Vector& X,Standard_Real& F,math_Vector& G) Standard_OVERRIDE; - -private: - - Handle(TColgp_HArray1OfXYZ) myPoints; - gp_Dir myDir; - -}; -#endif // _ShapeAnalysis_FuncCylinderLSDist_HeaderFile diff --git a/src/ShapeAnalysis/ShapeAnalysis_FuncSphereLSDist.cxx b/src/ShapeAnalysis/ShapeAnalysis_FuncSphereLSDist.cxx deleted file mode 100644 index 7bf64af460..0000000000 --- a/src/ShapeAnalysis/ShapeAnalysis_FuncSphereLSDist.cxx +++ /dev/null @@ -1,115 +0,0 @@ -// Created on: 2016-05-10 -// Created by: Alexander MALYSHEV -// Copyright (c) 1995-1999 Matra Datavision -// Copyright (c) 1999-2016 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 - -//======================================================================= -//function : ShapeAnalysis_FuncSphereLSDist -//purpose : -//======================================================================= -ShapeAnalysis_FuncSphereLSDist::ShapeAnalysis_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints): - myPoints(thePoints) -{ -} - -//======================================================================= -//function : NbVariables -//purpose : -//======================================================================= -Standard_Integer ShapeAnalysis_FuncSphereLSDist::NbVariables () const -{ - return 4; -} - -//======================================================================= -//function : Value -//purpose : -//======================================================================= -Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Value(const math_Vector& X,Standard_Real& F) -{ - gp_XYZ aLoc(X(1), X(2), X(3)); - Standard_Real anR2 = X(4)*X(4); - - F = 0.; - Standard_Integer i; - for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) - { - Standard_Real d = (myPoints->Value(i) - aLoc).SquareModulus() - anR2; - F += d * d; - } - - return Standard_True; -} - -//======================================================================= -//function : Gradient -//purpose : -//======================================================================= -Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Gradient(const math_Vector& X,math_Vector& G) - -{ - gp_XYZ aLoc(X(1), X(2), X(3)); - Standard_Real anR = X(4), anR2 = anR * anR; - - G.Init(0.); - Standard_Integer i; - for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) - { - gp_XYZ dLoc = myPoints->Value(i) - aLoc; - Standard_Real d = dLoc.SquareModulus() - anR2; - G(1) += d * dLoc.X(); - G(2) += d * dLoc.Y(); - G(3) += d * dLoc.Z(); - G(4) += d; - } - G *= -4; - G(4) *= anR; - - return Standard_True; -} - -//======================================================================= -//function : Values -//purpose : -//======================================================================= -Standard_Boolean ShapeAnalysis_FuncSphereLSDist::Values(const math_Vector& X,Standard_Real& F,math_Vector& G) -{ - gp_XYZ aLoc(X(1), X(2), X(3)); - Standard_Real anR = X(4), anR2 = anR * anR; - - G.Init(0.); - F = 0.; - Standard_Integer i; - for (i = myPoints->Lower(); i <= myPoints->Upper(); ++i) - { - gp_XYZ dLoc = myPoints->Value(i) - aLoc; - Standard_Real d = dLoc.SquareModulus() - anR2; - G(1) += d * dLoc.X(); - G(2) += d * dLoc.Y(); - G(3) += d * dLoc.Z(); - G(4) += d; - F += d * d; - } - G *= -4; - G(4) *= anR; - - return true; -} - diff --git a/src/ShapeAnalysis/ShapeAnalysis_FuncSphereLSDist.hxx b/src/ShapeAnalysis/ShapeAnalysis_FuncSphereLSDist.hxx deleted file mode 100644 index fae0ffa8c6..0000000000 --- a/src/ShapeAnalysis/ShapeAnalysis_FuncSphereLSDist.hxx +++ /dev/null @@ -1,77 +0,0 @@ - -// Copyright (c) 1991-1999 Matra Datavision -// Copyright (c) 1999-2022 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 _ShapeAnalysis_FuncSphereLSDist_HeaderFile -#define _ShapeAnalysis_FuncSphereLSDist_HeaderFile - -#include -#include - -#include -#include -#include - -//! Function for search of sphere canonic parameters: coordinates of center and radius from set of moints -//! by least square method. -//! //! -//! The class inherits math_MultipleVarFunctionWithGradient and thus is intended -//! for use in math_BFGS algorithm. -//! -//! The criteria is: -//! F(x0, y0, z0, R) = Sum[(x(i) - x0)^2 + (y(i) - y0)^2 + (z(i) - z0)^2 - R^2]^2 => min, -//! x(i), y(i), z(i) - coordinates of sample points, x0, y0, z0, R - coordinates of center and radius of sphere, -//! which must be defined -//! -//! The first derivative are: -//! dF/dx0 : G1(x0, y0, z0, R) = -4*Sum{[...]*(x(i) - x0)} -//! dF/dy0 : G2(x0, y0, z0, R) = -4*Sum{[...]*(y(i) - y0)} -//! dF/dz0 : G3(x0, y0, z0, R) = -4*Sum{[...]*(z(i) - z0)} -//! dF/dR : G4(x0, y0, z0, R) = -4*R*Sum[...] -//! [...] = [(x(i) - x0)^2 + (y(i) - y0)^2 + (z(i) - z0)^2 - R^2] -//! -class ShapeAnalysis_FuncSphereLSDist : public math_MultipleVarFunctionWithGradient -{ -public: - - DEFINE_STANDARD_ALLOC - - //! Constructor. - Standard_EXPORT ShapeAnalysis_FuncSphereLSDist() {}; - - Standard_EXPORT ShapeAnalysis_FuncSphereLSDist(const Handle(TColgp_HArray1OfXYZ)& thePoints); - - void SetPoints(const Handle(TColgp_HArray1OfXYZ)& thePoints) - { - myPoints = thePoints; - } - - //! Number of variables. - Standard_EXPORT Standard_Integer NbVariables() const Standard_OVERRIDE; - - //! Value. - Standard_EXPORT Standard_Boolean Value(const math_Vector& X,Standard_Real& F) Standard_OVERRIDE; - - //! Gradient. - Standard_EXPORT Standard_Boolean Gradient(const math_Vector& X,math_Vector& G) Standard_OVERRIDE; - - //! Value and gradient. - Standard_EXPORT Standard_Boolean Values(const math_Vector& X,Standard_Real& F,math_Vector& G) Standard_OVERRIDE; - -private: - - Handle(TColgp_HArray1OfXYZ) myPoints; - -}; -#endif // _ShapeAnalysis_FuncSphereLSDist_HeaderFile diff --git a/tests/cr/base/B10 b/tests/cr/base/B10 new file mode 100644 index 0000000000..b890b67b29 --- /dev/null +++ b/tests/cr/base/B10 @@ -0,0 +1,18 @@ +cylinder surf 1 +trimv surf surf -10 10 +plane pp 0 0 0 1 0 1 +intersect ii surf pp +extsurf surf ii 0 0 1 +trimv surf surf -1 1 +convert surf surf +mkface f surf +getanasurf asurf f cyl 1.e-7 +if {[isdraw asurf]} { + set log [dump asurf] + if { [regexp {CylindricalSurface} $log ] != 1 } { + puts "Error: surface is not a cylindrical surface" + } +} else { + puts "Error: required surface is not got" +} +