0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / GeometryTest / GeometryTest_CurveCommands.cxx
old mode 100755 (executable)
new mode 100644 (file)
index e400f75..03004ff
@@ -1,7 +1,19 @@
-// File:       DrawTrSurf_1.cxx
-// Created:    Thu Aug 12 19:33:03 1993
-// Author:     Bruno DUMORTIER
-//             <dub@topsn3>
+// Created on: 1993-08-12
+// Created by: Bruno DUMORTIER
+// Copyright (c) 1993-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// 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.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
 // 09/06/97 : JPI : suppression des commandes redondantes suite a la creation de GeomliteTest
 
 #include <GeometryTest.hxx>
@@ -137,17 +149,17 @@ static Standard_Integer polelaw (Draw_Interpretor& , Standard_Integer n, const c
 
   if (n < 3) return 1;
   Standard_Boolean periodic = Standard_False ;
-  Standard_Integer deg = atoi(a[2]);
-  Standard_Integer nbk = atoi(a[3]);
+  Standard_Integer deg = Draw::Atoi(a[2]);
+  Standard_Integer nbk = Draw::Atoi(a[3]);
   
   TColStd_Array1OfReal    knots(1, nbk);
   TColStd_Array1OfInteger mults(1, nbk);
   k = 4;
   Standard_Integer Sigma = 0;
   for (i = 1; i<=nbk; i++) {
-    knots( i) = atof(a[k]);
+    knots( i) = Draw::Atof(a[k]);
     k++;
-    mults( i) = atoi(a[k]);
+    mults( i) = Draw::Atoi(a[k]);
     Sigma += mults(i);
     k++;
   }
@@ -169,7 +181,7 @@ static Standard_Integer polelaw (Draw_Interpretor& , Standard_Integer n, const c
                                  flat_knots,
                                  schoenberg_points) ;
   for (i = 1; i <= np; i++) {
-    poles(i).SetCoord(schoenberg_points(i),atof(a[k]));
+    poles(i).SetCoord(schoenberg_points(i),Draw::Atof(a[k]));
     k++;
   }
     
@@ -254,9 +266,9 @@ static Standard_Integer gproject(Draw_Interpretor& di, Standard_Integer n, const
   Standard_Integer ONE = 1;
 
   if (n == 3)
-    sprintf(name,"p");
+    Sprintf(name,"p");
   else if (n == 4) {
-    sprintf(name,"%s",a[1]);
+    Sprintf(name,"%s",a[1]);
     ONE = 2;
   }
   else {
@@ -290,8 +302,8 @@ static Standard_Integer gproject(Draw_Interpretor& di, Standard_Integer n, const
   Handle(Geom2d_Curve) PCur2d; // Only for isoparametric projection
 
   for(k = 1; k <= Projector.NbCurves(); k++){
-    sprintf(newname,"%s_%d",name,k);
-    sprintf(newname1,"%s2d_%d",name,k);
+    Sprintf(newname,"%s_%d",name,k);
+    Sprintf(newname1,"%s2d_%d",name,k);
     if(Projector.IsSinglePnt(k, P2d)){
 //      cout<<"Part "<<k<<" of the projection is punctual"<<endl;
       Projector.GetSurface()->D0(P2d.X(), P2d.Y(), P);
@@ -406,7 +418,7 @@ static Standard_Integer project (Draw_Interpretor& di,
   Standard_Real U1,U2,V1,V2;
   GS->Bounds(U1,U2,V1,V2);
 
-  Standard_Boolean Verif = Standard_False, Extent = Standard_False;
+  Standard_Boolean Verif = Standard_False;
   Standard_Integer NbPoints=0;
 
   Standard_Integer index = 4;
@@ -414,18 +426,17 @@ static Standard_Integer project (Draw_Interpretor& di,
     if ( a[index][0] != '-') return 1;
 
     if ( a[index][1] == 'e') {
-      Standard_Real p = atof(a[index+1]);
+      Standard_Real p = Draw::Atof(a[index+1]);
       Standard_Real dU = p * (U2 - U1) / 100.;
       Standard_Real dV = p * (V2 - V1) / 100.;
       U1 -= dU; U2 += dU; V1 -= dV; V2 += dV;
-      Extent = Standard_True;
     }
     else if ( a[index][1] == 'v') {
       Verif = Standard_True;
-      NbPoints = atoi(a[index+1]);
+      NbPoints = Draw::Atoi(a[index+1]);
     }
     else if ( a[index][1] == 't') {
-      tolerance = atof(a[index+1]);
+      tolerance = Draw::Atof(a[index+1]);
     }
     index += 2;
   }
@@ -491,13 +502,13 @@ Standard_Integer projonplane(Draw_Interpretor& di,
   if ( C.IsNull()) return 1;
   
   Standard_Boolean Param = Standard_True;
-  if ((n == 5 && atoi(a[4]) == 0) ||
-      (n == 8 && atoi(a[7]) == 0)) Param = Standard_False;
+  if ((n == 5 && Draw::Atoi(a[4]) == 0) ||
+      (n == 8 && Draw::Atoi(a[7]) == 0)) Param = Standard_False;
 
   gp_Dir D;
   
   if ( n == 8) {
-    D = gp_Dir(atof(a[4]),atof(a[5]),atof(a[6]));
+    D = gp_Dir(Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]));
   }
   else { 
     D = Pl->Pln().Position().Direction();
@@ -523,9 +534,9 @@ static void solution(const Handle(GccInt_Bisec)& Bis,
 {
   char solname[200];
   if ( i == 0) 
-    sprintf(solname,"%s",name);
+    Sprintf(solname,"%s",name);
   else
-    sprintf(solname,"%s_%d",name,i);
+    Sprintf(solname,"%s_%d",name,i);
   const char* temp = solname; // pour portage WNT
 
   switch ( Bis->ArcType()) {
@@ -575,7 +586,7 @@ static Standard_Integer bisec (Draw_Interpretor& di,
          char solname[200];
          NbSol = Bis.NbSolutions();
          for ( i = 1; i <= NbSol; i++) {
-           sprintf(solname,"%s_%d",a[1],i);
+           Sprintf(solname,"%s_%d",a[1],i);
            const char* temp = solname; // pour portage WNT
            DrawTrSurf::Set(temp,new Geom2d_Line(Bis.ThisSolution(i)));
          }
@@ -750,74 +761,221 @@ static Standard_Integer bisec (Draw_Interpretor& di,
 
 static Standard_Integer movelaw (Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
-  Standard_Integer dimension,
-  ii,
-  condition=0,
-  error_status ;
+  Standard_Integer 
+    ii,
+    condition=0,
+    error_status ;
   Standard_Real u,
-  x,
-  tolerance,
-  tx ;
+    x,
+    tolerance,
+    tx ;
 
-  u = atof(a[2]);
-  x = atof(a[3]);
+  u = Draw::Atof(a[2]);
+  x = Draw::Atof(a[3]);
   tolerance = 1.0e-5 ;
-  dimension = 2 ;
   if (n < 5) {
-      return 1 ;
+    return 1 ;
   }
   Handle(Geom2d_BSplineCurve) G2 = DrawTrSurf::GetBSplineCurve2d(a[1]);
   if (!G2.IsNull()) {
-      tx = atof(a[4]) ;
-      if (n == 6) {
-       condition = Max(atoi(a[5]), -1)  ;
-       condition = Min(condition, G2->Degree()-1) ;
-      }
-      TColgp_Array1OfPnt2d   curve_poles(1,G2->NbPoles()) ;
-      TColStd_Array1OfReal    law_poles(1,G2->NbPoles()) ;
-      TColStd_Array1OfReal    law_knots(1,G2->NbKnots()) ;
-      TColStd_Array1OfInteger law_mults(1,G2->NbKnots()) ;
-
-      G2->Knots(law_knots) ;
-      G2->Multiplicities(law_mults) ;
-      G2->Poles(curve_poles) ;
-      for (ii = 1 ; ii <= G2->NbPoles() ; ii++) {
-       law_poles(ii) = curve_poles(ii).Coord(2) ;
-      }
+    tx = Draw::Atof(a[4]) ;
+    if (n == 6) {
+      condition = Max(Draw::Atoi(a[5]), -1)  ;
+      condition = Min(condition, G2->Degree()-1) ;
+    }
+    TColgp_Array1OfPnt2d   curve_poles(1,G2->NbPoles()) ;
+    TColStd_Array1OfReal    law_poles(1,G2->NbPoles()) ;
+    TColStd_Array1OfReal    law_knots(1,G2->NbKnots()) ;
+    TColStd_Array1OfInteger law_mults(1,G2->NbKnots()) ;
+
+    G2->Knots(law_knots) ;
+    G2->Multiplicities(law_mults) ;
+    G2->Poles(curve_poles) ;
+    for (ii = 1 ; ii <= G2->NbPoles() ; ii++) {
+      law_poles(ii) = curve_poles(ii).Coord(2) ;
+    }
 
-      Law_BSpline  a_law(law_poles,
-                        law_knots,
-                        law_mults,
-                        G2->Degree(),
-                        Standard_False) ;
-
-      a_law.MovePointAndTangent(u, 
-                             x, 
-                             tx,
-                             tolerance,
-                             condition,
-                             condition,
-                             error_status) ;
-
-      for (ii = 1 ; ii <= G2->NbPoles() ; ii++) {
-       curve_poles(ii).SetCoord(2,a_law.Pole(ii)) ;
-        G2->SetPole(ii,curve_poles(ii)) ;
-      }
+    Law_BSpline  a_law(law_poles,
+      law_knots,
+      law_mults,
+      G2->Degree(),
+      Standard_False) ;
+
+    a_law.MovePointAndTangent(u, 
+      x, 
+      tx,
+      tolerance,
+      condition,
+      condition,
+      error_status) ;
+
+    for (ii = 1 ; ii <= G2->NbPoles() ; ii++) {
+      curve_poles(ii).SetCoord(2,a_law.Pole(ii)) ;
+      G2->SetPole(ii,curve_poles(ii)) ;
+    }
 
-       
-      if (! error_status) {
-       Draw::Repaint();
-       }
-      else {
-       di << "Not enought degree of freedom increase degree please" << "\n";
-      }
-      
-    
+
+    if (! error_status) {
+      Draw::Repaint();
     }
+    else {
+      di << "Not enought degree of freedom increase degree please" << "\n";
+    }
+
+
+  }
   return 0;
 } 
 
 
+//Static method computing deviation of curve and polyline
+#include <math_PSO.hxx>
+#include <math_PSOParticlesPool.hxx>
+#include <math_MultipleVarFunctionWithHessian.hxx>
+#include <math_NewtonMinimum.hxx>
+
+class aMaxCCDist : public math_MultipleVarFunctionWithHessian
+{
+public:
+  aMaxCCDist(const Handle(Geom_Curve)& theCurve,
+             const Handle(Geom_BSplineCurve)& thePnts)
+: myCurve(theCurve),
+  myPnts(thePnts)
+  {
+  }
+
+  virtual Standard_Boolean Value (const math_Vector& X,
+                                  Standard_Real& F)
+  {
+    if (!CheckInputData(X(1)))
+    {
+      return Standard_False;
+    }
+    F = -myCurve->Value(X(1)).SquareDistance(myPnts->Value(X(1)));
+    return Standard_True;
+  }
+
+  
+  virtual Standard_Boolean Gradient (const math_Vector& X, math_Vector& G)
+  {
+    if (!CheckInputData(X(1)))
+    {
+      return Standard_False;
+    }
+    gp_Pnt aPnt1, aPnt2;
+    gp_Vec aVec1, aVec2;
+    myCurve->D1(X(1), aPnt1, aVec1);
+    myPnts->D1 (X(1), aPnt2, aVec2);
+
+    G(1) = 2 * (aPnt1.X() - aPnt2.X()) * (aVec1.X() - aVec2.X())
+         + 2 * (aPnt1.Y() - aPnt2.Y()) * (aVec1.Y() - aVec2.Y())
+         + 2 * (aPnt1.Z() - aPnt2.Z()) * (aVec1.Z() - aVec2.Z());
+    G(1) *= -1.0; // Maximum search.
+
+    return Standard_True;
+  }
+
+  virtual Standard_Boolean Values (const math_Vector& X, Standard_Real& F, math_Vector& G, math_Matrix& H)
+  {
+    if (Value(X, F) && Gradient(X, G))
+    {
+      gp_Pnt aPnt1, aPnt2;
+      gp_Vec aVec11, aVec12, aVec21, aVec22;
+      myCurve->D2(X(1), aPnt1, aVec11, aVec12);
+      myPnts->D2 (X(1), aPnt2, aVec21, aVec22);
+
+      H(1,1) = 2 * (aVec11.X() - aVec21.X()) * (aVec11.X() - aVec21.X())
+             + 2 * (aVec11.Y() - aVec21.Y()) * (aVec11.Y() - aVec21.Y())
+             + 2 * (aVec11.Z() - aVec21.Z()) * (aVec11.Z() - aVec21.Z())
+             + 2 * (aPnt1.X() - aPnt2.X()) * (aVec12.X() - aVec22.X())
+             + 2 * (aPnt1.Y() - aPnt2.Y()) * (aVec12.Y() - aVec22.Y())
+             + 2 * (aPnt1.Z() - aPnt2.Z()) * (aVec12.Z() - aVec22.Z());
+      H(1,1) *= -1.0; // Maximum search.
+
+      return Standard_True;
+    }
+    return Standard_False;
+  }
+
+  virtual Standard_Boolean Values (const math_Vector& X, Standard_Real& F, math_Vector& G)
+  {
+    return (Value(X, F) && Gradient(X, G));
+  }
+
+  virtual Standard_Integer NbVariables() const
+  {
+    return 1;
+  }
+
+private:
+  aMaxCCDist & operator = (const aMaxCCDist & theOther);
+
+  Standard_Boolean CheckInputData(Standard_Real theParam)
+  {
+    if (theParam < myCurve->FirstParameter() || 
+        theParam > myCurve->LastParameter())
+      return Standard_False;
+    return Standard_True;
+  }
+
+  const Handle(Geom_Curve)& myCurve;
+  const Handle(Geom_BSplineCurve)& myPnts;
+};
+
+
+static void ComputeDeviation(const Handle(Geom_Curve)& theCurve,
+                             const Handle(Geom_BSplineCurve)& thePnts,
+                             Standard_Real& theDmax,
+                             Standard_Real& theUfMax,
+                             Standard_Real& theUlMax,
+                             Standard_Integer& theImax)
+{
+  theDmax = 0.;
+  theUfMax = 0.;
+  theUlMax = 0.;
+  theImax = 0;
+
+  //take knots
+  Standard_Integer nbp = thePnts->NbKnots();
+  TColStd_Array1OfReal aKnots(1, nbp);
+  thePnts->Knots(aKnots);
+  math_Vector aLowBorder(1,1);
+  math_Vector aUppBorder(1,1);
+  math_Vector aSteps(1,1);
+
+  Standard_Integer i;
+  for(i = 1; i < nbp; ++i)
+  {
+    aLowBorder(1) = aKnots(i);
+    aUppBorder(1) = aKnots(i+1);
+    aSteps(1) =(aUppBorder(1) - aLowBorder(1)) * 0.01; // Run PSO on even distribution with 100 points.
+
+    Standard_Real aValue;
+    math_Vector aT(1,1);
+    aMaxCCDist aFunc(theCurve, thePnts);
+    math_PSO aFinder(&aFunc, aLowBorder, aUppBorder, aSteps); // Choose 32 best points from 100 above.
+    aFinder.Perform(aSteps, aValue, aT);
+    Standard_Real d = 0.;
+
+    math_NewtonMinimum anOptLoc(aFunc);
+    anOptLoc.Perform(aFunc, aT);
+
+    if (anOptLoc.IsDone())
+    {
+      d = -anOptLoc.Minimum();
+      if(d > theDmax)
+      {
+        theDmax = d;
+        theUfMax = aLowBorder(1);
+        theUlMax = aUppBorder(1);
+        theImax = i;
+      }
+    }
+  }
+  theDmax = Sqrt(theDmax); // Convert to Euclidean distance.
+}
+
+
 //=======================================================================
 //function : crvpoints
 //purpose  : 
@@ -829,17 +987,11 @@ static Standard_Integer crvpoints (Draw_Interpretor& di, Standard_Integer /*n*/,
   Standard_Real defl;
 
   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
-  defl = atof(a[3]);
+  defl = Draw::Atof(a[3]);
 
   GeomAdaptor_Curve GAC(C);
-
   GCPnts_QuasiUniformDeflection PntGen(GAC, defl);
-  //GCPnts_UniformDeflection PntGen(GAC, defl);
-//  Standard_Real uf = C->FirstParameter();
-//  Standard_Real ul = C->LastParameter();
-//  Standard_Real utol = Max(.001*(ul-uf), 1.e-7);
-//  GCPnts_TangentialDeflection PntGen(GAC, defl, 0.5*defl, 2, utol);
-  
+    
   if(!PntGen.IsDone()) {
     di << "Points generation failed" << "\n";
     return 1;
@@ -874,34 +1026,67 @@ static Standard_Integer crvpoints (Draw_Interpretor& di, Standard_Integer /*n*/,
   Standard_Real dmax = 0., ufmax = 0., ulmax = 0.;
   Standard_Integer imax = 0;
 
-  for(i = 1; i < nbp; ++i) {
-    Standard_Real uf = aKnots(i);
-    Standard_Real ul = aKnots(i+1);
+  //check deviation
+  ComputeDeviation(C,aPnts,dmax,ufmax,ulmax,imax);
+  di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << imax << "\n"; 
 
-    GeomAPI_ExtremaCurveCurve ECC(C, aPnts, uf, ul, uf, ul);
+  return 0;
+} 
 
-    Standard_Integer nbe = ECC.NbExtrema();
-    if(nbe > 0) {
-      Standard_Integer k;
-      Standard_Real d = 0.;
-      for(k = 1; k <= nbe; k++) {
-       if(ECC.Distance(k) > d) d = ECC.Distance(k);
-      }
+//=======================================================================
+//function : crvtpoints
+//purpose  : 
+//=======================================================================
 
-      if(d > dmax) {
-       dmax = d;
-       ufmax = uf;
-       ulmax = ul;
-       imax = i;
-      }
-    }
+static Standard_Integer crvtpoints (Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+  Standard_Integer i, nbp;
+  Standard_Real defl, angle = Precision::Angular();
+
+  Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
+  defl = Draw::Atof(a[3]);
+
+  if(n > 3)
+    angle = Draw::Atof(a[4]);
+
+  GeomAdaptor_Curve GAC(C);
+  GCPnts_TangentialDeflection PntGen(GAC, angle, defl, 2);
+  
+  nbp = PntGen.NbPoints();
+  di << "Nb points : " << nbp << "\n";
+
+  TColgp_Array1OfPnt aPoles(1, nbp);
+  TColStd_Array1OfReal aKnots(1, nbp);
+  TColStd_Array1OfInteger aMults(1, nbp);
+
+  for(i = 1; i <= nbp; ++i) {
+    aPoles(i) = PntGen.Value(i);
+    aKnots(i) = PntGen.Parameter(i);
+    aMults(i) = 1;
   }
+  
+  aMults(1) = 2;
+  aMults(nbp) = 2;
+
+  Handle(Geom_BSplineCurve) aPnts = new Geom_BSplineCurve(aPoles, aKnots, aMults, 1);
+  Handle(DrawTrSurf_BSplineCurve) aDrCrv = new DrawTrSurf_BSplineCurve(aPnts);
+
+  aDrCrv->ClearPoles();
+  Draw_Color aKnColor(Draw_or);
+  aDrCrv->SetKnotsColor(aKnColor);
+  aDrCrv->SetKnotsShape(Draw_Plus);
+
+  Draw::Set(a[1], aDrCrv);
+
+  Standard_Real dmax = 0., ufmax = 0., ulmax = 0.;
+  Standard_Integer imax = 0;
 
-  di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << i << "\n"; 
+  //check deviation
+  ComputeDeviation(C,aPnts,dmax,ufmax,ulmax,imax);
+  di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << imax << "\n"; 
 
   return 0;
 } 
-
 //=======================================================================
 //function : uniformAbscissa
 //purpose  : epa test (TATA-06-002 (Problem with GCPnts_UniformAbscissa class)
@@ -928,7 +1113,7 @@ static Standard_Integer uniformAbscissa (Draw_Interpretor& di, Standard_Integer
   }
 
   Standard_Integer nocp;
-  nocp = atoi(a[2]);
+  nocp = Draw::Atoi(a[2]);
   if(nocp < 2)
     return 1;
 
@@ -976,17 +1161,17 @@ static Standard_Integer EllipsUniformAbscissa (Draw_Interpretor& di, Standard_In
     return 1;  
   
   Standard_Real R1;
-  R1 = atof(a[1]);
+  R1 = Draw::Atof(a[1]);
   Standard_Real R2;
-  R2 = atof(a[2]);
+  R2 = Draw::Atof(a[2]);
 
   Standard_Integer nocp;
-  nocp = atoi(a[3]);
+  nocp = Draw::Atoi(a[3]);
   if(nocp < 2)
     return 1;
   
   //test nbPoints for Geom_Ellipse
-  Handle_Geom_Ellipse ellip;
+  Handle(Geom_Ellipse) ellip;
 
 
   try
@@ -1043,6 +1228,107 @@ static Standard_Integer EllipsUniformAbscissa (Draw_Interpretor& di, Standard_In
   return 0;
 }
 
+//=======================================================================
+//function : discrCurve
+//purpose  :
+//=======================================================================
+static Standard_Integer discrCurve(Draw_Interpretor& di, Standard_Integer theArgNb, const char** theArgVec)
+{
+  if (theArgNb < 3)
+  {
+    di << "Invalid number of parameters.\n";
+    return 1;
+  }
+
+  Handle(Geom_Curve) aCurve = DrawTrSurf::GetCurve(theArgVec[2]);
+  if (aCurve.IsNull())
+  {
+    di << "Curve is NULL.\n";
+    return 1;
+  }
+
+  Standard_Integer aSrcNbPnts = 0;
+  Standard_Boolean isUniform = Standard_False;
+  for (Standard_Integer anArgIter = 3; anArgIter < theArgNb; ++anArgIter)
+  {
+    TCollection_AsciiString anArg     (theArgVec[anArgIter]);
+    TCollection_AsciiString anArgCase (anArg);
+    anArgCase.LowerCase();
+    if (anArgCase == "nbpnts")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        di << "Value for argument '" << anArg << "' is absent.\n";
+        return 1;
+      }
+
+      aSrcNbPnts = Draw::Atoi (theArgVec[anArgIter]);
+    }
+    else if (anArgCase == "uniform")
+    {
+      if (++anArgIter >= theArgNb)
+      {
+        di << "Value for argument '" << anArg << "' is absent.\n";
+        return 1;
+      }
+
+      isUniform = (Draw::Atoi (theArgVec[anArgIter]) == 1);
+    }
+    else
+    {
+      di << "Invalid argument '" << anArg << "'.\n";
+      return 1;
+    }
+  }
+
+  if (aSrcNbPnts < 2)
+  {
+    di << "Invalid count of points.\n";
+    return 1;
+  }
+
+  if (!isUniform)
+  {
+    di << "Invalid type of discretization.\n";
+    return 1;
+  }
+
+  GeomAdaptor_Curve aCurveAdaptor(aCurve);
+  GCPnts_UniformAbscissa aSplitter(aCurveAdaptor, aSrcNbPnts, Precision::Confusion());
+  if (!aSplitter.IsDone())
+  {
+    di << "Error: Invalid result.\n";
+    return 0;
+  }
+
+  const Standard_Integer aDstNbPnts = aSplitter.NbPoints();
+
+  if (aDstNbPnts < 2)
+  {
+    di << "Error: Invalid result.\n";
+    return 0;
+  }
+
+  TColgp_Array1OfPnt aPoles(1, aDstNbPnts);
+  TColStd_Array1OfReal aKnots(1, aDstNbPnts);
+  TColStd_Array1OfInteger aMultiplicities(1, aDstNbPnts);
+
+  for (Standard_Integer aPntIter = 1; aPntIter <= aDstNbPnts; ++aPntIter)
+  {
+    aPoles.ChangeValue(aPntIter) = aCurveAdaptor.Value(aSplitter.Parameter(aPntIter));
+    aKnots.ChangeValue(aPntIter) = (aPntIter - 1) / (aDstNbPnts - 1.0);
+    aMultiplicities.ChangeValue(aPntIter) = 1;
+  }
+  aMultiplicities.ChangeValue(1) = 2;
+  aMultiplicities.ChangeValue(aDstNbPnts) = 2;
+
+  Handle(Geom_BSplineCurve) aPolyline =
+    new Geom_BSplineCurve(aPoles, aKnots, aMultiplicities, 1);
+  DrawTrSurf::Set(theArgVec[1], aPolyline);
+
+  return 0;
+}
+
 //=======================================================================
 //function : mypoints
 //purpose  : 
@@ -1054,8 +1340,8 @@ static Standard_Integer mypoints (Draw_Interpretor& di, Standard_Integer /*n*/,
   Standard_Real defl;
 
   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
-  defl = atof(a[3]);
-  const Handle(Geom_BSplineCurve)& aBS = Handle(Geom_BSplineCurve)::DownCast(C);
+  defl = Draw::Atof(a[3]);
+  Handle(Geom_BSplineCurve) aBS (Handle(Geom_BSplineCurve)::DownCast(C));
 
   if(aBS.IsNull()) return 1;
 
@@ -1160,32 +1446,10 @@ static Standard_Integer mypoints (Draw_Interpretor& di, Standard_Integer /*n*/,
 
   Draw::Set(a[1], aDrCrv);
 
-  Standard_Real dmax = 0., ufmax = 0., ulmax = 0., uf, ul;
+  Standard_Real dmax = 0., ufmax = 0., ulmax = 0.;
   Standard_Integer imax = 0;
 
-  for(i = 1; i < nbp; ++i) {
-    uf = aKnots(i);
-    ul = aKnots(i+1);
-
-    GeomAPI_ExtremaCurveCurve ECC(C, aPnts, uf, ul, uf, ul);
-
-    Standard_Integer nbe = ECC.NbExtrema();
-    if(nbe > 0) {
-      Standard_Integer k;
-      Standard_Real d = 0.;
-      for(k = 1; k <= nbe; k++) {
-       if(ECC.Distance(k) > d) d = ECC.Distance(k);
-      }
-
-      if(d > dmax) {
-       dmax = d;
-       ufmax = uf;
-       ulmax = ul;
-       imax = i;
-      }
-    }
-  }
-
+  ComputeDeviation(C,aPnts,dmax,ufmax,ulmax,imax);
   di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << imax << "\n"; 
 
   return 0;
@@ -1204,7 +1468,7 @@ static Standard_Integer surfpoints (Draw_Interpretor& /*di*/, Standard_Integer /
   Standard_Real defl;
 
   Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[2]);
-  defl = atof(a[3]);
+  defl = Draw::Atof(a[3]);
 
   Handle(GeomAdaptor_HSurface) AS = new GeomAdaptor_HSurface(S);
 
@@ -1261,144 +1525,214 @@ static Standard_Integer surfpoints (Draw_Interpretor& /*di*/, Standard_Integer /
 //function : intersect
 //purpose  : 
 //=======================================================================
-static Standard_Integer intersection (Draw_Interpretor& di, Standard_Integer n, const char** a)
+static Standard_Integer intersection (Draw_Interpretor& di, 
+                                      Standard_Integer n, const char** a)
 {
-  if (n < 4) {
+  if (n < 4)
     return 1;
-  }
+
   //
   Handle(Geom_Curve) GC1;
   Handle(Geom_Surface) GS1 = DrawTrSurf::GetSurface(a[2]);
-  if (GS1.IsNull()) {
+  if (GS1.IsNull())
+  {
     GC1 = DrawTrSurf::GetCurve(a[2]);
     if (GC1.IsNull())
       return 1;
   }
+
   //
   Handle(Geom_Surface) GS2 = DrawTrSurf::GetSurface(a[3]);
-  if (GS2.IsNull()) {
+  if (GS2.IsNull())
     return 1;
-  }
+
   //
   Standard_Real tol = Precision::Confusion();
-  if (n == 5 || n == 9 || n == 13 || n == 17) tol = atof(a[n-1]);
+  if (n == 5 || n == 9 || n == 13 || n == 17)
+    tol = Draw::Atof(a[n-1]);
+
   //
   Handle(Geom_Curve) Result;
   gp_Pnt             Point;
+
   //
-  if (GC1.IsNull()) {
+  if (GC1.IsNull())
+  {
     GeomInt_IntSS Inters;
     //
     // Surface Surface
-    if (n <= 5) {
+    if (n <= 5)
+    {
       // General case
       Inters.Perform(GS1,GS2,tol,Standard_True);
     }
-    else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 16 || n == 17) {
+    else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 16 || n == 17)
+    {
       Standard_Boolean useStart = Standard_True, useBnd = Standard_True;
       Standard_Integer ista1=0,ista2=0,ibnd1=0,ibnd2=0;
       Standard_Real UVsta[4];
       Handle(GeomAdaptor_HSurface) AS1,AS2;
+
       //
-      if (n <= 9) {        // user starting point
+      if (n <= 9)          // user starting point
+      {
         useBnd = Standard_False;
-        ista1 = 4; ista2 = 7;
+        ista1 = 4;
+        ista2 = 7;
       }
-      else if (n <= 13) {        // user bounding
+      else if (n <= 13)   // user bounding
+      {
         useStart = Standard_False;
         ibnd1 = 4; ibnd2 = 11;
       }
-      else {        // both user starting point and bounding
+      else        // both user starting point and bounding
+      {
         ista1 = 4; ista2 = 7;
         ibnd1 = 8; ibnd2 = 15;
       }
+
       if (useStart)
+      {
         for (Standard_Integer i=ista1; i <= ista2; i++)
-          UVsta[i-ista1] = atof(a[i]);
-      if (useBnd) {
+        {
+          UVsta[i-ista1] = Draw::Atof(a[i]);
+        }
+      }
+
+      if (useBnd)
+      {
         Standard_Real UVbnd[8];
         for (Standard_Integer i=ibnd1; i <= ibnd2; i++)
-          UVbnd[i-ibnd1] = atof(a[i]);
+          UVbnd[i-ibnd1] = Draw::Atof(a[i]);
+
         AS1 = new GeomAdaptor_HSurface(GS1,UVbnd[0],UVbnd[1],UVbnd[2],UVbnd[3]);
         AS2 = new GeomAdaptor_HSurface(GS2,UVbnd[4],UVbnd[5],UVbnd[6],UVbnd[7]);
       }
+
       //
-      if (useStart && !useBnd) {
+      if (useStart && !useBnd)
+      {
         Inters.Perform(GS1,GS2,tol,UVsta[0],UVsta[1],UVsta[2],UVsta[3]);
       }
-      else if (!useStart && useBnd) {
+      else if (!useStart && useBnd)
+      {
         Inters.Perform(AS1,AS2,tol);
       }
-      else {
+      else
+      {
         Inters.Perform(AS1,AS2,tol,UVsta[0],UVsta[1],UVsta[2],UVsta[3]);
       }
-    }//else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 16 || n == 17) {
-    else {
+    }//else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 16 || n == 17)
+    else
+    {
       di<<"incorrect number of arguments"<<"\n";
       return 1;
     }
+
     //
-    if (!Inters.IsDone()) {
+    if (!Inters.IsDone())
+    {
+      di<<"No intersections found!"<<"\n";
+
       return 1;
     }
+
     //
     char buf[1024];
     Standard_Integer i, aNbLines, aNbPoints; 
-      //
+
+    //
     aNbLines = Inters.NbLines();
-    if (aNbLines >= 2) {
-      for (i=1; i<=aNbLines; ++i) {
-       sprintf(buf, "%s_%d",a[1],i);
-       Result = Inters.Line(i);
-       const char* temp = buf; 
-       DrawTrSurf::Set(temp,Result);
+    if (aNbLines >= 2)
+    {
+      for (i=1; i<=aNbLines; ++i)
+      {
+        Sprintf(buf, "%s_%d",a[1],i);
+        di << buf << " ";
+        Result = Inters.Line(i);
+        const char* temp = buf;
+        DrawTrSurf::Set(temp,Result);
       }
     }
-    else if (aNbLines == 1) {
+    else if (aNbLines == 1)
+    {
       Result = Inters.Line(1);
+      Sprintf(buf,"%s",a[1]);
+      di << buf << " ";
       DrawTrSurf::Set(a[1],Result);
     }
+
     //
     aNbPoints=Inters.NbPoints();
-    for (i=1; i<=aNbPoints; ++i) {
+    for (i=1; i<=aNbPoints; ++i)
+    {
       Point=Inters.Point(i);
-      sprintf(buf,"%s_p_%d",a[1],i);
-      const char* temp =buf;
+      Sprintf(buf,"%s_p_%d",a[1],i);
+      di << buf << " ";
+      const char* temp = buf;
       DrawTrSurf::Set(temp, Point);
     }
-  }// if (GC1.IsNull()) {
-  //
-  else {
+  }// if (GC1.IsNull())
+  else
+  {
     // Curve Surface
     GeomAPI_IntCS Inters(GC1,GS2);
+
     //
-    if (!Inters.IsDone()) return 1;
-    
+    if (!Inters.IsDone())
+    {
+      di<<"No intersections found!"<<"\n";
+      return 1;
+    }
+
     Standard_Integer nblines = Inters.NbSegments();
     Standard_Integer nbpoints = Inters.NbPoints();
-    if ( (nblines+nbpoints) >= 2) {
-      char newname[1024];
+
+    char newname[1024];
+
+    if ( (nblines+nbpoints) >= 2)
+    {
       Standard_Integer i;
       Standard_Integer Compt = 1;
-      for (i = 1; i <= nblines; i++, Compt++) {
-       sprintf(newname,"%s_%d",a[1],Compt);
-       Result = Inters.Segment(i);
-       const char* temp = newname; // pour portage WNT
-       DrawTrSurf::Set(temp,Result);
+
+      if(nblines >= 1)
+        cout << "   Lines: " << endl;
+
+      for (i = 1; i <= nblines; i++, Compt++)
+      {
+        Sprintf(newname,"%s_%d",a[1],Compt);
+        di << newname << " ";
+        Result = Inters.Segment(i);
+        const char* temp = newname; // pour portage WNT
+        DrawTrSurf::Set(temp,Result);
       }
-      for (i = 1; i <= nbpoints; i++, Compt++) {
-       sprintf(newname,"%s_%d",a[1],i);
-       Point = Inters.Point(i);
-       const char* temp = newname; // pour portage WNT
-       DrawTrSurf::Set(temp,Point);
+
+      if(nbpoints >= 1)
+        cout << "   Points: " << endl;
+
+      const Standard_Integer imax = nblines+nbpoints;
+
+      for (/*i = 1*/; i <= imax; i++, Compt++)
+      {
+        Sprintf(newname,"%s_%d",a[1],i);
+        di << newname << " ";
+        Point = Inters.Point(i);
+        const char* temp = newname; // pour portage WNT
+        DrawTrSurf::Set(temp,Point);
       }
     }
-    else if (nblines == 1) {
+    else if (nblines == 1)
+    {
       Result = Inters.Segment(1);
+      Sprintf(newname,"%s",a[1]);
+      di << newname << " ";
       DrawTrSurf::Set(a[1],Result);
     }
-    else if (nbpoints == 1) {
+    else if (nbpoints == 1)
+    {
       Point = Inters.Point(1);
+      Sprintf(newname,"%s",a[1]);
+      di << newname << " ";
       DrawTrSurf::Set(a[1],Point);
     }
   }
@@ -1407,6 +1741,51 @@ static Standard_Integer intersection (Draw_Interpretor& di, Standard_Integer n,
   return 0;
 }
 
+//=======================================================================
+//function : GetCurveContinuity
+//purpose  : Returns the continuity of the given curve
+//=======================================================================
+static Standard_Integer GetCurveContinuity( Draw_Interpretor& theDI,
+                                            Standard_Integer theNArg,
+                                            const char** theArgv)
+{
+  if(theNArg != 2)
+  {
+    theDI << "Use: getcurvcontinuity {curve or 2dcurve} \n";
+    return 1;
+  }
+
+  char aContName[7][3] = {"C0",   //0
+                          "G1",   //1
+                          "C1",   //2
+                          "G2",   //3
+                          "C2",   //4
+                          "C3",   //5
+                          "CN"};  //6
+
+  Handle(Geom2d_Curve) GC2d;
+  Handle(Geom_Curve) GC3d = DrawTrSurf::GetCurve(theArgv[1]);
+  if(GC3d.IsNull())
+  {
+    GC2d = DrawTrSurf::GetCurve2d(theArgv[1]);
+    if(GC2d.IsNull())
+    {
+      theDI << "Argument is not a 2D or 3D curve!\n";
+      return 1;
+    }
+    else
+    {
+      theDI << theArgv[1] << " has " << aContName[GC2d->Continuity()] << " continuity.\n";
+    }
+  }
+  else
+  {
+    theDI << theArgv[1] << " has " << aContName[GC3d->Continuity()] << " continuity.\n";
+  }
+
+  return 0;
+}
+
 //=======================================================================
 //function : CurveCommands
 //purpose  : 
@@ -1478,6 +1857,11 @@ void  GeometryTest::CurveCommands(Draw_Interpretor& theCommands)
                  "crvpoints result curv deflection",
                  __FILE__,
                  crvpoints,g);
+
+  theCommands.Add("crvtpoints",
+                 "crvtpoints result curv deflection angular deflection - tangential deflection points",
+                 __FILE__,
+                 crvtpoints,g);
   
   theCommands.Add("uniformAbscissa",
                  "uniformAbscissa Curve nbPnt",
@@ -1488,6 +1872,13 @@ void  GeometryTest::CurveCommands(Draw_Interpretor& theCommands)
                  "uniformAbscissaEl maxR minR nbPnt",
                  __FILE__,  EllipsUniformAbscissa,g);
 
+  theCommands.Add("discrCurve",
+    "discrCurve polyline curve params\n"
+    "Approximates a curve by a polyline (first degree B-spline).\n"
+    "nbPnts number - creates polylines with the number points\n"
+    "uniform 0 | 1 - creates polyline with equal length segments",
+    __FILE__,  discrCurve, g);
+
   theCommands.Add("mypoints",
                  "mypoints result curv deflection",
                  __FILE__,
@@ -1497,5 +1888,11 @@ void  GeometryTest::CurveCommands(Draw_Interpretor& theCommands)
                  __FILE__,
                  surfpoints,g);
 
+  theCommands.Add("getcurvcontinuity",
+                 "getcurvcontinuity {curve or 2dcurve}: \n\tReturns the continuity of the given curve",
+                 __FILE__,
+                 GetCurveContinuity,g);
+
+
 }