From 093ae5d0b50ef8b7b85f2a71bc8910b0fc591f4d Mon Sep 17 00:00:00 2001 From: emv Date: Fri, 16 Jun 2017 09:43:26 +0300 Subject: [PATCH] 0028848: It is necessary to protect the algorithms from degenerated surfaces of type SurfaceOfLinearExtrusion Forbid the creation of degenerated SurfaceOfLinearExtrusion in case the basis curve is a line (or BSpline with two points only) and the direction of extrusion is parallel to the direction of the line. --- dox/dev_guides/upgrade/upgrade.md | 4 ++ src/Geom/Geom_SurfaceOfLinearExtrusion.cxx | 79 ++++++++++++++++++---- src/Geom/Geom_SurfaceOfLinearExtrusion.hxx | 45 +++++++----- 3 files changed, 97 insertions(+), 31 deletions(-) diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index 6c317a4aba..53eadb2814 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -1391,3 +1391,7 @@ if (anError != Storage_VSOk) Since 7.2.0 version, method *IsPeriodic()* returns the corresponding status of periodicity of the basis curve regardless of closure status of the adaptor curve (see method *IsClosed()*). Method *IsClosed()* for adaptor can return false even on periodic curve, in the case if its parametric range is not full period, e.g. for adaptor on circle in range [0, @f$ \pi @f$]. In previous versions, *IsPeriodic()* always returned false if *IsClosed()* returned false. + +@subsection upgrade_720_Creation_SurfaceOfLinearExtrusion + +Since 7.2.0 version, it will be impossible to create the SurfaceOfLinearExtrusion from the linear basis curve (*Line* or *BSpline* curve with only two poles) in the direction parallel to the direction of that curve. The *Standard_ConstructionError* exception will be thrown in this case. diff --git a/src/Geom/Geom_SurfaceOfLinearExtrusion.cxx b/src/Geom/Geom_SurfaceOfLinearExtrusion.cxx index 62d816d994..92b347b767 100644 --- a/src/Geom/Geom_SurfaceOfLinearExtrusion.cxx +++ b/src/Geom/Geom_SurfaceOfLinearExtrusion.cxx @@ -64,6 +64,9 @@ typedef gp_Vec Vec; typedef gp_XYZ XYZ; +static + Standard_Boolean IsParallel(const Handle(Geom_Curve)& theCurve, + const gp_Dir& theDir); //======================================================================= //function : Copy @@ -84,15 +87,19 @@ Handle(Geom_Geometry) Geom_SurfaceOfLinearExtrusion::Copy () const //purpose : //======================================================================= -Geom_SurfaceOfLinearExtrusion::Geom_SurfaceOfLinearExtrusion - ( const Handle(Geom_Curve)& C, - const Dir& V) { - - basisCurve = Handle(Geom_Curve)::DownCast(C->Copy()); // Copy 10-03-93 - direction = V; - smooth = C->Continuity(); - myEvaluator = new GeomEvaluator_SurfaceOfExtrusion(basisCurve, direction); - } +Geom_SurfaceOfLinearExtrusion::Geom_SurfaceOfLinearExtrusion + (const Handle(Geom_Curve)& C, + const Dir& V) +{ + if (IsParallel(C, V)) + throw Standard_ConstructionError("Geom_SurfaceOfLinearExtrusion - " + "direction of the extrusion coincides with the direction of the basis line"); + // + basisCurve = Handle(Geom_Curve)::DownCast(C->Copy()); // Copy 10-03-93 + direction = V; + smooth = C->Continuity(); + myEvaluator = new GeomEvaluator_SurfaceOfExtrusion(basisCurve, direction); +} //======================================================================= @@ -149,6 +156,9 @@ void Geom_SurfaceOfLinearExtrusion::SetDirection (const Dir& V) { direction = V; myEvaluator->SetDirection(direction); + if (!basisCurve.IsNull() && IsParallel(basisCurve, direction)) + throw Standard_ConstructionError("Geom_SurfaceOfLinearExtrusion::SetDirection - " + "direction of the extrusion coincides with the direction of the basis line"); } @@ -158,10 +168,13 @@ void Geom_SurfaceOfLinearExtrusion::SetDirection (const Dir& V) //======================================================================= void Geom_SurfaceOfLinearExtrusion::SetBasisCurve (const Handle(Geom_Curve)& C) { - - smooth = C->Continuity(); - basisCurve = Handle(Geom_Curve)::DownCast(C->Copy()); // Copy 10-03-93 - myEvaluator = new GeomEvaluator_SurfaceOfExtrusion(basisCurve, direction); + if (IsParallel(C, direction)) + throw Standard_ConstructionError("Geom_SurfaceOfLinearExtrusion::SetBasisCurve - " + "direction of the extrusion coincides with the direction of the basis line"); + // + smooth = C->Continuity(); + basisCurve = Handle(Geom_Curve)::DownCast(C->Copy()); // Copy 10-03-93 + myEvaluator = new GeomEvaluator_SurfaceOfExtrusion(basisCurve, direction); } @@ -391,3 +404,43 @@ gp_GTrsf2d Geom_SurfaceOfLinearExtrusion::ParametricTransformation return TU * TV; } + +//======================================================================= +//function : IsParallel +//purpose : Checks if the direction of the given curve is parallel to +// the given direction (only lines and BSplines are currently checked) +//======================================================================= +Standard_Boolean IsParallel(const Handle(Geom_Curve)& theCurve, + const gp_Dir& theDir) +{ + Handle(Geom_Curve) aCurve = theCurve; + while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) || + aCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) + { + aCurve = aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ? + Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve() : + Handle(Geom_OffsetCurve) ::DownCast(aCurve)->BasisCurve(); + } + // + Standard_Boolean bParallel = Standard_False; + if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)) || + aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) + { + if (aCurve->IsKind(STANDARD_TYPE(Geom_Line))) + { + gp_Lin aLine = Handle(Geom_Line)::DownCast(aCurve)->Lin(); + bParallel = aLine.Position().Direction().IsParallel(theDir, Precision::Angular()); + } + else + { + Handle(Geom_BSplineCurve) aBSplineC = Handle(Geom_BSplineCurve)::DownCast(aCurve); + if (aBSplineC->Degree() == 1 && aBSplineC->NbPoles() == 2) + { + gp_Vec aBSplDir(aBSplineC->Pole(1), aBSplineC->Pole(2)); + bParallel = (aBSplDir.Magnitude() < gp::Resolution()) || + aBSplDir.IsParallel(theDir, Precision::Angular()); + } + } + } + return bParallel; +} diff --git a/src/Geom/Geom_SurfaceOfLinearExtrusion.hxx b/src/Geom/Geom_SurfaceOfLinearExtrusion.hxx index e0fb9d2f2f..b1e8dcfc15 100644 --- a/src/Geom/Geom_SurfaceOfLinearExtrusion.hxx +++ b/src/Geom/Geom_SurfaceOfLinearExtrusion.hxx @@ -43,30 +43,32 @@ DEFINE_STANDARD_HANDLE(Geom_SurfaceOfLinearExtrusion, Geom_SweptSurface) //! surface"), e.g. a generalized cylinder. Such a surface //! is obtained by sweeping a curve (called the "extruded //! curve" or "basis") in a given direction (referred to as -//! the "direction of extrusion" and defined by a unit vector). +//! the "direction of extrusion" and defined by a unit vector).
//! The u parameter is along the extruded curve. The v //! parameter is along the direction of extrusion. //! The parameter range for the u parameter is defined //! by the reference curve. //! The parameter range for the v parameter is ] - //! infinity, + infinity [. -//! The position of the curve gives the origin of the v parameter. -//! The surface is "CN" in the v parametric direction. +//! The position of the curve gives the origin of the v parameter.
+//! The surface is "CN" in the v parametric direction.
//! The form of a surface of linear extrusion is generally a -//! ruled surface (GeomAbs_RuledForm). It can be: +//! ruled surface (GeomAbs_RuledForm). It can be:
//! - a cylindrical surface, if the extruded curve is a circle, //! or a trimmed circle, with an axis parallel to the -//! direction of extrusion (GeomAbs_CylindricalForm), or +//! direction of extrusion (GeomAbs_CylindricalForm), or
//! - a planar surface, if the extruded curve is a line -//! (GeomAbs_PlanarForm). +//! (GeomAbs_PlanarForm).
//! Note: The surface of extrusion is built from a copy of //! the original basis curve, so the original curve is not -//! modified when the surface is modified. -//! Warning -//! Degenerate surfaces are not detected. A degenerate -//! surface is obtained, for example, when the extruded -//! curve is a line and the direction of extrusion is parallel -//! to that line. +//! modified when the surface is modified.
+//! Warning: Not all cases of the creation of the degenerated +//! surfaces are detected.
+//! Only the following case is currently detected:
+//! - The extruded curve is a line (or a BSpline with only two poles) +//! and the direction of extrusion is parallel to that line.
+//! The exception Standard_ConstructionError will be thrown in +//! this case. class Geom_SurfaceOfLinearExtrusion : public Geom_SweptSurface { @@ -81,18 +83,25 @@ public: //! . a cylindrical surface if the extruded curve is a circle or //! a trimmed circle (CylindricalForm), //! . a plane surface if the extruded curve is a Line (PlanarForm). - //! Warnings : - //! Degenerated surface cases are not detected. For example if the - //! curve C is a line and V is parallel to the direction of this - //! line. + //! Warning: Not all cases of the creation of the degenerated + //! surfaces are detected.
+ //! Only the following case is currently detected:
+ //! - The given curve is a line (or a BSpline with only two poles) + //! and the given direction of extrusion is parallel to that line.
+ //! The exception Standard_ConstructionError will be thrown in + //! this case. Standard_EXPORT Geom_SurfaceOfLinearExtrusion(const Handle(Geom_Curve)& C, const gp_Dir& V); //! Assigns V as the "direction of extrusion" for this - //! surface of linear extrusion. + //! surface of linear extrusion.
+ //! Throws the exception Standard_ConstructionError if the given direction is + //! parallel to the direction of the basisCurve. Standard_EXPORT void SetDirection (const gp_Dir& V); //! Modifies this surface of linear extrusion by redefining - //! its "basis curve" (the "extruded curve"). + //! its "basis curve" (the "extruded curve").
+ //! Throws the exception Standard_ConstructionError if the direction + //! of extrusion is parallel to the direction of the given curve. Standard_EXPORT void SetBasisCurve (const Handle(Geom_Curve)& C); //! Changes the orientation of this surface of linear -- 2.39.5