0026931: [Regression in 6.9.0] Exporting a face throws an exception
authorika <ika@opencascade.com>
Thu, 3 Dec 2015 08:35:42 +0000 (11:35 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 13 Jan 2016 12:22:59 +0000 (15:22 +0300)
Writing periodic BSpline surfaces to IGES:
Replace segmentation of surface to setting new origin.
Fix face bounds if its length (in U or V) is more than period.

Segmentation of BSpline curve/surface:
Throw exception if segment length more than period.

Fix test case bugs moddata_1 bug14782:
bounds of segmentation must be the same as curve bounds, according to issue description.

Changes in classes Geom2d_BSplineCurve, Geom_BSplineCurve, Geom_BSplineSurface:
- Replace *Raise_if macros with unconditional exceptions where it does not affect on performance.
- Update comments in .hxx files in regard of raised exceptions.

src/Geom/Geom_BSplineCurve.cxx
src/Geom/Geom_BSplineCurve.hxx
src/Geom/Geom_BSplineSurface.cxx
src/Geom/Geom_BSplineSurface.hxx
src/Geom/Geom_BSplineSurface_1.cxx
src/Geom2d/Geom2d_BSplineCurve.cxx
src/Geom2d/Geom2d_BSplineCurve.hxx
src/GeomToIGES/GeomToIGES_GeomSurface.cxx
tests/bugs/iges/bug26931 [new file with mode: 0644]
tests/bugs/moddata_1/bug14782

index e7e9118..195d56f 100644 (file)
@@ -525,8 +525,8 @@ Standard_Real Geom_BSplineCurve::ReversedParameter
 void Geom_BSplineCurve::Segment(const Standard_Real U1,
                                const Standard_Real U2)
 {
-  Standard_DomainError_Raise_if ( U2 < U1,
-                                "Geom_BSplineCurve::Segment");
+  if (U2 < U1)
+    Standard_DomainError::Raise("Geom_BSplineCurve::Segment");
   
   Standard_Real NewU1, NewU2;
   Standard_Real U,DU=0,aDDU=0;
@@ -540,9 +540,9 @@ void Geom_BSplineCurve::Segment(const Standard_Real U1,
   if (periodic) {
     Standard_Real Period = LastParameter() - FirstParameter();
     DU = U2 - U1;
-    while (DU > Period)
-      DU -= Period;
-    if (DU <= Epsilon(Period))
+    if (DU - Period > Precision::PConfusion())
+      Standard_DomainError::Raise("Geom_BSplineCurve::Segment");
+    if (DU > Period)
       DU = Period;
     aDDU = DU;
   }
@@ -783,14 +783,15 @@ void Geom_BSplineCurve::SetPeriodic ()
 
 void Geom_BSplineCurve::SetOrigin(const Standard_Integer Index)
 {
-  Standard_NoSuchObject_Raise_if( !periodic,
-                                "Geom_BSplineCurve::SetOrigin");
+  if (!periodic)
+    Standard_NoSuchObject::Raise("Geom_BSplineCurve::SetOrigin");
+
   Standard_Integer i,k;
   Standard_Integer first = FirstUKnotIndex();
   Standard_Integer last  = LastUKnotIndex();
 
-  Standard_DomainError_Raise_if( (Index < first) || (Index > last),
-                               "Geom_BSplineCurve::SetOrigine");
+  if ((Index < first) || (Index > last))
+    Standard_DomainError::Raise("Geom_BSplineCurve::SetOrigin");
 
   Standard_Integer nbknots = knots->Length();
   Standard_Integer nbpoles = poles->Length();
@@ -872,8 +873,8 @@ void Geom_BSplineCurve::SetOrigin(const Standard_Integer Index)
 void Geom_BSplineCurve::SetOrigin(const Standard_Real U,
                                  const Standard_Real Tol)
 {
-  Standard_NoSuchObject_Raise_if( !periodic,
-                                "Geom_BSplineCurve::SetOrigin");
+  if (!periodic)
+    Standard_NoSuchObject::Raise("Geom_BSplineCurve::SetOrigin");
   //U est il dans la period.
   Standard_Real uf = FirstParameter(), ul = LastParameter();
   Standard_Real u = U, period = ul - uf;
index 9e82fe5..63e612b 100644 (file)
@@ -296,6 +296,8 @@ public:
   //! of the curve <me> or if the curve makes loop.
   //! After the segmentation the length of a curve can be null.
   //! raises if U2 < U1.
+  //! Standard_DomainError if U2 - U1 exceeds the period for periodic curves.
+  //! i.e. ((U2 - U1) - Period) > Precision::PConfusion().
   Standard_EXPORT void Segment (const Standard_Real U1, const Standard_Real U2);
   
   //! Modifies this BSpline curve by assigning the value K
@@ -525,42 +527,27 @@ public:
   Standard_EXPORT gp_Vec DN (const Standard_Real U, const Standard_Integer N) const Standard_OVERRIDE;
   
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT gp_Pnt LocalValue (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2) const;
   
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT void LocalD0 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt& P) const;
   
 
   //! Raised if the local continuity of the curve is not C1
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT void LocalD1 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt& P, gp_Vec& V1) const;
   
 
   //! Raised if the local continuity of the curve is not C2
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT void LocalD2 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt& P, gp_Vec& V1, gp_Vec& V2) const;
   
 
   //! Raised if the local continuity of the curve is not C3
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT void LocalD3 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt& P, gp_Vec& V1, gp_Vec& V2, gp_Vec& V3) const;
   
 
@@ -568,9 +555,6 @@ public:
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
   //! Raised if N < 1.
-  //!
-  //! Raises if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT gp_Vec LocalDN (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, const Standard_Integer N) const;
   
 
@@ -610,7 +594,8 @@ public:
   //! repeated in the knot table. The Multiplicity function
   //! can be used to obtain the multiplicity of each knot.
   //!
-  //! Raised if the length of K is not equal to the number of knots.
+  //! Raised K.Lower() is less than number of first knot or
+  //! K.Upper() is more than number of last knot.
   Standard_EXPORT void Knots (TColStd_Array1OfReal& K) const;
   
   //! returns the knot values of the B-spline curve;
@@ -670,8 +655,9 @@ public:
   //! K = { k3-p k3-p k1 k1 k1 k2 k3 k3
   //! k4 k4 k4 k2+p k3+p }
   //! Exceptions
-  //! Standard_DimensionError if the array K is not of
-  //! the appropriate length.Returns the knots sequence.
+  //! Raised if K.Lower() is less than number of first knot
+  //! in knot sequence with repetitions or K.Upper() is more
+  //! than number of last knot in knot sequence with repetitions.
   Standard_EXPORT void KnotSequence (TColStd_Array1OfReal& K) const;
   
   //! returns the knots of the B-spline curve.
index 0696f6e..a328ab5 100644 (file)
@@ -538,16 +538,29 @@ void Geom_BSplineSurface::Segment(const Standard_Real U1,
                                  const Standard_Real V1,
                                  const Standard_Real V2) 
 {
-
-  Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
-                                "Geom_BSplineCurve::Segment");
+  if ((U2 < U1) || (V2 < V1))
+    Standard_DomainError::Raise("Geom_BSplineSurface::Segment");
   Standard_Real deltaU = Max(Abs(U2),Abs(U1));
   Standard_Real EpsU = Epsilon(deltaU);
   deltaU = U2 - U1;
+  if (uperiodic) {
+    Standard_Real aUPeriod = uknots->Last() - uknots->First();
+    if (deltaU - aUPeriod > Precision::PConfusion())
+      Standard_DomainError::Raise("Geom_BSplineSurface::Segment");
+    if (deltaU > aUPeriod)
+      deltaU = aUPeriod;
+  }
   
   Standard_Real deltaV = Max(Abs(V2),Abs(V1));
   Standard_Real EpsV = Epsilon(deltaV);
   deltaV = V2 - V1;
+  if (vperiodic) {
+    Standard_Real aVPeriod = vknots->Last() - vknots->First();
+    if (deltaV - aVPeriod > Precision::PConfusion())
+      Standard_DomainError::Raise("Geom_BSplineSurface::Segment");
+    if (deltaV > aVPeriod)
+      deltaV = aVPeriod;
+  }
 
   Standard_Real NewU1, NewU2, NewV1, NewV2;
   Standard_Real U,V;
@@ -747,15 +760,29 @@ void Geom_BSplineSurface::CheckAndSegment(const Standard_Real U1,
                                          const Standard_Real V2) 
 {
 
-  Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
-                                "Geom_BSplineCurve::Segment");
+  if ((U2 < U1) || (V2 < V1))
+    Standard_DomainError::Raise("Geom_BSplineSurface::CheckAndSegment");
   Standard_Real deltaU = Max(Abs(U2),Abs(U1));
   Standard_Real EpsU = Epsilon(deltaU);
   deltaU = U2 - U1;
+  if (uperiodic) {
+    Standard_Real aUPeriod = uknots->Last() - uknots->First();
+    if (deltaU - aUPeriod > Precision::PConfusion())
+      Standard_DomainError::Raise("Geom_BSplineSurface::CheckAndSegment");
+    if (deltaU > aUPeriod)
+      deltaU = aUPeriod;
+  }
   
   Standard_Real deltaV = Max(Abs(V2),Abs(V1));
   Standard_Real EpsV = Epsilon(deltaV);
   deltaV = V2 - V1;
+  if (vperiodic) {
+    Standard_Real aVPeriod = vknots->Last() - vknots->First();
+    if (deltaV - aVPeriod > Precision::PConfusion())
+      Standard_DomainError::Raise("Geom_BSplineSurface::CheckAndSegment");
+    if (deltaV > aVPeriod)
+      deltaV = aVPeriod;
+  }
 
   Standard_Real NewU1, NewU2, NewV1, NewV2;
   Standard_Real U,V;
index e0a7a20..52e2585 100644 (file)
@@ -551,7 +551,11 @@ public:
   //! Even if <me> is not closed it can become closed after the
   //! segmentation for example if U1 or U2 are out of the bounds
   //! of the surface <me> or if the surface makes loop.
-  //! raises if U2 < U1 or V2 < V1
+  //! raises if U2 < U1 or V2 < V1.
+  //! Standard_DomainError if U2 - U1 exceeds the uperiod for uperiodic surfaces.
+  //! i.e. ((U2 - U1) - UPeriod) > Precision::PConfusion().
+  //! Standard_DomainError if V2 - V1 exceeds the vperiod for vperiodic surfaces.
+  //! i.e. ((V2 - V1) - VPeriod) > Precision::PConfusion()).
   Standard_EXPORT void Segment (const Standard_Real U1, const Standard_Real U2, const Standard_Real V1, const Standard_Real V2);
   
 
@@ -567,7 +571,11 @@ public:
   //! Even if <me> is not closed it can become closed after the
   //! segmentation for example if U1 or U2 are out of the bounds
   //! of the surface <me> or if the surface makes loop.
-  //! raises if U2 < U1 or V2 < V1
+  //! raises if U2 < U1 or V2 < V1.
+  //! Standard_DomainError if U2 - U1 exceeds the uperiod for uperiodic surfaces.
+  //! i.e. ((U2 - U1) - UPeriod) > Precision::PConfusion().
+  //! Standard_DomainError if V2 - V1 exceeds the vperiod for vperiodic surfaces.
+  //! i.e. ((V2 - V1) - VPeriod) > Precision::PConfusion()).
   Standard_EXPORT void CheckAndSegment (const Standard_Real U1, const Standard_Real U2, const Standard_Real V1, const Standard_Real V2);
   
   //! Substitutes the UKnots of range UIndex with K.
@@ -975,6 +983,7 @@ public:
   Standard_EXPORT Standard_Integer VDegree() const;
   
   //! Returns the Knot value of range VIndex.
+  //! Raised if VIndex < 1 or VIndex > NbVKnots
   Standard_EXPORT Standard_Real VKnot (const Standard_Integer VIndex) const;
   
 
@@ -1086,40 +1095,24 @@ public:
   Standard_EXPORT gp_Vec DN (const Standard_Real U, const Standard_Real V, const Standard_Integer Nu, const Standard_Integer Nv) const Standard_OVERRIDE;
   
   //! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2.
-  //!
-  //! Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex,
-  //! LastUKnotIndex] or if FromVK1, ToVK2 are not in the range
-  //! [FirstVKnotIndex, LastVKnotIndex]
   Standard_EXPORT void LocalD0 (const Standard_Real U, const Standard_Real V, const Standard_Integer FromUK1, const Standard_Integer ToUK2, const Standard_Integer FromVK1, const Standard_Integer ToVK2, gp_Pnt& P) const;
   
 
   //! Raised if the local continuity of the surface is not C1
   //! between the knots FromUK1, ToUK2 and FromVK1, ToVK2.
   //! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2.
-  //!
-  //! Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex,
-  //! LastUKnotIndex] or if FromVK1, ToVK2 are not in the range
-  //! [FirstVKnotIndex, LastVKnotIndex]
   Standard_EXPORT void LocalD1 (const Standard_Real U, const Standard_Real V, const Standard_Integer FromUK1, const Standard_Integer ToUK2, const Standard_Integer FromVK1, const Standard_Integer ToVK2, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V) const;
   
 
   //! Raised if the local continuity of the surface is not C2
   //! between the knots FromUK1, ToUK2 and FromVK1, ToVK2.
   //! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2.
-  //!
-  //! Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex,
-  //! LastUKnotIndex] or if FromVK1, ToVK2 are not in the range
-  //! [FirstVKnotIndex, LastVKnotIndex]
   Standard_EXPORT void LocalD2 (const Standard_Real U, const Standard_Real V, const Standard_Integer FromUK1, const Standard_Integer ToUK2, const Standard_Integer FromVK1, const Standard_Integer ToVK2, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) const;
   
 
   //! Raised if the local continuity of the surface is not C3
   //! between the knots FromUK1, ToUK2 and FromVK1, ToVK2.
   //! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2.
-  //!
-  //! Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex,
-  //! LastUKnotIndex] or if FromVK1, ToVK2 are not in the range
-  //! [FirstVKnotIndex, LastVKnotIndex]
   Standard_EXPORT void LocalD3 (const Standard_Real U, const Standard_Real V, const Standard_Integer FromUK1, const Standard_Integer ToUK2, const Standard_Integer FromVK1, const Standard_Integer ToVK2, 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;
   
 
@@ -1127,10 +1120,6 @@ public:
   //! between the knots FromUK1, ToUK2 and CNv between the knots
   //! FromVK1, ToVK2.
   //! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2.
-  //!
-  //! Raised if FromUK1, ToUK2 are not in the range [FirstUKnotIndex,
-  //! LastUKnotIndex] or if FromVK1, ToVK2 are not in the range
-  //! [FirstVKnotIndex, LastVKnotIndex]
   Standard_EXPORT gp_Vec LocalDN (const Standard_Real U, const Standard_Real V, const Standard_Integer FromUK1, const Standard_Integer ToUK2, const Standard_Integer FromVK1, const Standard_Integer ToVK2, const Standard_Integer Nu, const Standard_Integer Nv) const;
   
 
@@ -1140,10 +1129,6 @@ public:
   //! [Knot VK1, Knot VK2]  but for the computation we only use the
   //! definition of the surface between these knot values.
   //! Raises if FromUK1 = ToUK2 or FromVK1 = ToVK2.
-  //!
-  //! Raises if FromUK1, ToUK2 are not in the range [FirstUKnotIndex,
-  //! LastUKnotIndex] or if FromVK1, ToVK2 are not in the range
-  //! [FirstVKnotIndex, LastVKnotIndex]
   Standard_EXPORT gp_Pnt LocalValue (const Standard_Real U, const Standard_Real V, const Standard_Integer FromUK1, const Standard_Integer ToUK2, const Standard_Integer FromVK1, const Standard_Integer ToVK2) const;
   
 
index f0ade1c..0d75f68 100644 (file)
@@ -921,15 +921,15 @@ void Geom_BSplineSurface::SetVPeriodic ()
 
 void Geom_BSplineSurface::SetUOrigin(const Standard_Integer Index)
 {
-  Standard_NoSuchObject_Raise_if( !uperiodic,
-                                "Geom_BSplineSurface::SetUOrigin");
+  if (!uperiodic)
+    Standard_NoSuchObject::Raise("Geom_BSplineSurface::SetUOrigin");
 
   Standard_Integer i,j,k;
   Standard_Integer first = FirstUKnotIndex();
   Standard_Integer last  = LastUKnotIndex();
 
-  Standard_DomainError_Raise_if( (Index < first) || (Index > last),
-                               "Geom_BSplineCurve::SetUOrigine");
+  if ((Index < first) || (Index > last))
+    Standard_DomainError::Raise("Geom_BSplineCurve::SetUOrigin");
 
   Standard_Integer nbknots = uknots->Length();
   Standard_Integer nbpoles = poles->ColLength();
@@ -1019,15 +1019,15 @@ void Geom_BSplineSurface::SetUOrigin(const Standard_Integer Index)
 
 void Geom_BSplineSurface::SetVOrigin(const Standard_Integer Index)
 {
-  Standard_NoSuchObject_Raise_if( !vperiodic,
-                                "Geom_BSplineSurface::SetVOrigin");
+  if (!vperiodic)
+    Standard_NoSuchObject::Raise("Geom_BSplineSurface::SetVOrigin");
 
   Standard_Integer i,j,k;
   Standard_Integer first = FirstVKnotIndex();
   Standard_Integer last  = LastVKnotIndex();
 
-  Standard_DomainError_Raise_if( (Index < first) || (Index > last),
-                               "Geom_BSplineCurve::SetVOrigine");
+  if ((Index < first) || (Index > last))
+    Standard_DomainError::Raise("Geom_BSplineCurve::SetVOrigin");
 
   Standard_Integer nbknots = vknots->Length();
   Standard_Integer nbpoles = poles->RowLength();
index d27abd9..163276a 100644 (file)
@@ -685,7 +685,8 @@ Standard_Real Geom2d_BSplineCurve::ReversedParameter( const Standard_Real U) con
 void Geom2d_BSplineCurve::Segment(const Standard_Real aU1,
                                  const Standard_Real aU2)
 {
-  Standard_DomainError_Raise_if ( aU2 < aU1, "Geom2d_BSplineCurve::Segment");
+  if (aU2 < aU1)
+    Standard_DomainError::Raise("Geom2d_BSplineCurve::Segment");
   //
   Standard_Real AbsUMax = Max(Abs(FirstParameter()),Abs(LastParameter()));
   Standard_Real Eps = Max (Epsilon(AbsUMax), Precision::PConfusion());
@@ -725,12 +726,10 @@ void Geom2d_BSplineCurve::Segment(const Standard_Real aU1,
   if (periodic) {
     Standard_Real Period = LastParameter() - FirstParameter();
     DU = U2 - U1;
-    while (DU > Period) {
-      DU -= Period;
-    }
-    if (DU <= Epsilon(Period)) {
+    if (DU - Period > Precision::PConfusion())
+      Standard_DomainError::Raise("Geom2d_BSplineCurve::Segment");
+    if (DU > Period)
       DU = Period;
-    }
   }
   //
   index = 0;
@@ -946,14 +945,14 @@ void Geom2d_BSplineCurve::SetPeriodic ()
 
 void Geom2d_BSplineCurve::SetOrigin(const Standard_Integer Index)
 {
-  Standard_NoSuchObject_Raise_if( !periodic,
-                                "Geom2d_BSplineCurve::SetOrigin");
+  if (!periodic)
+    Standard_NoSuchObject::Raise("Geom2d_BSplineCurve::SetOrigin");
   Standard_Integer i,k;
   Standard_Integer first = FirstUKnotIndex();
   Standard_Integer last  = LastUKnotIndex();
 
-  Standard_DomainError_Raise_if( (Index < first) || (Index > last),
-                               "Geom2d_BSplineCurve::SetOrigine");
+  if ((Index < first) || (Index > last))
+  Standard_DomainError::Raise("Geom2d_BSplineCurve::SetOrigin");
 
   Standard_Integer nbknots = knots->Length();
   Standard_Integer nbpoles = poles->Length();
index dd8383d..08aab57 100644 (file)
@@ -367,6 +367,8 @@ public:
   //! Exceptions
   //! Standard_DomainError if U2 is less than U1.
   //! raises if U2 < U1.
+  //! Standard_DomainError if U2 - U1 exceeds the period for periodic curves.
+  //! i.e. ((U2 - U1) - Period) > Precision::PConfusion().
   Standard_EXPORT void Segment (const Standard_Real U1, const Standard_Real U2);
   
   //! Modifies this BSpline curve by assigning the value K
@@ -609,38 +611,27 @@ public:
   Standard_EXPORT gp_Vec2d DN (const Standard_Real U, const Standard_Integer N) const Standard_OVERRIDE;
   
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT gp_Pnt2d LocalValue (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2) const;
   
+  //! Raised if FromK1 = ToK2.
   Standard_EXPORT void LocalD0 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt2d& P) const;
   
 
   //! Raised if the local continuity of the curve is not C1
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT void LocalD1 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt2d& P, gp_Vec2d& V1) const;
   
 
   //! Raised if the local continuity of the curve is not C2
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT void LocalD2 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const;
   
 
   //! Raised if the local continuity of the curve is not C3
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
-  //!
-  //! Raised if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT void LocalD3 (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2, gp_Vec2d& V3) const;
   
 
@@ -648,9 +639,6 @@ public:
   //! between the knot K1 and the knot K2.
   //! Raised if FromK1 = ToK2.
   //! Raised if N < 1.
-  //!
-  //! Raises if FromK1 and ToK2 are not in the range
-  //! [FirstUKnotIndex, LastUKnotIndex].
   Standard_EXPORT gp_Vec2d LocalDN (const Standard_Real U, const Standard_Integer FromK1, const Standard_Integer ToK2, const Standard_Integer N) const;
   
 
@@ -684,7 +672,8 @@ public:
   
   //! returns the knot values of the B-spline curve;
   //!
-  //! Raised if the length of K is not equal to the number of knots.
+  //! Raised K.Lower() is less than number of first knot or
+  //! K.Upper() is more than number of last knot.
   Standard_EXPORT void Knots (TColStd_Array1OfReal& K) const;
   
   //! returns the knot values of the B-spline curve;
@@ -696,7 +685,9 @@ public:
   //! Example :
   //! K = {k1, k1, k1, k2, k3, k3, k4, k4, k4}
   //!
-  //! Raised if the length of K is not equal to NbPoles + Degree + 1
+  //! Raised if K.Lower() is less than number of first knot
+  //! in knot sequence with repetitions or K.Upper() is more
+  //! than number of last knot in knot sequence with repetitions.
   Standard_EXPORT void KnotSequence (TColStd_Array1OfReal& K) const;
   
   //! Returns the knots sequence.
index 87cfdc2..64e80f9 100644 (file)
@@ -242,8 +242,7 @@ Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle
   Standard_Real uShift = 0, vShift = 0;
   mysurface->Bounds(U0,U1,V0,V1);
 
-  // cut segment from periodic surfaces for syncronization of pcurves ranges
-  // and surface bounds (issue 26138)
+  // fix bounds
   if (!PeriodU) {
     if (Umin < U0)
       Umin = U0;
@@ -258,6 +257,8 @@ Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle
     uShift = ShapeAnalysis::AdjustToPeriod(Umin, U0, U1);
     Umin += uShift;
     Umax += uShift;
+    if (Umax - Umin > U1 - U0)
+      Umax = Umin + (U1 - U0);
   }
   if (!PeriodV) {
     if (Vmin < V0)
@@ -273,44 +274,40 @@ Handle(IGESData_IGESEntity) GeomToIGES_GeomSurface::TransferSurface(const Handle
     vShift = ShapeAnalysis::AdjustToPeriod(Vmin, V0, V1);
     Vmin += vShift;
     Vmax += vShift;
-  }
-  if (PeriodU || PeriodV) {
-    Standard_Boolean isNeedSegment = Standard_True;
-    isNeedSegment = Abs(Umax-Umin) > Precision::PConfusion() && 
-                    Abs(Vmax-Vmin) > Precision::PConfusion();
-    Standard_Real uMaxShift = 0, vMaxShift = 0;
-    uMaxShift = ShapeAnalysis::AdjustToPeriod(Ufin, U0, U1);
-    vMaxShift = ShapeAnalysis::AdjustToPeriod(Vfin, V0, V1);
-    isNeedSegment &= 
-      (PeriodU && Abs(uShift - uMaxShift) > Precision::PConfusion()) ||
-      (PeriodV && Abs(vShift - vMaxShift) > Precision::PConfusion());
-    if (isNeedSegment) {
-      try {
-        OCC_CATCH_SIGNALS
-        Handle(Geom_BSplineSurface) bspl = Handle(Geom_BSplineSurface)::DownCast ( start->Copy() );
-        if ( ! bspl.IsNull() ) {
-          bspl->CheckAndSegment(Umin, Umax, Vmin, Vmax);
-          if ((U1 - U0) - (Umax - Umin) > Precision::PConfusion())
-            PeriodU = Standard_False;
-          if ((V1 - V0) - (Vmax - Vmin) > Precision::PConfusion())
-            PeriodV = Standard_False;
-            mysurface = bspl;
-        }
-      }
-      catch ( Standard_Failure ) {
-        #ifdef OCCT_DEBUG
-        cout << "Warning: GeomToIGES_GeomSurface: can't trim bspline" << endl;
-        cout << "Warning: Exception in Segment(): " ;
-        Standard_Failure::Caught()->Print(cout);
-        #endif
-      }
-    }
+    if (Vmax - Vmin > V1 - V0)
+      Vmax = Vmin + (V1 - V0);
   }
   //unperiodize surface to get neccessary for IGES standard number of knots and mults
   if ( mysurface->IsUPeriodic() ) {
+    // set new origin for periodic BSpline surfaces for synchronization of pcurves ranges
+    // and surface bounds (issue 26138)
+    if (mysurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
+      Standard_Real uMaxShift = 0;
+      uMaxShift = ShapeAnalysis::AdjustToPeriod(Ufin, U0, U1);
+      if (Abs(uShift - uMaxShift) > Precision::PConfusion()) {
+        Handle(Geom_BSplineSurface) aBspl = Handle(Geom_BSplineSurface)::DownCast (mysurface->Copy());
+        Standard_Integer aLeft, aRight;
+        aBspl->LocateU(Umin, Precision::PConfusion(), aLeft, aRight);
+        aBspl->SetUOrigin(aLeft);
+        mysurface = aBspl;
+      }
+    }
     mysurface->SetUNotPeriodic();
   }
   if ( mysurface->IsVPeriodic() ) {
+    // set new origin for periodic BSpline surfaces for synchronization of pcurves ranges
+    // and surface bounds (issue 26138)
+    if (mysurface->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
+      Standard_Real vMaxShift = 0;
+      vMaxShift = ShapeAnalysis::AdjustToPeriod(Vfin, V0, V1);
+      if (Abs(vShift - vMaxShift) > Precision::PConfusion()) {
+        Handle(Geom_BSplineSurface) aBspl = Handle(Geom_BSplineSurface)::DownCast (mysurface->Copy());
+        Standard_Integer aLeft, aRight;
+        aBspl->LocateV(Vmin, Precision::PConfusion(), aLeft, aRight);
+        aBspl->SetVOrigin(aLeft);
+        mysurface = aBspl;
+      }
+    }
     mysurface->SetVNotPeriodic();
   }
  
diff --git a/tests/bugs/iges/bug26931 b/tests/bugs/iges/bug26931
new file mode 100644 (file)
index 0000000..f7172bf
--- /dev/null
@@ -0,0 +1,11 @@
+#######################################################################
+# OCC26931: [Regression in 6.9.0] Exporting a face throws an exception
+#######################################################################
+
+# restore initial face
+restore [locate_data_file bug26931.brep] face
+set square 6416.6
+# export face to IGES 
+brepiges face ${imagedir}/${casename}.igs
+# import back to check similarity
+igesbrep ${imagedir}/${casename}.igs result *
index c10128b..641dad6 100755 (executable)
@@ -43,7 +43,7 @@ if { [llength ${bounds_list}] < 7 } {
 set ll1 [lindex [length res] end]
 puts "length1=${ll1}"
 
-segment res t3 t4
+segment res t1 t2
 set segment_list [dump res]
 
 puts ""