0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / GeomliteTest / GeomliteTest_CurveCommands.cxx
index 3491988..74a90ba 100644 (file)
@@ -5,8 +5,8 @@
 //
 // 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 version 2.1 as published
+// 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.
 #include <GeomAdaptor_HCurve.hxx>
 #include <Approx_CurvilinearParameter.hxx>
 #include <Approx_CurveOnSurface.hxx>
-#ifdef WNT
+#include <Geom_BSplineSurface.hxx>
+
+#include <AppCont_Function.hxx>
+#include <Adaptor3d_HCurve.hxx>
+#include <GeomAdaptor_HCurve.hxx>
+#include <Approx_FitAndDivide.hxx>
+#include <Convert_CompBezierCurvesToBSplineCurve.hxx>
+
+#ifdef _WIN32
 Standard_IMPORT Draw_Viewer dout;
 #endif
 
+//Class is used in fitcurve
+class CurveEvaluator : public AppCont_Function
+
+{
+
+public:
+  Handle(Adaptor3d_HCurve) myCurve;
+
+  CurveEvaluator(const Handle(Adaptor3d_HCurve)& C)
+    : myCurve(C)
+  {
+    myNbPnt = 1;
+    myNbPnt2d = 0;
+  }
+
+  Standard_Real FirstParameter() const
+  {
+    return myCurve->FirstParameter();
+  }
+
+  Standard_Real LastParameter() const
+  {
+    return myCurve->LastParameter();
+  }
+
+  Standard_Boolean Value(const Standard_Real   theT,
+    NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
+    NCollection_Array1<gp_Pnt>&   thePnt) const
+  {
+    thePnt(1) = myCurve->Value(theT);
+    return Standard_True;
+  }
+
+  Standard_Boolean D1(const Standard_Real   theT,
+    NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
+    NCollection_Array1<gp_Vec>&   theVec) const
+  {
+    gp_Pnt aDummyPnt;
+    myCurve->D1(theT, aDummyPnt, theVec(1));
+    return Standard_True;
+  }
+};
+
+
 //=======================================================================
 //function : anacurve
 //purpose  : 
@@ -585,7 +637,7 @@ static Standard_Integer cmovetangent (Draw_Interpretor& di, Standard_Integer n,
        Draw::Repaint();
        }
       else {
-       di << "Not enought degree of freedom increase degree please" << "\n";
+       di << "Not enought degree of freedom increase degree please\n";
       }
       
       return 0;
@@ -616,7 +668,7 @@ static Standard_Integer cmovetangent (Draw_Interpretor& di, Standard_Integer n,
        Draw::Repaint();
        }
       else {
-       di << "Not enought degree of freedom increase degree please" << "\n";
+       di << "Not enought degree of freedom increase degree please\n";
       }
       
       return 0;
@@ -786,11 +838,11 @@ static Standard_Integer cremknot (Draw_Interpretor& di, Standard_Integer n, cons
 
   if (!GBs.IsNull()) {
     if (!GBs->RemoveKnot(index,mult,tol))
-      di << "Remove knots failed"<<"\n";
+      di << "Remove knots failed\n";
   }
   else {
     if (!GBs2d->RemoveKnot(index,mult,tol))
-      di << "Remove knots failed"<<"\n";
+      di << "Remove knots failed\n";
   }
 
   Draw::Repaint();
@@ -920,15 +972,15 @@ static Standard_Integer cfindp (Draw_Interpretor& , Standard_Integer n, const ch
     if (!DBs.IsNull())
       DBs->FindPole( x, y, d, 5, Index);
     else {
-      Handle(DrawTrSurf_BezierCurve2d) DBz = 
+      Handle(DrawTrSurf_BezierCurve2d) DBz2d = 
        Handle(DrawTrSurf_BezierCurve2d)::DownCast(D);
-      if( !DBz.IsNull())
-       DBz->FindPole( x, y, d, 5, Index);
+      if( !DBz2d.IsNull())
+       DBz2d->FindPole( x, y, d, 5, Index);
       else {
-       Handle(DrawTrSurf_BSplineCurve2d) DBs = 
+       Handle(DrawTrSurf_BSplineCurve2d) DBs2d = 
          Handle(DrawTrSurf_BSplineCurve2d)::DownCast(D);
-       if (!DBs.IsNull())
-         DBs->FindPole( x, y, d, 5, Index);
+       if (!DBs2d.IsNull())
+         DBs2d->FindPole( x, y, d, 5, Index);
        else 
          return 1;
       }
@@ -1079,7 +1131,7 @@ static Standard_Integer value2d (Draw_Interpretor& ,
 
 static Standard_Integer segment (Draw_Interpretor& , Standard_Integer n, const char** a)
 {
-  if (n < 4) return 1;
+  if (n < 4 || n > 5) return 1;
 
   Handle(Geom_BezierCurve) GBz = DrawTrSurf::GetBezierCurve(a[1]);
   Handle(Geom_BSplineCurve) GBs = DrawTrSurf::GetBSplineCurve(a[1]);
@@ -1088,14 +1140,18 @@ static Standard_Integer segment (Draw_Interpretor& , Standard_Integer n, const c
 
   Standard_Real f = Draw::Atof(a[2]), l = Draw::Atof(a[3]);
 
+  Standard_Real aTolerance = Precision::PConfusion();
+  if (n == 5)
+    aTolerance = Draw::Atof(a[4]);
+
   if (!GBz.IsNull()) 
     GBz->Segment(f,l);
   else if (!GBs.IsNull())
-    GBs->Segment(f,l);
+    GBs->Segment(f, l, aTolerance);
   else if (!GBz2d.IsNull()) 
     GBz2d->Segment(f,l);
   else if (!GBs2d.IsNull())
-    GBs2d->Segment(f,l);
+    GBs2d->Segment(f, l, aTolerance);
   else
     return 1;
 
@@ -1367,7 +1423,7 @@ static Standard_Integer localprop(Draw_Interpretor& di,
       }
     }
     else 
-      di <<"Tangent undefined."<<"\n";  
+      di <<"Tangent undefined.\n";  
   }
   else {
     Geom2dLProp_CLProps2d Prop (C2d,2,Precision::Confusion());
@@ -1394,7 +1450,7 @@ static Standard_Integer localprop(Draw_Interpretor& di,
       }
     }
     else 
-      di <<"Tangent undefined."<<"\n";
+      di <<"Tangent undefined.\n";
   }
   return 0;
 }  
@@ -1435,32 +1491,32 @@ static Standard_Integer rawcont(Draw_Interpretor& di, Standard_Integer n, const
                            Precision::Angular()) ;
     switch (cont) {
     case GeomAbs_C0: 
-      di << " C0 Continuity " << "\n" ;
+      di << " C0 Continuity \n" ;
       break ;
     case GeomAbs_G1:
-      di << " G1 Continuity " << "\n" ;
+      di << " G1 Continuity \n" ;
       break ;
     case GeomAbs_C1 :
-      di << " C1 Continuity " << "\n" ;
+      di << " C1 Continuity \n" ;
       break ;
     case GeomAbs_G2 :
-      di << " G2 Continuity " << "\n" ;
+      di << " G2 Continuity \n" ;
       break ; 
     case GeomAbs_C2 :
-      di << " C2 Continuity " << "\n" ;
+      di << " C2 Continuity \n" ;
       break ; 
     case GeomAbs_C3 :
-      di << " C3 Continuity " << "\n" ;
+      di << " C3 Continuity \n" ;
       break ; 
     case GeomAbs_CN :
-      di << " CN Continuity " << "\n" ;
+      di << " CN Continuity \n" ;
       break ; 
     default:
       break ; 
     }
   }
   else {
-    di << " not C0 continuity " << "\n" ;
+    di << " not C0 continuity \n" ;
   }
   return 0 ;
 }
@@ -1496,9 +1552,8 @@ static Standard_Integer approxcurveonsurf(Draw_Interpretor& di, Standard_Integer
   Handle(Geom2dAdaptor_HCurve) A2d = new (Geom2dAdaptor_HCurve)(curve2d);
   Handle(GeomAdaptor_HSurface) AS = new (GeomAdaptor_HSurface)(Surf);
 
-  Approx_CurveOnSurface App(A2d, AS, A2d->FirstParameter(), A2d->LastParameter(),
-                           Tol,  Continuity,  MaxDeg, MaxSeg,
-                           Standard_True, Standard_False);
+  Approx_CurveOnSurface App(A2d, AS, A2d->FirstParameter(), A2d->LastParameter(), Tol);
+  App.Perform(MaxSeg, MaxDeg, Continuity, Standard_True, Standard_False);
 
   if(App.HasResult()) {
     Handle(Geom_BSplineCurve) BSCurve = App.Curve3d(); 
@@ -1506,7 +1561,7 @@ static Standard_Integer approxcurveonsurf(Draw_Interpretor& di, Standard_Integer
     return 0;
   }
 
-  di << "Approximation failed !" << "\n";
+  di << "Approximation failed !\n";
   return 1;
                            
 }
@@ -1604,7 +1659,7 @@ static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, co
   if (Case == 1) {
     GeomConvert_ApproxCurve appr(curve, Tol, Continuity, MaxSeg, MaxDeg);
     if(appr.HasResult()) {
-      //appr.Dump(cout);
+      //appr.Dump(std::cout);
       Standard_SStream aSStream;
       appr.Dump(aSStream);
       di << aSStream;
@@ -1616,7 +1671,7 @@ static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, co
   else if (Case == 2) {
     Geom2dConvert_ApproxCurve appr(curve2d, Tol, Continuity, MaxSeg, MaxDeg);
     if(appr.HasResult()) {
-      //appr.Dump(cout);
+      //appr.Dump(std::cout);
       Standard_SStream aSStream;
       appr.Dump(aSStream);
       di << aSStream;
@@ -1629,7 +1684,7 @@ static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, co
     Handle(Adaptor3d_HCurve) HACur = new GeomAdaptor_HCurve(curve);
     Approx_CurvilinearParameter appr(HACur, Tol, Continuity, MaxDeg, MaxSeg);
     if(appr.HasResult()) {
-      //appr.Dump(cout);
+      //appr.Dump(std::cout);
       Standard_SStream aSStream;
       appr.Dump(aSStream);
       di << aSStream;
@@ -1642,7 +1697,7 @@ static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, co
     Handle(Adaptor3d_HSurface) HASur = new GeomAdaptor_HSurface(surface);
     Approx_CurvilinearParameter appr(HACur2d, HASur, Tol, Continuity, MaxDeg, MaxSeg);
     if(appr.HasResult()) {
-      //appr.Dump(cout);
+      //appr.Dump(std::cout);
       Standard_SStream aSStream;
       appr.Dump(aSStream);
       di << aSStream;
@@ -1658,7 +1713,7 @@ static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, co
     Handle(Adaptor3d_HSurface) HASur2 = new GeomAdaptor_HSurface(surface2);
     Approx_CurvilinearParameter appr(HACur2d, HASur, HACur2d2, HASur2, Tol, Continuity, MaxDeg, MaxSeg);
     if(appr.HasResult()) {
-      //appr.Dump(cout);
+      //appr.Dump(std::cout);
       Standard_SStream aSStream;
       appr.Dump(aSStream);
       di << aSStream;
@@ -1671,6 +1726,99 @@ static Standard_Integer approxcurve(Draw_Interpretor& di, Standard_Integer n, co
   return 0;
 }
 
+
+//=======================================================================
+//function : fitcurve
+//purpose  : 
+//=======================================================================
+
+static Standard_Integer fitcurve(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+  if (n<3) return 1;
+
+  Handle(Geom_Curve) GC;
+  GC = DrawTrSurf::GetCurve(a[2]);
+  if (GC.IsNull())
+    return 1;
+
+  Standard_Integer Dmin = 3;
+  Standard_Integer Dmax = 14;
+  Standard_Real Tol3d = 1.e-5;
+  Standard_Boolean inverse = Standard_True;
+
+  if (n > 3)
+  {
+    Tol3d = Atof(a[3]);
+  }
+
+  if (n > 4)
+  {
+    Dmax = atoi(a[4]);
+  }
+
+  if (n > 5)
+  {
+    Standard_Integer inv = atoi(a[5]);
+    if (inv > 0)
+    {
+      inverse = Standard_True;
+    }
+    else
+    {
+      inverse = Standard_False;
+    }
+  }
+
+  Handle(GeomAdaptor_HCurve) aGAC = new GeomAdaptor_HCurve(GC);
+
+  CurveEvaluator aCE(aGAC);
+
+  Approx_FitAndDivide anAppro(Dmin, Dmax, Tol3d, 0., Standard_True);
+  anAppro.SetInvOrder(inverse);
+  anAppro.Perform(aCE);
+
+  if (!anAppro.IsAllApproximated())
+  {
+    di << "Approximation failed \n";
+    return 1;
+  }
+  Standard_Integer i;
+  Standard_Integer NbCurves = anAppro.NbMultiCurves();
+
+  Convert_CompBezierCurvesToBSplineCurve Conv;
+
+  Standard_Real tol3d, tol2d, tolreached = 0.;
+  for (i = 1; i <= NbCurves; i++) {
+    anAppro.Error(i, tol3d, tol2d);
+    tolreached = Max(tolreached, tol3d);
+    AppParCurves_MultiCurve MC = anAppro.Value(i);
+    TColgp_Array1OfPnt Poles(1, MC.Degree() + 1);
+    MC.Curve(1, Poles);
+    Conv.AddCurve(Poles);
+  }
+  Conv.Perform();
+  Standard_Integer NbPoles = Conv.NbPoles();
+  Standard_Integer NbKnots = Conv.NbKnots();
+
+  TColgp_Array1OfPnt      NewPoles(1, NbPoles);
+  TColStd_Array1OfReal    NewKnots(1, NbKnots);
+  TColStd_Array1OfInteger NewMults(1, NbKnots);
+
+  Conv.KnotsAndMults(NewKnots, NewMults);
+  Conv.Poles(NewPoles);
+
+  BSplCLib::Reparametrize(GC->FirstParameter(),
+    GC->LastParameter(),
+    NewKnots);
+  Handle(Geom_BSplineCurve) TheCurve = new Geom_BSplineCurve(NewPoles, NewKnots, NewMults, Conv.Degree());
+
+  DrawTrSurf::Set(a[1], TheCurve);
+  di << a[1] << ": tolreached = " << tolreached << "\n";
+
+  return 0;
+
+}
+
 //=======================================================================
 //function : newbspline
 //purpose  : reduce the multiplicity of the knots to their minimum 
@@ -1698,7 +1846,7 @@ static Standard_Integer splitc1(Draw_Interpretor& di,
  Standard_Real l = ACurve->LastParameter();
 
  if ( Precision::IsInfinite(f) || Precision::IsInfinite(l)) {
-   di << " Error: Infinite curves" << "\n";
+   di << " Error: Infinite curves\n";
    return 1;
  }
 
@@ -1750,13 +1898,13 @@ static Standard_Integer splitc12d(Draw_Interpretor& di,
    tolerance=Draw::Atof(c[3]);
  if (n==5) 
    angular_tolerance = Draw::Atof(c[4]) ;
- Handle(Geom2d_Curve) ACurve = Handle(Geom2d_Curve)::DownCast(DrawTrSurf::GetCurve2d(c[1])) ;
+ Handle(Geom2d_Curve) ACurve = DrawTrSurf::GetCurve2d(c[1]);
  
  Standard_Real f = ACurve->FirstParameter();
  Standard_Real l = ACurve->LastParameter();
 
  if ( Precision::IsInfinite(f) || Precision::IsInfinite(l)) {
-   di << " Error: Infinite curves" << "\n";
+   di << " Error: Infinite curves\n";
    return 1;
  }
 
@@ -1804,7 +1952,7 @@ static Standard_Integer canceldenom(Draw_Interpretor& ,
    udirection=Standard_True;
  if (voption)
    vdirection=Standard_True;
- Handle(Geom_BSplineSurface) BSurf = Handle(Geom_BSplineSurface)::DownCast(DrawTrSurf::GetBSplineSurface(c[1]));
+ Handle(Geom_BSplineSurface) BSurf = DrawTrSurf::GetBSplineSurface(c[1]);
  GeomLib::CancelDenominatorDerivative(BSurf,udirection,vdirection);
  DrawTrSurf::Set(c[1],BSurf);
  return 0;
@@ -1833,7 +1981,7 @@ static Standard_Integer length(Draw_Interpretor& di,
     L = GCPnts_AbscissaPoint::Length(AC, Tol);
   }
   else {
-    di << a[1] << "is not a curve" << "\n";
+    di << a[1] << "is not a curve\n";
     return 1;
   }
 
@@ -1990,7 +2138,7 @@ void  GeomliteTest::CurveCommands(Draw_Interpretor& theCommands)
                  csetperiodic,g);
 
   theCommands.Add("segment",
-                 "segment name Ufirst Ulast",
+                 "segment name Ufirst Ulast [tol]",
                   __FILE__,
                  segment , g);
 
@@ -2059,6 +2207,8 @@ void  GeomliteTest::CurveCommands(Draw_Interpretor& theCommands)
                  __FILE__,
                  approxcurveonsurf,g);
 
+ theCommands.Add("fitcurve", "fitcurve result  curve [tol [maxdeg [inverse]]]", __FILE__, fitcurve, g);
+
  theCommands.Add("length", "length curve [Tol]", 
                  __FILE__,
                  length, g);