From: mpv Date: Sat, 2 Jan 2021 10:59:40 +0000 (+0300) Subject: 0031839: Application Framework - Add ability to partially load OCAF document X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=47e489e84d388b09154602c8db0c2db060dce97b;p=occt-copy.git 0031839: Application Framework - Add ability to partially load OCAF document 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 --- diff --git a/dox/user_guides/ocaf/ocaf.md b/dox/user_guides/ocaf/ocaf.md index 80dc90e74f..8de7c08d3c 100644 --- a/dox/user_guides/ocaf/ocaf.md +++ b/dox/user_guides/ocaf/ocaf.md @@ -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*. diff --git a/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.cxx b/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.cxx index bc36e96af1..e7dde6a91b 100644 --- a/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.cxx +++ b/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.cxx @@ -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 diff --git a/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.hxx b/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.hxx index f7c51d7bd5..836edd6f3d 100644 --- a/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.hxx +++ b/src/BinDrivers/BinDrivers_DocumentRetrievalDriver.hxx @@ -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 diff --git a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx index 686e585359..39c6955283 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx +++ b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx @@ -40,9 +40,11 @@ #include #include #include +#include #include #include #include +#include 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*/) { diff --git a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx index 7b9325af5c..5c77e85149 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx +++ b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx @@ -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); diff --git a/src/BinMNaming/BinMNaming_NamedShapeDriver.cxx b/src/BinMNaming/BinMNaming_NamedShapeDriver.cxx index 767c19d8ff..bb79761d35 100644 --- a/src/BinMNaming/BinMNaming_NamedShapeDriver.cxx +++ b/src/BinMNaming/BinMNaming_NamedShapeDriver.cxx @@ -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 diff --git a/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx b/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx index 4e15ab7829..54bd4bc7f2 100644 --- a/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx +++ b/src/BinMNaming/BinMNaming_NamedShapeDriver.hxx @@ -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 diff --git a/src/BinTools/BinTools.cxx b/src/BinTools/BinTools.cxx index 16237e5a87..32f6a77688 100644 --- a/src/BinTools/BinTools.cxx +++ b/src/BinTools/BinTools.cxx @@ -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()); } //======================================================================= diff --git a/src/BinTools/BinTools_ShapeSet.cxx b/src/BinTools/BinTools_ShapeSet.cxx index eaec192d4a..bcb4aeb54c 100644 --- a/src/BinTools/BinTools_ShapeSet.cxx +++ b/src/BinTools/BinTools_ShapeSet.cxx @@ -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 < 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(); } diff --git a/src/BinTools/BinTools_ShapeSet.hxx b/src/BinTools/BinTools_ShapeSet.hxx index bbc171cfe0..c3e486249f 100644 --- a/src/BinTools/BinTools_ShapeSet.hxx +++ b/src/BinTools/BinTools_ShapeSet.hxx @@ -20,7 +20,9 @@ #include #include -#include +#include +#include +#include #include #include #include @@ -32,6 +34,8 @@ #include #include #include +#include +#include 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 . - 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 . 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 the shape . 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 . Standard_EXPORT virtual void ReadGeometry (Standard_IStream& IS, - const Message_ProgressRange& theRange = Message_ProgressRange()); + const Message_ProgressRange& theRange = Message_ProgressRange()); - //! Reads from a shape and returns it in S. + //! Reads from 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 a shape and returns it in S. //! 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 on the stream in a + Standard_EXPORT virtual void ReadSubs + (TopoDS_Shape& S, Standard_IStream& IS, const Standard_Integer NbShapes); + + //! Passes in a shape flags and sub-shapes indices. + Standard_EXPORT virtual void PassFlagsAndSubs(Standard_IStream& IS); + + //! Writes the shape on the stream 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 from the - //! stream and returns it in . - 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 . - Standard_EXPORT virtual void AddGeometry (const TopoDS_Shape& S); + //! Reads a shape of type from the stream and returns it in . + 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 . + Standard_EXPORT virtual void PassShape (const TopAbs_ShapeEnum T, Standard_IStream& IS); + + //! Stores the shape . + Standard_EXPORT virtual void AddShape (const TopoDS_Shape& S); - //! Inserts the shape in the shape . + //! Inserts the shape in the shape . 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 myShapes; ///< index and its shape (started from 1) + NCollection_Sequence 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 myTriangulations; NCollection_IndexedMap myNodes; Standard_Boolean myWithTriangles; - }; #endif // _BinTools_ShapeSet_HeaderFile diff --git a/src/CDF/CDF_Application.cxx b/src/CDF/CDF_Application.cxx index 3fbbd92e5e..39875d9348 100644 --- a/src/CDF/CDF_Application.cxx +++ b/src/CDF/CDF_Application.cxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -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); } //======================================================================= diff --git a/src/CDF/CDF_Application.hxx b/src/CDF/CDF_Application.hxx index d8ab7573b7..0333bc5c32 100644 --- a/src/CDF/CDF_Application.hxx +++ b/src/CDF/CDF_Application.hxx @@ -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: diff --git a/src/CDM/CDM_Application.hxx b/src/CDM/CDM_Application.hxx index 7a1edcc4ac..a55dc67e59 100644 --- a/src/CDM/CDM_Application.hxx +++ b/src/CDM/CDM_Application.hxx @@ -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. diff --git a/src/DDocStd/DDocStd_ApplicationCommands.cxx b/src/DDocStd/DDocStd_ApplicationCommands.cxx index 04bab120a9..d6c7b35162 100644 --- a/src/DDocStd/DDocStd_ApplicationCommands.cxx +++ b/src/DDocStd/DDocStd_ApplicationCommands.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -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", diff --git a/src/PCDM/FILES b/src/PCDM/FILES index f8b252d6f9..4bd85fb794 100755 --- a/src/PCDM/FILES +++ b/src/PCDM/FILES @@ -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 diff --git a/src/PCDM/PCDM_Reader.hxx b/src/PCDM/PCDM_Reader.hxx index 4a751de4d3..7621070936 100644 --- a/src/PCDM/PCDM_Reader.hxx +++ b/src/PCDM/PCDM_Reader.hxx @@ -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 index 0000000000..9a74bb4d89 --- /dev/null +++ b/src/PCDM/PCDM_ReaderFilter.cxx @@ -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 + +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::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 index 0000000000..b78a5c3933 --- /dev/null +++ b/src/PCDM/PCDM_ReaderFilter.hxx @@ -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 +#include +#include +#include +#include + +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 mySkip; + // Class names of only attributes to read (if it is not empty, mySkip is unused) + NCollection_Map myRead; + // Paths to the labels that must be read. If it is empty, read all. + NCollection_List mySubTrees; +}; + +#endif // _PCDM_ReaderFilter_HeaderFile diff --git a/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.cxx b/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.cxx index 7ef95c85f5..ff136e0c99 100644 --- a/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.cxx +++ b/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.cxx @@ -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"); diff --git a/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.hxx b/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.hxx index c8e498ee8b..821045f8fb 100644 --- a/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.hxx +++ b/src/StdLDrivers/StdLDrivers_DocumentRetrievalDriver.hxx @@ -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) diff --git a/src/TDocStd/TDocStd_Application.cxx b/src/TDocStd/TDocStd_Application.cxx index 27f77042ad..c18d4102df 100644 --- a/src/TDocStd/TDocStd_Application.cxx +++ b/src/TDocStd/TDocStd_Application.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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 = "< in the //! 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 in the //! 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()); diff --git a/src/TDocStd/TDocStd_Document.cxx b/src/TDocStd/TDocStd_Document.cxx index b3798214f1..5560f5ef50 100644 --- a/src/TDocStd/TDocStd_Document.cxx +++ b/src/TDocStd/TDocStd_Document.cxx @@ -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() { diff --git a/src/XDEDRAW/XDEDRAW.cxx b/src/XDEDRAW/XDEDRAW.cxx index f737cb3e02..9ed84f96a3 100644 --- a/src/XDEDRAW/XDEDRAW.cxx +++ b/src/XDEDRAW/XDEDRAW.cxx @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx b/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx index af8426a971..0980fc08d1 100644 --- a/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx +++ b/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx @@ -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(); diff --git a/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.hxx b/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.hxx index 6617c9cb5a..5e2edc9f1a 100644 --- a/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.hxx +++ b/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.hxx @@ -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 index 0000000000..b72372ba09 --- /dev/null +++ b/tests/bugs/caf/bug31839_1 @@ -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 index 0000000000..d72cdb1af1 --- /dev/null +++ b/tests/bugs/caf/bug31839_2 @@ -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)" +} diff --git a/tests/caf/progress/B1 b/tests/caf/progress/B1 index 5595338005..6bd7155ea4 100644 --- a/tests/caf/progress/B1 +++ b/tests/caf/progress/B1 @@ -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} {