0031918: Application Framework - New binary format for fast reading part of OCAF...
authormpv <mpv@opencascade.com>
Thu, 24 Jun 2021 14:26:52 +0000 (17:26 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 9 Jul 2021 16:13:59 +0000 (19:13 +0300)
Implementation of new format for quick reading and writing parts of the documents (sub-set of labels and sub-set of attributes). It consists in writing shapes and all their contents right in the TNaming_NamedShape attribute placement and skipping the shape section. New format 12 for Binary file types is assigned to this version.

Added PCDM_ReaderFilter class that could be used in Open methods of TDocStd_Application. If it is defined, it allows to read:
- into already opened document in append mode AppendMode_Protect (do not overwrite existing attributes) or AppendMode_Overwrite
- only specified sub-trees of the document using AddPath (const TCollection_AsciiString& theEntryToRead)
- only specified attributes using AddRead (const TCollection_AsciiString& theRead) where theRead could be "TDataStd_Name", for example
- to skip specified attributes read using AddSkipped (const TCollection_AsciiString& theSkipped) where theSkipped could be "TDF_Reference", for example

The current limitations:
- only in Bin format
- if shapes have in the document shared topology, loaded in "append" mode in different "load" operations, they will have no shared topology anymore

Modifications:
BinLDrivers and BinDrivers packages - modifications related to the quick part tree format flag usage, skipping shape section writing and adding labels sizes into the document to be able to pass labels during the reading quickly.
BinObjMgt_Persistent and BinObjMgt_Position - to add possibility to write directly into the stream some data just after the attribute. Before this record a data-size is recorded.
BinMXCAFDoc package modifications to write BinMXCAFDoc_LocationDriver location in the same way as shapes write location data right after the attribute (empty) data in this new format.
BinTools package: creation of ShapeReader and ShapeWriter classes with same root class ShapeSetBase with ShapeSet class. These classes allows to write/read shapes directly to the stream. If some object is already in the stream, write a reference - relative position of the duplicated object. The old format of documents is still supported by Bin_ToolsShapeSet class.
PCDM_ReaderFilter - Allows the user to create a reading filter. It contains algorithm to browse labels tree quickly, without usage of referencing by entry-strings.
TDocStd, CDF and some other packages are changed for supporting reading filters API and options.

Tests, documentation and upgrade information are also added for both issues: 31839 and 31918 related to this commit.

74 files changed:
dox/upgrade/upgrade.md
dox/user_guides/ocaf/ocaf.md
src/BinDrivers/BinDrivers_DocumentRetrievalDriver.cxx
src/BinDrivers/BinDrivers_DocumentRetrievalDriver.hxx
src/BinDrivers/BinDrivers_DocumentStorageDriver.cxx
src/BinDrivers/BinDrivers_DocumentStorageDriver.hxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx
src/BinLDrivers/BinLDrivers_DocumentSection.cxx
src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentStorageDriver.hxx
src/BinMNaming/BinMNaming_NamedShapeDriver.cxx
src/BinMNaming/BinMNaming_NamedShapeDriver.hxx
src/BinMNaming/BinMNaming_NamedShapeDriver.lxx
src/BinMXCAFDoc/BinMXCAFDoc.cxx
src/BinMXCAFDoc/BinMXCAFDoc_LocationDriver.cxx
src/BinMXCAFDoc/BinMXCAFDoc_LocationDriver.hxx
src/BinMXCAFDoc/BinMXCAFDoc_LocationDriver.lxx [deleted file]
src/BinMXCAFDoc/FILES
src/BinObjMgt/BinObjMgt_Persistent.cxx
src/BinObjMgt/BinObjMgt_Persistent.hxx
src/BinObjMgt/BinObjMgt_Persistent.lxx
src/BinObjMgt/BinObjMgt_Position.cxx [new file with mode: 0644]
src/BinObjMgt/BinObjMgt_Position.hxx [new file with mode: 0644]
src/BinObjMgt/FILES
src/BinTools/BinTools.cxx
src/BinTools/BinTools.hxx
src/BinTools/BinTools_Curve2dSet.cxx
src/BinTools/BinTools_Curve2dSet.hxx
src/BinTools/BinTools_CurveSet.cxx
src/BinTools/BinTools_CurveSet.hxx
src/BinTools/BinTools_IStream.cxx [new file with mode: 0644]
src/BinTools/BinTools_IStream.hxx [new file with mode: 0644]
src/BinTools/BinTools_LocationSet.cxx
src/BinTools/BinTools_LocationSet.hxx
src/BinTools/BinTools_OStream.cxx [new file with mode: 0644]
src/BinTools/BinTools_OStream.hxx [new file with mode: 0644]
src/BinTools/BinTools_ObjectType.hxx [new file with mode: 0644]
src/BinTools/BinTools_ShapeReader.cxx [new file with mode: 0644]
src/BinTools/BinTools_ShapeReader.hxx [new file with mode: 0644]
src/BinTools/BinTools_ShapeSet.cxx
src/BinTools/BinTools_ShapeSet.hxx
src/BinTools/BinTools_ShapeSetBase.cxx [new file with mode: 0644]
src/BinTools/BinTools_ShapeSetBase.hxx [new file with mode: 0644]
src/BinTools/BinTools_ShapeWriter.cxx [new file with mode: 0644]
src/BinTools/BinTools_ShapeWriter.hxx [new file with mode: 0644]
src/BinTools/BinTools_SurfaceSet.cxx
src/BinTools/BinTools_SurfaceSet.hxx
src/BinTools/FILES
src/CDF/CDF_Application.cxx
src/CDF/CDF_Application.hxx
src/CDM/CDM_Application.hxx
src/DDocStd/DDocStd_ApplicationCommands.cxx
src/PCDM/FILES
src/PCDM/PCDM_ReadWriter.cxx
src/PCDM/PCDM_Reader.hxx
src/PCDM/PCDM_ReaderFilter.cxx [new file with mode: 0644]
src/PCDM/PCDM_ReaderFilter.hxx [new file with mode: 0644]
src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.cxx
src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.hxx
src/TDocStd/TDocStd_Application.cxx
src/TDocStd/TDocStd_Application.hxx
src/TDocStd/TDocStd_Document.cxx
src/TDocStd/TDocStd_FormatVersion.hxx
src/XDEDRAW/XDEDRAW.cxx
src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx
src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.hxx
tests/bugs/caf/bug31839_1 [new file with mode: 0644]
tests/bugs/caf/bug31839_2 [new file with mode: 0644]
tests/bugs/caf/bug31918_1 [new file with mode: 0644]
tests/bugs/caf/bug31918_2 [new file with mode: 0644]
tests/caf/progress/A1
tests/caf/progress/B1
tests/caf/progress/C1

index 115b364..b5f57b5 100644 (file)
@@ -2211,6 +2211,15 @@ BRep and Binary BRep Shape formats (only in case of triangulation-only Faces, wi
 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_changesBinaryFormat Changes in storage of binary document format
+
+All kinds of binary document formats since the new version 12 saved with support of partial reading (sub-set of labels and sub-set of attributes).
+For that the shapes data structures are stored with the related NamedShape attributes in the file, not in the particular section in the start of the document.
+Also, size allocated for each label is stored in the file. This allows to skip big parts of document in partial reading mode if needed.
+
+As a result, the new binary files become some smaller, but default reading and writing of documents may take some more time (depenging on the environment), up to 15 percents slower in the worse cases.
+Backward compatibility (loading of old documents in the newer version) is still fully supported, as well as writing the older versions of the document.
+
 @subsection upgrade_occt760_poly Changes in *Poly* package and *Poly_Triangulation* class
 
 *Poly_Triangulation* does no more provide access to internal array structures: methods Nodes(), ChangeNode(), Triangles(), ChangeTriangle(), UVNodes(), ChangeUVNode(), Normals() have been removed.
index 7a5b610..69fc905 100644 (file)
@@ -745,6 +745,32 @@ To open the document from a file where it has been previously saved, you can use
 app->Open("/tmp/example.caf", doc); 
 ~~~~
 
+For binary formats only the part of the stored document can be loaded. For that the *PCDM_ReadingFilter* class could be used. It is possible to define which attributes must be loaded or omitted,
+or to define one or several entries for sub-tree that must be loaded only. The following example opens document *doc*, but reads only "0:1:2" label and its sub-labels and only *TDataStd_Name* attributes on them.
+
+~~~~{.cpp}
+Handle(PCDM_ReaderFilter) filter = new PCDM_ReaderFilter("0:1:2");
+filter->AddRead("TDataStd_Name");
+app->Open("example.cbf", doc, filter); 
+~~~~
+
+Also, using filters, part of the document can be appended into the already loaded document from the same file. For an example, to read into the previously opened *doc* all attributes, except *TDataStd_Name* and *TDataStd_Integer*:
+
+~~~~{.cpp}
+Handle(PCDM_ReaderFilter) filter2 = new PCDM_ReaderFilter(PCDM_ReaderFilter::AppendMode_Protect);
+filter2->AddSkipped("TDataStd_Name");
+filter2->AddSkipped("TDataStd_Integer");
+app->Open("example.cbf", doc, filter2); 
+~~~~
+
+*PCDM_ReaderFilter::AppendMode_Protect* means that if the loading algorithm finds already existing attribute in the document, it will not be overwritten by attibute from the loading file. If it is needed to
+substitute the existing attributes, the reading mode *PCDM_ReaderFilter::AppendMode_Overwrite* must be used instead.
+
+*AddRead* and *AddSkipped* methods for attributes should not be used in one filter. If it is so, *AddSkipped* attributes are ignored during the read.
+
+Appending to the document content of already loaded file may be performed several times with the same or different parts of the document loaded. For that the filter reading mode must be *PCDM_ReaderFilter::AppendMode_Protect*
+or *PCDM_ReaderFilter::AppendMode_Overwrite*, which enables the "append" mode of document open. If the filter is empty or null or skipped in arguments, it opens document with "append" mode disabled and any loading limitations.
+
 @subsubsection occt_ocaf_4_3_5 Cutting, copying and pasting inside a document
 
 To cut, copy and paste inside a document, use the class *TDF_CopyLabel*.
index bc36e96..8ddd4f3 100644 (file)
@@ -26,6 +26,7 @@
 #include <Standard_Failure.hxx>
 #include <Standard_IStream.hxx>
 #include <Standard_Type.hxx>
+#include <Standard_NotImplemented.hxx>
 #include <TCollection_ExtendedString.hxx>
 #include <TNaming_NamedShape.hxx>
 
@@ -64,7 +65,7 @@ void BinDrivers_DocumentRetrievalDriver::ReadShapeSection
 {
   // Read Shapes
   Handle(BinMDF_ADriver) aDriver;
-  if (myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape),aDriver))
+  if (myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape),aDriver))
   {
     try {
       OCC_CATCH_SIGNALS
@@ -75,7 +76,7 @@ void BinDrivers_DocumentRetrievalDriver::ReadShapeSection
     catch(Standard_Failure const& anException) {
       const TCollection_ExtendedString aMethStr
         ("BinDrivers_DocumentRetrievalDriver: ");
-      myMsgDriver ->Send(aMethStr + "error of Shape Section " +
+      myMsgDriver->Send(aMethStr + "error of Shape Section " +
         anException.GetMessageString(), Message_Fail);
     }
   }
@@ -85,7 +86,7 @@ void BinDrivers_DocumentRetrievalDriver::ReadShapeSection
 //function : CheckShapeSection
 //purpose  : 
 //=======================================================================
-void BinDrivers_DocumentRetrievalDriver::CheckShapeSection(
+void BinDrivers_DocumentRetrievalDriver::CheckShapeSection (
                               const Storage_Position& /*ShapeSectionPos*/,
                               Standard_IStream& /*IS*/)
 {}
@@ -98,13 +99,32 @@ void BinDrivers_DocumentRetrievalDriver::Clear()
 {
   // Clear NamedShape driver
   Handle(BinMDF_ADriver) aDriver;
-  if (myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver))
+  if (myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver))
   {
     Handle(BinMNaming_NamedShapeDriver) aNamedShapeDriver =
-      Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+      Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
     aNamedShapeDriver->Clear();
   }
   BinLDrivers_DocumentRetrievalDriver::Clear();
 }
 
+//=======================================================================
+//function : EnableQuickPartReading
+//purpose  : 
+//=======================================================================
+void BinDrivers_DocumentRetrievalDriver::EnableQuickPartReading (
+  const Handle(Message_Messenger)& theMessageDriver, Standard_Boolean theValue)
+{
+  if (myDrivers.IsNull())
+    myDrivers = AttributeDrivers (theMessageDriver);
+  if (myDrivers.IsNull())
+    return;
 
+  Handle(BinMDF_ADriver) aDriver;
+  myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver);
+  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
+  if (aShapesDriver.IsNull())
+    throw Standard_NotImplemented ("Internal Error - TNaming_NamedShape is not found!");
+
+  aShapesDriver->EnableQuickPart (theValue);
+}
index f7c51d7..163a092 100644 (file)
@@ -57,6 +57,10 @@ public:
   //! Clears the NamedShape driver
   Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
 
+  //! Enables reading in the quick part access mode.
+  Standard_EXPORT virtual void EnableQuickPartReading
+    (const Handle(Message_Messenger)& theMessageDriver, Standard_Boolean theValue) Standard_OVERRIDE;
+
 
   DEFINE_STANDARD_RTTIEXT(BinDrivers_DocumentRetrievalDriver,BinLDrivers_DocumentRetrievalDriver)
 
index 492ef6d..410b70e 100644 (file)
@@ -33,7 +33,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BinDrivers_DocumentStorageDriver,BinLDrivers_Document
 //function : BinDrivers_DocumentStorageDriver
 //purpose  : Constructor
 //=======================================================================
-BinDrivers_DocumentStorageDriver::BinDrivers_DocumentStorageDriver ()
+BinDrivers_DocumentStorageDriver::BinDrivers_DocumentStorageDriver()
 {
 }
 
@@ -61,7 +61,7 @@ Standard_Boolean BinDrivers_DocumentStorageDriver::IsWithTriangles() const
 
   Handle(BinMDF_ADriver) aDriver;
   myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver);
-  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
   return !aShapesDriver.IsNull()
        && aShapesDriver->IsWithTriangles();
 }
@@ -84,15 +84,55 @@ void BinDrivers_DocumentStorageDriver::SetWithTriangles (const Handle(Message_Me
 
   Handle(BinMDF_ADriver) aDriver;
   myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver);
-  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
   if (aShapesDriver.IsNull())
   {
-    throw Standard_NotImplemented("Internal Error - TNaming_NamedShape is not found!");
+    throw Standard_NotImplemented ("Internal Error - TNaming_NamedShape is not found!");
   }
 
   aShapesDriver->SetWithTriangles (theWithTriangulation);
 }
 
+void BinDrivers_DocumentStorageDriver::EnableQuickPartWriting (const Handle(Message_Messenger)& theMessageDriver,
+                                                               const Standard_Boolean theValue)
+{
+  if (myDrivers.IsNull())
+  {
+    myDrivers = AttributeDrivers (theMessageDriver);
+  }
+  if (myDrivers.IsNull())
+  {
+    return;
+  }
+
+  Handle(BinMDF_ADriver) aDriver;
+  myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver);
+  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
+  if (aShapesDriver.IsNull())
+  {
+    throw Standard_NotImplemented ("Internal Error - TNaming_NamedShape is not found!");
+  }
+
+  aShapesDriver->EnableQuickPart (theValue);
+}
+
+//=======================================================================
+//function : Clear
+//purpose  : 
+//=======================================================================
+void BinDrivers_DocumentStorageDriver::Clear()
+{
+  // Clear NamedShape driver
+  Handle(BinMDF_ADriver) aDriver;
+  if (myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver))
+  {
+    Handle(BinMNaming_NamedShapeDriver) aNamedShapeDriver =
+      Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
+    aNamedShapeDriver->Clear();
+  }
+  BinLDrivers_DocumentStorageDriver::Clear();
+}
+
 //=======================================================================
 //function : IsWithNormals
 //purpose  :
@@ -105,8 +145,8 @@ Standard_Boolean BinDrivers_DocumentStorageDriver::IsWithNormals() const
   }
 
   Handle(BinMDF_ADriver) aDriver;
-  myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver);
-  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+  myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver);
+  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
   return !aShapesDriver.IsNull()
     && aShapesDriver->IsWithNormals();
 }
@@ -115,12 +155,12 @@ Standard_Boolean BinDrivers_DocumentStorageDriver::IsWithNormals() const
 //function : SetWithNormals
 //purpose  :
 //=======================================================================
-void BinDrivers_DocumentStorageDriver::SetWithNormals(const Handle(Message_Messenger)& theMessageDriver,
+void BinDrivers_DocumentStorageDriver::SetWithNormals (const Handle(Message_Messenger)& theMessageDriver,
   const Standard_Boolean theWithNormals)
 {
   if (myDrivers.IsNull())
   {
-    myDrivers = AttributeDrivers(theMessageDriver);
+    myDrivers = AttributeDrivers (theMessageDriver);
   }
   if (myDrivers.IsNull())
   {
@@ -128,14 +168,14 @@ void BinDrivers_DocumentStorageDriver::SetWithNormals(const Handle(Message_Messe
   }
 
   Handle(BinMDF_ADriver) aDriver;
-  myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver);
-  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+  myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver);
+  Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
   if (aShapesDriver.IsNull())
   {
-    throw Standard_NotImplemented("Internal Error - TNaming_NamedShape is not found!");
+    throw Standard_NotImplemented ("Internal Error - TNaming_NamedShape is not found!");
   }
 
-  aShapesDriver->SetWithNormals(theWithNormals);
+  aShapesDriver->SetWithNormals (theWithNormals);
 }
 
 //=======================================================================
@@ -151,7 +191,7 @@ void BinDrivers_DocumentStorageDriver::WriteShapeSection
   const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp();
   
   Handle(BinMDF_ADriver) aDriver;
-  if (myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver))
+  if (myDrivers->GetDriver (STANDARD_TYPE(TNaming_NamedShape), aDriver))
   {
     try { 
       OCC_CATCH_SIGNALS
@@ -159,7 +199,7 @@ void BinDrivers_DocumentStorageDriver::WriteShapeSection
         Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
       aNamedShapeDriver->WriteShapeSection (theOS, theDocVer, theRange);
     }
-    catch(Standard_Failure const& anException) {
+    catch (Standard_Failure const& anException) {
       TCollection_ExtendedString anErrorStr ("BinDrivers_DocumentStorageDriver, Shape Section :");
       myMsgDriver->Send (anErrorStr  + anException.GetMessageString(), Message_Fail);
     }
index d02fa87..457ba74 100644 (file)
@@ -61,6 +61,13 @@ public:
   Standard_EXPORT void SetWithNormals(const Handle(Message_Messenger)& theMessageDriver,
                                          const Standard_Boolean theWithTriangulation);
 
+  //! Enables writing in the quick part access mode.
+  Standard_EXPORT void EnableQuickPartWriting(const Handle(Message_Messenger)& theMessageDriver,
+                                              const Standard_Boolean theValue) Standard_OVERRIDE;
+
+  //! Clears the NamedShape driver
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+
   DEFINE_STANDARD_RTTIEXT(BinDrivers_DocumentStorageDriver,BinLDrivers_DocumentStorageDriver)
 
 };
index 429709c..e50c315 100644 (file)
 #include <TDF_Attribute.hxx>
 #include <TDF_Data.hxx>
 #include <TDF_Label.hxx>
+#include <TDF_Tool.hxx>
 #include <TDocStd_Document.hxx>
 #include <TDocStd_FormatVersion.hxx>
 #include <TDocStd_Owner.hxx>
 #include <Message_ProgressScope.hxx>
+#include <PCDM_ReaderFilter.hxx>
 
 
 IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentRetrievalDriver,PCDM_RetrievalDriver)
 
 #define SHAPESECTION_POS "SHAPE_SECTION_POS:"
+#define ENDSECTION_POS ":"
 #define SIZEOFSHAPELABEL  18
 
 #define DATATYPE_MIGRATION
@@ -71,6 +74,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read
                          (const TCollection_ExtendedString& theFileName,
                           const Handle(CDM_Document)&       theNewDocument,
                           const Handle(CDM_Application)&    theApplication,
+                          const Handle(PCDM_ReaderFilter)&  theFilter,
                           const Message_ProgressRange&      theRange)
 {
   std::ifstream aFileStream;
@@ -81,7 +85,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read
     Handle(Storage_Data) dData;
     TCollection_ExtendedString aFormat = PCDM_ReadWriter::FileFormat (aFileStream, dData);
 
-    Read(aFileStream, dData, theNewDocument, theApplication, theRange);
+    Read (aFileStream, dData, theNewDocument, theApplication, theFilter, theRange);
     if (!theRange.More())
     {
       myReaderStatus = PCDM_RS_UserBreak;
@@ -104,11 +108,12 @@ void BinLDrivers_DocumentRetrievalDriver::Read
 //function : Read
 //purpose  :
 //=======================================================================
-void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&               theIStream,
-                                                const Handle(Storage_Data)&     theStorageData,
-                                                const Handle(CDM_Document)&     theDoc,
-                                                const Handle(CDM_Application)&  theApplication,
-                                                const Message_ProgressRange&    theRange)
+void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&                theIStream,
+                                                const Handle(Storage_Data)&      theStorageData,
+                                                const Handle(CDM_Document)&      theDoc,
+                                                const Handle(CDM_Application)&   theApplication,
+                                                const Handle(PCDM_ReaderFilter)& theFilter,
+                                                const Message_ProgressRange&     theRange)
 {
   myReaderStatus = PCDM_RS_DriverFailure;
   myMsgDriver = theApplication -> MessageDriver();
@@ -176,7 +181,6 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   Standard_Boolean begin = Standard_False;
   Standard_Integer i;
   for (i=1; i <= aUserInfo.Length(); i++) {
-    //const TCollection_AsciiString& aStr = aUserInfo(i);
     TCollection_AsciiString aStr = aUserInfo(i);
     if (aStr == START_TYPES)
       begin = Standard_True;
@@ -221,10 +225,11 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   myRelocTable.SetHeaderData(aHeaderData);
   mySections.Clear();
   myPAtt.Init();
-  Handle(TDF_Data) aData = new TDF_Data();
+  Handle(TDF_Data) aData = (!theFilter.IsNull() && theFilter->IsAppendMode()) ? aDoc->GetData() : new TDF_Data();
   std::streampos aDocumentPos = -1;
 
-  Message_ProgressScope aPS(theRange, "Reading data", 3);
+  Message_ProgressScope aPS (theRange, "Reading data", 3);
+  Standard_Boolean aQuickPart = IsQuickPart (aFileVer);
 
   // 2b. Read the TOC of Sections
   if (aFileVer >= TDocStd_FormatVersion_VERSION_3) {
@@ -232,7 +237,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
     do {
       BinLDrivers_DocumentSection::ReadTOC (aSection, theIStream, aFileVer);
       mySections.Append(aSection);
-    } while(!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS) && !theIStream.eof());
+    } while (!aSection.Name().IsEqual (aQuickPart ? ENDSECTION_POS : SHAPESECTION_POS) && !theIStream.eof());
 
     if (theIStream.eof()) {
       // There is no shape section in the file.
@@ -248,7 +253,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
       BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue();
       if (aCurSection.IsPostRead() == Standard_False) {
         theIStream.seekg ((std::streampos) aCurSection.Offset());
-        if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS))
+        if (aCurSection.Name().IsEqual (SHAPESECTION_POS))
         {
           ReadShapeSection (aCurSection, theIStream, false, aPS.Next());
           if (!aPS.More())
@@ -257,7 +262,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
             return;
           }
         }
-        else
+        else if (!aCurSection.Name().IsEqual (ENDSECTION_POS))
           ReadSection (aCurSection, theDoc, theIStream);
       }
     }
@@ -313,8 +318,14 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   Standard_Integer aTag;
   theIStream.read ((char*)&aTag, sizeof(Standard_Integer));
 
+  if (aQuickPart)
+    myPAtt.SetIStream (theIStream); // for reading shapes data from the stream directly
+  EnableQuickPartReading (myMsgDriver, aQuickPart);
+
   // read sub-tree of the root label
-  Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), aPS.Next());
+  if (!theFilter.IsNull())
+    theFilter->StartIteration();
+  Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), theFilter, aQuickPart, aPS.Next());
   if (!aPS.More()) 
   {
     myReaderStatus = PCDM_RS_UserBreak;
@@ -331,9 +342,12 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
     
   if (nbRead > 0) {
     // attach data to the document
-    aDoc->SetData (aData);
-    TDocStd_Owner::SetDocument (aData, aDoc);
-    aDoc->SetComments(aHeaderData->Comments());
+    if (theFilter.IsNull() || !theFilter->IsAppendMode())
+    {
+      aDoc->SetData(aData);
+      TDocStd_Owner::SetDocument(aData, aDoc);
+      aDoc->SetComments(aHeaderData->Comments());
+    }
     myReaderStatus = PCDM_RS_OK;
   }
 
@@ -356,33 +370,68 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
 //=======================================================================
 
 Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
-                         (Standard_IStream& theIS,
-                          const TDF_Label&  theLabel,
-                          const Message_ProgressRange& theRange)
+(Standard_IStream& theIS,
+  const TDF_Label& theLabel,
+  const Handle(PCDM_ReaderFilter)& theFilter,
+  const Standard_Boolean& theQuickPart,
+  const Message_ProgressRange& theRange)
 {
   Standard_Integer nbRead = 0;
   TCollection_ExtendedString aMethStr
-    ("BinLDrivers_DocumentRetrievalDriver: ");
+  ("BinLDrivers_DocumentRetrievalDriver: ");
 
   Message_ProgressScope aPS(theRange, "Reading sub tree", 2, true);
 
+  bool aSkipAttrs = Standard_False;
+  if (!theFilter.IsNull() && theFilter->IsPartTree())
+    aSkipAttrs = !theFilter->IsPassed();
+
+  if (theQuickPart)
+  {
+    uint64_t aLabelSize = 0;
+    theIS.read((char*)&aLabelSize, sizeof(uint64_t));
+#if DO_INVERSE
+    aLabelSize = InverseUint64(aLabelSize);
+#endif
+    // no one sub-label is needed, so, skip everything
+    if (aSkipAttrs && !theFilter->IsSubPassed())
+    {
+      aLabelSize -= sizeof (uint64_t);
+      theIS.seekg (aLabelSize, std::ios_base::cur);
+      if (!theFilter.IsNull())
+        theFilter->Up();
+      return 0;
+    }
+  }
+
   // Read attributes:
-  theIS >> myPAtt;
-  while (theIS && myPAtt.TypeId() > 0 &&             // not an end marker ?
-         myPAtt.Id() > 0 &&                          // not a garbage ?
-         !theIS.eof())
+  for (theIS >> myPAtt;
+    theIS && myPAtt.TypeId() > 0 &&             // not an end marker ?
+    myPAtt.Id() > 0 &&                          // not a garbage ?
+    !theIS.eof();
+    theIS >> myPAtt)
   {
     if (!aPS.More())
     {
       myReaderStatus = PCDM_RS_UserBreak;
       return -1;
     }
-        
+    if (aSkipAttrs)
+    {
+      if (myPAtt.IsDirect()) // skip direct written stream
+      {
+        uint64_t aStreamSize = 0;
+        theIS.read ((char*)&aStreamSize, sizeof (uint64_t));
+        aStreamSize -= sizeof (uint64_t); // size is already passed, so, reduce it by size
+        theIS.seekg (aStreamSize, std::ios_base::cur);
+      }
+      continue;
+    }
+
     // get a driver according to TypeId
-    Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (myPAtt.TypeId());
+    Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver(myPAtt.TypeId());
     if (!aDriver.IsNull()) {
       // create transient attribute
-      nbRead++;
       Standard_Integer anID = myPAtt.Id();
       Handle(TDF_Attribute) tAtt;
       Standard_Boolean isBound = myRelocTable.IsBound(anID);
@@ -391,11 +440,30 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
       else
         tAtt = aDriver->NewEmpty();
 
+      if (!theFilter.IsNull() && !theFilter->IsPassed (tAtt->DynamicType())) {
+        if (myPAtt.IsDirect()) // skip direct written stream
+        {
+          uint64_t aStreamSize = 0;
+          theIS.read ((char*)&aStreamSize, sizeof (uint64_t));
+          aStreamSize -= sizeof (uint64_t); // size is already passed, so, reduce it by size
+          theIS.seekg (aStreamSize, std::ios_base::cur);
+        }
+        continue;
+      }
+      nbRead++;
+
       if (tAtt->Label().IsNull())
       {
+        if (!theFilter.IsNull() && theFilter->Mode() != PCDM_ReaderFilter::AppendMode_Forbid && theLabel.IsAttribute(tAtt->ID()))
+        {
+          if (theFilter->Mode() == PCDM_ReaderFilter::AppendMode_Protect)
+            continue; // do not overwrite the existing attribute
+          if (theFilter->Mode() == PCDM_ReaderFilter::AppendMode_Overwrite)
+            theLabel.ForgetAttribute(tAtt->ID()); // forget old attribute to write a new one
+        }
         try
         {
-          theLabel.AddAttribute (tAtt);
+          theLabel.AddAttribute(tAtt);
         }
         catch (const Standard_DomainError&)
         {
@@ -404,34 +472,32 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
           // present  on the same label; the reason is that actual GUID will be read later.
           // To avoid this, set invalid (null) GUID to the newly added attribute (see #29669)
           static const Standard_GUID fbidGuid;
-          tAtt->SetID (fbidGuid);
-          theLabel.AddAttribute (tAtt);
+          tAtt->SetID(fbidGuid);
+          theLabel.AddAttribute(tAtt);
         }
       }
       else
-        myMsgDriver->Send (aMethStr +
-                     "warning: attempt to attach attribute " +
-                     aDriver->TypeName() + " to a second label", Message_Warning);
+        myMsgDriver->Send(aMethStr +
+          "warning: attempt to attach attribute " +
+          aDriver->TypeName() + " to a second label", Message_Warning);
 
-      Standard_Boolean ok = aDriver->Paste (myPAtt, tAtt, myRelocTable);
+      Standard_Boolean ok = aDriver->Paste(myPAtt, tAtt, myRelocTable);
       if (!ok) {
         // error converting persistent to transient
-        myMsgDriver->Send (aMethStr + "warning: failure reading attribute " +
-                      aDriver->TypeName(), Message_Warning);
+        myMsgDriver->Send(aMethStr + "warning: failure reading attribute " +
+          aDriver->TypeName(), Message_Warning);
       }
       else if (!isBound)
-        myRelocTable.Bind (anID, tAtt);
+        myRelocTable.Bind(anID, tAtt);
     }
     else if (!myMapUnsupported.Contains(myPAtt.TypeId()))
-      myMsgDriver->Send (aMethStr + "warning: type ID not registered in header: "
-                    + myPAtt.TypeId(), Message_Warning);
+      myMsgDriver->Send(aMethStr + "warning: type ID not registered in header: "
+        + myPAtt.TypeId(), Message_Warning);
 
-    // read next attribute
-    theIS >> myPAtt;
   }
   if (!theIS || myPAtt.TypeId() != BinLDrivers_ENDATTRLIST) {
     // unexpected EOF or garbage data
-    myMsgDriver->Send (aMethStr + "error: unexpected EOF or garbage data", Message_Fail);
+    myMsgDriver->Send(aMethStr + "error: unexpected EOF or garbage data", Message_Fail);
     myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
     return -1;
   }
@@ -439,14 +505,14 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
   // Read children:
   // read the tag of a child label
   Standard_Integer aTag = BinLDrivers_ENDLABEL;
-  theIS.read ((char*) &aTag, sizeof(Standard_Integer));
+  theIS.read((char*)&aTag, sizeof(Standard_Integer));
 #ifdef DO_INVERSE
-  aTag = InverseInt (aTag);
+  aTag = InverseInt(aTag);
 #endif
-  
+
   while (theIS && aTag >= 0 && !theIS.eof()) { // not an end marker ?
     // create sub-label
-    TDF_Label aLab = theLabel.FindChild (aTag, Standard_True);
+    TDF_Label aLab = theLabel.FindChild(aTag, Standard_True);
     if (!aPS.More())
     {
       myReaderStatus = PCDM_RS_UserBreak;
@@ -455,25 +521,29 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
 
 
     // read sub-tree
-    Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, aPS.Next());
+    if (!theFilter.IsNull())
+      theFilter->Down (aTag);
+    Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, theFilter, theQuickPart, aPS.Next());
     // check for error
     if (nbSubRead == -1)
       return -1;
     nbRead += nbSubRead;
 
     // read the tag of the next child
-    theIS.read ((char*) &aTag, sizeof(Standard_Integer));
+    theIS.read((char*)&aTag, sizeof(Standard_Integer));
 #ifdef DO_INVERSE
-    aTag = InverseInt (aTag);
+    aTag = InverseInt(aTag);
 #endif
   }
 
   if (aTag != BinLDrivers_ENDLABEL) {
     // invalid end label marker
-    myMsgDriver->Send (aMethStr + "error: invalid end label marker", Message_Fail);
+    myMsgDriver->Send(aMethStr + "error: invalid end label marker", Message_Fail);
     myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
     return -1;
   }
+  if (!theFilter.IsNull())
+    theFilter->Up();
 
   return nbRead;
 }
@@ -524,13 +594,12 @@ void BinLDrivers_DocumentRetrievalDriver::ReadShapeSection
 //function : CheckShapeSection
 //purpose  : 
 //=======================================================================
-void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection(
-                                          const Storage_Position& ShapeSectionPos, 
-                                          Standard_IStream& IS)
+void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection
+  (const Storage_Position& ShapeSectionPos, Standard_IStream& IS)
 {
   if (!IS.eof())
   {
-    const std::streamoff endPos = IS.rdbuf()->pubseekoff(0L, std::ios_base::end, std::ios_base::in);
+    const std::streamoff endPos = IS.rdbuf()->pubseekoff (0L, std::ios_base::end, std::ios_base::in);
 #ifdef OCCT_DEBUG
     std::cout << "endPos = " << endPos <<std::endl;
 #endif
@@ -556,9 +625,8 @@ void BinLDrivers_DocumentRetrievalDriver::Clear()
 //function : CheckDocumentVersion
 //purpose  : 
 //=======================================================================
-Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion(
-                                                          const Standard_Integer theFileVersion,
-                                                          const Standard_Integer theCurVersion)
+Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion
+  (const Standard_Integer theFileVersion, const Standard_Integer theCurVersion)
 {
   if (theFileVersion < TDocStd_FormatVersion_LOWER || theFileVersion > theCurVersion) {
     // file was written with another version
@@ -566,3 +634,12 @@ Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion(
   }
   return Standard_True;
 }
+
+//=======================================================================
+//function : IsQuickPart
+//purpose  : 
+//=======================================================================
+Standard_Boolean BinLDrivers_DocumentRetrievalDriver::IsQuickPart (const Standard_Integer theFileVer)
+{
+  return theFileVer >= TDocStd_FormatVersion_VERSION_12;
+}
index f613ff7..33818f8 100644 (file)
@@ -59,12 +59,14 @@ public:
   Standard_EXPORT virtual void Read (const TCollection_ExtendedString& theFileName,
                                      const Handle(CDM_Document)& theNewDocument, 
                                      const Handle(CDM_Application)& theApplication, 
+                                     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
                                      const Message_ProgressRange& theProgress = Message_ProgressRange()) Standard_OVERRIDE;
 
   Standard_EXPORT virtual void Read (Standard_IStream&               theIStream,
                                      const Handle(Storage_Data)&     theStorageData,
                                      const Handle(CDM_Document)&     theDoc,
                                      const Handle(CDM_Application)&  theApplication,
+                                     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
                                      const Message_ProgressRange& theProgress = Message_ProgressRange()) Standard_OVERRIDE;
   
   Standard_EXPORT virtual Handle(BinMDF_ADriverTable) AttributeDrivers (const Handle(Message_Messenger)& theMsgDriver);
@@ -81,7 +83,9 @@ protected:
   Standard_EXPORT virtual Standard_Integer ReadSubTree
     (Standard_IStream& theIS, 
      const TDF_Label& theData, 
-        const Message_ProgressRange& theRanges = Message_ProgressRange());
+     const Handle(PCDM_ReaderFilter)& theFilter,
+     const Standard_Boolean& theQuickPart,
+     const Message_ProgressRange& theRanges = Message_ProgressRange());
   
   
   //! define the procedure of reading a section to file.
@@ -92,10 +96,10 @@ protected:
   
   //! define the procedure of reading a shapes section to file.
   Standard_EXPORT virtual void ReadShapeSection
-    (BinLDrivers_DocumentSection& theSection, 
-     Standard_IStream& theIS, 
-     const Standard_Boolean isMess = Standard_False,
-        const Message_ProgressRange& theRange = Message_ProgressRange());
+   (BinLDrivers_DocumentSection& theSection,
+    Standard_IStream& theIS,
+    const Standard_Boolean isMess = Standard_False,
+    const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! checks the shapes section can be correctly retrieved.
   Standard_EXPORT virtual void CheckShapeSection (const Storage_Position& thePos, Standard_IStream& theIS);
@@ -110,6 +114,12 @@ protected:
   //! current or lesser than 2, then return false, else true
   Standard_EXPORT virtual Standard_Boolean CheckDocumentVersion (const Standard_Integer theFileVersion, const Standard_Integer theCurVersion);
 
+  //! Return true if retrieved document allows to read parts quickly.
+  static Standard_Boolean IsQuickPart (const Standard_Integer theFileVer);
+
+  //! Enables reading in the quick part access mode.
+  Standard_EXPORT virtual void EnableQuickPartReading (const Handle(Message_Messenger)& /*theMessageDriver*/, Standard_Boolean /*theValue*/) {}
+
   Handle(BinMDF_ADriverTable) myDrivers;
   BinObjMgt_RRelocationTable myRelocTable;
   Handle(Message_Messenger) myMsgDriver;
index 7810355..3ef3d12 100644 (file)
@@ -228,6 +228,7 @@ void BinLDrivers_DocumentSection::ReadTOC
 #endif
   if (aNameBufferSize > 0) {
     theStream.read ((char *)&aBuf[0], (Standard_Size)aNameBufferSize);
+    aBuf[aNameBufferSize] = '\0';
     theSection.myName = (Standard_CString)&aBuf[0];
 
     uint64_t aValue[3];
index bfe167e..39ad9b0 100644 (file)
@@ -21,6 +21,7 @@
 #include <BinMDF_ADriver.hxx>
 #include <BinMDF_ADriverTable.hxx>
 #include <BinObjMgt_Persistent.hxx>
+#include <BinObjMgt_Position.hxx>
 #include <CDM_Application.hxx>
 #include <CDM_Document.hxx>
 #include <Message_Messenger.hxx>
 IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentStorageDriver,PCDM_StorageDriver)
 
 #define SHAPESECTION_POS (Standard_CString)"SHAPE_SECTION_POS:"
+#define ENDSECTION_POS (Standard_CString)":"
 
 //=======================================================================
 //function : BinLDrivers_DocumentStorageDriver
 //purpose  : Constructor
 //=======================================================================
 
-BinLDrivers_DocumentStorageDriver::BinLDrivers_DocumentStorageDriver ()
+BinLDrivers_DocumentStorageDriver::BinLDrivers_DocumentStorageDriver()
 {
 }
 
@@ -97,9 +99,9 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)&  theD
 {
   myMsgDriver = theDoc->Application()->MessageDriver();
   myMapUnsupported.Clear();
+  mySizesToWrite.Clear();
 
-  Handle(TDocStd_Document) aDoc =
-    Handle(TDocStd_Document)::DownCast(theDoc);
+  Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast (theDoc);
   if (aDoc.IsNull()) {
     SetIsError(Standard_True);
     SetStoreStatus(PCDM_SS_Doc_IsNull);
@@ -129,20 +131,33 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)&  theD
     for (; anIterS.More(); anIterS.Next())
       anIterS.ChangeValue().WriteTOC (theOStream, aDocVer);
 
-    // Shapes Section is the last one, it indicates the end of the table.
-    BinLDrivers_DocumentSection aShapesSection (SHAPESECTION_POS,
-                                                Standard_False);
-    aShapesSection.WriteTOC (theOStream, aDocVer);
+    EnableQuickPartWriting (myMsgDriver, IsQuickPart (aDocVer));
+    BinLDrivers_DocumentSection* aShapesSection = 0;
+    Standard_Boolean aQuickPart = IsQuickPart (aDocVer);
+    if (!aQuickPart)
+    {
+      // Shapes Section is the last one, it indicates the end of the table.
+      aShapesSection = new BinLDrivers_DocumentSection (SHAPESECTION_POS, Standard_False);
+      aShapesSection->WriteTOC (theOStream, aDocVer);
+    }
+    else
+    {
+      // End Section is the last one, it indicates the end of the table.
+      BinLDrivers_DocumentSection anEndSection (ENDSECTION_POS, Standard_False);
+      anEndSection.WriteTOC (theOStream, aDocVer);
+    }
 
 //  3. Write document contents
     // (Storage data to the stream)
     myRelocTable.Clear();
     myPAtt.Init();
+    if (aQuickPart)
+      myPAtt.SetOStream (theOStream); // for writing shapes data into the stream directly
 
     Message_ProgressScope aPS(theRange, "Writing document", 3);
 
 //  Write Doc structure
-    WriteSubTree (aData->Root(), theOStream, aPS.Next()); // Doc is written
+    WriteSubTree (aData->Root(), theOStream, aQuickPart, aPS.Next()); // Doc is written
     if (!aPS.More())
     {
       SetIsError(Standard_True);
@@ -151,12 +166,19 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)&  theD
     }
 
 //  4. Write Shapes section
-    WriteShapeSection (aShapesSection, theOStream, aDocVer, aPS.Next());
+    if (!aQuickPart)
+    {
+      WriteShapeSection (*aShapesSection, theOStream, aDocVer, aPS.Next());
+      delete aShapesSection;
+    }
+    else
+      Clear();
+
     if (!aPS.More())
     {
-       SetIsError(Standard_True);
-       SetStoreStatus(PCDM_SS_UserBreak);
-       return;
+      SetIsError (Standard_True);
+      SetStoreStatus (PCDM_SS_UserBreak);
+      return;
     }
 
     // Write application-defined sections
@@ -167,6 +189,10 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)&  theD
       aSection.Write (theOStream, aSectionOffset, aDocVer);
     }
 
+//  5. Write sizes along the file where it is needed for quick part mode
+    if (aQuickPart)
+      WriteSizes (theOStream);
+
     // End of processing: close structures and check the status
     myPAtt.Destroy();   // free buffer
     myEmptyLabels.Clear();
@@ -211,7 +237,7 @@ void BinLDrivers_DocumentStorageDriver::UnsupportedAttrMsg
 {
 #ifdef OCCT_DEBUG
   TCollection_ExtendedString aMsg
-    ("BinDrivers_DocumentStorageDriver: warning: attribute driver for type ");
+    ("BinLDrivers_DocumentStorageDriver: warning: attribute driver for type ");
 #endif
   if (!myMapUnsupported.Contains(theType)) {
     myMapUnsupported.Add(theType);
@@ -229,6 +255,7 @@ void BinLDrivers_DocumentStorageDriver::UnsupportedAttrMsg
 void BinLDrivers_DocumentStorageDriver::WriteSubTree
                         (const TDF_Label&             theLabel,
                          Standard_OStream&            theOS,
+                         const Standard_Boolean&      theQuickPart,
                          const Message_ProgressRange& theRange)
 {
   // Skip empty labels
@@ -244,6 +271,13 @@ void BinLDrivers_DocumentStorageDriver::WriteSubTree
 #endif
   theOS.write ((char*)&aTag, sizeof(Standard_Integer));
 
+  Handle(BinObjMgt_Position) aPosition;
+  if (theQuickPart)
+  {
+    aPosition = mySizesToWrite.Append (new BinObjMgt_Position (theOS));
+    aPosition->WriteSize (theOS, Standard_True);
+  }
+
   // Write attributes
   TDF_AttributeIterator itAtt (theLabel);
   for ( ; itAtt.More() && theOS && aPS.More(); itAtt.Next()) {
@@ -251,7 +285,7 @@ void BinLDrivers_DocumentStorageDriver::WriteSubTree
     const Handle(Standard_Type)& aType = tAtt->DynamicType();
     // Get type ID and driver
     Handle(BinMDF_ADriver) aDriver;
-    const Standard_Integer aTypeId = myDrivers->GetDriver (aType,aDriver);
+    const Standard_Integer aTypeId = myDrivers->GetDriver (aType, aDriver);
     if (aTypeId > 0) {
       // Add source to relocation table
       const Standard_Integer anId = myRelocTable.Add (tAtt);
@@ -260,6 +294,12 @@ void BinLDrivers_DocumentStorageDriver::WriteSubTree
       myPAtt.SetTypeId (aTypeId);
       myPAtt.SetId (anId);
       aDriver->Paste (tAtt, myPAtt, myRelocTable);
+      if (!myPAtt.StreamStart().IsNull())
+      {
+        Handle(BinObjMgt_Position) anAttrPosition = myPAtt.StreamStart();
+        anAttrPosition->StoreSize (theOS);
+        mySizesToWrite.Append (anAttrPosition);
+      }
 
       // Write data to the stream -->!!!
       theOS << myPAtt;
@@ -297,16 +337,16 @@ void BinLDrivers_DocumentStorageDriver::WriteSubTree
       SetStoreStatus(PCDM_SS_UserBreak);
       return;
     }
-    WriteSubTree (aChildLab, theOS, aPS.Next());
+    WriteSubTree (aChildLab, theOS, theQuickPart, aPS.Next());
   }
-
   // Write the end label marker
   BinLDrivers_Marker anEndLabel = BinLDrivers_ENDLABEL;
 #ifdef DO_INVERSE
-  anEndLabel = (BinLDrivers_Marker) InverseInt (anEndLabel);
+  anEndLabel = (BinLDrivers_Marker)InverseInt (anEndLabel);
 #endif
-  theOS.write ((char*)&anEndLabel, sizeof(anEndLabel));
-
+  theOS.write ((char*)&anEndLabel, sizeof (anEndLabel));
+  if (theQuickPart)
+    aPosition->StoreSize (theOS);
 }
 
 //=======================================================================
@@ -553,3 +593,34 @@ void BinLDrivers_DocumentStorageDriver::WriteShapeSection
   const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp();
   theSection.Write (theOS, aShapesSectionOffset, theDocVer);
 }
+
+//=======================================================================
+//function : IsQuickPart
+//purpose  : Return true if document should be stored in quick mode for partial reading
+//=======================================================================
+Standard_Boolean BinLDrivers_DocumentStorageDriver::IsQuickPart (const Standard_Integer theVersion) const
+{
+  return theVersion >= TDocStd_FormatVersion_VERSION_12;
+}
+
+//=======================================================================
+//function : Clear
+//purpose  : 
+//=======================================================================
+void BinLDrivers_DocumentStorageDriver::Clear()
+{
+  // empty; should be redefined in subclasses
+}
+
+
+//=======================================================================
+//function : WriteSizes
+//purpose  : 
+//=======================================================================
+void BinLDrivers_DocumentStorageDriver::WriteSizes (Standard_OStream& theOS)
+{
+  NCollection_List<Handle(BinObjMgt_Position)>::Iterator anIter (mySizesToWrite);
+  for (; anIter.More() && theOS; anIter.Next())
+    anIter.Value()->WriteSize (theOS);
+  mySizesToWrite.Clear();
+}
index e91d56c..2ba79f2 100644 (file)
@@ -37,6 +37,7 @@ class CDM_Document;
 class TDF_Label;
 class TCollection_AsciiString;
 class BinLDrivers_DocumentSection;
+class BinObjMgt_Position;
 
 
 class BinLDrivers_DocumentStorageDriver;
@@ -67,7 +68,8 @@ public:
   //! Create a section that should be written after the OCAF data
   Standard_EXPORT void AddSection (const TCollection_AsciiString& theName, const Standard_Boolean isPostRead = Standard_True);
 
-
+  //! Return true if document should be stored in quick mode for partial reading
+  Standard_EXPORT Standard_Boolean IsQuickPart (const Standard_Integer theVersion) const;
 
 
   DEFINE_STANDARD_RTTIEXT(BinLDrivers_DocumentStorageDriver,PCDM_StorageDriver)
@@ -77,7 +79,8 @@ protected:
   
   //! Write the tree under <theLabel> to the stream <theOS>
   Standard_EXPORT void WriteSubTree (const TDF_Label& theData,
-                                     Standard_OStream& theOS, 
+                                     Standard_OStream& theOS,
+                                     const Standard_Boolean& theQuickPart,
                                      const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! define the procedure of writing a section to file.
@@ -91,6 +94,13 @@ protected:
                                                   const TDocStd_FormatVersion theDocVer,
                                                   const Message_ProgressRange& theRange = Message_ProgressRange());
 
+  //! Enables writing in the quick part access mode.
+  Standard_EXPORT virtual void EnableQuickPartWriting (
+    const Handle(Message_Messenger)& /*theMessageDriver*/, const Standard_Boolean /*theValue*/) {}
+
+  //! clears the writing-cash data in drivers if any.
+  Standard_EXPORT virtual void Clear();
+
   Handle(BinMDF_ADriverTable) myDrivers;
   BinObjMgt_SRelocationTable myRelocTable;
   Handle(Message_Messenger) myMsgDriver;
@@ -108,13 +118,17 @@ private:
   
   Standard_EXPORT void UnsupportedAttrMsg (const Handle(Standard_Type)& theType);
 
+  //! Writes sizes along the file where it is needed for quick part mode
+  Standard_EXPORT void WriteSizes (Standard_OStream& theOS);
+
   BinObjMgt_Persistent myPAtt;
   TDF_LabelList myEmptyLabels;
   TColStd_MapOfTransient myMapUnsupported;
   TColStd_IndexedMapOfTransient myTypesMap;
   BinLDrivers_VectorOfDocumentSection mySections;
   TCollection_ExtendedString myFileName;
-
+  //! Sizes of labels and some attributes that will be stored in the second pass
+  NCollection_List<Handle(BinObjMgt_Position)> mySizesToWrite;
 };
 
 #endif // _BinLDrivers_DocumentStorageDriver_HeaderFile
index 651facd..2d08ecf 100644 (file)
@@ -18,6 +18,8 @@
 #include <BinObjMgt_Persistent.hxx>
 #include <BinTools_LocationSet.hxx>
 #include <BinTools_ShapeSet.hxx>
+#include <BinTools_ShapeWriter.hxx>
+#include <BinTools_ShapeReader.hxx>
 #include <Message_Messenger.hxx>
 #include <Standard_DomainError.hxx>
 #include <Standard_Type.hxx>
@@ -36,7 +38,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
 
 #define SHAPESET "SHAPE_SECTION"
 //=======================================================================
-static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
+static Standard_Character EvolutionToChar (const TNaming_Evolution theEvol)
 {
   switch(theEvol) {
     case TNaming_PRIMITIVE    : return 'P';
@@ -51,7 +53,7 @@ static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
 }
 
 //=======================================================================
-static TNaming_Evolution EvolutionToEnum(const Standard_Character theEvol)
+static TNaming_Evolution EvolutionToEnum (const Standard_Character theEvol)
 {
   switch(theEvol) {
     case 'P': return TNaming_PRIMITIVE;
@@ -65,7 +67,7 @@ static TNaming_Evolution EvolutionToEnum(const Standard_Character theEvol)
   }
 }
 //=======================================================================
-static Standard_Character OrientationToChar(const TopAbs_Orientation theOrient)
+static Standard_Character OrientationToChar (const TopAbs_Orientation theOrient)
 {
   switch(theOrient) {
     case TopAbs_FORWARD    : return 'F';
@@ -77,7 +79,7 @@ static Standard_Character OrientationToChar(const TopAbs_Orientation theOrient)
   }
 }
 //=======================================================================
-static TopAbs_Orientation CharToOrientation(const Standard_Character  theCharOrient)
+static TopAbs_Orientation CharToOrientation (const Standard_Character  theCharOrient)
 {
   switch(theCharOrient) {
     case 'F':  return TopAbs_FORWARD;
@@ -92,45 +94,45 @@ static TopAbs_Orientation CharToOrientation(const Standard_Character  theCharOri
 //=======================================================================
 static void TranslateTo (const TopoDS_Shape&            theShape,
                          BinObjMgt_Persistent&          theResult,
-                         BinTools_ShapeSet&            theShapeSet)
+                         BinTools_ShapeSet            theShapeSet)
 {
   // Check for empty shape
   if (theShape.IsNull()) {
-    theResult.PutInteger(-1);
-    theResult.PutInteger(-1);
-    theResult.PutInteger(-1);
+    theResult.PutInteger (-1);
+    theResult.PutInteger (-1);
+    theResult.PutInteger (-1);
     return;
   }
   // Add to shape set both TShape and Location contained in <theShape>
-  const Standard_Integer aTShapeID = theShapeSet.Add (theShape);
+  const Standard_Integer aTShapeID = theShapeSet->Add (theShape);
   const Standard_Integer aLocID =
-    theShapeSet.Locations().Index (theShape.Location());
+    theShapeSet->Locations().Index (theShape.Location());
 
   // Fill theResult with shape parameters: TShape ID, Location, Orientation
   theResult << aTShapeID;
   theResult << aLocID;
-  theResult << OrientationToChar(theShape.Orientation());
+  theResult << OrientationToChar (theShape.Orientation());
 }
 //=======================================================================
 static int TranslateFrom  (const BinObjMgt_Persistent&  theSource,
                          TopoDS_Shape&                  theResult,
-                         BinTools_ShapeSet&            theShapeSet)
+                         BinTools_ShapeSet*            theShapeSet)
 {
   Standard_Integer aShapeID, aLocID;
   Standard_Character aCharOrient;
   Standard_Boolean Ok = theSource >> aShapeID; //TShapeID;
   if(!Ok) return 1;
   // Read TShape and Orientation
-  if (aShapeID <= 0 || aShapeID > theShapeSet.NbShapes())
+  if (aShapeID <= 0 || aShapeID > theShapeSet->NbShapes())
     return 1;
   Ok = theSource >> aLocID;
   if(!Ok) return 1;
   Ok = theSource >> aCharOrient;
   if(!Ok) return 1;
-  TopAbs_Orientation anOrient = CharToOrientation(aCharOrient);
+  TopAbs_Orientation anOrient = CharToOrientation (aCharOrient);
 
-  theResult.TShape      (theShapeSet.Shape(aShapeID).TShape());//TShape
-  theResult.Location    (theShapeSet.Locations().Location (aLocID)); //Location
+  theResult.TShape      (theShapeSet->Shape (aShapeID).TShape());//TShape
+  theResult.Location    (theShapeSet->Locations().Location (aLocID)); //Location
   theResult.Orientation (anOrient);//Orientation
   return 0;
 }
@@ -142,7 +144,11 @@ static int TranslateFrom  (const BinObjMgt_Persistent&  theSource,
 
 BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
                         (const Handle(Message_Messenger)& theMsgDriver)
-: BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name())
+     : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()),
+       myShapeSet (NULL),
+       myWithTriangles (Standard_False),
+       myWithNormals  (Standard_False),
+       myIsQuickPart (Standard_False)
 {
 }
 
@@ -166,11 +172,11 @@ Standard_Boolean BinMNaming_NamedShapeDriver::Paste
                                  const Handle(TDF_Attribute)& theTarget,
                                  BinObjMgt_RRelocationTable&  ) const
 {
-  Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast(theTarget);
+  Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast (theTarget);
   Standard_Integer aNbShapes;
   theSource >> aNbShapes;
   TDF_Label aLabel = theTarget->Label ();
-  TNaming_Builder   aBuilder   (aLabel);
+  TNaming_Builder aBuilder (aLabel);
   Standard_Integer aVer;
   Standard_Boolean ok = theSource >> aVer;
   if(!ok) return Standard_False;
@@ -178,10 +184,13 @@ Standard_Boolean BinMNaming_NamedShapeDriver::Paste
   Standard_Character aCharEvol;
   ok = theSource >> aCharEvol;
   if(!ok) return Standard_False;
-  TNaming_Evolution anEvol  = EvolutionToEnum(aCharEvol); //Evolution
-  aTAtt->SetVersion(anEvol);
+  TNaming_Evolution anEvol  = EvolutionToEnum (aCharEvol); //Evolution
+  aTAtt->SetVersion (anEvol);
 
-  BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
+  BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_True);
+  Standard_IStream* aDirectStream = NULL;
+  if (myIsQuickPart) // enables direct reading of shapes from the stream
+    aDirectStream = const_cast<BinObjMgt_Persistent*>(&theSource)->GetIStream();
 
   NCollection_List<TopoDS_Shape> anOldShapes, aNewShapes;
   for (Standard_Integer i = 1; i <= aNbShapes; i++)
@@ -189,10 +198,20 @@ Standard_Boolean BinMNaming_NamedShapeDriver::Paste
     TopoDS_Shape anOldShape, aNewShape;
 
     if (anEvol != TNaming_PRIMITIVE)
-      if (TranslateFrom (theSource, anOldShape, aShapeSet)) return Standard_False;
+    {
+      if (myIsQuickPart)
+        aShapeSet->Read (*aDirectStream, anOldShape);
+      else
+        if (TranslateFrom (theSource, anOldShape, static_cast<BinTools_ShapeSet*>(aShapeSet))) return Standard_False;
+    }
 
     if (anEvol != TNaming_DELETE)
-      if (TranslateFrom (theSource, aNewShape, aShapeSet)) return Standard_False;
+    {
+      if (myIsQuickPart)
+        aShapeSet->Read (*aDirectStream, aNewShape);
+      else
+        if (TranslateFrom (theSource, aNewShape, static_cast<BinTools_ShapeSet*>(aShapeSet))) return Standard_False;
+    }
 
     // Here we add shapes in reverse order because TNaming_Builder also adds them in reverse order.
     anOldShapes.Prepend (anOldShape);
@@ -246,24 +265,38 @@ void BinMNaming_NamedShapeDriver::Paste (const Handle(TDF_Attribute)& theSource,
   for (TNaming_Iterator SItr (aSAtt); SItr.More (); SItr.Next ()) NbShapes++;
   //--------------------------------------------------------------
 
-  BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
+  BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_False);
   TNaming_Evolution anEvol = aSAtt->Evolution();
   
   theTarget << NbShapes;
   theTarget << aSAtt->Version();
-  theTarget << EvolutionToChar(anEvol);
+  theTarget << EvolutionToChar (anEvol);
+
+
+  Standard_OStream* aDirectStream = NULL;
+  if (myIsQuickPart) // enables direct writing of shapes to the stream
+    aDirectStream = theTarget.GetOStream();
 
   Standard_Integer i = 1;  
-  for (TNaming_Iterator SIterator(aSAtt) ;SIterator.More(); SIterator.Next()) {
-    const TopoDS_Shape& OldShape = SIterator.OldShape();
-    const TopoDS_Shape& NewShape = SIterator.NewShape();
+  for (TNaming_Iterator SIterator(aSAtt)SIterator.More(); SIterator.Next()) {
+    const TopoDS_Shape& anOldShape = SIterator.OldShape();
+    const TopoDS_Shape& aNewShape = SIterator.NewShape();
     
-    if ( anEvol != TNaming_PRIMITIVE ) 
-      TranslateTo (OldShape, theTarget, aShapeSet); 
+    if (anEvol != TNaming_PRIMITIVE)
+    {
+      if (myIsQuickPart)
+        aShapeSet->Write (anOldShape, *aDirectStream);
+      else
+        TranslateTo (anOldShape, theTarget, static_cast<BinTools_ShapeSet*>(aShapeSet));
+    }
 
-    if (anEvol != TNaming_DELETE) 
-      TranslateTo (NewShape, theTarget, aShapeSet);
+    if (anEvol != TNaming_DELETE)
+    {
+      if (myIsQuickPart)
+        aShapeSet->Write (aNewShape, *aDirectStream);
+      else
+        TranslateTo (aNewShape, theTarget, static_cast<BinTools_ShapeSet*>(aShapeSet));
+    }
     
     i++;
   }
@@ -280,18 +313,18 @@ void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS,
                                                      const Standard_Integer theDocVer,
                                                      const Message_ProgressRange& theRange)
 {
-  theOS << SHAPESET; 
+  myIsQuickPart = Standard_False;
+  theOS << SHAPESET;
   if (theDocVer >= TDocStd_FormatVersion_VERSION_11)
   {
-    myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_4);
+    ShapeSet (Standard_False)->SetFormatNb (BinTools_FormatVersion_VERSION_4);
   }
   else
   {
-    myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_1);
+    ShapeSet (Standard_False)->SetFormatNb (BinTools_FormatVersion_VERSION_1);
   }
-
-  myShapeSet.Write (theOS, theRange);
-  myShapeSet.Clear();
+  ShapeSet (Standard_False)->Write (theOS, theRange);
+  ShapeSet (Standard_False)->Clear();
 }
 
 //=======================================================================
@@ -301,7 +334,12 @@ void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS,
 
 void BinMNaming_NamedShapeDriver::Clear()
 {
-  myShapeSet.Clear();
+  if (myShapeSet)
+  {
+    myShapeSet->Clear();
+    delete myShapeSet;
+    myShapeSet = NULL;
+  }
 }
 
 //=======================================================================
@@ -312,15 +350,51 @@ void BinMNaming_NamedShapeDriver::Clear()
 void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS,
                                                     const Message_ProgressRange& theRange)
 {
+  myIsQuickPart = Standard_False;
   // check section title string; note that some versions of OCCT (up to 6.3.1) 
   // might avoid writing shape section if it is empty
   std::streamoff aPos = theIS.tellg();
   TCollection_AsciiString aSectionTitle;
   theIS >> aSectionTitle;
   if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) {
-    myShapeSet.Clear();
-    myShapeSet.Read (theIS, theRange);
+    BinTools_ShapeSetBase* aShapeSet = ShapeSet (Standard_True);
+    aShapeSet->Clear();
+    aShapeSet->Read (theIS, theRange);
   }
   else
-    theIS.seekg(aPos); // no shape section is present, try to return to initial point
+    theIS.seekg (aPos); // no shape section is present, try to return to initial point
+}
+
+//=======================================================================
+//function : ShapeSet
+//purpose  : 
+//=======================================================================
+
+BinTools_ShapeSetBase* BinMNaming_NamedShapeDriver::ShapeSet (const Standard_Boolean theReading)
+{
+  if (!myShapeSet)
+  {
+    if (myIsQuickPart)
+    {
+      if (theReading)
+        myShapeSet = new BinTools_ShapeReader();
+      else
+        myShapeSet = new BinTools_ShapeWriter();
+    }
+    else
+      myShapeSet = new BinTools_ShapeSet();
+    myShapeSet->SetWithTriangles(myWithTriangles);
+    myShapeSet->SetWithNormals(myWithNormals);
+  }
+  return myShapeSet;
+}
+
+//=======================================================================
+//function : GetShapesLocations
+//purpose  : 
+//=======================================================================
+BinTools_LocationSet& BinMNaming_NamedShapeDriver::GetShapesLocations() const
+{
+  BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_False);
+  return static_cast<BinTools_ShapeSet*>(aShapeSet)->ChangeLocations();
 }
index c5b3788..7a2d312 100644 (file)
@@ -64,33 +64,35 @@ public:
   Standard_EXPORT void Clear();
 
   //! Return true if shape should be stored with triangles.
-  Standard_Boolean IsWithTriangles() const { return myShapeSet.IsWithTriangles(); }
+  Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
   //! Return true if shape should be stored with triangulation normals.
-  Standard_Boolean IsWithNormals() const { return myShapeSet.IsWithNormals(); }
-
+  Standard_Boolean IsWithNormals() const { return myWithNormals; }
   //! set whether to store triangulation
-  void SetWithTriangles (const Standard_Boolean isWithTriangles) { myShapeSet.SetWithTriangles(isWithTriangles); }
+  void SetWithTriangles (const Standard_Boolean isWithTriangles);
   //! set whether to store triangulation with normals
-  void SetWithNormals (const Standard_Boolean isWithNormals) { myShapeSet.SetWithNormals(isWithNormals); }
-  
-  
+  void SetWithNormals (const Standard_Boolean isWithNormals);
   //! get the shapes locations
-  BinTools_LocationSet& GetShapesLocations();
-
+  Standard_EXPORT BinTools_LocationSet& GetShapesLocations() const;
 
+  //! Sets the flag for quick part of the document access: shapes are stored in the attribute.
+  Standard_EXPORT void EnableQuickPart(const Standard_Boolean theValue) { myIsQuickPart = theValue; }
+  //! Returns true if quick part of the document access is enabled: shapes are stored in the attribute.
+  Standard_EXPORT Standard_Boolean IsQuickPart() { return myIsQuickPart; }
 
+  //! Returns shape-set of the needed type
+  Standard_EXPORT BinTools_ShapeSetBase* ShapeSet (const Standard_Boolean theReading);
 
   DEFINE_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
 
-protected:
-
-
-
 
 private:
 
 
-  BinTools_ShapeSet myShapeSet;
+  BinTools_ShapeSetBase *myShapeSet;
+  Standard_Boolean myWithTriangles;
+  Standard_Boolean myWithNormals;
+  //! Enables storing of whole shape data just in the attribute, not in a separated shapes section
+  Standard_Boolean myIsQuickPart;
 
 };
 
index c313d6f..35d4dfd 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 //=======================================================================
-//function : GetShapesLocations
+//function : SetWithTriangles
 //purpose  : 
 //=======================================================================
-inline BinTools_LocationSet& BinMNaming_NamedShapeDriver::GetShapesLocations()
+
+inline void BinMNaming_NamedShapeDriver::SetWithTriangles(const Standard_Boolean isWithTriangles) 
 {
-  return myShapeSet.ChangeLocations();
+  myWithTriangles = isWithTriangles;
+  if (myShapeSet)
+    myShapeSet->SetWithTriangles (isWithTriangles);
 }
 
+//=======================================================================
+//function : SetWithNormals
+//purpose  : 
+//=======================================================================
+
+inline void BinMNaming_NamedShapeDriver::SetWithNormals(const Standard_Boolean isWithNormals) 
+{
+  myWithNormals = isWithNormals;
+  if (myShapeSet)
+    myShapeSet->SetWithNormals (isWithNormals);
+
+}
index b458ebe..3a2bac5 100644 (file)
@@ -51,9 +51,9 @@ void BinMXCAFDoc::AddDrivers(const Handle(BinMDF_ADriverTable)& theDriverTable,
     Handle(BinMNaming_NamedShapeDriver)::DownCast (aNSDriver);
   
   Handle(BinMXCAFDoc_LocationDriver) aLocationDriver = new BinMXCAFDoc_LocationDriver (theMsgDrv);
-  if( !aNamedShapeDriver.IsNull() )
+  if (!aNamedShapeDriver.IsNull())
   {
-    aLocationDriver->SetSharedLocations( &(aNamedShapeDriver->GetShapesLocations()) );
+    aLocationDriver->SetNSDriver (aNamedShapeDriver);
   }
   
   theDriverTable->AddDriver( aLocationDriver);
index 99a5854..0b624bf 100644 (file)
@@ -18,6 +18,8 @@
 #include <BinMXCAFDoc_LocationDriver.hxx>
 #include <BinObjMgt_Persistent.hxx>
 #include <BinTools_LocationSet.hxx>
+#include <BinTools_ShapeReader.hxx>
+#include <BinTools_ShapeWriter.hxx>
 #include <Message_Messenger.hxx>
 #include <gp_Mat.hxx>
 #include <gp_Trsf.hxx>
@@ -37,7 +39,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BinMXCAFDoc_LocationDriver,BinMDF_ADriver)
 //=======================================================================
 BinMXCAFDoc_LocationDriver::BinMXCAFDoc_LocationDriver(const Handle(Message_Messenger)& theMsgDriver)
      : BinMDF_ADriver(theMsgDriver, STANDARD_TYPE(XCAFDoc_Location)->Name())
-     , myLocations(0) {
+{
 }
 
 //=======================================================================
@@ -84,6 +86,14 @@ Standard_Boolean BinMXCAFDoc_LocationDriver::Translate(const BinObjMgt_Persisten
                                                        TopLoc_Location& theLoc,
                                                        BinObjMgt_RRelocationTable& theMap) const
 {
+  if (!myNSDriver.IsNull() && myNSDriver->IsQuickPart())
+  {
+    BinTools_IStream aDirectStream (*(const_cast<BinObjMgt_Persistent*>(&theSource)->GetIStream()));
+    BinTools_ShapeReader* aReader = static_cast<BinTools_ShapeReader*>(myNSDriver->ShapeSet (Standard_True));
+    theLoc = *(aReader->ReadLocation (aDirectStream));
+    return Standard_True;
+  }
+
   Standard_Integer anId = 0;
   theSource >> anId;
   
@@ -91,19 +101,25 @@ Standard_Boolean BinMXCAFDoc_LocationDriver::Translate(const BinObjMgt_Persisten
   {
     return Standard_True;
   }
+
+  if (!myNSDriver.IsNull() && myNSDriver->IsQuickPart())
+  { // read directly from the stream
+
+
+  }
   
   Standard_Integer aFileVer = theMap.GetHeaderData()->StorageVersion().IntegerValue();
-  if( aFileVer >= TDocStd_FormatVersion_VERSION_6 && myLocations == 0 )
+  if( aFileVer >= TDocStd_FormatVersion_VERSION_6 && myNSDriver.IsNull() )
   {
     return Standard_False;
   }
   
-  Standard_Integer aPower;
+  Standard_Integer aPower (0);
   Handle(TopLoc_Datum3D) aDatum;
   
-  ifaFileVer >= TDocStd_FormatVersion_VERSION_6)
+  if (aFileVer >= TDocStd_FormatVersion_VERSION_6)
   {
-    const TopLoc_Location& aLoc = myLocations->Location(anId);
+    const TopLoc_Location& aLoc = myNSDriver->GetShapesLocations().Location (anId);
     aPower = aLoc.FirstPower();
     aDatum = aLoc.FirstDatum();
   } else {
@@ -168,35 +184,43 @@ void BinMXCAFDoc_LocationDriver::Translate(const TopLoc_Location& theLoc,
                                            BinObjMgt_Persistent& theTarget,
                                            BinObjMgt_SRelocationTable& theMap) const
 {
-  if(theLoc.IsIdentity()) 
+  if (!myNSDriver.IsNull() && myNSDriver->IsQuickPart())
+  { // write directly to the stream
+    Standard_OStream* aDirectStream = theTarget.GetOStream();
+    BinTools_ShapeWriter* aWriter = static_cast<BinTools_ShapeWriter*>(myNSDriver->ShapeSet (Standard_False));
+    BinTools_OStream aStream(*aDirectStream);
+    aWriter->WriteLocation (aStream, theLoc);
+    return;
+  }
+  if (theLoc.IsIdentity())
   {
     theTarget.PutInteger(0);
     return;
   }
   
-  // The location is not identity  
-  if( myLocations == 0 )
+  // The location is not identity
+  if (myNSDriver.IsNull())
   {
 #ifdef OCCT_DEBUG
-    std::cout<<"Pointer to LocationSet is NULL\n";
+    std::cout << "NamedShape Driver is NULL\n";
 #endif
     return;
   }
-  
-  Standard_Integer anId = myLocations->Add(theLoc);
+
+  Standard_Integer anId = myNSDriver->GetShapesLocations().Add (theLoc);
   theTarget << anId;
-  
+
   // In earlier version of this driver a datums from location stored in 
   // the relocation table, but now it's not necessary
   // (try to uncomment it if some problems appear)
   /*
   Handle(TopLoc_Datum3D) aDatum = theLoc.FirstDatum();
-  
+
   if(!theMap.Contains(aDatum)) {
     theMap.Add(aDatum);
   }
   */
-  
+
   Translate(theLoc.NextLocation(), theTarget, theMap);
 }
 
index 76fe223..c46d5b8 100644 (file)
@@ -19,7 +19,7 @@
 #include <Standard.hxx>
 #include <Standard_Type.hxx>
 
-#include <BinTools_LocationSetPtr.hxx>
+#include <BinMNaming_NamedShapeDriver.hxx>
 #include <BinMDF_ADriver.hxx>
 #include <Standard_Boolean.hxx>
 #include <BinObjMgt_RRelocationTable.hxx>
@@ -53,7 +53,7 @@ public:
   //! Translate transient location to storable
   Standard_EXPORT void Translate (const TopLoc_Location& theLoc, BinObjMgt_Persistent& theTarget, BinObjMgt_SRelocationTable& theMap) const;
   
-    void SetSharedLocations (const BinTools_LocationSetPtr& theLocations);
+  void SetNSDriver (const Handle(BinMNaming_NamedShapeDriver)& theNSDriver) { myNSDriver = theNSDriver; }
 
 
 
@@ -68,16 +68,10 @@ protected:
 private:
 
 
-  BinTools_LocationSetPtr myLocations;
-
+  Handle(BinMNaming_NamedShapeDriver) myNSDriver;
 
 };
 
 
-#include <BinMXCAFDoc_LocationDriver.lxx>
-
-
-
-
 
 #endif // _BinMXCAFDoc_LocationDriver_HeaderFile
diff --git a/src/BinMXCAFDoc/BinMXCAFDoc_LocationDriver.lxx b/src/BinMXCAFDoc/BinMXCAFDoc_LocationDriver.lxx
deleted file mode 100644 (file)
index f4ab83a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Created on: 2011-02-08
-// Created by: Oleg AGASHIN
-// Copyright (c) 2011-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//=======================================================================
-//function : SetSharedLocations
-//purpose  : 
-//=======================================================================
-inline void BinMXCAFDoc_LocationDriver::SetSharedLocations(const BinTools_LocationSetPtr& theLocations)
-{ 
-  if( myLocations != theLocations )
-  {
-    myLocations = theLocations;
-  }
-}
index 68f84fa..93026d7 100644 (file)
@@ -14,7 +14,6 @@ BinMXCAFDoc_GraphNodeDriver.cxx
 BinMXCAFDoc_GraphNodeDriver.hxx
 BinMXCAFDoc_LocationDriver.cxx
 BinMXCAFDoc_LocationDriver.hxx
-BinMXCAFDoc_LocationDriver.lxx
 BinMXCAFDoc_MaterialDriver.cxx
 BinMXCAFDoc_MaterialDriver.hxx
 BinMXCAFDoc_NoteDriver.cxx
index 2bde323..4056c7d 100644 (file)
@@ -15,6 +15,7 @@
 
 
 #include <BinObjMgt_Persistent.hxx>
+#include <BinObjMgt_Position.hxx>
 #include <FSD_FileHeader.hxx>
 #include <Standard_GUID.hxx>
 #include <TCollection_AsciiString.hxx>
@@ -52,7 +53,10 @@ BinObjMgt_Persistent::BinObjMgt_Persistent ()
      : myIndex (1),
        myOffset(BP_HEADSIZE),
        mySize  (BP_HEADSIZE),
-       myIsError (Standard_False)
+       myIsError (Standard_False),
+       myOStream (NULL),
+       myIStream (NULL),
+       myDirectWritingIsEnabled (Standard_False)
 {
   Init();
 }
@@ -76,6 +80,7 @@ void BinObjMgt_Persistent::Init ()
   myOffset = BP_HEADSIZE;
   mySize = BP_HEADSIZE;
   myIsError = Standard_False;
+  myDirectWritingIsEnabled = Standard_False;
 }
 
 //=======================================================================
@@ -85,13 +90,20 @@ void BinObjMgt_Persistent::Init ()
 //           const BinObjMgt_Persistent&) is also available
 //=======================================================================
 
-Standard_OStream& BinObjMgt_Persistent::Write (Standard_OStream& theOS)
+Standard_OStream& BinObjMgt_Persistent::Write (Standard_OStream& theOS, const Standard_Boolean theDirectStream)
 {
+  if (myDirectWritingIsEnabled)
+  { // if direct writing was enabled, everything is already written, just pass this stage
+    myDirectWritingIsEnabled = Standard_False;
+    return theOS;
+  }
   Standard_Integer nbWritten = 0;
   Standard_Integer *aData = (Standard_Integer*) myData(1);
   // update data length
   aData[2] = mySize - BP_HEADSIZE;
-#ifdef DO_INVERSE
+  if (theDirectStream)
+    aData[1] = -aData[1];
+#if DO_INVERSE
   aData[0] = InverseInt (aData[0]);
   aData[1] = InverseInt (aData[1]);
   aData[2] = InverseInt (aData[2]);
@@ -141,7 +153,10 @@ Standard_IStream& BinObjMgt_Persistent::Read (Standard_IStream& theIS)
     aData[1] = InverseInt (aData[1]);
     aData[2] = InverseInt (aData[2]);
 #endif
-    if (theIS && aData[1] > 0 && aData[2] > 0) {
+    myDirectWritingIsEnabled = aData[1] < 0;
+    if (myDirectWritingIsEnabled)
+      aData[1] = -aData[1];
+    if (theIS && aData[2] > 0) {
       mySize += aData[2];
       // read remaining data
       Standard_Integer nbRead = BP_HEADSIZE;
@@ -1164,3 +1179,28 @@ void BinObjMgt_Persistent::inverseShortRealData
     }
   }
 }
+
+//=======================================================================
+//function : GetOStream
+//purpose  : Gets the stream for and enables direct writing
+//=======================================================================
+
+Standard_OStream* BinObjMgt_Persistent::GetOStream()
+{
+  Write (*myOStream, Standard_True); // finishes already stored data save
+  myStreamStart = new BinObjMgt_Position (*myOStream);
+  myStreamStart->WriteSize (*myOStream, Standard_True);
+  myDirectWritingIsEnabled = Standard_True;
+  return myOStream;
+}
+
+//=======================================================================
+//function : GetOStream
+//purpose  : Gets the stream for and enables direct writing
+//=======================================================================
+Standard_IStream* BinObjMgt_Persistent::GetIStream()
+{
+  // skip the stream size first
+  myIStream->seekg (sizeof (uint64_t), std::ios_base::cur);
+  return myIStream;
+}
index a43a51d..2919efc 100644 (file)
@@ -35,6 +35,7 @@
 #include <BinObjMgt_PInteger.hxx>
 #include <BinObjMgt_PReal.hxx>
 #include <BinObjMgt_PShortReal.hxx>
+#include <BinObjMgt_Position.hxx>
 #include <Standard_OStream.hxx>
 #include <Standard_IStream.hxx>
 #include <Standard_Address.hxx>
@@ -261,13 +262,13 @@ const BinObjMgt_Persistent& operator >> (Standard_GUID& theValue) const
   //! Indicates an error after Get methods or SetPosition
     Standard_Boolean IsError() const;
   Standard_Boolean operator !() const
-{
-  return IsError();
-}
+  {
+    return IsError();
+  }
   
   //! Indicates a good state after Get methods or SetPosition
     Standard_Boolean IsOK() const;
-operator Standard_Boolean () const { return IsOK(); }
+  operator Standard_Boolean () const { return IsOK(); }
   
   //! Initializes me to reuse again
   Standard_EXPORT void Init();
@@ -289,8 +290,9 @@ operator Standard_Boolean () const { return IsOK(); }
   
   //! Stores <me> to the stream.
   //! inline Standard_OStream& operator<< (Standard_OStream&,
-  //! BinObjMgt_Persistent&) is also available
-  Standard_EXPORT Standard_OStream& Write (Standard_OStream& theOS);
+  //! BinObjMgt_Persistent&) is also available.
+  //! If theDirectStream is true, after this data the direct stream data is stored.
+  Standard_EXPORT Standard_OStream& Write (Standard_OStream& theOS, const Standard_Boolean theDirectStream = Standard_False);
   
   //! Retrieves <me> from the stream.
   //! inline Standard_IStream& operator>> (Standard_IStream&,
@@ -300,19 +302,23 @@ operator Standard_Boolean () const { return IsOK(); }
   //! Frees the allocated memory;
   //! This object can be reused after call to Init
   Standard_EXPORT void Destroy();
-~BinObjMgt_Persistent()
-{
-  Destroy();
-}
-
-
-
-
-protected:
-
-
-
+  ~BinObjMgt_Persistent()
+  {
+    Destroy();
+  }
 
+  //! Sets the stream for direct writing
+  Standard_EXPORT void SetOStream (Standard_OStream& theStream) { myOStream = &theStream; }
+  //! Sets the stream for direct reading
+  Standard_EXPORT void SetIStream (Standard_IStream& theStream) { myIStream = &theStream; }
+  //! Gets the stream for and enables direct writing
+  Standard_EXPORT Standard_OStream* GetOStream();
+  //! Gets the stream for and enables direct reading
+  Standard_EXPORT Standard_IStream* GetIStream();
+  //! Returns true if after this record a direct writing to the stream is performed.
+  Standard_EXPORT Standard_Boolean IsDirect() { return myDirectWritingIsEnabled; }
+  //! Returns the start position of the direct writing in the stream
+  Standard_EXPORT Handle(BinObjMgt_Position) StreamStart() { return myStreamStart; }
 
 private:
 
@@ -358,8 +364,10 @@ private:
   Standard_Integer myOffset;
   Standard_Integer mySize;
   Standard_Boolean myIsError;
-
-
+  Standard_OStream* myOStream; ///< stream to write in case direct writing is enabled
+  Standard_IStream* myIStream; ///< stream to write in case direct reading is enabled
+  Standard_Boolean myDirectWritingIsEnabled;
+  Handle(BinObjMgt_Position) myStreamStart; ///< position where the direct writing to the script is started
 };
 
 
index c7c22af..9ea3282 100644 (file)
@@ -34,6 +34,7 @@ inline void BinObjMgt_Persistent::SetId (const Standard_Integer theId)
 inline void BinObjMgt_Persistent::SetTypeId (const Standard_Integer theTypeId)
 {
   ((Standard_Integer*) myData(1)) [0] = theTypeId;
+  myStreamStart.Nullify();
 }
 
 //=======================================================================
diff --git a/src/BinObjMgt/BinObjMgt_Position.cxx b/src/BinObjMgt/BinObjMgt_Position.cxx
new file mode 100644 (file)
index 0000000..305ca72
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) 2021 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 <BinObjMgt_Position.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (BinObjMgt_Position, Standard_Transient)
+
+//=======================================================================
+//function : BinObjMgt_Position
+//purpose  : 
+//=======================================================================
+BinObjMgt_Position::BinObjMgt_Position (Standard_OStream& theStream) :
+  myPosition (theStream.tellp()), mySize(0)
+{}
+
+//=======================================================================
+//function : StoreSize
+//purpose  : 
+//=======================================================================
+void BinObjMgt_Position::StoreSize (Standard_OStream& theStream)
+{
+  mySize = uint64_t (theStream.tellp() - myPosition);
+}
+
+//=======================================================================
+//function : WriteSize
+//purpose  : 
+//=======================================================================
+void BinObjMgt_Position::WriteSize (Standard_OStream& theStream, const Standard_Boolean theDummy)
+{
+  if (!theDummy && theStream.tellp() != myPosition)
+    theStream.seekp (myPosition);
+  uint64_t aSize = theDummy ? 0 : mySize;
+#if DO_INVERSE
+  aSize = FSD_BinaryFile::InverseUint64 (aSize);
+#endif
+  theStream.write ((char*)&aSize, sizeof (uint64_t));
+}
diff --git a/src/BinObjMgt/BinObjMgt_Position.hxx b/src/BinObjMgt/BinObjMgt_Position.hxx
new file mode 100644 (file)
index 0000000..7fdc3f7
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (c) 2021 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 _BinObjMgt_Position_HeaderFile
+#define _BinObjMgt_Position_HeaderFile
+
+#include <Standard_Type.hxx>
+
+class BinObjMgt_Position;
+DEFINE_STANDARD_HANDLE (BinObjMgt_Position, Standard_Transient)
+
+//! Stores and manipulates position in the stream.
+class BinObjMgt_Position : public Standard_Transient
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  //! Creates position using the current stream position.
+  Standard_EXPORT BinObjMgt_Position (Standard_OStream& theStream);
+
+  //! Stores the difference between the current position and the stored one.
+  Standard_EXPORT void StoreSize (Standard_OStream& theStream);
+  //! Writes stored size at the stored position. Changes the current stream position.
+//! If theDummy is true, is writes to the current position zero size.
+  Standard_EXPORT void WriteSize (Standard_OStream& theStream, const Standard_Boolean theDummy = Standard_False);
+
+  DEFINE_STANDARD_RTTIEXT (BinObjMgt_Position, Standard_Transient)
+
+private:
+  std::streampos myPosition;
+  uint64_t mySize;
+};
+
+#endif // _BinObjMgt_Position_HeaderFile
index 7954116..4683730 100755 (executable)
@@ -5,6 +5,8 @@ BinObjMgt_Persistent.hxx
 BinObjMgt_Persistent.lxx
 BinObjMgt_PExtChar.hxx
 BinObjMgt_PInteger.hxx
+BinObjMgt_Position.cxx
+BinObjMgt_Position.hxx
 BinObjMgt_PReal.hxx
 BinObjMgt_PShortReal.hxx
 BinObjMgt_RRelocationTable.cxx
index a17e8ed..d5c5d3a 100644 (file)
@@ -42,7 +42,7 @@ Standard_OStream& BinTools::PutInteger(Standard_OStream& OS, const Standard_Inte
 #ifdef DO_INVERSE
       anIntValue = InverseInt (aValue);
 #endif
-  OS.write((char*)&anIntValue, sizeof(Standard_Integer));  
+  OS.write ((char*)&anIntValue, sizeof (Standard_Integer));  
   return OS;
 }
 
@@ -56,9 +56,9 @@ Standard_OStream& BinTools::PutReal (Standard_OStream& theOS,
 {
 #ifdef DO_INVERSE
   const Standard_Real aRValue = InverseReal (theValue);
-  theOS.write((char*)&aRValue, sizeof(Standard_Real));
+  theOS.write ((char*)&aRValue, sizeof (Standard_Real));
 #else
-  theOS.write((char*)&theValue, sizeof(Standard_Real));
+  theOS.write ((char*)&theValue, sizeof (Standard_Real));
 #endif
   return theOS;
 }
@@ -200,7 +200,7 @@ void BinTools::Read (TopoDS_Shape& theShape, Standard_IStream& theStream,
   BinTools_ShapeSet aShapeSet;
   aShapeSet.SetWithTriangles(Standard_True);
   aShapeSet.Read (theStream, theRange);
-  aShapeSet.Read (theShape, theStream, aShapeSet.NbShapes());
+  aShapeSet.ReadSubs (theShape, theStream, aShapeSet.NbShapes());
 }
 
 //=======================================================================
index e6fe7e7..e662232 100644 (file)
@@ -53,7 +53,7 @@ public:
   Standard_EXPORT static Standard_OStream& PutBool (Standard_OStream& OS, const Standard_Boolean theValue);
   
   Standard_EXPORT static Standard_OStream& PutExtChar (Standard_OStream& OS, const Standard_ExtCharacter theValue);
-  
+
   Standard_EXPORT static Standard_IStream& GetReal (Standard_IStream& IS, Standard_Real& theValue);
 
   Standard_EXPORT static Standard_IStream& GetShortReal (Standard_IStream& IS, Standard_ShortReal& theValue);
index 4da831f..bbcfc9f 100644 (file)
@@ -105,35 +105,12 @@ Standard_Integer  BinTools_Curve2dSet::Index
   return myMap.FindIndex(S);
 }
 
-//=======================================================================
-//function : operator << (gp_Pnt2d)
-//purpose  : 
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt2d P)
-                 
-{
-  BinTools::PutReal(OS, P.X());
-  return BinTools::PutReal(OS, P.Y());
-}
-
-//=======================================================================
-//function : operator << (gp_Dir2d D)
-//purpose  : 
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Dir2d D)
-{
-  BinTools::PutReal(OS, D.X());
-  return BinTools::PutReal(OS, D.Y());
-}
-
 //=======================================================================
 //function : operator << ((Geom2d_Line)& L)
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_Line)& L)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Line)& L)
 {
 
   OS << (Standard_Byte)LINE;
@@ -148,14 +125,14 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_L
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_Circle)& C)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Circle)& C)
 {
   OS << (Standard_Byte)CIRCLE;
   gp_Circ2d C2d = C->Circ2d();
   OS << C2d.Location();
   OS << C2d.XAxis().Direction();
   OS << C2d.YAxis().Direction();
-  BinTools::PutReal(OS, C2d.Radius());
+  OS << C2d.Radius();
   return OS;
 }
 
@@ -164,15 +141,15 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_C
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_Ellipse)& E)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Ellipse)& E)
 {
   OS << (Standard_Byte)ELLIPSE;
   gp_Elips2d C2d = E->Elips2d();
   OS << C2d.Location();
   OS << C2d.XAxis().Direction();
   OS << C2d.YAxis().Direction();
-  BinTools::PutReal(OS, C2d.MajorRadius());
-  BinTools::PutReal(OS, C2d.MinorRadius());
+  OS << C2d.MajorRadius();
+  OS << C2d.MinorRadius();
   return OS;
 }
 
@@ -181,14 +158,14 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_E
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_Parabola)& P)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Parabola)& P)
 {
   OS << (Standard_Byte)PARABOLA;
   gp_Parab2d C2d = P->Parab2d();
-  OS << C2d.Location();//Loc
-  OS << C2d.Axis().XAxis().Direction();//XDir
-  OS << C2d.Axis().YAxis().Direction();//YDir
-  BinTools::PutReal(OS, C2d.Focal());//Focal
+  OS << C2d.Location(); // Loc
+  OS << C2d.Axis().XAxis().Direction(); // XDir
+  OS << C2d.Axis().YAxis().Direction(); // YDir
+  OS << C2d.Focal(); // Focal
   return OS;
 }
 
@@ -197,15 +174,15 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_P
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_Hyperbola)& H)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_Hyperbola)& H)
 {
   OS << (Standard_Byte)HYPERBOLA;
   gp_Hypr2d C2d = H->Hypr2d();
-  OS << C2d.Location(); //Loc
-  OS << C2d.XAxis().Direction();//XDir
-  OS << C2d.YAxis().Direction();//YDir
-  BinTools::PutReal(OS, C2d.MajorRadius());//MajR
-  BinTools::PutReal(OS, C2d.MinorRadius());
+  OS << C2d.Location(); // Loc
+  OS << C2d.XAxis().Direction(); // XDir
+  OS << C2d.YAxis().Direction(); // YDir
+  OS << C2d.MajorRadius(); // MajR
+  OS << C2d.MinorRadius();
   return OS;
 }
 
@@ -214,18 +191,18 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_H
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_BezierCurve)& B)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_BezierCurve)& B)
 {
   OS << (Standard_Byte)BEZIER;
   Standard_Boolean aRational = B->IsRational() ? 1:0;
-  BinTools::PutBool(OS, aRational); //rational
+  OS << aRational; // rational
   // poles and weights
   Standard_Integer i,aDegree = B->Degree(); 
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter)aDegree); //Degree
+  OS << (Standard_ExtCharacter)aDegree; // Degree
   for (i = 1; i <= aDegree+1; i++) {
-    OS << B->Pole(i); //Pnt2d
+    OS << B->Pole(i); // Pnt2d
     if (aRational)
-      BinTools::PutReal(OS, B->Weight(i));//Real
+      OS << B->Weight(i); // Real
   }
   return OS;
 }
@@ -235,30 +212,30 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_B
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_BSplineCurve)& B)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_BSplineCurve)& B)
 {
   OS << (Standard_Byte)BSPLINE;
   Standard_Boolean aRational = B->IsRational() ? 1:0;
-  BinTools::PutBool(OS, aRational); //rational
+  OS << aRational; //rational
   Standard_Boolean aPeriodic = B->IsPeriodic() ? 1:0;
-  BinTools::PutBool(OS, aPeriodic); //periodic
+  OS << aPeriodic; //periodic
   // poles and weights
   Standard_Integer i,aDegree,aNbPoles,aNbKnots;
   aDegree = B->Degree();
   aNbPoles = B->NbPoles();
   aNbKnots = B->NbKnots();
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter) aDegree);
-  BinTools::PutInteger(OS,  aNbPoles);
-  BinTools::PutInteger(OS,  aNbKnots);
+  OS << (Standard_ExtCharacter) aDegree;
+  OS <<  aNbPoles;
+  OS <<  aNbKnots;
   for (i = 1; i <= aNbPoles; i++) {
     OS << B->Pole(i); // Pnt2d
     if (aRational)
-      BinTools::PutReal(OS, B->Weight(i));
+      OS << B->Weight(i);
   }
 
   for (i = 1; i <= aNbKnots; i++) {
-    BinTools::PutReal(OS, B->Knot(i));
-    BinTools::PutInteger(OS, B->Multiplicity(i));
+    OS << B->Knot(i);
+    OS << B->Multiplicity(i);
   }
 
   return OS;
@@ -269,12 +246,12 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_B
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_TrimmedCurve)& C)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_TrimmedCurve)& C)
 {
   OS << (Standard_Byte)TRIMMED;
-  BinTools::PutReal(OS, C->FirstParameter()); 
-  BinTools::PutReal(OS, C->LastParameter());
-  BinTools_Curve2dSet::WriteCurve2d(C->BasisCurve(),OS);
+  OS << C->FirstParameter(); 
+  OS << C->LastParameter();
+  BinTools_Curve2dSet::WriteCurve2d (C->BasisCurve(), OS);
   return OS;
 }
 
@@ -283,11 +260,11 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_T
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_OffsetCurve)& C)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom2d_OffsetCurve)& C)
 {
   OS << (Standard_Byte)OFFSET;
-  BinTools::PutReal(OS,C->Offset());//Offset 
-  BinTools_Curve2dSet::WriteCurve2d(C->BasisCurve(),OS);
+  OS << C->Offset(); // Offset 
+  BinTools_Curve2dSet::WriteCurve2d (C->BasisCurve(), OS);
   return OS;  
 }
 
@@ -296,8 +273,8 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom2d_O
 //purpose  : 
 //=======================================================================
 
-void BinTools_Curve2dSet::WriteCurve2d(const Handle(Geom2d_Curve)& C,
-                                       Standard_OStream& OS)
+void BinTools_Curve2dSet::WriteCurve2d(
+  const Handle(Geom2d_Curve)& C, BinTools_OStream& OS)
 {
   Handle(Standard_Type) TheType = C->DynamicType();
   try {
@@ -352,8 +329,9 @@ void  BinTools_Curve2dSet::Write (Standard_OStream& OS,
   Standard_Integer i, aNbCurves = myMap.Extent();
   Message_ProgressScope aPS(theRange, "Writing 2D curves",aNbCurves);
   OS << "Curve2ds "<< aNbCurves << "\n";
+  BinTools_OStream aStream (OS);
   for (i = 1; i <= aNbCurves && aPS.More(); i++, aPS.Next()) {
-    WriteCurve2d(Handle(Geom2d_Curve)::DownCast(myMap(i)),OS);
+    WriteCurve2d (Handle(Geom2d_Curve)::DownCast (myMap (i)), aStream);
   }
 }
 
index d163b39..4d99ffa 100644 (file)
@@ -26,6 +26,7 @@
 #include <Standard_IStream.hxx>
 
 #include <Message_ProgressRange.hxx>
+#include <BinTools_OStream.hxx>
 
 class Standard_OutOfRange;
 class Geom2d_Curve;
@@ -69,7 +70,7 @@ public:
                              const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! Dumps the curve on the binary stream, that can be read back.
-  Standard_EXPORT static void WriteCurve2d(const Handle(Geom2d_Curve)& C, Standard_OStream& OS);
+  Standard_EXPORT static void WriteCurve2d(const Handle(Geom2d_Curve)& C, BinTools_OStream& OS);
   
   //! Reads the curve  from  the stream.  The  curve  is
   //! assumed   to have  been  written  with  the Write
index 176bb41..4b30c29 100644 (file)
@@ -110,44 +110,17 @@ Standard_Integer  BinTools_CurveSet::Index
 }
 
 
-//=======================================================================
-//function : operator << (gp_Pnt)
-//purpose  : 
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt P)
-{
-  BinTools::PutReal(OS, P.X());
-  BinTools::PutReal(OS, P.Y());
-  BinTools::PutReal(OS, P.Z());
-  return OS;
-}
-
-//=======================================================================
-//function : operator << (gp_Dir)
-//purpose  : 
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Dir D)
-{
-  BinTools::PutReal(OS, D.X());
-  BinTools::PutReal(OS, D.Y());
-  BinTools::PutReal(OS, D.Z());
-  return OS;
-}
-
-
 //=======================================================================
 //function : operator << (Geom_Line)
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Line)& L)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_Line)& L)
 {
   OS << (Standard_Byte)LINE;
   gp_Lin C = L->Lin();
-  OS << C.Location();//Pnt
-  OS << C.Direction();//Dir
+  OS << C.Location(); // Pnt
+  OS << C.Direction(); // Dir
   return OS;
   
 }
@@ -157,7 +130,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Lin
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Circle)& CC)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_Circle)& CC)
 {
   OS << (Standard_Byte)CIRCLE;
   gp_Circ C = CC->Circ();
@@ -165,7 +138,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Cir
   OS << C.Axis().Direction();
   OS << C.XAxis().Direction();
   OS << C.YAxis().Direction();
-  BinTools::PutReal(OS, C.Radius());
+  OS << C.Radius();
   return OS;
 }
 
@@ -174,7 +147,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Cir
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Ellipse)& E)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_Ellipse)& E)
 {
   OS << (Standard_Byte)ELLIPSE;
   gp_Elips C = E->Elips();
@@ -182,8 +155,8 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Ell
   OS << C.Axis().Direction();
   OS << C.XAxis().Direction();
   OS << C.YAxis().Direction();
-  BinTools::PutReal(OS, C.MajorRadius());
-  BinTools::PutReal(OS, C.MinorRadius());
+  OS << C.MajorRadius();
+  OS << C.MinorRadius();
   return OS;  
 }
 
@@ -192,7 +165,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Ell
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Parabola)& P)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_Parabola)& P)
 {
   OS << (Standard_Byte)PARABOLA;
   gp_Parab C = P->Parab();
@@ -200,7 +173,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Par
   OS << C.Axis().Direction();
   OS << C.XAxis().Direction();
   OS << C.YAxis().Direction();
-  BinTools::PutReal(OS, C.Focal());
+  OS << C.Focal();
   return OS;  
 }
 
@@ -209,7 +182,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Par
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Hyperbola)& H)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_Hyperbola)& H)
 {
   OS << (Standard_Byte)HYPERBOLA;
   gp_Hypr C = H->Hypr();
@@ -217,8 +190,8 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Hyp
   OS << C.Axis().Direction();
   OS << C.XAxis().Direction();
   OS << C.YAxis().Direction();
-  BinTools::PutReal(OS, C.MajorRadius());
-  BinTools::PutReal(OS, C.MinorRadius());
+  OS << C.MajorRadius();
+  OS << C.MinorRadius();
   return OS; 
 }
 
@@ -227,18 +200,18 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Hyp
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_BezierCurve)& B)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_BezierCurve)& B)
 {
   OS << (Standard_Byte)BEZIER;
   Standard_Boolean aRational = B->IsRational() ? 1:0;
-  BinTools::PutBool(OS, aRational); //rational
+  OS << aRational; // rational
   // poles and weights
-  Standard_Integer i,aDegree = B->Degree(); 
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter)aDegree); //<< Degree
+  Standard_Integer i, aDegree = B->Degree(); 
+  OS << (Standard_ExtCharacter)aDegree; //<< Degree
   for (i = 1; i <= aDegree+1; i++) {
-    OS << B->Pole(i); //Pnt
+    OS << B->Pole(i); // Pnt
     if (aRational)
-      BinTools::PutReal(OS, B->Weight(i));//Real
+      OS << B->Weight(i); // Real
   }
   return OS;  
 }
@@ -248,30 +221,30 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Bez
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_BSplineCurve)& B)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_BSplineCurve)& B)
 {
   OS << (Standard_Byte)BSPLINE;
   Standard_Boolean aRational = B->IsRational() ? 1:0;
-  BinTools::PutBool(OS, aRational); //rational
+  OS << aRational; // rational
   Standard_Boolean aPeriodic = B->IsPeriodic() ? 1:0;
-  BinTools::PutBool(OS, aPeriodic); //periodic
+  OS << aPeriodic; // periodic
   // poles and weights
   Standard_Integer i,aDegree,aNbPoles,aNbKnots;
   aDegree = B->Degree();
   aNbPoles = B->NbPoles();
   aNbKnots = B->NbKnots();
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter) aDegree);
-  BinTools::PutInteger(OS, aNbPoles);
-  BinTools::PutInteger(OS, aNbKnots);
+  OS << (Standard_ExtCharacter) aDegree;
+  OS << aNbPoles;
+  OS << aNbKnots;
   for (i = 1; i <= aNbPoles; i++) {
     OS << B->Pole(i); // Pnt
     if (aRational)
-      BinTools::PutReal(OS, B->Weight(i));
+      OS << B->Weight(i);
   }
   
   for (i = 1; i <= aNbKnots; i++) {
-    BinTools::PutReal(OS, B->Knot(i));
-    BinTools::PutInteger(OS, B->Multiplicity(i));
+    OS << B->Knot(i);
+    OS << B->Multiplicity(i);
   }  
   return OS;
 }
@@ -281,11 +254,11 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_BSp
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_TrimmedCurve)& C)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_TrimmedCurve)& C)
 {
   OS << (Standard_Byte)TRIMMED;
-  BinTools::PutReal(OS, C->FirstParameter()); 
-  BinTools::PutReal(OS, C->LastParameter());
+  OS << C->FirstParameter(); 
+  OS << C->LastParameter();
   BinTools_CurveSet::WriteCurve(C->BasisCurve(),OS);
   return OS; 
 }
@@ -295,10 +268,10 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Tri
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_OffsetCurve)& C)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_OffsetCurve)& C)
 {
   OS << (Standard_Byte)OFFSET;
-  BinTools::PutReal(OS,C->Offset());//Offset 
+  OS << C->Offset(); // Offset 
   OS << C->Direction();
   BinTools_CurveSet::WriteCurve(C->BasisCurve(),OS);
   return OS; 
@@ -310,7 +283,7 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Off
 //=======================================================================
 
 void BinTools_CurveSet::WriteCurve(const Handle(Geom_Curve)& C,
-                                   Standard_OStream& OS)
+                                   BinTools_OStream& OS)
 {
   Handle(Standard_Type) TheType = C->DynamicType();
   try {
@@ -363,10 +336,11 @@ void  BinTools_CurveSet::Write (Standard_OStream& OS,
                                 const Message_ProgressRange& theRange)const
 {
   Standard_Integer i, nbcurv = myMap.Extent();
-  Message_ProgressScope aPS(theRange, "Writing curves", nbcurv);
+  Message_ProgressScope aPS (theRange, "Writing curves", nbcurv);
   OS << "Curves "<< nbcurv << "\n";
+  BinTools_OStream aStream (OS);
   for (i = 1; i <= nbcurv &&aPS.More(); i++, aPS.Next()) {
-    WriteCurve(Handle(Geom_Curve)::DownCast(myMap(i)),OS);
+    WriteCurve(Handle(Geom_Curve)::DownCast(myMap(i)), aStream);
   }
 }
 
index 30a1014..d825805 100644 (file)
@@ -26,6 +26,7 @@
 #include <Standard_IStream.hxx>
 
 #include <Message_ProgressRange.hxx>
+#include <BinTools_OStream.hxx>
 
 class Standard_OutOfRange;
 class Geom_Curve;
@@ -67,7 +68,7 @@ public:
   
   //! Dumps the curve on the stream in binary format
   //! that can be read back.
-  Standard_EXPORT static void WriteCurve (const Handle(Geom_Curve)& C, Standard_OStream& OS);
+  Standard_EXPORT static void WriteCurve (const Handle(Geom_Curve)& C, BinTools_OStream& OS);
   
   //! Reads the curve  from  the stream.  The  curve  is
   //! assumed  to have  been  written  with  the Write
diff --git a/src/BinTools/BinTools_IStream.cxx b/src/BinTools/BinTools_IStream.cxx
new file mode 100644 (file)
index 0000000..5d5175c
--- /dev/null
@@ -0,0 +1,257 @@
+// Copyright (c) 2021 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 <BinTools_IStream.hxx>
+#include <Storage_StreamTypeMismatchError.hxx>
+
+//=======================================================================
+//function : BinTools_IStream
+//purpose  : 
+//=======================================================================
+BinTools_IStream::BinTools_IStream (Standard_IStream& theStream)
+  : myStream (&theStream), myPosition (theStream.tellg()), myLastType (BinTools_ObjectType_Unknown)
+{}
+
+//=======================================================================
+//function : ReadType
+//purpose  : 
+//=======================================================================
+BinTools_ObjectType BinTools_IStream::ReadType()
+{
+  myLastType = BinTools_ObjectType (myStream->get());
+  myPosition++;
+  return myLastType;
+}
+
+//=======================================================================
+//function : IsReference
+//purpose  : 
+//=======================================================================
+Standard_Boolean BinTools_IStream::IsReference()
+{
+  return myLastType == BinTools_ObjectType_Reference8 || myLastType == BinTools_ObjectType_Reference16 ||
+         myLastType == BinTools_ObjectType_Reference32 || myLastType == BinTools_ObjectType_Reference64;
+}
+
+//=======================================================================
+//function : ReadReference
+//purpose  : 
+//=======================================================================
+uint64_t BinTools_IStream::ReadReference()
+{
+  uint64_t aDelta = 0;
+  uint64_t aCurrentPos = uint64_t (myStream->tellg());
+  switch (myLastType)
+  {
+  case BinTools_ObjectType_Reference8:
+    aDelta = uint64_t (myStream->get());
+    myPosition++;
+    break;
+  case BinTools_ObjectType_Reference16:
+  {
+    uint16_t aDelta16 = 0;
+    myStream->read ((char*)&aDelta16, sizeof (uint16_t));
+    myPosition += 2;
+#if DO_INVERSE
+    aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
+      | ((aDelta16 & 0xFF00) >> 8));
+#endif
+    aDelta = uint64_t (aDelta16);
+    break;
+  }
+  case BinTools_ObjectType_Reference32:
+  {
+    uint32_t aDelta32 = 0;
+    myStream->read ((char*)&aDelta32, sizeof (uint32_t));
+    myPosition += 4;
+#if DO_INVERSE
+    aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
+      | ((aDelta32 & 0x0000ff00) << 8)
+      | ((aDelta32 & 0x00ff0000) >> 8)
+      | ((aDelta32 >> 24) & 0x000000ff));
+#endif
+    aDelta = uint64_t (aDelta32);
+    break;
+  }
+  case BinTools_ObjectType_Reference64:
+    myStream->read ((char*)&aDelta, sizeof (uint64_t));
+    myPosition += 8;
+#if DO_INVERSE
+    aDelta = InverseUint64 (aDelta);
+#endif
+    break;
+  default:
+    break;
+  }
+  if (aDelta == 0)
+  {
+    Standard_SStream aMsg;
+    aMsg << "BinTools_IStream::ReadReference: invalid reference " << (char)myLastType << std::endl;
+    throw Standard_Failure (aMsg.str().c_str());
+  }
+  return aCurrentPos - aDelta - 1; // add a type-byte
+}
+
+//=======================================================================
+//function : GoTo
+//purpose  : 
+//=======================================================================
+void BinTools_IStream::GoTo (const uint64_t& thePosition)
+{
+  myStream->seekg (std::streampos (thePosition));
+  myPosition = thePosition;
+}
+
+//=======================================================================
+//function : ShapeType
+//purpose  : 
+//=======================================================================
+TopAbs_ShapeEnum BinTools_IStream::ShapeType()
+{
+  return TopAbs_ShapeEnum ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) >> 2);
+}
+
+//=======================================================================
+//function : ShapeOrientation
+//purpose  : 
+//=======================================================================
+TopAbs_Orientation BinTools_IStream::ShapeOrientation()
+{
+  return TopAbs_Orientation ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) & 3);
+}
+
+//=======================================================================
+//function : operator bool
+//purpose  : 
+//=======================================================================
+BinTools_IStream::operator bool() const
+{
+  return *myStream ? Standard_True : Standard_False;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Real& theValue)
+{
+  if (!myStream->read ((char*)&theValue, sizeof (Standard_Real)))
+    throw Storage_StreamTypeMismatchError();
+  myPosition += sizeof (Standard_Real);
+#if DO_INVERSE
+  theValue = InverseReal (theValue);
+#endif
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Integer& theValue)
+{
+  if (!myStream->read ((char*)&theValue, sizeof (Standard_Integer)))
+    throw Storage_StreamTypeMismatchError();
+  myPosition += sizeof (Standard_Integer);
+#if DO_INVERSE
+  theValue = InverseInt (theValue);
+#endif
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (gp_Pnt& theValue)
+{
+  Standard_Real aValue;
+  for (int aCoord = 1; aCoord <= 3; aCoord++)
+  {
+    if (!myStream->read ((char*)&aValue, sizeof (Standard_Real)))
+      throw Storage_StreamTypeMismatchError();
+#if DO_INVERSE
+    aValue = InverseReal (aValue);
+#endif
+    theValue.SetCoord (aCoord, aValue);
+  }
+  myPosition += 3 * sizeof (Standard_Real);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Byte& theValue)
+{
+  myStream->read ((char*)&theValue, sizeof (Standard_Byte));
+  myPosition += sizeof (Standard_Byte);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_ShortReal& theValue)
+{
+  myStream->read ((char*)&theValue, sizeof (Standard_ShortReal));
+  myPosition += sizeof (Standard_ShortReal);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (gp_Trsf& theValue)
+{
+  Standard_Real aV1[3], aV2[3], aV3[3], aV[3];
+  *this >> aV1[0] >> aV1[1] >> aV1[2] >> aV[0];
+  *this >> aV2[0] >> aV2[1] >> aV2[2] >> aV[1];
+  *this >> aV3[0] >> aV3[1] >> aV3[2] >> aV[2];
+  theValue.SetValues (aV1[0], aV1[1], aV1[2], aV[0],
+                      aV2[0], aV2[1], aV2[2], aV[1],
+                      aV3[0], aV3[1], aV3[2], aV[2]);
+  return *this;
+}
+
+//=======================================================================
+//function : ReadBools
+//purpose  : 
+//=======================================================================
+void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3)
+{
+  Standard_Byte aByte = ReadByte();
+  theBool1 = (aByte & 1) == 1;
+  theBool2 = (aByte & 2) == 2;
+  theBool3 = (aByte & 4) == 4;
+}
+
+//=======================================================================
+//function : ReadBools
+//purpose  : 
+//=======================================================================
+void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3,
+  Standard_Boolean& theBool4, Standard_Boolean& theBool5, Standard_Boolean& theBool6, Standard_Boolean& theBool7)
+{
+  Standard_Byte aByte = ReadByte();
+  theBool1 = (aByte & 1) == 1;
+  theBool2 = (aByte & 2) == 2;
+  theBool3 = (aByte & 4) == 4;
+  theBool4 = (aByte & 8) == 8;
+  theBool5 = (aByte & 16) == 16;
+  theBool6 = (aByte & 32) == 32;
+  theBool7 = (aByte & 64) == 64;
+}
diff --git a/src/BinTools/BinTools_IStream.hxx b/src/BinTools/BinTools_IStream.hxx
new file mode 100644 (file)
index 0000000..ca07699
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright (c) 2021 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 _BinTools_IStream_HeaderFile
+#define _BinTools_IStream_HeaderFile
+
+#include <BinTools.hxx>
+#include <BinTools_ObjectType.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopAbs_Orientation.hxx>
+#include <gp_Pnt.hxx>
+
+//! Substitution of IStream for shape reader for fast management of position in the file (get and go)
+//! and operation on all reading types.
+class BinTools_IStream
+{
+public:
+
+  //! Creates IStream using the current stream IStream.
+  Standard_EXPORT BinTools_IStream (Standard_IStream& theStream);
+
+  //! Reads and returns the type.
+  Standard_EXPORT BinTools_ObjectType ReadType();
+  //! Returns the last read type.
+  Standard_EXPORT const BinTools_ObjectType& LastType() { return myLastType; }
+  //! Returns the shape type by the last retrieved type.
+  Standard_EXPORT TopAbs_ShapeEnum ShapeType();
+  //! Returns the shape orientation by the last retrieved type.
+  Standard_EXPORT TopAbs_Orientation ShapeOrientation();
+
+  //! Returns the current position in the stream.
+  Standard_EXPORT uint64_t Position() { return myPosition; }
+  //! Moves the current stream position to the given one.
+  Standard_EXPORT void GoTo (const uint64_t& thePosition);
+
+  //! Returns true if the last restored type is one of a reference
+  Standard_EXPORT Standard_Boolean IsReference();
+  //! Reads a reference IStream using the last restored type.
+  Standard_EXPORT uint64_t ReadReference();
+  //! Returns the original IStream.
+  Standard_EXPORT Standard_IStream& Stream() { return *myStream; }
+  //! Makes up to date the myPosition because myStream was used outside and position is changed.
+  Standard_EXPORT void UpdatePosition() { myPosition = uint64_t (myStream->tellg()); }
+
+  //! Returns false if stream reading is failed.
+  Standard_EXPORT operator bool() const;
+  //! Reads real value from the stream.
+  Standard_EXPORT Standard_Real ReadReal() { Standard_Real aValue; *this >> aValue; return aValue; }
+  Standard_EXPORT BinTools_IStream& operator >> (Standard_Real& theValue);
+  //! Reads integer value from the stream.
+  Standard_EXPORT Standard_Integer ReadInteger() { Standard_Integer aValue; *this >> aValue; return aValue; }
+  Standard_EXPORT BinTools_IStream& operator >> (Standard_Integer& theValue);
+  //! Reads point coordinates value from the stream.
+  Standard_EXPORT gp_Pnt ReadPnt() { gp_Pnt aValue; *this >> aValue; return aValue; }
+  Standard_EXPORT BinTools_IStream& operator >> (gp_Pnt& theValue);
+  //! Reads byte value from the stream.
+  Standard_EXPORT Standard_Byte ReadByte() { Standard_Byte aValue; *this >> aValue; return aValue; }
+  Standard_EXPORT BinTools_IStream& operator >> (Standard_Byte& theValue);
+  //! Reads boolean value from the stream (stored as one byte).
+  Standard_EXPORT Standard_Boolean ReadBool() { return ReadByte() != 0; }
+  Standard_EXPORT BinTools_IStream& operator >> (Standard_Boolean& theValue) { theValue = ReadByte() != 0; return *this; }
+  //! Reads short real value from the stream.
+  Standard_EXPORT Standard_ShortReal ReadShortReal() { Standard_ShortReal aValue; *this >> aValue; return aValue; }
+  Standard_EXPORT BinTools_IStream& operator >> (Standard_ShortReal& theValue);
+  //! Reads transformation value from the stream.
+  Standard_EXPORT BinTools_IStream& operator >> (gp_Trsf& theValue);
+  //! Reads 3 boolean values from one byte
+  Standard_EXPORT void ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3);
+  //! Reads 7 boolean values from one byte
+  Standard_EXPORT void ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3,
+    Standard_Boolean& theBool4, Standard_Boolean& theBool5, Standard_Boolean& theBool6, Standard_Boolean& theBool7);
+
+
+private:
+  Standard_IStream* myStream; ///< pointer to the stream
+  uint64_t myPosition; ///< equivalent to tellg returned value for fast access
+  BinTools_ObjectType myLastType; ///< last type that was read
+};
+
+#endif // _BinTools_IStream_HeaderFile
index c269197..3f16450 100644 (file)
@@ -57,7 +57,7 @@ static Standard_IStream& operator >>(Standard_IStream& IS, gp_Trsf& T)
 //function : operator << (gp_Trsf& T)
 //purpose  : 
 //=======================================================================
-static Standard_OStream& operator <<(Standard_OStream& OS,const gp_Trsf& T)
+Standard_OStream& operator <<(Standard_OStream& OS,const gp_Trsf& T)
 {
   gp_XYZ V = T.TranslationPart();
   gp_Mat M = T.VectorialPart();
index d28d4ae..b00d598 100644 (file)
@@ -27,6 +27,8 @@
 class Standard_OutOfRange;
 class TopLoc_Location;
 
+//! Operator for writing transformation into the stream
+Standard_OStream& operator << (Standard_OStream& OS, const gp_Trsf& T);
 
 //! The class LocationSet stores a set of location in
 //! a relocatable state.
@@ -68,9 +70,6 @@ public:
   //! is first cleared.
   Standard_EXPORT void Read (Standard_IStream& IS);
 
-
-
-
 protected:
 
 
diff --git a/src/BinTools/BinTools_OStream.cxx b/src/BinTools/BinTools_OStream.cxx
new file mode 100644 (file)
index 0000000..36d7486
--- /dev/null
@@ -0,0 +1,352 @@
+// Copyright (c) 2021 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 <BinTools_OStream.hxx>
+#include <Storage_StreamTypeMismatchError.hxx>
+
+#if DO_INVERSE
+#include <FSD_BinaryFile.hxx>
+#endif
+
+//=======================================================================
+//function : BinTools_OStream
+//purpose  : 
+//=======================================================================
+BinTools_OStream::BinTools_OStream (Standard_OStream& theStream)
+  : myStream (&theStream), myPosition (theStream.tellp())
+{}
+
+//=======================================================================
+//function : WriteReference
+//purpose  : 
+//=======================================================================
+void BinTools_OStream::WriteReference (const uint64_t& thePosition)
+{
+  uint64_t aDelta = myPosition - thePosition;
+  if (aDelta <= 0xFF)
+  {
+    *myStream << (Standard_Byte)BinTools_ObjectType_Reference8;
+    *myStream << (Standard_Byte)aDelta;
+    myPosition += sizeof (Standard_Byte) * 2;
+  }
+  else if (aDelta <= 0xFFFF)
+  {
+    *myStream << (Standard_Byte)BinTools_ObjectType_Reference16;
+    uint16_t aDelta16 = uint16_t (aDelta);
+#if DO_INVERSE
+    aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
+      | ((aDelta16 & 0xFF00) >> 8));
+#endif
+    myStream->write ((char*)&aDelta16, sizeof (uint16_t));
+    myPosition += sizeof (Standard_Byte)  + sizeof (uint16_t);
+  }
+  else if (aDelta <= 0xFFFFFFFF)
+  {
+    *myStream << (Standard_Byte)BinTools_ObjectType_Reference32;
+    uint32_t aDelta32 = uint32_t (aDelta);
+#if DO_INVERSE
+    aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
+      | ((aDelta32 & 0x0000ff00) << 8)
+      | ((aDelta32 & 0x00ff0000) >> 8)
+      | ((aDelta32 >> 24) & 0x000000ff) );
+#endif
+    myStream->write ((char*)&aDelta32, sizeof (uint32_t));
+    myPosition += sizeof (Standard_Byte)  + sizeof (uint32_t);
+  }
+  else
+  {
+    *myStream << (Standard_Byte)BinTools_ObjectType_Reference64;
+#if DO_INVERSE
+    aDelta = FSD_BinaryFile::InverseUint64 (aDelta);
+#endif
+    myStream->write ((char*)&aDelta, sizeof (uint64_t));
+    myPosition += sizeof (Standard_Byte)  + sizeof (uint64_t);
+  }
+}
+
+//=======================================================================
+//function : WriteShape
+//purpose  : 
+//=======================================================================
+void BinTools_OStream::WriteShape (const TopAbs_ShapeEnum& theType, const TopAbs_Orientation& theOrientation)
+{
+  Standard_Byte aType = Standard_Byte (BinTools_ObjectType_EndShape) + 1 +   // taking into account that orientation <= 3
+    (Standard_Byte (theType) << 2) + Standard_Byte (theOrientation); // and type <= 8
+  myStream->put ((Standard_Byte)aType);
+  myPosition += sizeof (Standard_Byte);
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const BinTools_ObjectType& theType)
+{
+  myStream->put ((Standard_Byte)theType);
+  myPosition += sizeof (Standard_Byte);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Byte& theValue)
+{
+  myStream->put (theValue);
+  myPosition += sizeof (Standard_Byte);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Real& theValue)
+{
+#if DO_INVERSE
+  const Standard_Real aRValue = FSD_BinaryFile::InverseReal (theValue);
+  myStream->write ((char*)&aRValue, sizeof (Standard_Real));
+#else
+  myStream->write ((char*)&theValue, sizeof (Standard_Real));
+#endif
+  myPosition += sizeof (Standard_Real);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Boolean& theValue)
+{
+  myStream->put ((Standard_Byte)(theValue ? 1 : 0));
+  myPosition += sizeof (Standard_Byte);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Integer& theValue)
+{
+#if DO_INVERSE
+  const Standard_Integer aRValue = FSD_BinaryFile::InverseInt (theValue);
+  myStream->write ((char*)&aRValue, sizeof (Standard_Integer));
+#else
+  myStream->write ((char*)&theValue, sizeof (Standard_Integer));
+#endif
+  myPosition += sizeof (Standard_Integer);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_ExtCharacter& theValue)
+{
+#if DO_INVERSE
+  const Standard_ExtCharacter aRValue = FSD_BinaryFile::InverseExtChar (theValue);
+  myStream->write ((char*)&aRValue, sizeof (Standard_ExtCharacter));
+#else
+  myStream->write ((char*)&theValue, sizeof (Standard_ExtCharacter));
+#endif
+  myPosition += sizeof (Standard_ExtCharacter);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Pnt& theValue)
+{
+#if DO_INVERSE
+  myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+  myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+  myRealBuf[2] = FSD_BinaryFile::InverseReal (theValue.Z());
+#else
+  myRealBuf[0] = theValue.X();
+  myRealBuf[1] = theValue.Y();
+  myRealBuf[2] = theValue.Z();
+#endif
+  myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 3);
+  myPosition += sizeof (Standard_Real) * 3;
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Dir& theValue)
+{
+#if DO_INVERSE
+  myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+  myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+  myRealBuf[2] = FSD_BinaryFile::InverseReal (theValue.Z());
+#else
+  myRealBuf[0] = theValue.X();
+  myRealBuf[1] = theValue.Y();
+  myRealBuf[2] = theValue.Z();
+#endif
+  myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 3);
+  myPosition += sizeof (Standard_Real) * 3;
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Pnt2d& theValue)
+{
+#if DO_INVERSE
+  myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+  myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+#else
+  myRealBuf[0] = theValue.X();
+  myRealBuf[1] = theValue.Y();
+#endif
+  myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 2);
+  myPosition += sizeof (Standard_Real) * 2;
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Dir2d& theValue)
+{
+#if DO_INVERSE
+  myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+  myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+#else
+  myRealBuf[0] = theValue.X();
+  myRealBuf[1] = theValue.Y();
+#endif
+  myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 2);
+  myPosition += sizeof (Standard_Real) * 2;
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Trsf& theValue)
+{
+  gp_XYZ aTr = theValue.TranslationPart();
+  gp_Mat aMat = theValue.VectorialPart();
+#if DO_INVERSE
+  myRealBuf[0] = FSD_BinaryFile::InverseReal (aMat (1, 1));
+  myRealBuf[1] = FSD_BinaryFile::InverseReal (aMat (1, 2));
+  myRealBuf[2] = FSD_BinaryFile::InverseReal (aMat (1, 3));
+  myRealBuf[3] = FSD_BinaryFile::InverseReal (aTr.Coord (1));
+  myRealBuf[4] = FSD_BinaryFile::InverseReal (aMat (2, 1));
+  myRealBuf[5] = FSD_BinaryFile::InverseReal (aMat (2, 2));
+  myRealBuf[6] = FSD_BinaryFile::InverseReal (aMat (2, 3));
+  myRealBuf[7] = FSD_BinaryFile::InverseReal (aTr.Coord (2));
+  myRealBuf[8] = FSD_BinaryFile::InverseReal (aMat (3, 1));
+  myRealBuf[9] = FSD_BinaryFile::InverseReal (aMat (3, 2));
+  myRealBuf[10] = FSD_BinaryFile::InverseReal (aMat (3, 3));
+  myRealBuf[11] = FSD_BinaryFile::InverseReal (aTr.Coord (3));
+#else
+  myRealBuf[0] = aMat (1, 1);
+  myRealBuf[1] = aMat (1, 2);
+  myRealBuf[2] = aMat (1, 3);
+  myRealBuf[3] = aTr.Coord (1);
+  myRealBuf[4] = aMat (2, 1);
+  myRealBuf[5] = aMat (2, 2);
+  myRealBuf[6] = aMat (2, 3);
+  myRealBuf[7] = aTr.Coord (2);
+  myRealBuf[8] = aMat (3, 1);
+  myRealBuf[9] = aMat (3, 2);
+  myRealBuf[10] = aMat (3, 3);
+  myRealBuf[11] = aTr.Coord (3);
+#endif
+  myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 12);
+  myPosition += sizeof (Standard_Real) * 12;
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Poly_Triangle& theValue)
+{
+  theValue.Value(1);
+#if DO_INVERSE
+  myIntBuf[0] = FSD_BinaryFile::InverseInt (theValue.Value(1));
+  myIntBuf[1] = FSD_BinaryFile::InverseInt (theValue.Value(2));
+  myIntBuf[2] = FSD_BinaryFile::InverseInt (theValue.Value(3));
+#else
+  myIntBuf[0] = theValue.Value(1);
+  myIntBuf[1] = theValue.Value(2);
+  myIntBuf[2] = theValue.Value(3);
+#endif
+  myStream->write ((char*)myIntBuf, sizeof (Standard_Integer) * 3);
+  myPosition += sizeof (Standard_Integer) * 3;
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Vec3f& theValue)
+{
+#if DO_INVERSE
+  myFloatBuf[0] = FSD_BinaryFile::InverseShortReal (theValue.x());
+  myFloatBuf[1] = FSD_BinaryFile::InverseShortReal (theValue.y());
+  myFloatBuf[2] = FSD_BinaryFile::InverseShortReal (theValue.z());
+#else
+  myFloatBuf[0] = theValue.x();
+  myFloatBuf[1] = theValue.y();
+  myFloatBuf[2] = theValue.z();
+#endif
+  myStream->write ((char*)myFloatBuf, sizeof (float) * 3);
+  myPosition += sizeof (float) * 3;
+  return *this;
+}
+
+//=======================================================================
+//function : PutBools
+//purpose  : 
+//=======================================================================
+void BinTools_OStream::PutBools (
+  const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3)
+{
+  Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0);
+  myStream->write((char*)&aValue, sizeof(Standard_Byte));
+  myPosition += sizeof(Standard_Byte);
+}
+
+//=======================================================================
+//function : PutBools
+//purpose  : 
+//=======================================================================
+void BinTools_OStream::PutBools (
+  const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3,
+  const Standard_Boolean theValue4, const Standard_Boolean theValue5, const Standard_Boolean theValue6,
+  const Standard_Boolean theValue7)
+{
+  Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0) | (theValue4 ? 8 : 0) |
+    (theValue5 ? 16 : 0) | (theValue6 ? 32 : 0) | (theValue7 ? 64 : 0);
+  myStream->write((char*)&aValue, sizeof(Standard_Byte));
+  myPosition += sizeof(Standard_Byte);
+}
diff --git a/src/BinTools/BinTools_OStream.hxx b/src/BinTools/BinTools_OStream.hxx
new file mode 100644 (file)
index 0000000..5b2ce39
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright (c) 2021 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 _BinTools_OStream_HeaderFile
+#define _BinTools_OStream_HeaderFile
+
+#include <BinTools.hxx>
+#include <BinTools_ObjectType.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopAbs_Orientation.hxx>
+#include <gp_Pnt.hxx>
+#include <Poly_Triangle.hxx>
+#include <gp_Vec3f.hxx>
+
+//! Substitution of OStream for shape writer for fast management of position in the file
+//! and operation on all writing types.
+class BinTools_OStream
+{
+public:
+
+  //! Creates OStream using the current stream OStream.
+  Standard_EXPORT BinTools_OStream (Standard_OStream& theStream);
+
+  //! Returns the current position of the stream
+  Standard_EXPORT const uint64_t& Position() { return myPosition; }
+  //! Writes the reference to the given position (an offset between the current and the given one).
+  Standard_EXPORT void WriteReference (const uint64_t& thePosition);
+  //! Writes an identifier of shape type and orientation into the stream.
+  Standard_EXPORT void WriteShape (const TopAbs_ShapeEnum& theType, const TopAbs_Orientation& theOrientation);
+
+
+  //! Writes an object type to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const BinTools_ObjectType& theType);
+  //! Writes a byte to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const Standard_Byte& theValue);
+  //! Writes a real to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const Standard_Real& theValue);
+  //! Writes a boolean to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const Standard_Boolean& theValue);
+  //! Writes a integer to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const Standard_Integer& theValue);
+  //! Writes a extended character to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const Standard_ExtCharacter& theValue);
+  //! Writes a 3D point to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const gp_Pnt& theValue);
+  //! Writes a 3D direction to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const gp_Dir& theValue);
+  //! Writes a 2D point to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const gp_Pnt2d& theValue);
+  //! Writes a 2D direction to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const gp_Dir2d& theValue);
+  //! Writes a transformation matrix to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const gp_Trsf& theValue);
+  //! Writes triangle nodes indices to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const Poly_Triangle& theValue);
+  //! Writes a vector to the stream.
+  Standard_EXPORT BinTools_OStream& operator << (const gp_Vec3f& theValue);
+
+  //! Writes 3 booleans as one byte to the stream.
+  Standard_EXPORT void PutBools (
+    const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3);
+
+  //! Writes 7 booleans as one byte to the stream.
+  Standard_EXPORT void PutBools (
+    const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3,
+    const Standard_Boolean theValue4, const Standard_Boolean theValue5, const Standard_Boolean theValue6,
+    const Standard_Boolean theValue7);
+
+private:
+  Standard_OStream* myStream; ///< pointer to the stream
+  uint64_t myPosition; ///< the current position relatively to the OStream position at the moment of creation of this class instance
+  Standard_Real myRealBuf[12]; ///< buffer for 12 reals storage
+  Standard_Integer myIntBuf[3]; ///< buffer for 3 integers storage
+  float myFloatBuf[3]; ///< buffer for 3 floats storage
+};
+
+#endif // _BinTools_OStream_HeaderFile
diff --git a/src/BinTools/BinTools_ObjectType.hxx b/src/BinTools/BinTools_ObjectType.hxx
new file mode 100644 (file)
index 0000000..e8dbe37
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (c) 2021 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 _BinTools_ObjectType_HeaderFile
+#define _BinTools_ObjectType_HeaderFile
+
+//! Enumeration defining objects identifiers in the shape read/write format.
+enum BinTools_ObjectType
+{
+  BinTools_ObjectType_Unknown = 0,
+  BinTools_ObjectType_Reference8,   //!< 8-bits reference
+  BinTools_ObjectType_Reference16,  //!< 16-bits reference
+  BinTools_ObjectType_Reference32,  //!< 32-bits reference
+  BinTools_ObjectType_Reference64,  //!< 64-bits reference
+  BinTools_ObjectType_Location,
+  BinTools_ObjectType_SimpleLocation,
+  BinTools_ObjectType_EmptyLocation,
+  BinTools_ObjectType_LocationEnd,
+  BinTools_ObjectType_Curve,
+  BinTools_ObjectType_EmptyCurve,
+  BinTools_ObjectType_Curve2d,
+  BinTools_ObjectType_EmptyCurve2d,
+  BinTools_ObjectType_Surface,
+  BinTools_ObjectType_EmptySurface,
+  BinTools_ObjectType_Polygon3d,
+  BinTools_ObjectType_EmptyPolygon3d,
+  BinTools_ObjectType_PolygonOnTriangulation,
+  BinTools_ObjectType_EmptyPolygonOnTriangulation,
+  BinTools_ObjectType_Triangulation,
+  BinTools_ObjectType_EmptyTriangulation,
+  BinTools_ObjectType_EmptyShape = 198, //!< identifier of the null shape
+  BinTools_ObjectType_EndShape = 199, //!< identifier of the shape record end
+  // here is the space for TopAbs_ShapeEnum+Orientation types
+};
+
+#endif // _BinTools_ObjectType_HeaderFile
diff --git a/src/BinTools/BinTools_ShapeReader.cxx b/src/BinTools/BinTools_ShapeReader.cxx
new file mode 100644 (file)
index 0000000..bf23f99
--- /dev/null
@@ -0,0 +1,602 @@
+// Copyright (c) 2021 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 <BinTools_ShapeReader.hxx>
+#include <TopoDS.hxx>
+#include <BRep_PointOnCurve.hxx>
+#include <BRep_PointOnCurveOnSurface.hxx>
+#include <BRep_PointOnSurface.hxx>
+#include <BRep_Polygon3D.hxx>
+#include <BRep_Builder.hxx>
+#include <BinTools_CurveSet.hxx>
+#include <BinTools_Curve2dSet.hxx>
+#include <BinTools_SurfaceSet.hxx>
+
+//=======================================================================
+//function : BinTools_ShapeReader
+//purpose  : 
+//=======================================================================
+BinTools_ShapeReader::BinTools_ShapeReader()
+{}
+  
+//=======================================================================
+//function : ~BinTools_ShapeReader
+//purpose  : 
+//=======================================================================
+BinTools_ShapeReader::~BinTools_ShapeReader()
+{}
+
+//=======================================================================
+//function : Clear
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeReader::Clear()
+{
+  BinTools_ShapeSetBase::Clear();
+  myShapePos.Clear();
+  myLocationPos.Clear();
+  myCurvePos.Clear();
+  myCurve2dPos.Clear();
+  mySurfacePos.Clear();
+  myPolygon3dPos.Clear();
+  myPolygonPos.Clear();
+  myTriangulationPos.Clear();
+}
+
+//=======================================================================
+//function : Read
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeReader::Read (Standard_IStream& theStream, TopoDS_Shape& theShape)
+{
+  BinTools_IStream aStream(theStream);
+  theShape = ReadShape(aStream);
+}
+
+//=======================================================================
+//function : ReadShape
+//purpose  : 
+//=======================================================================
+TopoDS_Shape BinTools_ShapeReader::ReadShape (BinTools_IStream& theStream)
+{
+  TopoDS_Shape aResult;
+  uint64_t aPosition = theStream.Position();
+  const BinTools_ObjectType& aType = theStream.ReadType();
+  if (aType == BinTools_ObjectType_EmptyShape || aType == BinTools_ObjectType_EndShape)
+    return aResult;
+
+  if (theStream.IsReference())
+  {
+    uint64_t aRef = theStream.ReadReference();
+    const TopoDS_Shape* aFound = myShapePos.Seek(aRef);
+    if (aFound) // the shape is already retrieved, just add location
+    {
+      aResult = *aFound;
+    }
+    else
+    {
+      uint64_t aCurrent = theStream.Position();
+      theStream.GoTo (aRef); // go to the referenced position
+      aResult = ReadShape (theStream);
+      theStream.GoTo (aCurrent); // returns to the current position
+    }
+    aResult.Location (*ReadLocation (theStream));
+    aResult.Orientation (TopAbs_Orientation (theStream.ReadByte()));
+    return aResult;
+  }
+  // read the shape
+  TopAbs_ShapeEnum aShapeType = theStream.ShapeType();
+  TopAbs_Orientation aShapeOrientation = theStream.ShapeOrientation();
+  const TopLoc_Location* aShapeLocation = ReadLocation (theStream);
+  Standard_Real aTol;
+  static BRep_Builder aBuilder;
+  try {
+    OCC_CATCH_SIGNALS
+      switch (aShapeType) {
+      case TopAbs_VERTEX:
+      {
+        TopoDS_Vertex& aV = TopoDS::Vertex (aResult);
+        // Read the point geometry
+        theStream >> aTol;
+        gp_Pnt aPnt = theStream.ReadPnt();
+        aBuilder.MakeVertex (aV, aPnt, aTol);
+        Handle(BRep_TVertex) aTV = Handle(BRep_TVertex)::DownCast (aV.TShape());
+        BRep_ListOfPointRepresentation& aLpr = aTV->ChangePoints();
+        static TopLoc_Location anEmptyLoc;
+        while (theStream) {
+          Standard_Byte aPrsType = theStream.ReadByte();
+          if (aPrsType == 0) // end of the cycle
+            break;
+          Standard_Real aParam = theStream.ReadReal();
+          Handle(BRep_PointRepresentation) aPR;
+          switch (aPrsType) {
+          case 1:
+          {
+            Handle(Geom_Curve) aCurve = ReadCurve (theStream);
+            if (!aCurve.IsNull())
+              aPR = new BRep_PointOnCurve (aParam, aCurve, anEmptyLoc);
+            break;
+          }
+          case 2:
+          {
+            Handle(Geom2d_Curve) aCurve2d = ReadCurve2d (theStream);
+            Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+            if (!aCurve2d.IsNull() && aSurface.IsNull())
+              aPR = new BRep_PointOnCurveOnSurface (aParam, aCurve2d, aSurface, anEmptyLoc);
+            break;
+          }
+          case 3:
+          {
+            Standard_Real aParam2 = theStream.ReadReal();
+            Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+            if (!aSurface.IsNull())
+              aPR = new BRep_PointOnSurface (aParam, aParam2, aSurface, anEmptyLoc);
+            break;
+          }
+          default:
+          {
+            Standard_SStream aMsg;
+            aMsg << "BinTools_ShapeReader::Read: UnExpected BRep_PointRepresentation = " << aPrsType << std::endl;
+            throw Standard_Failure (aMsg.str().c_str());
+          }
+          }
+          const TopLoc_Location* aPRLoc = ReadLocation (theStream);
+          if (!aPR.IsNull())
+          {
+            aPR->Location (*aPRLoc);
+            aLpr.Append (aPR);
+          }
+        }
+        break;
+      }
+      case TopAbs_EDGE:
+      {
+        TopoDS_Edge& aE = TopoDS::Edge (aResult);
+        aBuilder.MakeEdge(aE);
+        // Read the curve geometry 
+        theStream >> aTol;
+        Standard_Boolean aSameParameter, aSameRange, aDegenerated;
+        theStream.ReadBools (aSameParameter, aSameRange, aDegenerated);
+        aBuilder.SameParameter (aE, aSameParameter);
+        aBuilder.SameRange (aE, aSameRange);
+        aBuilder.Degenerated (aE, aDegenerated);
+        Standard_Real aFirst, aLast;
+        while (theStream) {
+          Standard_Byte aPrsType = theStream.ReadByte(); //{0|1|2|3|4|5|6|7}
+          if (aPrsType == 0)
+            break;
+          switch (aPrsType)
+          {
+          case 1: // -1- Curve 3D
+          {
+            Handle(Geom_Curve) aCurve = ReadCurve (theStream);
+            const TopLoc_Location* aLoc = ReadLocation (theStream);
+            theStream >> aFirst;
+            theStream >> aLast;
+            if (!aCurve.IsNull())
+            {
+              aBuilder.UpdateEdge (aE, aCurve, *aLoc, aTol);
+              aBuilder.Range (aE, aFirst, aLast, Standard_True);
+            }
+            break;
+          }
+          case 2: // -2- Curve on surf
+          case 3: // -3- Curve on closed surf
+          {
+            Standard_Boolean aClosed = (aPrsType == 3);
+            Handle(Geom2d_Curve) aCurve2d_2, aCurve2d_1 = ReadCurve2d (theStream);
+            GeomAbs_Shape aReg = GeomAbs_C0;
+            if (aClosed) {
+              aCurve2d_2 = ReadCurve2d (theStream);
+              aReg = (GeomAbs_Shape)theStream.ReadByte();
+            }
+            Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+            const TopLoc_Location* aLoc = ReadLocation (theStream);
+            // range
+            theStream >> aFirst;
+            theStream >> aLast;
+            if (!aCurve2d_1.IsNull() && (!aClosed || !aCurve2d_2.IsNull()) && !aSurface.IsNull())
+            {
+              if (aClosed)
+              {
+                aBuilder.UpdateEdge (aE, aCurve2d_1, aCurve2d_2, aSurface, *aLoc, aTol);
+                aBuilder.Continuity (aE, aSurface, aSurface, *aLoc, *aLoc, aReg);
+              }
+              else
+                aBuilder.UpdateEdge (aE, aCurve2d_1, aSurface, *aLoc, aTol);
+              aBuilder.Range (aE, aSurface, *aLoc, aFirst, aLast);
+            }
+            break;
+          }
+          case 4: // -4- Regularity
+          {
+            GeomAbs_Shape aReg = (GeomAbs_Shape)theStream.ReadByte();
+            Handle(Geom_Surface) aSurface1 = ReadSurface (theStream);
+            const TopLoc_Location* aLoc1 = ReadLocation (theStream);
+            Handle(Geom_Surface) aSurface2 = ReadSurface (theStream);
+            const TopLoc_Location* aLoc2 = ReadLocation (theStream);
+            if (!aSurface1.IsNull() && !aSurface2.IsNull())
+              aBuilder.Continuity (aE, aSurface1, aSurface2, *aLoc1, *aLoc2, aReg);
+            break;
+          }
+          case 5: // -5- Polygon3D                     
+          {
+            Handle(Poly_Polygon3D) aPolygon = ReadPolygon3d (theStream);
+            const TopLoc_Location* aLoc = ReadLocation (theStream);
+            aBuilder.UpdateEdge (aE, aPolygon, *aLoc);
+            break;
+          }
+          case 6: // -6- Polygon on triangulation
+          case 7: // -7- Polygon on closed triangulation
+          {
+            Standard_Boolean aClosed = (aPrsType == 7);
+            Handle(Poly_PolygonOnTriangulation) aPoly2, aPoly1 = ReadPolygon (theStream);
+            if (aClosed)
+              aPoly2 = ReadPolygon (theStream);
+            Handle(Poly_Triangulation) aTriangulation = ReadTriangulation (theStream);
+            const TopLoc_Location* aLoc = ReadLocation (theStream);
+            if (aClosed)
+              aBuilder.UpdateEdge (aE, aPoly1, aPoly2, aTriangulation, *aLoc);
+            else
+              aBuilder.UpdateEdge (aE, aPoly1, aTriangulation, *aLoc);
+            // range            
+            break;
+          }
+          default:
+          {
+            Standard_SStream aMsg;
+            aMsg << "Unexpected Curve Representation =" << aPrsType << std::endl;
+            throw Standard_Failure (aMsg.str().c_str());
+          }
+
+          }
+        }
+        break;
+      }
+      case TopAbs_WIRE:
+        aBuilder.MakeWire (TopoDS::Wire (aResult));
+        break;
+      case TopAbs_FACE:
+      {
+        TopoDS_Face& aF = TopoDS::Face (aResult);
+        aBuilder.MakeFace (aF);
+        Standard_Boolean aNatRes = theStream.ReadBool();
+        theStream >> aTol;
+        Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+        const TopLoc_Location* aLoc = ReadLocation (theStream);
+        aBuilder.UpdateFace (aF, aSurface, *aLoc, aTol);
+        aBuilder.NaturalRestriction (aF, aNatRes);
+        if (theStream.ReadByte() == 2) // triangulation
+          aBuilder.UpdateFace (aF, ReadTriangulation (theStream));
+        break;
+      }
+      case TopAbs_SHELL:
+        aBuilder.MakeShell (TopoDS::Shell (aResult));
+        break;
+      case TopAbs_SOLID:
+        aBuilder.MakeSolid (TopoDS::Solid (aResult));
+        break;
+      case TopAbs_COMPSOLID:
+        aBuilder.MakeCompSolid (TopoDS::CompSolid (aResult));
+        break;
+      case TopAbs_COMPOUND:
+        aBuilder.MakeCompound (TopoDS::Compound (aResult));
+        break;
+      default:
+      {
+        Standard_SStream aMsg;
+        aMsg << "Unexpected topology type = " << aShapeType << std::endl;
+        throw Standard_Failure (aMsg.str().c_str());
+        break;
+      }
+      }
+  }
+  catch (Standard_Failure const& anException)
+  {
+    Standard_SStream aMsg;
+    aMsg << "EXCEPTION in BinTools_ShapeReader::Read" << std::endl;
+    aMsg << anException << std::endl;
+    throw Standard_Failure (aMsg.str().c_str());
+  }
+  // read flags and subs
+  Standard_Boolean aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv;
+  theStream.ReadBools (aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv);
+  // sub-shapes
+  for(TopoDS_Shape aSub = ReadShape (theStream); !aSub.IsNull(); aSub = ReadShape (theStream))
+    aBuilder.Add (aResult, aSub);
+  aResult.Free (aFree);
+  aResult.Modified (aMod);
+  aResult.Checked (aChecked);
+  aResult.Orientable (anOrient);
+  aResult.Closed (aClosed);
+  aResult.Infinite (anInf);
+  aResult.Convex (aConv);
+  myShapePos.Bind (aPosition, aResult);
+  aResult.Orientation (aShapeOrientation);
+  aResult.Location (*aShapeLocation);
+  return aResult;
+}
+
+//=======================================================================
+//function : ReadLocation
+//purpose  : 
+//=======================================================================
+const TopLoc_Location* BinTools_ShapeReader::ReadLocation (BinTools_IStream& theStream)
+{
+  static const TopLoc_Location* anEmptyLoc = new TopLoc_Location;
+
+  uint64_t aPosition = theStream.Position();
+  const BinTools_ObjectType& aType = theStream.ReadType();
+  if (aType == BinTools_ObjectType_EmptyLocation || aType == BinTools_ObjectType_LocationEnd)
+    return anEmptyLoc;
+  if (theStream.IsReference())
+  {
+    uint64_t aRef = theStream.ReadReference();
+    const TopLoc_Location* aFound = myLocationPos.Seek (aRef);
+    if (aFound) // the location is already retrieved
+      return aFound;
+    uint64_t aCurrent = theStream.Position();
+    theStream.GoTo (aRef); // go to the referenced position
+    const TopLoc_Location* aResult = ReadLocation (theStream);
+    theStream.GoTo (aCurrent); // returns to the current position
+    return aResult;
+  }
+  // read the location directly from the stream
+  TopLoc_Location aLoc;
+  if (aType == BinTools_ObjectType_SimpleLocation)
+  {
+    gp_Trsf aTrsf;
+    theStream >> aTrsf;
+    aLoc = aTrsf;
+  }
+  else if (aType == BinTools_ObjectType_Location)
+  {
+    for(const TopLoc_Location* aNextLoc = ReadLocation (theStream); !aNextLoc->IsIdentity();
+                               aNextLoc = ReadLocation (theStream))
+      aLoc = aNextLoc->Powered (theStream.ReadInteger()) * aLoc;
+  }
+  myLocationPos.Bind (aPosition, aLoc);
+  return myLocationPos.Seek (aPosition);
+}
+
+//=======================================================================
+//function : ReadCurve
+//purpose  : 
+//=======================================================================
+Handle(Geom_Curve) BinTools_ShapeReader::ReadCurve (BinTools_IStream& theStream)
+{
+  Handle(Geom_Curve) aResult;
+  uint64_t aPosition = theStream.Position();
+  theStream.ReadType();
+  if (theStream.IsReference())
+  { // get by reference
+    uint64_t aRef = theStream.ReadReference();
+    const Handle(Geom_Curve)* aFound = myCurvePos.Seek (aRef);
+    if (aFound) // the location is already retrieved
+      return *aFound;
+    uint64_t aCurrent = theStream.Position();
+    theStream.GoTo (aRef); // go to the referenced position
+    aResult = ReadCurve (theStream);
+    theStream.GoTo (aCurrent); // returns to the current position
+  }
+  else if (theStream.LastType() == BinTools_ObjectType_Curve)
+  { // read from the stream
+    BinTools_CurveSet::ReadCurve (theStream.Stream(), aResult);
+    theStream.UpdatePosition();
+    myCurvePos.Bind (aPosition, aResult);
+  }
+  return aResult;
+}
+
+//=======================================================================
+//function : ReadCurve2d
+//purpose  : 
+//=======================================================================
+Handle(Geom2d_Curve) BinTools_ShapeReader::ReadCurve2d (BinTools_IStream& theStream)
+{
+  Handle(Geom2d_Curve) aResult;
+  uint64_t aPosition = theStream.Position();
+  theStream.ReadType();
+  if (theStream.IsReference())
+  { // get by reference
+    uint64_t aRef = theStream.ReadReference();
+    const Handle(Geom2d_Curve)* aFound = myCurve2dPos.Seek (aRef);
+    if (aFound) // the location is already retrieved
+      return *aFound;
+    uint64_t aCurrent = theStream.Position();
+    theStream.GoTo (aRef); // go to the referenced position
+    aResult = ReadCurve2d (theStream);
+    theStream.GoTo (aCurrent); // returns to the current position
+  }
+  else if (theStream.LastType() == BinTools_ObjectType_Curve2d)
+  { // read from the stream
+    BinTools_Curve2dSet::ReadCurve2d (theStream.Stream(), aResult);
+    theStream.UpdatePosition();
+    myCurve2dPos.Bind (aPosition, aResult);
+  }
+  return aResult;
+}
+
+//=======================================================================
+//function : ReadSurface
+//purpose  : 
+//=======================================================================
+Handle(Geom_Surface) BinTools_ShapeReader::ReadSurface (BinTools_IStream& theStream)
+{
+  Handle(Geom_Surface) aResult;
+  uint64_t aPosition = theStream.Position();
+  theStream.ReadType();
+  if (theStream.IsReference())
+  { // get by reference
+    uint64_t aRef = theStream.ReadReference();
+    const Handle(Geom_Surface)* aFound = mySurfacePos.Seek (aRef);
+    if (aFound) // the location is already retrieved
+      return *aFound;
+    uint64_t aCurrent = theStream.Position();
+    theStream.GoTo (aRef); // go to the referenced position
+    aResult = ReadSurface (theStream);
+    theStream.GoTo (aCurrent); // returns to the current position
+  }
+  else if (theStream.LastType() == BinTools_ObjectType_Surface)
+  { // read from the stream
+    BinTools_SurfaceSet::ReadSurface (theStream.Stream(), aResult);
+    theStream.UpdatePosition();
+    mySurfacePos.Bind (aPosition, aResult);
+  }
+  return aResult;
+}
+
+//=======================================================================
+//function : ReadPolygon3d
+//purpose  : 
+//=======================================================================
+Handle(Poly_Polygon3D) BinTools_ShapeReader::ReadPolygon3d (BinTools_IStream& theStream)
+{
+  Handle(Poly_Polygon3D) aResult;
+  uint64_t aPosition = theStream.Position();
+  theStream.ReadType();
+  if (theStream.IsReference())
+  { // get by reference
+    uint64_t aRef = theStream.ReadReference();
+    const Handle(Poly_Polygon3D)* aFound = myPolygon3dPos.Seek (aRef);
+    if (aFound) // the location is already retrieved
+      return *aFound;
+    uint64_t aCurrent = theStream.Position();
+    theStream.GoTo (aRef); // go to the referenced position
+    aResult = ReadPolygon3d (theStream);
+    theStream.GoTo (aCurrent); // returns to the current position
+  }
+  else if (theStream.LastType() == BinTools_ObjectType_Polygon3d)
+  { // read from the stream
+    Standard_Integer aNbNodes = theStream.ReadInteger();
+    Standard_Boolean aHasParameters = theStream.ReadBool();
+    aResult = new Poly_Polygon3D (aNbNodes, aHasParameters);
+    aResult->Deflection (theStream.ReadReal());
+    TColgp_Array1OfPnt& aNodes = aResult->ChangeNodes();
+    for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+      theStream >> aNodes.ChangeValue (aNodeIter);
+    if (aHasParameters)
+    {
+      TColStd_Array1OfReal& aParam = aResult->ChangeParameters();
+      for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+        theStream >> aParam.ChangeValue (aNodeIter);
+    }
+    myPolygon3dPos.Bind (aPosition, aResult);
+  }
+  return aResult;
+}
+
+//=======================================================================
+//function : ReadPolygon
+//purpose  : 
+//=======================================================================
+Handle(Poly_PolygonOnTriangulation) BinTools_ShapeReader::ReadPolygon (BinTools_IStream& theStream)
+{
+  Handle(Poly_PolygonOnTriangulation) aResult;
+  uint64_t aPosition = theStream.Position();
+  theStream.ReadType();
+  if (theStream.IsReference())
+  { // get by reference
+    uint64_t aRef = theStream.ReadReference();
+    const Handle(Poly_PolygonOnTriangulation)* aFound = myPolygonPos.Seek (aRef);
+    if (aFound) // the location is already retrieved
+      return *aFound;
+    uint64_t aCurrent = theStream.Position();
+    theStream.GoTo (aRef); // go to the referenced position
+    aResult = ReadPolygon (theStream);
+    theStream.GoTo (aCurrent); // returns to the current position
+  }
+  else if (theStream.LastType() == BinTools_ObjectType_PolygonOnTriangulation)
+  { // read from the stream
+    Standard_Integer aNbNodes = theStream.ReadInteger();
+    aResult = new Poly_PolygonOnTriangulation (aNbNodes, Standard_False);
+    for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+      aResult->SetNode(aNodeIter, theStream.ReadInteger());
+    aResult->Deflection (theStream.ReadReal());
+    if (theStream.ReadBool())
+    {
+      Handle(TColStd_HArray1OfReal) aParams = new TColStd_HArray1OfReal (1, aNbNodes);
+      for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+        theStream >> aParams->ChangeValue (aNodeIter);
+      aResult->SetParameters (aParams);
+    }
+    myPolygonPos.Bind (aPosition, aResult);
+  }
+  return aResult;
+}
+
+//=======================================================================
+//function : ReadTriangulation
+//purpose  : 
+//=======================================================================
+Handle(Poly_Triangulation) BinTools_ShapeReader::ReadTriangulation (BinTools_IStream& theStream)
+{
+  Handle(Poly_Triangulation) aResult;
+  uint64_t aPosition = theStream.Position();
+  const BinTools_ObjectType& aType = theStream.ReadType();
+  if (theStream.IsReference())
+  { // get by reference
+    uint64_t aRef = theStream.ReadReference();
+    const Handle(Poly_Triangulation)* aFound = myTriangulationPos.Seek (aRef);
+    if (aFound) // the location is already retrieved
+      return *aFound;
+    uint64_t aCurrent = theStream.Position();
+    theStream.GoTo (aRef); // go to the referenced position
+    aResult = ReadTriangulation (theStream);
+    theStream.GoTo (aCurrent); // returns to the current position
+  }
+  else if (aType == BinTools_ObjectType_Triangulation)
+  { // read from the stream
+    Standard_Integer aNbNodes = theStream.ReadInteger();
+    Standard_Integer aNbTriangles = theStream.ReadInteger();
+    Standard_Boolean aHasUV = theStream.ReadBool();
+    Standard_Boolean aHasNormals = theStream.ReadBool();
+    aResult = new Poly_Triangulation (aNbNodes, aNbTriangles, aHasUV, aHasNormals);
+    aResult->Deflection (theStream.ReadReal());
+    for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+      aResult->SetNode(aNodeIter, theStream.ReadPnt());
+    if (aHasUV)
+    {
+      gp_Pnt2d anUV;
+      for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+      {
+        theStream >> anUV.ChangeCoord().ChangeCoord (1);
+        theStream >> anUV.ChangeCoord().ChangeCoord (2);
+        aResult->SetUVNode(aNodeIter, anUV);
+      }
+    }
+    // read the triangles
+    Poly_Triangle aTriangle;
+    for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
+    {
+      theStream >> aTriangle.ChangeValue (1);
+      theStream >> aTriangle.ChangeValue (2);
+      theStream >> aTriangle.ChangeValue (3);
+      aResult->SetTriangle(aTriIter, aTriangle);
+    }
+    if (aHasNormals)
+    {
+      gp_Vec3f aNormal;
+      for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes; ++aNormalIter)
+      {
+        theStream >> aNormal.x();
+        theStream >> aNormal.y();
+        theStream >> aNormal.z();
+        aResult->SetNormal (aNormalIter, aNormal);
+      }
+    }
+
+    myTriangulationPos.Bind (aPosition, aResult);
+  }
+  return aResult;
+}
diff --git a/src/BinTools/BinTools_ShapeReader.hxx b/src/BinTools/BinTools_ShapeReader.hxx
new file mode 100644 (file)
index 0000000..190d8a9
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright (c) 2021 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 _BinTools_ShapeReader_HeaderFile
+#define _BinTools_ShapeReader_HeaderFile
+
+#include <BinTools_ShapeSetBase.hxx>
+#include <BinTools_IStream.hxx>
+#include <NCollection_DataMap.hxx>
+
+class TopLoc_Location;
+class Geom_Curve;
+class Geom2d_Curve;
+class Geom_Surface;
+class Poly_Polygon3D;
+class Poly_PolygonOnTriangulation;
+class Poly_Triangulation;
+
+//! Reads topology from IStream in binary format without grouping of objects by types
+//! and using relative positions in a file as references.
+class BinTools_ShapeReader : public BinTools_ShapeSetBase
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+  
+  //! Initializes a shape reader.
+  Standard_EXPORT BinTools_ShapeReader();
+  
+  Standard_EXPORT virtual ~BinTools_ShapeReader();
+
+  //! Clears the content of the set.
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+  
+  //! Reads the shape from stream using previously restored shapes and objects by references.
+  Standard_EXPORT void Read (Standard_IStream& theStream, TopoDS_Shape& theShape) Standard_OVERRIDE;
+
+  //! Reads location from the stream.
+  Standard_EXPORT const TopLoc_Location* ReadLocation (BinTools_IStream& theStream);
+
+private:
+  //! Reads the shape from stream using previously restored shapes and objects by references.
+  TopoDS_Shape ReadShape (BinTools_IStream& theStream);
+  //! Reads curve from the stream.
+  Handle(Geom_Curve) ReadCurve (BinTools_IStream& theStream);
+  //! Reads curve2d from the stream.
+  Handle(Geom2d_Curve) ReadCurve2d (BinTools_IStream& theStream);
+  //! Reads surface from the stream.
+  Handle(Geom_Surface) ReadSurface (BinTools_IStream& theStream);
+  //! Reads ploygon3d from the stream.
+  Handle(Poly_Polygon3D) ReadPolygon3d (BinTools_IStream& theStream);
+  //! Reads polygon on triangulation from the stream.
+  Handle(Poly_PolygonOnTriangulation) ReadPolygon (BinTools_IStream& theStream);
+  //! Reads triangulation from the stream.
+  Handle(Poly_Triangulation) ReadTriangulation (BinTools_IStream& theStream);
+
+  /// position of the shape previously restored
+  NCollection_DataMap<uint64_t, TopoDS_Shape> myShapePos;
+  NCollection_DataMap<uint64_t, TopLoc_Location> myLocationPos;
+  NCollection_DataMap<uint64_t, Handle(Geom_Curve)> myCurvePos;
+  NCollection_DataMap<uint64_t, Handle(Geom2d_Curve)> myCurve2dPos;
+  NCollection_DataMap<uint64_t, Handle(Geom_Surface)> mySurfacePos;
+  NCollection_DataMap<uint64_t, Handle(Poly_Polygon3D)> myPolygon3dPos;
+  NCollection_DataMap<uint64_t, Handle(Poly_PolygonOnTriangulation)> myPolygonPos;
+  NCollection_DataMap<uint64_t, Handle(Poly_Triangulation)> myTriangulationPos;
+};
+
+#endif // _BinTools_ShapeReader_HeaderFile
index 718f4b8..19f4a7b 100644 (file)
 #include <Message_ProgressRange.hxx>
 
 #include <string.h>
-//#define MDTV_DEB 1
 
-const Standard_CString BinTools_ShapeSet::THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1] =
-{
-  "",
-  "Open CASCADE Topology V1 (c)",
-  "Open CASCADE Topology V2 (c)",
-  "Open CASCADE Topology V3 (c)",
-  "Open CASCADE Topology V4, (c) Open Cascade"
-};
-
-//=======================================================================
-//function : operator << (gp_Pnt)
-//purpose  : 
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt P)
-{
-  BinTools::PutReal(OS, P.X());
-  BinTools::PutReal(OS, P.Y());
-  BinTools::PutReal(OS, P.Z());
-  return OS;
-}
 //=======================================================================
 //function : BinTools_ShapeSet
 //purpose  :
 //=======================================================================
 BinTools_ShapeSet::BinTools_ShapeSet ()
-: myFormatNb (BinTools_FormatVersion_CURRENT),
-  myWithTriangles (Standard_False),
-  myWithNormals(Standard_False)
+  : BinTools_ShapeSetBase ()
 {}
 
 //=======================================================================
@@ -95,28 +71,6 @@ BinTools_ShapeSet::BinTools_ShapeSet ()
 BinTools_ShapeSet::~BinTools_ShapeSet()
 {}
 
-//=======================================================================
-//function : SetFormatNb
-//purpose  : 
-//=======================================================================
-void BinTools_ShapeSet::SetFormatNb(const Standard_Integer theFormatNb)
-{
-  Standard_ASSERT_RETURN(theFormatNb >= BinTools_FormatVersion_LOWER &&
-                         theFormatNb <= BinTools_FormatVersion_UPPER,
-    "Error: unsupported BinTools version.", );
-
-  myFormatNb = theFormatNb;
-}
-
-//=======================================================================
-//function : FormatNb
-//purpose  : 
-//=======================================================================
-Standard_Integer BinTools_ShapeSet::FormatNb() const
-{
-  return myFormatNb;
-}
-
 //=======================================================================
 //function : Clear
 //purpose  : 
@@ -139,18 +93,18 @@ void  BinTools_ShapeSet::Clear()
 //purpose  : 
 //=======================================================================
 
-Standard_Integer  BinTools_ShapeSet::Add(const TopoDS_Shape& theShape)
+Standard_Integer BinTools_ShapeSet::Add (const TopoDS_Shape& theShape)
 {
   if (theShape.IsNull()) return 0;
   myLocations.Add(theShape.Location());
   TopoDS_Shape aS2 = theShape;
-  aS2.Location(TopLoc_Location());
-  Standard_Integer anIndex = myShapes.FindIndex(aS2);
+  aS2.Location (TopLoc_Location());
+  Standard_Integer anIndex = myShapes.FindIndex (aS2);
   if (anIndex == 0) {
-    AddGeometry(aS2);
-    for (TopoDS_Iterator its(aS2,Standard_False,Standard_False);its.More(); its.Next())
-      Add(its.Value());
-    anIndex = myShapes.Add(aS2);
+    AddShape  (aS2);
+    for (TopoDS_Iterator its (aS2, Standard_False, Standard_False); its.More(); its.Next())
+      Add (its.Value());
+    anIndex = myShapes.Add (aS2);
   }
   return anIndex;
 }
@@ -161,9 +115,9 @@ Standard_Integer  BinTools_ShapeSet::Add(const TopoDS_Shape& theShape)
 //purpose  : 
 //=======================================================================
 
-const TopoDS_Shape&  BinTools_ShapeSet::Shape(const Standard_Integer theIndx)const 
+const TopoDS_Shape& BinTools_ShapeSet::Shape (const Standard_Integer theIndx)
 {
-  return myShapes(theIndx);
+  return myShapes (theIndx);
 }
 
 //=======================================================================
@@ -171,9 +125,9 @@ const TopoDS_Shape&  BinTools_ShapeSet::Shape(const Standard_Integer theIndx)con
 //purpose  : 
 //=======================================================================
 
-Standard_Integer BinTools_ShapeSet::Index(const TopoDS_Shape& theShape) const
+Standard_Integer BinTools_ShapeSet::Index (const TopoDS_Shape& theShape) const
 {
-  return myShapes.FindIndex(theShape);
+  return myShapes.FindIndex (theShape);
 }
 
 //=======================================================================
@@ -181,7 +135,7 @@ Standard_Integer BinTools_ShapeSet::Index(const TopoDS_Shape& theShape) const
 //purpose  : 
 //=======================================================================
 
-const BinTools_LocationSet&  BinTools_ShapeSet::Locations()const 
+const BinTools_LocationSet&  BinTools_ShapeSet::Locations() const 
 {
   return myLocations;
 }
@@ -202,7 +156,7 @@ BinTools_LocationSet&  BinTools_ShapeSet::ChangeLocations()
 //purpose  : 
 //=======================================================================
 
-void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
+void BinTools_ShapeSet::AddShape (const TopoDS_Shape& S)
 {
   // Add the geometry
   
@@ -259,7 +213,7 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
         mySurfaces.Add(CR->Surface2());
         ChangeLocations().Add(CR->Location2());
       }
-      else if (myWithTriangles) { 
+      else if (IsWithTriangles()) { 
         if (CR->IsPolygon3D()) {
           if (!CR->Polygon3D().IsNull()) {
             myPolygons3D.Add(CR->Polygon3D());
@@ -292,7 +246,7 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
   else if (S.ShapeType() == TopAbs_FACE) {
 
     // Add the surface geometry
-    Standard_Boolean needNormals(myWithNormals);
+    Standard_Boolean needNormals (IsWithNormals());
     Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
     if (!TF->Surface().IsNull())
     {
@@ -302,8 +256,7 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
     {
       needNormals = Standard_True;
     }
-    if (myWithTriangles
-     || TF->Surface().IsNull())
+    if (IsWithTriangles() || TF->Surface().IsNull())
     {
       Handle(Poly_Triangulation) Tr = TF->Triangulation();
       if (!Tr.IsNull()) myTriangulations.Add(Tr, needNormals);
@@ -346,10 +299,10 @@ void  BinTools_ShapeSet::WriteGeometry (Standard_OStream& OS,
 //=======================================================================
 
 void  BinTools_ShapeSet::Write (Standard_OStream& OS,
-                                const Message_ProgressRange& theRange)const
+                                const Message_ProgressRange& theRange)
 {
   // write the copyright
-  OS << "\n" << THE_ASCII_VERSIONS[myFormatNb] << "\n";
+  OS << "\n" << THE_ASCII_VERSIONS[FormatNb()] << "\n";
 
   //-----------------------------------------
   // write the locations
@@ -378,13 +331,13 @@ void  BinTools_ShapeSet::Write (Standard_OStream& OS,
   // subshapes are written first
   for (i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next()) {
 
-    const TopoDS_Shape& S = myShapes(i);
+    const TopoDS_Shape& S = myShapes (i);
     
     // Type
     OS << (Standard_Byte)S.ShapeType();
 
     // Geometry
-    WriteGeometry(S,OS);
+    WriteShape (S, OS);
 
     // Flags
     BinTools::PutBool(OS, S.Free()? 1:0);
@@ -410,11 +363,9 @@ void  BinTools_ShapeSet::Write (Standard_OStream& OS,
 //function : Read
 //purpose  : 
 //=======================================================================
-
 void  BinTools_ShapeSet::Read (Standard_IStream& IS,
                                const Message_ProgressRange& theRange)
 {
-
   Clear();
 
   // Check the version
@@ -454,7 +405,6 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
   //-----------------------------------------
   // read the locations
   //-----------------------------------------
-
   myLocations.Read(IS);
   //-----------------------------------------
   // read the geometry
@@ -479,54 +429,13 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
   IS >> nbShapes;
   IS.get();//remove lf 
   Message_ProgressScope aPSinner(aPSouter.Next(), "Reading Shapes", nbShapes);
-  for (int i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next()) {
-
+  for (int i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next())
+  {
     TopoDS_Shape S;
-    
-    //Read type and create empty shape.
-
-    TopAbs_ShapeEnum T = (TopAbs_ShapeEnum) IS.get();
-
-    ReadGeometry(T,IS,S);
-    
-    // Set the flags
-    Standard_Boolean aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv;
-    BinTools::GetBool(IS, aFree);
-    BinTools::GetBool(IS, aMod);
-    BinTools::GetBool(IS, aChecked);
-    BinTools::GetBool(IS, anOrient);
-    BinTools::GetBool(IS, aClosed);
-    BinTools::GetBool(IS, anInf);
-    BinTools::GetBool(IS, aConv);
-
-    // sub-shapes
-    TopoDS_Shape SS;
-    do {
-      Read(SS,IS,nbShapes);
-      if (!SS.IsNull())
-       AddShapes(S,SS);
-    } while(!SS.IsNull());
-
-    S.Free(aFree);
-    S.Modified(aMod);
-    if (myFormatNb != BinTools_FormatVersion_VERSION_2
-     && myFormatNb != BinTools_FormatVersion_VERSION_3)
-    {
-      aChecked = false; // force check at reading
-    }
-    S.Checked (aChecked);
-    S.Orientable(anOrient);
-    S.Closed    (aClosed);
-    S.Infinite  (anInf);
-    S.Convex    (aConv);
-    // check
-
-    if (myFormatNb == BinTools_FormatVersion_VERSION_1)
-      if(T == TopAbs_FACE) {
-       const TopoDS_Face& F = TopoDS::Face(S);
-       BRepTools::Update(F);
-      }
-    myShapes.Add(S);
+    TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
+    ReadShape (T, IS, S);
+    ReadFlagsAndSubs (S, T, IS, nbShapes);
+    myShapes.Add (S);
   }
 }
 
@@ -536,7 +445,7 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
 //=======================================================================
 
 void  BinTools_ShapeSet::Write (const TopoDS_Shape& S, 
-                                Standard_OStream& OS)const
+                                Standard_OStream& OS)
 {
   if (S.IsNull()) 
 
@@ -544,29 +453,75 @@ void  BinTools_ShapeSet::Write (const TopoDS_Shape& S,
   else {    
 // {TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL} 
     OS << (Standard_Byte) S.Orientation();
-    BinTools::PutInteger(OS, myShapes.Extent() - myShapes.FindIndex(S.Located(TopLoc_Location())) + 1);
-    BinTools::PutInteger(OS, Locations().Index(S.Location()));
+    BinTools::PutInteger (OS, myShapes.Extent() - myShapes.FindIndex (S.Located (TopLoc_Location())) + 1);
+    BinTools::PutInteger (OS, Locations().Index (S.Location()));
   }    
 }
 
 //=======================================================================
-//function : Read
+//function : ReadFlagsAndSubs
 //purpose  : 
 //=======================================================================
 
-void  BinTools_ShapeSet::Read (TopoDS_Shape& S, Standard_IStream& IS,
-                               const Standard_Integer nbshapes)const 
+void BinTools_ShapeSet::ReadFlagsAndSubs(TopoDS_Shape& S, const TopAbs_ShapeEnum T,
+  Standard_IStream& IS, const Standard_Integer nbShapes)
+{
+  // Set the flags
+  Standard_Boolean aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv;
+  BinTools::GetBool(IS, aFree);
+  BinTools::GetBool(IS, aMod);
+  BinTools::GetBool(IS, aChecked);
+  BinTools::GetBool(IS, anOrient);
+  BinTools::GetBool(IS, aClosed);
+  BinTools::GetBool(IS, anInf);
+  BinTools::GetBool(IS, aConv);
+
+  // sub-shapes
+  TopoDS_Shape SS;
+  do {
+    ReadSubs(SS, IS, nbShapes);
+    if (!SS.IsNull())
+      AddShapes(S, SS);
+  } while (!SS.IsNull());
+
+  S.Free(aFree);
+  S.Modified(aMod);
+  if (FormatNb() != BinTools_FormatVersion_VERSION_2 &&
+      FormatNb() != BinTools_FormatVersion_VERSION_3)
+  {
+    aChecked = false; // force check at reading
+  }
+  S.Checked (aChecked);
+  S.Orientable (anOrient);
+  S.Closed (aClosed);
+  S.Infinite (anInf);
+  S.Convex (aConv);
+  // check
+
+  if (FormatNb() == BinTools_FormatVersion_VERSION_1)
+    if (T == TopAbs_FACE) {
+      const TopoDS_Face& F = TopoDS::Face(S);
+      BRepTools::Update(F);
+    }
+}
+
+//=======================================================================
+//function : ReadSubs
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeSet::ReadSubs(TopoDS_Shape& S, Standard_IStream& IS,
+                                 const Standard_Integer nbshapes)
 {
   Standard_Character aChar = '\0';
   IS >> aChar;
-  if(aChar == '*')
+  if (aChar == '*')
     S = TopoDS_Shape();
   else {
     TopAbs_Orientation anOrient;
     anOrient = (TopAbs_Orientation)aChar;
     Standard_Integer anIndx;
     BinTools::GetInteger(IS, anIndx);
-    S = myShapes(nbshapes - anIndx + 1);
+    S = Shape (nbshapes - anIndx + 1);
     S.Orientation(anOrient);
 
     Standard_Integer l;
@@ -580,25 +535,31 @@ void  BinTools_ShapeSet::Read (TopoDS_Shape& S, Standard_IStream& IS,
 //purpose  : 
 //=======================================================================
 
-void  BinTools_ShapeSet::ReadGeometry (Standard_IStream& IS,
-                                       const Message_ProgressRange& theRange)
+void BinTools_ShapeSet::ReadGeometry (Standard_IStream& IS,
+                                      const Message_ProgressRange& theRange)
 {
-  Message_ProgressScope aPS(theRange, "Reading geomentry", 6);
+
+  Message_ProgressScope aPS(theRange, "Reading geometry", 6);
   myCurves2d.Read(IS, aPS.Next());
   if (!aPS.More())
     return;
+
   myCurves.Read(IS, aPS.Next());
   if (!aPS.More())
     return;
+
   ReadPolygon3D(IS, aPS.Next());
   if (!aPS.More())
     return;
+
   ReadPolygonOnTriangulation(IS, aPS.Next());
   if (!aPS.More())
     return;
+
   mySurfaces.Read(IS, aPS.Next());
   if (!aPS.More())
     return;
+
   ReadTriangulation(IS, aPS.Next());
 }
 
@@ -607,8 +568,8 @@ void  BinTools_ShapeSet::ReadGeometry (Standard_IStream& IS,
 //purpose  : 
 //=======================================================================
 
-void  BinTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S, 
-                                        Standard_OStream&   OS)const 
+void BinTools_ShapeSet::WriteShape (const TopoDS_Shape& S, 
+                                    Standard_OStream&   OS) const 
 {
 // Write the geometry
   try {
@@ -714,8 +675,8 @@ void  BinTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S,
          BinTools::PutReal(OS, last);
 
         // Write UV Points for higher performance
-         if (myFormatNb == BinTools_FormatVersion_VERSION_2
-          || myFormatNb == BinTools_FormatVersion_VERSION_3)
+         if (FormatNb() == BinTools_FormatVersion_VERSION_2
+          || FormatNb() == BinTools_FormatVersion_VERSION_3)
            {
              gp_Pnt2d Pf,Pl;
              if (CR->IsCurveOnClosedSurface()) {
@@ -743,7 +704,7 @@ void  BinTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S,
          
        }
 
-       else if (myWithTriangles) { 
+       else if (IsWithTriangles()) { 
          if (CR->IsPolygon3D()) {
            Handle(BRep_Polygon3D) GC = Handle(BRep_Polygon3D)::DownCast(itrc.Value());
            if (!GC->Polygon3D().IsNull()) {
@@ -793,8 +754,7 @@ void  BinTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S,
                                : 0);
       BinTools::PutInteger (OS, Locations().Index (TF->Location()));
 
-      if (myWithTriangles
-       || TF->Surface().IsNull())
+      if (IsWithTriangles() || TF->Surface().IsNull())
       {
        if (!(TF->Triangulation()).IsNull()) {
          OS << (Standard_Byte) 2;
@@ -815,308 +775,307 @@ void  BinTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S,
 }
 
 //=======================================================================
-//function : ReadGeometry
+//function : ReadShape
 //purpose  : 
 //=======================================================================
 
-void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T, 
-                                       Standard_IStream&      IS, 
-                                       TopoDS_Shape&          S)
+void  BinTools_ShapeSet::ReadShape (const TopAbs_ShapeEnum T,
+                                    Standard_IStream&      IS,
+                                    TopoDS_Shape&          S)
 {
   // Read the geometry
 
-  Standard_Integer val, c,pc,pc2 = 0,s,s2,l,l2,t, pt, pt2 = 0;
-  Standard_Real tol,X,Y,Z,first,last,p1 = 0.,p2;
-  Standard_Real PfX,PfY,PlX,PlY;
+  Standard_Integer val, c, pc, pc2 = 0, s, s2, l, l2, t, pt, pt2 = 0;
+  Standard_Real tol, X, Y, Z, first, last, p1 = 0., p2;
+  Standard_Real PfX, PfY, PlX, PlY;
   gp_Pnt2d aPf, aPl;
   Standard_Boolean closed, bval;
   GeomAbs_Shape reg = GeomAbs_C0;
   try {
     OCC_CATCH_SIGNALS
-    switch (T) {
+      switch (T) {
 
 
-    //---------
-    // vertex
-    //---------
+        //---------
+        // vertex
+        //---------
 
-    case TopAbs_VERTEX :
+      case TopAbs_VERTEX:
       {
-//       Standard_Integer aPos = IS.tellg();      
-//       std::cout << "\nPOS = " << aPos << std::endl;
-       TopoDS_Vertex& V = TopoDS::Vertex(S);
-
-      // Read the point geometry
-       BinTools::GetReal(IS, tol);
-       BinTools::GetReal(IS, X);
-       BinTools::GetReal(IS, Y);
-       BinTools::GetReal(IS, Z);
-       gp_Pnt aPnt (X, Y, Z);
-       myBuilder.MakeVertex (V, aPnt, tol);
-       Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V.TShape());
-
-       BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
-       TopLoc_Location L;
-       do {
-         if(myFormatNb == BinTools_FormatVersion_VERSION_3) {
-           val = (Standard_Integer)IS.get();//case {0|1|2|3}
-           if (val > 0 && val <= 3) 
-             BinTools::GetReal(IS, p1); 
-         } else {
-        std::streampos aPos = IS.tellg();
-           BinTools::GetReal(IS, p1);      
-           val = (Standard_Integer)IS.get();//case {0|1|2|3}
+        TopoDS_Vertex& V = TopoDS::Vertex(S);
+
+        // Read the point geometry
+        BinTools::GetReal(IS, tol);
+        BinTools::GetReal(IS, X);
+        BinTools::GetReal(IS, Y);
+        BinTools::GetReal(IS, Z);
+        gp_Pnt aPnt(X, Y, Z);
+        myBuilder.MakeVertex(V, aPnt, tol);
+        Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V.TShape());
+
+        BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
+        TopLoc_Location L;
+        do {
+          if (FormatNb() == BinTools_FormatVersion_VERSION_3) {
+            val = (Standard_Integer)IS.get();//case {0|1|2|3}
+            if (val > 0 && val <= 3)
+              BinTools::GetReal(IS, p1);
+          }
+          else {
+            std::streampos aPos = IS.tellg();
+            BinTools::GetReal(IS, p1);
+            val = (Standard_Integer)IS.get();//case {0|1|2|3}
 #ifdef OCCT_DEBUG
-           std::cout << "\nVal = " << val <<std::endl;   
+            std::cout << "\nVal = " << val << std::endl;
 #endif   
-           if(val != 1 && val !=2 && val !=3){
-             IS.seekg(aPos);
-             val = (Standard_Integer)IS.get();
-             if (val > 0 && val <= 3) 
-               BinTools::GetReal(IS, p1);
-           }
-         }
-         Handle(BRep_PointRepresentation) PR;
-         switch (val) {
-         case 0 :
-           break;
-           
-         case 1 :
-           {
-             BinTools::GetInteger(IS, c);
-             if (myCurves.Curve(c).IsNull())
-               break;
-             Handle(BRep_PointOnCurve) POC =
-               new BRep_PointOnCurve(p1,
-                                     myCurves.Curve(c),
-                                     L);
-             PR = POC;
-           }
-           break;
-           
-         case 2 :
-           {
-             BinTools::GetInteger(IS, pc);
-             BinTools::GetInteger(IS, s);
-             if (myCurves2d.Curve2d(pc).IsNull() ||
-                 mySurfaces.Surface(s).IsNull())
-               break;
-             
-             Handle(BRep_PointOnCurveOnSurface) POC =
-               new BRep_PointOnCurveOnSurface(p1,
-                                              myCurves2d.Curve2d(pc),
-                                              mySurfaces.Surface(s),
-                                              L);
-             PR = POC;
-           }
-           break;
-           
-         case 3 :
-           {
-             BinTools::GetReal(IS, p2);
-             BinTools::GetInteger(IS, s);
-             if (mySurfaces.Surface(s).IsNull())
-               break;
-             
-             Handle(BRep_PointOnSurface) POC =
-               new BRep_PointOnSurface(p1,p2,
-                                       mySurfaces.Surface(s),
-                                       L);
-             PR = POC;
-           }
-           break;
-           
-         default:
-           {
-              Standard_SStream aMsg;
-             aMsg << "BinTools_SurfaceSet::ReadGeometry: UnExpected BRep_PointRepresentation = "<< val <<std::endl;
-             throw Standard_Failure(aMsg.str().c_str());
-             }
-         }
-         
-         if (val > 0) {
-           BinTools::GetInteger(IS, l);//Locations index
-           
-           if (!PR.IsNull()) {
-             PR->Location(Locations().Location(l));
-             lpr.Append(PR);
-           }
-         }
-       } while (val > 0);
+            if (val != 1 && val != 2 && val != 3) {
+              IS.seekg(aPos);
+              val = (Standard_Integer)IS.get();
+              if (val > 0 && val <= 3)
+                BinTools::GetReal(IS, p1);
+            }
+          }
+          Handle(BRep_PointRepresentation) PR;
+          switch (val) {
+          case 0:
+            break;
+
+          case 1:
+          {
+            BinTools::GetInteger(IS, c);
+            if (myCurves.Curve(c).IsNull())
+              break;
+            Handle(BRep_PointOnCurve) POC =
+              new BRep_PointOnCurve(p1,
+                myCurves.Curve(c),
+                L);
+            PR = POC;
+          }
+          break;
+
+          case 2:
+          {
+            BinTools::GetInteger(IS, pc);
+            BinTools::GetInteger(IS, s);
+            if (myCurves2d.Curve2d(pc).IsNull() ||
+              mySurfaces.Surface(s).IsNull())
+              break;
+
+            Handle(BRep_PointOnCurveOnSurface) POC =
+              new BRep_PointOnCurveOnSurface(p1,
+                myCurves2d.Curve2d(pc),
+                mySurfaces.Surface(s),
+                L);
+            PR = POC;
+          }
+          break;
+
+          case 3:
+          {
+            BinTools::GetReal(IS, p2);
+            BinTools::GetInteger(IS, s);
+            if (mySurfaces.Surface(s).IsNull())
+              break;
+
+            Handle(BRep_PointOnSurface) POC =
+              new BRep_PointOnSurface(p1, p2,
+                mySurfaces.Surface(s),
+                L);
+            PR = POC;
+          }
+          break;
+
+          default:
+          {
+            Standard_SStream aMsg;
+            aMsg << "BinTools_SurfaceSet::ReadGeometry: UnExpected BRep_PointRepresentation = " << val << std::endl;
+            throw Standard_Failure(aMsg.str().c_str());
+          }
+          }
+
+          if (val > 0) {
+            BinTools::GetInteger(IS, l);//Locations index
+
+            if (!PR.IsNull()) {
+              PR->Location(Locations().Location(l));
+              lpr.Append(PR);
+            }
+          }
+        } while (val > 0);
       }
       break;
-      
+
 
       //---------
       // edge
       //---------
 
 
-    case TopAbs_EDGE :
+      case TopAbs_EDGE:
 
-      // Create an edge
+        // Create an edge
       {
         TopoDS_Edge& E = TopoDS::Edge(S);
-        
+
         myBuilder.MakeEdge(E);
-        
+
         // Read the curve geometry 
-       BinTools::GetReal(IS, tol);
-       BinTools::GetBool(IS, bval);
+        BinTools::GetReal(IS, tol);
+        BinTools::GetBool(IS, bval);
         myBuilder.SameParameter(E, bval);
 
-       BinTools::GetBool(IS, bval);
-        myBuilder.SameRange(E,bval);
+        BinTools::GetBool(IS, bval);
+        myBuilder.SameRange(E, bval);
+
+        BinTools::GetBool(IS, bval);
+        myBuilder.Degenerated(E, bval);
 
-       BinTools::GetBool(IS, bval);
-        myBuilder.Degenerated(E,bval);
-        
         do {
-         val = (Standard_Integer)IS.get();//{0|1|2|3|4|5|6|7}
-         // -0- no representation
-         // -1- Curve 3D
-         // -2- Curve on surf
-         // -3- Curve on closed surf
-         // -4- Regularity
-         // -5- Polygon3D
-         // -6- Polygon on triangulation
-         // -7- Polygon on closed triangulation
+          val = (Standard_Integer)IS.get();//{0|1|2|3|4|5|6|7}
+          // -0- no representation
+          // -1- Curve 3D
+          // -2- Curve on surf
+          // -3- Curve on closed surf
+          // -4- Regularity
+          // -5- Polygon3D
+          // -6- Polygon on triangulation
+          // -7- Polygon on closed triangulation
 
           switch (val) {
-         case 0:
-           break;
-
-          case 1 :                               // -1- Curve 3D
-           BinTools::GetInteger(IS, c);
-           BinTools::GetInteger(IS, l);
-           if (!myCurves.Curve(c).IsNull()) {
-             myBuilder.UpdateEdge(E,myCurves.Curve(c),
-                                  Locations().Location(l),tol);
-           }
-           BinTools::GetReal(IS, first);
-           BinTools::GetReal(IS, last);
-           if (!myCurves.Curve(c).IsNull()) {
-             Standard_Boolean Only3d = Standard_True;
-             myBuilder.Range(E,first,last,Only3d);
-           }
+          case 0:
+            break;
+
+          case 1:                               // -1- Curve 3D
+            BinTools::GetInteger(IS, c);
+            BinTools::GetInteger(IS, l);
+            if (!myCurves.Curve(c).IsNull()) {
+              myBuilder.UpdateEdge(E, myCurves.Curve(c),
+                Locations().Location(l), tol);
+            }
+            BinTools::GetReal(IS, first);
+            BinTools::GetReal(IS, last);
+            if (!myCurves.Curve(c).IsNull()) {
+              Standard_Boolean Only3d = Standard_True;
+              myBuilder.Range(E, first, last, Only3d);
+            }
             break;
-            
-            
-          case 2 : // -2- Curve on surf
-          case 3 : // -3- Curve on closed surf
+
+
+          case 2: // -2- Curve on surf
+          case 3: // -3- Curve on closed surf
             closed = (val == 3);
-            BinTools::GetInteger(IS, pc);
+            BinTools::GetInteger(IS, pc);
             if (closed) {
-             BinTools::GetInteger(IS, pc2);
-             reg = (GeomAbs_Shape)IS.get();
+              BinTools::GetInteger(IS, pc2);
+              reg = (GeomAbs_Shape)IS.get();
             }
 
             // surface, location
-           BinTools::GetInteger(IS, s);
-           BinTools::GetInteger(IS, l);
+            BinTools::GetInteger(IS, s);
+            BinTools::GetInteger(IS, l);
 
             // range
-           BinTools::GetReal(IS, first);
-           BinTools::GetReal(IS, last);
+            BinTools::GetReal(IS, first);
+            BinTools::GetReal(IS, last);
 
             // read UV Points // for XML Persistence higher performance
-            if (myFormatNb == BinTools_FormatVersion_VERSION_2
-             || myFormatNb == BinTools_FormatVersion_VERSION_3)
+            if (FormatNb() == BinTools_FormatVersion_VERSION_2
+             || FormatNb() == BinTools_FormatVersion_VERSION_3)
             {
-             BinTools::GetReal(IS, PfX);
-             BinTools::GetReal(IS, PfY);
-             BinTools::GetReal(IS, PlX);
-             BinTools::GetReal(IS, PlY);
-              aPf = gp_Pnt2d(PfX,PfY);
-              aPl = gp_Pnt2d(PlX,PlY);
+              BinTools::GetReal(IS, PfX);
+              BinTools::GetReal(IS, PfY);
+              BinTools::GetReal(IS, PlX);
+              BinTools::GetReal(IS, PlY);
+              aPf = gp_Pnt2d(PfX, PfY);
+              aPl = gp_Pnt2d(PlX, PlY);
             }
 
-           if (myCurves2d.Curve2d(pc).IsNull() ||
-               (closed && myCurves2d.Curve2d(pc2).IsNull()) ||
-               mySurfaces.Surface(s).IsNull())
-             break;
-           
+            if (myCurves2d.Curve2d(pc).IsNull() ||
+              (closed && myCurves2d.Curve2d(pc2).IsNull()) ||
+              mySurfaces.Surface(s).IsNull())
+              break;
+
             if (closed) {
-              if (myFormatNb == BinTools_FormatVersion_VERSION_2
-               || myFormatNb == BinTools_FormatVersion_VERSION_3)
+              if (FormatNb() == BinTools_FormatVersion_VERSION_2
+               || FormatNb() == BinTools_FormatVersion_VERSION_3)
               {
-                myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
-                                     myCurves2d.Curve2d(pc2),
-                                     mySurfaces.Surface(s),
-                                     Locations().Location(l),tol,
-                                     aPf, aPl);
+                myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+                  myCurves2d.Curve2d(pc2),
+                  mySurfaces.Surface(s),
+                  Locations().Location(l), tol,
+                  aPf, aPl);
               }
               else
               {
-                myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
-                                     myCurves2d.Curve2d(pc2),
-                                     mySurfaces.Surface(s),
-                                     Locations().Location(l),tol);
+                myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+                  myCurves2d.Curve2d(pc2),
+                  mySurfaces.Surface(s),
+                  Locations().Location(l), tol);
               }
 
               myBuilder.Continuity(E,
-                                   mySurfaces.Surface(s),
-                                   mySurfaces.Surface(s),
-                                   Locations().Location(l),
-                                   Locations().Location(l),
-                                   reg);
+                mySurfaces.Surface(s),
+                mySurfaces.Surface(s),
+                Locations().Location(l),
+                Locations().Location(l),
+                reg);
             }
             else
             {
-              if (myFormatNb == BinTools_FormatVersion_VERSION_2
-               || myFormatNb == BinTools_FormatVersion_VERSION_3)
+              if (FormatNb() == BinTools_FormatVersion_VERSION_2
+               || FormatNb() == BinTools_FormatVersion_VERSION_3)
               {
-                myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
-                                     mySurfaces.Surface(s),
-                                     Locations().Location(l),tol,
-                                     aPf, aPl);
+                myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+                  mySurfaces.Surface(s),
+                  Locations().Location(l), tol,
+                  aPf, aPl);
               }
               else
               {
-                myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
-                                     mySurfaces.Surface(s),
-                                     Locations().Location(l),tol);
+                myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+                  mySurfaces.Surface(s),
+                  Locations().Location(l), tol);
               }
             }
             myBuilder.Range(E,
-                            mySurfaces.Surface(s),
-                            Locations().Location(l),
-                            first,last);
+              mySurfaces.Surface(s),
+              Locations().Location(l),
+              first, last);
             break;
-            
-          case 4 : // -4- Regularity
-           reg = (GeomAbs_Shape)IS.get();
-           BinTools::GetInteger(IS, s);
-           BinTools::GetInteger(IS, l);
-           BinTools::GetInteger(IS, s2);
-           BinTools::GetInteger(IS, l2);
-           if (mySurfaces.Surface(s).IsNull() ||
-               mySurfaces.Surface(s2).IsNull())
-             break;
+
+          case 4: // -4- Regularity
+            reg = (GeomAbs_Shape)IS.get();
+            BinTools::GetInteger(IS, s);
+            BinTools::GetInteger(IS, l);
+            BinTools::GetInteger(IS, s2);
+            BinTools::GetInteger(IS, l2);
+            if (mySurfaces.Surface(s).IsNull() ||
+              mySurfaces.Surface(s2).IsNull())
+              break;
             myBuilder.Continuity(E,
-                                 mySurfaces.Surface(s),
-                                 mySurfaces.Surface(s2),
-                                 Locations().Location(l),
-                                 Locations().Location(l2),
-                                 reg);
+              mySurfaces.Surface(s),
+              mySurfaces.Surface(s2),
+              Locations().Location(l),
+              Locations().Location(l2),
+              reg);
             break;
-           
-          case 5 : // -5- Polygon3D                     
-           BinTools::GetInteger(IS, c);
-           BinTools::GetInteger(IS, l);
-//??? Bug?  myBuilder.UpdateEdge(E,myPolygons3D(c));
-           myBuilder.UpdateEdge(E, myPolygons3D(c), Locations().Location(l));
+
+          case 5: // -5- Polygon3D                     
+            BinTools::GetInteger(IS, c);
+            BinTools::GetInteger(IS, l);
+            //??? Bug?  myBuilder.UpdateEdge(E,myPolygons3D(c));
+            myBuilder.UpdateEdge(E, myPolygons3D(c), Locations().Location(l));
             break;
 
-          case 6 : // -6- Polygon on triangulation
-          case 7 : // -7- Polygon on closed triangulation
+          case 6: // -6- Polygon on triangulation
+          case 7: // -7- Polygon on closed triangulation
             closed = (val == 7);
-           BinTools::GetInteger(IS, pt);
-            if (closed) 
-             BinTools::GetInteger(IS, pt2);
+            BinTools::GetInteger(IS, pt);
+            if (closed)
+              BinTools::GetInteger(IS, pt2);
 
-           BinTools::GetInteger(IS, t);
-           BinTools::GetInteger(IS, l);
+            BinTools::GetInteger(IS, t);
+            BinTools::GetInteger(IS, l);
             if (closed)
             {
               myBuilder.UpdateEdge (E, myNodes(pt), myNodes(pt2), myTriangulations.FindKey(t), Locations().Location(l));
@@ -1127,102 +1086,102 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
             }
             // range            
             break;
-         default:
-           {
-              Standard_SStream aMsg;
-             aMsg <<"Unexpected Curve Representation ="<< val << std::endl;
-             throw Standard_Failure(aMsg.str().c_str());
-           }
-            
+          default:
+          {
+            Standard_SStream aMsg;
+            aMsg << "Unexpected Curve Representation =" << val << std::endl;
+            throw Standard_Failure(aMsg.str().c_str());
+          }
+
           }
         } while (val > 0);
       }
       break;
 
 
-    //---------
-    // wire
-    //---------
+      //---------
+      // wire
+      //---------
 
-    case TopAbs_WIRE :
-      myBuilder.MakeWire(TopoDS::Wire(S));
-      break;
+      case TopAbs_WIRE:
+        myBuilder.MakeWire(TopoDS::Wire(S));
+        break;
 
 
-    //---------
-    // face
-    //---------
+        //---------
+        // face
+        //---------
 
-    case TopAbs_FACE :
+      case TopAbs_FACE:
       {
-    // create a face :
-       TopoDS_Face& F = TopoDS::Face(S);
-       myBuilder.MakeFace(F);
-       BinTools::GetBool(IS, bval); //NaturalRestriction flag
-       BinTools::GetReal(IS, tol);
-       BinTools::GetInteger(IS, s); //surface indx
-       BinTools::GetInteger(IS, l); //location indx
-       myBuilder.UpdateFace (F,
-                        s > 0 ? mySurfaces.Surface(s) : Handle(Geom_Surface)(),
-                                         Locations().Location(l),
-                        tol);
-       myBuilder.NaturalRestriction (F, bval);
-    
-       Standard_Byte aByte = (Standard_Byte)IS.get();
-      // cas triangulation
-       if(aByte == 2) {
-         BinTools::GetInteger(IS, s);
+        // create a face :
+        TopoDS_Face& F = TopoDS::Face(S);
+        myBuilder.MakeFace(F);
+        BinTools::GetBool(IS, bval); //NaturalRestriction flag
+        BinTools::GetReal(IS, tol);
+        BinTools::GetInteger(IS, s); //surface indx
+        BinTools::GetInteger(IS, l); //location indx
+        myBuilder.UpdateFace(F,
+          s > 0 ? mySurfaces.Surface(s) : Handle(Geom_Surface)(),
+          Locations().Location(l),
+          tol);
+        myBuilder.NaturalRestriction(F, bval);
+
+        Standard_Byte aByte = (Standard_Byte)IS.get();
+        // cas triangulation
+        if (aByte == 2) {
+          BinTools::GetInteger(IS, s);
          myBuilder.UpdateFace(TopoDS::Face(S), myTriangulations.FindKey(s));
-       }
+        }
       }
       break;
 
 
-    //---------
-    // shell
-    //---------
+      //---------
+      // shell
+      //---------
 
-    case TopAbs_SHELL :
-      myBuilder.MakeShell(TopoDS::Shell(S));
-      break;
+      case TopAbs_SHELL:
+        myBuilder.MakeShell(TopoDS::Shell(S));
+        break;
 
 
-    //---------
-    // solid
-    //---------
+        //---------
+        // solid
+        //---------
 
-    case TopAbs_SOLID :
-      myBuilder.MakeSolid(TopoDS::Solid(S));
-      break;
+      case TopAbs_SOLID:
+        myBuilder.MakeSolid(TopoDS::Solid(S));
+        break;
 
 
-    //---------
-    // compsolid
-    //---------
+        //---------
+        // compsolid
+        //---------
 
-    case TopAbs_COMPSOLID :
-      myBuilder.MakeCompSolid(TopoDS::CompSolid(S));
-      break;
+      case TopAbs_COMPSOLID:
+        myBuilder.MakeCompSolid(TopoDS::CompSolid(S));
+        break;
 
 
-    //---------
-    // compound
-    //---------
+        //---------
+        // compound
+        //---------
 
-    case TopAbs_COMPOUND :
-      myBuilder.MakeCompound(TopoDS::Compound(S));
-      break;
+      case TopAbs_COMPOUND:
+        myBuilder.MakeCompound(TopoDS::Compound(S));
+        break;
 
-    default:
+      default:
       {
         Standard_SStream aMsg;
-        aMsg << "Unexpected topology type = "<< T <<std::endl;
+        aMsg << "Unexpected topology type = " << T << std::endl;
         throw Standard_Failure(aMsg.str().c_str());
         break;
       }
-    }
+      }
   }
-  catch(Standard_Failure const& anException) {
+  catch (Standard_Failure const& anException) {
     Standard_SStream aMsg;
     aMsg << "EXCEPTION in BinTools_ShapeSet::ReadGeometry(S,OS)" << std::endl;
     aMsg << anException << std::endl;
@@ -1230,20 +1189,17 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
   }
 }
 
-
-
 //=======================================================================
 //function : AddShapes
 //purpose  : 
 //=======================================================================
 
-void  BinTools_ShapeSet::AddShapes(TopoDS_Shape&       S1, 
-                                    const TopoDS_Shape& S2)
+void BinTools_ShapeSet::AddShapes(TopoDS_Shape&       S1, 
+                                  const TopoDS_Shape& S2)
 {
   myBuilder.Add(S1,S2);
 }
 
-
 //=======================================================================
 //function : WritePolygonOnTriangulation
 //purpose  :
@@ -1492,7 +1448,7 @@ void BinTools_ShapeSet::WriteTriangulation (Standard_OStream& OS,
       BinTools::PutInteger(OS, aNbNodes);
       BinTools::PutInteger(OS, aNbTriangles);
       BinTools::PutBool(OS, aTriangulation->HasUVNodes() ? 1 : 0);
-      if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+      if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
       {
         BinTools::PutBool(OS, (aTriangulation->HasNormals() && NeedToWriteNormals) ? 1 : 0);
       }
@@ -1526,7 +1482,7 @@ void BinTools_ShapeSet::WriteTriangulation (Standard_OStream& OS,
       }
 
       // write the normals
-      if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+      if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
       {
         if (aTriangulation->HasNormals() && NeedToWriteNormals)
         {
@@ -1581,7 +1537,7 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
       BinTools::GetInteger(IS, aNbNodes);
       BinTools::GetInteger(IS, aNbTriangles);
       BinTools::GetBool(IS, hasUV);
-      if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+      if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
       {
         BinTools::GetBool(IS, hasNormals);
       }
@@ -1618,6 +1574,7 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
         BinTools::GetInteger(IS, aTriNodes[2]);
         aTriangulation->SetTriangle (aTriIter, Poly_Triangle (aTriNodes[0], aTriNodes[1], aTriNodes[2]));
       }
+      //IS.ignore(sizeof(Standard_Real) * (hasUV ? 5 : 3) * aNbNodes + sizeof(Standard_Integer) * 3 * aNbTriangles);
 
       if (hasNormals)
       {
index 87cae7c..83add95 100644 (file)
 #ifndef _BinTools_ShapeSet_HeaderFile
 #define _BinTools_ShapeSet_HeaderFile
 
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
+#include <BinTools_ShapeSetBase.hxx>
 
 #include <TopTools_IndexedMapOfShape.hxx>
-#include <BinTools_FormatVersion.hxx>
 #include <BinTools_LocationSet.hxx>
-#include <Standard_Integer.hxx>
 #include <BRep_Builder.hxx>
 #include <BinTools_SurfaceSet.hxx>
 #include <BinTools_CurveSet.hxx>
 #include <BinTools_Curve2dSet.hxx>
 #include <TColStd_IndexedMapOfTransient.hxx>
-#include <Standard_Boolean.hxx>
 #include <Standard_OStream.hxx>
 #include <Standard_IStream.hxx>
-#include <TopAbs_ShapeEnum.hxx>
-
-class TopoDS_Shape;
-class BinTools_LocationSet;
 
 
 //! Writes topology in OStream in binary format
-class BinTools_ShapeSet 
+class BinTools_ShapeSet : public BinTools_ShapeSetBase
 {
 public:
 
@@ -51,25 +42,6 @@ public:
 
   Standard_EXPORT virtual ~BinTools_ShapeSet();
 
-  //! Return true if shape should be stored with triangles.
-  Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
-  //! Return true if shape should be stored triangulation with normals.
-  Standard_Boolean IsWithNormals() const { return myWithNormals; }
-
-
-  //! Define if shape will be stored with triangles.
-  //! Ignored (always written) if face defines only triangulation (no surface).
-  void SetWithTriangles (const Standard_Boolean theWithTriangles) { myWithTriangles = theWithTriangles; }
-  //! Define if shape will be stored triangulation with normals.
-  //! Ignored (always written) if face defines only triangulation (no surface).
-  void SetWithNormals(const Standard_Boolean theWithNormals) { myWithNormals = theWithNormals; }
-
-  //! Sets the BinTools_FormatVersion.
-  Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
-
-  //! Returns the BinTools_FormatVersion.
-  Standard_EXPORT Standard_Integer FormatNb() const;
-  
   //! Clears the content of the set.
   Standard_EXPORT virtual void Clear();
   
@@ -78,7 +50,7 @@ public:
   Standard_EXPORT Standard_Integer Add (const TopoDS_Shape& S);
   
   //! Returns the sub-shape of index <I>.
-  Standard_EXPORT const TopoDS_Shape& Shape (const Standard_Integer I) const;
+  Standard_EXPORT const TopoDS_Shape& Shape (const Standard_Integer I);
   
   //! Returns the index of <S>.
   Standard_EXPORT Standard_Integer Index (const TopoDS_Shape& S) const;
@@ -104,7 +76,7 @@ public:
   //! Write the flags, the subshapes.
   Standard_EXPORT virtual void Write
     (Standard_OStream& OS,
-     const Message_ProgressRange& theRange = Message_ProgressRange()) const;
+     const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! Reads the content of me from the binary stream  <IS>. me
   //! is first cleared.
@@ -120,42 +92,48 @@ public:
   //! Reads the flag, the subshapes.
   Standard_EXPORT virtual void Read
     (Standard_IStream& IS,
-        const Message_ProgressRange& theRange = Message_ProgressRange());
+     const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! Writes   on  <OS>   the shape   <S>.    Writes the
   //! orientation, the index of the TShape and the index
   //! of the Location.
-  Standard_EXPORT virtual void Write (const TopoDS_Shape& S, Standard_OStream& OS) const;
+  Standard_EXPORT virtual void Write (const TopoDS_Shape& S, Standard_OStream& OS);
   
   //! Writes the geometry of  me  on the stream <OS> in a
   //! binary format that can be read back by Read.
   Standard_EXPORT virtual void WriteGeometry
     (Standard_OStream& OS,
-        const Message_ProgressRange& theRange = Message_ProgressRange()) const;
+     const Message_ProgressRange& theRange = Message_ProgressRange()) const;
   
   //! Reads the geometry of me from the  stream  <IS>.
   Standard_EXPORT virtual void ReadGeometry
     (Standard_IStream& IS,
-        const Message_ProgressRange& theRange = Message_ProgressRange());
+     const Message_ProgressRange& theRange = Message_ProgressRange());
   
-  //! Reads  from <IS>  a shape  and  returns  it in  S.
+  //! Reads from <IS> a shape flags and sub-shapes and modifies S.
+  Standard_EXPORT virtual void ReadFlagsAndSubs
+    (TopoDS_Shape& S, const TopAbs_ShapeEnum T,
+     Standard_IStream& IS, const Standard_Integer NbShapes);
+
+  //! Reads from <IS> a shape and returns it in S.
   //! <NbShapes> is the number of tshapes in the set.
-  Standard_EXPORT virtual void Read
-    (TopoDS_Shape& S,
-     Standard_IStream& IS, const Standard_Integer NbShapes) const;
-  
-  //! Writes the geometry of <S>  on the stream <OS> in a
+  Standard_EXPORT virtual void ReadSubs
+  (TopoDS_Shape& S, Standard_IStream& IS, const Standard_Integer NbShapes);
+
+  //! An empty virtual method for redefinition in shape-reader.
+  Standard_EXPORT virtual void Read (Standard_IStream& /*theStream*/, TopoDS_Shape& /*theShape*/) {};
+
+  //! Writes the shape <S> on the stream <OS> in a
   //! binary format that can be read back by Read.
-  Standard_EXPORT virtual void WriteGeometry (const TopoDS_Shape& S, Standard_OStream& OS) const;
-  
-  //! Reads the geometry of a shape of type <T> from the
-  //! stream <IS> and returns it in <S>.
-  Standard_EXPORT virtual void ReadGeometry (const TopAbs_ShapeEnum T, Standard_IStream& IS, TopoDS_Shape& S);
+  Standard_EXPORT virtual void WriteShape (const TopoDS_Shape& S, Standard_OStream& OS) const;
   
-  //! Stores the goemetry of <S>.
-  Standard_EXPORT virtual void AddGeometry (const TopoDS_Shape& S);
+  //! Reads  a shape of type <T> from the stream <IS> and returns it in <S>.
+  Standard_EXPORT virtual void ReadShape (const TopAbs_ShapeEnum T, Standard_IStream& IS, TopoDS_Shape& S);
+
+  //! Stores the shape <S>.
+  Standard_EXPORT virtual void AddShape (const TopoDS_Shape& S);
   
-  //! Inserts  the shape <S2> in  the  shape <S1>.
+  //! Inserts  the shape <S2> in the shape <S1>.
   Standard_EXPORT virtual void AddShapes (TopoDS_Shape& S1, const TopoDS_Shape& S2);
   
   //! Reads the 3d polygons  of me
@@ -197,15 +175,10 @@ public:
     (Standard_OStream& OS,
         const Message_ProgressRange& theRange = Message_ProgressRange()) const;
 
-public:
-
-  static const Standard_CString THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1];
-
 private:
 
-  TopTools_IndexedMapOfShape myShapes;
+  TopTools_IndexedMapOfShape myShapes; ///< index and its shape (started from 1)
   BinTools_LocationSet myLocations;
-  Standard_Integer myFormatNb;
   BRep_Builder myBuilder;
   BinTools_SurfaceSet mySurfaces;
   BinTools_CurveSet myCurves;
@@ -216,9 +189,6 @@ private:
                              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;
-  Standard_Boolean myWithNormals;
-
 };
 
 #endif // _BinTools_ShapeSet_HeaderFile
diff --git a/src/BinTools/BinTools_ShapeSetBase.cxx b/src/BinTools/BinTools_ShapeSetBase.cxx
new file mode 100644 (file)
index 0000000..dcc9b42
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (c) 2021 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 <BinTools.hxx>
+#include <BinTools_ShapeSetBase.hxx>
+#include <TopoDS_Shape.hxx>
+
+const Standard_CString BinTools_ShapeSetBase::THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1] =
+{
+  "",
+  "Open CASCADE Topology V1 (c)",
+  "Open CASCADE Topology V2 (c)",
+  "Open CASCADE Topology V3 (c)",
+  "Open CASCADE Topology V4, (c) Open Cascade"
+};
+
+//=======================================================================
+//function : operator << (gp_Pnt)
+//purpose  : 
+//=======================================================================
+Standard_OStream& operator << (Standard_OStream& OS, const gp_Pnt P)
+{
+  BinTools::PutReal (OS, P.X());
+  BinTools::PutReal (OS, P.Y());
+  BinTools::PutReal (OS, P.Z());
+  return OS;
+}
+
+//=======================================================================
+//function : BinTools_ShapeSetBase
+//purpose  : 
+//=======================================================================
+
+BinTools_ShapeSetBase::BinTools_ShapeSetBase()
+  : myFormatNb (BinTools_FormatVersion_CURRENT),
+    myWithTriangles (Standard_False),
+    myWithNormals (Standard_False)
+{}
+
+//=======================================================================
+//function : ~BinTools_ShapeSetBase
+//purpose  : 
+//=======================================================================
+
+BinTools_ShapeSetBase::~BinTools_ShapeSetBase()
+{}
+
+//=======================================================================
+//function : SetFormatNb
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeSetBase::SetFormatNb (const Standard_Integer theFormatNb)
+{
+  Standard_ASSERT_RETURN(theFormatNb >= BinTools_FormatVersion_LOWER &&
+                         theFormatNb <= BinTools_FormatVersion_UPPER,
+    "Error: unsupported BinTools version.", );
+
+  myFormatNb = theFormatNb;
+}
diff --git a/src/BinTools/BinTools_ShapeSetBase.hxx b/src/BinTools/BinTools_ShapeSetBase.hxx
new file mode 100644 (file)
index 0000000..551218a
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright (c) 2021 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 _BinTools_ShapeSetBase_HeaderFile
+#define _BinTools_ShapeSetBase_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+#include <Standard_OStream.hxx>
+#include <Standard_IStream.hxx>
+#include <Message_ProgressRange.hxx>
+#include <BinTools_FormatVersion.hxx>
+
+class TopoDS_Shape;
+class gp_Pnt;
+
+//! Writes to the stream a gp_Pnt data
+Standard_OStream& operator << (Standard_OStream& OS, const gp_Pnt P);
+
+//! Computes a hash code for the given value of the uint64_t type, in range [1, theUpperBound]
+inline Standard_Integer HashCode (const uint64_t theValue, const Standard_Integer theUpperBound)
+{
+  return IntegerHashCode(theValue, 0xffffffffffffffff, theUpperBound);
+}
+
+//! A base class for all readers/writers of TopoDS_Shape into/from stream.
+class BinTools_ShapeSetBase
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  
+  //! A default constructor.
+  Standard_EXPORT BinTools_ShapeSetBase();
+  
+  Standard_EXPORT virtual ~BinTools_ShapeSetBase();
+
+  //! Return true if shape should be stored with triangles.
+  Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
+  //! Return true if shape should be stored triangulation with normals.
+  Standard_Boolean IsWithNormals() const { return myWithNormals; }
+
+  //! Define if shape will be stored with triangles.
+  //! Ignored (always written) if face defines only triangulation (no surface).
+  void SetWithTriangles (const Standard_Boolean theWithTriangles) { myWithTriangles = theWithTriangles; }
+  //! Define if shape will be stored triangulation with normals.
+  //! Ignored (always written) if face defines only triangulation (no surface).
+  void SetWithNormals(const Standard_Boolean theWithNormals) { myWithNormals = theWithNormals; }
+
+  //! Sets the BinTools_FormatVersion.
+  Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
+
+  //! Returns the BinTools_FormatVersion.
+  Standard_EXPORT Standard_Integer FormatNb() const { return myFormatNb; }
+  
+  //! Clears the content of the set.
+  Standard_EXPORT virtual void Clear() {}
+  
+  //! Writes the content of  me  on the stream <OS> in binary
+  //! format that can be read back by Read.
+  //!
+  //! Writes the locations.
+  //!
+  //! Writes the geometry calling WriteGeometry.
+  //!
+  //! Dumps the shapes from last to first.
+  //! For each shape  :
+  //! Write the type.
+  //! calls WriteGeometry(S).
+  //! Write the flags, the subshapes.
+  Standard_EXPORT virtual void Write
+    (Standard_OStream& /*OS*/, const Message_ProgressRange& /*theRange*/ = Message_ProgressRange()) {}
+  
+  //! Reads the content of me from the binary stream  <IS>. me
+  //! is first cleared.
+  //!
+  //! Reads the locations.
+  //!
+  //! Reads the geometry calling ReadGeometry.
+  //!
+  //! Reads the shapes.
+  //! For each shape
+  //! Reads the type.
+  //! calls ReadGeometry(T,S).
+  //! Reads the flag, the subshapes.
+  Standard_EXPORT virtual void Read
+    (Standard_IStream& /*IS*/, const Message_ProgressRange& /*theRange*/ = Message_ProgressRange()) {}
+  
+  //! Writes   on  <OS>   the shape   <S>.    Writes the
+  //! orientation, the index of the TShape and the index
+  //! of the Location.
+  Standard_EXPORT virtual void Write (const TopoDS_Shape& /*theShape*/, Standard_OStream& /*theStream*/) {}
+  
+  //! An empty virtual method for redefinition in shape-reader.
+  Standard_EXPORT virtual void Read (Standard_IStream& /*theStream*/, TopoDS_Shape& /*theShape*/) {}
+                                                                                    
+  static const Standard_CString THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1];
+private:
+
+  Standard_Integer myFormatNb;
+  Standard_Boolean myWithTriangles;
+  Standard_Boolean myWithNormals;
+};
+
+#endif // _BinTools_ShapeSet_HeaderFile
diff --git a/src/BinTools/BinTools_ShapeWriter.cxx b/src/BinTools/BinTools_ShapeWriter.cxx
new file mode 100644 (file)
index 0000000..ac604c7
--- /dev/null
@@ -0,0 +1,496 @@
+// Copyright (c) 2021 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 <BinTools_ShapeWriter.hxx>
+#include <BinTools_LocationSet.hxx>
+
+#include <TopoDS.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRep_GCurve.hxx>
+#include <BRep_Polygon3D.hxx>
+#include <BRep_PolygonOnTriangulation.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRep_Tool.hxx>
+#include <BRep_TVertex.hxx>
+#include <BRep_PointRepresentation.hxx>
+#include <BRep_TFace.hxx>
+#include <BinTools_CurveSet.hxx>
+#include <BinTools_Curve2dSet.hxx>
+#include <BinTools_SurfaceSet.hxx>
+#include <BinTools_OStream.hxx>
+
+//=======================================================================
+//function : BinTools_ShapeWriter
+//purpose  : 
+//=======================================================================
+BinTools_ShapeWriter::BinTools_ShapeWriter()
+  : BinTools_ShapeSetBase()
+{}
+  
+//=======================================================================
+//function : ~BinTools_ShapeWriter
+//purpose  : 
+//=======================================================================
+BinTools_ShapeWriter::~BinTools_ShapeWriter()
+{}
+
+//=======================================================================
+//function : Clear
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::Clear()
+{
+  BinTools_ShapeSetBase::Clear();
+  myShapePos.Clear();
+  myLocationPos.Clear();
+  myCurvePos.Clear();
+  myCurve2dPos.Clear();
+  mySurfacePos.Clear();
+  myPolygon3dPos.Clear();
+  myPolygonPos.Clear();
+  myTriangulationPos.Clear();
+}
+  
+//=======================================================================
+//function : Write
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::Write (const TopoDS_Shape& theShape, Standard_OStream& theStream)
+{
+  BinTools_OStream anOStream(theStream);
+  WriteShape (anOStream, theShape);
+}
+
+//=======================================================================
+//function : WriteShape
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::WriteShape (BinTools_OStream& theStream, const TopoDS_Shape& theShape)
+{
+  if (theShape.IsNull())
+  {
+    theStream << BinTools_ObjectType_EmptyShape;
+    return;
+  }
+  TopoDS_Shape aShape = theShape.Located (TopLoc_Location());
+  const uint64_t* anExisting = myShapePos.Seek (aShape);
+  if (anExisting) // shape is already there, so, write reference to it
+  {
+    theStream.WriteReference(*anExisting);
+    WriteLocation (theStream, theShape.Location());
+    theStream << Standard_Byte (theShape.Orientation ());
+    return;
+  }
+  uint64_t aNewPos = theStream.Position();
+  myShapePos.Bind (aShape, aNewPos);
+  theStream.WriteShape (aShape.ShapeType(), aShape.Orientation());
+  WriteLocation (theStream, theShape.Location());
+
+  try {
+    OCC_CATCH_SIGNALS
+    switch (aShape.ShapeType())
+    {
+    case TopAbs_VERTEX:
+    {
+      TopoDS_Vertex aV = TopoDS::Vertex (aShape);
+      theStream << BRep_Tool::Tolerance (aV);
+      gp_Pnt aP = BRep_Tool::Pnt (aV);
+      theStream << aP;
+      Handle(BRep_TVertex) aTV = Handle(BRep_TVertex)::DownCast (aShape.TShape());
+      for(BRep_ListIteratorOfListOfPointRepresentation anIter (aTV->Points()); anIter.More(); anIter.Next())
+      {
+        const Handle(BRep_PointRepresentation)& aPR = anIter.Value();
+        if (aPR->IsPointOnCurve())
+        {
+          theStream << (Standard_Byte)1; // 1
+          theStream << aPR->Parameter();
+          WriteCurve (theStream, aPR->Curve());
+        }
+        else if (aPR->IsPointOnCurveOnSurface())
+        {
+          theStream << (Standard_Byte)2;// 2
+          theStream << aPR->Parameter();
+          WriteCurve (theStream, aPR->PCurve());
+          WriteSurface (theStream, aPR->Surface());
+        }
+        else if (aPR->IsPointOnSurface())
+        {
+          theStream << (Standard_Byte)3;// 3
+          theStream << aPR->Parameter2() << aPR->Parameter();
+          WriteSurface (theStream, aPR->Surface());
+        }
+        WriteLocation (theStream, aPR->Location());
+      }
+      theStream << (Standard_Byte)0;
+    }
+    break;
+    case TopAbs_EDGE:
+    {
+      Handle(BRep_TEdge) aTE = Handle(BRep_TEdge)::DownCast (aShape.TShape());
+      theStream << aTE->Tolerance();
+      theStream.PutBools (aTE->SameParameter(), aTE->SameRange(), aTE->Degenerated());
+      Standard_Real aFirst, aLast;
+      for(BRep_ListIteratorOfListOfCurveRepresentation anIter = aTE->Curves(); anIter.More(); anIter.Next())
+      {
+        const Handle(BRep_CurveRepresentation)& aCR = anIter.Value();
+        if (aCR->IsCurve3D())
+        {
+          if (!aCR->Curve3D().IsNull())
+          {
+            Handle(BRep_GCurve) aGC = Handle(BRep_GCurve)::DownCast (aCR);
+            aGC->Range (aFirst, aLast);
+            theStream << (Standard_Byte)1; // -1- CURVE_3D;
+            WriteCurve (theStream, aCR->Curve3D());
+            WriteLocation (theStream, aCR->Location());
+            theStream << aFirst << aLast;
+          }
+        }
+        else if (aCR->IsCurveOnSurface()) {
+          Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast (aCR);
+          GC->Range (aFirst, aLast);
+          if (!aCR->IsCurveOnClosedSurface())
+            theStream << (Standard_Byte)2; // -2- Curve on surf
+          else
+            theStream << (Standard_Byte)3; // -3- Curve on closed surf
+          WriteCurve (theStream, aCR->PCurve());
+
+          if (aCR->IsCurveOnClosedSurface()) { //+ int|char
+            WriteCurve (theStream, aCR->PCurve2());
+            theStream << (Standard_Byte)aCR->Continuity();
+          }
+          WriteSurface (theStream, aCR->Surface());
+          WriteLocation (theStream, aCR->Location());
+          theStream << aFirst << aLast;
+        }
+        else if (aCR->IsRegularity())
+        {
+          theStream << (Standard_Byte)4; // -4- Regularity
+          theStream << (Standard_Byte)aCR->Continuity();
+          WriteSurface (theStream, aCR->Surface());
+          WriteLocation (theStream, aCR->Location());
+          WriteSurface (theStream, aCR->Surface2());
+          WriteLocation (theStream, aCR->Location2());
+        }
+        else if (IsWithTriangles())
+        {
+          if (aCR->IsPolygon3D())
+          {
+            Handle(BRep_Polygon3D) aGC = Handle(BRep_Polygon3D)::DownCast (aCR);
+            if (!aGC->Polygon3D().IsNull())
+            {
+              theStream << (Standard_Byte)5; // -5- Polygon3D
+              WritePolygon (theStream, aCR->Polygon3D());
+              WriteLocation (theStream, aCR->Location());
+            }
+          }
+          else if (aCR->IsPolygonOnTriangulation())
+          {
+            Handle(BRep_PolygonOnTriangulation) aPT = Handle(BRep_PolygonOnTriangulation)::DownCast (aCR);
+            if (!aCR->IsPolygonOnClosedTriangulation())
+              theStream << (Standard_Byte)6; // -6- Polygon on triangulation
+            else
+              theStream << (Standard_Byte)7; // -7- Polygon on closed triangulation
+            WritePolygon (theStream, aPT->PolygonOnTriangulation());
+
+            if (aCR->IsPolygonOnClosedTriangulation())
+              WritePolygon (theStream, aPT->PolygonOnTriangulation2());
+            // edge triangulation does not need normals
+            WriteTriangulation (theStream, aPT->Triangulation(), Standard_False);
+            WriteLocation (theStream, aCR->Location());
+          }
+        }
+      }
+      theStream << (Standard_Byte)0;
+    }
+    break;
+    case TopAbs_FACE:
+    {
+
+      Handle(BRep_TFace) aTF = Handle(BRep_TFace)::DownCast (aShape.TShape());
+      const TopoDS_Face& aF = TopoDS::Face (aShape);
+
+      // Write the surface geometry
+      theStream << BRep_Tool::NaturalRestriction (aF) << aTF->Tolerance();
+      WriteSurface (theStream, aTF->Surface());
+      WriteLocation (theStream, aTF->Location());
+
+      if (IsWithTriangles() || aTF->Surface().IsNull())
+      {
+        if (!(aTF->Triangulation()).IsNull())
+        {
+          theStream << (Standard_Byte)2;
+          WriteTriangulation (theStream, aTF->Triangulation(),
+            aTF->Triangulation()->HasNormals() && (IsWithNormals() || aTF->Surface().IsNull()));
+        }
+        else
+          theStream << (Standard_Byte)1;
+      }
+      else
+        theStream << (Standard_Byte)0; //without triangulation
+    }
+    break;
+    default:
+    {}
+  }
+  }
+  catch (Standard_Failure const& anException)
+  {
+    Standard_SStream aMsg;
+    aMsg << "EXCEPTION in BinTools_ShapeWriter::WriteShape" << std::endl;
+    aMsg << anException << std::endl;
+    throw Standard_Failure(aMsg.str().c_str());
+  }
+  theStream.PutBools (aShape.Free(), aShape.Modified(), aShape.Checked(),
+    aShape.Orientable(), aShape.Closed(), aShape.Infinite(), aShape.Convex());
+  // process sub-shapes
+  for (TopoDS_Iterator aSub (aShape, Standard_False, Standard_False); aSub.More(); aSub.Next())
+    WriteShape (theStream, aSub.Value());
+
+  theStream << BinTools_ObjectType_EndShape;
+}
+
+//=======================================================================
+//function : WriteLocation
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::WriteLocation (BinTools_OStream& theStream, const TopLoc_Location& theLocation)
+{
+  if (theLocation.IsIdentity())
+  {
+    theStream << BinTools_ObjectType_EmptyLocation;
+    return;
+  }
+  const uint64_t* aLoc = myLocationPos.Seek (theLocation);
+  if (aLoc)
+  {
+    theStream.WriteReference (*aLoc);
+    return;
+  }
+  uint64_t aNewLoc = theStream.Position();
+  try
+  {
+    OCC_CATCH_SIGNALS
+    TopLoc_Location aL2 = theLocation.NextLocation();
+    Standard_Boolean isSimple = aL2.IsIdentity();
+    Standard_Integer aPower = theLocation.FirstPower();
+    TopLoc_Location aL1 = theLocation.FirstDatum();
+    Standard_Boolean elementary = (isSimple && aPower == 1);
+    if (elementary)
+    {
+      theStream << BinTools_ObjectType_SimpleLocation << theLocation.Transformation();
+    }
+    else
+    {
+      theStream << BinTools_ObjectType_Location;
+      WriteLocation (theStream, aL1);
+      theStream << aPower;
+      while (!aL2.IsIdentity()) {
+        aL1 = aL2.FirstDatum();
+        aPower = aL2.FirstPower();
+        aL2 = aL2.NextLocation();
+        WriteLocation (theStream, aL1);
+        theStream << aPower;
+      }
+      theStream << BinTools_ObjectType_LocationEnd;
+    }
+    myLocationPos.Bind (theLocation, aNewLoc);
+  }
+  catch (Standard_Failure const& anException) {
+    Standard_SStream aMsg;
+    aMsg << "EXCEPTION in BinTools_ShapeWriter::WriteLocation" << std::endl;
+    aMsg << anException << std::endl;
+    throw Standard_Failure (aMsg.str().c_str());
+  }
+}
+
+//=======================================================================
+//function : WriteCurve
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::WriteCurve (BinTools_OStream& theStream, const Handle(Geom_Curve)& theCurve)
+{
+  if (theCurve.IsNull())
+  {
+    theStream << BinTools_ObjectType_EmptyCurve;
+    return;
+  }
+  const uint64_t* aCurve = myCurvePos.Seek (theCurve);
+  if (aCurve)
+  {
+    theStream.WriteReference (*aCurve);
+    return;
+  }
+  myCurvePos.Bind (theCurve, theStream.Position());
+  theStream << BinTools_ObjectType_Curve;
+  BinTools_CurveSet::WriteCurve (theCurve, theStream);
+}
+
+//=======================================================================
+//function : WriteCurve
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::WriteCurve (BinTools_OStream& theStream, const Handle(Geom2d_Curve)& theCurve)
+{
+  if (theCurve.IsNull())
+  {
+    theStream << BinTools_ObjectType_EmptyCurve2d;
+    return;
+  }
+  const uint64_t* aCurve = myCurve2dPos.Seek (theCurve);
+  if (aCurve)
+  {
+    theStream.WriteReference (*aCurve);
+    return;
+  }
+  myCurve2dPos.Bind (theCurve, theStream.Position());
+  theStream << BinTools_ObjectType_Curve2d;
+  BinTools_Curve2dSet::WriteCurve2d (theCurve, theStream);
+}
+
+//=======================================================================
+//function : WriteSurface
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::WriteSurface (BinTools_OStream& theStream, const Handle(Geom_Surface)& theSurface)
+{
+  if (theSurface.IsNull())
+  {
+    theStream << BinTools_ObjectType_EmptySurface;
+    return;
+  }
+  const uint64_t* aSurface = mySurfacePos.Seek (theSurface);
+  if (aSurface)
+  {
+    theStream.WriteReference (*aSurface);
+    return;
+  }
+  mySurfacePos.Bind (theSurface, theStream.Position());
+  theStream << BinTools_ObjectType_Surface;
+  BinTools_SurfaceSet::WriteSurface (theSurface, theStream);
+}
+
+//=======================================================================
+//function : WritePolygon
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::WritePolygon (BinTools_OStream& theStream, const Handle(Poly_Polygon3D)& thePolygon)
+{
+  if (thePolygon.IsNull())
+  {
+    theStream << BinTools_ObjectType_EmptyPolygon3d;
+    return;
+  }
+  const uint64_t* aPolygon = myPolygon3dPos.Seek (thePolygon);
+  if (aPolygon)
+  {
+    theStream.WriteReference (*aPolygon);
+    return;
+  }
+  myPolygon3dPos.Bind (thePolygon, theStream.Position());
+  theStream << BinTools_ObjectType_Polygon3d;
+
+  const Standard_Integer aNbNodes = thePolygon->NbNodes();
+  theStream << aNbNodes << thePolygon->HasParameters() << thePolygon->Deflection();
+  const TColgp_Array1OfPnt& aNodes = thePolygon->Nodes();
+  for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+    theStream << aNodes.Value (aNodeIter);
+  if (thePolygon->HasParameters())
+  {
+    const TColStd_Array1OfReal& aParam = thePolygon->Parameters();
+    for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+      theStream << aParam.Value (aNodeIter);
+  }
+}
+
+//=======================================================================
+//function : WritePolygon
+//purpose  : 
+//=======================================================================
+void BinTools_ShapeWriter::WritePolygon (BinTools_OStream& theStream,
+                                         const Handle(Poly_PolygonOnTriangulation)& thePolygon)
+{
+  if (thePolygon.IsNull())
+  {
+    theStream << BinTools_ObjectType_EmptyPolygonOnTriangulation;
+    return;
+  }
+  const uint64_t* aPolygon = myPolygonPos.Seek (thePolygon);
+  if (aPolygon)
+  {
+    theStream.WriteReference (*aPolygon);
+    return;
+  }
+  myPolygonPos.Bind (thePolygon, theStream.Position());
+  theStream << BinTools_ObjectType_PolygonOnTriangulation;
+
+  const TColStd_Array1OfInteger& aNodes = thePolygon->Nodes();
+  theStream << aNodes.Length();
+  for (Standard_Integer aNodeIter = 1; aNodeIter <= aNodes.Length(); ++aNodeIter)
+    theStream << aNodes.Value(aNodeIter);
+  theStream << thePolygon->Deflection();
+  if (const Handle(TColStd_HArray1OfReal)& aParam = thePolygon->Parameters())
+  {
+    theStream << Standard_True;
+    for (Standard_Integer aNodeIter = 1; aNodeIter <= aParam->Length(); ++aNodeIter)
+      theStream << aParam->Value(aNodeIter);
+  }
+  else
+    theStream << Standard_False;
+}
+
+void BinTools_ShapeWriter::WriteTriangulation (BinTools_OStream& theStream,
+                                               const Handle(Poly_Triangulation)& theTriangulation,
+                                               const Standard_Boolean theNeedToWriteNormals)
+{
+  if (theTriangulation.IsNull())
+  {
+    theStream << BinTools_ObjectType_EmptyTriangulation;
+    return;
+  }
+  const uint64_t* aTriangulation = myTriangulationPos.Seek (theTriangulation);
+  if (aTriangulation)
+  {
+    theStream.WriteReference (*aTriangulation);
+    return;
+  }
+  myTriangulationPos.Bind (theTriangulation, theStream.Position());
+  theStream << BinTools_ObjectType_Triangulation;
+
+  const Standard_Integer aNbNodes = theTriangulation->NbNodes();
+  const Standard_Integer aNbTriangles = theTriangulation->NbTriangles();
+  theStream << aNbNodes << aNbTriangles << theTriangulation->HasUVNodes();
+  theStream << theNeedToWriteNormals << theTriangulation->Deflection();
+  // write the 3d nodes
+  for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+    theStream << theTriangulation->Node (aNodeIter);
+  //theStream.write ((char*)(theTriangulation->InternalNodes().value(0)) , sizeof (gp_Pnt) * aNbNodes);  
+
+  if (theTriangulation->HasUVNodes())
+  {
+    for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+      theStream << theTriangulation->UVNode (aNodeIter);
+  }
+  for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
+    theStream << theTriangulation->Triangle (aTriIter);
+
+  if (theNeedToWriteNormals)
+  {
+    gp_Vec3f aNormal;
+    for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes; ++aNormalIter)
+    {
+      theTriangulation->Normal (aNormalIter, aNormal);
+      theStream << aNormal;
+    }
+  }
+}
diff --git a/src/BinTools/BinTools_ShapeWriter.hxx b/src/BinTools/BinTools_ShapeWriter.hxx
new file mode 100644 (file)
index 0000000..88561da
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (c) 2021 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 _BinTools_ShapeWriter_HeaderFile
+#define _BinTools_ShapeWriter_HeaderFile
+
+#include <BinTools_ShapeSetBase.hxx>
+#include <BinTools_OStream.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Map.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+
+class TopLoc_Location;
+class Geom_Curve;
+class Geom2d_Curve;
+class Geom_Surface;
+class Poly_Polygon3D;
+class Poly_PolygonOnTriangulation;
+class Poly_Triangulation;
+
+//! Writes topology in OStream in binary format without grouping of objects by types
+//! and using relative positions in a file as references.
+class BinTools_ShapeWriter : public BinTools_ShapeSetBase
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+  
+  //! Builds an empty ShapeSet.
+  //! Parameter <theWithTriangles> is added for XML Persistence
+  Standard_EXPORT BinTools_ShapeWriter();
+  
+  Standard_EXPORT virtual ~BinTools_ShapeWriter();
+
+  //! Clears the content of the set.
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+  
+  //! Writes the shape to stream using previously stored shapes and objects to refer them.
+  Standard_EXPORT virtual void Write (const TopoDS_Shape& theShape, Standard_OStream& theStream) Standard_OVERRIDE;
+
+  //! Writes location to the stream (all the needed sub-information or reference if it is already used).
+  Standard_EXPORT virtual void WriteLocation (BinTools_OStream& theStream, const TopLoc_Location& theLocation);
+
+private:
+  //! Writes shape to the stream (all the needed sub-information or reference if it is already used).
+  virtual void WriteShape (BinTools_OStream& theStream, const TopoDS_Shape& theShape);
+  //! Writes curve to the stream (all the needed sub-information or reference if it is already used).
+  void WriteCurve (BinTools_OStream& theStream, const Handle(Geom_Curve)& theCurve);
+  //! Writes curve2d to the stream (all the needed sub-information or reference if it is already used).
+  void WriteCurve (BinTools_OStream& theStream, const Handle(Geom2d_Curve)& theCurve);
+  //! Writes surface to the stream.
+  void WriteSurface (BinTools_OStream& theStream, const Handle(Geom_Surface)& theSurface);
+  //! Writes ploygon3d to the stream.
+  void WritePolygon (BinTools_OStream& theStream, const Handle(Poly_Polygon3D)& thePolygon);
+  //! Writes polygon on triangulation to the stream.
+  void WritePolygon (BinTools_OStream& theStream, const Handle(Poly_PolygonOnTriangulation)& thePolygon);
+  //! Writes triangulation to the stream.
+  void WriteTriangulation (BinTools_OStream& theStream, const Handle(Poly_Triangulation)& theTriangulation,
+    const Standard_Boolean theNeedToWriteNormals);
+
+  /// position of the shape previously stored
+  NCollection_DataMap<TopoDS_Shape, uint64_t, TopTools_ShapeMapHasher> myShapePos;
+  NCollection_DataMap<TopLoc_Location, uint64_t> myLocationPos;
+  NCollection_DataMap<Handle(Geom_Curve), uint64_t> myCurvePos;
+  NCollection_DataMap<Handle(Geom2d_Curve), uint64_t> myCurve2dPos;
+  NCollection_DataMap<Handle(Geom_Surface), uint64_t> mySurfacePos;
+  NCollection_DataMap<Handle(Poly_Polygon3D), uint64_t> myPolygon3dPos;
+  NCollection_DataMap<Handle(Poly_PolygonOnTriangulation), uint64_t> myPolygonPos;
+  NCollection_DataMap<Handle(Poly_Triangulation), uint64_t> myTriangulationPos;
+};
+
+#endif // _BinTools_ShapeWriter_HeaderFile
index 843b9d8..2e837e2 100644 (file)
@@ -111,43 +111,16 @@ Standard_Integer  BinTools_SurfaceSet::Index
   return myMap.FindIndex(S);
 }
 
-//=======================================================================
-//function : operator << (gp_Pnt)
-//purpose  : 
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt P)
-{
-  BinTools::PutReal(OS, P.X());
-  BinTools::PutReal(OS, P.Y());
-  BinTools::PutReal(OS, P.Z());
-  return OS;
-}
-
-//=======================================================================
-//function : operator << (gp_Dir)
-//purpose  : 
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Dir D)
-{
-  BinTools::PutReal(OS, D.X());
-  BinTools::PutReal(OS, D.Y());
-  BinTools::PutReal(OS, D.Z());
-  return OS;
-}
-
-
 //=======================================================================
 //function : operator <<(Geom_Plane)
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Plane)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_Plane)& S)
 {
   OS << (Standard_Byte)PLANE;
   gp_Pln P = S->Pln();
-  OS << P.Location();//Pnt
+  OS << P.Location(); // Pnt
   OS << P.Axis().Direction();
   OS << P.XAxis().Direction();
   OS << P.YAxis().Direction();
@@ -160,15 +133,15 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Pla
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_CylindricalSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_CylindricalSurface)& S)
 {
   OS << (Standard_Byte)CYLINDER;
   gp_Cylinder P = S->Cylinder();
-  OS << P.Location();//Pnt
+  OS << P.Location(); // Pnt
   OS << P.Axis().Direction();
   OS << P.XAxis().Direction();
   OS << P.YAxis().Direction();
-  BinTools::PutReal(OS, P.Radius());
+  OS << P.Radius();
   return OS;
 }
 
@@ -178,16 +151,16 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Cyl
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_ConicalSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_ConicalSurface)& S)
 {
   OS << (Standard_Byte)CONE;
   gp_Cone P = S->Cone();
-  OS << P.Location();//Pnt
+  OS << P.Location(); // Pnt
   OS << P.Axis().Direction();
   OS << P.XAxis().Direction();
   OS << P.YAxis().Direction();
-  BinTools::PutReal(OS, P.RefRadius());
-  BinTools::PutReal(OS, P.SemiAngle());
+  OS << P.RefRadius();
+  OS << P.SemiAngle();
   return OS;
 }
 
@@ -197,15 +170,15 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Con
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_SphericalSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_SphericalSurface)& S)
 {
   OS << (Standard_Byte)SPHERE;
   gp_Sphere P = S->Sphere();
-  OS << P.Location();//Pnt
+  OS << P.Location(); // Pnt
   OS << P.Position().Axis().Direction();
   OS << P.XAxis().Direction();
   OS << P.YAxis().Direction();
-  BinTools::PutReal(OS, P.Radius());
+  OS << P.Radius();
   return OS;
 }
 
@@ -215,16 +188,16 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Sph
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_ToroidalSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_ToroidalSurface)& S)
 {
   OS << (Standard_Byte)TORUS;
   gp_Torus P = S->Torus();
-  OS << P.Location();//Pnt
+  OS << P.Location(); // Pnt
   OS << P.Axis().Direction();
   OS << P.XAxis().Direction();
   OS << P.YAxis().Direction();
-  BinTools::PutReal(OS, P.MajorRadius());
-  BinTools::PutReal(OS, P.MinorRadius());
+  OS << P.MajorRadius();
+  OS << P.MinorRadius();
   return OS;
 }
 
@@ -234,11 +207,11 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Tor
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_SurfaceOfLinearExtrusion)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_SurfaceOfLinearExtrusion)& S)
 {
   OS << (Standard_Byte)LINEAREXTRUSION;
   OS << S->Direction();
-  BinTools_CurveSet::WriteCurve(S->BasisCurve(),OS);
+  BinTools_CurveSet::WriteCurve (S->BasisCurve(), OS);
   return OS;
 }
 
@@ -248,12 +221,12 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Sur
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_SurfaceOfRevolution)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_SurfaceOfRevolution)& S)
 {
   OS << (Standard_Byte)REVOLUTION;
   OS << S->Location();
   OS << S->Direction();
-  BinTools_CurveSet::WriteCurve(S->BasisCurve(),OS);
+  BinTools_CurveSet::WriteCurve (S->BasisCurve(), OS);
   return OS;
 }
 
@@ -263,27 +236,25 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Sur
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_BezierSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_BezierSurface)& S)
 {
   OS << (Standard_Byte)BEZIER;
   Standard_Boolean urational = S->IsURational() ? 1:0;
   Standard_Boolean vrational = S->IsVRational() ? 1:0;
-  BinTools::PutBool(OS, urational); //rational
-  BinTools::PutBool(OS, vrational);
-//  std::cout << "Bezier Surface:"<< std::endl;
-//  std::cout << "\turational = "<<urational<<" vrational = " <<vrational<<std::endl;
+  OS << urational; // rational
+  OS << vrational;
 
-// poles and weights
+  // poles and weights
   Standard_Integer i,j,udegree,vdegree;
   udegree = S->UDegree();
   vdegree = S->VDegree();
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter)udegree);
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter)vdegree);
+  OS << (Standard_ExtCharacter)udegree;
+  OS << (Standard_ExtCharacter)vdegree;
   for (i = 1; i <= udegree+1; i++) {
     for (j = 1; j <= vdegree+1; j++) {
-      OS << S->Pole(i,j); //Pnt
+      OS << S->Pole (i,j); // Pnt
       if (urational || vrational) {
-       BinTools::PutReal(OS, S->Weight(i,j));//Real
+             OS << S->Weight (i,j); // Real
       }
     }
   }
@@ -296,17 +267,17 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Bez
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_BSplineSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_BSplineSurface)& S)
 {
   OS << (Standard_Byte)BSPLINE;
   Standard_Boolean urational = S->IsURational() ? 1:0;
   Standard_Boolean vrational = S->IsVRational() ? 1:0;
   Standard_Boolean uperiodic = S->IsUPeriodic() ? 1:0;
   Standard_Boolean vperiodic = S->IsVPeriodic() ? 1:0;
-  BinTools::PutBool(OS, urational); 
-  BinTools::PutBool(OS, vrational)
-  BinTools::PutBool(OS, uperiodic); 
-  BinTools::PutBool(OS, vperiodic); 
+  OS << urational;
+  OS << vrational
+  OS << uperiodic;
+  OS << vperiodic;
 
 // poles and weights
   Standard_Integer i,j,udegree,vdegree,nbupoles,nbvpoles,nbuknots,nbvknots;
@@ -316,28 +287,28 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_BSp
   nbvpoles = S->NbVPoles();
   nbuknots = S->NbUKnots();
   nbvknots = S->NbVKnots();
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter) udegree);
-  BinTools::PutExtChar(OS, (Standard_ExtCharacter) vdegree);
-  BinTools::PutInteger(OS, nbupoles);
-  BinTools::PutInteger(OS, nbvpoles);
-  BinTools::PutInteger(OS, nbuknots);
-  BinTools::PutInteger(OS, nbvknots);
+  OS << (Standard_ExtCharacter) udegree;
+  OS << (Standard_ExtCharacter) vdegree;
+  OS << nbupoles;
+  OS << nbvpoles;
+  OS << nbuknots;
+  OS << nbvknots;
   for (i = 1; i <= nbupoles; i++) {
     for (j = 1; j <= nbvpoles; j++) {
-      OS << S->Pole(i,j); //Pnt
+      OS << S->Pole (i,j); // Pnt
       if (urational || vrational)
-       BinTools::PutReal(OS, S->Weight(i,j));//Real    
+             OS << S->Weight (i,j); // Real    
     }
   }
 
   for (i = 1; i <= nbuknots; i++) {
-    BinTools::PutReal(OS,S->UKnot(i));
-    BinTools::PutInteger(OS, S->UMultiplicity(i));
+    OS << S->UKnot (i);
+    OS << S->UMultiplicity (i);
   }
 
   for (i = 1; i <= nbvknots; i++) {
-    BinTools::PutReal(OS,S->VKnot(i));
-    BinTools::PutInteger(OS, S->VMultiplicity(i));
+    OS << S->VKnot (i);
+    OS << S->VMultiplicity (i);
   }
   return OS;
 }
@@ -348,16 +319,13 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_BSp
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_RectangularTrimmedSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_RectangularTrimmedSurface)& S)
 {
   OS << (Standard_Byte)RECTANGULAR;
   Standard_Real U1,U2,V1,V2;
   S->Bounds(U1,U2,V1,V2);
-  BinTools::PutReal(OS, U1);
-  BinTools::PutReal(OS, U2);
-  BinTools::PutReal(OS, V1);
-  BinTools::PutReal(OS, V2);
-  BinTools_SurfaceSet::WriteSurface(S->BasisSurface(),OS);
+  OS << U1 << U2 << V1 << V2;
+  BinTools_SurfaceSet::WriteSurface (S->BasisSurface(), OS);
   return OS;
 }
 
@@ -367,11 +335,11 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Rec
 //purpose  : 
 //=======================================================================
 
-static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_OffsetSurface)& S)
+static BinTools_OStream& operator <<(BinTools_OStream& OS, const Handle(Geom_OffsetSurface)& S)
 {
   OS << (Standard_Byte)OFFSET;
-  BinTools::PutReal(OS, S->Offset());
-  BinTools_SurfaceSet::WriteSurface(S->BasisSurface(),OS);
+  OS << S->Offset();
+  BinTools_SurfaceSet::WriteSurface (S->BasisSurface(), OS);
   return OS;
 }
 
@@ -381,8 +349,8 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const Handle(Geom_Off
 //purpose  : 
 //=======================================================================
 
-void BinTools_SurfaceSet::WriteSurface(const Handle(Geom_Surface)& S,
-                                       Standard_OStream& OS)
+void BinTools_SurfaceSet::WriteSurface (const Handle(Geom_Surface)& S,
+  BinTools_OStream& OS)
 {
   Handle(Standard_Type) TheType = S->DynamicType();
   try {
@@ -442,10 +410,11 @@ void  BinTools_SurfaceSet::Write (Standard_OStream& OS,
 {
 
   Standard_Integer i, nbsurf = myMap.Extent();
-  Message_ProgressScope aPS(theRange, "Writing surfases", nbsurf);
+  Message_ProgressScope aPS(theRange, "Writing surfaces", nbsurf);
   OS << "Surfaces "<< nbsurf << "\n";
+  BinTools_OStream aStream (OS);
   for (i = 1; i <= nbsurf && aPS.More(); i++, aPS.Next()) {
-    WriteSurface(Handle(Geom_Surface)::DownCast(myMap(i)),OS);
+    WriteSurface(Handle(Geom_Surface)::DownCast(myMap(i)), aStream);
   }
 
 }
index cb2e6d5..d595b86 100644 (file)
@@ -26,6 +26,7 @@
 #include <Standard_IStream.hxx>
 
 #include <Message_ProgressRange.hxx>
+#include <BinTools_OStream.hxx>
 
 class Standard_OutOfRange;
 class Geom_Surface;
@@ -67,7 +68,7 @@ public:
   
   //! Dumps the surface on the stream in binary
   //! format that can be read back.
-  Standard_EXPORT static void WriteSurface (const Handle(Geom_Surface)& S, Standard_OStream& OS);
+  Standard_EXPORT static void WriteSurface (const Handle(Geom_Surface)& S, BinTools_OStream& OS);
   
   //! Reads the surface  from  the stream.  The  surface  is
   //! assumed   to have  been  written  with  the Write
index 93f41e6..a8c3e7b 100644 (file)
@@ -5,10 +5,21 @@ BinTools_Curve2dSet.hxx
 BinTools_CurveSet.cxx
 BinTools_CurveSet.hxx
 BinTools_FormatVersion.hxx
+BinTools_IStream.cxx
+BinTools_IStream.hxx
 BinTools_LocationSet.cxx
 BinTools_LocationSet.hxx
 BinTools_LocationSetPtr.hxx
 BinTools_ShapeSet.cxx
 BinTools_ShapeSet.hxx
+BinTools_ShapeSetBase.cxx
+BinTools_ShapeSetBase.hxx
 BinTools_SurfaceSet.cxx
 BinTools_SurfaceSet.hxx
+BinTools_ObjectType.hxx
+BinTools_OStream.cxx
+BinTools_OStream.hxx
+BinTools_ShapeReader.hxx
+BinTools_ShapeReader.cxx
+BinTools_ShapeWriter.hxx
+BinTools_ShapeWriter.cxx
index 3fbbd92..39875d9 100644 (file)
@@ -26,6 +26,7 @@
 #include <PCDM_ReadWriter.hxx>
 #include <PCDM_RetrievalDriver.hxx>
 #include <PCDM_StorageDriver.hxx>
+#include <PCDM_ReaderFilter.hxx>
 #include <Plugin.hxx>
 #include <Standard_ErrorHandler.hxx>
 #include <Standard_GUID.hxx>
@@ -104,10 +105,11 @@ void CDF_Application::Close(const Handle(CDM_Document)& aDocument) {
 Handle(CDM_Document) CDF_Application::Retrieve (const TCollection_ExtendedString& aFolder, 
                                                 const TCollection_ExtendedString& aName,
                                                 const Standard_Boolean UseStorageConfiguration,
+                                                const Handle(PCDM_ReaderFilter)& theFilter,
                                                 const Message_ProgressRange& theRange)
 {
   TCollection_ExtendedString nullVersion;
-  return Retrieve(aFolder, aName, nullVersion, UseStorageConfiguration, theRange);
+  return Retrieve(aFolder, aName, nullVersion, UseStorageConfiguration, theFilter, theRange);
 }
 
 //=======================================================================
@@ -115,10 +117,11 @@ Handle(CDM_Document) CDF_Application::Retrieve (const TCollection_ExtendedString
 //purpose  : 
 //=======================================================================
 Handle(CDM_Document)  CDF_Application::Retrieve (const TCollection_ExtendedString& aFolder, 
-                                                const TCollection_ExtendedString& aName,
-                                                const TCollection_ExtendedString& aVersion,
-                                                const Standard_Boolean UseStorageConfiguration,
-                                                const Message_ProgressRange& theRange)
+                                                 const TCollection_ExtendedString& aName,
+                                                 const TCollection_ExtendedString& aVersion,
+                                                 const Standard_Boolean UseStorageConfiguration,
+                                                 const Handle(PCDM_ReaderFilter)& theFilter,
+                                                 const Message_ProgressRange& theRange)
 {
   Handle(CDM_MetaData) theMetaData; 
   
@@ -129,7 +132,7 @@ Handle(CDM_Document)  CDF_Application::Retrieve (const TCollection_ExtendedStrin
 
   CDF_TypeOfActivation theTypeOfActivation=TypeOfActivation(theMetaData);
   Handle(CDM_Document) theDocument = Retrieve(theMetaData, UseStorageConfiguration,
-                                              Standard_False, theRange);
+                                              Standard_False, theFilter, theRange);
 
   myDirectory->Add(theDocument);
   Activate(theDocument,theTypeOfActivation);
@@ -142,39 +145,51 @@ Handle(CDM_Document)  CDF_Application::Retrieve (const TCollection_ExtendedStrin
 //function : CanRetrieve
 //purpose  : 
 //=======================================================================
-PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& aFolder, const TCollection_ExtendedString&  aName) {
- TCollection_ExtendedString aVersion;
- return CanRetrieve(aFolder,aName,aVersion);
+PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& theFolder,
+                                               const TCollection_ExtendedString& theName,
+                                               const bool theAppendMode)
+{
+  TCollection_ExtendedString aVersion;
+  return CanRetrieve(theFolder, theName, aVersion, theAppendMode);
 }
 
 //=======================================================================
 //function : CanRetrieve
 //purpose  : 
 //=======================================================================
-PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString&  aFolder, const TCollection_ExtendedString&  aName, const TCollection_ExtendedString&  aVersion) {
-  
-  if (!myMetaDataDriver->Find(aFolder,aName,aVersion))
+PCDM_ReaderStatus CDF_Application::CanRetrieve(const TCollection_ExtendedString& theFolder,
+                                               const TCollection_ExtendedString& theName,
+                                               const TCollection_ExtendedString& theVersion,
+                                               const bool theAppendMode)
+{
+
+  if (!myMetaDataDriver->Find(theFolder, theName, theVersion))
     return PCDM_RS_UnknownDocument;
-  else if (!myMetaDataDriver->HasReadPermission(aFolder,aName,aVersion))
+  else if (!myMetaDataDriver->HasReadPermission(theFolder, theName, theVersion))
     return PCDM_RS_PermissionDenied;
   else {
-    Handle(CDM_MetaData) theMetaData = myMetaDataDriver->MetaData(aFolder,aName,aVersion);
+    Handle(CDM_MetaData) theMetaData = myMetaDataDriver->MetaData(theFolder, theName, theVersion);
 
-    if(theMetaData->IsRetrieved()) {
-      return theMetaData->Document()->IsModified()
-       ? PCDM_RS_AlreadyRetrievedAndModified : PCDM_RS_AlreadyRetrieved;
+    if (!theAppendMode && theMetaData->IsRetrieved())
+    {
+      return theMetaData->Document()->IsModified() ? PCDM_RS_AlreadyRetrievedAndModified : PCDM_RS_AlreadyRetrieved;
+    }
+    else if (theAppendMode && !theMetaData->IsRetrieved())
+    {
+      return PCDM_RS_NoDocument;
     }
-    else {
-      TCollection_ExtendedString theFileName=theMetaData->FileName();
-      TCollection_ExtendedString theFormat=PCDM_ReadWriter::FileFormat(theFileName);
-      if(theFormat.Length()==0) {
-       TCollection_ExtendedString ResourceName=UTL::Extension(theFileName);
-       ResourceName+=".FileFormat";
-       if(UTL::Find(Resources(),ResourceName))  {
-         theFormat=UTL::Value(Resources(),ResourceName);
-       }
-       else
-         return PCDM_RS_UnrecognizedFileFormat;
+    else
+    {
+      TCollection_ExtendedString theFileName = theMetaData->FileName();
+      TCollection_ExtendedString theFormat = PCDM_ReadWriter::FileFormat(theFileName);
+      if (theFormat.Length() == 0) {
+        TCollection_ExtendedString ResourceName = UTL::Extension(theFileName);
+        ResourceName += ".FileFormat";
+        if (UTL::Find(Resources(), ResourceName)) {
+          theFormat = UTL::Value(Resources(), ResourceName);
+        }
+        else
+          return PCDM_RS_UnrecognizedFileFormat;
       }
 
       // check actual availability of the driver
@@ -227,8 +242,9 @@ Standard_Boolean CDF_Application::SetDefaultFolder(const Standard_ExtString aFol
 //=======================================================================
 Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMetaData,
                                                const Standard_Boolean UseStorageConfiguration, 
+                                               const Handle(PCDM_ReaderFilter)& theFilter,
                                                const Message_ProgressRange& theRange) {
-  return Retrieve(aMetaData, UseStorageConfiguration, Standard_True, theRange);
+  return Retrieve(aMetaData, UseStorageConfiguration, Standard_True, theFilter, theRange);
 } 
 
 //=======================================================================
@@ -238,33 +254,39 @@ Handle(CDM_Document) CDF_Application::Retrieve(const Handle(CDM_MetaData)& aMeta
 Handle(CDM_Document) CDF_Application::Retrieve (const Handle(CDM_MetaData)& aMetaData, 
                                                 const Standard_Boolean UseStorageConfiguration, 
                                                 const Standard_Boolean IsComponent, 
+                                                const Handle(PCDM_ReaderFilter)& theFilter,
                                                 const Message_ProgressRange& theRange) {
   
   Handle(CDM_Document) theDocumentToReturn;
   myRetrievableStatus = PCDM_RS_DriverFailure;
-  if(IsComponent) {
+  Standard_Boolean isAppendMode = !theFilter.IsNull() && theFilter->IsAppendMode();
+  if (IsComponent) {
     Standard_SStream aMsg;
-    switch (CanRetrieve(aMetaData)) {
+    myRetrievableStatus = CanRetrieve(aMetaData, isAppendMode);
+    switch (myRetrievableStatus) {
     case PCDM_RS_UnknownDocument: 
       aMsg << "could not find the referenced document: " << aMetaData->Path() << "; not found."  <<(char)0 << std::endl;
-      myRetrievableStatus = PCDM_RS_UnknownDocument;
-      throw Standard_Failure(aMsg.str().c_str());
       break;
     case PCDM_RS_PermissionDenied:      
       aMsg << "Could not find the referenced document: " << aMetaData->Path() << "; permission denied. " <<(char)0 << std::endl;
-      myRetrievableStatus = PCDM_RS_PermissionDenied;
-      throw Standard_Failure(aMsg.str().c_str());
       break;
-    default:
+    case PCDM_RS_NoDocument:
+      aMsg << "Document for appending is not defined." << (char)0 << std::endl;
       break;
+    default:
+      myRetrievableStatus = PCDM_RS_OK;
     }
-    
+    if (myRetrievableStatus != PCDM_RS_OK)
+      throw Standard_Failure(aMsg.str().c_str());
+    myRetrievableStatus = PCDM_RS_DriverFailure;
   }
-  Standard_Boolean AlreadyRetrieved=aMetaData->IsRetrieved();
-  if(AlreadyRetrieved) myRetrievableStatus = PCDM_RS_AlreadyRetrieved;
-  Standard_Boolean Modified=AlreadyRetrieved && aMetaData->Document()->IsModified();
-  if(Modified) myRetrievableStatus = PCDM_RS_AlreadyRetrievedAndModified;
-  if(!AlreadyRetrieved || Modified)
+  Standard_Boolean AlreadyRetrieved = aMetaData->IsRetrieved();
+  if (AlreadyRetrieved)
+    myRetrievableStatus = PCDM_RS_AlreadyRetrieved;
+  Standard_Boolean Modified = AlreadyRetrieved && aMetaData->Document()->IsModified();
+  if (Modified)
+    myRetrievableStatus = PCDM_RS_AlreadyRetrievedAndModified;
+  if (!AlreadyRetrieved || Modified || isAppendMode)
   {
     TCollection_ExtendedString aFormat;
     if (!Format(aMetaData->FileName(), aFormat))
@@ -273,43 +295,47 @@ Handle(CDM_Document) CDF_Application::Retrieve (const Handle(CDM_MetaData)& aMet
       aMsg << "Could not determine format for the file " << aMetaData->FileName() << (char)0;
       throw Standard_NoSuchObject(aMsg.str().c_str());
     }
-    Handle(PCDM_Reader) theReader = ReaderFromFormat (aFormat);
-        
-    Handle(CDM_Document) theDocument;
+    Handle(PCDM_Reader) theReader = ReaderFromFormat(aFormat);
 
-    if(Modified)  {
-      theDocument=aMetaData->Document();
-      theDocument->RemoveAllReferences();
+    Handle(CDM_Document) aDocument;
+
+    if (Modified || isAppendMode) {
+      aDocument = aMetaData->Document();
+      if (!isAppendMode)
+        aDocument->RemoveAllReferences();
     }
     else
-      NewDocument(aFormat, theDocument);
-    
-    SetReferenceCounter(theDocument,PCDM_RetrievalDriver::ReferenceCounter(aMetaData->FileName(), MessageDriver()));
-    
-    SetDocumentVersion(theDocument,aMetaData);
-    myMetaDataDriver->ReferenceIterator(MessageDriver())->LoadReferences(theDocument,aMetaData,this,UseStorageConfiguration);
+    {
+      NewDocument(aFormat, aDocument);
+      SetReferenceCounter(aDocument, PCDM_RetrievalDriver::ReferenceCounter(aMetaData->FileName(), MessageDriver()));
+      SetDocumentVersion(aDocument, aMetaData);
+      myMetaDataDriver->ReferenceIterator(MessageDriver())->LoadReferences(aDocument, aMetaData, this, UseStorageConfiguration);
+    }
 
-    try {    
+    try {
       OCC_CATCH_SIGNALS
-      theReader->Read (aMetaData->FileName(), theDocument, this, theRange);
-    } 
+        theReader->Read(aMetaData->FileName(), aDocument, this, theFilter, theRange);
+    }
     catch (Standard_Failure const& anException) {
       myRetrievableStatus = theReader->GetStatus();
-      if(myRetrievableStatus  > PCDM_RS_AlreadyRetrieved){
-       Standard_SStream aMsg;
-       aMsg << anException << std::endl;
-       throw Standard_Failure(aMsg.str().c_str());
-      }        
+      if (myRetrievableStatus > PCDM_RS_AlreadyRetrieved) {
+        Standard_SStream aMsg;
+        aMsg << anException << std::endl;
+        throw Standard_Failure(aMsg.str().c_str());
+      }
     }
     myRetrievableStatus = theReader->GetStatus();
-    theDocument->Open (this); // must be done before SetMetaData
-    theDocument->SetMetaData(aMetaData);
+    if (!isAppendMode)
+    {
+      aDocument->Open(this); // must be done before SetMetaData
+      aDocument->SetMetaData(aMetaData);
+    }
 
-    theDocumentToReturn=theDocument;
+    theDocumentToReturn = aDocument;
   }
   else
-    theDocumentToReturn=aMetaData->Document();
-  
+    theDocumentToReturn = aMetaData->Document();
+
   return theDocumentToReturn;
 }
 
@@ -347,10 +373,11 @@ CDF_TypeOfActivation CDF_Application::TypeOfActivation(const Handle(CDM_MetaData
 //function : Read
 //purpose  : 
 //=======================================================================
-Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream,
+void CDF_Application::Read (Standard_IStream& theIStream,
+                                            Handle(CDM_Document)& theDocument,
+                                            const Handle(PCDM_ReaderFilter)& theFilter,
                                             const Message_ProgressRange& theRange)
 {
-  Handle(CDM_Document) aDoc;
   Handle(Storage_Data) dData;
   
   TCollection_ExtendedString aFormat;
@@ -373,20 +400,37 @@ Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream,
   if (aFormat.IsEmpty())
   {
     myRetrievableStatus = PCDM_RS_FormatFailure;
-    return aDoc;
+    return;
   }
  
-  // 1. use a format name to detect plugin corresponding to the format to continue reading
+  // use a format name to detect plugin corresponding to the format to continue reading
   Handle(PCDM_Reader) aReader = ReaderFromFormat (aFormat);
 
-  // 2. create document with the detected reader
-  NewDocument(aFormat, aDoc);
+  if (theFilter.IsNull() || !theFilter->IsAppendMode())
+  {
+    NewDocument(aFormat, theDocument);
+  }
+  else
+  {
+    // check the document is ready to append
+    if (theDocument.IsNull())
+    {
+      myRetrievableStatus = PCDM_RS_NoDocument;
+      return;
+    }
+    //check document format equals to the format of the stream
+    if (theDocument->StorageFormat() != aFormat)
+    {
+      myRetrievableStatus = PCDM_RS_FormatFailure;
+      return;
+    }
+  }
 
-  // 3. read the content of theIStream to aDoc
+  // read the content of theIStream to aDoc
   try
   {
     OCC_CATCH_SIGNALS
-    aReader->Read (theIStream, dData, aDoc, this, theRange);
+    aReader->Read (theIStream, dData, theDocument, this, theFilter, theRange);
   }
   catch (Standard_Failure const& anException)
   {
@@ -400,8 +444,6 @@ Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream,
   }
 
   myRetrievableStatus = aReader->GetStatus();
-
-  return aDoc;
 }
 
 //=======================================================================
@@ -541,11 +583,11 @@ Standard_Boolean CDF_Application::Format(const TCollection_ExtendedString& aFile
 //function : CanRetrieve
 //purpose  : 
 //=======================================================================
-PCDM_ReaderStatus CDF_Application::CanRetrieve(const Handle(CDM_MetaData)& aMetaData) {
+PCDM_ReaderStatus CDF_Application::CanRetrieve(const Handle(CDM_MetaData)& aMetaData, const bool theAppendMode) {
   if(aMetaData->HasVersion())
-    return CanRetrieve(aMetaData->Folder(),aMetaData->Name(),aMetaData->Version());
+    return CanRetrieve(aMetaData->Folder(),aMetaData->Name(),aMetaData->Version(), theAppendMode);
   else
-    return CanRetrieve(aMetaData->Folder(),aMetaData->Name());
+    return CanRetrieve(aMetaData->Folder(),aMetaData->Name(), theAppendMode);
 }
 
 //=======================================================================
index 82ca5a9..b4ef68f 100644 (file)
@@ -103,6 +103,7 @@ public:
     (const TCollection_ExtendedString& aFolder,
      const TCollection_ExtendedString& aName,
      const Standard_Boolean UseStorageConfiguration = Standard_True,
+     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
      const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! This method retrieves  a  document from the database.
@@ -124,22 +125,27 @@ public:
      const TCollection_ExtendedString& aName, 
      const TCollection_ExtendedString& aVersion, 
      const Standard_Boolean UseStorageConfiguration = Standard_True,
+     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
      const Message_ProgressRange& theRange = Message_ProgressRange());
   
-  Standard_EXPORT PCDM_ReaderStatus CanRetrieve (const TCollection_ExtendedString& aFolder,
-                                                 const TCollection_ExtendedString& aName);
+  Standard_EXPORT PCDM_ReaderStatus CanRetrieve (const TCollection_ExtendedString& theFolder,
+                                                 const TCollection_ExtendedString& theName,
+                                                 const bool theAppendMode);
   
-  Standard_EXPORT PCDM_ReaderStatus CanRetrieve (const TCollection_ExtendedString& aFolder,
-                                                 const TCollection_ExtendedString& aName,
-                                                 const TCollection_ExtendedString& aVersion);
+  Standard_EXPORT PCDM_ReaderStatus CanRetrieve (const TCollection_ExtendedString& theFolder,
+                                                 const TCollection_ExtendedString& theName,
+                                                 const TCollection_ExtendedString& theVersion,
+                                                 const bool theAppendMode);
   
   //! Checks  status  after  Retrieve
   PCDM_ReaderStatus GetRetrieveStatus() const { return myRetrievableStatus; }
   
-  //! Reads aDoc from standard SEEKABLE stream theIStream,
+  //! Reads theDocument from standard SEEKABLE stream theIStream,
   //! the stream should support SEEK functionality
-  Standard_EXPORT Handle(CDM_Document) Read
+  Standard_EXPORT void Read
     (Standard_IStream& theIStream,
+     Handle(CDM_Document)& theDocument,
+     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
      const Message_ProgressRange& theRange = Message_ProgressRange());
  
   //! Returns instance of read driver for specified format.
@@ -209,19 +215,21 @@ private:
   Standard_EXPORT Handle(CDM_Document) Retrieve
     (const Handle(CDM_MetaData)& aMetaData, 
      const Standard_Boolean UseStorageConfiguration, 
+     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
      const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
   
   Standard_EXPORT Handle(CDM_Document) Retrieve
     (const Handle(CDM_MetaData)& aMetaData,
      const Standard_Boolean UseStorageConfiguration, 
      const Standard_Boolean IsComponent, 
+     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
      const Message_ProgressRange& theRange = Message_ProgressRange());
   
   Standard_EXPORT Standard_Integer DocumentVersion (const Handle(CDM_MetaData)& theMetaData) Standard_OVERRIDE;
   
   Standard_EXPORT CDF_TypeOfActivation TypeOfActivation (const Handle(CDM_MetaData)& aMetaData);
   
-  Standard_EXPORT PCDM_ReaderStatus CanRetrieve (const Handle(CDM_MetaData)& aMetaData);
+  Standard_EXPORT PCDM_ReaderStatus CanRetrieve (const Handle(CDM_MetaData)& aMetaData, const bool theAppendMode);
 
 protected:
 
index 7a1edcc..a55dc67 100644 (file)
@@ -34,6 +34,7 @@ class CDM_MetaData;
 class CDM_Document;
 class Resource_Manager;
 class Message_Messenger;
+class PCDM_ReaderFilter;
 
 class CDM_Application;
 DEFINE_STANDARD_HANDLE(CDM_Application, Standard_Transient)
@@ -95,6 +96,7 @@ private:
   Standard_EXPORT virtual Handle(CDM_Document) Retrieve
         (const Handle(CDM_MetaData)& aMetaData, 
          const Standard_Boolean UseStorageConfiguration,
+         const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
          const Message_ProgressRange& theRange = Message_ProgressRange()) = 0;
   
   //! returns -1 if the metadata has no modification counter.
index 9edcc85..c923df9 100644 (file)
@@ -31,6 +31,7 @@
 #include <TDF_Data.hxx>
 #include <TDF_ChildIterator.hxx>
 #include <TDF_Tool.hxx> 
+#include <PCDM_ReaderFilter.hxx>
 
 #include <OSD_Path.hxx>
 #include <OSD_OpenFile.hxx>
@@ -128,43 +129,73 @@ static Standard_Integer DDocStd_Open (Draw_Interpretor& di,
 {   
   if (nb >= 3) {
     TCollection_ExtendedString path (a[1], Standard_True); 
+    Standard_CString DocName = a[2];
     Handle(TDocStd_Application) A = DDocStd::GetApplication();
     Handle(TDocStd_Document) D;
-    Standard_Integer insession = A->IsInSession(path);
-    if (insession > 0) {  
-      di <<"document " << insession << "  is already in session\n";
-      return 0;
-    }
     PCDM_ReaderStatus theStatus;
 
     Standard_Boolean anUseStream = Standard_False;
+    Handle(PCDM_ReaderFilter) aFilter = new PCDM_ReaderFilter;
     for ( Standard_Integer i = 3; i < nb; i++ )
     {
-      if (!strcmp (a[i], "-stream"))
+      TCollection_AsciiString anArg(a[i]);
+      if (anArg == "-append")
+      {
+        aFilter->Mode() = PCDM_ReaderFilter::AppendMode_Protect;
+      }
+      else if (anArg == "-overwrite")
+      {
+        aFilter->Mode() = PCDM_ReaderFilter::AppendMode_Overwrite;
+      }
+      else if (anArg == "-stream")
       {
         di << "standard SEEKABLE stream is used\n";
         anUseStream = Standard_True;
-        break;
+      }
+      else if (anArg.StartsWith("-skip"))
+      {
+        TCollection_AsciiString anAttrType = anArg.SubString(6, anArg.Length());
+        aFilter->AddSkipped(anAttrType);
+      }
+      else if (anArg.StartsWith("-read"))
+      {
+        TCollection_AsciiString aValue = anArg.SubString(6, anArg.Length());
+        if (aValue.Value(1) == '0') // path
+        {
+          aFilter->AddPath(aValue);
+        }
+        else // attribute to read
+        {
+          aFilter->AddRead(aValue);
+        }
       }
     }
 
+    if (aFilter->IsAppendMode() && !DDocStd::GetDocument(DocName, D, Standard_False))
+    {
+      di << "for append mode document " << DocName << " must be already created\n";
+      return 1;
+    }
     Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
     if (anUseStream)
     {
       std::ifstream aFileStream;
       OSD_OpenStream (aFileStream, path, std::ios::in | std::ios::binary);
 
-      theStatus = A->Open (aFileStream, D, aProgress->Start());
+      theStatus = A->Open (aFileStream, D, aFilter, aProgress->Start());
     }
     else
     {
-      theStatus = A->Open (path, D, aProgress->Start());
+      theStatus = A->Open (path, D, aFilter , aProgress->Start());
     }
     if (theStatus == PCDM_RS_OK && !D.IsNull())
     {
-      Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(D);
-      TDataStd_Name::Set(D->GetData()->Root(),a[2]);
-      Draw::Set(a[2],DD);
+      if (!aFilter->IsAppendMode())
+      {
+        Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument (D);
+        TDataStd_Name::Set (D->GetData()->Root(), DocName);
+        Draw::Set (DocName, DD);
+      }
       return 0; 
     } 
     else
@@ -579,7 +610,13 @@ void DDocStd::ApplicationCommands(Draw_Interpretor& theCommands)
                  __FILE__, DDocStd_NewDocument, g);  
 
   theCommands.Add("Open",
-                 "Open path docname [-stream]",
+                 "Open path docname [-stream] [-skipAttribute] [-readAttribute] [-readPath] [-append|-overwrite]"
+       "\n\t\t The options are:"
+       "\n\t\t   -stream : opens path as a stream"
+       "\n\t\t   -skipAttribute : class name of the attribute to skip during open, for example -skipTDF_Reference"
+       "\n\t\t   -readAttribute : class name of the attribute to read only during open, for example -readTDataStd_Name loads only such attributes"
+       "\n\t\t   -append : to read file into already existing document once again, append new attributes and don't touch existing"
+       "\n\t\t   -overwrite : to read file into already existing document once again, overwriting existing attributes",
                  __FILE__, DDocStd_Open, g);   
 
   theCommands.Add("SaveAs",
index f8b252d..4bd85fb 100755 (executable)
@@ -9,6 +9,8 @@ PCDM_DriverError.hxx
 PCDM_Reader.cxx
 PCDM_Reader.hxx
 PCDM_Reader.lxx
+PCDM_ReaderFilter.cxx
+PCDM_ReaderFilter.hxx
 PCDM_ReaderStatus.hxx
 PCDM_ReadWriter.cxx
 PCDM_ReadWriter.hxx
index cce1c5c..a0a7b44 100644 (file)
@@ -69,10 +69,7 @@ void PCDM_ReadWriter::Open (const Handle(Storage_BaseDriver)&   aDriver,
 //purpose  : 
 //=======================================================================
 
-//Handle(PCDM_ReadWriter) PCDM_ReadWriter::Reader(const TCollection_ExtendedString& aFileName) {
-
-Handle(PCDM_ReadWriter) PCDM_ReadWriter::Reader
-                                           (const TCollection_ExtendedString&)
+Handle(PCDM_ReadWriter) PCDM_ReadWriter::Reader (const TCollection_ExtendedString&)
 {
   return (new PCDM_ReadWriter_1);
 }
@@ -82,7 +79,7 @@ Handle(PCDM_ReadWriter) PCDM_ReadWriter::Reader
 //purpose  : 
 //=======================================================================
 
-Handle(PCDM_ReadWriter) PCDM_ReadWriter::Writer ()
+Handle(PCDM_ReadWriter) PCDM_ReadWriter::Writer()
 {
   return (new PCDM_ReadWriter_1);
 }
index 4a751de..7621070 100644 (file)
@@ -30,7 +30,7 @@ class PCDM_DriverError;
 class CDM_Document;
 class TCollection_ExtendedString;
 class CDM_Application;
-
+class PCDM_ReaderFilter;
 
 class PCDM_Reader;
 DEFINE_STANDARD_HANDLE(PCDM_Reader, Standard_Transient)
@@ -45,12 +45,14 @@ public:
   Standard_EXPORT virtual void Read (const TCollection_ExtendedString& aFileName, 
                                      const Handle(CDM_Document)& aNewDocument, 
                                      const Handle(CDM_Application)& anApplication, 
+                                     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
                                      const Message_ProgressRange& theProgress = Message_ProgressRange()) = 0;
 
   Standard_EXPORT virtual void Read (Standard_IStream&               theIStream,
                                      const Handle(Storage_Data)&    theStorageData,
                                      const Handle(CDM_Document)&    theDoc,
                                      const Handle(CDM_Application)& theApplication,
+                                     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
                                      const Message_ProgressRange& theProgress = Message_ProgressRange()) = 0;
   
     PCDM_ReaderStatus GetStatus() const;
diff --git a/src/PCDM/PCDM_ReaderFilter.cxx b/src/PCDM/PCDM_ReaderFilter.cxx
new file mode 100644 (file)
index 0000000..1a8b841
--- /dev/null
@@ -0,0 +1,175 @@
+// Copyright (c) 2021 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 <PCDM_ReaderFilter.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(PCDM_ReaderFilter,Standard_Transient)
+
+PCDM_ReaderFilter::PCDM_ReaderFilter (const Handle(Standard_Type)& theSkipped) : myAppend (AppendMode_Forbid)
+{
+  mySkip.Add(theSkipped->Name());
+}
+
+PCDM_ReaderFilter::PCDM_ReaderFilter (const TCollection_AsciiString& theEntryToRead) : myAppend (AppendMode_Forbid)
+{
+  mySubTrees.Append(theEntryToRead);
+}
+
+PCDM_ReaderFilter::PCDM_ReaderFilter (const AppendMode theAppend) : myAppend (theAppend)
+{}
+
+void PCDM_ReaderFilter::Clear()
+{
+  mySkip.Clear();
+  myRead.Clear();
+  mySubTrees.Clear();
+}
+
+PCDM_ReaderFilter::~PCDM_ReaderFilter()
+{
+  ClearTree();
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassed (const Handle(Standard_Type)& theAttributeID) const
+{
+  return IsPassedAttr(theAttributeID->Name());
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassedAttr (const TCollection_AsciiString& theAttributeType) const
+{
+  return myRead.IsEmpty() ? !mySkip.Contains (theAttributeType) :
+                             myRead.Contains (theAttributeType);
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassed (const TCollection_AsciiString& theEntry) const
+{
+  if (mySubTrees.IsEmpty())
+    return true;
+  for (NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees); anEntry.More(); anEntry.Next())
+  {
+    if (theEntry.StartsWith (anEntry.Value()))
+    {
+      if (theEntry.Length() > anEntry.Value().Length() &&
+          theEntry.Value (anEntry.Value().Length() + 1) != ':')  // case when theEntry="0:10" should not match "0:1"
+        continue;
+      return true;
+    }
+  }
+  return false;
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsSubPassed (const TCollection_AsciiString& theEntry) const
+{
+  if (mySubTrees.IsEmpty() || theEntry.Length() == 2) // root is always passed if any sub is defined
+    return true;
+  for (NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees); anEntry.More(); anEntry.Next())
+  {
+    if (theEntry.Length() < anEntry.Value().Length() &&
+        anEntry.Value().Value (theEntry.Length() + 1) == ':' && // case when theEntry="0:1" should not match "0:10"
+        anEntry.Value().StartsWith (theEntry))
+      return true;
+  }
+  return false;
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPartTree()
+{
+  return !(mySubTrees.IsEmpty() || (mySubTrees.Size() == 1 && mySubTrees.First().Length() < 3));
+}
+
+void PCDM_ReaderFilter::StartIteration()
+{
+  myCurrent = &myTree;
+  myCurrentDepth = 0;
+  ClearTree();
+  myTree.Bind(-1, NULL);
+  if (mySubTrees.IsEmpty())
+    return;
+  // create an iteration-tree by the mySubTrees entries
+  for (NCollection_List<TCollection_AsciiString>::Iterator aTreeIter (mySubTrees); aTreeIter.More(); aTreeIter.Next())
+  {
+    TagTree* aMap = &myTree;
+    TCollection_AsciiString aTagStr, anEntry = aTreeIter.Value();
+    for (Standard_Integer aTagIndex = 2; !anEntry.IsEmpty(); ++aTagIndex) // skip the root tag
+    {
+      aTagStr = anEntry.Token(":", aTagIndex);
+      if (aTagStr.IsEmpty())
+        break;
+      Standard_Integer aTag = aTagStr.IntegerValue();
+      if (aMap->IsBound (aTag))
+      {
+        aMap = (TagTree*)aMap->Find (aTag);
+      }
+      else
+      {
+        TagTree* aNewMap = new TagTree;
+        aNewMap->Bind (-1, aMap); // to be able to iterate up, keep father map in the child
+        aMap->Bind (aTag, aNewMap);
+        aMap = aNewMap;
+      }
+    }
+    aMap->Bind (-2, NULL); // identifier that this node is in subtrees definition
+  }
+}
+
+void PCDM_ReaderFilter::Up()
+{
+  if (myCurrentDepth == 0)
+    myCurrent = (TagTree*)myCurrent->Find(-1);
+  else
+    myCurrentDepth--;
+}
+
+void PCDM_ReaderFilter::Down (const int& theTag)
+{
+  if (myCurrentDepth== 0)
+  {
+    if (myCurrent->IsBound (theTag))
+      myCurrent= (TagTree*)myCurrent->Find (theTag);
+    else
+      ++myCurrentDepth;
+  }
+  else
+    ++myCurrentDepth;
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassed() const
+{
+  return myCurrent->IsBound(-2);
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsSubPassed() const
+{
+  return myCurrentDepth == 0;
+}
+
+void PCDM_ReaderFilter::ClearSubTree (const Standard_Address theMap)
+{
+  if (theMap)
+  {
+    TagTree* aMap = (TagTree*)theMap;
+    for (TagTree::Iterator aTagIter (*aMap); aTagIter.More(); aTagIter.Next())
+      if (aTagIter.Key() != -1)
+        ClearSubTree (aTagIter.Value());
+    delete aMap;
+  }
+}
+
+void PCDM_ReaderFilter::ClearTree()
+{
+  for (TagTree::Iterator aTagIter (myTree); aTagIter.More(); aTagIter.Next())
+    if (aTagIter.Key() != -1)
+      ClearSubTree (aTagIter.Value());
+  myTree.Clear();
+}
diff --git a/src/PCDM/PCDM_ReaderFilter.hxx b/src/PCDM/PCDM_ReaderFilter.hxx
new file mode 100644 (file)
index 0000000..0ba809b
--- /dev/null
@@ -0,0 +1,136 @@
+// Copyright (c) 2021 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 _PCDM_ReaderFilter_HeaderFile
+#define _PCDM_ReaderFilter_HeaderFile
+
+#include <Standard_Type.hxx>
+#include <Standard_Transient.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <NCollection_Map.hxx>
+#include <NCollection_List.hxx>
+
+class PCDM_ReaderFilter;
+DEFINE_STANDARD_HANDLE (PCDM_ReaderFilter, Standard_Transient)
+
+
+//! Class represents a document reading filter.
+//!
+//! It allows to set attributes (by class names) that must be skipped during the document reading
+//! or attributes that must be retrieved only.
+//! In addition it is possible to define one or several subtrees (by entry) which must be
+//! retrieved during the reading. Other labels are created, but no one attribute on them.
+class PCDM_ReaderFilter : public Standard_Transient
+{
+public:
+
+  //! Supported modes of appending the file content into existing document
+  enum AppendMode
+  {
+    AppendMode_Forbid    = 0, //!< do not allow append, default mode
+    AppendMode_Protect   = 1, //!< keeps existing attributes, reads only new ones
+    AppendMode_Overwrite = 2, //!< overwrites the existing attributes by the loaded ones
+  };
+
+
+  //! Creates an empty filter, so, all will be retrieved if nothing else is defined.
+  inline PCDM_ReaderFilter() : myAppend(AppendMode_Forbid) {}
+
+  //! Creates a filter to skip only one type of attributes.
+  Standard_EXPORT PCDM_ReaderFilter (const Handle(Standard_Type)& theSkipped);
+
+  //! Creates a filter to read only sub-labels of a label-path.
+  //! Like, for "0:2" it will read all attributes for labels "0:2", "0:2:1", etc.
+  Standard_EXPORT PCDM_ReaderFilter (const TCollection_AsciiString& theEntryToRead);
+
+  //! Creates a filter to append the content of file to open to existing document.
+  Standard_EXPORT PCDM_ReaderFilter (const AppendMode theAppend);
+
+  //! Destructor for the filter content
+  Standard_EXPORT ~PCDM_ReaderFilter();
+
+  //! Adds skipped attribute by type.
+  Standard_EXPORT void AddSkipped (const Handle(Standard_Type)& theSkipped) { mySkip.Add(theSkipped->Name()); }
+  //! Adds skipped attribute by type name.
+  Standard_EXPORT void AddSkipped (const TCollection_AsciiString& theSkipped) { mySkip.Add (theSkipped); }
+
+  //! Adds attribute to read by type. Disables the skipped attributes added.
+  Standard_EXPORT void AddRead (const Handle(Standard_Type)& theRead) { myRead.Add(theRead->Name()); }
+  //! Adds attribute to read by type name. Disables the skipped attributes added.
+  Standard_EXPORT void AddRead (const TCollection_AsciiString& theRead) { myRead.Add (theRead); }
+
+  //! Adds sub-tree path (like "0:2").
+  Standard_EXPORT void AddPath (const TCollection_AsciiString& theEntryToRead) { mySubTrees.Append (theEntryToRead); }
+
+  //! Makes filter pass all data.
+  Standard_EXPORT void Clear();
+
+  //! Returns true if attribute must be read.
+  Standard_EXPORT virtual Standard_Boolean IsPassed (const Handle(Standard_Type)& theAttributeID) const;
+  //! Returns true if attribute must be read.
+  Standard_EXPORT virtual Standard_Boolean IsPassedAttr (const TCollection_AsciiString& theAttributeType) const;
+  //! Returns true if content of the label must be read.
+  Standard_EXPORT virtual Standard_Boolean IsPassed (const TCollection_AsciiString& theEntry) const;
+  //! Returns true if some sub-label of the given label is passed.
+  Standard_EXPORT virtual Standard_Boolean IsSubPassed (const TCollection_AsciiString& theEntry) const;
+  //! Returns true if only part of the document tree will be retrieved.
+  Standard_EXPORT virtual Standard_Boolean IsPartTree();
+
+  //! Returns the append mode.
+  Standard_EXPORT AppendMode& Mode() { return myAppend; }
+  //! Returns true if appending to the document is performed.
+  Standard_EXPORT Standard_Boolean IsAppendMode() { return myAppend != PCDM_ReaderFilter::AppendMode_Forbid; }
+
+  //! Starts the tree iterator. It is used for fast searching of passed labels if the whole tree of labels
+  //! is parsed. So, on each iteration step the methods Up and Down must be called after the iteration start.
+  Standard_EXPORT virtual void StartIteration();
+  //! Iteration to the child label.
+  Standard_EXPORT virtual void Up();
+  //! Iteration to the child with defined tag.
+  Standard_EXPORT virtual void Down (const int& theTag);
+  //! Returns true if content of the currently iterated label must be read.
+  Standard_EXPORT virtual Standard_Boolean IsPassed() const;
+  //! Returns true if some sub-label of the currently iterated label is passed.
+  Standard_EXPORT virtual Standard_Boolean IsSubPassed() const;
+
+  DEFINE_STANDARD_RTTIEXT (PCDM_ReaderFilter, Standard_Transient)
+
+private:
+  //! Clears the iteration tree
+  Standard_EXPORT void ClearTree();
+  //! Clears the iteration sub-tree
+  Standard_EXPORT static void ClearSubTree (const Standard_Address theMap);
+
+protected:
+  //! Append mode for reading files into existing document
+  AppendMode myAppend;
+  //! Class names of attributes that must be skipped during the read
+  NCollection_Map<TCollection_AsciiString> mySkip;
+  //! Class names of only attributes to read (if it is not empty, mySkip is unused)
+  NCollection_Map<TCollection_AsciiString> myRead;
+  //! Paths to the labels that must be read. If it is empty, read all.
+  NCollection_List<TCollection_AsciiString> mySubTrees;
+
+  //! Map from tag of a label to sub-tree of this tag. Used for fast browsing the tree
+  //! and compare with entities that must be read.
+  typedef NCollection_DataMap<Standard_Integer, Standard_Address> TagTree;
+  //! Whole tree that correspond to retrieved document.
+  TagTree myTree;
+  //! Pointer to the current node of the iterator.
+  TagTree* myCurrent;
+  //! If a node does not described in the read-entries, the iterator goes inside of this subtree just by
+  //! keeping the depth of iteration.
+  Standard_Integer myCurrentDepth;
+};
+
+#endif // _PCDM_ReaderFilter_HeaderFile
index 7ef95c8..ff136e0 100644 (file)
@@ -45,6 +45,7 @@ IMPLEMENT_STANDARD_RTTIEXT (StdLDrivers_DocumentRetrievalDriver, PCDM_RetrievalD
 void StdLDrivers_DocumentRetrievalDriver::Read (const TCollection_ExtendedString& theFileName,
                                                 const Handle(CDM_Document)&       theNewDocument,
                                                 const Handle(CDM_Application)&                  ,
+                                                const Handle(PCDM_ReaderFilter)&                ,
                                                 const Message_ProgressRange&     /*theRange*/)
 {
   // Read header data and persistent document
@@ -229,6 +230,7 @@ void StdLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
                                                 const Handle(Storage_Data)&     /*theStorageData*/,
                                                 const Handle(CDM_Document)&     /*theDoc*/,
                                                 const Handle(CDM_Application)&  /*theApplication*/,
+                                                const Handle(PCDM_ReaderFilter)&/*theFilter*/,
                                                 const Message_ProgressRange&    /*theRange*/)
 {
   throw Standard_NotImplemented("Reading from stream is not supported by StdLDrivers_DocumentRetrievalDriver");
index c8e498e..821045f 100644 (file)
@@ -29,6 +29,7 @@ public:
   Standard_EXPORT virtual void Read (const TCollection_ExtendedString& theFileName,
                                      const Handle(CDM_Document)&       theNewDocument,
                                      const Handle(CDM_Application)&    theApplication,
+                                     const Handle(PCDM_ReaderFilter)&  theFilter = Handle(PCDM_ReaderFilter)(),
                                      const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
 
   //! Override pure virtual method (raises exception Standard_NotImplemented) 
@@ -36,6 +37,7 @@ public:
                                      const Handle(Storage_Data)&    theStorageData,
                                      const Handle(CDM_Document)&    theDoc,
                                      const Handle(CDM_Application)& theApplication,
+                                     const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
                                      const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
 
   DEFINE_STANDARD_RTTIEXT (StdLDrivers_DocumentRetrievalDriver, PCDM_RetrievalDriver)
index 27f7704..7c1d347 100644 (file)
@@ -21,6 +21,7 @@
 #include <CDF_Store.hxx>
 #include <PCDM_RetrievalDriver.hxx>
 #include <PCDM_StorageDriver.hxx>
+#include <PCDM_ReaderFilter.hxx>
 #include <Plugin.hxx>
 #include <Plugin_Failure.hxx>
 #include <Resource_Manager.hxx>
@@ -161,7 +162,7 @@ Standard_Integer TDocStd_Application::NbDocuments() const
 //purpose  :
 //=======================================================================
 
-void TDocStd_Application::GetDocument(const Standard_Integer index,Handle(TDocStd_Document)& aDoc) const
+void TDocStd_Application::GetDocument(const Standard_Integer index,Handle(TDocStd_Document)& theDoc) const
 {
   CDF_DirectoryIterator it (myDirectory);
   Standard_Integer current = 0;
@@ -170,7 +171,7 @@ void TDocStd_Application::GetDocument(const Standard_Integer index,Handle(TDocSt
     if (index == current) {
       Handle(TDocStd_Document) D =
         Handle(TDocStd_Document)::DownCast(it.Document());
-      aDoc = D;
+      theDoc = D;
       return;
     }
   }
@@ -181,12 +182,12 @@ void TDocStd_Application::GetDocument(const Standard_Integer index,Handle(TDocSt
 //purpose  :
 //=======================================================================
 
-void TDocStd_Application::NewDocument(const TCollection_ExtendedString& format, Handle(CDM_Document)& aDoc)
+void TDocStd_Application::NewDocument(const TCollection_ExtendedString& format, Handle(CDM_Document)& theDoc)
 {
   Handle(TDocStd_Document) D = new TDocStd_Document(format);
   InitDocument (D);
   CDF_Application::Open(D); // add the document in the session
-  aDoc = D;
+  theDoc = D;
 }
 
 //=======================================================================
@@ -195,11 +196,11 @@ void TDocStd_Application::NewDocument(const TCollection_ExtendedString& format,
 //         : Internally it calls a virtual method NewDocument() with CDM_Document object.
 //=======================================================================
 
-void TDocStd_Application::NewDocument (const TCollection_ExtendedString& format, Handle(TDocStd_Document)& aDoc)
+void TDocStd_Application::NewDocument (const TCollection_ExtendedString& format, Handle(TDocStd_Document)& theDoc)
 {
   Handle(CDM_Document) aCDMDoc;
   NewDocument (format, aCDMDoc);
-  aDoc = Handle(TDocStd_Document)::DownCast (aCDMDoc);
+  theDoc = Handle(TDocStd_Document)::DownCast (aCDMDoc);
 }
 
 //=======================================================================
@@ -216,20 +217,20 @@ void TDocStd_Application::InitDocument(const Handle(CDM_Document)& /*aDoc*/) con
 //purpose  :
 //=======================================================================
 
-void TDocStd_Application::Close(const Handle(TDocStd_Document)& aDoc)
+void TDocStd_Application::Close(const Handle(TDocStd_Document)& theDoc)
 {
-  if (aDoc.IsNull())
+  if (theDoc.IsNull())
   {
     return;
   }
 
   Handle(TDocStd_Owner) Owner;
-  if (aDoc->Main().Root().FindAttribute(TDocStd_Owner::GetID(),Owner)) {
+  if (theDoc->Main().Root().FindAttribute(TDocStd_Owner::GetID(),Owner)) {
     Handle(TDocStd_Document) emptyDoc;
     Owner->SetDocument(emptyDoc);
   }
-  aDoc->BeforeClose();
-  CDF_Application::Close(aDoc);
+  theDoc->BeforeClose();
+  CDF_Application::Close(theDoc);
 }
 
 //=======================================================================
@@ -267,7 +268,8 @@ Standard_Integer TDocStd_Application::IsInSession (const TCollection_ExtendedStr
 //=======================================================================
 
 PCDM_ReaderStatus TDocStd_Application::Open (const TCollection_ExtendedString& path, 
-                                             Handle(TDocStd_Document)& aDoc, 
+                                             Handle(TDocStd_Document)& theDoc,
+                                             const Handle(PCDM_ReaderFilter)& theFilter,
                                              const Message_ProgressRange& theRange)
 {
   PCDM_ReaderStatus status = PCDM_RS_DriverFailure;
@@ -276,7 +278,7 @@ PCDM_ReaderStatus TDocStd_Application::Open (const TCollection_ExtendedString& p
   TCollection_ExtendedString file = tool.Name();
   file += ".";
   file += tool.Extension();
-  status = CanRetrieve(directory, file);
+  status = CanRetrieve(directory, file, !theFilter.IsNull() && theFilter->IsAppendMode());
 
   if (status != PCDM_RS_OK)
   {
@@ -287,9 +289,10 @@ PCDM_ReaderStatus TDocStd_Application::Open (const TCollection_ExtendedString& p
   {
     OCC_CATCH_SIGNALS
     Handle(TDocStd_Document) D =
-      Handle(TDocStd_Document)::DownCast(Retrieve(directory, file, Standard_True, theRange));
-    CDF_Application::Open(D);
-    aDoc = D;
+      Handle(TDocStd_Document)::DownCast(Retrieve(directory, file, Standard_True, theFilter, theRange));
+    if (theFilter.IsNull() || !theFilter->IsAppendMode())
+      CDF_Application::Open(D);
+    theDoc = D;
   }
   catch (Standard_Failure const& anException)
   {
@@ -316,17 +319,20 @@ PCDM_ReaderStatus TDocStd_Application::Open (const TCollection_ExtendedString& p
 //=======================================================================
 PCDM_ReaderStatus TDocStd_Application::Open (Standard_IStream& theIStream,
                                              Handle(TDocStd_Document)& theDoc,
+                                             const Handle(PCDM_ReaderFilter)& theFilter,
                                              const Message_ProgressRange& theRange)
 { 
   try
   {
     OCC_CATCH_SIGNALS
-    Handle(TDocStd_Document) D = Handle(TDocStd_Document)::DownCast(Read(theIStream, theRange));
+    Handle(CDM_Document) aCDMDoc = theDoc;
+    Read(theIStream, aCDMDoc, theFilter, theRange);
+    // Read calls NewDocument of TDocStd_Application, so, it should the TDocStd_Document in the result anyway
+    theDoc = Handle(TDocStd_Document)::DownCast(aCDMDoc);
 
-    if (!D.IsNull())
+    if (!theDoc.IsNull() && (theFilter.IsNull() || !theFilter->IsAppendMode()))
     {
-      CDF_Application::Open(D);
-      theDoc = D;
+      CDF_Application::Open(theDoc);
     }
   }
 
@@ -346,7 +352,7 @@ PCDM_ReaderStatus TDocStd_Application::Open (Standard_IStream& theIStream,
 //purpose  :
 //=======================================================================
 
-PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& D, 
+PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc,
                                               const TCollection_ExtendedString& path,
                                               const Message_ProgressRange& theRange)
 {
@@ -355,8 +361,8 @@ PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& D,
   TCollection_ExtendedString file = tool.Name();
   file+=".";
   file+=tool.Extension();
-  D->Open(this);
-  CDF_Store storer (D);
+  theDoc->Open(this);
+  CDF_Store storer (theDoc);
   if (!storer.SetFolder(directory))
   {
     TCollection_ExtendedString aMsg ("TDocStd_Application::SaveAs() - folder ");
@@ -378,7 +384,7 @@ PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& D,
     }
   }
   if(storer.StoreStatus() == PCDM_SS_OK)
-    D->SetSaved();
+    theDoc->SetSaved();
 #ifdef OCCT_DEBUG
   std::cout<<"TDocStd_Application::SaveAs(): The status = "<<storer.StoreStatus()<<std::endl;
 #endif
index 442a8f3..5891ca7 100644 (file)
@@ -227,19 +227,25 @@ public:
   //! In order not to override a version of aDoc which
   //! is already in memory, this method can be made
   //! to depend on the value returned by IsInSession.
+  //! It is possible to filter out some attributes or
+  //! parts of the retrieved tree by theFilter.
   Standard_EXPORT PCDM_ReaderStatus Open (const TCollection_ExtendedString& path, 
-                                          Handle(TDocStd_Document)& aDoc,
+                                          Handle(TDocStd_Document)& theDoc,
+                                          const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
                                           const Message_ProgressRange& theRange = Message_ProgressRange());
 
   //! Retrieves aDoc from standard SEEKABLE stream theIStream.
   //! the stream should support SEEK functionality
-  Standard_EXPORT PCDM_ReaderStatus Open (Standard_IStream& theIStream, Handle(TDocStd_Document)& theDoc, 
+  //! It is possible to filter out some attributes or
+  //! parts of the retrieved tree by theFilter.
+  Standard_EXPORT PCDM_ReaderStatus Open (Standard_IStream& theIStream, Handle(TDocStd_Document)& theDoc,
+                                          const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
                                           const Message_ProgressRange& theRange = Message_ProgressRange());
 
   
   //! Save the  active document  in the file  <name> in the
   //! path <path> ; o verwrites  the file  if  it already exists.
-  Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& aDoc,
+  Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& theDoc,
                                            const TCollection_ExtendedString& path,
                                            const Message_ProgressRange& theRange = Message_ProgressRange());
 
@@ -253,13 +259,13 @@ public:
   //! Exceptions:
   //! Standard_NotImplemented if the document
   //! was not retrieved in the applicative session by using Open.
-  Standard_EXPORT PCDM_StoreStatus Save (const Handle(TDocStd_Document)& aDoc,
+  Standard_EXPORT PCDM_StoreStatus Save (const Handle(TDocStd_Document)& theDoc,
                                          const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! Save the  active document  in the file  <