]> OCCT Git - occt-copy.git/commitdiff
0031136: Modeling Data - BinXCAF persistence loses normals from triangulation-only...
authorasuraven <asuraven@opencascade.com>
Tue, 3 Nov 2020 14:22:14 +0000 (17:22 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 12 Nov 2020 14:37:09 +0000 (17:37 +0300)
* Information about normals are stored in BinOCAF, XmlOCAF, BRep and BBRep (in case of triangulation-only Faces).
* Versions of formats have been changed (11 for BinOCAF, 10 for XmlOCAF, 4 for BRep Shape and 3 for Binary BRep Shape)
* Add new optional -version parameter for save/binsave draw commands

63 files changed:
dox/specification/brep_format.md
dox/upgrade/upgrade.md
src/BRepTools/BRepTools_ShapeSet.cxx
src/BRepTools/BRepTools_ShapeSet.hxx
src/BinLDrivers/BinLDrivers.cxx
src/BinLDrivers/BinLDrivers.hxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentSection.cxx
src/BinLDrivers/BinLDrivers_FormatVersion.hxx [new file with mode: 0644]
src/BinLDrivers/FILES
src/BinMDataStd/BinMDataStd.hxx
src/BinMDataStd/BinMDataStd_AsciiStringDriver.cxx
src/BinMDataStd/BinMDataStd_ByteArrayDriver.cxx
src/BinMDataStd/BinMDataStd_ExtStringArrayDriver.cxx
src/BinMDataStd/BinMDataStd_GenericExtStringDriver.cxx
src/BinMDataStd/BinMDataStd_IntPackedMapDriver.cxx
src/BinMDataStd/BinMDataStd_IntegerArrayDriver.cxx
src/BinMDataStd/BinMDataStd_IntegerDriver.cxx
src/BinMDataStd/BinMDataStd_RealArrayDriver.cxx
src/BinMDataStd/BinMDataStd_RealDriver.cxx
src/BinMNaming/BinMNaming_NamedShapeDriver.cxx
src/BinMNaming/BinMNaming_NamingDriver.cxx
src/BinMXCAFDoc/BinMXCAFDoc_LocationDriver.cxx
src/BinTools/BinTools.cxx
src/BinTools/BinTools_FormatVersion.hxx [new file with mode: 0644]
src/BinTools/BinTools_ShapeSet.cxx
src/BinTools/BinTools_ShapeSet.hxx
src/BinTools/FILES
src/DBRep/DBRep.cxx
src/Draw/Draw_Appli.hxx
src/Draw/Draw_SaveAndRestore.cxx [new file with mode: 0644]
src/Draw/Draw_SaveAndRestore.hxx [new file with mode: 0644]
src/Draw/Draw_VariableCommands.cxx
src/Draw/FILES
src/DrawResources/StandardCommands.tcl
src/DrawTrSurf/DrawTrSurf.cxx
src/HLRTest/HLRTest.cxx
src/Poly/Poly_Triangulation.cxx
src/Poly/Poly_Triangulation.hxx
src/Storage/Storage_HeaderData.hxx
src/TopTools/FILES
src/TopTools/TopTools_FormatVersion.hxx [new file with mode: 0644]
src/TopTools/TopTools_ShapeSet.cxx
src/TopTools/TopTools_ShapeSet.hxx
src/XmlLDrivers/FILES
src/XmlLDrivers/XmlLDrivers.cxx
src/XmlLDrivers/XmlLDrivers.hxx
src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx
src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx
src/XmlLDrivers/XmlLDrivers_FormatVersion.hxx [new file with mode: 0644]
src/XmlMDF/XmlMDF.cxx
src/XmlMDataStd/XmlMDataStd_ByteArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_ExtStringArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_IntPackedMapDriver.cxx
src/XmlMDataStd/XmlMDataStd_IntegerArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_RealArrayDriver.cxx
src/XmlMDataStd/XmlMDataStd_TreeNodeDriver.cxx
src/XmlMNaming/XmlMNaming_NamedShapeDriver.cxx
src/XmlMNaming/XmlMNaming_NamingDriver.cxx
src/XmlMXCAFDoc/XmlMXCAFDoc_LocationDriver.cxx
tests/bugs/moddata_3/bug31136_1 [new file with mode: 0644]
tests/bugs/moddata_3/bug31136_2 [new file with mode: 0644]
tests/bugs/moddata_3/bug31136_3 [new file with mode: 0644]

index 82c508aabc2c2910a2253b023f1ace15419f4169..eb84573649c21a16cb7285e46061b1528de74f11 100644 (file)
@@ -54,6 +54,7 @@ The following sample code reads a shape from ASCII file and writes it to a binar
   * \<flag\>: = "0" | "1";
   * \<int\>: It is an integer number from -2<sup>31</sup> to 2<sup>31</sup>-1 which is written in  denary system;  
   * \<real\>: It is a real from -1.7976931348623158 @f$\cdot@f$ 10<sup>308</sup> to 1.7976931348623158 @f$\cdot@f$ 10<sup>308</sup> which is written in decimal or E form with base 10.The point is used as a delimiter of the integer and  fractional parts;
+  * \<short real\>: It is a real from -3.402823 @f$\cdot@f$ 10<sup>38</sup> to 3.402823 @f$\cdot@f$ 10<sup>38</sup> which is written in decimal or E form with base 10.The point is used as a delimiter of the integer and  fractional parts;  
   * \<2D point\>: = \<real\>\<_\>\<real\>;  
   * \<3D point\>: = \<real\>(\<_\>\<real)\><sup>2</sup>;  
   * \<2D direction\>: It is a \<2D point\> *x y* so that *x<sup>2</sup> + y<sup>2</sup>* = 1;  
@@ -71,7 +72,7 @@ The following sample code reads a shape from ASCII file and writes it to a binar
   \<content type\> = "DBRep_DrawableShape" \<_\\n\>\<_\\n\>;  
   \<content type\> have other values [1].  
  
-  \<version\> = ("CASCADE Topology V1, (c)  Matra-Datavision" | "CASCADE Topology V2, (c) Matra-Datavision")\<_\\n\>;  
+  \<version\> = ("CASCADE Topology V1, (c)  Matra-Datavision" | "CASCADE Topology V2, (c) Matra-Datavision" | "Open CASCADE Topology V3 (c)")\<_\\n\>;  
   The difference of the versions is described in the  document.  
  
   Sections \<locations\>, \<geometry\> and \<shapes\> are described below in separate chapters of the document.  
@@ -1436,14 +1437,16 @@ The example record describes a polyline from *m*=2 nodes with a parameter prese
 
        <triangulation records> = <triangulation record> ^ <triangulation count>;
 
-       <triangulation record> = <triangulation node count> <_> <triangulation triangle count> <_> <triangulation parameter presence flag> <_> <triangulation deflection> <_\n> 
-       <triangulation nodes> [<_> <triangulation u v parameters>] <_> <triangulation triangles> <_\n>;
+       <triangulation record> = <triangulation node count> <_> <triangulation triangle count> <_> <triangulation parameter presence flag> [<_> <need to write normals flag>] <_> <triangulation deflection> <_\n> 
+       <triangulation nodes> [<_> <triangulation u v parameters>] <_> <triangulation triangles> [<_> <triangulation normals>] <_\n>;
 
        <triangulation node count> = <int>;
 
        <triangulation triangle count> = <int>;
 
        <triangulation parameter presence flag> = <flag>;
+       
+       <need to write normals flag> = <flag>;
 
        <triangulation deflection> = <real>;
 
@@ -1458,10 +1461,17 @@ The example record describes a polyline from *m*=2 nodes with a parameter prese
 
        <triangulation triangles> = (<triangulation triangle> <_>) ^ <triangulation triangle count>;
 
-       <triangulation triangle> = <int> <_> <int> <_> <int>.  
+       <triangulation triangle> = <int> <_> <int> <_> <int>;
+       
+       <triangulation normals> = (<triangulation normal> <_>) ^ <triangulation node count> ^ 3;
+       
+       <triangulation normal> = <short real>.  
 ~~~~
  
 **Description**  
+
+\<triangulation u v parameters\> are used in version 2 or later.
+\<need to write normals flag\> and \<triangulation normals\> are used in version 3.
  
 \<triangulation record\> describes a triangulation  *T* which  approximates a surface *S*. The triangulation data consist of a node  count @f$ m \geq 3 @f$, a triangle count @f$ k \geq 1 @f$, a parameter  presence flag *p*, a deflection @f$ d \geq 0 @f$, nodes @f$ N_{i}\; (1\leq i \leq m) @f$, parameter pairs @f$ u_{i}\; v_{i}\; (1\leq i \leq m) @f$, triangles @f$ n_{j,1}\; n_{j,2}\; n_{j,3}\; (1\leq j \leq k,\; n_{j,l} \in \left \{1,...,m \right \}\; (1\leq l\leq 3)) @f$. The parameters are present  only if *p*=1. The deflection describes the triangulation deflection from the surface:  
  
@@ -1640,7 +1650,7 @@ An example of section shapes and a whole  *.brep file are given in chapter 7 @re
 
   *  @f$ f_{1} @f$ -- free;  
   *  @f$ f_{2} @f$ -- modified;  
-  *  @f$ f_{3} @f$ -- IGNORED(version 1) \\ checked (version 2);  
+  *  @f$ f_{3} @f$ -- IGNORED(version 1 only) \\ checked (version 2 or later);  
   *  @f$ f_{4} @f$ -- orientable;  
   *  @f$ f_{5} @f$ -- closed;  
   *  @f$ f_{6} @f$ -- infinite;  
@@ -1827,10 +1837,10 @@ Flags \<edge data same parameter flag\>, \<edge data same range flag\> and \<edg
 \<edge data representation data 1\> describes a 3D curve.  
  
 \<edge data representation data 2\> describes a 2D curve on a surface.  
-\<curve values for parameter minimal and maximal  values\> are used only in version 2.  
+\<curve values for parameter minimal and maximal  values\> are used in version 2 or later.  
  
 \<edge data representation data 3\> describes a 2D  curve on a closed surface.  
-\<curve values for parameter minimal and maximal  values\> are used only in version 2.  
+\<curve values for parameter minimal and maximal  values\> are used in version 2 or later.  
  
 \<edge data representation data 5\> describes a 3D polyline.  
  
index 34958e3bd6a08dc5f99a34f724db7be816127d90..0fab42b1e36845f9f3c854fc931740b325753ae7 100644 (file)
@@ -2159,6 +2159,14 @@ Existing message files containing 8-bit characters (previously interpreted as ch
 
 @section upgrade_occt760 Upgrade to OCCT 7.6.0
 
+@subsection upgrade_760_changesInStorageOfShapes Changes in storage of shapes
+
+Information about per-vertex triangulations normals is now stored in BinOCAF and XmlOCAF document,
+BRep and Binary BRep Shape formats (only in case of triangulation-only Faces, with no analytical geometry to restore normals).
+
+Versions of formats have been changed (11 for BinOCAF, 10 for XmlOCAF, 4 for BRep Shape and 3 for Binary BRep Shape).
+Files written with the new version will not be readable by applications of old versions.
+
 @subsection upgrade_760_trimming_surface Trimming surface
 
 Geom_RectangularTrimmedSurface sequentially trimming in U and V directions already no longer loses the first trim.
index 5c7b4030910668ec51deeaffa2e64ecc948eca42..3f7b46ae81066c7fcdeaf3ac28492b6d24c48aea 100644 (file)
@@ -190,7 +190,11 @@ void BRepTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
           }
         }
         else if (CR->IsPolygonOnTriangulation()) {
-          myTriangulations.Add(CR->Triangulation());
+          // NCollection_IndexedDataMap::Add() function use is correct because
+          // Bin(Brep)Tools_ShapeSet::AddGeometry() is called from Bin(Brep)Tools_ShapeSet::Add()
+          // that processes shapes recursively from complex to elementary ones.
+          // As a result, the TopAbs_FACE's will be processed earlier than the TopAbs_EDGE's.
+          myTriangulations.Add(CR->Triangulation(), Standard_False); // edge triangulation does not need normals
           myNodes.Add(CR->PolygonOnTriangulation());
           ChangeLocations().Add(CR->Location());
           if (CR->IsPolygonOnClosedTriangulation())
@@ -211,12 +215,19 @@ void BRepTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
   else if (S.ShapeType() == TopAbs_FACE) {
 
     // Add the surface geometry
+    Standard_Boolean needNormals = Standard_False;
     Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
-    if (!TF->Surface().IsNull())  mySurfaces.Add(TF->Surface());
-
+    if (!TF->Surface().IsNull())
+    {
+      mySurfaces.Add(TF->Surface());
+    }
+    else
+    {
+      needNormals = Standard_True;
+    }
     if (myWithTriangles || TF->Surface().IsNull()) { // for XML Persistence
       Handle(Poly_Triangulation) Tr = TF->Triangulation();
-      if (!Tr.IsNull()) myTriangulations.Add(Tr);
+      if (!Tr.IsNull()) myTriangulations.Add(Tr, needNormals);
     }
 
     ChangeLocations().Add(TF->Location());
@@ -592,7 +603,7 @@ void  BRepTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S, Standard_OStream
         OS << "\n";
 
         // Write UV Points // for XML Persistence higher performance
-        if (FormatNb() == 2)
+        if (FormatNb() >= TOP_TOOLS_VERSION_2)
         {
           gp_Pnt2d Pf,Pl;
           if (CR->IsCurveOnClosedSurface()) {
@@ -902,7 +913,7 @@ void  BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
             GeomTools::GetReal(IS, last);
 
             // read UV Points // for XML Persistence higher performance
-            if (FormatNb() == 2)
+            if (FormatNb() >= TOP_TOOLS_VERSION_2)
             {
               GeomTools::GetReal(IS, PfX);
               GeomTools::GetReal(IS, PfY);
@@ -920,7 +931,7 @@ void  BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
 //  Modified by Sergey KHROMOV - Wed Apr 24 12:11:17 2002 End
 
             if (closed) {
-              if (FormatNb() == 2)
+              if (FormatNb() >= TOP_TOOLS_VERSION_2)
                 myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
                                      myCurves2d.Curve2d(pc2),
                                      mySurfaces.Surface(s),
@@ -941,7 +952,7 @@ void  BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
             }
             else
             {
-              if (FormatNb() == 2)
+              if (FormatNb() >= TOP_TOOLS_VERSION_2)
                 myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
                                      mySurfaces.Surface(s),
                                      Locations().Location(l),tol,
@@ -995,7 +1006,7 @@ void  BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
                 myBuilder.UpdateEdge
                   (E, Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt)),
                    Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt2)),
-                   Handle(Poly_Triangulation)::DownCast(myTriangulations(t)),
+                   myTriangulations.FindKey(t),
                    Locations().Location(l));
             }
             else {
@@ -1003,7 +1014,7 @@ void  BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
                                  pt > 0 && pt <= myNodes.Extent())
                 myBuilder.UpdateEdge
                   (E,Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt)),
-                   Handle(Poly_Triangulation)::DownCast(myTriangulations(t)),
+                   myTriangulations.FindKey(t),
                    Locations().Location(l));
             }
             // range
@@ -1055,7 +1066,7 @@ void  BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
       //only triangulation
       IS >> s;
       myBuilder.UpdateFace(TopoDS::Face(S),
-                           Handle(Poly_Triangulation)::DownCast(myTriangulations(s)));
+                           myTriangulations.FindKey(s));
     }
 //    else pos = IS.tellg();
     
@@ -1072,7 +1083,7 @@ void  BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
       s = atoi ( &string[2] );
          if (s > 0 && s <= myTriangulations.Extent())
         myBuilder.UpdateFace(TopoDS::Face(S),
-                             Handle(Poly_Triangulation)::DownCast(myTriangulations(s)));
+                             myTriangulations.FindKey(s));
     }
 //    else IS.seekg(pos);
     }
@@ -1415,16 +1426,24 @@ void BRepTools_ShapeSet::WriteTriangulation(Standard_OStream&      OS,
   Handle(Poly_Triangulation) T;
   for (i = 1; i <= nbtri && aPS.More(); i++, aPS.Next()) {
 
-    T = Handle(Poly_Triangulation)::DownCast(myTriangulations(i));
+    T = myTriangulations.FindKey(i);
+    const Standard_Boolean toWriteNormals = myTriangulations(i);
     if (Compact) {
       OS << T->NbNodes() << " " << T->NbTriangles() << " ";
       OS << ((T->HasUVNodes()) ? "1" : "0") << " ";
+      if (FormatNb() >= TOP_TOOLS_VERSION_3)
+      {
+        OS << ((T->HasNormals() && toWriteNormals) ? "1" : "0") << " ";
+      }
     }
     else {
       OS << "  "<< i << " : Triangulation with " << T->NbNodes() << " Nodes and "
          << T->NbTriangles() <<" Triangles\n";
       OS << "      "<<((T->HasUVNodes()) ? "with" : "without") << " UV nodes\n";
-
+      if (FormatNb() >= TOP_TOOLS_VERSION_3)
+      {
+        OS << "      " << ((T->HasNormals() && toWriteNormals) ? "with" : "without") << " normals\n";
+      }
     }
     
     // write the deflection
@@ -1479,6 +1498,32 @@ void BRepTools_ShapeSet::WriteTriangulation(Standard_OStream&      OS,
       if (!Compact) OS << "\n";
       else OS << " ";
     }
+
+    if (FormatNb() >= TOP_TOOLS_VERSION_3)
+    {
+      if (T->HasNormals() && toWriteNormals)
+      {
+        if (!Compact) OS << "\nNormals :\n";
+        const TShort_Array1OfShortReal& Normals = T->Normals();
+        for (j = 1; j <= nbNodes * 3; j++)
+        {
+          if (!Compact)
+          {
+            OS << std::setw(10) << j << " : ";
+            OS << std::setw(17);
+          }
+          OS << Normals(j) << " ";
+          if (!Compact)
+          {
+            OS << "\n";
+          }
+          else
+          {
+            OS << " ";
+          }
+        }
+      }
+    }
     OS << "\n";
   }
 }
@@ -1505,8 +1550,10 @@ void BRepTools_ShapeSet::ReadTriangulation(Standard_IStream& IS, const Message_P
   //  Standard_Integer i, j, val, nbtri;
   Standard_Integer i, j, nbtri =0;
   Standard_Real d, x, y, z;
+  Standard_Real normal;
   Standard_Integer nbNodes =0, nbTriangles=0;
   Standard_Boolean hasUV= Standard_False;
+  Standard_Boolean hasNormals= Standard_False;
 
   Handle(Poly_Triangulation) T;
 
@@ -1519,11 +1566,19 @@ void BRepTools_ShapeSet::ReadTriangulation(Standard_IStream& IS, const Message_P
   for (i=1; i<=nbtri && aPS.More();i++, aPS.Next()) {
 
     IS >> nbNodes >> nbTriangles >> hasUV;
+    if (FormatNb() >= TOP_TOOLS_VERSION_3)
+    {
+      IS >> hasNormals;
+    }
     GeomTools::GetReal(IS, d);
 
     TColgp_Array1OfPnt Nodes(1, nbNodes);
     TColgp_Array1OfPnt2d UVNodes(1, nbNodes);
-
+    Handle(TShort_HArray1OfShortReal) Normals;
+    if (hasNormals)
+    {
+      Normals = new TShort_HArray1OfShortReal(1, nbNodes * 3);
+    }
     for (j = 1; j <= nbNodes; j++) {
       GeomTools::GetReal(IS, x);
       GeomTools::GetReal(IS, y);
@@ -1546,12 +1601,24 @@ void BRepTools_ShapeSet::ReadTriangulation(Standard_IStream& IS, const Message_P
       IS >> n1 >> n2 >> n3;
       Triangles(j).Set(n1,n2,n3);
     }
-      
+
+    if (hasNormals)
+    {
+      for (j = 1; j <= nbNodes * 3; j++)
+      {
+        GeomTools::GetReal(IS, normal);
+        Normals->SetValue(j, static_cast<Standard_ShortReal>(normal));
+      }
+    }
+
     if (hasUV) T =  new Poly_Triangulation(Nodes,UVNodes,Triangles);
     else T = new Poly_Triangulation(Nodes,Triangles);
       
     T->Deflection(d);
-      
-    myTriangulations.Add(T);
+    if (hasNormals)
+    {
+      T->SetNormals(Normals);
+    }
+    myTriangulations.Add(T, hasNormals);
   }
 }
index ac5197b4521cc356095a394907b22691d843a5eb..726ca2b9d2702f313c836941d4095e81219de813 100644 (file)
@@ -159,7 +159,9 @@ private:
   GeomTools_Curve2dSet myCurves2d;
   TColStd_IndexedMapOfTransient myPolygons2D;
   TColStd_IndexedMapOfTransient myPolygons3D;
-  TColStd_IndexedMapOfTransient myTriangulations;
+  NCollection_IndexedDataMap<Handle(Poly_Triangulation),
+                             Standard_Boolean> myTriangulations; //!< Contains a boolean flag with information
+                                                                 //!  to save normals for triangulation
   TColStd_IndexedMapOfTransient myNodes;
   Standard_Boolean myWithTriangles;
 
index 1d6774271fdafe893e1e2ae77161edb7e8c33142..dd5e73940d9591aca02c03ffe994e0d1b49af3bd 100644 (file)
@@ -33,7 +33,6 @@
 //#include <BinMNaming.hxx>
 static Standard_GUID BinLStorageDriver  ("13a56835-8269-11d5-aab2-0050044b1af1");
 static Standard_GUID BinLRetrievalDriver("13a56836-8269-11d5-aab2-0050044b1af1");
-#define CURRENT_DOCUMENT_VERSION 10
 
 //=======================================================================
 //function : Factory
@@ -100,7 +99,7 @@ Handle(BinMDF_ADriverTable) BinLDrivers::AttributeDrivers
 
 TCollection_AsciiString BinLDrivers::StorageVersion()
 {
-  TCollection_AsciiString aVersionStr (CURRENT_DOCUMENT_VERSION);
+  TCollection_AsciiString aVersionStr (THE_CURRENT_VERSION);
   return aVersionStr;
 }
 
index 839745981786191b72d1118df40939a4a978565e..920dee082d6423b5cc1191109cbe97bcb9b346c4 100644 (file)
@@ -17,6 +17,7 @@
 #define _BinLDrivers_HeaderFile
 
 #include <Standard_Handle.hxx>
+#include <BinLDrivers_FormatVersion.hxx>
 
 class Standard_Transient;
 class Standard_GUID;
@@ -43,6 +44,10 @@ public:
   
   //! returns last storage version
   Standard_EXPORT static TCollection_AsciiString StorageVersion();
+
+public:
+
+  static const Standard_Integer THE_CURRENT_VERSION = BIN_LDRIVERS_VERSION_11;
 };
 
 #endif // _BinLDrivers_HeaderFile
index ad2e6ff3bf485a640f0fda7ded5eb00cb6ea4c0c..9e4ba602ef8f2a7c8e37ad9bb96f27408863e4b2 100644 (file)
@@ -168,7 +168,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
     return;
   }
   Standard_Integer aFileVer = aHeaderData->StorageVersion().IntegerValue();
-  Standard_Integer aCurrVer = BinLDrivers::StorageVersion().IntegerValue();
+  Standard_Integer aCurrVer = BinLDrivers::THE_CURRENT_VERSION;
   // maintain one-way compatibility starting from version 2+
   if (!CheckDocumentVersion(aFileVer, aCurrVer)) {
     myReaderStatus = PCDM_RS_NoVersion;
@@ -192,7 +192,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
     else if (aStr == END_TYPES)
       break;
     else if (begin) {
-      if ( aFileVer < ) {
+      if ( aFileVer < BIN_LDRIVERS_VERSION_8) {
 #ifdef DATATYPE_MIGRATION
         TCollection_AsciiString  newName;      
         if(Storage_Schema::CheckTypeMigration(aStr, newName)) {
@@ -236,7 +236,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   Message_ProgressScope aPS(theRange, "Reading data", 3);
 
   // 2b. Read the TOC of Sections
-  if (aFileVer >= 3) {
+  if (aFileVer >= BIN_LDRIVERS_VERSION_3) {
     BinLDrivers_DocumentSection aSection;
     do {
       BinLDrivers_DocumentSection::ReadTOC (aSection, theIStream, aFileVer);
@@ -347,7 +347,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   }
 
   // Read Sections (post-reading type)
-  if (aFileVer >= 3) {
+  if (aFileVer >= BIN_LDRIVERS_VERSION_3) {
     BinLDrivers_VectorOfDocumentSection::Iterator aSectIter (mySections);
     for (; aSectIter.More(); aSectIter.Next()) {
       BinLDrivers_DocumentSection& aCurSection = aSectIter.ChangeValue();
@@ -569,7 +569,7 @@ Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion(
                                                           const Standard_Integer theFileVersion,
                                                           const Standard_Integer theCurVersion)
 {
-  if (theFileVersion < 2 || theFileVersion > theCurVersion) {
+  if (theFileVersion < BIN_LDRIVERS_VERSION_2 || theFileVersion > theCurVersion) {
     // file was written with another version
     return Standard_False;
   }
index e3a7c90dcfca058a4eef335af744f60224f919f4..4a7d35b2a5a75f019da514c127eb0ac1d43d07f3 100644 (file)
@@ -199,7 +199,7 @@ void BinLDrivers_DocumentSection::ReadTOC
     theSection.myName = (Standard_CString)&aBuf[0];
 
     uint64_t aValue[3];
-    if (theDocFormatVersion <= 9)
+    if (theDocFormatVersion <= BIN_LDRIVERS_VERSION_9)
     {
       // Old documents stored file position as 4-bytes values.
       Standard_Integer aValInt[3];
diff --git a/src/BinLDrivers/BinLDrivers_FormatVersion.hxx b/src/BinLDrivers/BinLDrivers_FormatVersion.hxx
new file mode 100644 (file)
index 0000000..f9e63d9
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (c) 2020 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.
+
+#ifndef _BinLDriversFormatVersion_HeaderFile
+#define _BinLDriversFormatVersion_HeaderFile
+
+//! Defined BinLDrivers format version
+enum BinLDrivers_FormatVersion
+{
+  BIN_LDRIVERS_VERSION_2 = 2, //!< First supported version
+  BIN_LDRIVERS_VERSION_3,     //!< Add Delta to numbers data, changes in ShapeSection
+  BIN_LDRIVERS_VERSION_4,     //!< entry, ContextLabel for tree
+  BIN_LDRIVERS_VERSION_5,     //!< Convert old format to new
+  BIN_LDRIVERS_VERSION_6,     //!< Add location
+  BIN_LDRIVERS_VERSION_7,     //!< Add orientation, type migration
+  BIN_LDRIVERS_VERSION_8,     //!< Stop convert old format
+  BIN_LDRIVERS_VERSION_9,     //!< Add GUIDs, ReadTOC changed
+  BIN_LDRIVERS_VERSION_10,    //!< Process user defined guid
+  BIN_LDRIVERS_VERSION_11     //!< Add normals to Shape
+};
+
+#endif
index 9d52e0d2b9de1ca343d9edb09e10054035f09218..631b59c81f2d6562238cebc29b6041f165aa691d 100755 (executable)
@@ -6,5 +6,6 @@ BinLDrivers_DocumentSection.cxx
 BinLDrivers_DocumentSection.hxx
 BinLDrivers_DocumentStorageDriver.cxx
 BinLDrivers_DocumentStorageDriver.hxx
+BinLDrivers_FormatVersion.hxx
 BinLDrivers_Marker.hxx
 BinLDrivers_VectorOfDocumentSection.hxx
index 50864bb07c5a90637c67008d1868344dd138fba8..e75e2143a4bb611abe6c990ecb9771bbf698a854 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <Standard_Integer.hxx>
 #include <BinObjMgt_Persistent.hxx>
+#include <BinLDrivers_FormatVersion.hxx>
 
 class BinMDF_ADriverTable;
 class Message_Messenger;
@@ -41,7 +42,7 @@ template<class T>
 static void SetAttributeID(const BinObjMgt_Persistent& theSource, const Handle(T)& anAtt, const Standard_Integer aDocFormatVersion)
 {
   Standard_Boolean ok = Standard_True;
-  if(aDocFormatVersion > 9) { // process user defined guid
+  if(aDocFormatVersion >= BIN_LDRIVERS_VERSION_10) { // process user defined guid
     const Standard_Integer& aPos = theSource.Position();
     Standard_GUID aGuid;
     ok = theSource >> aGuid;
index cc17b780672a9391a93c53a6e42e30cca0393225..73397bf6b4aa6e72a685d817ece73002a56fb8f7 100644 (file)
@@ -62,7 +62,7 @@ Standard_Boolean BinMDataStd_AsciiStringDriver::Paste
   Standard_Boolean ok = Source >> aString;
   if (ok)
     aStrAtt->Set( aString );
-  if(RelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 8) { // process user defined guid
+  if(RelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_9) { // process user defined guid
        const Standard_Integer& aPos = Source.Position();
        Standard_GUID aGuid;
        ok = Source >> aGuid;   
index 5572d807c81720e702b8ec5a7085d5c056249c0d..82e08efe7708564208def94b78c960cf6019457a 100644 (file)
@@ -71,7 +71,7 @@ Standard_Boolean BinMDataStd_ByteArrayDriver::Paste(const BinObjMgt_Persistent&
   anAtt->ChangeArray(bytes);
 
   Standard_Boolean aDelta(Standard_False); 
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_3) {
     Standard_Byte aDeltaValue;
     if (! (theSource >> aDeltaValue))
       return Standard_False;
index 089e2cf1606534acf555342bc20322786108e418..f950f499c6da38bbd87ee18262beadbfc87eaeaa 100644 (file)
@@ -81,7 +81,7 @@ Standard_Boolean BinMDataStd_ExtStringArrayDriver::Paste
 
   if(ok) {
     Standard_Boolean aDelta(Standard_False);
-    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_3) {
       Standard_Byte aDeltaValue;
       if (! (theSource >> aDeltaValue)) {
         return Standard_False;
index 84a0e397496b53131712fe8842e974bb286c6ded..caed67847474dc3986d316f9140a6cf0ef1d2198 100644 (file)
@@ -67,7 +67,7 @@ Standard_Boolean BinMDataStd_GenericExtStringDriver::Paste
   Standard_Boolean ok = Source >> aStr;
   if (ok)
     aStrAttr->Set( aStr );
-  if(RelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 8) { // process user defined guid
+  if(RelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_9) { // process user defined guid
        const Standard_Integer& aPos = Source.Position();
        Standard_GUID aGuid;
        ok = Source >> aGuid;   
index 5d2dd63fef2c26632f53bd22e080da19414ded9a..f74be8df8f4873a84da1c3110c0f310f0c8ecd0f 100644 (file)
@@ -87,7 +87,7 @@ Standard_Boolean BinMDataStd_IntPackedMapDriver::Paste
   }
 
   Standard_Boolean aDelta(Standard_False);
-  if(RelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(RelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_3) {
     Standard_Byte aDeltaValue;
     if (! (Source >> aDeltaValue))
       return Standard_False;
index d0663b17f3b8b749730853e80d5a6d6182b9c3ad..d64490167eaf90ebdae4e54f045b53a7667f0927 100644 (file)
@@ -69,7 +69,7 @@ Standard_Boolean BinMDataStd_IntegerArrayDriver::Paste
   if(!theSource.GetIntArray (&aTargetArray(aFirstInd), aLength))
     return Standard_False;
   Standard_Boolean aDelta(Standard_False);
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_3) {
     Standard_Byte aDeltaValue;
     if (! (theSource >> aDeltaValue))
       return Standard_False;
index 5325bdfd8ffecd83def3e8b40b31190635262f99..db96cc66ccad1483e73fcb9130008b0e4de12539 100644 (file)
@@ -59,7 +59,7 @@ Standard_Boolean BinMDataStd_IntegerDriver::Paste
   Standard_Boolean ok = theSource >> aValue;
   if (ok)
     anAtt->Set(aValue);
-  if(theRT.GetHeaderData()->StorageVersion().IntegerValue() > 8) { // process user defined guid
+  if(theRT.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_9) { // process user defined guid
        const Standard_Integer& aPos = theSource.Position();
        Standard_GUID aGuid;
        ok = theSource >> aGuid;        
index f6d41acba6ad749a59eaa1e64d6dcb854bbff3b4..2fbba0a128af641783ed216dd223b5804876153c 100644 (file)
@@ -70,7 +70,7 @@ Standard_Boolean BinMDataStd_RealArrayDriver::Paste
     return Standard_False;
 
   Standard_Boolean aDelta(Standard_False);
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_3) {
     Standard_Byte aDeltaValue;
     if (! (theSource >> aDeltaValue))
       return Standard_False;
index 5c0111ef3ddae62218e9e23de41f06967705000a..7bd8492d9b467f2f9383d0565c0ea8df1a1c7e8f 100644 (file)
@@ -59,7 +59,7 @@ Standard_Boolean BinMDataStd_RealDriver::Paste
   Standard_Boolean ok = theSource >> aValue;
   if (ok)
     anAtt->Set(aValue);
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 8) { // process user defined guid
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_9) { // process user defined guid
        const Standard_Integer& aPos = theSource.Position();
        Standard_GUID aGuid;
        ok = theSource >> aGuid;        
index 767c19d8ff06f265c95e1d7328e6130b451b659e..6df17625213b0b2112390821b7efab718871572a 100644 (file)
@@ -34,7 +34,6 @@
 IMPLEMENT_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
 
 #define SHAPESET "SHAPE_SECTION"
-#define FORMAT_NUMBER 3
 //=======================================================================
 static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
 {
@@ -142,7 +141,7 @@ static int TranslateFrom  (const BinObjMgt_Persistent&  theSource,
 
 BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
                         (const Handle(Message_Messenger)& theMsgDriver)
-     : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()), myShapeSet(Standard_False),myFormatNb(FORMAT_NUMBER)
+     : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()), myShapeSet(Standard_False), myFormatNb(BinTools_ShapeSet::THE_CURRENT_VERSION)
 {
 }
 
index 5a45a1e0749b41a4dc184b4a99f019a1d8f90315..338ea82f13058a4198b48fb48ebf1193c9fc838f 100644 (file)
@@ -13,7 +13,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
+#include <BinLDrivers_FormatVersion.hxx>
 #include <BinMDF_ADriver.hxx>
 #include <BinMNaming.hxx>
 #include <BinMNaming_NamingDriver.hxx>
@@ -237,7 +237,7 @@ Standard_Boolean BinMNaming_NamingDriver::Paste
        myMessageDriver->Send (aMsg, Message_Warning);
          }
 
-    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 3) {
+    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_4) {
        TCollection_AsciiString entry;
        ok = theSource >> entry;
        if(ok) {
@@ -254,8 +254,8 @@ Standard_Boolean BinMNaming_NamingDriver::Paste
                aName.ContextLabel(tLab);
            }
        }
-    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 4 && 
-       theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < 7) {
+    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_5 &&
+       theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < BIN_LDRIVERS_VERSION_7) {
           // Orientation processing - converting from old format
       Handle(TNaming_NamedShape) aNShape;
       if(anAtt->Label().FindAttribute(TNaming_NamedShape::GetID(), aNShape)) {
@@ -274,7 +274,7 @@ Standard_Boolean BinMNaming_NamingDriver::Paste
                }
          }
        }
-    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 6) {
+    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= BIN_LDRIVERS_VERSION_7) {
       ok = theSource >> anIndx;
       TopAbs_Orientation OrientationToApply(TopAbs_FORWARD);
       if(ok) {
index 43fa820dfe1a544c07f84f40a53b7d73b937722e..448e169086abada1ebd4830cc86f089bb7d425da 100644 (file)
@@ -93,7 +93,7 @@ Standard_Boolean BinMXCAFDoc_LocationDriver::Translate(const BinObjMgt_Persisten
   }
   
   Standard_Integer aFileVer = theMap.GetHeaderData()->StorageVersion().IntegerValue();
-  if( aFileVer > 5 && myLocations == 0 )
+  if( aFileVer >= BIN_LDRIVERS_VERSION_6 && myLocations == 0 )
   {
     return Standard_False;
   }
@@ -101,7 +101,7 @@ Standard_Boolean BinMXCAFDoc_LocationDriver::Translate(const BinObjMgt_Persisten
   Standard_Integer aPower;
   Handle(TopLoc_Datum3D) aDatum;
   
-  if( aFileVer > 5 )
+  if( aFileVer >= BIN_LDRIVERS_VERSION_6 )
   {
     const TopLoc_Location& aLoc = myLocations->Location(anId);
     aPower = aLoc.FirstPower();
index 16237e5a870580c022fd60c542ef73eb1a5fd5ad..30647730e0ff41f94aab9c5aa8b0440bc7b9b5b0 100644 (file)
@@ -178,7 +178,6 @@ void BinTools::Write (const TopoDS_Shape& theShape, Standard_OStream& theStream,
                       const Message_ProgressRange& theRange)
 {
   BinTools_ShapeSet aShapeSet(Standard_True);
-  aShapeSet.SetFormatNb (3);
   aShapeSet.Add (theShape);
   aShapeSet.Write (theStream, theRange);
   aShapeSet.Write (theShape, theStream);
diff --git a/src/BinTools/BinTools_FormatVersion.hxx b/src/BinTools/BinTools_FormatVersion.hxx
new file mode 100644 (file)
index 0000000..2e65ba5
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (c) 2020 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.
+
+#ifndef _BinToolsFormatVersion_HeaderFile
+#define _BinToolsFormatVersion_HeaderFile
+
+//! Defined BinTools format version
+enum BinTools_FormatVersion
+{
+  BIN_TOOLS_DEFAULT_VERSION = 0, //!< Default version
+  BIN_TOOLS_VERSION_1 = 1,       //!< Does not write CurveOnSurface UV Points
+                                 //!  into the file. On reading calls Check() method.
+  BIN_TOOLS_VERSION_2 = 2,       //!< Stores CurveOnSurface UV Points.
+                                 //!  On reading format is recognized from Version string.
+  BIN_TOOLS_VERSION_3 = 3,
+  BIN_TOOLS_VERSION_4 = 4        //!< Stores per-vertex normal information in case
+                                 //!  of triangulation-only Faces, because
+                                 //!  no analytical geometry to restore normals
+};
+
+#endif
index eaec192d4a74af55c26b0a9c82d098e796a35b3c..d85ee6aad8799e382137857c836e42cfd9e92812 100644 (file)
 
 #include <string.h>
 //#define MDTV_DEB 1
-const char* Version_1  = "Open CASCADE Topology V1 (c)";
-const char* Version_2  = "Open CASCADE Topology V2 (c)";
-const char* Version_3  = "Open CASCADE Topology V3 (c)";
+Standard_CString BinTools_ShapeSet::Version_1  = "Open CASCADE Topology V1 (c)";
+Standard_CString BinTools_ShapeSet::Version_2  = "Open CASCADE Topology V2 (c)";
+Standard_CString BinTools_ShapeSet::Version_3  = "Open CASCADE Topology V3 (c)";
+Standard_CString BinTools_ShapeSet::Version_4  = "Open CASCADE Topology V4 (c)";
+
 //=======================================================================
 //function : operator << (gp_Pnt)
 //purpose  : 
@@ -76,7 +78,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt P)
 //=======================================================================
 
 BinTools_ShapeSet::BinTools_ShapeSet(const Standard_Boolean isWithTriangles)
-     :myFormatNb(3), myWithTriangles(isWithTriangles)
+     :myFormatNb(THE_CURRENT_VERSION), myWithTriangles(isWithTriangles)
 {}
 
 //=======================================================================
@@ -93,6 +95,10 @@ BinTools_ShapeSet::~BinTools_ShapeSet()
 //=======================================================================
 void BinTools_ShapeSet::SetFormatNb(const Standard_Integer theFormatNb)
 {
+  Standard_ASSERT_RETURN(theFormatNb >= BIN_TOOLS_VERSION_1 &&
+                         theFormatNb <= THE_CURRENT_VERSION,
+    "Error: unsupported BinTools version.", );
+
   myFormatNb = theFormatNb;
 }
 
@@ -255,7 +261,11 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
           }
         }
         else if (CR->IsPolygonOnTriangulation()) {
-          myTriangulations.Add(CR->Triangulation());
+          // NCollection_IndexedDataMap::Add() function use is correct because
+          // Bin(Brep)Tools_ShapeSet::AddGeometry() is called from Bin(Brep)Tools_ShapeSet::Add()
+          // that processes shapes recursively from complex to elementary ones.
+          // As a result, the TopAbs_FACE's will be processed earlier than the TopAbs_EDGE's.
+          myTriangulations.Add(CR->Triangulation(), Standard_False); // edge triangulation does not need normals
           myNodes.Add(CR->PolygonOnTriangulation());
           ChangeLocations().Add(CR->Location());
           if (CR->IsPolygonOnClosedTriangulation())
@@ -276,14 +286,21 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
   else if (S.ShapeType() == TopAbs_FACE) {
 
     // Add the surface geometry
+    Standard_Boolean needNormals(Standard_False);
     Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
-    if (!TF->Surface().IsNull())  mySurfaces.Add(TF->Surface());
-
+    if (!TF->Surface().IsNull())
+    {
+      mySurfaces.Add(TF->Surface());
+    }
+    else
+    {
+      needNormals = Standard_True;
+    }
     if (myWithTriangles
      || TF->Surface().IsNull())
     {
       Handle(Poly_Triangulation) Tr = TF->Triangulation();
-      if (!Tr.IsNull()) myTriangulations.Add(Tr);
+      if (!Tr.IsNull()) myTriangulations.Add(Tr, needNormals);
     }
 
     ChangeLocations().Add(TF->Location());
@@ -327,12 +344,22 @@ void  BinTools_ShapeSet::Write (Standard_OStream& OS,
 {
 
   // write the copyright
-  if (myFormatNb == 3)
+  if (myFormatNb == BIN_TOOLS_VERSION_4)
+  {
+    OS << "\n" << Version_4 << "\n";
+  }
+  else if (myFormatNb == BIN_TOOLS_VERSION_3)
+  {
     OS << "\n" << Version_3 << "\n";
-  else if (myFormatNb == 2)
+  }
+  else if (myFormatNb == BIN_TOOLS_VERSION_2)
+  {
     OS << "\n" << Version_2 << "\n";
+  }
   else
+  {
     OS << "\n" << Version_1 << "\n";
+  }
 
   //-----------------------------------------
   // write the locations
@@ -413,15 +440,28 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
     }
     
   } while ( ! IS.fail() && strcmp(vers,Version_1) && strcmp(vers,Version_2) &&
-          strcmp(vers,Version_3));
+           strcmp(vers,Version_3) && strcmp(vers,Version_4));
   if (IS.fail()) {
-    std::cout << "BinTools_ShapeSet::Read: File was not written with this version of the topology"<<std::endl;
-     return;
+    std::cout << "BinTools_ShapeSet::Read: File was not written with this version of the topology" << std::endl;
+    return;
   }
 
-  if (strcmp(vers,Version_3) == 0) SetFormatNb(3);
-  else  if (strcmp(vers,Version_2) == 0) SetFormatNb(2);    
-  else SetFormatNb(1);
+  if (strcmp(vers, Version_4) == 0)
+  {
+    SetFormatNb(BIN_TOOLS_VERSION_4);
+  }
+  else if (strcmp(vers, Version_3) == 0)
+  {
+    SetFormatNb(BIN_TOOLS_VERSION_3);
+  }
+  else if (strcmp(vers, Version_2) == 0)
+  {
+    SetFormatNb(BIN_TOOLS_VERSION_2);
+  }
+  else
+  {
+    SetFormatNb(BIN_TOOLS_VERSION_1);
+  }
 
   //-----------------------------------------
   // read the locations
@@ -481,7 +521,7 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
 
     S.Free(aFree);
     S.Modified(aMod);
-     if (myFormatNb >= 2)
+     if (myFormatNb >= BIN_TOOLS_VERSION_2)
        S.Checked(aChecked);
      else
        S.Checked   (Standard_False);     // force check at reading.. 
@@ -491,7 +531,7 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
     S.Convex    (aConv);
     // check
 
-    if (myFormatNb == 1)
+    if (myFormatNb == BIN_TOOLS_VERSION_1)
       if(T == TopAbs_FACE) {
        const TopoDS_Face& F = TopoDS::Face(S);
        BRepTools::Update(F);
@@ -684,7 +724,7 @@ void  BinTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S,
          BinTools::PutReal(OS, last);
 
         // Write UV Points for higher performance
-         if (FormatNb() >= 2)
+         if (myFormatNb >= BIN_TOOLS_VERSION_2)
            {
              gp_Pnt2d Pf,Pl;
              if (CR->IsCurveOnClosedSurface()) {
@@ -828,7 +868,7 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
 
        BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
        TopLoc_Location L;
-       Standard_Boolean aNewF = (myFormatNb > 2);
+       Standard_Boolean aNewF = (myFormatNb >= BIN_TOOLS_VERSION_3);
        do {
          if(aNewF) {
            val = (Standard_Integer)IS.get();//case {0|1|2|3}
@@ -992,7 +1032,7 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
            BinTools::GetReal(IS, last);
 
             // read UV Points // for XML Persistence higher performance
-            if (FormatNb() >= 2)
+            if (myFormatNb >= BIN_TOOLS_VERSION_2)
             {
              BinTools::GetReal(IS, PfX);
              BinTools::GetReal(IS, PfY);
@@ -1008,7 +1048,7 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
              break;
            
             if (closed) {
-              if (FormatNb() >= 2)
+              if (myFormatNb >= BIN_TOOLS_VERSION_2)
                 myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
                                      myCurves2d.Curve2d(pc2),
                                      mySurfaces.Surface(s),
@@ -1029,7 +1069,7 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
             }
             else
             {
-              if (FormatNb() >= 2)
+              if (myFormatNb >= BIN_TOOLS_VERSION_2)
                 myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
                                      mySurfaces.Surface(s),
                                      Locations().Location(l),tol,
@@ -1080,11 +1120,11 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
            BinTools::GetInteger(IS, l);
             if (closed)
             {
-              myBuilder.UpdateEdge (E, myNodes(pt), myNodes(pt2), myTriangulations(t), Locations().Location(l));
+              myBuilder.UpdateEdge (E, myNodes(pt), myNodes(pt2), myTriangulations.FindKey(t), Locations().Location(l));
             }
             else
             {
-              myBuilder.UpdateEdge (E, myNodes(pt), myTriangulations(t), Locations().Location(l));
+              myBuilder.UpdateEdge (E, myNodes(pt), myTriangulations.FindKey(t), Locations().Location(l));
             }
             // range            
             break;
@@ -1133,7 +1173,7 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
       // cas triangulation
        if(aByte == 2) {
          BinTools::GetInteger(IS, s);
-         myBuilder.UpdateFace(TopoDS::Face(S), myTriangulations(s));
+         myBuilder.UpdateFace(TopoDS::Face(S), myTriangulations.FindKey(s));
        }
       }
       break;
@@ -1446,11 +1486,16 @@ void BinTools_ShapeSet::WriteTriangulation (Standard_OStream& OS,
     for (Standard_Integer aTriangulationIter = 1; aTriangulationIter <= aNbTriangulations && aPS.More(); ++aTriangulationIter, aPS.Next())
     {
       const Handle(Poly_Triangulation)& aTriangulation = myTriangulations.FindKey (aTriangulationIter);
+      Standard_Boolean NeedToWriteNormals = myTriangulations.FindFromIndex(aTriangulationIter);
       const Standard_Integer aNbNodes     = aTriangulation->NbNodes();
       const Standard_Integer aNbTriangles = aTriangulation->NbTriangles();
       BinTools::PutInteger(OS, aNbNodes);
       BinTools::PutInteger(OS, aNbTriangles);
       BinTools::PutBool(OS, aTriangulation->HasUVNodes() ? 1 : 0);
+      if (myFormatNb >= BIN_TOOLS_VERSION_4)
+      {
+        BinTools::PutBool(OS, (aTriangulation->HasNormals() && NeedToWriteNormals) ? 1 : 0);
+      }
       BinTools::PutReal(OS, aTriangulation->Deflection());
 
       // write the 3d nodes
@@ -1482,6 +1527,20 @@ void BinTools_ShapeSet::WriteTriangulation (Standard_OStream& OS,
         BinTools::PutInteger(OS, aTri.Value (2));
         BinTools::PutInteger(OS, aTri.Value (3));
       }
+
+      // write the normals
+      if (myFormatNb >= BIN_TOOLS_VERSION_4)
+      {
+        if (aTriangulation->HasNormals() && NeedToWriteNormals)
+        {
+          const TShort_Array1OfShortReal& aNormals = aTriangulation->Normals();
+          for (Standard_Integer aNormalIter = 1; aNormalIter <= 3 * aNbNodes; ++aNormalIter)
+          {
+            const Standard_ShortReal& aNormal = aNormals.Value(aNormalIter);
+            BinTools::PutShortReal(OS, aNormal);
+          }
+        }
+      }
     }
   }
   catch (Standard_Failure const& anException)
@@ -1518,12 +1577,17 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
     {
       Standard_Integer aNbNodes = 0, aNbTriangles = 0;
       Standard_Boolean hasUV = Standard_False;
+      Standard_Boolean hasNormals = Standard_False;
       Standard_Real aDefl = 0.0;
       BinTools::GetInteger(IS, aNbNodes);
       BinTools::GetInteger(IS, aNbTriangles);
       BinTools::GetBool(IS, hasUV);
+      if (myFormatNb >= BIN_TOOLS_VERSION_4)
+      {
+        BinTools::GetBool(IS, hasNormals);
+      }
       BinTools::GetReal(IS, aDefl); //deflection
-      Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation (aNbNodes, aNbTriangles, hasUV);
+      Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation (aNbNodes, aNbTriangles, hasUV, hasNormals);
       aTriangulation->Deflection (aDefl);
 
       TColgp_Array1OfPnt& aNodes = aTriangulation->ChangeNodes();
@@ -1556,7 +1620,19 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
         BinTools::GetInteger(IS, aTri.ChangeValue (3));
       }
 
-      myTriangulations.Add (aTriangulation);
+      if (hasNormals)
+      {
+        TShort_Array1OfShortReal& aNormals = aTriangulation->ChangeNormals();
+        for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes*3; ++aNormalIter)
+        {
+          Standard_ShortReal aNormalFromFile;
+          BinTools::GetShortReal(IS, aNormalFromFile);
+          Standard_ShortReal& aNormalCoordinate = aNormals.ChangeValue(aNormalIter);
+          aNormalCoordinate = aNormalFromFile;
+        }
+      }
+
+      myTriangulations.Add (aTriangulation, hasNormals);
     }
   }
   catch (Standard_Failure const& anException)
index bbc171cfe0e57757ca178a6e92afe081d091d376..693cbe86999b3728a88a44dda5d8e805487bfd7c 100644 (file)
@@ -21,6 +21,7 @@
 #include <Standard_Handle.hxx>
 
 #include <TopTools_IndexedMapOfShape.hxx>
+#include <BinTools_FormatVersion.hxx>
 #include <BinTools_LocationSet.hxx>
 #include <Standard_Integer.hxx>
 #include <BRep_Builder.hxx>
@@ -58,13 +59,10 @@ public:
   //! Ignored (always written) if face defines only triangulation (no surface).
   void SetWithTriangles (const Standard_Boolean isWithTriangles) { myWithTriangles = isWithTriangles; }
 
+  //! Sets the BinTools_FormatVersion.
   Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
-  
-  //! two formats available for the moment:
-  //! First: does not write CurveOnSurface UV Points into the file
-  //! on reading calls Check() method.
-  //! Second: stores CurveOnSurface UV Points.
-  //! On reading format is recognized from Version string.
+
+  //! Returns the BinTools_FormatVersion.
   Standard_EXPORT Standard_Integer FormatNb() const;
   
   //! Clears the content of the set.
@@ -194,6 +192,14 @@ public:
     (Standard_OStream& OS,
         const Message_ProgressRange& theRange = Message_ProgressRange()) const;
 
+public:
+
+  static Standard_CString Version_1;
+  static Standard_CString Version_2;
+  static Standard_CString Version_3;
+  static Standard_CString Version_4;
+  static const BinTools_FormatVersion THE_CURRENT_VERSION = BIN_TOOLS_VERSION_4;
+
 private:
 
   TopTools_IndexedMapOfShape myShapes;
@@ -205,7 +211,9 @@ private:
   BinTools_Curve2dSet myCurves2d;
   NCollection_IndexedMap<Handle(Poly_Polygon2D), TColStd_MapTransientHasher> myPolygons2D;
   NCollection_IndexedMap<Handle(Poly_Polygon3D), TColStd_MapTransientHasher> myPolygons3D;
-  NCollection_IndexedMap<Handle(Poly_Triangulation), TColStd_MapTransientHasher> myTriangulations;
+  NCollection_IndexedDataMap<Handle(Poly_Triangulation),
+                             Standard_Boolean> myTriangulations; //!< Contains a boolean flag with information
+                                                                 //!  to save normals for triangulation
   NCollection_IndexedMap<Handle(Poly_PolygonOnTriangulation), TColStd_MapTransientHasher> myNodes;
   Standard_Boolean myWithTriangles;
 
index fd4a059d363b472239fe731971d08c4f1614a6ab..93f41e661fa05a83113fff9b3169f8cfebe4f21f 100644 (file)
@@ -4,6 +4,7 @@ BinTools_Curve2dSet.cxx
 BinTools_Curve2dSet.hxx
 BinTools_CurveSet.cxx
 BinTools_CurveSet.hxx
+BinTools_FormatVersion.hxx
 BinTools_LocationSet.cxx
 BinTools_LocationSet.hxx
 BinTools_LocationSetPtr.hxx
index ff00a8ab6bea926ba0de235b9a8ab144c5ab43df..769cf61f8d0d132b46f783ba801613c546c5a176 100644 (file)
@@ -14,7 +14,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
+#include <BinTools_ShapeSet.hxx>
 #include <BRep_TEdge.hxx>
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepGProp.hxx>
@@ -27,6 +27,7 @@
 #include <Draw.hxx>
 #include <Draw_Appli.hxx>
 #include <Draw_ProgressIndicator.hxx>
+#include <Draw_SaveAndRestore.hxx>
 #include <Message_ProgressRange.hxx>
 #include <Draw_Segment3D.hxx>
 #include <gp_Ax2.hxx>
@@ -1379,24 +1380,66 @@ static Standard_Integer XProgress (Draw_Interpretor& di, Standard_Integer argc,
 // binsave
 //=======================================================================
 
-static Standard_Integer binsave(Draw_Interpretor& di, Standard_Integer n, const char** a)
+static Standard_Integer binsave(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
-  if (n <= 2) return 1;
+  if (argc < 3)
+  {
+    di << "Syntax error: wrong number of arguments!\n";
+    di.PrintHelp(argv[0]);
+    return 1;
+  }
 
-  TopoDS_Shape aShape = DBRep::Get (a[1]);
+  BinTools_FormatVersion aVersion = BinTools_ShapeSet::THE_CURRENT_VERSION;
+
+  for (Standard_Integer i = 3; i < argc; ++i)
+  {
+    TCollection_AsciiString aParam(argv[i]);
+    aParam.LowerCase();
+    if (aParam == "-version")
+    {
+      ++i;
+      if (i < argc)
+      {
+        aVersion = static_cast<BinTools_FormatVersion>(Draw::Atoi(argv[i]));
+      }
+      if (aVersion == BIN_TOOLS_DEFAULT_VERSION)
+      {
+        aVersion = BinTools_ShapeSet::THE_CURRENT_VERSION;
+      }
+      if (aVersion < BIN_TOOLS_VERSION_1)
+      {
+        di << "Version must not be negative\n";
+        return 1;
+      }
+      if (aVersion > BinTools_ShapeSet::THE_CURRENT_VERSION)
+      {
+        di << "Version higher than "
+           << BinTools_ShapeSet::THE_CURRENT_VERSION
+           << " is not supported\n";
+        return 1;
+      }
+    }
+    else
+    {
+      di << "Syntax error: unknown argument '" << aParam << "'\n";
+      return 1;
+    }
+  }
+
+  TopoDS_Shape aShape = DBRep::Get (argv[1]);
   if (aShape.IsNull())
   {
-    di << a[1] << " is not a shape";
+    di << argv[1] << " is not a shape";
     return 1;
   }
 
-  if (!BinTools::Write (aShape, a[2]))
+  if (!BinTools::Write (aShape, argv[2]))
   {
-    di << "Cannot write to the file " << a[2];
+    di << "Cannot write to the file " << argv[2];
     return 1;
   }
 
-  di << a[1];
+  di << argv[1];
   return 0;
 }
 
@@ -1573,60 +1616,68 @@ Standard_Real DBRep::HLRAngle()
 { return anglHLR; }
 
 //=======================================================================
-//function : 
-//purpose  : save and restore shapes
+//class : DBRep_SaveAndRestore
 //=======================================================================
 
-static Standard_Boolean stest(const Handle(Draw_Drawable3D)& d) 
+class DBRep_SaveAndRestore : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DBRep_DrawableShape));
-}
+public:
+    DBRep_SaveAndRestore()
+    :Draw_SaveAndRestoreBase("DBRep_DrawableShape") {}
 
-static void ssave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DBRep_DrawableShape) 
-    N = Handle(DBRep_DrawableShape)::DownCast(d);
-  BRep_Builder B;
-  BRepTools_ShapeSet S(B);
-  S.Add (N->Shape());
-  Handle(Draw_ProgressIndicator) aProgress = Draw::GetProgressBar();
-  S.Write(OS, Message_ProgressIndicator::Start(aProgress));
-  if (! aProgress.IsNull() && aProgress->UserBreak())
-    return;
-  S.Write(N->Shape(),OS);
-}
+  Standard_Boolean Test(const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DBRep_DrawableShape));
+  }
 
-static Handle(Draw_Drawable3D) srestore (std::istream& IS)
-{
-  BRep_Builder B;
-  BRepTools_ShapeSet S(B);
-  Handle(Draw_ProgressIndicator) aProgress = Draw::GetProgressBar();
-  S.Read(IS, Message_ProgressIndicator::Start(aProgress));
-  Handle(DBRep_DrawableShape) N;
-  if (! aProgress.IsNull() && aProgress->UserBreak())
-    return N;
-  TopoDS_Shape theShape;
-  S.Read(theShape,IS );
-  N = new DBRep_DrawableShape(theShape,
-                           Draw_vert,
-                           Draw_jaune,
-                           Draw_rouge,
-                           Draw_bleu,
-                           size,
-                           nbIsos,
-                           discret);
-  N->DisplayTriangulation(disptriangles);
-  N->DisplayPolygons(disppolygons);
-  N->DisplayHLR(withHLR,withRg1,withRgN,withHid,anglHLR);
-  
-  return N;
-}
+  void Save(const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const Standard_OVERRIDE
+  {
+    Handle(DBRep_DrawableShape) N = Handle(DBRep_DrawableShape)::DownCast(d);
+    BRep_Builder B;
+    BRepTools_ShapeSet S(B);
+    S.SetFormatNb(theVersion);
+    S.Add (N->Shape());
+    Handle(Draw_ProgressIndicator) aProgress = Draw::GetProgressBar();
+    S.Write(OS, Message_ProgressIndicator::Start(aProgress));
+    if (! aProgress.IsNull() && aProgress->UserBreak())
+      return;
+    S.Write(N->Shape(),OS);
+  }
 
+  Handle(Draw_Drawable3D) Restore(std::istream& IS) const Standard_OVERRIDE
+  {
+    BRep_Builder B;
+    BRepTools_ShapeSet S(B);
+    Handle(Draw_ProgressIndicator) aProgress = Draw::GetProgressBar();
+    S.Read(IS, Message_ProgressIndicator::Start(aProgress));
+    Handle(DBRep_DrawableShape) N;
+    if (! aProgress.IsNull() && aProgress->UserBreak())
+      return N;
+    TopoDS_Shape theShape;
+    S.Read(theShape,IS );
+    N = new DBRep_DrawableShape(theShape,
+                             Draw_vert,
+                             Draw_jaune,
+                             Draw_rouge,
+                             Draw_bleu,
+                             size,
+                             nbIsos,
+                             discret);
+    N->DisplayTriangulation(disptriangles);
+    N->DisplayPolygons(disppolygons);
+    N->DisplayHLR(withHLR,withRg1,withRgN,withHid,anglHLR);
 
-static Draw_SaveAndRestore ssr("DBRep_DrawableShape",
-                              stest,ssave,srestore);
+    return N;
+  }
+
+};
 
+static DBRep_SaveAndRestore saveAndRestoreDBRep;
 
+//=======================================================================
+//function : dumps
+//purpose  :
+//=======================================================================
 void dumps (const TopoDS_Shape& S)
 {
  BRepTools::Dump(S,std::cout);
index 8296480d0e6b3fd46bd8f289287901a487d9682a..5d3724cff50632d1b856ec89e7aa2f7833e2c23c 100644 (file)
@@ -37,35 +37,8 @@ extern Draw_Viewer dout;
 extern Standard_Boolean Draw_Batch;
 #endif
 
-class Draw_SaveAndRestore {
 
-  public :
 
-    Standard_EXPORT Draw_SaveAndRestore 
-      (const char* name,
-       Standard_Boolean (*test)(const Handle(Draw_Drawable3D)&),
-       void (*save)(const Handle(Draw_Drawable3D)&, std::ostream&),
-       Handle(Draw_Drawable3D) (*restore) (std::istream&),
-       Standard_Boolean display = Standard_True);
-
-
-  const char* Name() const {return myName;}
-  Standard_Boolean Test(const Handle(Draw_Drawable3D)&d);
-  void Save(const Handle(Draw_Drawable3D)& d, std::ostream& os) const;
-  Handle(Draw_Drawable3D) Restore(std::istream&) const;
-  Standard_Boolean Disp() const {return myDisplay;}
-  Draw_SaveAndRestore* Next() {return myNext;}
-
-  private :
-    
-    const char* myName;
-    Standard_Boolean (*myTest)(const Handle(Draw_Drawable3D)&);
-    void (*mySave)(const Handle(Draw_Drawable3D)&, std::ostream&);
-    Handle(Draw_Drawable3D) (*myRestore) (std::istream&);
-    Standard_Boolean myDisplay;
-    Draw_SaveAndRestore* myNext;
-    
-};
 
 #endif
 
diff --git a/src/Draw/Draw_SaveAndRestore.cxx b/src/Draw/Draw_SaveAndRestore.cxx
new file mode 100644 (file)
index 0000000..50d9927
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (c) 2020 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 <Draw_SaveAndRestore.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepTools_ShapeSet.hxx>
+#include <DBRep_DrawableShape.hxx>
+#include <Draw_Number.hxx>
+#include <Draw_ProgressIndicator.hxx>
+
+Draw_SaveAndRestoreBase* Draw_SaveAndRestoreBase::Draw_FirstSaveAndRestore = NULL;
+
+// ================================================================
+// Function : Draw_SaveAndRestoreBase
+// Purpose  :
+// ================================================================
+Draw_SaveAndRestoreBase::Draw_SaveAndRestoreBase (Standard_CString theName, Standard_Boolean theDisplay)
+: myNext(Draw_FirstSaveAndRestore),
+  myName (theName),
+  myDisplay (theDisplay)
+{
+  Draw_FirstSaveAndRestore = this;
+}
+
+// ================================================================
+// Function : Test
+// Purpose  :
+// ================================================================
+Standard_Boolean Draw_SaveAndRestoreNumber::Test (const Handle(Draw_Drawable3D)& theDrawable3D) const
+{
+  return theDrawable3D->IsInstance(STANDARD_TYPE(Draw_Number));
+}
+
+// ================================================================
+// Function : Save
+// Purpose  :
+// ================================================================
+void Draw_SaveAndRestoreNumber::Save (const Handle(Draw_Drawable3D)& theDrawable3D,
+                                      std::ostream& theStream,
+                                      TopTools_FormatVersion theVersion) const
+{
+  (void) theVersion;
+  Handle(Draw_Number) aNum = Handle(Draw_Number)::DownCast(theDrawable3D);
+  std::ios::fmtflags aFlags = theStream.flags();
+  theStream.setf(std::ios::scientific);
+  theStream.precision(15);
+  theStream.width(30);
+  theStream << aNum->Value() << "\n";
+  theStream.setf(aFlags);
+}
+
+// ================================================================
+// Function : Restore
+// Purpose  :
+// ================================================================
+Handle(Draw_Drawable3D) Draw_SaveAndRestoreNumber::Restore (std::istream& is) const
+{
+  Standard_Real val = RealLast();
+  is >> val;
+  Handle(Draw_Number) N = new Draw_Number(val);
+  return N;
+}
+
+static Draw_SaveAndRestoreNumber saveAndRestoreNumber;
diff --git a/src/Draw/Draw_SaveAndRestore.hxx b/src/Draw/Draw_SaveAndRestore.hxx
new file mode 100644 (file)
index 0000000..941fa6c
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (c) 2020 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.
+
+#ifndef Draw_SaveAndRestore_HeaderFile
+#define Draw_SaveAndRestore_HeaderFile
+
+#include <Draw.hxx>
+#include <TopTools_FormatVersion.hxx>
+
+class Draw_SaveAndRestoreBase
+{
+public:
+  static Draw_SaveAndRestoreBase* GetFirst() { return Draw_FirstSaveAndRestore; }
+
+public:
+  Standard_EXPORT Draw_SaveAndRestoreBase (Standard_CString thename,
+                                           Standard_Boolean theDisplay = Standard_True);
+
+public:
+  virtual void Save (const Handle(Draw_Drawable3D)& theDrawable3D,
+                     std::ostream& theStream,
+                     TopTools_FormatVersion theVersion) const = 0;
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const = 0;
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& theDrawable3D) const = 0;
+
+  Standard_CString Name() const { return myName; }
+
+  const Draw_SaveAndRestoreBase* Next() const { return myNext; }
+
+  Standard_Boolean Disp() const { return myDisplay; }
+
+private:
+  Draw_SaveAndRestoreBase* myNext;
+  Standard_CString         myName;
+  Standard_Boolean         myDisplay;
+private:
+  static Draw_SaveAndRestoreBase* Draw_FirstSaveAndRestore;
+};
+
+class Draw_SaveAndRestoreNumber : public Draw_SaveAndRestoreBase
+{
+public:
+
+  Draw_SaveAndRestoreNumber()
+  : Draw_SaveAndRestoreBase ("Draw_Number", Standard_False) {}
+
+  Standard_EXPORT virtual void Save (const Handle(Draw_Drawable3D)& theDrawable3D,
+                                     std::ostream& theStream,
+                                     TopTools_FormatVersion theVersion) const Standard_OVERRIDE;
+  Standard_EXPORT virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE;
+  Standard_EXPORT virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& theDrawable3D) const Standard_OVERRIDE;
+
+};
+
+#endif
index 5450d9cc2dda82fbbbac3df89b5603c586723e74..57c9583858f34cd3ceadc13cada00c90d5d29340 100644 (file)
 #include <Draw_Number.hxx>
 #include <Message.hxx>
 #include <Draw_ProgressIndicator.hxx>
+#include <Draw_SaveAndRestore.hxx>
 #include <Draw_SequenceOfDrawable3D.hxx>
 #include <Message.hxx>
 #include <NCollection_Map.hxx>
 #include <Standard_SStream.hxx>
 #include <Standard_Stream.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TopTools_ShapeSet.hxx>
 
 #include <ios>
 #ifdef _WIN32
@@ -68,82 +70,57 @@ static Standard_Integer p_b;
 static const char* p_Name = "";
 
 
-static Draw_SaveAndRestore* Draw_First = NULL;
 
 //=======================================================================
-//function : Draw_SaveAndRestore
-//purpose  : 
-//=======================================================================
-
-Draw_SaveAndRestore::Draw_SaveAndRestore
-  (const char* name,
-   Standard_Boolean (*test)(const Handle(Draw_Drawable3D)&),
-  void (*save)(const Handle(Draw_Drawable3D)&, std::ostream&),
-  Handle(Draw_Drawable3D) (*restore) (std::istream&),
-  Standard_Boolean display) :
-  myName(name),
-  myTest(test),
-  mySave(save), 
-  myRestore(restore),
-  myDisplay(display),
-  myNext(Draw_First)
-{
-  Draw_First = this;
-}
-
-Standard_Boolean Draw_SaveAndRestore::Test(const Handle(Draw_Drawable3D)&d)
-{return (*myTest) (d);}
-
-void Draw_SaveAndRestore::Save(const Handle(Draw_Drawable3D)& d, 
-                              std::ostream& os) const
-{ (*mySave) (d,os);}
-
-Handle(Draw_Drawable3D) Draw_SaveAndRestore::Restore(std::istream& is) const
-{return (*myRestore) (is);}
-
-//=======================================================================
-// numeric save and restore
+// save
 //=======================================================================
-
-static Standard_Boolean numtest(const Handle(Draw_Drawable3D)& d) 
+static Standard_Integer save(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
-  return d->IsInstance(STANDARD_TYPE(Draw_Number));
-}
-
-static void numsave (const Handle(Draw_Drawable3D)& theDrawable,
-                     std::ostream&                       theStream)
-{
-  Handle(Draw_Number) aNum = Handle(Draw_Number)::DownCast (theDrawable);
-  std::ios::fmtflags aFlags = theStream.flags();
-  theStream.setf      (std::ios::scientific);
-  theStream.precision (15);
-  theStream.width     (30);
-  theStream << aNum->Value() << "\n";
-  theStream.setf      (aFlags);
-}
-
-static Handle(Draw_Drawable3D) numrestore (std::istream& is)
-{
-  Standard_Real val;
-  is >> val;
-  Handle(Draw_Number) N = new Draw_Number(val);
-  return N;
-}
-
+  if (argc < 3)
+  {
+    di << "Syntax error: wrong number of arguments!\n";
+    di.PrintHelp(argv[0]);
+    return 1;
+  }
 
-static Draw_SaveAndRestore numsr("Draw_Number",
-                                numtest,numsave,numrestore,
-                                Standard_False);
+  TopTools_FormatVersion aVersion = TopTools_ShapeSet::THE_CURRENT_VERSION;
 
-//=======================================================================
-// save
-//=======================================================================
-
-static Standard_Integer save(Draw_Interpretor& di, Standard_Integer n, const char** a)
-{
-  if (n <= 2) return 1;
+  for (Standard_Integer i = 3; i < argc; ++i)
+  {
+    TCollection_AsciiString aParam(argv[i]);
+    aParam.LowerCase();
+    if (aParam == "-version")
+    {
+      ++i;
+      if (i < argc)
+      {
+        aVersion = static_cast<TopTools_FormatVersion>(Draw::Atoi(argv[i]));
+      }
+      if (aVersion == TOP_TOOLS_DEFAULT_VERSION)
+      {
+        aVersion = TopTools_ShapeSet::THE_CURRENT_VERSION;
+      }
+      if (aVersion < TOP_TOOLS_VERSION_1)
+      {
+        di << "Version must not be negative\n";
+        return 1;
+      }
+      if (aVersion > TopTools_ShapeSet::THE_CURRENT_VERSION)
+      {
+        di << "Version higher than " 
+           << static_cast<Standard_Integer>(TopTools_ShapeSet::THE_CURRENT_VERSION) 
+           << " is not supported\n"; \
+        return 1;
+      }
+    }
+    else
+    {
+      di << "Syntax error: unknown argument '" << aParam << "'\n";
+      return 1;
+    }
+  }
 
-  const char* name = a[2];
+  Standard_CString name = argv[2];
   std::ofstream os;
   os.precision(15);
   OSD_OpenStream(os, name, std::ios::out);
@@ -153,10 +130,10 @@ static Standard_Integer save(Draw_Interpretor& di, Standard_Integer n, const cha
     return 1;
   }
 
-  Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
+  Handle(Draw_Drawable3D) D = Draw::Get(argv[1]);
   if (!D.IsNull()) {
     // find a tool
-    Draw_SaveAndRestore* tool = Draw_First;
+    const Draw_SaveAndRestoreBase* tool = Draw_SaveAndRestoreBase::GetFirst();
     Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
 
     while (tool) {
@@ -166,13 +143,14 @@ static Standard_Integer save(Draw_Interpretor& di, Standard_Integer n, const cha
     if (tool) {
       os << tool->Name() << "\n";
       Draw::SetProgressBar(progress);
-      tool->Save(D,os);
+      tool->Save(D, os, aVersion);
       os << "\n";
     }
     else {
-      di << "No method for saving " << a[1];
+      di << "No method for saving " << argv[1];
       return 1;
     }
+
     Draw::SetProgressBar( 0 );
   }
   
@@ -189,7 +167,7 @@ static Standard_Integer save(Draw_Interpretor& di, Standard_Integer n, const cha
     return 1;
   }
 
-  di << a[1];
+  di << argv[1];
   return 0;
 }
 
@@ -220,10 +198,10 @@ static Standard_Integer restore(Draw_Interpretor& di, Standard_Integer n, const
     Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
     Draw::SetProgressBar(progress);
 
-    Draw_SaveAndRestore* tool = Draw_First;
-    Draw_SaveAndRestore* aDBRepTool = NULL;
+    const Draw_SaveAndRestoreBase* tool = Draw_SaveAndRestoreBase::GetFirst();
+    const Draw_SaveAndRestoreBase* aDBRepTool = NULL;
     while (tool) {
-      const char* toolName = tool->Name();
+      Standard_CString toolName = tool->Name();
       if (!strcmp(typ,toolName)) break;
       if (!strcmp("DBRep_DrawableShape",toolName))
         aDBRepTool = tool;
index 479b683ce97decccb9801c4d52044ce50138599a..1b33cbbf859138b0bdc7964773b766dbe2973dbe 100755 (executable)
@@ -54,6 +54,8 @@ Draw_Printer.hxx
 Draw_ProgressIndicator.cxx
 Draw_ProgressIndicator.hxx
 Draw_Replace.tcl
+Draw_SaveAndRestore.cxx
+Draw_SaveAndRestore.hxx
 Draw_Segment2D.cxx
 Draw_Segment2D.hxx
 Draw_Segment3D.cxx
index bcebbde5456a3be80b2016c0c86867b02b2aeda5..70b92bd429a5faff0f58afdd5c403582085a31cc 100644 (file)
@@ -261,14 +261,41 @@ proc datadir {{dir ""}} {
     return $Draw_DataDir
 }
 
-help save {save variable [filename]} "DRAW Variables management"
+help save {
+  Use: save variable [filename] [options...]
+  Allowed options are:
+  -version versnumber: a number of format version to save.
+                       Awailable versions are 1, 2, 3
+                                          Default version is 3
+} "DRAW Variables management"
+
+proc save {name {file ""} {args {}}} {
+    # set default values of arguments
+    set version 0
+
+    # check arguments
+    for {set narg 0} {$narg < [llength $args]} {incr narg} {
+        set arg [lindex $args $narg]
+
+        # set version
+        if { $arg == "-version" } {
+            incr narg
+            if { $narg < [llength $args] && ! [regexp {^-} [lindex $args $narg]] } {
+                set version [lindex $args $narg]
+            } else {
+                error "Option -version requires argument"
+            }
+            continue
+        }
 
-proc save {name {file ""}} {
+        # unsupported option
+        error "Error: unsupported option \"$arg\""
+    }
     if {$file == ""} {set file $name}
     upvar $name n
     if {![isdraw n]} {error "save : $name is not a Draw variable"}
     global Draw_DataDir
-    bsave n [file join $Draw_DataDir $file]
+    bsave n [file join $Draw_DataDir $file] "-version" $version
     return [file join $Draw_DataDir $file]
 }
 
index feb6d5f5dad371ffc02b5ed05f7a062c11bfa1a8..75d3d1681a35951f1bf7f2337e7e58d2697d863f 100644 (file)
@@ -32,6 +32,7 @@
 #include <DrawTrSurf_Polygon2D.hxx>
 #include <DrawTrSurf_Polygon3D.hxx>
 #include <DrawTrSurf_Surface.hxx>
+#include <Draw_SaveAndRestore.hxx>
 #include <DrawTrSurf_Triangulation.hxx>
 #include <Geom2d_BezierCurve.hxx>
 #include <Geom2d_BSplineCurve.hxx>
@@ -1422,491 +1423,556 @@ void  DrawTrSurf::BasicCommands(Draw_Interpretor& theCommands)
 
 
 //=================================================================
-// save and restore curves
+// class : DrawTrSurf_SaveAndRestoreCurve
 //=================================================================
 
-static Standard_Boolean ctest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreCurve : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Curve));
-}
-
-static void csave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_Curve) N = Handle(DrawTrSurf_Curve)::DownCast(d);
-  GeomTools_CurveSet::PrintCurve(N->GetCurve(),OS,Standard_True);
-}
+public:
 
-static Handle(Draw_Drawable3D) crestore (std::istream& is)
-{
-  Handle(Geom_Curve) G = GeomTools_CurveSet::ReadCurve(is);
-  Handle(DrawTrSurf_Curve) N = 
-    new DrawTrSurf_Curve(G,CurvColor,Discret,Deflection,DrawMode);
-  return N;
-}
+  DrawTrSurf_SaveAndRestoreCurve()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_Curve") {}
 
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Curve));
+  }
 
-static Draw_SaveAndRestore csr("DrawTrSurf_Curve",
-                              ctest,csave,crestore);
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const Standard_OVERRIDE
+  {
+    (void)theVersion;
+    Handle(DrawTrSurf_Curve) N = Handle(DrawTrSurf_Curve)::DownCast(d);
+    GeomTools_CurveSet::PrintCurve(N->GetCurve(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom_Curve) G = GeomTools_CurveSet::ReadCurve(is);
+    Handle(DrawTrSurf_Curve) N =
+      new DrawTrSurf_Curve(G,CurvColor,Discret,Deflection,DrawMode);
+    return N;
+  }
 
+};
 
+static DrawTrSurf_SaveAndRestoreCurve saveAndRestoreCurve;
 
 //=================================================================
-// save and restore bezier curves
+// class : DrawTrSurf_SaveAndRestoreBezierCurve
 //=================================================================
 
-static Standard_Boolean bzctest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreBezierCurve : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BezierCurve));
-}
+public:
 
-static void bzcsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_BezierCurve) 
-    N = Handle(DrawTrSurf_BezierCurve)::DownCast(d);
-  GeomTools_CurveSet::PrintCurve(N->GetCurve(),OS,Standard_True);
-}
-
-static Handle(Draw_Drawable3D) bzcrestore (std::istream& is)
-{
-  Handle(Geom_BezierCurve) G = 
-    Handle(Geom_BezierCurve)::DownCast (GeomTools_CurveSet::ReadCurve(is));
-  Handle(DrawTrSurf_BezierCurve) N = 
-    new DrawTrSurf_BezierCurve(G,CurvColor,PolesColor,ShowPoles,
-                              Discret,Deflection,DrawMode);
-  return N;
-}
+  DrawTrSurf_SaveAndRestoreBezierCurve()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_BezierCurve") {}
 
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BezierCurve));
+  }
 
-static Draw_SaveAndRestore bzcsr("DrawTrSurf_BezierCurve",
-                              bzctest,bzcsave,bzcrestore);
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void)theVersion;
+    Handle(DrawTrSurf_BezierCurve) N = Handle(DrawTrSurf_BezierCurve)::DownCast(d);
+    GeomTools_CurveSet::PrintCurve(N->GetCurve(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom_BezierCurve) G = Handle(Geom_BezierCurve)::DownCast (GeomTools_CurveSet::ReadCurve(is));
+    Handle(DrawTrSurf_BezierCurve) N =
+      new DrawTrSurf_BezierCurve(G,CurvColor,PolesColor,ShowPoles,
+                                Discret,Deflection,DrawMode);
+    return N;
+  }
 
+};
 
+static DrawTrSurf_SaveAndRestoreBezierCurve saveAndRestoreBezierCurve;
 
 //=================================================================
-// save and restore bspline curves
+// class : DrawTrSurf_SaveAndRestoreBSplineCurve
 //=================================================================
 
-static Standard_Boolean bsctest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreBSplineCurve : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BSplineCurve));
-}
+public:
 
-static void bscsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_BSplineCurve) 
-    N = Handle(DrawTrSurf_BSplineCurve)::DownCast(d);
-  GeomTools_CurveSet::PrintCurve(N->GetCurve(),OS,Standard_True);
-}
+  DrawTrSurf_SaveAndRestoreBSplineCurve()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_BSplineCurve") {}
 
-static Handle(Draw_Drawable3D) bscrestore (std::istream& is)
-{
-  Handle(Geom_BSplineCurve) G =
-    Handle(Geom_BSplineCurve)::DownCast (GeomTools_CurveSet::ReadCurve(is));
-  Handle(DrawTrSurf_BSplineCurve) N = 
-    new DrawTrSurf_BSplineCurve(G, CurvColor,PolesColor,
-                               KnotsColor,
-                               KnotsShape,KnotsSize,
-                               ShowPoles,ShowKnots,
-                               Discret,Deflection,DrawMode);
-  return N;
-}
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BSplineCurve));
+  }
+
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_BSplineCurve) N = Handle(DrawTrSurf_BSplineCurve)::DownCast(d);
+    GeomTools_CurveSet::PrintCurve(N->GetCurve(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore(std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom_BSplineCurve) G = Handle(Geom_BSplineCurve)::DownCast (GeomTools_CurveSet::ReadCurve(is));
+    Handle(DrawTrSurf_BSplineCurve) N =
+      new DrawTrSurf_BSplineCurve(G, CurvColor,PolesColor,
+                                 KnotsColor,
+                                 KnotsShape,KnotsSize,
+                                 ShowPoles,ShowKnots,
+                                 Discret,Deflection,DrawMode);
+    return N;
+  }
 
-static Draw_SaveAndRestore bscsr("DrawTrSurf_BSplineCurve",
-                              bsctest,bscsave,bscrestore);
+};
 
+static DrawTrSurf_SaveAndRestoreBSplineCurve saveAndRestoreBSplineCurve;
 
 //=================================================================
-// save and restore curves 2d
+// class : DrawTrSurf_SaveAndRestoreCurve2d
 //=================================================================
 
-static Standard_Boolean c2dtest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreCurve2d : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Curve2d));
-}
+public:
 
-static void c2dsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_Curve2d) N = Handle(DrawTrSurf_Curve2d)::DownCast(d);
-  GeomTools_Curve2dSet::PrintCurve2d(N->GetCurve(),OS,Standard_True);
-}
-
-static Handle(Draw_Drawable3D) c2drestore (std::istream& is)
-{
-  Handle(Geom2d_Curve) G = GeomTools_Curve2dSet::ReadCurve2d(is);
-  Handle(DrawTrSurf_Curve2d) N = 
-    new DrawTrSurf_Curve2d(G,CurvColor,Discret);
-  return N;
-}
+  DrawTrSurf_SaveAndRestoreCurve2d()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_Curve2d") {}
 
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Curve2d));
+  }
 
-static Draw_SaveAndRestore c2dsr("DrawTrSurf_Curve2d",
-                              c2dtest,c2dsave,c2drestore);
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_Curve2d) N = Handle(DrawTrSurf_Curve2d)::DownCast(d);
+    GeomTools_Curve2dSet::PrintCurve2d(N->GetCurve(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom2d_Curve) G = GeomTools_Curve2dSet::ReadCurve2d(is);
+    Handle(DrawTrSurf_Curve2d) N = new DrawTrSurf_Curve2d(G,CurvColor,Discret);
+    return N;
+  }
 
+};
 
+static DrawTrSurf_SaveAndRestoreCurve2d saveAndRestoreCurve2d;
 
 //=================================================================
-// save and restore bezier curves 2d
+// class : DrawTrSurf_SaveAndRestoreBezierCurve2d
 //=================================================================
 
-static Standard_Boolean bzc2dtest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreBezierCurve2d : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BezierCurve2d));
-}
+public:
 
-static void bzc2dsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_BezierCurve2d) 
-    N = Handle(DrawTrSurf_BezierCurve2d)::DownCast(d);
-  GeomTools_Curve2dSet::PrintCurve2d(N->GetCurve(),OS,Standard_True);
-}
-
-static Handle(Draw_Drawable3D) bzc2drestore (std::istream& is)
-{
-  Handle(Geom2d_BezierCurve) G =
-    Handle(Geom2d_BezierCurve)::DownCast (GeomTools_Curve2dSet::ReadCurve2d(is));
-  Handle(DrawTrSurf_BezierCurve2d) N = 
-    new DrawTrSurf_BezierCurve2d(G,CurvColor,PolesColor,ShowPoles,
-                              Discret);
-  return N;
-}
+  DrawTrSurf_SaveAndRestoreBezierCurve2d()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_BezierCurve2d") {}
 
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BezierCurve2d));
+  }
 
-static Draw_SaveAndRestore bzc2dsr("DrawTrSurf_BezierCurve2d",
-                              bzc2dtest,bzc2dsave,bzc2drestore);
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_BezierCurve2d) N = Handle(DrawTrSurf_BezierCurve2d)::DownCast(d);
+    GeomTools_Curve2dSet::PrintCurve2d(N->GetCurve(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom2d_BezierCurve) G = Handle(Geom2d_BezierCurve)::DownCast (GeomTools_Curve2dSet::ReadCurve2d(is));
+    Handle(DrawTrSurf_BezierCurve2d) N =
+      new DrawTrSurf_BezierCurve2d(G,CurvColor,PolesColor,ShowPoles,
+                                Discret);
+    return N;
+  }
 
+};
 
+static DrawTrSurf_SaveAndRestoreBezierCurve2d saveAndRestoreBezierCurve2d;
 
 //=================================================================
-// save and restore bspline curves 2d
+// class : DrawTrSurf_SaveAndRestoreBSplineCurve2d
 //=================================================================
 
-static Standard_Boolean bsc2dtest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreBSplineCurve2d : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BSplineCurve2d));
-}
+public:
 
-static void bsc2dsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_BSplineCurve2d) 
-    N = Handle(DrawTrSurf_BSplineCurve2d)::DownCast(d);
-  GeomTools_Curve2dSet::PrintCurve2d(N->GetCurve(),OS,Standard_True);
-}
+  DrawTrSurf_SaveAndRestoreBSplineCurve2d()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_BSplineCurve2d") {}
 
-static Handle(Draw_Drawable3D) bsc2drestore (std::istream& is)
-{
-  Handle(Geom2d_BSplineCurve) G =
-    Handle(Geom2d_BSplineCurve)::DownCast (GeomTools_Curve2dSet::ReadCurve2d(is));
-  Handle(DrawTrSurf_BSplineCurve2d) N = 
-    new DrawTrSurf_BSplineCurve2d(G, CurvColor,PolesColor,
-                               KnotsColor,
-                               KnotsShape,KnotsSize,
-                               ShowPoles,ShowKnots,
-                               Discret);
-  return N;
-}
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BSplineCurve2d));
+  }
+
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_BSplineCurve2d) N = Handle(DrawTrSurf_BSplineCurve2d)::DownCast(d);
+    GeomTools_Curve2dSet::PrintCurve2d(N->GetCurve(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom2d_BSplineCurve) G = Handle(Geom2d_BSplineCurve)::DownCast (GeomTools_Curve2dSet::ReadCurve2d(is));
+    Handle(DrawTrSurf_BSplineCurve2d) N =
+      new DrawTrSurf_BSplineCurve2d(G, CurvColor,PolesColor,
+                                 KnotsColor,
+                                 KnotsShape,KnotsSize,
+                                 ShowPoles,ShowKnots,
+                                 Discret);
+    return N;
+  }
 
-static Draw_SaveAndRestore bsc2dsr("DrawTrSurf_BSplineCurve2d",
-                              bsc2dtest,bsc2dsave,bsc2drestore);
+};
 
+static DrawTrSurf_SaveAndRestoreBSplineCurve2d saveAndRestoreBSplineCurve2d;
 
 //=================================================================
-// save and restore surfaces
+// class : DrawTrSurf_SaveAndRestoreSurface
 //=================================================================
-
-static Standard_Boolean stest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreSurface : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Surface));
-}
-
-static void ssave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_Surface) N = Handle(DrawTrSurf_Surface)::DownCast(d);
-  GeomTools_SurfaceSet::PrintSurface(N->GetSurface(),OS,Standard_True);
-}
+public:
 
-static Handle(Draw_Drawable3D) srestore (std::istream& is)
-{
-  Handle(Geom_Surface) G = GeomTools_SurfaceSet::ReadSurface(is);
-  Handle(DrawTrSurf_Surface) N = 
-    new DrawTrSurf_Surface(G,
-                          NbUIsos,NbVIsos,
-                          BoundsColor,IsosColor,
-                          Discret,Deflection,DrawMode);
-  return N;
-}
+  DrawTrSurf_SaveAndRestoreSurface()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_Surface") {}
 
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Surface));
+  }
 
-static Draw_SaveAndRestore ssr("DrawTrSurf_Surface",
-                              stest,ssave,srestore);
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_Surface) N = Handle(DrawTrSurf_Surface)::DownCast(d);
+    GeomTools_SurfaceSet::PrintSurface(N->GetSurface(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom_Surface) G = GeomTools_SurfaceSet::ReadSurface(is);
+    Handle(DrawTrSurf_Surface) N =
+      new DrawTrSurf_Surface(G,
+                            NbUIsos,NbVIsos,
+                            BoundsColor,IsosColor,
+                            Discret,Deflection,DrawMode);
+    return N;
+  }
 
+};
 
+static DrawTrSurf_SaveAndRestoreSurface saveAndRestoreSurface;
 
 //=================================================================
-// save and restore bezier surfaces
+// class : DrawTrSurf_SaveAndRestoreBezierSurface
 //=================================================================
 
-static Standard_Boolean bzstest(const Handle(Draw_Drawable3D)& d) 
-{
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BezierSurface));
-}
-
-static void bzssave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
+class DrawTrSurf_SaveAndRestoreBezierSurface : public Draw_SaveAndRestoreBase
 {
-  Handle(DrawTrSurf_BezierSurface) 
-    N = Handle(DrawTrSurf_BezierSurface)::DownCast(d);
-  GeomTools_SurfaceSet::PrintSurface(N->GetSurface(),OS,Standard_True);
-}
+public:
 
-static Handle(Draw_Drawable3D) bzsrestore (std::istream& is)
-{
-  Handle(Geom_BezierSurface) G =
-    Handle(Geom_BezierSurface)::DownCast (GeomTools_SurfaceSet::ReadSurface(is));
-  Handle(DrawTrSurf_BezierSurface) N = 
-    new DrawTrSurf_BezierSurface(G,NbUIsos,NbVIsos,
-                                BoundsColor,IsosColor,PolesColor,
-                                ShowPoles,
-                                Discret,Deflection,DrawMode);
-  return N;
-}
+  DrawTrSurf_SaveAndRestoreBezierSurface()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_BezierSurface") {}
 
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BezierSurface));
+  }
 
-static Draw_SaveAndRestore bzssr("DrawTrSurf_BezierSurface",
-                              bzstest,bzssave,bzsrestore);
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_BezierSurface) N = Handle(DrawTrSurf_BezierSurface)::DownCast(d);
+    GeomTools_SurfaceSet::PrintSurface(N->GetSurface(),OS,Standard_True);
+  }
 
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom_BezierSurface) G = Handle(Geom_BezierSurface)::DownCast (GeomTools_SurfaceSet::ReadSurface(is));
+    Handle(DrawTrSurf_BezierSurface) N =
+      new DrawTrSurf_BezierSurface(G,NbUIsos,NbVIsos,
+                                  BoundsColor,IsosColor,PolesColor,
+                                  ShowPoles,
+                                  Discret,Deflection,DrawMode);
+    return N;
+  }
 
+};
 
+static DrawTrSurf_SaveAndRestoreBezierSurface saveAndRestoreBezierSurface;
 
 //=================================================================
-// save and restore bspline surfaces
+// class : DrawTrSurf_SaveAndRestoreBSplineSurface
 //=================================================================
 
-static Standard_Boolean bsstest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreBSplineSurface : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BSplineSurface));
-}
+public:
 
-static void bsssave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_BSplineSurface) 
-    N = Handle(DrawTrSurf_BSplineSurface)::DownCast(d);
-  GeomTools_SurfaceSet::PrintSurface(N->GetSurface(),OS,Standard_True);
-}
+  DrawTrSurf_SaveAndRestoreBSplineSurface()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_BSplineSurface") {}
 
-static Handle(Draw_Drawable3D) bssrestore (std::istream& is)
-{
-  Handle(Geom_BSplineSurface) G =
-    Handle(Geom_BSplineSurface)::DownCast (GeomTools_SurfaceSet::ReadSurface(is));
-  Handle(DrawTrSurf_BSplineSurface) N;
-  if (!knotsIsos) 
-    N   = new DrawTrSurf_BSplineSurface(G,
-                                       NbUIsos,NbVIsos,
-                                       BoundsColor,IsosColor,
-                                       PolesColor,KnotsColor,
-                                       KnotsShape,KnotsSize,
-                                       ShowPoles,ShowKnots,
-                                             Discret,Deflection,DrawMode);
-  else
-    N   = new DrawTrSurf_BSplineSurface(G,
-                                       BoundsColor,IsosColor,
-                                       PolesColor,KnotsColor,
-                                       KnotsShape,KnotsSize,
-                                       ShowPoles,ShowKnots,
-                                       Discret,Deflection,DrawMode);
-       
-  return N;
-}
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_BSplineSurface));
+  }
 
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_BSplineSurface) N = Handle(DrawTrSurf_BSplineSurface)::DownCast(d);
+    GeomTools_SurfaceSet::PrintSurface(N->GetSurface(),OS,Standard_True);
+  }
 
-static Draw_SaveAndRestore bsssr("DrawTrSurf_BSplineSurface",
-                              bsstest,bsssave,bssrestore);
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Handle(Geom_BSplineSurface) G = Handle(Geom_BSplineSurface)::DownCast (GeomTools_SurfaceSet::ReadSurface(is));
+    Handle(DrawTrSurf_BSplineSurface) N;
+    if (!knotsIsos)
+    {
+      N   = new DrawTrSurf_BSplineSurface(G,
+                                         NbUIsos,NbVIsos,
+                                         BoundsColor,IsosColor,
+                                         PolesColor,KnotsColor,
+                                         KnotsShape,KnotsSize,
+                                         ShowPoles,ShowKnots,
+                                               Discret,Deflection,DrawMode);
+    }
+    else
+    {
+      N   = new DrawTrSurf_BSplineSurface(G,
+                                         BoundsColor,IsosColor,
+                                         PolesColor,KnotsColor,
+                                         KnotsShape,KnotsSize,
+                                         ShowPoles,ShowKnots,
+                                         Discret,Deflection,DrawMode);
+    }
+    return N;
+  }
+
+};
 
+static DrawTrSurf_SaveAndRestoreBSplineSurface saveAndRestoreBSplineSurface;
 
 //=================================================================
-// save and restore points
+// class : DrawTrSurf_SaveAndRestorePoint
 //=================================================================
 
-static Standard_Boolean pnttest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestorePoint : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Point));
-}
+public:
 
-static void pntsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_Point) 
-    N = Handle(DrawTrSurf_Point)::DownCast(d);
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  std::ios::fmtflags F = OS.flags();
-  OS.setf(std::ios::scientific,std::ios::floatfield);
-  OS.precision(15);
-#else
-  long form = OS.setf(std::ios::scientific);
-  std::streamsize prec = OS.precision(15);
-#endif
-  gp_Pnt P = N->Point();
-  if (N->Is3D()) {
-    OS << "1 ";
-    OS << P.X() << " " << P.Y() << " " << P.Z() << "\n";
-  }
-  else {
-    OS << "0 ";
-    OS << P.X() << " " << P.Y() << "\n";
-  }
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  OS.setf(F);
-#else
-  OS.setf(form);
-  OS.precision(prec);
-#endif
-}
+  DrawTrSurf_SaveAndRestorePoint()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_Point") {}
 
-static Handle(Draw_Drawable3D) pntrestore (std::istream& is)
-{
-  Standard_Integer is3d;
-  is >> is3d;
-  Standard_Real x,y,z = 0.;
-  if (is3d)
-    is >> x >> y >> z;
-  else
-    is >> x >> y;
-  Handle(DrawTrSurf_Point) N;
-  if (is3d)
-    N = new DrawTrSurf_Point(gp_Pnt(x,y,z),PntShape,PntColor);
-  else
-    N = new DrawTrSurf_Point(gp_Pnt2d(x,y),PntShape,PntColor);
-    
-  return N;
-}
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Point));
+  }
 
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_Point) N = Handle(DrawTrSurf_Point)::DownCast(d);
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    std::ios::fmtflags F = OS.flags();
+    OS.setf(std::ios::scientific,std::ios::floatfield);
+    OS.precision(15);
+  #else
+    long form = OS.setf(std::ios::scientific);
+    std::streamsize prec = OS.precision(15);
+  #endif
+    gp_Pnt P = N->Point();
+    if (N->Is3D()) {
+      OS << "1 ";
+      OS << P.X() << " " << P.Y() << " " << P.Z() << "\n";
+    }
+    else {
+      OS << "0 ";
+      OS << P.X() << " " << P.Y() << "\n";
+    }
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    OS.setf(F);
+  #else
+    OS.setf(form);
+    OS.precision(prec);
+  #endif
+  }
 
-static Draw_SaveAndRestore pntsr("DrawTrSurf_Point",
-                              pnttest,pntsave,pntrestore);
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    Standard_Integer is3d;
+    is >> is3d;
+    Standard_Real x,y,z = 0.;
+    if (is3d)
+      is >> x >> y >> z;
+    else
+      is >> x >> y;
+    Handle(DrawTrSurf_Point) N;
+    if (is3d)
+      N = new DrawTrSurf_Point(gp_Pnt(x,y,z),PntShape,PntColor);
+    else
+      N = new DrawTrSurf_Point(gp_Pnt2d(x,y),PntShape,PntColor);
+
+    return N;
+  }
 
+};
 
+static DrawTrSurf_SaveAndRestorePoint saveAndRestorePoint;
 
 //=================================================================
-// save and restore triangulation
+// class : DrawTrSurf_SaveAndRestoreTriangulation
 //=================================================================
 
-static Standard_Boolean triatest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestoreTriangulation : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Triangulation));
-}
+public:
 
-static void triasave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_Triangulation) 
-    T = Handle(DrawTrSurf_Triangulation)::DownCast(d);
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  std::ios::fmtflags F = OS.flags();
-  OS.setf(std::ios::scientific,std::ios::floatfield);
-  OS.precision(15);
-#else
-  long form = OS.setf(std::ios::scientific);
-  std::streamsize prec = OS.precision(15);
-#endif
-  Poly::Write(T->Triangulation(),OS);
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  OS.setf(F);
-#else
-  OS.setf(form);
-  OS.precision(prec);
-#endif
-}
+  DrawTrSurf_SaveAndRestoreTriangulation()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_Triangulation") {}
 
-static Handle(Draw_Drawable3D) triarestore (std::istream& is)
-{
-  return new DrawTrSurf_Triangulation(Poly::ReadTriangulation(is));
-}
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Triangulation));
+  }
 
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_Triangulation) T = Handle(DrawTrSurf_Triangulation)::DownCast(d);
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    std::ios::fmtflags F = OS.flags();
+    OS.setf(std::ios::scientific,std::ios::floatfield);
+    OS.precision(15);
+  #else
+    long form = OS.setf(std::ios::scientific);
+    std::streamsize prec = OS.precision(15);
+  #endif
+    Poly::Write(T->Triangulation(),OS);
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    OS.setf(F);
+  #else
+    OS.setf(form);
+    OS.precision(prec);
+  #endif
+  }
 
-static Draw_SaveAndRestore triasr("DrawTrSurf_Triangulation",
-                              triatest,triasave,triarestore);
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    return new DrawTrSurf_Triangulation(Poly::ReadTriangulation(is));
+  }
+
+};
+
+static DrawTrSurf_SaveAndRestoreTriangulation saveAndRestoreTriangulation;
 
 
 
 //=================================================================
-// save and restore polygon3d
+// class : DrawTrSurf_SaveAndRestorePolygon3D
 //=================================================================
 
-static Standard_Boolean poly3dtest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestorePolygon3D : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Polygon3D));
-}
+public:
 
-static void poly3dsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_Polygon3D) 
-    T = Handle(DrawTrSurf_Polygon3D)::DownCast(d);
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  std::ios::fmtflags F = OS.flags();
-  OS.setf(std::ios::scientific,std::ios::floatfield);
-  OS.precision(15);
-#else
-  long form = OS.setf(std::ios::scientific);
-  std::streamsize prec = OS.precision(15);
-#endif
-  Poly::Write(T->Polygon3D(),OS);
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  OS.setf(F);
-#else
-  OS.setf(form);
-  OS.precision(prec);
-#endif
-}
+  DrawTrSurf_SaveAndRestorePolygon3D()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_Polygon3D") {}
 
-static Handle(Draw_Drawable3D) poly3drestore (std::istream& is)
-{
-  return new DrawTrSurf_Polygon3D(Poly::ReadPolygon3D(is));
-}
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Polygon3D));
+  }
 
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_Polygon3D) T = Handle(DrawTrSurf_Polygon3D)::DownCast(d);
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    std::ios::fmtflags F = OS.flags();
+    OS.setf(std::ios::scientific,std::ios::floatfield);
+    OS.precision(15);
+  #else
+    long form = OS.setf(std::ios::scientific);
+    std::streamsize prec = OS.precision(15);
+  #endif
+    Poly::Write(T->Polygon3D(),OS);
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    OS.setf(F);
+  #else
+    OS.setf(form);
+    OS.precision(prec);
+  #endif
+  }
 
-static Draw_SaveAndRestore poly3dsr("DrawTrSurf_Polygon3D",
-                              poly3dtest,poly3dsave,poly3drestore);
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    return new DrawTrSurf_Polygon3D(Poly::ReadPolygon3D(is));
+  }
+
+};
 
+static DrawTrSurf_SaveAndRestorePolygon3D saveAndRestorePolygon3D;
 
 //=================================================================
-// save and restore polygon2d
+// class : DrawTrSurf_SaveAndRestorePolygon2D
 //=================================================================
 
-static Standard_Boolean poly2dtest(const Handle(Draw_Drawable3D)& d) 
+class DrawTrSurf_SaveAndRestorePolygon2D : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Polygon2D));
-}
+public:
 
-static void poly2dsave(const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(DrawTrSurf_Polygon2D) 
-    T = Handle(DrawTrSurf_Polygon2D)::DownCast(d);
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  std::ios::fmtflags F = OS.flags();
-  OS.setf(std::ios::scientific, std::ios::floatfield);
-  OS.precision(15);
-#else
-  long form = OS.setf(std::ios::scientific);
-  std::streamsize prec = OS.precision(15);
-#endif
-  Poly::Write(T->Polygon2D(),OS);
-#if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
-  OS.setf(F);
-#else
-  OS.setf(form);
-  OS.precision(prec);
-#endif
-}
+  DrawTrSurf_SaveAndRestorePolygon2D()
+  : Draw_SaveAndRestoreBase("DrawTrSurf_Polygon2D") {}
 
-static Handle(Draw_Drawable3D) poly2drestore (std::istream& is)
-{
-  return new DrawTrSurf_Polygon2D(Poly::ReadPolygon2D(is));
-}
+  virtual Standard_Boolean Test (const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(DrawTrSurf_Polygon2D));
+  }
+
+  virtual void Save (const Handle(Draw_Drawable3D)&d, std::ostream& OS, TopTools_FormatVersion theVersion) const  Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(DrawTrSurf_Polygon2D) T = Handle(DrawTrSurf_Polygon2D)::DownCast(d);
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    std::ios::fmtflags F = OS.flags();
+    OS.setf(std::ios::scientific, std::ios::floatfield);
+    OS.precision(15);
+  #else
+    long form = OS.setf(std::ios::scientific);
+    std::streamsize prec = OS.precision(15);
+  #endif
+    Poly::Write(T->Polygon2D(),OS);
+  #if !defined(_MSC_VER) && !defined(__sgi) && !defined(IRIX)
+    OS.setf(F);
+  #else
+    OS.setf(form);
+    OS.precision(prec);
+  #endif
+  }
+
+  virtual Handle(Draw_Drawable3D) Restore (std::istream& is) const Standard_OVERRIDE
+  {
+    return new DrawTrSurf_Polygon2D(Poly::ReadPolygon2D(is));
+  }
 
+};
 
-static Draw_SaveAndRestore poly2dsr("DrawTrSurf_Polygon2D",
-                              poly2dtest,poly2dsave,poly2drestore);
+static DrawTrSurf_SaveAndRestorePolygon2D saveAndRestorePolygon2D;
 
index 57e31117e40c5a6315e9abf5de286c8a4844dc88..3f3108e8eb3486d4c06f4e225509a854caa0125c 100644 (file)
@@ -18,6 +18,7 @@
 #include <DBRep.hxx>
 #include <Draw.hxx>
 #include <Draw_Appli.hxx>
+#include <Draw_SaveAndRestore.hxx>
 #include <gp_Ax3.hxx>
 #include <HLRAlgo_Projector.hxx>
 #include <HLRAppli_ReflectLines.hxx>
@@ -596,91 +597,84 @@ void HLRTest::Commands (Draw_Interpretor& theCommands)
 }
 
 //=======================================================================
-//function : save and restore projector
-//purpose  : 
+// class : HLRTest_SaveAndRestore
 //=======================================================================
-
-static Standard_Boolean stest(const Handle(Draw_Drawable3D)& d) 
+class HLRTest_SaveAndRestore : public Draw_SaveAndRestoreBase
 {
-  return d->IsInstance(STANDARD_TYPE(HLRTest_Projector));
-}
+public:
 
-//=======================================================================
-//function : ssave
-//purpose  : 
-//=======================================================================
+  HLRTest_SaveAndRestore()
+    :Draw_SaveAndRestoreBase("HLRTest_Projector") {}
 
-static void ssave (const Handle(Draw_Drawable3D)&d, std::ostream& OS)
-{
-  Handle(HLRTest_Projector) HP =
-    Handle(HLRTest_Projector)::DownCast(d);
+  Standard_Boolean Test(const Handle(Draw_Drawable3D)& d) const Standard_OVERRIDE
+  {
+    return d->IsInstance(STANDARD_TYPE(HLRTest_Projector));
+  }
 
-  const HLRAlgo_Projector& P = HP->Projector();
-  OS << (P.Perspective() ? "1" : "0") << "\n";
-  if (P.Perspective())
-    OS << P.Focus() << "\n";
+  void Save(const Handle(Draw_Drawable3D)& d, std::ostream& OS, TopTools_FormatVersion theVersion) const Standard_OVERRIDE
+  {
+    (void) theVersion;
+    Handle(HLRTest_Projector) HP =
+      Handle(HLRTest_Projector)::DownCast(d);
+
+    const HLRAlgo_Projector& P = HP->Projector();
+    OS << (P.Perspective() ? "1" : "0") << "\n";
+    if (P.Perspective())
+      OS << P.Focus() << "\n";
   
-  gp_Trsf T = P.Transformation();
-  gp_XYZ V = T.TranslationPart();
-  gp_Mat M = T.VectorialPart();
-
-  OS << M(1,1) << " ";
-  OS << M(1,2) << " ";
-  OS << M(1,3) << " ";
-  OS << V.Coord(1) << " ";
-  OS << "\n";
-  OS << M(2,1) << " ";
-  OS << M(2,2) << " ";
-  OS << M(2,3) << " ";
-  OS << V.Coord(2) << " ";
-  OS << "\n";
-  OS << M(3,1) << " ";
-  OS << M(3,2) << " ";
-  OS << M(3,3) << " ";
-  OS << V.Coord(3) << " ";
-  OS << "\n";
-
-}
+    gp_Trsf T = P.Transformation();
+    gp_XYZ V = T.TranslationPart();
+    gp_Mat M = T.VectorialPart();
+
+    OS << M(1,1) << " ";
+    OS << M(1,2) << " ";
+    OS << M(1,3) << " ";
+    OS << V.Coord(1) << " ";
+    OS << "\n";
+    OS << M(2,1) << " ";
+    OS << M(2,2) << " ";
+    OS << M(2,3) << " ";
+    OS << V.Coord(2) << " ";
+    OS << "\n";
+    OS << M(3,1) << " ";
+    OS << M(3,2) << " ";
+    OS << M(3,3) << " ";
+    OS << V.Coord(3) << " ";
+    OS << "\n";
 
-//=======================================================================
-//function : srestore
-//purpose  : 
-//=======================================================================
+  }
 
-static Handle(Draw_Drawable3D) srestore (std::istream& IS)
-{
-  Standard_Boolean pers;
-  IS >> pers;
-  Standard_Real focus = 1;
-  if (pers) IS >> focus;
+  Handle(Draw_Drawable3D) Restore(std::istream& IS) const Standard_OVERRIDE
+  {
+    Standard_Boolean pers;
+    IS >> pers;
+    Standard_Real focus = 1;
+    if (pers) IS >> focus;
   
-  gp_Trsf T;
-  Standard_Real V1[3],V2[3],V3[3];
-  Standard_Real V[3];
-
-  IS >> V1[0] >> V1[1] >> V1[2] >> V[0];
-  IS >> V2[0] >> V2[1] >> V2[2] >> V[1];
-  IS >> V3[0] >> V3[1] >> V3[2] >> V[2];
-
-  gp_Dir D1(V1[0],V1[1],V1[2]);
-  gp_Dir D2(V2[0],V2[1],V2[2]);
-  gp_Dir D3(V3[0],V3[1],V3[2]);
-  gp_Ax3 axes(gp_Pnt(0,0,0),D3,D1);
-  D3.Cross(D1);
-  if (D3.Dot(D2) < 0) axes.YReverse();
-  T.SetTransformation(axes);
-
-  T.SetTranslationPart(gp_Vec(V[0],V[1],V[2]));
-
-  HLRAlgo_Projector P(T,pers,focus);
-  Handle(HLRTest_Projector) HP = new HLRTest_Projector(P);
-  return HP;
-}
+    gp_Trsf T;
+    Standard_Real V1[3],V2[3],V3[3];
+    Standard_Real V[3];
+
+    IS >> V1[0] >> V1[1] >> V1[2] >> V[0];
+    IS >> V2[0] >> V2[1] >> V2[2] >> V[1];
+    IS >> V3[0] >> V3[1] >> V3[2] >> V[2];
+
+    gp_Dir D1(V1[0],V1[1],V1[2]);
+    gp_Dir D2(V2[0],V2[1],V2[2]);
+    gp_Dir D3(V3[0],V3[1],V3[2]);
+    gp_Ax3 axes(gp_Pnt(0,0,0),D3,D1);
+    D3.Cross(D1);
+    if (D3.Dot(D2) < 0) axes.YReverse();
+    T.SetTransformation(axes);
+
+    T.SetTranslationPart(gp_Vec(V[0],V[1],V[2]));
+
+    HLRAlgo_Projector P(T,pers,focus);
+    Handle(HLRTest_Projector) HP = new HLRTest_Projector(P);
+    return HP;
+  }
 
-//=======================================================================
-//function : ssr
-//purpose  : 
-//=======================================================================
+};
 
-static Draw_SaveAndRestore ssr("HLRTest_Projector",stest,ssave,srestore);
+static HLRTest_SaveAndRestore saveAndRestoreHLRTest;
 
index b367b5a37d22ba43a520b223db6b76de41a93bf0..a1d67cc3dcd8980de7ecd822b945b449aea53fb4 100644 (file)
@@ -41,9 +41,30 @@ Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
 
 //=======================================================================
 //function : Poly_Triangulation
-//purpose  : 
+//purpose  :
 //=======================================================================
+Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
+                                       const Standard_Integer theNbTriangles,
+                                       const Standard_Boolean theHasUVNodes,
+                                       const Standard_Boolean theHasNormals)
+: myDeflection(0),
+  myNodes     (1, theNbNodes),
+  myTriangles (1, theNbTriangles)
+{
+  if (theHasUVNodes)
+  {
+    myUVNodes = new TColgp_HArray1OfPnt2d(1, theNbNodes);
+  }
+  if (theHasNormals)
+  {
+    myNormals = new TShort_HArray1OfShortReal(1, theNbNodes * 3);
+  }
+}
 
+//=======================================================================
+//function : Poly_Triangulation
+//purpose  :
+//=======================================================================
 Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
                                        const Poly_Array1OfTriangle& theTriangles)
 : myDeflection(0),
index 0465962bbafe33144361df3797f38f5b42699c73..ad7bc9481eeb605766e39105dfb9c15cc1d6099b 100644 (file)
@@ -76,6 +76,17 @@ public:
   //! enable a 2D representation).
   Standard_EXPORT Poly_Triangulation(const Standard_Integer nbNodes, const Standard_Integer nbTriangles, const Standard_Boolean UVNodes);
 
+  //! Constructs a triangulation from a set of triangles.
+  //! The triangulation is initialized without a triangle or a node,
+  //! but capable of containing nbNodes nodes, and nbTriangles triangles.
+  //! Here the UVNodes flag indicates whether 2D nodes will be associated with 3D ones,
+  //! (i.e. to enable a 2D representation).
+  //! Here the hasNormals flag indicates whether normals will be given and associated with nodes.
+  Standard_EXPORT Poly_Triangulation(const Standard_Integer nbNodes,
+                                     const Standard_Integer nbTriangles,
+                                     const Standard_Boolean UVNodes,
+                                     const Standard_Boolean hasNormals);
+
   //! Constructs a triangulation from a set of triangles. The
   //! triangulation is initialized with 3D points from Nodes and triangles
   //! from Triangles.
index 7f726976d6a2dccf817706a16bb3469ed8b97284..79960addea02892dca62a4bed6d065f13cc0dcb4 100644 (file)
@@ -111,6 +111,11 @@ public:
   Standard_EXPORT void SetNumberOfObjects (const Standard_Integer anObjectNumber);
   
   Standard_EXPORT void SetStorageVersion (const TCollection_AsciiString& aVersion);
+
+  void SetStorageVersion (const Standard_Integer aVersion)
+  {
+    SetStorageVersion(TCollection_AsciiString(aVersion));
+  }
   
   Standard_EXPORT void SetCreationDate (const TCollection_AsciiString& aDate);
   
index 9aa32c899b394a78154ea27d868101250abba10c..747e21c1fdde1658a75d850a191e43e23c63a936 100644 (file)
@@ -24,6 +24,7 @@ TopTools_DataMapOfShapeListOfShape.hxx
 TopTools_DataMapOfShapeReal.hxx
 TopTools_DataMapOfShapeSequenceOfShape.hxx
 TopTools_DataMapOfShapeShape.hxx
+TopTools_FormatVersion.hxx
 TopTools_HArray1OfListOfShape.hxx
 TopTools_HArray1OfShape.hxx
 TopTools_HArray2OfShape.hxx
diff --git a/src/TopTools/TopTools_FormatVersion.hxx b/src/TopTools/TopTools_FormatVersion.hxx
new file mode 100644 (file)
index 0000000..3695fad
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (c) 2020 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.
+
+#ifndef _TopToolsFormatVersion_HeaderFile
+#define _TopToolsFormatVersion_HeaderFile
+
+//! Defined TopTools format version
+enum TopTools_FormatVersion
+{
+  TOP_TOOLS_DEFAULT_VERSION = 0, //!< Default version
+  TOP_TOOLS_VERSION_1 = 1,       //!< Does not write CurveOnSurface UV Points into
+                                 //!  the file. On reading calls Check() method.
+  TOP_TOOLS_VERSION_2 = 2,       //!< Stores CurveOnSurface UV Points. On reading format is
+                                 //!  recognized from Version string.
+  TOP_TOOLS_VERSION_3 = 3        //!< Stores per-vertex normal information in case
+                                 //!  of triangulation-only Faces, because
+                                 //!  no analytical geometry to restore normals
+};
+
+#endif
index 8c1c99cfd90b2726799d7b25ba6aabe4df8d7ae9..b14c9e3261476fc8ce32fb804c15fc3eb929eaab 100644 (file)
 #include <TopoDS_Shape.hxx>
 #include <TopTools_LocationSet.hxx>
 #include <TopTools_ShapeSet.hxx>
+#include <Standard_Assert.hxx>
+
+#include <BRep_TFace.hxx>
 
 #include <locale.h>
 #include <string.h>
-static const char* Version  = "CASCADE Topology V1, (c) Matra-Datavision";
-static const char* Version2 = "CASCADE Topology V2, (c) Matra-Datavision";
+Standard_CString TopTools_ShapeSet::Version_1 = "CASCADE Topology V1, (c) Matra-Datavision";
+Standard_CString TopTools_ShapeSet::Version_2 = "CASCADE Topology V2, (c) Matra-Datavision";
+Standard_CString TopTools_ShapeSet::Version_3 = "Open CASCADE Topology V3 (c)";
 
 //=======================================================================
 //function : TopTools_ShapeSet
 //purpose  : 
 //=======================================================================
 
-TopTools_ShapeSet::TopTools_ShapeSet() : myFormatNb(1)
+TopTools_ShapeSet::TopTools_ShapeSet() : myFormatNb(THE_CURRENT_VERSION)
 {
 }
 
@@ -52,6 +56,10 @@ TopTools_ShapeSet::~TopTools_ShapeSet()
 //=======================================================================
 void TopTools_ShapeSet::SetFormatNb(const Standard_Integer theFormatNb)
 {
+  Standard_ASSERT_RETURN(theFormatNb >= TOP_TOOLS_VERSION_1 &&
+                         theFormatNb <= THE_CURRENT_VERSION,
+    "Error: unsupported TopTools version.", );
+
   myFormatNb = theFormatNb;
 }
 
@@ -451,10 +459,18 @@ void  TopTools_ShapeSet::Write(Standard_OStream& OS, const Message_ProgressRange
   std::streamsize prec = OS.precision(15);
 
   // write the copyright
-  if (myFormatNb == 2)
-    OS << "\n" << Version2 << "\n";
+  if (myFormatNb == TOP_TOOLS_VERSION_3)
+  {
+    OS << "\n" << Version_3 << "\n";
+  }
+  else if (myFormatNb == TOP_TOOLS_VERSION_2)
+  {
+    OS << "\n" << Version_2 << "\n";
+  }
   else
-    OS << "\n" << Version << "\n";
+  {
+    OS << "\n" << Version_1 << "\n";
+  }
 
   //-----------------------------------------
   // write the locations
@@ -606,14 +622,27 @@ void  TopTools_ShapeSet::Read(Standard_IStream& IS, const Message_ProgressRange&
         vers[lv] = '\0';
     }
     
-  } while ( ! IS.fail() && strcmp(vers,Version) && strcmp(vers,Version2) );
+  } while ( !IS.fail() && 
+          strcmp(vers, Version_1) && 
+          strcmp(vers, Version_2) &&
+          strcmp(vers, Version_3));
   if (IS.fail()) {
     std::cout << "File was not written with this version of the topology"<<std::endl;
     IS.imbue (anOldLocale);
     return;
   }
-  if (strcmp(vers,Version2) == 0) SetFormatNb(2);
-  else SetFormatNb(1);
+  if (strcmp(vers, Version_3) == 0)
+  {
+    SetFormatNb(TOP_TOOLS_VERSION_3);
+  }
+  else if (strcmp(vers, Version_2) == 0)
+  {
+    SetFormatNb(TOP_TOOLS_VERSION_2);
+  }
+  else
+  {
+    SetFormatNb(TOP_TOOLS_VERSION_1);
+  }
 
   //-----------------------------------------
   // read the locations
@@ -681,7 +710,7 @@ void  TopTools_ShapeSet::Read(Standard_IStream& IS, const Message_ProgressRange&
     S.Free      (buffer[0] == '1');
     S.Modified  (buffer[1] == '1');
 
-    if (myFormatNb == 2)
+    if (myFormatNb >= TOP_TOOLS_VERSION_2)
       S.Checked   (buffer[2] == '1');
     else
       S.Checked   (Standard_False);     // force check at reading.. 
@@ -693,7 +722,7 @@ void  TopTools_ShapeSet::Read(Standard_IStream& IS, const Message_ProgressRange&
 
     // check
 
-    if (myFormatNb == 1)
+    if (myFormatNb == TOP_TOOLS_VERSION_1)
       Check(T,S);
 
     myShapes.Add(S);
index e47fe074a19f069c0f591b8210ccc98439bed5cb..6e0e9f8224dc3f2010cbcd00efb417f678fdc705 100644 (file)
@@ -27,6 +27,7 @@
 #include <Standard_OStream.hxx>
 #include <Standard_IStream.hxx>
 #include <TopAbs_ShapeEnum.hxx>
+#include <TopTools_FormatVersion.hxx>
 
 class TopoDS_Shape;
 class TopTools_LocationSet;
@@ -50,13 +51,10 @@ public:
   
   Standard_EXPORT virtual ~TopTools_ShapeSet();
   
+  //! Sets the TopTools_FormatVersion
   Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
   
-  //! two formats available for the moment:
-  //! First: does not write CurveOnSurface UV Points into the file
-  //! on reading calls Check() method.
-  //! Second: stores CurveOnSurface UV Points.
-  //! On reading format is recognized from Version string.
+  //! Returns the TopTools_FormatVersion
   Standard_EXPORT Standard_Integer FormatNb() const;
   
   //! Clears the content of the set.  This method can be
@@ -181,6 +179,13 @@ public:
   //! Returns number of shapes read from file.
   Standard_EXPORT Standard_Integer NbShapes() const;
 
+public:
+
+  static const TopTools_FormatVersion THE_CURRENT_VERSION = TOP_TOOLS_VERSION_3;
+  static Standard_CString Version_1;
+  static Standard_CString Version_2;
+  static Standard_CString Version_3;
+
 private:
 
   //! Reads  from <IS>  a shape  and  returns  it in  S.
index c64b80983a6e7014d902991b109557ac36ecfabd..fc64e05b89135293def9c8eb40376478883d9706 100644 (file)
@@ -4,6 +4,7 @@ XmlLDrivers_DocumentRetrievalDriver.cxx
 XmlLDrivers_DocumentRetrievalDriver.hxx
 XmlLDrivers_DocumentStorageDriver.cxx
 XmlLDrivers_DocumentStorageDriver.hxx
+XmlLDrivers_FormatVersion.hxx
 XmlLDrivers_NamespaceDef.cxx
 XmlLDrivers_NamespaceDef.hxx
 XmlLDrivers_SequenceOfNamespaceDef.hxx
index 28b44691ac1b8dcdcfd172eb26a0012e911b181b..a5aeed51a821b23b208aa11fe8f40f65d8bcc61a 100644 (file)
@@ -33,7 +33,6 @@
 static Standard_GUID XmlLStorageDriver  ("13a56820-8269-11d5-aab2-0050044b1af1");
 static Standard_GUID XmlLRetrievalDriver("13a56822-8269-11d5-aab2-0050044b1af1");
 
-static int CURRENT_DOCUMENT_VERSION(9);
 
 //=======================================================================
 //function : Factory
@@ -128,9 +127,9 @@ Handle(XmlMDF_ADriverTable) XmlLDrivers::AttributeDrivers
 //purpose  : Document storage version
 //=======================================================================
 
-int XmlLDrivers::StorageVersion()
+TCollection_AsciiString XmlLDrivers::StorageVersion()
 {
-  return CURRENT_DOCUMENT_VERSION;
+  return TCollection_AsciiString(THE_CURRENT_VERSION);
 }
 
 // Declare entry point PLUGINFACTORY
index 171426217354eeb2aedf3c2dc29e4403d3161cb4..2d77c561966f0fa2d98fe7caa0d708707d2e72b4 100644 (file)
@@ -17,6 +17,7 @@
 #define _XmlLDrivers_HeaderFile
 
 #include <Standard_Handle.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
 
 class Standard_Transient;
 class Standard_GUID;
@@ -41,8 +42,12 @@ public:
   Standard_EXPORT static void DefineFormat (const Handle(TDocStd_Application)& theApp);
 
   Standard_EXPORT static Handle(XmlMDF_ADriverTable) AttributeDrivers (const Handle(Message_Messenger)& theMsgDriver);
-  
-  Standard_EXPORT static int StorageVersion();
+
+  Standard_EXPORT static TCollection_AsciiString StorageVersion();
+
+public:
+
+  static const Standard_Integer THE_CURRENT_VERSION = XML_LDRIVERS_VERSION_10;
 };
 
 #endif // _XmlLDrivers_HeaderFile
index 35bf5d345211d68f7ea6c6b7ffa6f5f841fcda43..8a65e6a64789eaa778620a6ae2ef32c8709897f4 100644 (file)
@@ -252,25 +252,32 @@ void XmlLDrivers_DocumentRetrievalDriver::ReadFromDomDocument
     theApplication -> MessageDriver();
   // 1. Read info // to be done
   TCollection_AsciiString anAbsoluteDirectory = GetDirFromFile(myFileName);
-  Standard_Integer aCurDocVersion = 0;
+  Standard_Integer aCurDocVersion = XML_LDRIVERS_VERSION_2; // minimum supported version
   TCollection_ExtendedString anInfo;
   const XmlObjMgt_Element anInfoElem =
     theElement.GetChildByTagName ("info");
   if (anInfoElem != NULL) {
     XmlObjMgt_DOMString aDocVerStr = anInfoElem.getAttribute("DocVersion");
-    if(aDocVerStr == NULL)
-      aCurDocVersion = 2;
-    else if (!aDocVerStr.GetInteger(aCurDocVersion)) {
-      TCollection_ExtendedString aMsg =
-        TCollection_ExtendedString ("Cannot retrieve the current Document version"
-                                    " attribute as \"") + aDocVerStr + "\"";
-      if(!aMsgDriver.IsNull()) 
-        aMsgDriver->Send(aMsg.ToExtString(), Message_Fail);
+    if (aDocVerStr != NULL)
+    {
+      Standard_Integer anIntegerVersion;
+      if (aDocVerStr.GetInteger(anIntegerVersion))
+      {
+        aCurDocVersion = anIntegerVersion;
+      }
+      else
+      {
+        TCollection_ExtendedString aMsg =
+          TCollection_ExtendedString("Cannot retrieve the current Document version"
+            " attribute as \"") + aDocVerStr + "\"";
+        if (!aMsgDriver.IsNull())
+          aMsgDriver->Send(aMsg.ToExtString(), Message_Fail);
+      }
     }
     
     // oan: OCC22305 - check a document verison and if it's greater than
     // current version of storage driver set an error status and return
-    if( aCurDocVersion > XmlLDrivers::StorageVersion() )
+    if( aCurDocVersion > XmlLDrivers::THE_CURRENT_VERSION )
     {
       TCollection_ExtendedString aMsg =
         TCollection_ExtendedString ("error: wrong file version: ") +
@@ -282,7 +289,6 @@ void XmlLDrivers_DocumentRetrievalDriver::ReadFromDomDocument
       return;
     }
 
-    if( aCurDocVersion < 2) aCurDocVersion = 2;
     Standard_Boolean isRef = Standard_False;
     for (LDOM_Node aNode = anInfoElem.getFirstChild();
          aNode != NULL; aNode = aNode.getNextSibling()) {
index bfcfdf1bea91c0e1b0d392746d495e4459239fd8..d1872d6899eb472b06b9b705fa2dc1a06a031b13 100644 (file)
@@ -269,10 +269,10 @@ Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteToDomDocument
 //  anInfoElem.setAttribute("appv", anAppVersion.ToCString());
 
   // Document version
-  Standard_Integer aFormatVersion(XmlLDrivers::StorageVersion());// the last version of the format
-  if (theDocument->StorageFormatVersion() > 0) 
+  Standard_Integer aFormatVersion(XmlLDrivers::THE_CURRENT_VERSION); // the last version of the format
+  if (theDocument->StorageFormatVersion() >= XML_LDRIVERS_VERSION_2) // the minimal supported version
   {
-    if (XmlLDrivers::StorageVersion() < theDocument->StorageFormatVersion())
+    if (theDocument->StorageFormatVersion() > XmlLDrivers::THE_CURRENT_VERSION)
     {
       TCollection_ExtendedString anErrorString("Unacceptable storage format version, the last verson is used");
       aMessageDriver->Send(anErrorString.ToExtString(), Message_Warning);     
@@ -280,7 +280,8 @@ Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteToDomDocument
     else            
       aFormatVersion = theDocument->StorageFormatVersion();
   }
-  anInfoElem.setAttribute("DocVersion", aFormatVersion);
+  TCollection_AsciiString aStringFormatVersion(aFormatVersion);
+  anInfoElem.setAttribute("DocVersion", aStringFormatVersion.ToCString());
  
   // User info with Copyright
   TColStd_SequenceOfAsciiString aUserInfo;
diff --git a/src/XmlLDrivers/XmlLDrivers_FormatVersion.hxx b/src/XmlLDrivers/XmlLDrivers_FormatVersion.hxx
new file mode 100644 (file)
index 0000000..7ec9acf
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (c) 2020 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.
+
+#ifndef _XmlLDriversFormatVersion_HeaderFile
+#define _XmlLDriversFormatVersion_HeaderFile
+
+enum XmlLDrivers_FormatVersion
+{
+  XML_LDRIVERS_VERSION_2 = 2,
+  XML_LDRIVERS_VERSION_3,
+  XML_LDRIVERS_VERSION_4,
+  XML_LDRIVERS_VERSION_5,
+  XML_LDRIVERS_VERSION_6,
+  XML_LDRIVERS_VERSION_7,
+  XML_LDRIVERS_VERSION_8,
+  XML_LDRIVERS_VERSION_9,
+  XML_LDRIVERS_VERSION_10
+};
+
+#endif
index 33711f40f18b2d1c50b33e8a0bc4012ea4052fa2..67074a112a4a0a3c4b121934df11dab45b0e2612 100644 (file)
@@ -35,6 +35,7 @@
 #include <XmlObjMgt_DOMString.hxx>
 #include <XmlObjMgt_Persistent.hxx>
 #include <XmlLDrivers.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
 #include <TDocStd_Owner.hxx>
 #include <TDocStd_Document.hxx>
 #include <Standard_GUID.hxx>
@@ -107,7 +108,7 @@ Standard_Integer XmlMDF::WriteSubTree
       // was replaced by TDataXtd_Presentation. Therefore, for old versions
       // we write old name of the attribute (TPrsStd_AISPresentation).
       Standard_CString typeName = aDriver->TypeName().ToCString();
-      if (theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < 8 &&
+      if (theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < XML_LDRIVERS_VERSION_8 &&
           strcmp(typeName, "TDataXtd_Presentation") == 0)
       {
         typeName = "TPrsStd_AISPresentation";
index 17fe955c2a1be3688bbfe1283fd36396e86b0eb2..06ec3ca423ff3fd1a0bf2bfa67dba1cbe2aefc4c 100644 (file)
@@ -24,6 +24,8 @@
 #include <XmlMDataStd_ByteArrayDriver.hxx>
 #include <XmlObjMgt.hxx>
 #include <XmlObjMgt_Persistent.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
+
 IMPLEMENT_DOMSTRING (AttributeIDString, "bytearrattguid")
 
 IMPLEMENT_STANDARD_RTTIEXT(XmlMDataStd_ByteArrayDriver,XmlMDF_ADriver)
@@ -129,7 +131,7 @@ Standard_Boolean XmlMDataStd_ByteArrayDriver::Paste(const XmlObjMgt_Persistent&
   
   Standard_Boolean aDelta(Standard_False);
   
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_3) {
     Standard_Integer aDeltaValue;
     if (!anElement.getAttribute(::IsDeltaOn()).GetInteger(aDeltaValue)) 
     {
index f60b5c30d6359b20b736249c397f0c1612c3ece1..41b0e227357988f9f5be78ec04b59109b4043f18 100644 (file)
@@ -195,7 +195,7 @@ Standard_Boolean XmlMDataStd_ExtStringArrayDriver::Paste
   // Read delta-flag.
   Standard_Boolean aDelta(Standard_False);
   
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_3) {
     Standard_Integer aDeltaValue;
     if (!anElement.getAttribute(::IsDeltaOn()).GetInteger(aDeltaValue)) 
       {
@@ -240,7 +240,7 @@ void XmlMDataStd_ExtStringArrayDriver::Paste (const Handle(TDF_Attribute)& theSo
   // So, if the user wants to save the document under the 7th or earlier versions,
   // don't apply this improvement.
   Standard_Character c = '-';
-  if (theRelocTable.GetHeaderData()->StorageVersion().IntegerValue()  > 7)
+  if (theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_8)
   {
     // Preferrable symbols for the separator: - _ . : ^ ~
     // Don't use a space as a separator: XML low-level parser sometimes "eats" it.
index 576e4bbef384c1fe6380de6be4495752c217a4d5..7b5fe0c809e1e3ffae21e29856a333f7a8e0087b 100644 (file)
@@ -22,6 +22,7 @@
 #include <TColStd_PackedMapOfInteger.hxx>
 #include <TDataStd_IntPackedMap.hxx>
 #include <TDF_Attribute.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
 #include <XmlMDataStd.hxx>
 #include <XmlMDataStd_IntPackedMapDriver.hxx>
 #include <XmlMDF_ADriver.hxx>
@@ -106,7 +107,7 @@ Standard_Boolean XmlMDataStd_IntPackedMapDriver::Paste
     if(Ok) {
       Standard_Boolean aDelta(Standard_False);
 
-      if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+      if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_3) {
         Standard_Integer aDeltaValue;
         if (!anElement.getAttribute(::IsDeltaOn()).GetInteger(aDeltaValue)) 
         {
index a82d818092dc8362629a20f4780ab63a73c95f9e..22b08693b9834dfb32535f82316c06295ff5da2e 100644 (file)
@@ -20,6 +20,7 @@
 #include <Standard_Type.hxx>
 #include <TDataStd_IntegerArray.hxx>
 #include <TDF_Attribute.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
 #include <XmlMDataStd.hxx>
 #include <XmlMDataStd_IntegerArrayDriver.hxx>
 #include <XmlObjMgt.hxx>
@@ -129,7 +130,7 @@ Standard_Boolean XmlMDataStd_IntegerArrayDriver::Paste
   }
   Standard_Boolean aDelta(Standard_False);
   
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_3) {
     Standard_Integer aDeltaValue;
     if (!anElement.getAttribute(::IsDeltaOn()).GetInteger(aDeltaValue)) 
       {
index ddc296ad5d5deb3f39399c1601fb0d2bd5a1bc46..2d3756fd07db722c4e15dea9e9df304fc30dc053 100644 (file)
@@ -23,6 +23,7 @@
 #include <TColStd_HArray1OfReal.hxx>
 #include <TDataStd_RealArray.hxx>
 #include <TDF_Attribute.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
 #include <XmlMDataStd.hxx>
 #include <XmlMDataStd_RealArrayDriver.hxx>
 #include <XmlObjMgt.hxx>
@@ -140,7 +141,7 @@ Standard_Boolean XmlMDataStd_RealArrayDriver::Paste
   }
   Standard_Boolean aDelta(Standard_False);
   
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 2) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_3) {
     Standard_Integer aDeltaValue;
     if (!anElement.getAttribute(::IsDeltaOn()).GetInteger(aDeltaValue)) 
       {
index c5004b505769f0c736a665eb39a941725b750789..17513c1c548780ddacc5d150fa5a4d2bb58de8d0 100644 (file)
@@ -118,7 +118,7 @@ void XmlMDataStd_TreeNodeDriver::Paste
   // tree id
   // A not default ID is skipped for storage version 8 and newer.
   if (aS->ID() != TDataStd_TreeNode::GetDefaultTreeID() ||
-      theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < 8)
+      theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < XML_LDRIVERS_VERSION_8)
   {
     Standard_Character aGuidStr [40];
     Standard_PCharacter pGuidStr=aGuidStr;
index 813bf7b087d93b9ffc307cab56eeca0de84d1378..edef5fa3d303efd2432c390d1c1a11aada694cd2 100644 (file)
@@ -370,7 +370,7 @@ void XmlMNaming_NamedShapeDriver::WriteShapeSection (XmlObjMgt_Element& theEleme
 
   //  Add text to the "shapes" element
   if (myShapeSet.NbShapes() > 0) {
-    myShapeSet.SetFormatNb(2);
+    myShapeSet.SetFormatNb(TopTools_ShapeSet::THE_CURRENT_VERSION);
     LDOM_OSStream aStream (16 * 1024);
 //    ostrstream aStream;
 //    aStream.rdbuf() -> setbuf (0, 16380);
index d89c1111a3071a7c856c6b39241e9207e08f668c..7c3095cd34463fbc6a336b17dbd99462e7d5457a 100644 (file)
@@ -23,6 +23,7 @@
 #include <TNaming_Name.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Naming.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
 #include <XmlMNaming_NamingDriver.hxx>
 #include <XmlObjMgt.hxx>
 #include <XmlObjMgt_Persistent.hxx>
@@ -174,7 +175,7 @@ Standard_Boolean XmlMNaming_NamingDriver::Paste
   }
   aNgName.Index(aNb);
 //
-  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 3) {
+  if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_4) {
     XmlObjMgt_DOMString aDomEntry = anElem.getAttribute(::ContextLabelString());
     if (aDomEntry != NULL)
     {  
@@ -203,8 +204,8 @@ Standard_Boolean XmlMNaming_NamingDriver::Paste
       std::cout << "Retrieving Context Label is NULL" <<std::endl;
 #endif
 
-    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 4 && 
-      theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < 7) {
+    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_5 &&
+      theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() < XML_LDRIVERS_VERSION_7) {
           // Orientation processing - converting from old format
           Handle(TNaming_NamedShape) aNS;
           if (aNg->Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -223,7 +224,7 @@ Standard_Boolean XmlMNaming_NamingDriver::Paste
             }
           }         
         }
-    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() > 6) {
+    if(theRelocTable.GetHeaderData()->StorageVersion().IntegerValue() >= XML_LDRIVERS_VERSION_7) {
        aDOMStr = anElem.getAttribute(::OrientString());
        if (!aDOMStr.GetInteger(aNb))
        {
index 7918e454a5b70a2bd0a3dd05b3601e18d9bd3ed9..eeab89366829fd2ad48ee526158761f9e175d4da 100644 (file)
@@ -21,6 +21,7 @@
 #include <TopLoc_Location.hxx>
 #include <TopTools_LocationSet.hxx>
 #include <XCAFDoc_Location.hxx>
+#include <XmlLDrivers_FormatVersion.hxx>
 #include <XmlMNaming.hxx>
 #include <XmlMXCAFDoc_LocationDriver.hxx>
 #include <XmlObjMgt.hxx>
@@ -149,7 +150,7 @@ Standard_Boolean XmlMXCAFDoc_LocationDriver::Translate
     return Standard_False;
   
   Standard_Integer aFileVer = theMap.GetHeaderData()->StorageVersion().IntegerValue();
-  if( aFileVer > 5 && myLocations == 0 )
+  if( aFileVer >= XML_LDRIVERS_VERSION_6 && myLocations == 0 )
   {
     return Standard_False;
   }
@@ -157,7 +158,7 @@ Standard_Boolean XmlMXCAFDoc_LocationDriver::Translate
   Standard_Integer aPower;
   Handle(TopLoc_Datum3D) aDatum;
   
-  if( aFileVer > 5 )
+  if( aFileVer >= XML_LDRIVERS_VERSION_6 )
   {
     //  Get Location ID
     Standard_Integer anId;
diff --git a/tests/bugs/moddata_3/bug31136_1 b/tests/bugs/moddata_3/bug31136_1
new file mode 100644 (file)
index 0000000..332f556
--- /dev/null
@@ -0,0 +1,23 @@
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload MODELING XDE OCAF VISUALIZATION
+source $env(CSF_OCCTSamplesPath)/tcl/cad.tcl
+trinfo res
+wavefront res $imagedir/${test_image}
+readobj o $imagedir/${test_image}.obj
+
+# binary format
+set test_image_bbrep ${test_image}_bbrep
+binsave o $imagedir/${test_image_bbrep}.bbrep
+binrestore $imagedir/${test_image_bbrep}.bbrep b1
+vclear
+vclose ALL
+vinit v1/v1
+vbottom
+vdisplay -dispMode 1 b1
+vfit
+vrenderparams -shadingModel phong
+checkview -screenshot -3d -path ${imagedir}/${test_image_bbrep}.png
diff --git a/tests/bugs/moddata_3/bug31136_2 b/tests/bugs/moddata_3/bug31136_2
new file mode 100644 (file)
index 0000000..23c834a
--- /dev/null
@@ -0,0 +1,24 @@
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload MODELING XDE OCAF VISUALIZATION
+source $env(CSF_OCCTSamplesPath)/tcl/cad.tcl
+trinfo res
+wavefront res $imagedir/${test_image}
+readobj o $imagedir/${test_image}.obj
+
+# ASCII format
+set test_image_brep ${test_image}_brep
+save o $imagedir/${test_image_brep}.brep
+restore $imagedir/${test_image_brep}.brep b2
+vclear
+vclose ALL
+vinit v1/v1
+vbottom
+vdisplay -dispMode 1 b2
+vfit
+vrenderparams -shadingModel phong
+checkview -screenshot -3d -path ${imagedir}/${test_image_brep}.png
+
diff --git a/tests/bugs/moddata_3/bug31136_3 b/tests/bugs/moddata_3/bug31136_3
new file mode 100644 (file)
index 0000000..3d5538a
--- /dev/null
@@ -0,0 +1,27 @@
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload MODELING XDE OCAF VISUALIZATION
+source $env(CSF_OCCTSamplesPath)/tcl/cad.tcl
+trinfo res
+wavefront res $imagedir/${test_image}
+readobj o $imagedir/${test_image}.obj
+
+# XBF format
+set test_image_XBF ${test_image}_XBF
+XNewDoc D1
+XAddShape D1 o
+XSave D1 $imagedir/${test_image_XBF}.xbf
+Close D1
+XOpen $imagedir/${test_image_XBF}.xbf D2
+vclear
+vclose ALL
+vinit v1/v1
+vbottom
+XDisplay -dispMode 1 D2
+Close D2
+vfit
+vrenderparams -shadingModel phong
+checkview -screenshot -3d -path ${imagedir}/${test_image_XBF}.png