0028661: BRepOffsetAPI_MakePipeShell throws an exception Standard_NoSuchObject: NColl...
[occt.git] / src / BRepTest / BRepTest_SweepCommands.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 118c3ae..8f3b51f
@@ -1,9 +1,18 @@
-// File:       BRepTest_SweepCommands.cxx
-// Created:    Thu Jul 22 16:40:19 1993
-// Author:     Remi LEQUETTE
-//             <rle@nonox>
-
-
+// Created on: 1993-07-22
+// Created by: Remi LEQUETTE
+// 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.
 
 #include <BRepTest.hxx>
 #include <DBRep.hxx>
@@ -19,6 +28,7 @@
 #include <BRepOffsetAPI_MakeEvolved.hxx>
 #include <BRepOffsetAPI_ThruSections.hxx>
 #include <BRepOffsetAPI_MakePipeShell.hxx>
+#include <BRepOffsetAPI_MiddlePath.hxx>
 
 #include <BRepLib_MakeWire.hxx>
 #include <TopoDS.hxx>
@@ -33,8 +43,8 @@
 #include <TColgp_Array1OfPnt2d.hxx>
 
 static BRepOffsetAPI_MakePipeShell* Sweep= 0;
+static BRepOffsetAPI_ThruSections* Generator = 0;
 
-//#ifdef WNT
 #include <stdio.h>
 #include <Geom_Curve.hxx>
 #include <GeomAdaptor_HCurve.hxx>
@@ -43,11 +53,11 @@ static BRepOffsetAPI_MakePipeShell* Sweep= 0;
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRep_Tool.hxx>
 #include <gp_Pnt.hxx>
-//#endi#include <gp_Vec.hxx>
 #include <gp_Vec.hxx>
 #include <Geom_Circle.hxx>
 #include <gp_Ax2.hxx>
 
+
 //=======================================================================
 // prism
 //=======================================================================
@@ -59,7 +69,7 @@ static Standard_Integer prism(Draw_Interpretor& , Standard_Integer n, const char
   TopoDS_Shape base = DBRep::Get(a[2]);
   if (base.IsNull()) return 1;
 
-  gp_Vec V(atof(a[3]),atof(a[4]),atof(a[5]));
+  gp_Vec V(Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]));
   
   Standard_Boolean copy = Standard_False;
   Standard_Boolean inf  = Standard_False;
@@ -96,11 +106,11 @@ static Standard_Integer revol(Draw_Interpretor& ,
   TopoDS_Shape base = DBRep::Get(a[2]);
   if (base.IsNull()) return 1;
 
-  gp_Pnt P(atof(a[3]),atof(a[4]),atof(a[5]));
-  gp_Dir D(atof(a[6]),atof(a[7]),atof(a[8]));
+  gp_Pnt P(Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]));
+  gp_Dir D(Draw::Atof(a[6]),Draw::Atof(a[7]),Draw::Atof(a[8]));
   gp_Ax1 A(P,D);
 
-  Standard_Real angle = atof(a[9]) * (M_PI / 180.0);
+  Standard_Real angle = Draw::Atof(a[9]) * (M_PI / 180.0);
   
   Standard_Boolean copy = n > 10;
 
@@ -116,23 +126,51 @@ static Standard_Integer revol(Draw_Interpretor& ,
 // pipe
 //=======================================================================
 
-static Standard_Integer pipe(Draw_Interpretor& ,
+static Standard_Integer pipe(Draw_Interpretor& di,
                             Standard_Integer n, const char** a)
 {
-  if ( n < 4) return 1;
+  if (n == 1)
+  {
+    di << "pipe result Wire_spine Profile [Mode [Approx]]\n";
+    di << "Mode = 0 - CorrectedFrenet,\n";
+    di << "     = 1 - Frenet,\n";
+    di << "     = 2 - DiscreteTrihedron\n";
+    di << "Approx - force C1-approximation if result is C0\n";
+    return 0;
+  }
+  
+  if (n > 1 && n < 4) return 1;
 
   TopoDS_Shape Spine = DBRep::Get(a[2],TopAbs_WIRE);
   if ( Spine.IsNull()) return 1;
 
   TopoDS_Shape Profile = DBRep::Get(a[3]);
   if ( Profile.IsNull()) return 1;
+
+  GeomFill_Trihedron Mode = GeomFill_IsCorrectedFrenet;
+  if (n >= 5)
+  {
+    Standard_Integer iMode = atoi(a[4]);
+    if (iMode == 1)
+      Mode = GeomFill_IsFrenet;
+    else if (iMode == 2)
+      Mode = GeomFill_IsDiscreteTrihedron;
+  }
+
+  Standard_Boolean ForceApproxC1 = Standard_False;
+  if (n >= 6)
+    ForceApproxC1 = Standard_True;
   
-  TopoDS_Shape S = BRepOffsetAPI_MakePipe(TopoDS::Wire(Spine),Profile);
+  TopoDS_Shape S = BRepOffsetAPI_MakePipe(TopoDS::Wire(Spine),
+                                          Profile,
+                                          Mode,
+                                          ForceApproxC1);
 
   DBRep::Set(a[1],S);
   
   return 0;
 }
+
 //=======================================================================
 
 static Standard_Integer geompipe(Draw_Interpretor& ,
@@ -149,7 +187,7 @@ static Standard_Integer geompipe(Draw_Interpretor& ,
   Handle(GeomAdaptor_HCurve) aAdaptCurve = new GeomAdaptor_HCurve(SpineCurve,aSpFirst,aSpLast);
   Standard_Boolean ByACR = Standard_False;
   Standard_Boolean rotate = Standard_False;
-  Standard_Real Radius = atof(a[4]);
+  Standard_Real Radius = Draw::Atof(a[4]);
   gp_Pnt ctr;
   gp_Vec norm;
   ProfileCurve->D1(aSpFirst,ctr,norm);
@@ -158,11 +196,16 @@ static Standard_Integer geompipe(Draw_Interpretor& ,
   Handle(Geom_Circle) cStart=new Geom_Circle(aAx2Start,Radius);                       
   Standard_Integer k =5;
   if(n > k)
-    ByACR = (atoi(a[k++]) ==1);
+    ByACR = (Draw::Atoi(a[k++]) ==1);
   if(n > k)
-    rotate = (atoi(a[k++])==1);
+    rotate = (Draw::Atoi(a[k++])==1);
   GeomFill_Pipe aPipe(ProfileCurve,aAdaptCurve,cStart,ByACR,rotate);
   aPipe.Perform(Standard_True);
+  if (!aPipe.IsDone())
+  {
+    cout << "GeomFill_Pipe cannot make a surface" << endl;
+    return 1;
+  }
   Handle(Geom_Surface) Sur=aPipe.Surface();
   TopoDS_Face F;
   if(!Sur.IsNull())
@@ -184,11 +227,11 @@ Standard_Integer evolved(Draw_Interpretor& di, Standard_Integer n, const char**
     //cout << "        is given in the referencial axis. " << endl;
     //cout << " 2) evolved result base profil o : "<< endl;
     //cout << "        This position is automatically computed." << endl;
-    di << " 1) evolved result base profil : "<< "\n";
-    di << "        The relative position of the profil on the base" << "\n";
-    di << "        is given in the referencial axis. " << "\n";
-    di << " 2) evolved result base profil o : "<< "\n";
-    di << "        This position is automatically computed." << "\n";
+    di << " 1) evolved result base profil : \n";
+    di << "        The relative position of the profil on the base\n";
+    di << "        is given in the referencial axis. \n";
+    di << " 2) evolved result base profil o : \n";
+    di << "        This position is automatically computed.\n";
     return 0;
   }
 
@@ -281,19 +324,19 @@ Standard_Integer gener(Draw_Interpretor&, Standard_Integer n, const char** a)
 
   TopoDS_Shape Shape; 
 
-  BRepFill_Generator Generator;
+  BRepFill_Generator aGenerator;
   
   for ( Standard_Integer i = 2; i<= n-1 ; i++) {
     Shape = DBRep::Get(a[i],TopAbs_WIRE);
     if ( Shape.IsNull()) 
       return 1;
 
-    Generator.AddWire(TopoDS::Wire(Shape));
+    aGenerator.AddWire(TopoDS::Wire(Shape));
   }
 
-  Generator.Perform();
+  aGenerator.Perform();
 
-  TopoDS_Shell Shell = Generator.Shell();
+  TopoDS_Shell Shell = aGenerator.Shell();
   
   DBRep::Set(a[1], Shell);
 
@@ -323,10 +366,15 @@ Standard_Integer thrusections(Draw_Interpretor&, Standard_Integer n, const char*
 
   TopoDS_Shape Shape; 
 
-  Standard_Boolean issolid = ( atoi(a[index]) == 1 );
-  Standard_Boolean isruled = ( atoi(a[index+1]) == 1 );
+  Standard_Boolean issolid = ( Draw::Atoi(a[index]) == 1 );
+  Standard_Boolean isruled = ( Draw::Atoi(a[index+1]) == 1 );
 
-  BRepOffsetAPI_ThruSections Generator(issolid,isruled);
+  if (Generator != 0)
+  {
+    delete Generator; 
+    Generator = 0;
+  }
+  Generator = new BRepOffsetAPI_ThruSections(issolid,isruled);
   
   Standard_Integer NbEdges = 0;
   Standard_Boolean IsFirstWire = Standard_False;
@@ -335,7 +383,7 @@ Standard_Integer thrusections(Draw_Interpretor&, Standard_Integer n, const char*
     Shape = DBRep::Get(a[i], TopAbs_WIRE);
     if (!Shape.IsNull())
       {
-       Generator.AddWire(TopoDS::Wire(Shape));
+       Generator->AddWire(TopoDS::Wire(Shape));
        if (!IsFirstWire)
          IsFirstWire = Standard_True;
        else
@@ -346,7 +394,7 @@ Standard_Integer thrusections(Draw_Interpretor&, Standard_Integer n, const char*
        Shape = DBRep::Get(a[i], TopAbs_VERTEX);
        IsWire = Standard_False;
        if (!Shape.IsNull())
-         Generator.AddVertex(TopoDS::Vertex(Shape));
+         Generator->AddVertex(TopoDS::Vertex(Shape));
        else
          return 1;
       }
@@ -365,14 +413,66 @@ Standard_Integer thrusections(Draw_Interpretor&, Standard_Integer n, const char*
   }
 
   check = (check || !samenumber);
-  Generator.CheckCompatibility(check);
+  Generator->CheckCompatibility(check);
 
-  Generator.Build();
+  Generator->Build();
 
-  TopoDS_Shape Shell = Generator.Shape();
-  
-  DBRep::Set(a[index-1], Shell);
+  if (Generator->IsDone()) {
+    TopoDS_Shape Shell = Generator->Shape();
+    DBRep::Set(a[index-1], Shell);
+  }
+  else {
+    cout << "Algorithm is not done" << endl;
+  }
+  return 0;
+}
 
+//============================================================================
+//function : genthrus
+//purpose  : returns generated shape for subshape of a section of thrusections
+//           Thrusections must be done previously
+//============================================================================
+static Standard_Integer genthrus(Draw_Interpretor& di,
+                                 Standard_Integer n, const char** a)
+{
+  if (n != 3)
+  {
+    di << "genthrus: it is called after thrusections command\n";
+    di << "returns:\n";
+    di << "- chain of generated faces for sub-edge of a profile;\n";
+    di << "- chain of generated edges for sub-vertex of a profile;\n";
+    di << "- bunch of chains of generated edges for start or end vertex if it is degenerated section.\n";
+    di << "Usage: genthrus res subshape_of_profile, thrusections must be done\n";
+    return 1;
+  }
+  if (Generator == 0)
+  {
+    di << "You have forgotten the <<thrusections>> command !\n";
+    return 1;
+  }
+  if (!Generator->IsDone())
+  {
+    di << "Thrusections is not done\n";
+    return 1;
+  }
+  TopoDS_Shape aShape = DBRep::Get(a[2]);
+  if (aShape.IsNull())
+  {
+    cout<<"Null subshape"<<endl;
+    return 1;
+  }
+  const TopTools_ListOfShape& Edges = Generator->Generated(aShape);
+  TopoDS_Compound aCompound;
+  BRep_Builder BB;
+  BB.MakeCompound(aCompound);
+  TopTools_ListIteratorOfListOfShape iter(Edges);
+  for (; iter.More(); iter.Next())
+  {
+    const TopoDS_Shape& anEdge = iter.Value();
+    BB.Add(aCompound, anEdge);
+  }
+
+  DBRep::Set(a[1], aCompound);
   return 0;
 }
 
@@ -410,21 +510,22 @@ static Standard_Integer setsweep(Draw_Interpretor& di,
     //cout << "   -CN dx dy dz : BiNormal is given by dx dy dz" << endl;
     //cout << "   -FX Tx Ty TZ [Nx Ny Nz] : Tangent and Normal are fixed" <<endl;
     //cout << "   -G guide  0|1(ACR|Plan)  0|1(contact|no contact) : with guide"<<endl;
-    di << "setsweep options [arg1 [arg2 [...]]] : options are :" << "\n";
-    di << "   -FR : Tangent and Normal are given by Frenet trihedron" <<"\n";
-    di << "   -CF : Tangente is given by Frenet," << "\n";
-    di << "         the Normal is computed to minimize the torsion " << "\n";
-    di << "   -DX Surf : Tangent and Normal are given by Darboux trihedron," <<"\n";     
-    di << "       Surf have to be a shell or a face" <<"\n";
-    di << "   -CN dx dy dz : BiNormal is given by dx dy dz" << "\n";
-    di << "   -FX Tx Ty TZ [Nx Ny Nz] : Tangent and Normal are fixed" <<"\n";
-    di << "   -G guide  0|1(ACR|Plan)  0|1(contact|no contact) : with guide"<<"\n";
+    di << "setsweep options [arg1 [arg2 [...]]] : options are :\n";
+    di << "   -FR : Tangent and Normal are given by Frenet trihedron\n";
+    di << "   -CF : Tangente is given by Frenet,\n";
+    di << "         the Normal is computed to minimize the torsion \n";
+    di << "   -DT : discrete trihedron\n";
+    di << "   -DX Surf : Tangent and Normal are given by Darboux trihedron,\n";     
+    di << "       Surf have to be a shell or a face\n";
+    di << "   -CN dx dy dz : BiNormal is given by dx dy dz\n";
+    di << "   -FX Tx Ty TZ [Nx Ny Nz] : Tangent and Normal are fixed\n";
+    di << "   -G guide  0|1(Plan|ACR)  0|1|2(no contact|contact|contact on border) : with guide\n";
     return 0;
   }
 
    if (Sweep ==0) {
      //cout << "You have forgotten the <<mksweep>> command  !"<< endl;
-     di << "You have forgotten the <<mksweep>> command  !"<< "\n";
+     di << "You have forgotten the <<mksweep>> command  !\n";
      return 1;
    }
   if (!strcmp(a[1],"-FR")) {
@@ -433,17 +534,20 @@ static Standard_Integer setsweep(Draw_Interpretor& di,
   else if (!strcmp(a[1],"-CF")) {
     Sweep->SetMode(Standard_False);
   }
+  else if (!strcmp(a[1],"-DT")) {
+    Sweep->SetDiscreteMode();
+  }
   else if (!strcmp(a[1],"-DX")) {
     if (n!=3) {
       //cout << "bad arguments !" << endl;
-      di << "bad arguments !" << "\n";
+      di << "bad arguments !\n";
       return 1;
     }
     TopoDS_Shape Surf;
     Surf = DBRep::Get(a[2],TopAbs_SHAPE);
     if (Surf.IsNull()) {
        //cout << a[2] <<"is not a shape !" << endl;
-       di << a[2] <<"is not a shape !" << "\n";
+       di << a[2] <<"is not a shape !\n";
       return 1;
     }
     Sweep->SetMode(Surf);
@@ -451,21 +555,21 @@ static Standard_Integer setsweep(Draw_Interpretor& di,
   else if (!strcmp(a[1],"-CN")) {
     if (n!=5) {
       //cout << "bad arguments !" << endl;
-      di << "bad arguments !" << "\n";
+      di << "bad arguments !\n";
       return 1;
     }
-    gp_Dir D(atof(a[2]), atof(a[3]), atof(a[4]));
+    gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
     Sweep->SetMode(D);;
   }
   else if (!strcmp(a[1],"-FX")) {
     if ((n!=5)&&(n!=8)) {
       //cout << "bad arguments !" << endl;
-      di << "bad arguments !" << "\n";
+      di << "bad arguments !\n";
       return 1;
     }
-    gp_Dir D(atof(a[2]), atof(a[3]), atof(a[4]));
+    gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
     if (n==8) {
-      gp_Dir DN(atof(a[5]), atof(a[6]), atof(a[7]));
+      gp_Dir DN(Draw::Atof(a[5]), Draw::Atof(a[6]), Draw::Atof(a[7]));
       gp_Ax2 Axe(gp_Pnt(0., 0., 0.), D, DN);
       Sweep->SetMode(Axe);
     }
@@ -479,19 +583,23 @@ static Standard_Integer setsweep(Draw_Interpretor& di,
      if (n != 5)
        {
         //cout << "bad arguments !" << endl;
-        di << "bad arguments !" << "\n";
+        di << "bad arguments !\n";
         return 1; 
        }
      else
        {  
          TopoDS_Shape Guide = DBRep::Get(a[2],TopAbs_WIRE);
-         Sweep->SetMode(TopoDS::Wire(Guide), atoi(a[3]), atoi(a[4]));
+          Standard_Boolean CurvilinearEquivalence = Draw::Atoi(a[3]) != 0;
+          Standard_Integer KeepContact = Draw::Atoi(a[4]);
+          Sweep->SetMode(TopoDS::Wire(Guide),
+                         CurvilinearEquivalence,
+                         (BRepFill_TypeOfContact)KeepContact);
        }
     }
  
   else {
     //cout << "The option "<< a[1] << " is unknown !" << endl;
-    di << "The option "<< a[1] << " is unknown !" << "\n";
+    di << "The option "<< a[1] << " is unknown !\n";
     return 1;
   }
   return 0;
@@ -510,17 +618,17 @@ static Standard_Integer addsweep(Draw_Interpretor& di,
     //cout << "        with the spine" <<endl;
     //cout << "   -R : the wire have to be rotated to assume orthogonality"<<endl;
     //cout << "        with the spine's tangent" << endl;
-    di << "addsweep wire/vertex [Vertex] [-T] [-R] [u0 v0 u1 v1 [...[uN vN]]] : options are :" << "\n";
-    di << "   -T : the wire/vertex have to be translated to assume contact"<< "\n";
-    di << "        with the spine" <<"\n";
-    di << "   -R : the wire have to be rotated to assume orthogonality"<<"\n";
-    di << "        with the spine's tangent" << "\n";
+    di << "addsweep wire/vertex [Vertex] [-T] [-R] [u0 v0 u1 v1 [...[uN vN]]] : options are :\n";
+    di << "   -T : the wire/vertex have to be translated to assume contact\n";
+    di << "        with the spine\n";
+    di << "   -R : the wire have to be rotated to assume orthogonality\n";
+    di << "        with the spine's tangent\n";
     return 0;
   }
 
   if (Sweep ==0) {
     //cout << "You have forgotten the <<mksweep>> command  !"<< endl;
-    di << "You have forgotten the <<mksweep>> command  !"<< "\n";
+    di << "You have forgotten the <<mksweep>> command  !\n";
     return 1;
   }
 
@@ -529,11 +637,12 @@ static Standard_Integer addsweep(Draw_Interpretor& di,
   Handle(Law_Interpol) thelaw;
 
   Section = DBRep::Get(a[1], TopAbs_SHAPE);
-  if (Section.ShapeType() != TopAbs_WIRE &&
-      Section.ShapeType() != TopAbs_VERTEX)
+  if (Section.IsNull() ||
+      (Section.ShapeType() != TopAbs_WIRE &&
+       Section.ShapeType() != TopAbs_VERTEX))
     {
       //cout << a[1] <<"is not a wire and is not a vertex!" << endl;
-      di << a[1] <<"is not a wire and is not a vertex!" << "\n";
+      di << a[1] <<" is not a wire and is not a vertex!\n";
       return 1;
     }
 
@@ -574,9 +683,9 @@ static Standard_Integer addsweep(Draw_Interpretor& di,
        Standard_Integer ii, L= nbreal/2;
        TColgp_Array1OfPnt2d ParAndRad(1, L);
        for (ii=1; ii<=L; ii++, cur+=2) {
-          ParAndRad(ii).SetX(atof(a[cur]));
-          ParAndRad(ii).SetY(atof(a[cur+1]));
-        }
+          ParAndRad(ii).SetX(Draw::Atof(a[cur]));
+          ParAndRad(ii).SetY(Draw::Atof(a[cur+1]));
+        }
        thelaw = new (Law_Interpol) ();
        thelaw->Set(ParAndRad, 
                   Abs(ParAndRad(1).Y() - ParAndRad(L).Y()) < Precision::Confusion());
@@ -611,7 +720,7 @@ static Standard_Integer deletesweep(Draw_Interpretor& di,
 //  Section = TopoDS::Wire(DBRep::Get(a[1],TopAbs_SHAPE));
   if (Section.IsNull()) {
     //cout << a[1] <<"is not a wire !" << endl;
-    di << a[1] <<"is not a wire !" << "\n";
+    di << a[1] <<"is not a wire !\n";
     return 1;
   }  
 
@@ -635,27 +744,27 @@ static Standard_Integer buildsweep(Draw_Interpretor& di,
     //cout << "   -R : Discontinuities are treated like Round Corner" << endl;
     //cout << "        Treatement is Intersect and Fill" << endl;
     //cout << "   -S : To build a Solid" << endl;
-    di << "build sweep result [-M/-C/-R] [-S] [tol] : options are" << "\n";
-    di << "   -M : Discontinuities are treated by Modfication of"<< "\n"; 
-    di << "        the sweeping mode : it is the default" <<"\n";
-    di << "   -C : Discontinuities are treated like Right Corner" << "\n";
-    di << "        Treatement is Extent && Intersect" << "\n";
-    di << "   -R : Discontinuities are treated like Round Corner" << "\n";
-    di << "        Treatement is Intersect and Fill" << "\n";
-    di << "   -S : To build a Solid" << "\n";
+    di << "build sweep result [-M/-C/-R] [-S] [tol] : options are\n";
+    di << "   -M : Discontinuities are treated by Modfication of\n"; 
+    di << "        the sweeping mode : it is the default\n";
+    di << "   -C : Discontinuities are treated like Right Corner\n";
+    di << "        Treatement is Extent && Intersect\n";
+    di << "   -R : Discontinuities are treated like Round Corner\n";
+    di << "        Treatement is Intersect and Fill\n";
+    di << "   -S : To build a Solid\n";
     return 0;
   }
 
   Standard_Boolean mksolid = Standard_False;
   if (Sweep ==0) {
     //cout << "You have forgotten the <<mksweep>> command  !"<< endl;
-    di << "You have forgotten the <<mksweep>> command  !"<< "\n";
+    di << "You have forgotten the <<mksweep>> command  !\n";
     return 1;
   }
 
   if (!Sweep->IsReady()) {
     //cout << "You have forgotten the <<addsweep>> command  !"<< endl;
-    di << "You have forgotten the <<addsweep>> command  !"<< "\n";
+    di << "You have forgotten the <<addsweep>> command  !\n";
     return 1;
   }
 
@@ -682,15 +791,15 @@ static Standard_Integer buildsweep(Draw_Interpretor& di,
   Sweep->Build();
   if (!Sweep->IsDone()) {
     //cout << "Buildsweep : Not Done" << endl;
-    di << "Buildsweep : Not Done" << "\n";
+    di << "Buildsweep : Not Done\n";
     BRepBuilderAPI_PipeError Stat = Sweep->GetStatus(); 
     if (Stat == BRepBuilderAPI_PlaneNotIntersectGuide) {
       //cout << "Buildsweep : One Plane not intersect the guide" << endl;
-      di << "Buildsweep : One Plane not intersect the guide" << "\n";
+      di << "Buildsweep : One Plane not intersect the guide\n";
     }
     if (Stat == BRepBuilderAPI_ImpossibleContact) {
       //cout << "BuildSweep : One section can not be in contact with the guide" << endl;
-      di << "BuildSweep : One section can not be in contact with the guide" << "\n";
+      di << "BuildSweep : One section can not be in contact with the guide\n";
     }
     return 1;
   }
@@ -699,7 +808,7 @@ static Standard_Integer buildsweep(Draw_Interpretor& di,
       Standard_Boolean B;
       B = Sweep->MakeSolid();
       //if (!B) cout << " BuildSweep : It is impossible to make a solid !" << endl;
-      if (!B) di << " BuildSweep : It is impossible to make a solid !" << "\n";
+      if (!B) di << " BuildSweep : It is impossible to make a solid !\n";
     }
     result = Sweep->Shape();
     DBRep::Set(a[1],result);
@@ -708,6 +817,63 @@ static Standard_Integer buildsweep(Draw_Interpretor& di,
   return 0;
 }
 
+//=======================================================================
+//function : gensweep
+//purpose  : returns generated shape for subshape of a section of sweep
+//           Sweep must be done previously
+//=======================================================================
+static Standard_Integer gensweep(Draw_Interpretor&,
+                                 Standard_Integer n, const char** a)
+{
+  if (n != 3)
+  {
+    cout<<"Usage: gensweep res subshape_of_profile, sweep must be done"<<endl;
+    return 1;
+  }
+  if (!Sweep->IsDone())
+  {
+    cout<<"Sweep is not done"<<endl;
+    return 1;
+  }
+  TopoDS_Shape aShape = DBRep::Get(a[2]);
+  if (aShape.IsNull())
+  {
+    cout<<"Null subshape"<<endl;
+    return 1;
+  }
+  TopTools_ListOfShape Shells = Sweep->Generated(aShape);
+  TopoDS_Compound aCompound;
+  BRep_Builder BB;
+  BB.MakeCompound(aCompound);
+  TopTools_ListIteratorOfListOfShape itsh(Shells);
+  for (; itsh.More(); itsh.Next())
+  {
+    const TopoDS_Shape& aShell = itsh.Value();
+    BB.Add(aCompound, aShell);
+  }
+
+  DBRep::Set(a[1], aCompound);
+  return 0;
+}
+
+//=======================================================================
+//function : errorsweep
+//purpose  : returns the summary error on resulting surfaces
+//           reached by Sweep
+//=======================================================================
+static Standard_Integer errorsweep(Draw_Interpretor& di,
+                                   Standard_Integer, const char**)
+{
+  if (!Sweep->IsDone())
+  {
+    di << "Sweep is not done\n";
+    return 1;
+  }
+  Standard_Real ErrorOnSurfaces = Sweep->ErrorOnSurface();
+  di << "Tolerance on surfaces = " << ErrorOnSurfaces << "\n";
+  return 0;
+}
+
 //=======================================================================
 //  simulsweep
 //=======================================================================
@@ -718,13 +884,13 @@ static Standard_Integer simulsweep(Draw_Interpretor& di,
   
   if (Sweep ==0) {
     //cout << "You have forgotten the <<mksweep>> command  !"<< endl;
-    di << "You have forgotten the <<mksweep>> command  !"<< "\n";
+    di << "You have forgotten the <<mksweep>> command  !\n";
     return 1;
   }
   
   if (!Sweep->IsReady()) {
     //cout << "You have forgotten the <<addsweep>> command  !"<< endl;
-    di << "You have forgotten the <<addsweep>> command  !"<< "\n";
+    di << "You have forgotten the <<addsweep>> command  !\n";
     return 1;
   }
   
@@ -732,7 +898,7 @@ static Standard_Integer simulsweep(Draw_Interpretor& di,
   TopTools_ListOfShape List;
   TopTools_ListIteratorOfListOfShape it;
   Standard_Integer N, ii;
-  N = atoi(a[2]);
+  N = Draw::Atoi(a[2]);
 
   if (n>3) {
     BRepBuilderAPI_TransitionMode Transition = BRepBuilderAPI_Transformed;
@@ -749,13 +915,39 @@ static Standard_Integer simulsweep(Draw_Interpretor& di,
   // Calculate the result
   Sweep->Simulate(N, List);
   for (ii=1, it.Initialize(List); it.More(); it.Next(), ii++) {
-    sprintf(name,"%s_%d",a[1],ii);
+    Sprintf(name,"%s_%d",a[1],ii);
     DBRep::Set(name, it.Value());
   }
 
   return 0;
 }
 
+//=======================================================================
+//  middlepath
+//=======================================================================
+static Standard_Integer middlepath(Draw_Interpretor& /*di*/,
+                                  Standard_Integer n, const char** a)
+{
+  if (n < 5) return 1;
+
+  TopoDS_Shape aShape = DBRep::Get(a[2]);
+  if (aShape.IsNull()) return 1;
+
+  TopoDS_Shape StartShape = DBRep::Get(a[3]);
+  if (StartShape.IsNull()) return 1;
+  
+  TopoDS_Shape EndShape   = DBRep::Get(a[4]);
+  if (EndShape.IsNull()) return 1;
+
+  BRepOffsetAPI_MiddlePath Builder(aShape, StartShape, EndShape);
+  Builder.Build();
+
+  TopoDS_Shape Result = Builder.Shape();
+  DBRep::Set(a[1], Result);
+
+  return 0;
+}
+
 //=======================================================================
 //function : SweepCommands
 //purpose  : 
@@ -780,7 +972,7 @@ void  BRepTest::SweepCommands(Draw_Interpretor& theCommands)
                  __FILE__,revol,g);
   
   theCommands.Add("pipe",
-                 "pipe result Wire_spine Profile",
+                 "pipe result Wire_spine Profile [Mode [Approx]], no args to get help",
                  __FILE__,pipe,g);
   
   theCommands.Add("evolved",
@@ -801,6 +993,8 @@ void  BRepTest::SweepCommands(Draw_Interpretor& theCommands)
   theCommands.Add("thrusections", "thrusections [-N] result issolid isruled shape1 shape2 [..shape..], the option -N means no check on wires, shapes must be wires or vertices (only first or last)",
                  __FILE__,thrusections,g);
 
+  theCommands.Add("genthrus", "genthrus res subshape_of_profile",
+                 __FILE__,genthrus,g);
   
   theCommands.Add("mksweep", "mksweep wire",
                  __FILE__,mksweep,g);
@@ -816,12 +1010,21 @@ void  BRepTest::SweepCommands(Draw_Interpretor& theCommands)
                  "deletesweep wire, To delete a section",
                  __FILE__,deletesweep,g);
 
-  theCommands.Add("buildsweep", "builsweep [r] [option] [Tol] , no args to get help"
+ theCommands.Add("buildsweep", "builsweep [r] [option] [Tol] , no args to get help",
                  __FILE__,buildsweep,g);
 
+ theCommands.Add("gensweep", "gensweep res subshape_of_profile",
+                 __FILE__,gensweep,g);
+
+ theCommands.Add("errorsweep", "errorsweep: returns the summary error on resulting surfaces reached by Sweep",
+                 __FILE__,errorsweep,g);
+
   theCommands.Add("simulsweep", "simulsweep r [n] [option]"
                  __FILE__,simulsweep,g);
   theCommands.Add("geompipe", "geompipe r spineedge profileedge radius [byACR [byrotate]]"
                  __FILE__,geompipe,g);
+  
+  theCommands.Add("middlepath", "middlepath res shape startshape endshape",
+                 __FILE__,middlepath,g);
 }