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