]> OCCT Git - occt-copy.git/commitdiff
0031839: Application Framework - Add ability to partially load OCAF document
authormpv <mpv@opencascade.com>
Sat, 2 Jan 2021 10:59:40 +0000 (13:59 +0300)
committeragv <agv@opencascade.com>
Sun, 24 Jan 2021 15:19:46 +0000 (18:19 +0300)
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 (it is very hard to implement it in the current format without loading time loses)
- only TopoDS_Shapes are loaded in "postponed mode", because all other elements stored in the shapes section loaded in the same time anyway do they created or not: locations, curves, surfaces, triangulation, etc.

Added filter usage description into OCAF User Guide.

# Conflicts:
# src/BinTools/BinTools_ShapeSet.cxx
# src/BinTools/BinTools_ShapeSet.hxx

29 files changed:
dox/user_guides/ocaf/ocaf.md
src/BinDrivers/BinDrivers_DocumentRetrievalDriver.cxx
src/BinDrivers/BinDrivers_DocumentRetrievalDriver.hxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx
src/BinMNaming/BinMNaming_NamedShapeDriver.cxx
src/BinMNaming/BinMNaming_NamedShapeDriver.hxx
src/BinTools/BinTools.cxx
src/BinTools/BinTools_ShapeSet.cxx
src/BinTools/BinTools_ShapeSet.hxx
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_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/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/caf/progress/B1

index 80dc90e74fd9e47677e7441ca6cff07b1b7dd101..8de7c08d3cca0dd1e1d2dc5f3f332b0db8bab9b1 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.
+
+Appeding 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 bc36e96af14339daff674e47f57a10c7339a9b21..e7dde6a91b667fe3ff8924d08386ff2a69a74578 100644 (file)
@@ -59,6 +59,7 @@ void BinDrivers_DocumentRetrievalDriver::ReadShapeSection
                               (BinLDrivers_DocumentSection& /*theSection*/,
                                Standard_IStream&            theIS,
                                const Standard_Boolean       /*isMess*/,
+                               const Standard_Boolean       thePostponeShapes,
                                const Message_ProgressRange& theRange)
 
 {
@@ -70,7 +71,7 @@ void BinDrivers_DocumentRetrievalDriver::ReadShapeSection
       OCC_CATCH_SIGNALS
       Handle(BinMNaming_NamedShapeDriver) aNamedShapeDriver =
         Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
-      aNamedShapeDriver->ReadShapeSection (theIS, theRange);
+      aNamedShapeDriver->ReadShapeSection (theIS, thePostponeShapes, theRange);
     }
     catch(Standard_Failure const& anException) {
       const TCollection_ExtendedString aMethStr
index f7c51d7bd5aa15921f818b8f4d1f199da6a7cde7..836edd6f3debd265c9d54b6c3fb8d69cc75470a9 100644 (file)
@@ -49,6 +49,7 @@ public:
     (BinLDrivers_DocumentSection& theSection, 
      Standard_IStream& theIS,
      const Standard_Boolean isMess = Standard_False, 
+     const Standard_Boolean thePostponeShapes = Standard_False,
      const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
   
   Standard_EXPORT virtual void CheckShapeSection
index 686e5853595bde6dac4a3b4bdcd03012f5b67d0a..39c69552832eaa1396a94f9eea1f96c4085a40a9 100644 (file)
 #include <TDF_Attribute.hxx>
 #include <TDF_Data.hxx>
 #include <TDF_Label.hxx>
+#include <TDF_Tool.hxx>
 #include <TDocStd_Document.hxx>
 #include <TDocStd_Owner.hxx>
 #include <Message_ProgressScope.hxx>
+#include <PCDM_ReaderFilter.hxx>
 
 
 IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentRetrievalDriver,PCDM_RetrievalDriver)
@@ -70,6 +72,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;
@@ -80,7 +83,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;
@@ -103,11 +106,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();
@@ -220,10 +224,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);
+  Standard_Boolean aPostponeShapes = !theFilter.IsNull() && (theFilter->IsPartTree() || !theFilter->IsPassedAttr("TNaming_NamedShape"));
 
   // 2b. Read the TOC of Sections
   if (aFileVer >= 3) {
@@ -249,7 +254,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
         theIStream.seekg ((std::streampos) aCurSection.Offset());
         if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS))
         {
-          ReadShapeSection (aCurSection, theIStream, false, aPS.Next());
+          ReadShapeSection (aCurSection, theIStream, false, aPostponeShapes, aPS.Next());
           if (!aPS.More())
           {
             myReaderStatus = PCDM_RS_UserBreak;
@@ -295,7 +300,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
         CheckShapeSection(aShapeSectionPos, theIStream);
         // Read Shapes
         BinLDrivers_DocumentSection aCurSection;
-        ReadShapeSection (aCurSection, theIStream, Standard_False, aPS.Next());
+        ReadShapeSection (aCurSection, theIStream, Standard_False, aPostponeShapes, aPS.Next());
         if (!aPS.More())
         {
           myReaderStatus = PCDM_RS_UserBreak;
@@ -313,7 +318,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   theIStream.read ((char*)&aTag, sizeof(Standard_Integer));
 
   // read sub-tree of the root label
-  Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), aPS.Next());
+  Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), theFilter, aPS.Next());
   if (!aPS.More()) 
   {
     myReaderStatus = PCDM_RS_UserBreak;
@@ -330,9 +335,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;
   }
 
@@ -355,31 +363,46 @@ 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 Message_ProgressRange& theRange)
 {
   Standard_Integer nbRead = 0;
   TCollection_ExtendedString aMethStr
-    ("BinLDrivers_DocumentRetrievalDriver: ");
+  ("BinLDrivers_DocumentRetrievalDriver: ");
 
   Message_ProgressScope aPS(theRange, "Reading sub tree", 2, true);
 
+  TCollection_AsciiString anEntry;
+  bool aSkipAttrs = Standard_False;
+  if (!theFilter.IsNull() && theFilter->IsPartTree())
+  {
+    TDF_Tool::Entry(theLabel, anEntry);
+    aSkipAttrs = !theFilter->IsPassed(anEntry);
+  }
+
   // 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)
+      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()) {
+      if (!theFilter.IsNull() && !theFilter->IsPassed(aDriver->SourceType())) {
+        continue;
+      }
       // create transient attribute
       nbRead++;
       Standard_Integer anID = myPAtt.Id();
@@ -392,9 +415,16 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
 
       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&)
         {
@@ -403,34 +433,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;
   }
@@ -438,14 +466,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));
 #if 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;
@@ -454,22 +482,22 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
 
 
     // read sub-tree
-    Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, aPS.Next());
+    Standard_Integer nbSubRead = ReadSubTree(theIS, aLab, theFilter, 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));
 #if 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;
   }
@@ -510,6 +538,7 @@ void BinLDrivers_DocumentRetrievalDriver::ReadShapeSection
                               (BinLDrivers_DocumentSection& theSection,
                                Standard_IStream&            /*theIS*/,
                                const Standard_Boolean isMess,
+                               const Standard_Boolean /*thePostponeShapes*/,
                                const Message_ProgressRange &/*theRange*/)
 
 {
index 7b9325af5c04e7c16e3b7d95792cff57782d1e1b..5c77e85149879f861b43633c54d9d11c979367cd 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,8 @@ 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 Message_ProgressRange& theRanges = Message_ProgressRange());
   
   
   //! define the procedure of reading a section to file.
@@ -92,10 +95,11 @@ 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 Standard_Boolean thePostponeShapes = Standard_False,
+    const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! checks the shapes section can be correctly retreived.
   Standard_EXPORT virtual void CheckShapeSection (const Storage_Position& thePos, Standard_IStream& theIS);
index 767c19d8ff06f265c95e1d7328e6130b451b659e..bb79761d35d4895ecb9fba5050bcab745a80675b 100644 (file)
@@ -301,6 +301,7 @@ void BinMNaming_NamedShapeDriver::Clear()
 //=======================================================================
 
 void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS,
+                                                    const Standard_Boolean thePostponeShapes,
                                                     const Message_ProgressRange& theRange)
 {
   // check section title string; note that some versions of OCCT (up to 6.3.1) 
@@ -310,7 +311,7 @@ void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS,
   theIS >> aSectionTitle;
   if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) {
     myShapeSet.Clear();
-    myShapeSet.Read (theIS, theRange);
+    myShapeSet.Read (theIS, thePostponeShapes, theRange);
     SetFormatNb(myShapeSet.FormatNb());
   }
   else
index 4e15ab78290ffbfad6f76b43b6a9f5e4ae0d4a50..54bd4bc7f2373747b7440291a8a8f99fc8af5734 100644 (file)
@@ -53,6 +53,7 @@ public:
   
   //! Input the shapes from Bin Document file
   Standard_EXPORT void ReadShapeSection (Standard_IStream& theIS,
+                                         const Standard_Boolean thePostponeShapes = Standard_False,
                                          const Message_ProgressRange& therange = Message_ProgressRange());
   
   //! Output the shapes into Bin Document file
index 16237e5a870580c022fd60c542ef73eb1a5fd5ad..32f6a776887d87aed0faba41d7ac4aca82d81dbd 100644 (file)
@@ -193,8 +193,8 @@ void BinTools::Read (TopoDS_Shape& theShape, Standard_IStream& theStream,
                      const Message_ProgressRange& theRange)
 {
   BinTools_ShapeSet aShapeSet(Standard_True);
-  aShapeSet.Read (theStream, theRange);
-  aShapeSet.Read (theShape, theStream, aShapeSet.NbShapes());
+  aShapeSet.Read (theStream, Standard_False, theRange);
+  aShapeSet.ReadSubs (theShape, theStream, aShapeSet.NbShapes());
 }
 
 //=======================================================================
index eaec192d4a74af55c26b0a9c82d098e796a35b3c..bcb4aeb54c1920bd13bc85de7ce838b2d71b404b 100644 (file)
@@ -127,20 +127,24 @@ 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);
-  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);
+
+  const int* anIndex = myShapes.Seek2(aS2);
+  if (!anIndex)
+  {
+    AddShape (aS2);
+    for (TopoDS_Iterator its (aS2, Standard_False, Standard_False); its.More(); its.Next())
+      Add (its.Value());
+    int aNewIndex = myShapes.Size() + 1;
+    myShapes.Bind(aNewIndex, aS2);
+    return aNewIndex;
   }
-  return anIndex;
+  return *anIndex;
 }
 
 
@@ -149,9 +153,22 @@ 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);
+  const TopoDS_Shape* aShape = myShapes.Seek1 (theIndx);
+  if (!aShape && myStream)
+  {
+    std::streampos aCurrentPos = myStream->tellg();
+    myStream->seekg(myShapesPositions.Value(theIndx));
+    TopoDS_Shape aNewShape;
+    TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)myStream->get();
+    ReadShape (T, *myStream, aNewShape);
+    ReadFlagsAndSubs (aNewShape, T, *myStream, myShapesPositions.Length());
+    myShapes.Bind(theIndx, aNewShape);
+    myStream->seekg(aCurrentPos);
+    return myShapes.Find1(theIndx);
+  }
+  return *aShape;
 }
 
 //=======================================================================
@@ -161,7 +178,7 @@ const TopoDS_Shape&  BinTools_ShapeSet::Shape(const Standard_Integer theIndx)con
 
 Standard_Integer BinTools_ShapeSet::Index(const TopoDS_Shape& theShape) const
 {
-  return myShapes.FindIndex(theShape);
+  return myShapes.Find2(theShape);
 }
 
 //=======================================================================
@@ -169,7 +186,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;
 }
@@ -190,7 +207,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
   
@@ -323,7 +340,7 @@ void  BinTools_ShapeSet::WriteGeometry (Standard_OStream& OS,
 //=======================================================================
 
 void  BinTools_ShapeSet::Write (Standard_OStream& OS,
-                                const Message_ProgressRange& theRange)const
+                                const Message_ProgressRange& theRange) const
 {
 
   // write the copyright
@@ -361,13 +378,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.Find1(i);
     
     // Type
     OS << (Standard_Byte)S.ShapeType();
 
     // Geometry
-    WriteGeometry(S,OS);
+    WriteShape (S, OS);
 
     // Flags
     BinTools::PutBool(OS, S.Free()? 1:0);
@@ -393,11 +410,11 @@ void  BinTools_ShapeSet::Write (Standard_OStream& OS,
 //function : Read
 //purpose  : 
 //=======================================================================
-
 void  BinTools_ShapeSet::Read (Standard_IStream& IS,
+                               const Standard_Boolean thePostponeShapes,
                                const Message_ProgressRange& theRange)
 {
-
+  myPostponed = thePostponeShapes;
   Clear();
 
   // Check the version
@@ -426,7 +443,6 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
   //-----------------------------------------
   // read the locations
   //-----------------------------------------
-
   myLocations.Read(IS);
   //-----------------------------------------
   // read the geometry
@@ -453,51 +469,24 @@ void  BinTools_ShapeSet::Read (Standard_IStream& IS,
   Message_ProgressScope aPSinner(aPSouter.Next(), "Reading Shapes", nbShapes);
   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 >= 2)
-       S.Checked(aChecked);
-     else
-       S.Checked   (Standard_False);     // force check at reading.. 
-    S.Orientable(anOrient);
-    S.Closed    (aClosed);
-    S.Infinite  (anInf);
-    S.Convex    (aConv);
-    // check
-
-    if (myFormatNb == 1)
-      if(T == TopAbs_FACE) {
-       const TopoDS_Face& F = TopoDS::Face(S);
-       BRepTools::Update(F);
-      }
-    myShapes.Add(S);
+    if (myPostponed)
+    {
+      std::streampos aCurrentPos = IS.tellg();
+      myShapesPositions.Append (aCurrentPos);
+      TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
+      PassShape (T, IS);
+      PassFlagsAndSubs (IS);
+    }
+    else {
+      TopoDS_Shape S;
+      TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
+      ReadShape (T, IS, S);
+      ReadFlagsAndSubs (S, T, IS, nbShapes);
+      myShapes.Bind(i, S);
+    }
   }
+  if (myPostponed)
+    myStream = &IS;
 }
 
 //=======================================================================
@@ -514,7 +503,7 @@ 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, myShapes.Extent() - myShapes.Find2(S.Located(TopLoc_Location())) + 1);
     BinTools::PutInteger(OS, Locations().Index(S.Location()));
   }    
 }
@@ -524,19 +513,61 @@ void  BinTools_ShapeSet::Write (const TopoDS_Shape& S,
 //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 (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);
+    }
+}
+
+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;
@@ -545,30 +576,46 @@ void  BinTools_ShapeSet::Read (TopoDS_Shape& S, Standard_IStream& IS,
   }
 }
 
+
+void BinTools_ShapeSet::PassFlagsAndSubs(Standard_IStream& IS)
+{
+  IS.ignore(7 * sizeof(Standard_Byte)); // 7 shape flags
+  Standard_Character aChar = '\0';
+  for (IS >> aChar; aChar != '*'; IS >> aChar)
+    if (aChar != '*')
+      IS.ignore(2 * sizeof(Standard_Integer)); // sub-shape and its location indices
+}
+
 //=======================================================================
 //function : ReadGeometry
 //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());
 }
 
@@ -577,8 +624,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 {
@@ -790,294 +837,302 @@ void  BinTools_ShapeSet::WriteGeometry (const TopoDS_Shape& S,
 //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;
-       Standard_Boolean aNewF = (myFormatNb > 2);
-       do {
-         if(aNewF) {
-           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 (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}
 #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 (FormatNb() >= 2)
             {
-             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 (FormatNb() >= 2)
-                myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
-                                     myCurves2d.Curve2d(pc2),
-                                     mySurfaces.Surface(s),
-                                     Locations().Location(l),tol,
-                                     aPf, aPl);
+              if (myFormatNb == BinTools_FormatVersion_VERSION_2
+               || myFormatNb == BinTools_FormatVersion_VERSION_3)
+              {
+                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 (FormatNb() >= 2)
-                myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
-                                     mySurfaces.Surface(s),
-                                     Locations().Location(l),tol,
-                                     aPf, aPl);
+              if (myFormatNb == BinTools_FormatVersion_VERSION_2
+               || myFormatNb == BinTools_FormatVersion_VERSION_3)
+              {
+                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(t), Locations().Location(l));
@@ -1088,102 +1143,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(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;
@@ -1191,15 +1246,124 @@ void  BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
   }
 }
 
+//=======================================================================
+//function : PassShape
+//purpose  : 
+//=======================================================================
+
+void  BinTools_ShapeSet::PassShape (const TopAbs_ShapeEnum T, Standard_IStream& IS)
+{
+  Standard_Integer val;
 
+  switch (T) {
+  case TopAbs_VERTEX:
+    IS.ignore(4 * sizeof(Standard_Real)); // tolerance + 3 coordinates
+    do {
+      if (myFormatNb > 2) {
+        val = (Standard_Integer)IS.get();
+        if (val > 0 && val <= 3)
+          IS.ignore(sizeof(Standard_Real)); // parameter
+      }
+      else {
+        std::streampos aPos = IS.tellg();
+        IS.ignore(sizeof(Standard_Real));
+        val = (Standard_Integer)IS.get();
+        if (val != 1 && val != 2 && val != 3) {
+          IS.seekg(aPos);
+          val = (Standard_Integer)IS.get();
+          if (val > 0 && val <= 3)
+            IS.ignore(sizeof(Standard_Real)); // parameter
+        }
+      }
+      switch (val) {
+      case 0:
+        break;
+      case 1:
+        IS.ignore(sizeof(Standard_Integer)); // index of curve
+        break;
+      case 2:
+        IS.ignore(sizeof(Standard_Integer) * 2); // curve 2d and surface indices
+        break;
+      case 3:
+        IS.ignore(sizeof(Standard_Real) + sizeof(Standard_Integer)); // parameter + surface index
+        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)
+        IS.ignore(sizeof(Standard_Integer));//Locations index
+    } while (val > 0);
+    break;
+  case TopAbs_EDGE:
+    IS.ignore(sizeof(Standard_Real) + 3); // tolerance + 3 flags
+    do {
+      val = (Standard_Integer)IS.get();
+      switch (val) {
+      case 0:
+        break;
+      case 1:
+        IS.ignore(2 * sizeof(Standard_Integer) + 2 * sizeof(Standard_Real)); // curve and location indices + 2 parameters
+        break;
+      case 2: // -2- Curve on surf
+      case 3: // -3- Curve on closed surf
+        IS.ignore((val == 3 ? 4 : 3) * sizeof(Standard_Integer) + (val == 3 ? 1 : 0) + (FormatNb() >= 2 ? 6 : 2) * sizeof(Standard_Real));
+        break;
+      case 4: // -4- Regularity
+        IS.ignore(1 + 4 * sizeof(Standard_Integer)); // reg byte + surace + location + surface + location indices
+        break;
+      case 5: // -5- Polygon3D                     
+        IS.ignore(2 * sizeof(Standard_Integer)); // polygon + location indices
+        break;
+      case 6: // -6- Polygon on triangulation
+      case 7: // -7- Polygon on closed triangulation
+        IS.ignore((val == 7 ? 4 : 3) * sizeof(Standard_Integer)); // polygon + triangulation + location indices
+        break;
+      default:
+      {
+        Standard_SStream aMsg;
+        aMsg << "Unexpected Curve Representation =" << val << std::endl;
+        throw Standard_Failure(aMsg.str().c_str());
+      }
+      }
+    } while (val > 0);
+    break;
+  case TopAbs_WIRE:
+    break;
+  case TopAbs_FACE:
+    IS.ignore(1 + sizeof(Standard_Real) + 2 * sizeof(Standard_Integer)); // flag + tolerance + surface and location indices
+    if ((Standard_Byte)IS.get() == 2)
+      IS.ignore(sizeof(Standard_Integer)); // triangulation index
+  break;
+  case TopAbs_SHELL:
+    break;
+  case TopAbs_SOLID:
+    break;
+  case TopAbs_COMPSOLID:
+    break;
+  case TopAbs_COMPOUND:
+    break;
+  default:
+  {
+    Standard_SStream aMsg;
+    aMsg << "Unexpected topology type = " << T << std::endl;
+    throw Standard_Failure(aMsg.str().c_str());
+    break;
+  }
+  }
+}
 
 //=======================================================================
 //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);
 }
@@ -1555,6 +1719,7 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
         BinTools::GetInteger(IS, aTri.ChangeValue (2));
         BinTools::GetInteger(IS, aTri.ChangeValue (3));
       }
+      //IS.ignore(sizeof(Standard_Real) * (hasUV ? 5 : 3) * aNbNodes + sizeof(Standard_Integer) * 3 * aNbTriangles);
 
       myTriangulations.Add (aTriangulation);
     }
@@ -1574,5 +1739,5 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
 
 Standard_Integer  BinTools_ShapeSet::NbShapes() const
 {
-  return myShapes.Extent();
+  return myPostponed ? myShapesPositions.Length() : myShapes.Extent();
 }
index bbc171cfe0e57757ca178a6e92afe081d091d376..c3e486249f1c67badf3637bdc71d6c64e9b19a4b 100644 (file)
@@ -20,7 +20,9 @@
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
-#include <TopTools_IndexedMapOfShape.hxx>
+#include <NCollection_DoubleMap.hxx>
+#include <BinTools_FormatVersion.hxx>
+#include <NCollection_Sequence.hxx>
 #include <BinTools_LocationSet.hxx>
 #include <Standard_Integer.hxx>
 #include <BRep_Builder.hxx>
@@ -32,6 +34,8 @@
 #include <Standard_OStream.hxx>
 #include <Standard_IStream.hxx>
 #include <TopAbs_ShapeEnum.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+#include <TColStd_MapIntegerHasher.hxx>
 
 class TopoDS_Shape;
 class BinTools_LocationSet;
@@ -75,7 +79,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;
@@ -117,7 +121,8 @@ public:
   //! Reads the flag, the subshapes.
   Standard_EXPORT virtual void Read
     (Standard_IStream& IS,
-        const Message_ProgressRange& theRange = Message_ProgressRange());
+     const Standard_Boolean thePostponeShapes = Standard_False,
+     const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! Writes   on  <OS>   the shape   <S>.    Writes the
   //! orientation, the index of the TShape and the index
@@ -128,31 +133,40 @@ public:
   //! 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);
+
+  //! Passes in <IS> a shape flags and sub-shapes indices.
+  Standard_EXPORT virtual void PassFlagsAndSubs(Standard_IStream& IS);
+
+  //! 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);
+
+  //! Passes in the input stream of a shape of type <T>.
+  Standard_EXPORT virtual void PassShape (const TopAbs_ShapeEnum T, Standard_IStream& IS);
+
+  //! 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
@@ -196,7 +210,10 @@ public:
 
 private:
 
-  TopTools_IndexedMapOfShape myShapes;
+  NCollection_DoubleMap<int, TopoDS_Shape, TColStd_MapIntegerHasher, TopTools_ShapeMapHasher> myShapes; ///< index and its shape (started from 1)
+  NCollection_Sequence<std::streampos> myShapesPositions; ///< positions in the file of the shape start for postponed reading
+  Standard_Boolean myPostponed; ///< postponed reading stores buffer positions, but does not create shapes
+  Standard_IStream* myStream; ///< stream used for postponed reading of shapes
   BinTools_LocationSet myLocations;
   Standard_Integer myFormatNb;
   BRep_Builder myBuilder;
@@ -208,7 +225,6 @@ private:
   NCollection_IndexedMap<Handle(Poly_Triangulation), TColStd_MapTransientHasher> myTriangulations;
   NCollection_IndexedMap<Handle(Poly_PolygonOnTriangulation), TColStd_MapTransientHasher> myNodes;
   Standard_Boolean myWithTriangles;
-
 };
 
 #endif // _BinTools_ShapeSet_HeaderFile
index 3fbbd92e5eeceb1b35a7f8e8efe6638175803434..39875d9348fbaf04643932ece9cda6e8abf81047 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 d8ab7573b7bdb936cf9e153b72cd9b0a8be6122c..0333bc5c3227ec2cd860340880be202be27b91bb 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 fuctionality
-  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 7a1edcc4ac06e5ef627de9fc183476b840b18177..a55dc67e59f543fe1643542ccf7d129e755e3868 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 04bab120a90bccc60315800faaf535c51fd8d1f8..d6c7b35162e50a0d4e2c329dc7467a15253885ab 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
@@ -541,7 +572,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 f8b252d6f9452df713eee0d00098fe7ce591b53a..4bd85fb794fa4693cdb6501dbc07fa23abd315f6 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 4a751de4d31a879eb8b398e2cad2a6498c83b454..7621070936c4e45356f8f76d4fcd79a544b81192 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..9a74bb4
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <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();
+}
+
+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;
+  NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees);
+  for (; anEntry.More(); anEntry.Next()) {
+    if (theEntry.StartsWith (anEntry.Value()))
+    {
+      if (theEntry.Length() > anEntry.Value().Length() && // case when theEntry="0:10" should not match "0:1"
+        theEntry.Value (anEntry.Value().Length() + 1) != ':')
+        continue;
+      return true;
+    }
+  }
+  return false;
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPartTree()
+{
+  return !(mySubTrees.IsEmpty() || (mySubTrees.Size() == 1 && mySubTrees.First().Length() < 3));
+}
diff --git a/src/PCDM/PCDM_ReaderFilter.hxx b/src/PCDM/PCDM_ReaderFilter.hxx
new file mode 100644 (file)
index 0000000..b78a5c3
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _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);
+
+  //! 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 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; }
+
+  DEFINE_STANDARD_RTTIEXT (PCDM_ReaderFilter, Standard_Transient)
+
+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;
+};
+
+#endif // _PCDM_ReaderFilter_HeaderFile
index 7ef95c85f5b330b634ccc338e55dcc8264838f47..ff136e0c998156461489eaf92b81f419f7c8f6c1 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 c8e498ee8b89ddc6a3c17a29237f29ffd036df2e..821045f8fbf060549a859791406ca1721501e389 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 27f77042ad35df8c70cab37458f9b866114b0237..c18d4102df6e538eba61369cbf814bdea455b610 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,17 @@ 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));
+    Read(theIStream, theDoc, theFilter, theRange);
 
-    if (!D.IsNull())
+    if (!theDoc.IsNull() && (theFilter.IsNull() || !theFilter->IsAppendMode()))
     {
-      CDF_Application::Open(D);
-      theDoc = D;
+      CDF_Application::Open(theDoc);
     }
   }
 
@@ -346,7 +349,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 +358,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 +381,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 bc28787000483a474ccbcf0eb112797aedbb447e..b8ccd4d51e3d1b7fb862e752925465badc9f09dc 100644 (file)
@@ -65,7 +65,7 @@ DEFINE_STANDARD_HANDLE(TDocStd_Application, CDF_Application)
 //! the events during the Open/Store operation, a MessageDriver
 //! based on Message_PrinterOStream may be used. In case of need client
 //! can implement his own version inheriting from Message_Printer class 
-//! and add it to the Messanger.
+//! and add it to the Messenger.
 //! Also the trace level of messages can be tuned by setting trace level (SetTraceLevel (Gravity )) for the used Printer.
 //! By default, trace level is Message_Info, so that all messages are output.
 
@@ -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 fuctionality
-  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  <name> in the
   //! path <path>  .  overwrite  the file  if  it
   //! already exist.
-  Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& aDoc,
+  Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& theDoc,
                                            const TCollection_ExtendedString& path,
                                            TCollection_ExtendedString& theStatusMessage,
                                            const Message_ProgressRange& theRange = Message_ProgressRange());
@@ -272,7 +278,7 @@ public:
                                            const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! Save the document overwriting the previous file
-  Standard_EXPORT PCDM_StoreStatus Save (const Handle(TDocStd_Document)& aDoc,
+  Standard_EXPORT PCDM_StoreStatus Save (const Handle(TDocStd_Document)& theDoc,
                                          TCollection_ExtendedString& theStatusMessage,
                                          const Message_ProgressRange& theRange = Message_ProgressRange());
 
index b3798214f101b0e73c513ef38202e86a6907a0c8..5560f5ef504cf2c8d0752149da75e975ec0563ad 100644 (file)
@@ -376,7 +376,7 @@ Standard_Boolean TDocStd_Document::CommitTransaction()
 
     }
 
-    // deny or allow modifications acording to transaction state
+    // deny or allow modifications according to transaction state
     if(myOnlyTransactionModification) {
       myData->AllowModification (myUndoTransaction.IsOpen() && myUndoLimit
                                  ? Standard_True :Standard_False);
@@ -457,7 +457,7 @@ void TDocStd_Document::OpenTransaction()
 
   if (myUndoLimit != 0) myUndoTransaction.Open();
 
-  // deny or allow modifications acording to transaction state
+  // deny or allow modifications according to transaction state
   if (myOnlyTransactionModification) {
     myData->AllowModification (myUndoTransaction.IsOpen() && myUndoLimit
                                ? Standard_True :Standard_False);
@@ -490,7 +490,7 @@ void TDocStd_Document::SetUndoLimit(const Standard_Integer L)
     myUndos.RemoveFirst();
     --n;
   }
-  // deny or allow modifications acording to transaction state
+  // deny or allow modifications according to transaction state
   if(myOnlyTransactionModification) {
     myData->AllowModification(myUndoTransaction.IsOpen() && myUndoLimit
                               ? Standard_True :Standard_False);
@@ -549,7 +549,7 @@ void TDocStd_Document::ClearRedos()
 //=======================================================================
 //function : Undo
 //purpose  : 
-// Some importante notice:
+// Some important notice:
 // 1) The most recent undo delta is at the end of the list.
 // 2) Removing the LAST item of a list is tedious, but it is done only on
 //    Undo. Remove first is done at each command if the limit is reached!
@@ -623,7 +623,6 @@ Standard_Boolean TDocStd_Document::Redo()
 {
   Standard_Boolean isOpened = myUndoTransaction.IsOpen();
   Standard_Boolean undoDone = Standard_False;
-  // TDF_Label currentObjectLabel = CurrentLabel();//Sauve pour usage ulterieur.
   if (!myRedos.IsEmpty()) {
     // should test the applicability before.
     // Reset the transaction
@@ -654,7 +653,7 @@ Standard_Boolean TDocStd_Document::Redo()
   
   if (isOpened && undoDone) OpenTransaction();
 
-  // deny or allow modifications acording to transaction state
+  // deny or allow modifications according to transaction state
   if(myOnlyTransactionModification) {
     myData->AllowModification(myUndoTransaction.IsOpen() && myUndoLimit
                               ? Standard_True :Standard_False);
@@ -924,7 +923,7 @@ void TDocStd_Document::ChangeStorageFormatVersion(const TDocStd_FormatVersion th
 
 //=======================================================================
 //function : CurrentStorageFormatVersion
-//purpose  : Returns current storage format verison of the document.
+//purpose  : Returns current storage format version of the document.
 //=======================================================================
 TDocStd_FormatVersion TDocStd_Document::CurrentStorageFormatVersion()
 {
index f737cb3e02d13039e25de329961804e1226f1730..9ed84f96a38c4058f0e2b60d12ced476436fc075 100644 (file)
@@ -55,6 +55,7 @@
 #include <TDocStd_Application.hxx>
 #include <TDocStd_Document.hxx>
 #include <TDocStd_Owner.hxx>
+#include <PCDM_ReaderFilter.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TPrsStd_AISPresentation.hxx>
@@ -206,31 +207,65 @@ static Standard_Integer openDoc (Draw_Interpretor& di, Standard_Integer argc, co
   Handle(DDocStd_DrawDocument) DD;
   Handle(TDocStd_Application) A = DDocStd::GetApplication();
 
-  if ( argc != 3 )
+  if ( argc < 3 )
   {
-    di << "invalid number of arguments. Usage:\t XOpen filename docname\n";
+    di << "invalid number of arguments. Usage:\t XOpen filename docname [-skipAttribute] [-readAttribute] [-readPath] [-append|-overwrite]\n";
     return 1;
   }
 
   TCollection_AsciiString Filename = argv[1];
   Standard_CString DocName = argv[2];
 
-  if ( DDocStd::GetDocument(DocName, D, Standard_False) )
+  Handle(PCDM_ReaderFilter) aFilter = new PCDM_ReaderFilter;
+  for (Standard_Integer i = 3; i < argc; i++)
   {
-    di << "document with name " << DocName << " already exists\n";
+    TCollection_AsciiString anArg(argv[i]);
+    if (anArg == "-append")
+    {
+      aFilter->Mode() = PCDM_ReaderFilter::AppendMode_Protect;
+    }
+    else if (anArg == "-overwrite")
+    {
+      aFilter->Mode() = PCDM_ReaderFilter::AppendMode_Overwrite;
+    }
+    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);
-  if ( A->Open(Filename, D, aProgress->Start()) != PCDM_RS_OK )
+  if ( A->Open (Filename, D, aFilter, aProgress->Start()) != PCDM_RS_OK )
   {
     di << "cannot open XDE document\n";
     return 1;
   }
 
-  DD = new DDocStd_DrawDocument(D);
-  TDataStd_Name::Set(D->GetData()->Root(), DocName);
-  Draw::Set(DocName, DD);
+  if (!aFilter->IsAppendMode())
+  {
+    DD = new DDocStd_DrawDocument (D);
+    TDataStd_Name::Set (D->GetData()->Root(), DocName);
+    Draw::Set (DocName, DD);
+  }
 
   di << "document " << DocName << " opened\n";
 
@@ -1443,8 +1478,13 @@ void XDEDRAW::Init(Draw_Interpretor& di)
   di.Add ("XSave","[Doc Path] \t: Save Doc or first document in session",
                   __FILE__, saveDoc, g);
 
-  di.Add ("XOpen","Path Doc \t: Open XDE Document with name Doc from Path",
-          __FILE__, openDoc, g);
+  di.Add ("XOpen","Path Doc [-skipAttribute] [-readAttribute] [-readPath] [-append|-overwrite]\t: Open XDE Document with name Doc from Path"
+          "\n\t\t The options are:"
+          "\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__, openDoc, g);
 
   di.Add ("Xdump","Doc [int deep (0/1)] \t: Print information about tree's structure",
                   __FILE__, dump, g);
index af8426a971fdb7df0ba8a44e5ab58cd0d23a0321..0980fc08d1e77e73d307c73abae8c63e7bdec764 100644 (file)
@@ -169,6 +169,7 @@ void XmlLDrivers_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)
 {
   myReaderStatus = PCDM_RS_DriverFailure;
@@ -179,7 +180,7 @@ void XmlLDrivers_DocumentRetrievalDriver::Read
 
   if (aFileStream.is_open() && aFileStream.good())
   {
-    Read (aFileStream, NULL, theNewDocument, theApplication, theRange);
+    Read (aFileStream, NULL, theNewDocument, theApplication, theFilter, theRange);
   }
   else
   {
@@ -201,6 +202,7 @@ void XmlLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&              t
                                                 const Handle(Storage_Data)&    /*theStorageData*/,
                                                 const Handle(CDM_Document)&    theNewDocument,
                                                 const Handle(CDM_Application)& theApplication,
+                                                const Handle(PCDM_ReaderFilter)& /*theFilter*/,
                                                 const Message_ProgressRange&   theRange)
 {
   Handle(Message_Messenger) aMessageDriver = theApplication -> MessageDriver();
index 6617c9cb5a0b08b5a258d89b8d17923c13f19026..5e2edc9f1aa40edc13394a37bb18f67cc40c22c1 100644 (file)
@@ -50,12 +50,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& theRange = 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& theRange= Message_ProgressRange()) Standard_OVERRIDE;
   
   Standard_EXPORT virtual Handle(XmlMDF_ADriverTable) AttributeDrivers (const Handle(Message_Messenger)& theMsgDriver);
diff --git a/tests/bugs/caf/bug31839_1 b/tests/bugs/caf/bug31839_1
new file mode 100644 (file)
index 0000000..b72372b
--- /dev/null
@@ -0,0 +1,141 @@
+puts "==========="
+puts "0031839: Application Framework - Add ability to partially load OCAF document"
+puts "==========="
+
+# This test checks partial opening of the document with integer and real attributes
+# and then partial appending (reading into the same document).
+
+NewDocument D0 BinOcaf
+UndoLimit D0 10
+
+# number of labels of objects in the document
+set labs 100
+# number of sub-labels of each object
+set sublabs 10
+
+NewCommand D0
+
+# store at each object-label sub-labels with two attributes at each
+set creation_time [lindex [time {
+  for {set i 1} {$i <= $labs} {incr i} {
+    set lab [Label D0 0:1:${i}]
+    SetName D0 ${lab} Object$i
+    for {set ii 1} {$ii <= $sublabs} {incr ii} {
+      set sublab [Label D0 ${lab}:$ii]
+      SetInteger D0 ${sublab} 10
+      SetReal D0 ${sublab} 12.3
+    }
+  }
+}] 0]
+
+set commit_time [lindex [time {
+  CommitCommand D0
+}] 0]
+
+
+puts "Tree creation time $creation_time mcs"
+puts "Creation commit time $commit_time mcs"
+
+set docname ${imagedir}/doc_${casename}.cbf
+SaveAs D0 ${docname}
+Close D0
+
+set open_time [lindex [time {
+  Open ${docname} D1
+}] 0]
+
+puts "Full document open time $open_time mcs"
+
+set attributes [Attributes D1 0:1:1:1]
+if {[lsearch $attributes TDataStd_Real] < 0 || [lsearch $attributes TDataStd_Integer] < 0} {
+  puts "Error: full document is opened incorrectly"
+}
+
+Close D1
+
+set open_noint_time [lindex [time {
+  Open ${docname} D2 -skipTDataStd_Integer
+}] 0]
+
+puts "Document without integers open time $open_noint_time mcs"
+
+set attributes [Attributes D2 0:1:1:1]
+if {[lsearch $attributes TDataStd_Real] < 0 || [lsearch $attributes TDataStd_Integer] >= 0} {
+  puts "Error: document open without integers contains wrong attributes"
+}
+
+set open_oneint_time [lindex [time {
+  Open ${docname} D2 -append -read0:1:1:1
+}] 0]
+
+puts "Read of one integer time $open_oneint_time mcs"
+
+set attributes [Attributes D2 0:1:1:1]
+if {[lsearch $attributes TDataStd_Real] < 0 || [lsearch $attributes TDataStd_Integer] < 0} {
+  puts "Error: document open with one integer contains wrong attributes"
+}
+
+set attributes [Attributes D2 0:1:1:10]
+if {[lsearch $attributes TDataStd_Real] < 0 || [lsearch $attributes TDataStd_Integer] >= 0} {
+  puts "Error: document open with one integer contains wrong attributes at label 10"
+}
+
+set open_nineint_time [lindex [time {
+  Open ${docname} D2 -append -read0:1:1
+}] 0]
+puts "Read of nine integer time $open_nineint_time mcs"
+
+set attributes [Attributes D2 0:1:1:10]
+if {[lsearch $attributes TDataStd_Real] < 0 || [lsearch $attributes TDataStd_Integer] < 0} {
+  puts "Error: document open with nine integer contains wrong attributes at label 10"
+}
+
+set attributes [Attributes D2 0:1:1:5]
+if {[lsearch $attributes TDataStd_Real] < 0 || [lsearch $attributes TDataStd_Integer] < 0} {
+  puts "Error: document open with nine integer contains wrong attributes at label 5"
+}
+
+set attributes [Attributes D2 0:1:2:5]
+if {[lsearch $attributes TDataStd_Real] < 0 || [lsearch $attributes TDataStd_Integer] >= 0} {
+  puts "Error: document open with nine integer contains wrong attributes at the second object"
+}
+
+SetInteger D2 0:1:1:5 21
+SetReal D2 0:1:1:7 32.1
+
+set open_overwrite_time [lindex [time {
+  Open ${docname} D2 -overwrite -read0:1:1
+}] 0]
+puts "Overwrite of ten integers time $open_overwrite_time mcs"
+
+
+set value [GetInteger D2 0:1:1:5]
+if {$value != 10} {
+  puts "Error: integer is overwritten incorrectly"
+}
+
+set value [GetReal D2 0:1:1:7]
+if {$value != 12.3} {
+  puts "Error: real is overwritten incorrectly"
+}
+
+SetInteger D2 0:1:1:5 21
+SetReal D2 0:1:1:7 32.1
+
+set open_append_time [lindex [time {
+  Open ${docname} D2 -append -read0:1:1
+}] 0]
+puts "Append of ten integers time $open_overwrite_time mcs"
+
+
+set value [GetInteger D2 0:1:1:5]
+if {$value != 21} {
+  puts "Error: integer is overwritten by append"
+}
+
+set value [GetReal D2 0:1:1:7]
+if {$value != 32.1} {
+  puts "Error: real is overwritten by append"
+}
+
+Close D2
diff --git a/tests/bugs/caf/bug31839_2 b/tests/bugs/caf/bug31839_2
new file mode 100644 (file)
index 0000000..d72cdb1
--- /dev/null
@@ -0,0 +1,55 @@
+puts "==========="
+puts "0031839: Application Framework - Add ability to partially load OCAF document"
+puts "==========="
+
+# This test checks partial opening of the document shapes, append and overwrite modes
+# for them checking that after overwrite the shapes keep shared topology.
+
+NewDocument D0 BinOcaf
+UndoLimit D0 10
+
+NewCommand D0
+
+box b 1 2 3
+explode b F
+
+SetShape D0 0:1 b
+for {set i 1} {$i <= 6} {incr i} {
+  set lab [Label D0 0:1:${i}]
+  SetShape D0 ${lab} b_${i}
+}
+
+CommitCommand D0
+
+set docname ${imagedir}/doc_${casename}.cbf
+SaveAs D0 ${docname}
+Close D0
+
+# open document with shapes skipped
+Open ${docname} D1 -skipTNaming_NamedShape
+if {![catch {GetShape D1 0:1 b1}]} {
+  puts "Error: found box at the label 0:1, but it should not be there"
+}
+if {![catch {GetShape D1 0:1:1 f0}]} {
+  puts "Error: found face at the label 0:1:1, but it should not be there"
+}
+
+# append one face
+Open ${docname} D1 -append -read0:1:1
+
+if {[catch {GetShape D1 0:1:1 f1}]} {
+  puts "Error: Can not find face at the label 0:1:1"
+}
+if {![catch {GetShape D1 0:1:2 f2}]} {
+  puts "Error: found face at the label 0:1:2, but it should not be there"
+}
+
+# append others, rewrite the first face
+Open ${docname} D1 -overwrite
+GetShape D1 0:1 box
+GetShape D1 0:1:1 f11
+
+set same [CheckSame box f11 F]
+if {$same == ""} {
+  puts "Error: shapes loaded in append mode do not share subshapes (so, face at 0:1:1 was not replaced)"
+}
index 5595338005a595f55d9a775cbcd1ea7416245848..6bd7155ea419c5ac268af7e5f8be8013adef5975 100644 (file)
@@ -25,7 +25,7 @@ set output [Open ${bDoc} Doc]
 Close Doc
 
 # Test data
-set ctr {"0%" "Reading data" "Reading geomentry" "Reading curves 2d"
+set ctr {"0%" "Reading data" "Reading geometry" "Reading curves 2d"
  "Reading surfaces" "Reading Shapes" "Reading sub tree" "100%" }
 
 foreach data ${ctr} {