0027875: GeomFill_NSections constructor crash on sequence of curve containing only...
[occt.git] / src / GeomFill / GeomFill_NSections.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 19f4ddb..a7a2ad4
@@ -1,23 +1,18 @@
 // Created on: 1998-12-14
 // Created by: Joelle CHAUVET
 // Copyright (c) 1998-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// 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.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 // Modified:    Fri Jan  8 15:47:20 1999
 //              enfin un calcul exact pour D1 et D2
 // Modified:    Mon Jan 18 11:06:46 1999
 //              mise au point de D1, D2 et IsConstant
 
-#include <stdio.h>
-
-#include <GeomFill_NSections.ixx>
-#include <GeomFill_SectionGenerator.hxx>
-#include <GeomFill_Line.hxx>
-#include <GeomFill_AppSurf.hxx>
-
-#include <GeomConvert.hxx>
+#include <BSplCLib.hxx>
 #include <Convert_ParameterisationType.hxx>
-
-#include <Geom_Geometry.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_BSplineSurface.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
 #include <Geom_BSplineCurve.hxx>
+#include <Geom_BSplineSurface.hxx>
 #include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Geometry.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <GeomAdaptor_Surface.hxx>
-#include <Geom_TrimmedCurve.hxx>
-
-#include <GCPnts_AbscissaPoint.hxx>
-#include <TColgp_Array2OfPnt.hxx>
+#include <GeomConvert.hxx>
+#include <GeomFill_AppSurf.hxx>
+#include <GeomFill_Line.hxx>
+#include <GeomFill_NSections.hxx>
+#include <GeomFill_SectionGenerator.hxx>
+#include <gp_Circ.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Pnt.hxx>
+#include <Precision.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <Standard_Type.hxx>
 #include <TColGeom_Array1OfCurve.hxx>
-#include <TColStd_Array1OfReal.hxx>
+#include <TColgp_Array2OfPnt.hxx>
 #include <TColStd_Array1OfInteger.hxx>
-#include <BSplCLib.hxx>
-#include <Precision.hxx>
+#include <TColStd_Array1OfReal.hxx>
 
-#include <gp_Lin.hxx>
-#include <gp_Circ.hxx>
+#include <stdio.h>
+IMPLEMENT_STANDARD_RTTIEXT(GeomFill_NSections,GeomFill_SectionLaw)
 
-#ifdef DEB
+#ifdef OCCT_DEBUG
 # ifdef DRAW
 #  include <DrawTrSurf.hxx>
+#include <Geom_Curve.hxx>
 # endif
 static Standard_Boolean Affich = 0;
 static Standard_Integer NbSurf = 0;
 #endif
 
-#ifdef DEB
+#ifdef OCCT_DEBUG
 // verification des fonctions de derivation D1 et D2 par differences finies
 Standard_Boolean verifD1(const TColgp_Array1OfPnt& P1,
                         const TColStd_Array1OfReal& W1,
@@ -152,7 +149,7 @@ Standard_Boolean verifD2(const TColgp_Array1OfVec& DP1,
 #endif
 
 // fonction d'evaluation des poles et des poids de mySurface pour D1 et D2
-static void ResultEval(const Handle_Geom_BSplineSurface& surf,
+static void ResultEval(const Handle(Geom_BSplineSurface)& surf,
                        const Standard_Real V,
                        const Standard_Integer deriv,
                        TColStd_Array1OfReal& Result)
@@ -211,6 +208,10 @@ static void ResultEval(const Handle_Geom_BSplineSurface& surf,
 GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC)
 {
   mySections = NC;
+  UFirst = 0.;
+  ULast = 1.;
+  VFirst = 0.;
+  VLast = 1.;
   myRefSurf.Nullify();
   ComputeSurface();
 }
@@ -367,7 +368,7 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
   if (NullWeight) return Standard_False;
 
   // verif par diff finies sous debug sauf pour les surfaces periodiques
-#ifdef DEB
+#ifdef OCCT_DEBUG
   if (!mySurface->IsVPeriodic()) {
     Standard_Real pas = 1.e-6, wTol = 1.e-4, pTol = 1.e-3;
     Standard_Real V1,V2;
@@ -461,7 +462,7 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
   if (NullWeight) return Standard_False;
 
   // verif par diff finies sous debug sauf pour les surfaces periodiques
-#ifdef DEB
+#ifdef OCCT_DEBUG
   if (!mySurface->IsVPeriodic()) {
     Standard_Real V1,V2;
     Standard_Boolean ok1,ok2;
@@ -523,26 +524,27 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
     Standard_Real myPres3d = 1.e-06;
     Standard_Integer i,j,jdeb=1,jfin=mySections.Length();
     
+    if (jfin <= jdeb)
+    {
+      //We will not be able to create surface from single curve.
+      return;
+    }
+
     GeomFill_SectionGenerator section;
     Handle(Geom_BSplineSurface) surface;
-    Handle(Geom_TrimmedCurve) curvTrim;
-    Handle(Geom_BSplineCurve) curvBS, curvBS1;
-    Handle(Geom_Curve) curv =  mySections(1);
 
     for (j=jdeb; j<=jfin; j++) {
 
         // read the j-th curve
-        curv =  mySections(j);
-        curvTrim = new Geom_TrimmedCurve(curv,
-                                         curv->FirstParameter(),
-                                         curv->LastParameter());
+        Handle(Geom_Curve) curv = mySections(j);
         
-        // transformation en BSpline reparametree sur [UFirst,ULast]
-        curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
-        if (curvBS.IsNull()) {
-          Convert_ParameterisationType ParamType = Convert_QuasiAngular;
-          curvBS = GeomConvert::CurveToBSplineCurve(curvTrim,ParamType);
+        // transformation to BSpline reparametrized to [UFirst,ULast]
+        Handle(Geom_BSplineCurve) curvBS = Handle(Geom_BSplineCurve)::DownCast (curv);
+        if (curvBS.IsNull())
+        {
+          curvBS = GeomConvert::CurveToBSplineCurve (curv, Convert_QuasiAngular);
         }
+
         TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
         curvBS->Knots(BSK);
         BSplCLib::Reparametrize(UFirst,ULast,BSK);
@@ -573,16 +575,20 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 
     Standard_Integer Nbcurves = mySections.Length();
     Standard_Integer Nbpar = myParams.Length();
-    Handle(TColStd_HArray1OfReal) HPar
-      = new TColStd_HArray1OfReal(1,Nbpar);
-    for (i=1;i<=Nbpar;i++) {
-      HPar->SetValue(i,myParams(i));
+    if (Nbpar > 0)
+    {
+      Handle(TColStd_HArray1OfReal) HPar
+        = new TColStd_HArray1OfReal(1, Nbpar);
+      for (i = 1; i <= Nbpar; i++) {
+        HPar->SetValue(i, myParams(i));
+      }
+      section.SetParam(HPar);
     }
-    section.SetParam(HPar);
     section.Perform(Precision::PConfusion());
+    
     Handle(GeomFill_Line) line = new GeomFill_Line(Nbcurves);
     Standard_Integer nbIt = 0, degmin = 2, degmax = 6;
-    Standard_Boolean knownP = Standard_True;
+    Standard_Boolean knownP = Nbpar > 0;
     GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt, knownP);
     Standard_Boolean SpApprox = Standard_True;
     anApprox.Perform(line, section, SpApprox);
@@ -621,7 +627,7 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
   if (mySurface->VDegree()<2) {
     mySurface->IncreaseDegree(mySurface->UDegree(),2);
   }
-#ifdef DEB
+#ifdef OCCT_DEBUG
   NbSurf++;
   if (Affich) {
 #ifdef DRAW
@@ -641,9 +647,12 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
                                             Standard_Integer& NbKnots,
                                             Standard_Integer& Degree) const
 {
-   NbPoles = mySurface->NbUPoles();
-   NbKnots = mySurface->NbUKnots();
-   Degree  = mySurface->UDegree();
+  if (mySurface.IsNull())
+    return;
+  
+  NbPoles = mySurface->NbUPoles();
+  NbKnots = mySurface->NbUKnots();
+  Degree  = mySurface->UDegree();
 }
 
 //=======================================================
@@ -651,7 +660,8 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 //=======================================================
  void GeomFill_NSections::Knots(TColStd_Array1OfReal& TKnots) const
 {
-  mySurface->UKnots(TKnots);
+  if (!mySurface.IsNull())
+    mySurface->UKnots(TKnots);
 }
 
 //=======================================================
@@ -659,7 +669,8 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 //=======================================================
  void GeomFill_NSections::Mults(TColStd_Array1OfInteger& TMults) const
 {
-  mySurface->UMultiplicities(TMults);
+  if (!mySurface.IsNull())
+    mySurface->UMultiplicities(TMults);
 }
 
 
@@ -668,7 +679,10 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 //=======================================================
  Standard_Boolean GeomFill_NSections::IsRational() const
 {
-  return mySurface->IsURational();
+  if (!mySurface.IsNull())
+    return mySurface->IsURational();
+
+  return Standard_False;
 }
 
 //=======================================================
@@ -676,7 +690,10 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 //=======================================================
  Standard_Boolean GeomFill_NSections::IsUPeriodic() const
 {
-  return  mySurface->IsUPeriodic();
+  if (!mySurface.IsNull())
+    return  mySurface->IsUPeriodic();
+
+  return Standard_False;
 }
 
 //=======================================================
@@ -684,7 +701,10 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 //=======================================================
  Standard_Boolean GeomFill_NSections::IsVPeriodic() const
 {
-  return  mySurface->IsVPeriodic();
+  if (!mySurface.IsNull())
+    return  mySurface->IsVPeriodic();
+
+  return Standard_False;
 }
 
 //=======================================================
@@ -692,6 +712,9 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 //=======================================================
  Standard_Integer GeomFill_NSections::NbIntervals(const GeomAbs_Shape S) const
 {
+  if (mySurface.IsNull())
+    return 0;
+
   GeomAdaptor_Surface AdS(mySurface);
   return AdS.NbVIntervals(S);
 }
@@ -703,6 +726,9 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
  void GeomFill_NSections::Intervals(TColStd_Array1OfReal& T,
                                          const GeomAbs_Shape S) const
 {
+  if (mySurface.IsNull())
+    return;
+
   GeomAdaptor_Surface AdS(mySurface);
   AdS.VIntervals(T,S);
 }
@@ -763,6 +789,9 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
   gp_Pnt P, Bary;
   Bary.SetCoord(0., 0., 0.);
 
+  if (mySurface.IsNull())
+    return Bary;
+
   Standard_Integer ii,jj;
   Standard_Real U0, U1, V0, V1;
   mySurface->Bounds(U0,U1,V0,V1);
@@ -801,6 +830,9 @@ GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
 //=======================================================
 void GeomFill_NSections::GetMinimalWeight(TColStd_Array1OfReal& Weights) const
 {
+  if (mySurface.IsNull())
+    return;
+
   if (mySurface->IsURational()) {
     Standard_Integer NbU = mySurface->NbUPoles(),
                      NbV = mySurface->NbVPoles();