From a9e5f65041b05e43937095c82ab180fccd544579 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 2 Mar 2022 08:58:10 +0300 Subject: [PATCH] 0032837: Documentation, Geom_Surface - add references to GeomLib::NormEstim() for Normal computations References to GeomLib::NormEstim() have been put to Geom_Surface, Adaptor3d_Surface and BRepAdaptor_Surface. Improved documentation of GeomLib::NormEstim(). --- src/Adaptor3d/Adaptor3d_Surface.hxx | 15 +- src/BRepAdaptor/BRepAdaptor_Surface.hxx | 15 +- src/Geom/Geom_Surface.hxx | 131 ++++++------- src/GeomLib/GeomLib.cxx | 236 +++++++++++++----------- src/GeomLib/GeomLib.hxx | 15 +- 5 files changed, 218 insertions(+), 194 deletions(-) diff --git a/src/Adaptor3d/Adaptor3d_Surface.hxx b/src/Adaptor3d/Adaptor3d_Surface.hxx index 5972b5ff76..1c4d1618a5 100644 --- a/src/Adaptor3d/Adaptor3d_Surface.hxx +++ b/src/Adaptor3d/Adaptor3d_Surface.hxx @@ -114,19 +114,20 @@ public: Standard_EXPORT virtual Standard_Boolean IsVPeriodic() const; Standard_EXPORT virtual Standard_Real VPeriod() const; - + //! Computes the point of parameters U,V on the surface. + //! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point. Standard_EXPORT virtual gp_Pnt Value (const Standard_Real U, const Standard_Real V) const; - + //! Computes the point of parameters U,V on the surface. Standard_EXPORT virtual void D0 (const Standard_Real U, const Standard_Real V, gp_Pnt& P) const; - //! Computes the point and the first derivatives on - //! the surface. - //! Raised if the continuity of the current - //! intervals is not C1. + //! Computes the point and the first derivatives on the surface. + //! Raised if the continuity of the current intervals is not C1. + //! + //! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point. Standard_EXPORT virtual void D1 (const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V) const; - + //! Computes the point, the first and second //! derivatives on the surface. //! Raised if the continuity of the current diff --git a/src/BRepAdaptor/BRepAdaptor_Surface.hxx b/src/BRepAdaptor/BRepAdaptor_Surface.hxx index ed06ef1b8a..9ac8e979d8 100644 --- a/src/BRepAdaptor/BRepAdaptor_Surface.hxx +++ b/src/BRepAdaptor/BRepAdaptor_Surface.hxx @@ -141,17 +141,18 @@ public: virtual Standard_Real VPeriod() const Standard_OVERRIDE { return mySurf.VPeriod(); } //! Computes the point of parameters U,V on the surface. + //! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point. Standard_EXPORT gp_Pnt Value (const Standard_Real U, const Standard_Real V) const Standard_OVERRIDE; - + //! Computes the point of parameters U,V on the surface. Standard_EXPORT void D0 (const Standard_Real U, const Standard_Real V, gp_Pnt& P) const Standard_OVERRIDE; - - //! Computes the point and the first derivatives on - //! the surface. - //! Raised if the continuity of the current - //! intervals is not C1. + + //! Computes the point and the first derivatives on the surface. + //! Raised if the continuity of the current intervals is not C1. + //! + //! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point. Standard_EXPORT void D1 (const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V) const Standard_OVERRIDE; - + //! Computes the point, the first and second //! derivatives on the surface. //! Raised if the continuity of the current diff --git a/src/Geom/Geom_Surface.hxx b/src/Geom/Geom_Surface.hxx index 05432d7e19..f117172642 100644 --- a/src/Geom/Geom_Surface.hxx +++ b/src/Geom/Geom_Surface.hxx @@ -27,29 +27,24 @@ class gp_Vec; class Geom_Surface; DEFINE_STANDARD_HANDLE(Geom_Surface, Geom_Geometry) -//! Describes the common behavior of surfaces in 3D -//! space. The Geom package provides many -//! implementations of concrete derived surfaces, such as -//! planes, cylinders, cones, spheres and tori, surfaces of -//! linear extrusion, surfaces of revolution, Bezier and -//! BSpline surfaces, and so on. -//! The key characteristic of these surfaces is that they -//! are parameterized. Geom_Surface demonstrates: -//! - how to work with the parametric equation of a -//! surface to compute the point of parameters (u, -//! v), and, at this point, the 1st, 2nd ... Nth derivative, +//! Describes the common behavior of surfaces in 3D space. +//! The Geom package provides many implementations of concrete derived surfaces, +//! such as planes, cylinders, cones, spheres and tori, surfaces of linear extrusion, +//! surfaces of revolution, Bezier and BSpline surfaces, and so on. +//! The key characteristic of these surfaces is that they are parameterized. +//! Geom_Surface demonstrates: +//! - how to work with the parametric equation of a surface +//! to compute the point of parameters (u, v), and, at this point, the 1st, 2nd ... Nth derivative; //! - how to find global information about a surface in -//! each parametric direction (for example, level of -//! continuity, whether the surface is closed, its -//! periodicity, the bounds of the parameters and so on), and -//! - how the parameters change when geometric -//! transformations are applied to the surface, or the -//! orientation is modified. -//! Note that all surfaces must have a geometric -//! continuity, and any surface is at least "C0". Generally, -//! continuity is checked at construction time or when the -//! curve is edited. Where this is not the case, the -//! documentation makes this explicit. +//! each parametric direction (for example, level of continuity, whether the surface is closed, +//! its periodicity, the bounds of the parameters and so on); +//! - how the parameters change when geometric transformations are applied to the surface, +//! or the orientation is modified. +//! +//! Note that all surfaces must have a geometric continuity, and any surface is at least "C0". +//! Generally, continuity is checked at construction time or when the curve is edited. +//! Where this is not the case, the documentation makes this explicit. +//! //! Warning //! The Geom package does not prevent the construction of //! surfaces with null areas, or surfaces which self-intersect. @@ -142,47 +137,42 @@ public: //! equal to Precision::Infinite: instead of Standard_Real::LastReal. Standard_EXPORT virtual void Bounds (Standard_Real& U1, Standard_Real& U2, Standard_Real& V1, Standard_Real& V2) const = 0; - //! Checks whether this surface is closed in the u - //! parametric direction. - //! Returns true if, in the u parametric direction: taking - //! uFirst and uLast as the parametric bounds in - //! the u parametric direction, for each parameter v, the - //! distance between the points P(uFirst, v) and + //! Checks whether this surface is closed in the u parametric direction. + //! Returns true if, in the u parametric direction: + //! taking uFirst and uLast as the parametric bounds in + //! the u parametric direction, for each parameter v, + //! the distance between the points P(uFirst, v) and //! P(uLast, v) is less than or equal to gp::Resolution(). Standard_EXPORT virtual Standard_Boolean IsUClosed() const = 0; - //! Checks whether this surface is closed in the u - //! parametric direction. - //! Returns true if, in the v parametric - //! direction: taking vFirst and vLast as the - //! parametric bounds in the v parametric direction, for - //! each parameter u, the distance between the points - //! P(u, vFirst) and P(u, vLast) is less than - //! or equal to gp::Resolution(). + //! Checks whether this surface is closed in the u parametric direction. + //! Returns true if, in the v parametric direction: + //! taking vFirst and vLast as the parametric bounds in the v parametric direction, + //! for each parameter u, the distance between the points + //! P(u, vFirst) and P(u, vLast) is less than or equal to gp::Resolution(). Standard_EXPORT virtual Standard_Boolean IsVClosed() const = 0; - //! Checks if this surface is periodic in the u - //! parametric direction. Returns true if: + //! Checks if this surface is periodic in the u parametric direction. + //! Returns true if: //! - this surface is closed in the u parametric direction, and //! - there is a constant T such that the distance - //! between the points P (u, v) and P (u + T, - //! v) (or the points P (u, v) and P (u, v + - //! T)) is less than or equal to gp::Resolution(). + //! between the points P (u, v) and P (u + T, v) + //! (or the points P (u, v) and P (u, v + T)) is less than or equal to gp::Resolution(). + //! //! Note: T is the parametric period in the u parametric direction. Standard_EXPORT virtual Standard_Boolean IsUPeriodic() const = 0; - //! Returns the period of this surface in the u - //! parametric direction. - //! raises if the surface is not uperiodic. + //! Returns the period of this surface in the u parametric direction. + //! Raises if the surface is not uperiodic. Standard_EXPORT virtual Standard_Real UPeriod() const; - //! Checks if this surface is periodic in the v - //! parametric direction. Returns true if: + //! Checks if this surface is periodic in the v parametric direction. + //! Returns true if: //! - this surface is closed in the v parametric direction, and //! - there is a constant T such that the distance - //! between the points P (u, v) and P (u + T, - //! v) (or the points P (u, v) and P (u, v + - //! T)) is less than or equal to gp::Resolution(). + //! between the points P (u, v) and P (u + T, v) + //! (or the points P (u, v) and P (u, v + T)) is less than or equal to gp::Resolution(). + //! //! Note: T is the parametric period in the v parametric direction. Standard_EXPORT virtual Standard_Boolean IsVPeriodic() const = 0; @@ -197,25 +187,24 @@ public: Standard_EXPORT virtual Handle(Geom_Curve) VIso (const Standard_Real V) const = 0; //! Returns the Global Continuity of the surface in direction U and V : - //! C0 : only geometric continuity, - //! C1 : continuity of the first derivative all along the surface, - //! C2 : continuity of the second derivative all along the surface, - //! C3 : continuity of the third derivative all along the surface, - //! G1 : tangency continuity all along the surface, - //! G2 : curvature continuity all along the surface, - //! CN : the order of continuity is infinite. - //! Example : + //! - C0: only geometric continuity, + //! - C1: continuity of the first derivative all along the surface, + //! - C2: continuity of the second derivative all along the surface, + //! - C3: continuity of the third derivative all along the surface, + //! - G1: tangency continuity all along the surface, + //! - G2: curvature continuity all along the surface, + //! - CN: the order of continuity is infinite. + //! + //! Example: //! If the surface is C1 in the V parametric direction and C2 //! in the U parametric direction Shape = C1. Standard_EXPORT virtual GeomAbs_Shape Continuity() const = 0; - //! Returns the order of continuity of the surface in the - //! U parametric direction. + //! Returns the order of continuity of the surface in the U parametric direction. //! Raised if N < 0. Standard_EXPORT virtual Standard_Boolean IsCNu (const Standard_Integer N) const = 0; - //! Returns the order of continuity of the surface in the - //! V parametric direction. + //! Returns the order of continuity of the surface in the V parametric direction. //! Raised if N < 0. Standard_EXPORT virtual Standard_Boolean IsCNv (const Standard_Integer N) const = 0; @@ -226,9 +215,10 @@ public: Standard_EXPORT virtual void D0 (const Standard_Real U, const Standard_Real V, gp_Pnt& P) const = 0; - //! Computes the point P and the first derivatives in the - //! directions U and V at this point. + //! Computes the point P and the first derivatives in the directions U and V at this point. //! Raised if the continuity of the surface is not C1. + //! + //! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point. Standard_EXPORT virtual void D1 (const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V) const = 0; //! Computes the point P, the first and the second derivatives in @@ -241,21 +231,18 @@ public: //! Raised if the continuity of the surface is not C2. Standard_EXPORT virtual void D3 (const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV, gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const = 0; - //! ---Purpose ; - //! Computes the derivative of order Nu in the direction U and Nv - //! in the direction V at the point P(U, V). + //! Computes the derivative of order Nu in the direction U and Nv in the direction V at the point P(U, V). //! - //! Raised if the continuity of the surface is not CNu in the U - //! direction or not CNv in the V direction. + //! Raised if the continuity of the surface is not CNu in the U direction or not CNv in the V direction. //! Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. Standard_EXPORT virtual gp_Vec DN (const Standard_Real U, const Standard_Real V, const Standard_Integer Nu, const Standard_Integer Nv) const = 0; - //! Computes the point of parameter U on the surface. + //! Computes the point of parameter (U, V) on the surface. //! - //! It is implemented with D0 + //! It is implemented with D0. + //! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point. //! - //! Raised only for an "OffsetSurface" if it is not possible to - //! compute the current point. + //! Raised only for an "OffsetSurface" if it is not possible to compute the current point. Standard_EXPORT gp_Pnt Value (const Standard_Real U, const Standard_Real V) const; //! Dumps the content of me into the stream diff --git a/src/GeomLib/GeomLib.cxx b/src/GeomLib/GeomLib.cxx index e1646bc098..e9dab9d188 100644 --- a/src/GeomLib/GeomLib.cxx +++ b/src/GeomLib/GeomLib.cxx @@ -2371,119 +2371,143 @@ void GeomLib::CancelDenominatorDerivative(Handle(Geom_BSplineSurface) & //======================================================================= //function : NormEstim -//purpose : +//purpose : //======================================================================= - -Standard_Integer GeomLib::NormEstim(const Handle(Geom_Surface)& S, - const gp_Pnt2d& UV, - const Standard_Real Tol, gp_Dir& N) +Standard_Integer GeomLib::NormEstim (const Handle(Geom_Surface)& theSurf, + const gp_Pnt2d& theUV, + const Standard_Real theTol, + gp_Dir& theNorm) { + const Standard_Real aTol2 = Square (theTol); + gp_Vec DU, DV; - gp_Pnt DummyPnt; - Standard_Real aTol2 = Square(Tol); + gp_Pnt aDummyPnt; + theSurf->D1 (theUV.X(), theUV.Y(), aDummyPnt, DU, DV); - S->D1(UV.X(), UV.Y(), DummyPnt, DU, DV); - - Standard_Real MDU = DU.SquareMagnitude(), MDV = DV.SquareMagnitude(); - - if(MDU >= aTol2 && MDV >= aTol2) { - gp_Vec Norm = DU^DV; - Standard_Real Magn = Norm.SquareMagnitude(); - if(Magn < aTol2) return 3; - - //Magn = sqrt(Magn); - N.SetXYZ(Norm.XYZ()); - - return 0; - } - else { - gp_Vec D2U, D2V, D2UV; - Standard_Boolean isDone; - CSLib_NormalStatus aStatus; - gp_Dir aNormal; - - S->D2(UV.X(), UV.Y(), DummyPnt, DU, DV, D2U, D2V, D2UV); - CSLib::Normal(DU, DV, D2U, D2V, D2UV, Tol, isDone, aStatus, aNormal); - - if (isDone) { - Standard_Real Umin, Umax, Vmin, Vmax; - Standard_Real step = 1.0e-5; - Standard_Real eps = 1.0e-16; - Standard_Real sign = -1.0; - - S->Bounds(Umin, Umax, Vmin, Vmax); - - // check for cone apex singularity point - if ((UV.Y() > Vmin + step) && (UV.Y() < Vmax - step)) - { - gp_Dir aNormal1, aNormal2; - Standard_Real aConeSingularityAngleEps = 1.0e-4; - S->D1(UV.X(), UV.Y() - sign * step, DummyPnt, DU, DV); - if ((DU.XYZ().SquareModulus() > eps) && (DV.XYZ().SquareModulus() > eps)) { - aNormal1 = DU^DV; - S->D1(UV.X(), UV.Y() + sign * step, DummyPnt, DU, DV); - if ((DU.XYZ().SquareModulus() > eps) && (DV.XYZ().SquareModulus() > eps)) { - aNormal2 = DU^DV; - if (aNormal1.IsOpposite(aNormal2, aConeSingularityAngleEps)) - return 2; - } - } - } - - // Along V - if(MDU < aTol2 && MDV >= aTol2) { - if ((Vmax - UV.Y()) > (UV.Y() - Vmin)) - sign = 1.0; - S->D1(UV.X(), UV.Y() + sign * step, DummyPnt, DU, DV); - gp_Vec Norm = DU^DV; - if (Norm.SquareMagnitude() < eps) { - Standard_Real sign1 = -1.0; - if ((Umax - UV.X()) > (UV.X() - Umin)) - sign1 = 1.0; - S->D1(UV.X() + sign1 * step, UV.Y() + sign * step, DummyPnt, DU, DV); - Norm = DU^DV; - } - if ((Norm.SquareMagnitude() >= eps) && (Norm.Dot(aNormal) < 0.0)) - aNormal.Reverse(); - } - - // Along U - if(MDV < aTol2 && MDU >= aTol2) { - if ((Umax - UV.X()) > (UV.X() - Umin)) - sign = 1.0; - S->D1(UV.X() + sign * step, UV.Y(), DummyPnt, DU, DV); - gp_Vec Norm = DU^DV; - if (Norm.SquareMagnitude() < eps) { - Standard_Real sign1 = -1.0; - if ((Vmax - UV.Y()) > (UV.Y() - Vmin)) - sign1 = 1.0; - S->D1(UV.X() + sign * step, UV.Y() + sign1 * step, DummyPnt, DU, DV); - Norm = DU^DV; - } - if ((Norm.SquareMagnitude() >= eps) && (Norm.Dot(aNormal) < 0.0)) - aNormal.Reverse(); - } - - // quasysingular - if ((aStatus == CSLib_D1NuIsNull) || (aStatus == CSLib_D1NvIsNull) || - (aStatus == CSLib_D1NuIsParallelD1Nv)) { - N.SetXYZ(aNormal.XYZ()); - return 1; - } - // conical - if (aStatus == CSLib_InfinityOfSolutions) - return 2; - } - // computation is impossible - else { - // conical - if (aStatus == CSLib_D1NIsNull) { - return 2; - } + const Standard_Real MDU = DU.SquareMagnitude(), MDV = DV.SquareMagnitude(); + if (MDU >= aTol2 + && MDV >= aTol2) + { + gp_Vec aNorm = DU ^ DV; + Standard_Real aMagn = aNorm.SquareMagnitude(); + if (aMagn < aTol2) + { return 3; } + + theNorm.SetXYZ (aNorm.XYZ()); + return 0; } - return 3; + + gp_Vec D2U, D2V, D2UV; + Standard_Boolean isDone = false; + CSLib_NormalStatus aStatus; + gp_Dir aNormal; + + theSurf->D2 (theUV.X(), theUV.Y(), aDummyPnt, DU, DV, D2U, D2V, D2UV); + CSLib::Normal (DU, DV, D2U, D2V, D2UV, theTol, isDone, aStatus, aNormal); + if (!isDone) + { + // computation is impossible + return aStatus == CSLib_D1NIsNull ? 2 : 3; + } + + Standard_Real Umin, Umax, Vmin, Vmax; + Standard_Real step = 1.0e-5; + Standard_Real eps = 1.0e-16; + Standard_Real sign = -1.0; + theSurf->Bounds (Umin, Umax, Vmin, Vmax); + + // check for cone apex singularity point + if ((theUV.Y() > Vmin + step) + && (theUV.Y() < Vmax - step)) + { + gp_Dir aNormal1, aNormal2; + Standard_Real aConeSingularityAngleEps = 1.0e-4; + theSurf->D1(theUV.X(), theUV.Y() - sign * step, aDummyPnt, DU, DV); + if ((DU.XYZ().SquareModulus() > eps) && (DV.XYZ().SquareModulus() > eps)) + { + aNormal1 = DU ^ DV; + theSurf->D1 (theUV.X(), theUV.Y() + sign * step, aDummyPnt, DU, DV); + if ((DU.XYZ().SquareModulus() > eps) + && (DV.XYZ().SquareModulus() > eps)) + { + aNormal2 = DU^DV; + if (aNormal1.IsOpposite (aNormal2, aConeSingularityAngleEps)) + { + return 2; + } + } + } + } + + // Along V + if (MDU < aTol2 + && MDV >= aTol2) + { + if ((Vmax - theUV.Y()) > (theUV.Y() - Vmin)) + { + sign = 1.0; + } + + theSurf->D1 (theUV.X(), theUV.Y() + sign * step, aDummyPnt, DU, DV); + gp_Vec Norm = DU ^ DV; + if (Norm.SquareMagnitude() < eps) + { + Standard_Real sign1 = -1.0; + if ((Umax - theUV.X()) > (theUV.X() - Umin)) + { + sign1 = 1.0; + } + theSurf->D1 (theUV.X() + sign1 * step, theUV.Y() + sign * step, aDummyPnt, DU, DV); + Norm = DU ^ DV; + } + if (Norm.SquareMagnitude() >= eps + && Norm.Dot (aNormal) < 0.0) + { + aNormal.Reverse(); + } + } + + // Along U + if (MDV < aTol2 + && MDU >= aTol2) + { + if ((Umax - theUV.X()) > (theUV.X() - Umin)) + { + sign = 1.0; + } + + theSurf->D1 (theUV.X() + sign * step, theUV.Y(), aDummyPnt, DU, DV); + gp_Vec Norm = DU ^ DV; + if (Norm.SquareMagnitude() < eps) + { + Standard_Real sign1 = -1.0; + if ((Vmax - theUV.Y()) > (theUV.Y() - Vmin)) + { + sign1 = 1.0; + } + + theSurf->D1 (theUV.X() + sign * step, theUV.Y() + sign1 * step, aDummyPnt, DU, DV); + Norm = DU ^ DV; + } + if (Norm.SquareMagnitude() >= eps + && Norm.Dot (aNormal) < 0.0) + { + aNormal.Reverse(); + } + } + + // quasysingular + if (aStatus == CSLib_D1NuIsNull + || aStatus == CSLib_D1NvIsNull + || aStatus == CSLib_D1NuIsParallelD1Nv) + { + theNorm.SetXYZ (aNormal.XYZ()); + return 1; + } + + return aStatus == CSLib_InfinityOfSolutions ? 2 : 3; } //======================================================================= diff --git a/src/GeomLib/GeomLib.hxx b/src/GeomLib/GeomLib.hxx index 97c3ee446e..71e817bb90 100644 --- a/src/GeomLib/GeomLib.hxx +++ b/src/GeomLib/GeomLib.hxx @@ -183,8 +183,19 @@ public: //! Cancel,on the boundaries,the denominator first derivative //! in the directions wished by the user and set its value to 1. Standard_EXPORT static void CancelDenominatorDerivative (Handle(Geom_BSplineSurface)& BSurf, const Standard_Boolean UDirection, const Standard_Boolean VDirection); - - Standard_EXPORT static Standard_Integer NormEstim (const Handle(Geom_Surface)& S, const gp_Pnt2d& UV, const Standard_Real Tol, gp_Dir& N); + + //! Estimate surface normal at the given (U, V) point. + //! @param[in] theSurf input surface + //! @param[in] theUV (U, V) point coordinates on the surface + //! @param[in] theTol estimation tolerance + //! @param[out] theNorm computed normal + //! @return 0 if normal estimated from D1, + //! 1 if estimated from D2 (quasysingular), + //! >=2 in case of failure (undefined or infinite solutions) + Standard_EXPORT static Standard_Integer NormEstim (const Handle(Geom_Surface)& theSurf, + const gp_Pnt2d& theUV, + const Standard_Real theTol, + gp_Dir& theNorm); //! This method defines if opposite boundaries of surface //! coincide with given tolerance