0029293: Boolean Operations algorithm does not preserve the orientations of the faces
[occt.git] / src / DBRep / DBRep.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 38d598c..8537c0a
@@ -1,67 +1,58 @@
 // Created on: 1993-07-21
 // Created by: Remi LEQUETTE
 // Copyright (c) 1993-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.
 
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <DBRep.ixx>
+#include <BRep_TEdge.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepGProp.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_ShapeSet.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <BinTools.hxx>
+#include <DBRep.hxx>
 #include <DBRep_DrawableShape.hxx>
-#include <Draw_Appli.hxx>
 #include <Draw.hxx>
+#include <Draw_Appli.hxx>
+#include <Draw_ProgressIndicator.hxx>
 #include <Draw_Segment3D.hxx>
-#include <TopAbs.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopExp_Explorer.hxx>
-#include <BRepTools.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <BRepTools_ShapeSet.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <Precision.hxx>
-#include <Poly_Triangulation.hxx>
 #include <gp_Ax2.hxx>
-
-#include <TopExp.hxx>
-#include <TopTools_Array1OfShape.hxx>
-#include <TColStd_Array1OfInteger.hxx>
 #include <GProp.hxx>
 #include <GProp_GProps.hxx>
-#include <BRepGProp.hxx>
+#include <NCollection_Vector.hxx>
+#include <Poly_Triangulation.hxx>
+#include <Precision.hxx>
+#include <Standard.hxx>
+#include <TColStd_Array1OfInteger.hxx>
 #include <TColStd_Array1OfReal.hxx>
-#include <Draw_ProgressIndicator.hxx>
+#include <TopAbs.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopTools_Array1OfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 
-// memory management
-#include <Standard.hxx>
-//#ifdef WNT
 #include <stdio.h>
-#ifdef WNT
+// memory management
+#ifdef _WIN32
 extern Draw_Viewer dout;
 #endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
 
 #define Characters(IArg) (strspn (Arg[IArg], "0123456789.+-eE") != strlen (Arg[IArg]))
 #define Float(IArg)      (strspn (Arg[IArg], "0123456789+-")    != strlen (Arg[IArg]))
@@ -188,7 +179,7 @@ static Standard_Integer hlr (Draw_Interpretor& di,
       di << "\n";
       if (withHLR) {
        di << "Angle of discretization : ";
-       di << anglHLR * 180 / M_PI << " degrees" << "\n";
+       di << anglHLR * 180 / M_PI << " degrees\n";
       }
     }
     else di << " wireframe";
@@ -223,7 +214,7 @@ static Standard_Integer hlr (Draw_Interpretor& di,
     }
     else if (!strcasecmp(a[1],"ang"  )) {
       di << "Angle de discretisation : ";
-      di << anglHLR * 180 / M_PI << " degres" << "\n";
+      di << anglHLR * 180 / M_PI << " degres\n";
     }
     else return 1;
   }
@@ -239,7 +230,7 @@ static Standard_Integer hlr (Draw_Interpretor& di,
       if (anglHLR > HAngMax) anglHLR = HAngMax;
     }
     di << "Angle of discretization : ";
-    di << anglHLR * 180 / M_PI << " degrees" << "\n";
+    di << anglHLR * 180 / M_PI << " degrees\n";
   }
 
   if (n >= nFirst + 1) {
@@ -349,7 +340,7 @@ static Standard_Integer triangles(Draw_Interpretor& ,
 
   if (n == 1) {
     disptriangles = !disptriangles;
-#ifdef DEB
+#ifdef OCCT_DEBUG
     if (disptriangles) cout <<"Triangulations are always displayed"<<endl;
     else cout <<"Triangulations are displayed only if there is no geometric representation"<<endl;
 #endif
@@ -399,7 +390,7 @@ static Standard_Integer polygons(Draw_Interpretor& ,
 
   if (n == 1) {
     disppolygons = !disppolygons;
-#ifdef DEB
+#ifdef OCCT_DEBUG
     if (disppolygons) cout <<"Polygons are always displayed"<<endl;
     else cout <<"Polygons are displayed only if there is no geometric representation"<<endl;
 #endif
@@ -595,6 +586,11 @@ static Standard_Integer nexplode(Draw_Interpretor& di,
     typ = TopAbs_EDGE;
     break;
     
+  case 'V' :
+  case 'v' :
+    typ = TopAbs_VERTEX;
+    break;
+    
     default :
       return 1;
   }
@@ -615,20 +611,26 @@ static Standard_Integer nexplode(Draw_Interpretor& di,
     }
     Exp.Next();
   }
-  
+  //
   TColStd_Array1OfInteger OrderInd(1,MaxShapes);
-//  gp_Pnt GPoint;
+  gp_Pnt GPoint;
   GProp_GProps GPr;
-//  Standard_Integer InOfminX = 1,aTemp;
   Standard_Integer aTemp;
   TColStd_Array1OfReal MidXYZ(1,MaxShapes); //X,Y,Z;
   Standard_Boolean NoSort = Standard_True;
-  
-  // Computing of CentreOfMass
+  //
+  // Computing of CentreOfMass for edge and face
+  // and for vertex use its point
   for (Index=1; Index <= MaxShapes; Index++) {
     OrderInd.SetValue(Index,Index);
-    BRepGProp::LinearProperties(aShapes(Index),GPr);
-    gp_Pnt GPoint = GPr.CentreOfMass();
+    const TopoDS_Shape& aS = aShapes(Index);
+    if (aS.ShapeType() != TopAbs_VERTEX) {
+      BRepGProp::LinearProperties(aS, GPr);
+      GPoint = GPr.CentreOfMass();
+    }
+    else {
+      GPoint = BRep_Tool::Pnt(TopoDS::Vertex(aS));
+    }
     MidXYZ.SetValue(Index, GPoint.X()*999 + GPoint.Y()*99 +
                    GPoint.Z()*0.9);
   }   
@@ -647,7 +649,7 @@ static Standard_Integer nexplode(Draw_Interpretor& di,
   // Check of equality of MidXYZ
   for (Index=1; Index < MaxShapes; Index++) {
     if (MidXYZ(OrderInd(Index+1)) == MidXYZ(OrderInd(Index)))
-      di<<"Warning! For this shape the results may be incorrect."<<"\n";
+      di<<"Warning! For this shape the results may be incorrect.\n";
   }
   
   for (Index=1 ;Index <= MaxShapes; Index++) {
@@ -700,8 +702,9 @@ static Standard_Integer invert(Draw_Interpretor& ,
   
   BRep_Builder B;
   TopoDS_Shape NS = S.EmptyCopied();
-  TopoDS_Iterator itr(S);
+  NS.Closed (S.Closed());
 
+  TopoDS_Iterator itr(S);
   while (itr.More()) {
     B.Add(NS,itr.Value().Reversed());
     itr.Next();
@@ -720,11 +723,7 @@ static Standard_Integer orientation(Draw_Interpretor& ,
 {
   if (n <= 1) return 1;
   Standard_Integer cas = 0;
-#ifdef DEB
-  TopAbs_Orientation ori;
-#else
   TopAbs_Orientation ori=TopAbs_FORWARD;
-#endif
   Standard_Integer last = n;
   if (!strcasecmp(a[0],"orientation")) {
     if (n <= 2) return 1;
@@ -977,6 +976,112 @@ static Standard_Integer countshapes(Draw_Interpretor& di,
   return 0;
 }
 
+//=======================================================================
+// 
+//=======================================================================
+void setProp(TopoDS_Shape Sh, const char** a, Standard_Integer n)
+{
+  Standard_Integer i;
+  for(i = 2; i < n; i++) {
+    if (strstr ( a[i], "free" )) {
+      if(a[i][0] == '-') {
+        Sh.Free(Standard_False);
+      }
+      else {
+        Sh.Free(Standard_True);
+      }
+    }
+    if (strstr ( a[i], "modified" )) {
+      if(a[i][0] == '-') {
+        Sh.Modified(Standard_False);
+      }
+      else {
+        Sh.Modified(Standard_True);
+      }
+    }
+    if (strstr ( a[i], "checked" )) {
+      if(a[i][0] == '-') {
+        Sh.Checked(Standard_False);
+      }
+      else {
+        Sh.Checked(Standard_True);
+      }
+    }
+    if (strstr ( a[i], "orientable" )) {
+      if(a[i][0] == '-') {
+        Sh.Orientable(Standard_False);
+      }
+      else {
+        Sh.Orientable(Standard_True);
+      }
+    }
+    if (strstr ( a[i], "closed" )) {
+      if(a[i][0] == '-') {
+        Sh.Closed(Standard_False);
+      }
+      else {
+        Sh.Closed(Standard_True);
+      }
+    }
+    if (strstr ( a[i], "infinite" )) {
+      if(a[i][0] == '-') {
+        Sh.Infinite(Standard_False);
+      }
+      else {
+        Sh.Infinite(Standard_True);
+      }
+    }
+    if (strstr ( a[i], "convex" )) {
+      if(a[i][0] == '-') {
+        Sh.Convex(Standard_False);
+      }
+      else {
+        Sh.Convex(Standard_True);
+      }
+    }
+    if (strstr ( a[i], "locked" )) {
+      if(a[i][0] == '-') {
+        Sh.Locked(Standard_False);
+      }
+      else {
+        Sh.Locked(Standard_True);
+      }
+    }
+  }
+}
+
+//=======================================================================
+// 
+//=======================================================================
+static Standard_Integer setFlags(Draw_Interpretor& ,
+                                    Standard_Integer n, const char** a)
+{
+  if (n < 3) return 1;
+
+  TopExp_Explorer ex;
+  TopoDS_Shape Sh = DBRep::Get(a[1]);
+
+  if (Sh.IsNull()) return 1;
+
+  setProp(Sh, a, n);
+  for (ex.Init (Sh,TopAbs_VERTEX); ex.More(); ex.Next()) {
+    TopoDS_Shape S = ex.Current();
+    setProp(S, a, n);
+  }
+
+  for (ex.Init (Sh,TopAbs_EDGE); ex.More(); ex.Next()) {
+    TopoDS_Shape S = ex.Current();
+    setProp(S, a, n);
+  }
+
+  for (ex.Init (Sh,TopAbs_FACE); ex.More(); ex.Next()) {
+    TopoDS_Shape S = ex.Current();
+    setProp(S, a, n);
+  }
+
+  return 0;
+}
+
 //=======================================================================
 //memory management
 //=======================================================================
@@ -1014,73 +1119,146 @@ static Standard_Integer check(Draw_Interpretor& ,
 //=======================================================================
 // normals
 //=======================================================================
-
-static Standard_Integer normals(Draw_Interpretor& di,
-                               Standard_Integer n, const char** a)
+static Standard_Integer normals (Draw_Interpretor& theDI,
+                                 Standard_Integer  theArgNum,
+                                 const char**      theArgs)
 {
-  if (n <= 1) return 1;
-  Standard_Real l = 1.;
-  if (n > 2) 
-    l = Draw::Atof(a[2]);
-
-  TopoDS_Shape S = DBRep::Get(a[1]);
-  if (S.IsNull()) return 1;
-
-  DBRep_WriteColorOrientation();
-
-  gp_Pnt P1,P2;
-  gp_Vec V,V1,V2;
-  Draw_Color col;
+  if (theArgNum < 2)
+  {
+    std::cout << "Syntax error: wrong number of arguments!\n";
+    theDI.PrintHelp (theArgs[0]);
+    return 1;
+  }
 
-  TopExp_Explorer ex(S,TopAbs_FACE);
-  while (ex.More()) {
+  TopoDS_Shape aShape = DBRep::Get (theArgs[1]);
+  if (aShape.IsNull())
+  {
+    std::cout << "Error: shape with name " << theArgs[1] << " is not found\n";
+    return 1;
+  }
 
-    const TopoDS_Face& F = TopoDS::Face(ex.Current());
-    
-    // find the center of the minmax
-    BRepAdaptor_Surface SF(F);
-
-    Standard_Real u, v, x;
-
-    u = SF.FirstUParameter();
-    x = SF.LastUParameter();
-    if (Precision::IsInfinite(u))
-      u =  (Precision::IsInfinite(x)) ? 0. : x;
-    else if (!Precision::IsInfinite(x))
-      u = (u+x) / 2.;
-
-    v = SF.FirstVParameter();
-    x = SF.LastVParameter();
-    if (Precision::IsInfinite(v))
-      v =  (Precision::IsInfinite(x)) ? 0. : x;
-    else if (!Precision::IsInfinite(x))
-      v = (v+x) / 2.;
-
-    SF.D1(u,v,P1,V1,V2);
-    V = V1.Crossed(V2);
-    x = V.Magnitude();
-    if (x > 1.e-10) 
-      V.Multiply(l/x);
-    else {
-      V.SetCoord(l/2.,0,0);
-      di << "Null normal"<< "\n";
+  Standard_Boolean toUseMesh = Standard_False;
+  Standard_Real    aLength   = 10.0;
+  Standard_Integer aNbAlongU = 1, aNbAlongV = 1;
+  Standard_Boolean bPrint = Standard_False;
+  for (Standard_Integer anArgIter = 2; anArgIter< theArgNum; ++anArgIter)
+  {
+    TCollection_AsciiString aParam (theArgs[anArgIter]);
+    aParam.LowerCase();
+    if (anArgIter == 2
+     && aParam.IsRealValue())
+    {
+      aLength = aParam.RealValue();
+      if (Abs (aLength) <= gp::Resolution())
+      {
+        std::cout << "Syntax error: length should not be zero\n";
+        return 1;
+      }
+    }
+    else if (aParam == "-usemesh"
+          || aParam == "-mesh")
+    {
+      toUseMesh = Standard_True;
+    }
+    else if (aParam == "-length"
+          || aParam == "-len")
+    {
+      ++anArgIter;
+      aLength = anArgIter < theArgNum ? Draw::Atof(theArgs[anArgIter]) : 0.0;
+      if (Abs(aLength) <= gp::Resolution())
+      {
+        std::cout << "Syntax error: length should not be zero\n";
+        return 1;
+      }
     }
+    else if (aParam == "-nbalongu"
+          || aParam == "-nbu")
+    {
+      ++anArgIter;
+      aNbAlongU = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
+      if (aNbAlongU < 1)
+      {
+        std::cout << "Syntax error: NbAlongU should be >=1\n";
+        return 1;
+      }
+    }
+    else if (aParam == "-nbalongv"
+          || aParam == "-nbv")
+    {
+      ++anArgIter;
+      aNbAlongV = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
+      if (aNbAlongV < 1)
+      {
+        std::cout << "Syntax error: NbAlongV should be >=1\n";
+        return 1;
+      }
+    }
+    else if (aParam == "-nbalong"
+          || aParam == "-nbuv")
+    {
+      ++anArgIter;
+      aNbAlongU = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
+      aNbAlongV = aNbAlongU;
+      if (aNbAlongU < 1)
+      {
+        std::cout << "Syntax error: NbAlong should be >=1\n";
+        return 1;
+      }
+    }
+    else if (aParam == "-print")
+    {
+      bPrint = Standard_True;
+    }
+    else
+    {
+      std::cout << "Syntax error: unknown argument '" << aParam << "'\n";
+      return 1;
+    }
+  }
 
-    P2 = P1;
-    P2.Translate(V);
+  DBRep_WriteColorOrientation();
 
-    col = DBRep_ColorOrientation(F.Orientation());
+  NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > aNormals;
+  if (toUseMesh)
+  {
+    DBRep_DrawableShape::addMeshNormals (aNormals, aShape, aLength);
+  }
+  else
+  {
+    DBRep_DrawableShape::addSurfaceNormals (aNormals, aShape, aLength, aNbAlongU, aNbAlongV);
+  }
 
-    Handle(Draw_Segment3D) seg = new Draw_Segment3D(P1,P2,col);
-    dout << seg;
-    
-    
-    ex.Next();
+  for (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >::Iterator aFaceIt (aNormals); aFaceIt.More(); aFaceIt.Next())
+  {
+    Standard_Boolean bReverse = Standard_False;
+    TopAbs_Orientation aFaceOri = aFaceIt.Key().Orientation();
+    const Draw_Color aColor = DBRep_ColorOrientation (aFaceOri);
+    if (aFaceOri == TopAbs_REVERSED)
+      bReverse = Standard_True;
+
+    for (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >::Iterator aNormalsIt (aFaceIt.Value()); aNormalsIt.More(); aNormalsIt.Next())
+    {
+      const std::pair<gp_Pnt, gp_Pnt>& aVec = aNormalsIt.Value();
+      Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(aVec.first, aVec.second, aColor);
+      dout << aSeg;
+      if (bPrint)
+      {
+        // Make the normal vector from the points
+        gp_Vec aV(aVec.first, aVec.second);
+        if (bReverse)
+          aV.Reverse();
+
+        // Print values of the vector avoiding printing "-0" values
+        theDI << "(" << (aV.X() == 0 ? 0 : aV.X()) << ", "
+                     << (aV.Y() == 0 ? 0 : aV.Y()) << ", "
+                     << (aV.Z() == 0 ? 0 : aV.Z()) << ")\n";
+      }
+    }
   }
+
   return 0;
 }
 
-
 //=======================================================================
 //function : Set
 //purpose  : 
@@ -1149,7 +1327,9 @@ static Standard_Integer XProgress (Draw_Interpretor& di, Standard_Integer argc,
     if ( argv[i][1] == 't' ) Draw_ProgressIndicator::DefaultTextMode() = turn;
     else if ( argv[i][1] == 'g' ) Draw_ProgressIndicator::DefaultGraphMode() = turn;
     else if ( ! strcmp ( argv[i], "-stop" ) && i+1 < argc ) {
-      Draw_ProgressIndicator::StopIndicator() = atol(argv[++i]);
+      Standard_Address aPtr = 0;
+      if (sscanf (argv[++i], "%p", &aPtr) == 1)
+        Draw_ProgressIndicator::StopIndicator() = aPtr;
       return 0;
     }
   }
@@ -1169,6 +1349,51 @@ static Standard_Integer XProgress (Draw_Interpretor& di, Standard_Integer argc,
   return 0;
 }
 
+//=======================================================================
+// binsave
+//=======================================================================
+
+static Standard_Integer binsave(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+  if (n <= 2) return 1;
+
+  TopoDS_Shape aShape = DBRep::Get (a[1]);
+  if (aShape.IsNull())
+  {
+    di << a[1] << " is not a shape";
+    return 1;
+  }
+
+  if (!BinTools::Write (aShape, a[2]))
+  {
+    di << "Cannot write to the file " << a[2];
+    return 1;
+  }
+
+  di << a[1];
+  return 0;
+}
+
+//=======================================================================
+// binrestore
+//=======================================================================
+
+static Standard_Integer binrestore(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+  if (n <= 2) return 1;
+
+  TopoDS_Shape aShape;
+  if (!BinTools::Read (aShape, a[1]))
+  {
+    di << "Cannot read from the file " << a[1];
+    return 1;
+  }
+
+  DBRep::Set (a[2], aShape);
+  di << a[2];
+  return 0;
+}
+
 //=======================================================================
 //function : BasicCommands
 //purpose  : 
@@ -1194,7 +1419,7 @@ void  DBRep::BasicCommands(Draw_Interpretor& theCommands)
   theCommands.Add("compound","compound [name1 name2 ..] compound",__FILE__,compound,g);
   theCommands.Add("add","add name1 name2",__FILE__,add,g);
   theCommands.Add("explode","explode name [Cd/C/So/Sh/F/W/E/V]",__FILE__,explode,g);
-  theCommands.Add("nexplode","stable numbered explode for edge and face: nexplode name [F/E]",__FILE__,nexplode,g);
+  theCommands.Add("nexplode","stable numbered explode for vertex, edge and face: nexplode name [V/E/F]",__FILE__,nexplode,g);
   theCommands.Add("exwire","exwire wirename",__FILE__,exwire,g);
   theCommands.Add("emptycopy","emptycopy [copyshape] originalshape",__FILE__,emptycopy,g);
   theCommands.Add("check","check shape1 shape2 ...",__FILE__,check,g);
@@ -1203,12 +1428,15 @@ void  DBRep::BasicCommands(Draw_Interpretor& theCommands)
   theCommands.Add("treverse","treverse name1 name2 ...",__FILE__,orientation,g);
   theCommands.Add("complement","complement name1 name2 ...",__FILE__,orientation,g);
   theCommands.Add("invert","invert name, reverse subshapes",__FILE__,invert,g);
-  theCommands.Add("normals","normals s (length = 10), disp normals",__FILE__,normals,g);
+  theCommands.Add("normals","normals shape [Length {10}] [-NbAlongU {1}] [-NbAlongV {1}] [-UseMesh] [-print], display normals",__FILE__,normals,g);
   theCommands.Add("nbshapes",
                   "\n nbshapes s - shows the number of sub-shapes in <s>;\n nbshapes s -t - shows the number of sub-shapes in <s> counting the same sub-shapes with different location as different sub-shapes.",
                   __FILE__,nbshapes,g);
   theCommands.Add("numshapes","numshapes s; size of shape",__FILE__,numshapes,g);
   theCommands.Add("countshapes","countshapes s; count of shape",__FILE__,countshapes,g);
+  theCommands.Add("setflags",
+                  "setflags shape_name flag1[flag2...]\n sets flags for shape(free, modidfied, checked, orientable, closed, infinite, convex, locked), for exmple <setflags a free> or <setflags a -free> if necessary unflag ",
+                  __FILE__,setFlags,g);
 
 //  theCommands.Add("dumpmmgt",
 //               "dump le contenu du gestionnaire de memoire",__FILE__,dumpmmgt,g);
@@ -1218,6 +1446,13 @@ void  DBRep::BasicCommands(Draw_Interpretor& theCommands)
   
   // Add command for DRAW-specific ProgressIndicator
   theCommands.Add ( "XProgress","XProgress [+|-t] [+|-g]: switch on/off textual and graphical mode of Progress Indicator",XProgress,"DE: General");
+
+  theCommands.Add("binsave", "binsave shape filename\n"
+                  "\t\tsave the shape in the binary format file",
+                  __FILE__, binsave, g);
+  theCommands.Add("binrestore", "binrestore filename shape\n"
+                  "\t\trestore the shape from the binary format file",
+                  __FILE__, binrestore, g);
 }
 
 //=======================================================================