Implementation of new format for quick reading and writing parts of the documents. It consists in writing shapes and all their contents right in the TNaming_NamedShape attribute placement and skipping the shape section.
For the current moment it is implemented as a new version 11 of the binary format. It will be decided later to have it like this and make this version of the format as default, or setting a special flag for such version reading/writing.
Modifications:
BinLDrivers and BinDrivers packages - modifications related to the quick part tree format flag usage, skipping shape section writing and adding labels sizes into the document to be able to pass labels during the reading quickly.
BinObjMgt_Persistent amd BinObjMgt_Position - to add possibility to write directly into the stream some data just after the attribute. Before this record a data-size is recorded.
BinMXCAFDoc package modifications to write BinMXCAFDoc_LocationDriver location in the same way as shapes write location data right after the attribute (empty) data in this new format.
BinTools package: creation of ShapeReader and ShapeWriter classes with same root class ShapeSetBase with ShapeSet class. These classes allows to write/read shapes directly to the stream. If some object is already in the stream, write a reference - relative position of the duplicated object.
PCDM_ReaderFilter - modified to be able to browse labels tree quickly, without usage of referencing by entry-strings.
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*.
#include <Standard_Failure.hxx>
#include <Standard_IStream.hxx>
#include <Standard_Type.hxx>
+#include <Standard_NotImplemented.hxx>
#include <TCollection_ExtendedString.hxx>
#include <TNaming_NamedShape.hxx>
BinLDrivers_DocumentRetrievalDriver::Clear();
}
+//=======================================================================
+//function : EnableQuickPartReading
+//purpose :
+//=======================================================================
+void BinDrivers_DocumentRetrievalDriver::EnableQuickPartReading(
+ const Handle(Message_Messenger)& theMessageDriver, Standard_Boolean theValue)
+{
+ if (myDrivers.IsNull())
+ myDrivers = AttributeDrivers(theMessageDriver);
+ if (myDrivers.IsNull())
+ return;
+ Handle(BinMDF_ADriver) aDriver;
+ myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver);
+ Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+ if (aShapesDriver.IsNull())
+ throw Standard_NotImplemented("Internal Error - TNaming_NamedShape is not found!");
+
+ aShapesDriver->EnableQuickPart(theValue);
+}
//! Clears the NamedShape driver
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+ //! Enables reading in the quick part access mode.
+ Standard_EXPORT virtual void EnableQuickPartReading
+ (const Handle(Message_Messenger)& theMessageDriver, Standard_Boolean theValue) Standard_OVERRIDE;
+
DEFINE_STANDARD_RTTIEXT(BinDrivers_DocumentRetrievalDriver,BinLDrivers_DocumentRetrievalDriver)
aShapesDriver->SetWithTriangles (theWithTriangulation);
}
+void BinDrivers_DocumentStorageDriver::EnableQuickPartWriting(const Handle(Message_Messenger)& theMessageDriver,
+ const Standard_Boolean theValue)
+{
+ if (myDrivers.IsNull())
+ {
+ myDrivers = AttributeDrivers(theMessageDriver);
+ }
+ if (myDrivers.IsNull())
+ {
+ return;
+ }
+
+ Handle(BinMDF_ADriver) aDriver;
+ myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver);
+ Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+ if (aShapesDriver.IsNull())
+ {
+ throw Standard_NotImplemented("Internal Error - TNaming_NamedShape is not found!");
+ }
+
+ aShapesDriver->EnableQuickPart(theValue);
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void BinDrivers_DocumentStorageDriver::Clear()
+{
+ // Clear NamedShape driver
+ Handle(BinMDF_ADriver) aDriver;
+ if (myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver))
+ {
+ Handle(BinMNaming_NamedShapeDriver) aNamedShapeDriver =
+ Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+ aNamedShapeDriver->Clear();
+ }
+ BinLDrivers_DocumentStorageDriver::Clear();
+}
+
//=======================================================================
//function : IsWithNormals
//purpose :
Standard_EXPORT void SetWithNormals(const Handle(Message_Messenger)& theMessageDriver,
const Standard_Boolean theWithTriangulation);
+ //! Enables writing in the quick part access mode.
+ Standard_EXPORT void EnableQuickPartWriting(const Handle(Message_Messenger)& theMessageDriver,
+ const Standard_Boolean theValue) Standard_OVERRIDE;
+
+ //! Clears the NamedShape driver
+ Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+
DEFINE_STANDARD_RTTIEXT(BinDrivers_DocumentStorageDriver,BinLDrivers_DocumentStorageDriver)
};
#include <TDF_Attribute.hxx>
#include <TDF_Data.hxx>
#include <TDF_Label.hxx>
+#include <TDF_Tool.hxx>
#include <TDocStd_Document.hxx>
#include <TDocStd_FormatVersion.hxx>
#include <TDocStd_Owner.hxx>
#include <Message_ProgressScope.hxx>
+#include <PCDM_ReaderFilter.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentRetrievalDriver,PCDM_RetrievalDriver)
#define SHAPESECTION_POS "SHAPE_SECTION_POS:"
+#define ENDSECTION_POS ":"
#define SIZEOFSHAPELABEL 18
#define DATATYPE_MIGRATION
(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;
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;
//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();
Standard_Boolean begin = Standard_False;
Standard_Integer i;
for (i=1; i <= aUserInfo.Length(); i++) {
- //const TCollection_AsciiString& aStr = aUserInfo(i);
TCollection_AsciiString aStr = aUserInfo(i);
if (aStr == START_TYPES)
begin = Standard_True;
myRelocTable.SetHeaderData(aHeaderData);
mySections.Clear();
myPAtt.Init();
- Handle(TDF_Data) aData = new TDF_Data();
+ Handle(TDF_Data) aData = (!theFilter.IsNull() && theFilter->IsAppendMode()) ? aDoc->GetData() : new TDF_Data();
std::streampos aDocumentPos = -1;
- Message_ProgressScope aPS(theRange, "Reading data", 3);
+ Message_ProgressScope aPS (theRange, "Reading data", 3);
+ Standard_Boolean aQuickPart = IsQuickPart (aFileVer);
// 2b. Read the TOC of Sections
if (aFileVer >= TDocStd_FormatVersion_VERSION_3) {
do {
BinLDrivers_DocumentSection::ReadTOC (aSection, theIStream, aFileVer);
mySections.Append(aSection);
- } while(!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS) && !theIStream.eof());
+ } while (!aSection.Name().IsEqual ((Standard_CString)
+ (aQuickPart ? ENDSECTION_POS : SHAPESECTION_POS)) && !theIStream.eof());
if (theIStream.eof()) {
// There is no shape section in the file.
return;
}
}
- else
+ else if (!aCurSection.Name().IsEqual ((Standard_CString)ENDSECTION_POS))
ReadSection (aCurSection, theDoc, theIStream);
}
}
Standard_Integer aTag;
theIStream.read ((char*)&aTag, sizeof(Standard_Integer));
+ if (aQuickPart)
+ myPAtt.SetIStream (theIStream); // for reading shapes data from the stream directly
+ EnableQuickPartReading (myMsgDriver, aQuickPart);
+
// read sub-tree of the root label
- Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), aPS.Next());
+ if (!theFilter.IsNull())
+ theFilter->StartIteration();
+ Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), theFilter, aQuickPart, aPS.Next());
if (!aPS.More())
{
myReaderStatus = PCDM_RS_UserBreak;
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;
}
//=======================================================================
Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
- (Standard_IStream& theIS,
- const TDF_Label& theLabel,
- const Message_ProgressRange& theRange)
+(Standard_IStream& theIS,
+ const TDF_Label& theLabel,
+ const Handle(PCDM_ReaderFilter)& theFilter,
+ const Standard_Boolean& theQuickPart,
+ const Message_ProgressRange& theRange)
{
Standard_Integer nbRead = 0;
TCollection_ExtendedString aMethStr
- ("BinLDrivers_DocumentRetrievalDriver: ");
+ ("BinLDrivers_DocumentRetrievalDriver: ");
Message_ProgressScope aPS(theRange, "Reading sub tree", 2, true);
+ bool aSkipAttrs = Standard_False;
+ if (!theFilter.IsNull() && theFilter->IsPartTree())
+ aSkipAttrs = !theFilter->IsPassed();
+
+ if (theQuickPart)
+ {
+ uint64_t aLabelSize = 0;
+ theIS.read((char*)&aLabelSize, sizeof(uint64_t));
+#if DO_INVERSE
+ aLabelSize = InverseUint64(aLabelSize);
+#endif
+ // no one sub-label is needed, so, skip everything
+ if (aSkipAttrs && !theFilter->IsSubPassed())
+ {
+ aLabelSize -= sizeof (uint64_t);
+ theIS.seekg (aLabelSize, std::ios_base::cur);
+ if (!theFilter.IsNull())
+ theFilter->Up();
+ return 0;
+ }
+ }
+
// Read attributes:
- theIS >> myPAtt;
- while (theIS && myPAtt.TypeId() > 0 && // not an end marker ?
- myPAtt.Id() > 0 && // not a garbage ?
- !theIS.eof())
+ for (theIS >> myPAtt;
+ theIS && myPAtt.TypeId() > 0 && // not an end marker ?
+ myPAtt.Id() > 0 && // not a garbage ?
+ !theIS.eof();
+ theIS >> myPAtt)
{
if (!aPS.More())
{
myReaderStatus = PCDM_RS_UserBreak;
return -1;
}
-
+ if (aSkipAttrs)
+ {
+ if (myPAtt.IsDirect()) // skip direct written stream
+ {
+ uint64_t aStreamSize = 0;
+ theIS.read ((char*)&aStreamSize, sizeof (uint64_t));
+ aStreamSize -= sizeof (uint64_t); // size is already passed, so, reduce it by size
+ theIS.seekg (aStreamSize, std::ios_base::cur);
+ }
+ continue;
+ }
+
// get a driver according to TypeId
- Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (myPAtt.TypeId());
+ Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver(myPAtt.TypeId());
if (!aDriver.IsNull()) {
// create transient attribute
- nbRead++;
Standard_Integer anID = myPAtt.Id();
Handle(TDF_Attribute) tAtt;
Standard_Boolean isBound = myRelocTable.IsBound(anID);
else
tAtt = aDriver->NewEmpty();
+ if (!theFilter.IsNull() && !theFilter->IsPassed (tAtt->DynamicType())) {
+ if (myPAtt.IsDirect()) // skip direct written stream
+ {
+ uint64_t aStreamSize = 0;
+ theIS.read ((char*)&aStreamSize, sizeof (uint64_t));
+ aStreamSize -= sizeof (uint64_t); // size is already passed, so, reduce it by size
+ theIS.seekg (aStreamSize, std::ios_base::cur);
+ }
+ continue;
+ }
+ nbRead++;
+
if (tAtt->Label().IsNull())
{
+ if (!theFilter.IsNull() && theFilter->Mode() != PCDM_ReaderFilter::AppendMode_Forbid && theLabel.IsAttribute(tAtt->ID()))
+ {
+ if (theFilter->Mode() == PCDM_ReaderFilter::AppendMode_Protect)
+ continue; // do not overwrite the existing attribute
+ if (theFilter->Mode() == PCDM_ReaderFilter::AppendMode_Overwrite)
+ theLabel.ForgetAttribute(tAtt->ID()); // forget old attribute to write a new one
+ }
try
{
- theLabel.AddAttribute (tAtt);
+ theLabel.AddAttribute(tAtt);
}
catch (const Standard_DomainError&)
{
// 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;
}
// 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;
// read sub-tree
- Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, aPS.Next());
+ if (!theFilter.IsNull())
+ theFilter->Down (aTag);
+ Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, theFilter, theQuickPart, aPS.Next());
// check for error
if (nbSubRead == -1)
return -1;
nbRead += nbSubRead;
// read the tag of the next child
- theIS.read ((char*) &aTag, sizeof(Standard_Integer));
+ theIS.read((char*)&aTag, sizeof(Standard_Integer));
#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;
}
+ if (!theFilter.IsNull())
+ theFilter->Up();
return nbRead;
}
//function : CheckShapeSection
//purpose :
//=======================================================================
-void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection(
- const Storage_Position& ShapeSectionPos,
- Standard_IStream& IS)
+void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection
+ (const Storage_Position& ShapeSectionPos, Standard_IStream& IS)
{
if (!IS.eof())
{
- const std::streamoff endPos = IS.rdbuf()->pubseekoff(0L, std::ios_base::end, std::ios_base::in);
+ const std::streamoff endPos = IS.rdbuf()->pubseekoff (0L, std::ios_base::end, std::ios_base::in);
#ifdef OCCT_DEBUG
std::cout << "endPos = " << endPos <<std::endl;
#endif
//function : CheckDocumentVersion
//purpose :
//=======================================================================
-Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion(
- const Standard_Integer theFileVersion,
- const Standard_Integer theCurVersion)
+Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion
+ (const Standard_Integer theFileVersion, const Standard_Integer theCurVersion)
{
if (theFileVersion < TDocStd_FormatVersion_LOWER || theFileVersion > theCurVersion) {
// file was written with another version
}
return Standard_True;
}
+
+//=======================================================================
+//function : IsQuickPart
+//purpose :
+//=======================================================================
+Standard_Boolean BinLDrivers_DocumentRetrievalDriver::IsQuickPart (const Standard_Integer theFileVer)
+{
+ return theFileVer >= TDocStd_FormatVersion_VERSION_12;
+}
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);
Standard_EXPORT virtual Standard_Integer ReadSubTree
(Standard_IStream& theIS,
const TDF_Label& theData,
- const Message_ProgressRange& theRanges = Message_ProgressRange());
+ const Handle(PCDM_ReaderFilter)& theFilter,
+ const Standard_Boolean& theQuickPart,
+ const Message_ProgressRange& theRanges = Message_ProgressRange());
//! define the procedure of reading a section to file.
//! define the procedure of reading a shapes section to file.
Standard_EXPORT virtual void ReadShapeSection
- (BinLDrivers_DocumentSection& theSection,
- Standard_IStream& theIS,
- const Standard_Boolean isMess = Standard_False,
- const Message_ProgressRange& theRange = Message_ProgressRange());
+ (BinLDrivers_DocumentSection& theSection,
+ Standard_IStream& theIS,
+ const Standard_Boolean isMess = Standard_False,
+ const Message_ProgressRange& theRange = Message_ProgressRange());
//! checks the shapes section can be correctly retreived.
Standard_EXPORT virtual void CheckShapeSection (const Storage_Position& thePos, Standard_IStream& theIS);
//! current or lesser than 2, then return false, else true
Standard_EXPORT virtual Standard_Boolean CheckDocumentVersion (const Standard_Integer theFileVersion, const Standard_Integer theCurVersion);
+ //! Return true if document retrieved document allows to read parts quickly.
+ static Standard_Boolean IsQuickPart (const Standard_Integer theFileVer);
+
+ //! Enables reading in the quick part access mode.
+ Standard_EXPORT virtual void EnableQuickPartReading (const Handle(Message_Messenger)& /*theMessageDriver*/, Standard_Boolean /*theValue*/) {}
+
Handle(BinMDF_ADriverTable) myDrivers;
BinObjMgt_RRelocationTable myRelocTable;
Handle(Message_Messenger) myMsgDriver;
#endif
if (aNameBufferSize > 0) {
theStream.read ((char *)&aBuf[0], (Standard_Size)aNameBufferSize);
+ aBuf[aNameBufferSize] = '\0';
theSection.myName = (Standard_CString)&aBuf[0];
uint64_t aValue[3];
#include <BinMDF_ADriver.hxx>
#include <BinMDF_ADriverTable.hxx>
#include <BinObjMgt_Persistent.hxx>
+#include <BinObjMgt_Position.hxx>
#include <CDM_Application.hxx>
#include <CDM_Document.hxx>
#include <Message_Messenger.hxx>
IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentStorageDriver,PCDM_StorageDriver)
#define SHAPESECTION_POS (Standard_CString)"SHAPE_SECTION_POS:"
+#define ENDSECTION_POS (Standard_CString)":"
//=======================================================================
//function : BinLDrivers_DocumentStorageDriver
//purpose : Constructor
//=======================================================================
-BinLDrivers_DocumentStorageDriver::BinLDrivers_DocumentStorageDriver ()
+BinLDrivers_DocumentStorageDriver::BinLDrivers_DocumentStorageDriver()
{
}
{
myMsgDriver = theDoc->Application()->MessageDriver();
myMapUnsupported.Clear();
+ mySizesToWrite.Clear();
- Handle(TDocStd_Document) aDoc =
- Handle(TDocStd_Document)::DownCast(theDoc);
+ Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast (theDoc);
if (aDoc.IsNull()) {
SetIsError(Standard_True);
SetStoreStatus(PCDM_SS_Doc_IsNull);
for (; anIterS.More(); anIterS.Next())
anIterS.ChangeValue().WriteTOC (theOStream, aDocVer);
- // Shapes Section is the last one, it indicates the end of the table.
- BinLDrivers_DocumentSection aShapesSection (SHAPESECTION_POS,
- Standard_False);
- aShapesSection.WriteTOC (theOStream, aDocVer);
+ EnableQuickPartWriting (myMsgDriver, IsQuickPart (aDocVer));
+ BinLDrivers_DocumentSection* aShapesSection = 0;
+ Standard_Boolean aQuickPart = IsQuickPart (aDocVer);
+ if (!aQuickPart)
+ {
+ // Shapes Section is the last one, it indicates the end of the table.
+ aShapesSection = new BinLDrivers_DocumentSection (SHAPESECTION_POS, Standard_False);
+ aShapesSection->WriteTOC (theOStream, aDocVer);
+ }
+ else
+ {
+ // End Section is the last one, it indicates the end of the table.
+ BinLDrivers_DocumentSection anEndSection (ENDSECTION_POS, Standard_False);
+ anEndSection.WriteTOC (theOStream, aDocVer);
+ }
// 3. Write document contents
// (Storage data to the stream)
myRelocTable.Clear();
myPAtt.Init();
+ if (aQuickPart)
+ myPAtt.SetOStream (theOStream); // for writing shapes data into the stream directly
Message_ProgressScope aPS(theRange, "Writing document", 3);
// Write Doc structure
- WriteSubTree (aData->Root(), theOStream, aPS.Next()); // Doc is written
+ WriteSubTree (aData->Root(), theOStream, aQuickPart, aPS.Next()); // Doc is written
if (!aPS.More())
{
SetIsError(Standard_True);
}
// 4. Write Shapes section
- WriteShapeSection (aShapesSection, theOStream, aDocVer, aPS.Next());
+ if (!aQuickPart)
+ {
+ WriteShapeSection (*aShapesSection, theOStream, aDocVer, aPS.Next());
+ delete aShapesSection;
+ }
+ else
+ Clear();
+
if (!aPS.More())
{
- SetIsError(Standard_True);
- SetStoreStatus(PCDM_SS_UserBreak);
- return;
+ SetIsError (Standard_True);
+ SetStoreStatus (PCDM_SS_UserBreak);
+ return;
}
// Write application-defined sections
aSection.Write (theOStream, aSectionOffset, aDocVer);
}
+// 5. Write sizes along the file where it is needed for quick part mode
+ if (aQuickPart)
+ WriteSizes (theOStream);
+
// End of processing: close structures and check the status
myPAtt.Destroy(); // free buffer
myEmptyLabels.Clear();
{
#ifdef OCCT_DEBUG
TCollection_ExtendedString aMsg
- ("BinDrivers_DocumentStorageDriver: warning: attribute driver for type ");
+ ("BinLDrivers_DocumentStorageDriver: warning: attribute driver for type ");
#endif
if (!myMapUnsupported.Contains(theType)) {
myMapUnsupported.Add(theType);
void BinLDrivers_DocumentStorageDriver::WriteSubTree
(const TDF_Label& theLabel,
Standard_OStream& theOS,
+ const Standard_Boolean& theQuickPart,
const Message_ProgressRange& theRange)
{
// Skip empty labels
#endif
theOS.write ((char*)&aTag, sizeof(Standard_Integer));
+ Handle(BinObjMgt_Position) aPosition;
+ if (theQuickPart)
+ {
+ aPosition = mySizesToWrite.Append (new BinObjMgt_Position (theOS));
+ aPosition->WriteSize (theOS);
+ }
+
// Write attributes
TDF_AttributeIterator itAtt (theLabel);
for ( ; itAtt.More() && theOS && aPS.More(); itAtt.Next()) {
const Handle(Standard_Type)& aType = tAtt->DynamicType();
// Get type ID and driver
Handle(BinMDF_ADriver) aDriver;
- const Standard_Integer aTypeId = myDrivers->GetDriver (aType,aDriver);
+ const Standard_Integer aTypeId = myDrivers->GetDriver (aType, aDriver);
if (aTypeId > 0) {
// Add source to relocation table
const Standard_Integer anId = myRelocTable.Add (tAtt);
myPAtt.SetTypeId (aTypeId);
myPAtt.SetId (anId);
aDriver->Paste (tAtt, myPAtt, myRelocTable);
+ if (!myPAtt.StreamStart().IsNull())
+ {
+ Handle(BinObjMgt_Position) anAttrPosition = myPAtt.StreamStart();
+ anAttrPosition->StoreSize (theOS);
+ mySizesToWrite.Append (anAttrPosition);
+ }
// Write data to the stream -->!!!
theOS << myPAtt;
SetStoreStatus(PCDM_SS_UserBreak);
return;
}
- WriteSubTree (aChildLab, theOS, aPS.Next());
+ WriteSubTree (aChildLab, theOS, theQuickPart, aPS.Next());
}
-
// Write the end label marker
BinLDrivers_Marker anEndLabel = BinLDrivers_ENDLABEL;
#if DO_INVERSE
- anEndLabel = (BinLDrivers_Marker) InverseInt (anEndLabel);
+ anEndLabel = (BinLDrivers_Marker)InverseInt (anEndLabel);
#endif
- theOS.write ((char*)&anEndLabel, sizeof(anEndLabel));
-
+ theOS.write ((char*)&anEndLabel, sizeof (anEndLabel));
+ if (theQuickPart)
+ aPosition->StoreSize (theOS);
}
//=======================================================================
const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp();
theSection.Write (theOS, aShapesSectionOffset, theDocVer);
}
+
+//=======================================================================
+//function : IsQuickPart
+//purpose : Return true if document should be stored in quick mode for partial reading
+//=======================================================================
+Standard_Boolean BinLDrivers_DocumentStorageDriver::IsQuickPart (const Standard_Integer theVersion) const
+{
+ return theVersion >= TDocStd_FormatVersion_VERSION_12;
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void BinLDrivers_DocumentStorageDriver::Clear()
+{
+ // empty; should be redefined in subclasses
+}
+
+
+//=======================================================================
+//function : WriteSizes
+//purpose :
+//=======================================================================
+void BinLDrivers_DocumentStorageDriver::WriteSizes (Standard_OStream& theOS)
+{
+ NCollection_List<Handle(BinObjMgt_Position)>::Iterator anIter (mySizesToWrite);
+ for (; anIter.More() && theOS; anIter.Next())
+ anIter.Value()->WriteSize (theOS);
+ mySizesToWrite.Clear();
+}
class TDF_Label;
class TCollection_AsciiString;
class BinLDrivers_DocumentSection;
+class BinObjMgt_Position;
class BinLDrivers_DocumentStorageDriver;
//! Create a section that should be written after the OCAF data
Standard_EXPORT void AddSection (const TCollection_AsciiString& theName, const Standard_Boolean isPostRead = Standard_True);
-
+ //! Return true if document should be stored in quick mode for partial reading
+ Standard_EXPORT Standard_Boolean IsQuickPart (const Standard_Integer theVersion) const;
DEFINE_STANDARD_RTTIEXT(BinLDrivers_DocumentStorageDriver,PCDM_StorageDriver)
//! Write the tree under <theLabel> to the stream <theOS>
Standard_EXPORT void WriteSubTree (const TDF_Label& theData,
- Standard_OStream& theOS,
+ Standard_OStream& theOS,
+ const Standard_Boolean& theQuickPart,
const Message_ProgressRange& theRange = Message_ProgressRange());
//! define the procedure of writing a section to file.
const TDocStd_FormatVersion theDocVer,
const Message_ProgressRange& theRange = Message_ProgressRange());
+ //! Enables writing in the quick part access mode.
+ Standard_EXPORT virtual void EnableQuickPartWriting (
+ const Handle(Message_Messenger)& /*theMessageDriver*/, const Standard_Boolean /*theValue*/) {}
+
+ //! clears the writing-cash data in drivers if any.
+ Standard_EXPORT virtual void Clear();
+
Handle(BinMDF_ADriverTable) myDrivers;
BinObjMgt_SRelocationTable myRelocTable;
Handle(Message_Messenger) myMsgDriver;
Standard_EXPORT void UnsupportedAttrMsg (const Handle(Standard_Type)& theType);
+ //! Writes sizes along the file where it is needed for quick part mode
+ Standard_EXPORT void WriteSizes (Standard_OStream& theOS);
+
BinObjMgt_Persistent myPAtt;
TDF_LabelList myEmptyLabels;
TColStd_MapOfTransient myMapUnsupported;
TColStd_IndexedMapOfTransient myTypesMap;
BinLDrivers_VectorOfDocumentSection mySections;
TCollection_ExtendedString myFileName;
-
+ //! Sizes of labels and some attributes that will be stored in the second pass
+ NCollection_List<Handle(BinObjMgt_Position)> mySizesToWrite;
};
#endif // _BinLDrivers_DocumentStorageDriver_HeaderFile
#include <BinObjMgt_Persistent.hxx>
#include <BinTools_LocationSet.hxx>
#include <BinTools_ShapeSet.hxx>
+#include <BinTools_ShapeWriter.hxx>
+#include <BinTools_ShapeReader.hxx>
#include <Message_Messenger.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_Type.hxx>
#define SHAPESET "SHAPE_SECTION"
//=======================================================================
-static Standard_Character EvolutionToChar(const TNaming_Evolution theEvol)
+static Standard_Character EvolutionToChar (const TNaming_Evolution theEvol)
{
switch(theEvol) {
case TNaming_PRIMITIVE : return 'P';
}
//=======================================================================
-static TNaming_Evolution EvolutionToEnum(const Standard_Character theEvol)
+static TNaming_Evolution EvolutionToEnum (const Standard_Character theEvol)
{
switch(theEvol) {
case 'P': return TNaming_PRIMITIVE;
}
}
//=======================================================================
-static Standard_Character OrientationToChar(const TopAbs_Orientation theOrient)
+static Standard_Character OrientationToChar (const TopAbs_Orientation theOrient)
{
switch(theOrient) {
case TopAbs_FORWARD : return 'F';
}
}
//=======================================================================
-static TopAbs_Orientation CharToOrientation(const Standard_Character theCharOrient)
+static TopAbs_Orientation CharToOrientation (const Standard_Character theCharOrient)
{
switch(theCharOrient) {
case 'F': return TopAbs_FORWARD;
//=======================================================================
static void TranslateTo (const TopoDS_Shape& theShape,
BinObjMgt_Persistent& theResult,
- BinTools_ShapeSet& theShapeSet)
+ BinTools_ShapeSet* theShapeSet)
{
// Check for empty shape
if (theShape.IsNull()) {
- theResult.PutInteger(-1);
- theResult.PutInteger(-1);
- theResult.PutInteger(-1);
+ theResult.PutInteger (-1);
+ theResult.PutInteger (-1);
+ theResult.PutInteger (-1);
return;
}
// Add to shape set both TShape and Location contained in <theShape>
- const Standard_Integer aTShapeID = theShapeSet.Add (theShape);
+ const Standard_Integer aTShapeID = theShapeSet->Add (theShape);
const Standard_Integer aLocID =
- theShapeSet.Locations().Index (theShape.Location());
+ theShapeSet->Locations().Index (theShape.Location());
// Fill theResult with shape parameters: TShape ID, Location, Orientation
theResult << aTShapeID;
theResult << aLocID;
- theResult << OrientationToChar(theShape.Orientation());
+ theResult << OrientationToChar (theShape.Orientation());
}
//=======================================================================
static int TranslateFrom (const BinObjMgt_Persistent& theSource,
TopoDS_Shape& theResult,
- BinTools_ShapeSet& theShapeSet)
+ BinTools_ShapeSet* theShapeSet)
{
Standard_Integer aShapeID, aLocID;
Standard_Character aCharOrient;
Standard_Boolean Ok = theSource >> aShapeID; //TShapeID;
if(!Ok) return 1;
// Read TShape and Orientation
- if (aShapeID <= 0 || aShapeID > theShapeSet.NbShapes())
+ if (aShapeID <= 0 || aShapeID > theShapeSet->NbShapes())
return 1;
Ok = theSource >> aLocID;
if(!Ok) return 1;
Ok = theSource >> aCharOrient;
if(!Ok) return 1;
- TopAbs_Orientation anOrient = CharToOrientation(aCharOrient);
+ TopAbs_Orientation anOrient = CharToOrientation (aCharOrient);
- theResult.TShape (theShapeSet.Shape(aShapeID).TShape());//TShape
- theResult.Location (theShapeSet.Locations().Location (aLocID)); //Location
+ theResult.TShape (theShapeSet->Shape (aShapeID).TShape());//TShape
+ theResult.Location (theShapeSet->Locations().Location (aLocID)); //Location
theResult.Orientation (anOrient);//Orientation
return 0;
}
BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
(const Handle(Message_Messenger)& theMsgDriver)
-: BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name())
+ : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()),
+ myShapeSet (NULL),
+ myWithTriangles (Standard_False),
+ myWithNormals (Standard_False),
+ myIsQuickPart (Standard_False)
{
}
const Handle(TDF_Attribute)& theTarget,
BinObjMgt_RRelocationTable& ) const
{
- Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast(theTarget);
+ Handle(TNaming_NamedShape) aTAtt= Handle(TNaming_NamedShape)::DownCast (theTarget);
Standard_Integer aNbShapes;
theSource >> aNbShapes;
TDF_Label aLabel = theTarget->Label ();
- TNaming_Builder aBuilder (aLabel);
+ TNaming_Builder aBuilder (aLabel);
Standard_Integer aVer;
Standard_Boolean ok = theSource >> aVer;
if(!ok) return Standard_False;
Standard_Character aCharEvol;
ok = theSource >> aCharEvol;
if(!ok) return Standard_False;
- TNaming_Evolution anEvol = EvolutionToEnum(aCharEvol); //Evolution
- aTAtt->SetVersion(anEvol);
+ TNaming_Evolution anEvol = EvolutionToEnum (aCharEvol); //Evolution
+ aTAtt->SetVersion (anEvol);
- BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
+ BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_True);
+ Standard_IStream* aDirectStream = NULL;
+ if (myIsQuickPart) // enables direct reading of shapes from the stream
+ aDirectStream = const_cast<BinObjMgt_Persistent*>(&theSource)->GetIStream();
NCollection_List<TopoDS_Shape> anOldShapes, aNewShapes;
for (Standard_Integer i = 1; i <= aNbShapes; i++)
TopoDS_Shape anOldShape, aNewShape;
if (anEvol != TNaming_PRIMITIVE)
- if (TranslateFrom (theSource, anOldShape, aShapeSet)) return Standard_False;
+ {
+ if (myIsQuickPart)
+ aShapeSet->Read (*aDirectStream, anOldShape);
+ else
+ if (TranslateFrom (theSource, anOldShape, static_cast<BinTools_ShapeSet*>(aShapeSet))) return Standard_False;
+ }
if (anEvol != TNaming_DELETE)
- if (TranslateFrom (theSource, aNewShape, aShapeSet)) return Standard_False;
+ {
+ if (myIsQuickPart)
+ aShapeSet->Read (*aDirectStream, aNewShape);
+ else
+ if (TranslateFrom (theSource, aNewShape, static_cast<BinTools_ShapeSet*>(aShapeSet))) return Standard_False;
+ }
// Here we add shapes in reverse order because TNaming_Builder also adds them in reverse order.
anOldShapes.Prepend (anOldShape);
for (TNaming_Iterator SItr (aSAtt); SItr.More (); SItr.Next ()) NbShapes++;
//--------------------------------------------------------------
- BinTools_ShapeSet& aShapeSet = (BinTools_ShapeSet&) myShapeSet;
+ BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_False);
TNaming_Evolution anEvol = aSAtt->Evolution();
theTarget << NbShapes;
theTarget << aSAtt->Version();
- theTarget << EvolutionToChar(anEvol);
-
+ theTarget << EvolutionToChar (anEvol);
+
+
+ Standard_OStream* aDirectStream = NULL;
+ if (myIsQuickPart) // enables direct writing of shapes to the stream
+ aDirectStream = theTarget.GetOStream();
Standard_Integer i = 1;
- for (TNaming_Iterator SIterator(aSAtt) ;SIterator.More(); SIterator.Next()) {
- const TopoDS_Shape& OldShape = SIterator.OldShape();
- const TopoDS_Shape& NewShape = SIterator.NewShape();
+ for (TNaming_Iterator SIterator(aSAtt); SIterator.More(); SIterator.Next()) {
+ const TopoDS_Shape& anOldShape = SIterator.OldShape();
+ const TopoDS_Shape& aNewShape = SIterator.NewShape();
- if ( anEvol != TNaming_PRIMITIVE )
- TranslateTo (OldShape, theTarget, aShapeSet);
+ if (anEvol != TNaming_PRIMITIVE)
+ {
+ if (myIsQuickPart)
+ aShapeSet->Write (anOldShape, *aDirectStream);
+ else
+ TranslateTo (anOldShape, theTarget, static_cast<BinTools_ShapeSet*>(aShapeSet));
+ }
- if (anEvol != TNaming_DELETE)
- TranslateTo (NewShape, theTarget, aShapeSet);
+ if (anEvol != TNaming_DELETE)
+ {
+ if (myIsQuickPart)
+ aShapeSet->Write (aNewShape, *aDirectStream);
+ else
+ TranslateTo (aNewShape, theTarget, static_cast<BinTools_ShapeSet*>(aShapeSet));
+ }
i++;
}
const Standard_Integer theDocVer,
const Message_ProgressRange& theRange)
{
- theOS << SHAPESET;
+ myIsQuickPart = Standard_False;
+ theOS << SHAPESET;
if (theDocVer >= TDocStd_FormatVersion_VERSION_11)
{
- myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_4);
+ ShapeSet (Standard_False)->SetFormatNb (BinTools_FormatVersion_VERSION_4);
}
else
{
- myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_1);
+ ShapeSet (Standard_False)->SetFormatNb (BinTools_FormatVersion_VERSION_1);
}
-
- myShapeSet.Write (theOS, theRange);
- myShapeSet.Clear();
+ ShapeSet (Standard_False)->Write (theOS, theRange);
+ ShapeSet (Standard_False)->Clear();
}
//=======================================================================
void BinMNaming_NamedShapeDriver::Clear()
{
- myShapeSet.Clear();
+ if (myShapeSet)
+ {
+ myShapeSet->Clear();
+ delete myShapeSet;
+ myShapeSet = NULL;
+ }
}
//=======================================================================
void BinMNaming_NamedShapeDriver::ReadShapeSection (Standard_IStream& theIS,
const Message_ProgressRange& theRange)
{
+ myIsQuickPart = Standard_False;
// check section title string; note that some versions of OCCT (up to 6.3.1)
// might avoid writing shape section if it is empty
std::streamoff aPos = theIS.tellg();
TCollection_AsciiString aSectionTitle;
theIS >> aSectionTitle;
if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) {
- myShapeSet.Clear();
- myShapeSet.Read (theIS, theRange);
+ BinTools_ShapeSetBase* aShapeSet = ShapeSet (Standard_True);
+ aShapeSet->Clear();
+ aShapeSet->Read (theIS, theRange);
}
else
- theIS.seekg(aPos); // no shape section is present, try to return to initial point
+ theIS.seekg (aPos); // no shape section is present, try to return to initial point
+}
+
+//=======================================================================
+//function : ShapeSet
+//purpose :
+//=======================================================================
+
+BinTools_ShapeSetBase* BinMNaming_NamedShapeDriver::ShapeSet (const Standard_Boolean theReading)
+{
+ if (!myShapeSet)
+ {
+ if (myIsQuickPart)
+ {
+ if (theReading)
+ myShapeSet = new BinTools_ShapeReader();
+ else
+ myShapeSet = new BinTools_ShapeWriter();
+ }
+ else
+ myShapeSet = new BinTools_ShapeSet();
+ myShapeSet->SetWithTriangles(myWithTriangles);
+ myShapeSet->SetWithNormals(myWithNormals);
+ }
+ return myShapeSet;
+}
+
+//=======================================================================
+//function : GetShapesLocations
+//purpose :
+//=======================================================================
+BinTools_LocationSet& BinMNaming_NamedShapeDriver::GetShapesLocations() const
+{
+ BinTools_ShapeSetBase* aShapeSet = const_cast<BinMNaming_NamedShapeDriver*>(this)->ShapeSet (Standard_False);
+ return static_cast<BinTools_ShapeSet*>(aShapeSet)->ChangeLocations();
}
Standard_EXPORT void Clear();
//! Return true if shape should be stored with triangles.
- Standard_Boolean IsWithTriangles() const { return myShapeSet.IsWithTriangles(); }
+ Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
//! Return true if shape should be stored with triangulation normals.
- Standard_Boolean IsWithNormals() const { return myShapeSet.IsWithNormals(); }
-
+ Standard_Boolean IsWithNormals() const { return myWithNormals; }
//! set whether to store triangulation
- void SetWithTriangles (const Standard_Boolean isWithTriangles) { myShapeSet.SetWithTriangles(isWithTriangles); }
+ void SetWithTriangles (const Standard_Boolean isWithTriangles);
//! set whether to store triangulation with normals
- void SetWithNormals (const Standard_Boolean isWithNormals) { myShapeSet.SetWithNormals(isWithNormals); }
-
-
+ void SetWithNormals (const Standard_Boolean isWithNormals);
//! get the shapes locations
- BinTools_LocationSet& GetShapesLocations();
-
+ Standard_EXPORT BinTools_LocationSet& GetShapesLocations() const;
+ //! Sets the flag for quick part of the document access: shapes are stored in the attribute.
+ Standard_EXPORT void EnableQuickPart(const Standard_Boolean theValue) { myIsQuickPart = theValue; }
+ //! Returns true if quick part of the document access is enabled: shapes are stored in the attribute.
+ Standard_EXPORT Standard_Boolean IsQuickPart() { return myIsQuickPart; }
+ //! Returns shape-set of the needed type
+ Standard_EXPORT BinTools_ShapeSetBase* ShapeSet (const Standard_Boolean theReading);
DEFINE_STANDARD_RTTIEXT(BinMNaming_NamedShapeDriver,BinMDF_ADriver)
-protected:
-
-
-
private:
- BinTools_ShapeSet myShapeSet;
+ BinTools_ShapeSetBase *myShapeSet;
+ Standard_Boolean myWithTriangles;
+ Standard_Boolean myWithNormals;
+ //! Enables storing of whole shape data just in the attribute, not in a separated shapes section
+ Standard_Boolean myIsQuickPart;
};
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-
//=======================================================================
-//function : GetShapesLocations
+//function : SetWithTriangles
//purpose :
//=======================================================================
-inline BinTools_LocationSet& BinMNaming_NamedShapeDriver::GetShapesLocations()
+
+inline void BinMNaming_NamedShapeDriver::SetWithTriangles(const Standard_Boolean isWithTriangles)
{
- return myShapeSet.ChangeLocations();
+ myWithTriangles = isWithTriangles;
+ if (myShapeSet)
+ myShapeSet->SetWithTriangles (isWithTriangles);
}
+//=======================================================================
+//function : SetWithNormals
+//purpose :
+//=======================================================================
+
+inline void BinMNaming_NamedShapeDriver::SetWithNormals(const Standard_Boolean isWithNormals)
+{
+ myWithNormals = isWithNormals;
+ if (myShapeSet)
+ myShapeSet->SetWithNormals (isWithNormals);
+
+}
Handle(BinMNaming_NamedShapeDriver)::DownCast (aNSDriver);
Handle(BinMXCAFDoc_LocationDriver) aLocationDriver = new BinMXCAFDoc_LocationDriver (theMsgDrv);
- if( !aNamedShapeDriver.IsNull() )
+ if (!aNamedShapeDriver.IsNull())
{
- aLocationDriver->SetSharedLocations( &(aNamedShapeDriver->GetShapesLocations()) );
+ aLocationDriver->SetNSDriver (aNamedShapeDriver);
}
theDriverTable->AddDriver( aLocationDriver);
#include <BinMXCAFDoc_LocationDriver.hxx>
#include <BinObjMgt_Persistent.hxx>
#include <BinTools_LocationSet.hxx>
+#include <BinTools_ShapeReader.hxx>
+#include <BinTools_ShapeWriter.hxx>
#include <Message_Messenger.hxx>
#include <gp_Mat.hxx>
#include <gp_Trsf.hxx>
//=======================================================================
BinMXCAFDoc_LocationDriver::BinMXCAFDoc_LocationDriver(const Handle(Message_Messenger)& theMsgDriver)
: BinMDF_ADriver(theMsgDriver, STANDARD_TYPE(XCAFDoc_Location)->Name())
- , myLocations(0) {
+{
}
//=======================================================================
TopLoc_Location& theLoc,
BinObjMgt_RRelocationTable& theMap) const
{
+ if (!myNSDriver.IsNull() && myNSDriver->IsQuickPart())
+ {
+ BinTools_IStream aDirectStream (*(const_cast<BinObjMgt_Persistent*>(&theSource)->GetIStream()));
+ BinTools_ShapeReader* aReader = static_cast<BinTools_ShapeReader*>(myNSDriver->ShapeSet (Standard_True));
+ theLoc = *(aReader->ReadLocation (aDirectStream));
+ return Standard_True;
+ }
+
Standard_Integer anId = 0;
theSource >> anId;
{
return Standard_True;
}
+
+ if (!myNSDriver.IsNull() && myNSDriver->IsQuickPart())
+ { // read directly from the stream
+
+
+ }
Standard_Integer aFileVer = theMap.GetHeaderData()->StorageVersion().IntegerValue();
- if( aFileVer >= TDocStd_FormatVersion_VERSION_6 && myLocations == 0 )
+ if( aFileVer >= TDocStd_FormatVersion_VERSION_6 && myNSDriver.IsNull() )
{
return Standard_False;
}
- Standard_Integer aPower;
+ Standard_Integer aPower (0);
Handle(TopLoc_Datum3D) aDatum;
- if( aFileVer >= TDocStd_FormatVersion_VERSION_6)
+ if (aFileVer >= TDocStd_FormatVersion_VERSION_6)
{
- const TopLoc_Location& aLoc = myLocations->Location(anId);
+ const TopLoc_Location& aLoc = myNSDriver->GetShapesLocations().Location (anId);
aPower = aLoc.FirstPower();
aDatum = aLoc.FirstDatum();
} else {
BinObjMgt_Persistent& theTarget,
BinObjMgt_SRelocationTable& theMap) const
{
- if(theLoc.IsIdentity())
+ // The location is not identity
+ if (!myNSDriver.IsNull() && myNSDriver->IsQuickPart())
+ { // write directly to the stream
+ Standard_OStream* aDirectStream = theTarget.GetOStream();
+ BinTools_ShapeWriter* aWriter = static_cast<BinTools_ShapeWriter*>(myNSDriver->ShapeSet (Standard_False));
+ aWriter->WriteLocation (*aDirectStream, theLoc);
+ return;
+ }
+ if(theLoc.IsIdentity())
{
theTarget.PutInteger(0);
return;
}
- // The location is not identity
- if( myLocations == 0 )
+ if (myNSDriver.IsNull())
{
#ifdef OCCT_DEBUG
- std::cout<<"Pointer to LocationSet is NULL\n";
+ std::cout << "NamedShape Driver is NULL\n";
#endif
return;
}
-
- Standard_Integer anId = myLocations->Add(theLoc);
+
+ Standard_Integer anId = myNSDriver->GetShapesLocations().Add (theLoc);
theTarget << anId;
-
+
// In earlier version of this driver a datums from location stored in
// the relocation table, but now it's not necessary
// (try to uncomment it if some problems appear)
/*
Handle(TopLoc_Datum3D) aDatum = theLoc.FirstDatum();
-
+
if(!theMap.Contains(aDatum)) {
theMap.Add(aDatum);
}
*/
-
+
Translate(theLoc.NextLocation(), theTarget, theMap);
}
#include <Standard.hxx>
#include <Standard_Type.hxx>
-#include <BinTools_LocationSetPtr.hxx>
+#include <BinMNaming_NamedShapeDriver.hxx>
#include <BinMDF_ADriver.hxx>
#include <Standard_Boolean.hxx>
#include <BinObjMgt_RRelocationTable.hxx>
//! Translate transient location to storable
Standard_EXPORT void Translate (const TopLoc_Location& theLoc, BinObjMgt_Persistent& theTarget, BinObjMgt_SRelocationTable& theMap) const;
- void SetSharedLocations (const BinTools_LocationSetPtr& theLocations);
+ void SetNSDriver (const Handle(BinMNaming_NamedShapeDriver)& theNSDriver) { myNSDriver = theNSDriver; }
private:
- BinTools_LocationSetPtr myLocations;
-
+ Handle(BinMNaming_NamedShapeDriver) myNSDriver;
};
-#include <BinMXCAFDoc_LocationDriver.lxx>
-
-
-
-
#endif // _BinMXCAFDoc_LocationDriver_HeaderFile
+++ /dev/null
-// Created on: 2011-02-08
-// Created by: Oleg AGASHIN
-// Copyright (c) 2011-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//=======================================================================
-//function : SetSharedLocations
-//purpose :
-//=======================================================================
-inline void BinMXCAFDoc_LocationDriver::SetSharedLocations(const BinTools_LocationSetPtr& theLocations)
-{
- if( myLocations != theLocations )
- {
- myLocations = theLocations;
- }
-}
BinMXCAFDoc_GraphNodeDriver.hxx
BinMXCAFDoc_LocationDriver.cxx
BinMXCAFDoc_LocationDriver.hxx
-BinMXCAFDoc_LocationDriver.lxx
BinMXCAFDoc_MaterialDriver.cxx
BinMXCAFDoc_MaterialDriver.hxx
BinMXCAFDoc_NoteDriver.cxx
#include <BinObjMgt_Persistent.hxx>
+#include <BinObjMgt_Position.hxx>
#include <FSD_FileHeader.hxx>
#include <Standard_GUID.hxx>
#include <TCollection_AsciiString.hxx>
: myIndex (1),
myOffset(BP_HEADSIZE),
mySize (BP_HEADSIZE),
- myIsError (Standard_False)
+ myIsError (Standard_False),
+ myOStream (NULL),
+ myIStream (NULL),
+ myDirectWritingIsEnabled (Standard_False)
{
Init();
}
myOffset = BP_HEADSIZE;
mySize = BP_HEADSIZE;
myIsError = Standard_False;
+ myDirectWritingIsEnabled = Standard_False;
}
//=======================================================================
// const BinObjMgt_Persistent&) is also available
//=======================================================================
-Standard_OStream& BinObjMgt_Persistent::Write (Standard_OStream& theOS)
+Standard_OStream& BinObjMgt_Persistent::Write (Standard_OStream& theOS, const Standard_Boolean theDirectStream)
{
+ if (myDirectWritingIsEnabled)
+ { // if direct writing was enabled, everything is already written, just pass this stage
+ myDirectWritingIsEnabled = Standard_False;
+ return theOS;
+ }
Standard_Integer nbWritten = 0;
Standard_Integer *aData = (Standard_Integer*) myData(1);
// update data length
aData[2] = mySize - BP_HEADSIZE;
+ if (theDirectStream)
+ aData[1] = -aData[1];
#if DO_INVERSE
aData[0] = InverseInt (aData[0]);
aData[1] = InverseInt (aData[1]);
aData[1] = InverseInt (aData[1]);
aData[2] = InverseInt (aData[2]);
#endif
- if (theIS && aData[1] > 0 && aData[2] > 0) {
+ myDirectWritingIsEnabled = aData[1] < 0;
+ if (myDirectWritingIsEnabled)
+ aData[1] = -aData[1];
+ if (theIS && aData[2] > 0) {
mySize += aData[2];
// read remaining data
Standard_Integer nbRead = BP_HEADSIZE;
}
}
}
+
+//=======================================================================
+//function : GetOStream
+//purpose : Gets the stream for and enables direct writing
+//=======================================================================
+
+Standard_OStream* BinObjMgt_Persistent::GetOStream()
+{
+ Write (*myOStream, Standard_True); // finishes already stored data save
+ myStreamStart = new BinObjMgt_Position (*myOStream);
+ myStreamStart->WriteSize (*myOStream);
+ myDirectWritingIsEnabled = Standard_True;
+ return myOStream;
+}
+
+//=======================================================================
+//function : GetOStream
+//purpose : Gets the stream for and enables direct writing
+//=======================================================================
+Standard_IStream* BinObjMgt_Persistent::GetIStream()
+{
+ // skip the stream size first
+ myIStream->seekg (sizeof (uint64_t), std::ios_base::cur);
+ return myIStream;
+}
#include <BinObjMgt_PInteger.hxx>
#include <BinObjMgt_PReal.hxx>
#include <BinObjMgt_PShortReal.hxx>
+#include <BinObjMgt_Position.hxx>
#include <Standard_OStream.hxx>
#include <Standard_IStream.hxx>
#include <Standard_Address.hxx>
//! Indicates an error after Get methods or SetPosition
Standard_Boolean IsError() const;
Standard_Boolean operator !() const
-{
- return IsError();
-}
+ {
+ return IsError();
+ }
//! Indicates a good state after Get methods or SetPosition
Standard_Boolean IsOK() const;
-operator Standard_Boolean () const { return IsOK(); }
+ operator Standard_Boolean () const { return IsOK(); }
//! Initializes me to reuse again
Standard_EXPORT void Init();
//! Stores <me> to the stream.
//! inline Standard_OStream& operator<< (Standard_OStream&,
- //! BinObjMgt_Persistent&) is also available
- Standard_EXPORT Standard_OStream& Write (Standard_OStream& theOS);
+ //! BinObjMgt_Persistent&) is also available.
+ //! If theDirectStream is true, after this data the direct stream data is stored.
+ Standard_EXPORT Standard_OStream& Write (Standard_OStream& theOS, const Standard_Boolean theDirectStream = Standard_False);
//! Retrieves <me> from the stream.
//! inline Standard_IStream& operator>> (Standard_IStream&,
//! Frees the allocated memory;
//! This object can be reused after call to Init
Standard_EXPORT void Destroy();
-~BinObjMgt_Persistent()
-{
- Destroy();
-}
-
-
-
-
-protected:
-
-
-
+ ~BinObjMgt_Persistent()
+ {
+ Destroy();
+ }
+ //! Sets the stream for direct writing
+ Standard_EXPORT void SetOStream (Standard_OStream& theStream) { myOStream = &theStream; }
+ //! Sets the stream for direct reading
+ Standard_EXPORT void SetIStream (Standard_IStream& theStream) { myIStream = &theStream; }
+ //! Gets the stream for and enables direct writing
+ Standard_EXPORT Standard_OStream* GetOStream();
+ //! Gets the stream for and enables direct reading
+ Standard_EXPORT Standard_IStream* GetIStream();
+ //! Returns true if after this record a direct writing to the stream is performed.
+ Standard_EXPORT Standard_Boolean IsDirect() { return myDirectWritingIsEnabled; }
+ //! Returns the start position of the direct writing in the stream
+ Standard_EXPORT Handle(BinObjMgt_Position) StreamStart() { return myStreamStart; }
private:
Standard_Integer myOffset;
Standard_Integer mySize;
Standard_Boolean myIsError;
-
-
+ Standard_OStream* myOStream; ///< stream to write in case direct writing is enabled
+ Standard_IStream* myIStream; ///< stream to write in case direct reading is enabled
+ Standard_Boolean myDirectWritingIsEnabled;
+ Handle(BinObjMgt_Position) myStreamStart; ///< position where the direct writing to the script is started
};
inline void BinObjMgt_Persistent::SetTypeId (const Standard_Integer theTypeId)
{
((Standard_Integer*) myData(1)) [0] = theTypeId;
+ myStreamStart.Nullify();
}
//=======================================================================
--- /dev/null
+// 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 <BinObjMgt_Position.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT (BinObjMgt_Position, Standard_Transient)
+
+//=======================================================================
+//function : BinObjMgt_Position
+//purpose :
+//=======================================================================
+BinObjMgt_Position::BinObjMgt_Position (Standard_OStream& theStream) :
+ myPosition (theStream.tellp()), mySize(0)
+{}
+
+//=======================================================================
+//function : StoreSize
+//purpose :
+//=======================================================================
+void BinObjMgt_Position::StoreSize (Standard_OStream& theStream)
+{
+ mySize = uint64_t (theStream.tellp() - myPosition);
+}
+
+//=======================================================================
+//function : WriteSize
+//purpose :
+//=======================================================================
+void BinObjMgt_Position::WriteSize (Standard_OStream& theStream)
+{
+ if (theStream.tellp() != myPosition)
+ theStream.seekp (myPosition);
+#if DO_INVERSE
+ mySize = FSD_BinaryFile::InverseUint64 (mySize);
+#endif
+ theStream.write ((char*)&mySize, sizeof (uint64_t));
+}
--- /dev/null
+// 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 _BinObjMgt_Position_HeaderFile
+#define _BinObjMgt_Position_HeaderFile
+
+#include <Standard_Type.hxx>
+
+class BinObjMgt_Position;
+DEFINE_STANDARD_HANDLE (BinObjMgt_Position, Standard_Transient)
+
+//! Stores and manipulates position in the stream.
+class BinObjMgt_Position : public Standard_Transient
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+ //! Creates position using the current stream position.
+ Standard_EXPORT BinObjMgt_Position (Standard_OStream& theStream);
+
+ //! Stores the difference between the current position and the stored one.
+ Standard_EXPORT void StoreSize (Standard_OStream& theStream);
+ //! Writes stored size at the stored position. Changes the current stream position.
+ Standard_EXPORT void WriteSize (Standard_OStream& theStream);
+
+ DEFINE_STANDARD_RTTIEXT (BinObjMgt_Position, Standard_Transient)
+
+private:
+ std::streampos myPosition;
+ uint64_t mySize;
+};
+
+#endif // _BinObjMgt_Position_HeaderFile
BinObjMgt_Persistent.lxx
BinObjMgt_PExtChar.hxx
BinObjMgt_PInteger.hxx
+BinObjMgt_Position.cxx
+BinObjMgt_Position.hxx
BinObjMgt_PReal.hxx
BinObjMgt_PShortReal.hxx
BinObjMgt_RRelocationTable.cxx
#if DO_INVERSE
anIntValue = InverseInt (aValue);
#endif
- OS.write((char*)&anIntValue, sizeof(Standard_Integer));
+ OS.write ((char*)&anIntValue, sizeof (Standard_Integer));
return OS;
}
{
#if DO_INVERSE
const Standard_Real aRValue = InverseReal (theValue);
- theOS.write((char*)&aRValue, sizeof(Standard_Real));
+ theOS.write ((char*)&aRValue, sizeof (Standard_Real));
#else
- theOS.write((char*)&theValue, sizeof(Standard_Real));
+ theOS.write ((char*)&theValue, sizeof (Standard_Real));
#endif
return theOS;
}
return OS;
}
+//=======================================================================
+//function : PutBools
+//purpose :
+//=======================================================================
+
+Standard_OStream& BinTools::PutBools (Standard_OStream& OS,
+ const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3)
+{
+ Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0);
+ OS.write((char*)&aValue, sizeof(Standard_Byte));
+ return OS;
+}
+
+//=======================================================================
+//function : PutBools
+//purpose :
+//=======================================================================
+
+Standard_OStream& BinTools::PutBools (Standard_OStream& OS,
+ const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3,
+ const Standard_Boolean theValue4, const Standard_Boolean theValue5, const Standard_Boolean theValue6,
+ const Standard_Boolean theValue7)
+{
+ Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0) | (theValue4 ? 8 : 0) |
+ (theValue5 ? 16 : 0) | (theValue6 ? 32 : 0) | (theValue7 ? 64 : 0);
+ OS.write ((char*)&aValue, sizeof(Standard_Byte));
+ return OS;
+}
+
//=======================================================================
//function : GetReal
//purpose :
BinTools_ShapeSet aShapeSet;
aShapeSet.SetWithTriangles(Standard_True);
aShapeSet.Read (theStream, theRange);
- aShapeSet.Read (theShape, theStream, aShapeSet.NbShapes());
+ aShapeSet.ReadSubs (theShape, theStream, aShapeSet.NbShapes());
}
//=======================================================================
Standard_EXPORT static Standard_OStream& PutBool (Standard_OStream& OS, const Standard_Boolean theValue);
Standard_EXPORT static Standard_OStream& PutExtChar (Standard_OStream& OS, const Standard_ExtCharacter theValue);
+
+ Standard_EXPORT static Standard_OStream& PutBools (Standard_OStream& OS,
+ const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3);
+
+ Standard_EXPORT static Standard_OStream& PutBools (Standard_OStream& OS,
+ const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3,
+ const Standard_Boolean theValue4, const Standard_Boolean theValue5, const Standard_Boolean theValue6,
+ const Standard_Boolean theValue7);
Standard_EXPORT static Standard_IStream& GetReal (Standard_IStream& IS, Standard_Real& theValue);
--- /dev/null
+// 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 <BinTools_IStream.hxx>
+#include <Storage_StreamTypeMismatchError.hxx>
+
+//=======================================================================
+//function : BinTools_IStream
+//purpose :
+//=======================================================================
+BinTools_IStream::BinTools_IStream (Standard_IStream& theStream)
+ : myStream (&theStream), myPosition (theStream.tellg()), myLastType (BinTools_ObjectType_Unknown)
+{}
+
+//=======================================================================
+//function : ReadType
+//purpose :
+//=======================================================================
+BinTools_ObjectType BinTools_IStream::ReadType()
+{
+ myLastType = BinTools_ObjectType (myStream->get());
+ myPosition++;
+ return myLastType;
+}
+
+//=======================================================================
+//function : IsReference
+//purpose :
+//=======================================================================
+Standard_Boolean BinTools_IStream::IsReference()
+{
+ return myLastType == BinTools_ObjectType_Reference8 || myLastType == BinTools_ObjectType_Reference16 ||
+ myLastType == BinTools_ObjectType_Reference32 || myLastType == BinTools_ObjectType_Reference64;
+}
+
+//=======================================================================
+//function : ReadReference
+//purpose :
+//=======================================================================
+uint64_t BinTools_IStream::ReadReference()
+{
+ uint64_t aDelta = 0;
+ uint64_t aCurrentPos = uint64_t (myStream->tellg());
+ switch (myLastType)
+ {
+ case BinTools_ObjectType_Reference8:
+ aDelta = uint64_t (myStream->get());
+ myPosition++;
+ break;
+ case BinTools_ObjectType_Reference16:
+ {
+ uint16_t aDelta16 = 0;
+ myStream->read ((char*)&aDelta16, sizeof (uint16_t));
+ myPosition += 2;
+#if DO_INVERSE
+ aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
+ | ((aDelta16 & 0xFF00) >> 8));
+#endif
+ aDelta = uint64_t (aDelta16);
+ break;
+ }
+ case BinTools_ObjectType_Reference32:
+ {
+ uint32_t aDelta32 = 0;
+ myStream->read ((char*)&aDelta32, sizeof (uint32_t));
+ myPosition += 4;
+#if DO_INVERSE
+ aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
+ | ((aDelta32 & 0x0000ff00) << 8)
+ | ((aDelta32 & 0x00ff0000) >> 8)
+ | ((aDelta32 >> 24) & 0x000000ff));
+#endif
+ aDelta = uint64_t (aDelta32);
+ break;
+ }
+ case BinTools_ObjectType_Reference64:
+ myStream->read ((char*)&aDelta, sizeof (uint64_t));
+ myPosition += 8;
+#if DO_INVERSE
+ aDelta = InverseUint64 (aDelta);
+#endif
+ break;
+ default:
+ break;
+ }
+ if (aDelta == 0)
+ {
+ Standard_SStream aMsg;
+ aMsg << "BinTools_Position::ReadReference: invalid reference " << (char)myLastType << std::endl;
+ throw Standard_Failure (aMsg.str().c_str());
+ }
+ return aCurrentPos - aDelta - 1; // add a type-byte
+}
+
+//=======================================================================
+//function : GoTo
+//purpose :
+//=======================================================================
+void BinTools_IStream::GoTo (const uint64_t& thePosition)
+{
+ myStream->seekg (std::streampos (thePosition));
+ myPosition = thePosition;
+}
+
+//=======================================================================
+//function : ShapeType
+//purpose :
+//=======================================================================
+TopAbs_ShapeEnum BinTools_IStream::ShapeType()
+{
+ return TopAbs_ShapeEnum ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) >> 2);
+}
+
+//=======================================================================
+//function : ShapeOrientation
+//purpose :
+//=======================================================================
+TopAbs_Orientation BinTools_IStream::ShapeOrientation()
+{
+ return TopAbs_Orientation ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) & 3);
+}
+
+//=======================================================================
+//function : operator bool
+//purpose :
+//=======================================================================
+BinTools_IStream::operator bool() const
+{
+ return *myStream ? Standard_True : Standard_False;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Real& theValue)
+{
+ if (!myStream->read ((char*)&theValue, sizeof (Standard_Real)))
+ throw Storage_StreamTypeMismatchError();
+ myPosition += sizeof (Standard_Real);
+#if DO_INVERSE
+ theValue = InverseReal (theValue);
+#endif
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Integer& theValue)
+{
+ if (!myStream->read ((char*)&theValue, sizeof (Standard_Integer)))
+ throw Storage_StreamTypeMismatchError();
+ myPosition += sizeof (Standard_Integer);
+#if DO_INVERSE
+ theValue = InverseInt (theValue);
+#endif
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (gp_Pnt& theValue)
+{
+ Standard_Real aValue;
+ for (int aCoord = 1; aCoord <= 3; aCoord++)
+ {
+ if (!myStream->read ((char*)&aValue, sizeof (Standard_Real)))
+ throw Storage_StreamTypeMismatchError();
+#if DO_INVERSE
+ aValue = InverseReal (aValue);
+#endif
+ theValue.SetCoord (aCoord, aValue);
+ }
+ myPosition += 3 * sizeof (Standard_Real);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Byte& theValue)
+{
+ myStream->read ((char*)&theValue, sizeof (Standard_Byte));
+ myPosition += sizeof (Standard_Byte);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_ShortReal& theValue)
+{
+ myStream->read ((char*)&theValue, sizeof (Standard_ShortReal));
+ myPosition += sizeof (Standard_ShortReal);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (gp_Trsf& theValue)
+{
+ Standard_Real aV1[3], aV2[3], aV3[3], aV[3];
+ *this >> aV1[0] >> aV1[1] >> aV1[2] >> aV[0];
+ *this >> aV2[0] >> aV2[1] >> aV2[2] >> aV[1];
+ *this >> aV3[0] >> aV3[1] >> aV3[2] >> aV[2];
+ theValue.SetValues (aV1[0], aV1[1], aV1[2], aV[0],
+ aV2[0], aV2[1], aV2[2], aV[1],
+ aV3[0], aV3[1], aV3[2], aV[2]);
+ return *this;
+}
+
+//=======================================================================
+//function : ReadBools
+//purpose :
+//=======================================================================
+void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3)
+{
+ Standard_Byte aByte = ReadByte();
+ theBool1 = (aByte & 1) == 1;
+ theBool2 = (aByte & 2) == 2;
+ theBool3 = (aByte & 4) == 4;
+}
+
+//=======================================================================
+//function : ReadBools
+//purpose :
+//=======================================================================
+void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3,
+ Standard_Boolean& theBool4, Standard_Boolean& theBool5, Standard_Boolean& theBool6, Standard_Boolean& theBool7)
+{
+ Standard_Byte aByte = ReadByte();
+ theBool1 = (aByte & 1) == 1;
+ theBool2 = (aByte & 2) == 2;
+ theBool3 = (aByte & 4) == 4;
+ theBool4 = (aByte & 8) == 8;
+ theBool5 = (aByte & 16) == 16;
+ theBool6 = (aByte & 32) == 32;
+ theBool7 = (aByte & 64) == 64;
+}
--- /dev/null
+// 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 _BinTools_IStream_HeaderFile
+#define _BinTools_IStream_HeaderFile
+
+#include <BinTools.hxx>
+#include <BinTools_ObjectType.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopAbs_Orientation.hxx>
+#include <gp_Pnt.hxx>
+
+//! Substitution of IStream for shape reader for fast management of position in the file (get and go)
+//! and operation on all reading types.
+class BinTools_IStream
+{
+public:
+
+ //! Creates IStream using the current stream IStream.
+ Standard_EXPORT BinTools_IStream (Standard_IStream& theStream);
+
+ //! Reads and returns the type.
+ Standard_EXPORT BinTools_ObjectType ReadType();
+ //! Returns the last read type.
+ Standard_EXPORT const BinTools_ObjectType& LastType() { return myLastType; }
+ //! Returns the shape type by the last retrieved type.
+ Standard_EXPORT TopAbs_ShapeEnum ShapeType();
+ //! Returns the shape orientation by the last retrieved type.
+ Standard_EXPORT TopAbs_Orientation ShapeOrientation();
+
+ //! Returns the current position in the stream.
+ Standard_EXPORT uint64_t Position() { return myPosition; }
+ //! Moves the current stream position to the given one.
+ Standard_EXPORT void GoTo (const uint64_t& thePosition);
+
+ //! Returns true if the last restored type is one of a reference
+ Standard_EXPORT Standard_Boolean IsReference();
+ //! Reads a reference IStream using the last restored type.
+ Standard_EXPORT uint64_t ReadReference();
+ //! Returns the original IStream.
+ Standard_EXPORT Standard_IStream& Stream() { return *myStream; }
+ //! Makes up to date the myPosition because myStream was used outside and position is changed.
+ Standard_EXPORT void UpdatePosition() { myPosition = uint64_t (myStream->tellg()); }
+
+ //! Returns false if stream reading is failed.
+ Standard_EXPORT operator bool() const;
+ //! Reads real value from the stream.
+ Standard_EXPORT Standard_Real ReadReal() { Standard_Real aValue; *this >> aValue; return aValue; }
+ Standard_EXPORT BinTools_IStream& operator >> (Standard_Real& theValue);
+ //! Reads integer value from the stream.
+ Standard_EXPORT Standard_Integer ReadInteger() { Standard_Integer aValue; *this >> aValue; return aValue; }
+ Standard_EXPORT BinTools_IStream& operator >> (Standard_Integer& theValue);
+ //! Reads point coordinates value from the stream.
+ Standard_EXPORT gp_Pnt ReadPnt() { gp_Pnt aValue; *this >> aValue; return aValue; }
+ Standard_EXPORT BinTools_IStream& operator >> (gp_Pnt& theValue);
+ //! Reads byte value from the stream.
+ Standard_EXPORT Standard_Byte ReadByte() { Standard_Byte aValue; *this >> aValue; return aValue; }
+ Standard_EXPORT BinTools_IStream& operator >> (Standard_Byte& theValue);
+ //! Reads boolean value from the stream (stored as one byte).
+ Standard_EXPORT Standard_Boolean ReadBool() { return ReadByte() != 0; }
+ Standard_EXPORT BinTools_IStream& operator >> (Standard_Boolean& theValue) { theValue = ReadByte() != 0; return *this; }
+ //! Reads short real value from the stream.
+ Standard_EXPORT Standard_ShortReal ReadShortReal() { Standard_ShortReal aValue; *this >> aValue; return aValue; }
+ Standard_EXPORT BinTools_IStream& operator >> (Standard_ShortReal& theValue);
+ //! Reads transformation value from the stream.
+ Standard_EXPORT BinTools_IStream& operator >> (gp_Trsf& theValue);
+ //! Reads 3 boolean values from one byte
+ Standard_EXPORT void ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3);
+ //! Reads 7 boolean values from one byte
+ Standard_EXPORT void ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3,
+ Standard_Boolean& theBool4, Standard_Boolean& theBool5, Standard_Boolean& theBool6, Standard_Boolean& theBool7);
+
+
+private:
+ Standard_IStream* myStream; ///< pointer to the stream
+ uint64_t myPosition; ///< equivalent to tellg returned value for fast access
+ BinTools_ObjectType myLastType; ///< last type that was read
+};
+
+#endif // _BinTools_IStream_HeaderFile
//function : operator << (gp_Trsf& T)
//purpose :
//=======================================================================
-static Standard_OStream& operator <<(Standard_OStream& OS,const gp_Trsf& T)
+Standard_OStream& operator <<(Standard_OStream& OS,const gp_Trsf& T)
{
gp_XYZ V = T.TranslationPart();
gp_Mat M = T.VectorialPart();
class Standard_OutOfRange;
class TopLoc_Location;
+//! Operator for writing transformation into the stream
+Standard_OStream& operator << (Standard_OStream& OS, const gp_Trsf& T);
//! The class LocationSet stores a set of location in
//! a relocatable state.
//! is first cleared.
Standard_EXPORT void Read (Standard_IStream& IS);
-
-
-
protected:
--- /dev/null
+// 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 _BinTools_ObjectType_HeaderFile
+#define _BinTools_ObjectType_HeaderFile
+
+//! Enumeration defining objects identifiers in the shape read/write format.
+enum BinTools_ObjectType
+{
+ BinTools_ObjectType_Unknown = 0,
+ BinTools_ObjectType_Reference8, //!< 8-bits reference
+ BinTools_ObjectType_Reference16, //!< 16-bits reference
+ BinTools_ObjectType_Reference32, //!< 32-bits reference
+ BinTools_ObjectType_Reference64, //!< 64-bits reference
+ BinTools_ObjectType_Location,
+ BinTools_ObjectType_SimpleLocation,
+ BinTools_ObjectType_EmptyLocation,
+ BinTools_ObjectType_LocationEnd,
+ BinTools_ObjectType_Curve,
+ BinTools_ObjectType_EmptyCurve,
+ BinTools_ObjectType_Curve2d,
+ BinTools_ObjectType_EmptyCurve2d,
+ BinTools_ObjectType_Surface,
+ BinTools_ObjectType_EmptySurface,
+ BinTools_ObjectType_Polygon3d,
+ BinTools_ObjectType_EmptyPolygon3d,
+ BinTools_ObjectType_PolygonOnTriangulation,
+ BinTools_ObjectType_EmptyPolygonOnTriangulation,
+ BinTools_ObjectType_Triangulation,
+ BinTools_ObjectType_EmptyTriangulation,
+ BinTools_ObjectType_EmptyShape = 198, //!< identifier of the null shape
+ BinTools_ObjectType_EndShape = 199, //!< identifier of the shape record end
+ // here is the space for TopAbs_ShapeEnum+Orientation types
+};
+
+#endif // _BinTools_ObjectType_HeaderFile
--- /dev/null
+// 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 <BinTools_Position.hxx>
+
+//=======================================================================
+//function : BinTools_Position
+//purpose :
+//=======================================================================
+BinTools_Position::BinTools_Position (Standard_OStream& theStream) :
+ myOStream (&theStream), myPosition (theStream.tellp())
+{}
+
+//=======================================================================
+//function : WriteReference
+//purpose :
+//=======================================================================
+void BinTools_Position::WriteReference() const
+{
+ uint64_t aDelta = uint64_t (myOStream->tellp()) - myPosition;
+ if (aDelta <= 0xFF)
+ {
+ *myOStream << (Standard_Byte)BinTools_ObjectType_Reference8;
+ *myOStream << (Standard_Byte)aDelta;
+ }
+ else if (aDelta <= 0xFFFF)
+ {
+ *myOStream << (Standard_Byte)BinTools_ObjectType_Reference16;
+ uint16_t aDelta16 = uint16_t (aDelta);
+#if DO_INVERSE
+ aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
+ | ((aDelta16 & 0xFF00) >> 8));
+#endif
+ myOStream->write ((char*)&aDelta16, sizeof (uint16_t));
+ }
+ else if (aDelta <= 0xFFFFFFFF)
+ {
+ *myOStream << (Standard_Byte)BinTools_ObjectType_Reference32;
+ uint32_t aDelta32 = uint32_t (aDelta);
+#if DO_INVERSE
+ aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
+ | ((aDelta32 & 0x0000ff00) << 8)
+ | ((aDelta32 & 0x00ff0000) >> 8)
+ | ((aDelta32 >> 24) & 0x000000ff) );
+#endif
+ myOStream->write ((char*)&aDelta32, sizeof (uint32_t));
+ }
+ else
+ {
+ *myOStream << (Standard_Byte)BinTools_ObjectType_Reference64;
+#if DO_INVERSE
+ aDelta = InverseUint64 (aDelta);
+#endif
+ myOStream->write ((char*)&aDelta, sizeof (uint64_t));
+ }
+}
+
+//=======================================================================
+//function : WriteShape
+//purpose :
+//=======================================================================
+void BinTools_Position::WriteShape (const TopAbs_ShapeEnum& theType, const TopAbs_Orientation& theOrientation) const
+{
+ Standard_Byte aType = Standard_Byte (BinTools_ObjectType_EndShape) + 1 + // taking into account that orientation <= 3
+ (Standard_Byte (theType) << 2) + Standard_Byte (theOrientation); // and type <= 8
+ *myOStream << (Standard_Byte)aType;
+}
+
+//=======================================================================
+//function : WriteObject
+//purpose :
+//=======================================================================
+void BinTools_Position::WriteObject(const BinTools_ObjectType& theType) const
+{
+ *myOStream << (Standard_Byte)theType;
+}
--- /dev/null
+// 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 _BinTools_Position_HeaderFile
+#define _BinTools_Position_HeaderFile
+
+#include <BinTools.hxx>
+#include <BinTools_ObjectType.hxx>
+
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopAbs_Orientation.hxx>
+
+//! Stores and manipulates position in the stream.
+class BinTools_Position
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+ //! Creates position using the current stream position.
+ Standard_EXPORT BinTools_Position (Standard_OStream& theStream);
+
+ //! Writes a reference to my position into the stream
+ Standard_EXPORT void WriteReference() const;
+ //! Writes an identifier of shape type and orientation into the stream.
+ Standard_EXPORT void WriteShape (const TopAbs_ShapeEnum& theType, const TopAbs_Orientation& theOrientation) const;
+ //! Writes an identifier of an object into the stream.
+ Standard_EXPORT void WriteObject (const BinTools_ObjectType& theType) const;
+
+private:
+ Standard_OStream* myOStream;
+ std::streampos myPosition;
+};
+
+#endif // _BinTools_Position_HeaderFile
--- /dev/null
+// 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 <BinTools_ShapeReader.hxx>
+#include <TopoDS.hxx>
+#include <BRep_PointOnCurve.hxx>
+#include <BRep_PointOnCurveOnSurface.hxx>
+#include <BRep_PointOnSurface.hxx>
+#include <BRep_Polygon3D.hxx>
+#include <BRep_Builder.hxx>
+#include <BinTools_CurveSet.hxx>
+#include <BinTools_Curve2dSet.hxx>
+#include <BinTools_SurfaceSet.hxx>
+
+//=======================================================================
+//function : BinTools_ShapeReader
+//purpose :
+//=======================================================================
+BinTools_ShapeReader::BinTools_ShapeReader()
+{}
+
+//=======================================================================
+//function : ~BinTools_ShapeReader
+//purpose :
+//=======================================================================
+BinTools_ShapeReader::~BinTools_ShapeReader()
+{}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void BinTools_ShapeReader::Clear()
+{
+ BinTools_ShapeSetBase::Clear();
+ myShapePos.Clear();
+ myLocationPos.Clear();
+ myCurvePos.Clear();
+ myCurve2dPos.Clear();
+ mySurfacePos.Clear();
+ myPolygon3dPos.Clear();
+ myPolygonPos.Clear();
+ myTriangulationPos.Clear();
+}
+
+//=======================================================================
+//function : Read
+//purpose :
+//=======================================================================
+void BinTools_ShapeReader::Read (Standard_IStream& theStream, TopoDS_Shape& theShape)
+{
+ BinTools_IStream aStream(theStream);
+ theShape = ReadShape(aStream);
+}
+
+//=======================================================================
+//function : ReadShape
+//purpose :
+//=======================================================================
+TopoDS_Shape BinTools_ShapeReader::ReadShape (BinTools_IStream& theStream)
+{
+ TopoDS_Shape aResult;
+ uint64_t aPosition = theStream.Position();
+ const BinTools_ObjectType& aType = theStream.ReadType();
+ if (aType == BinTools_ObjectType_EmptyShape || aType == BinTools_ObjectType_EndShape)
+ return aResult;
+
+ if (theStream.IsReference())
+ {
+ uint64_t aRef = theStream.ReadReference();
+ const TopoDS_Shape* aFound = myShapePos.Seek(aRef);
+ if (aFound) // the shape is already retrieved, just add location
+ {
+ aResult = *aFound;
+ }
+ else
+ {
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ aResult = ReadShape (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ }
+ aResult.Location (*ReadLocation (theStream));
+ aResult.Orientation (TopAbs_Orientation (theStream.ReadByte()));
+ return aResult;
+ }
+ // read the shape
+ TopAbs_ShapeEnum aShapeType = theStream.ShapeType();
+ TopAbs_Orientation aShapeOrientation = theStream.ShapeOrientation();
+ const TopLoc_Location* aShapeLocation = ReadLocation (theStream);
+ Standard_Real aTol;
+ static BRep_Builder aBuilder;
+ try {
+ OCC_CATCH_SIGNALS
+ switch (aShapeType) {
+ case TopAbs_VERTEX:
+ {
+ TopoDS_Vertex& aV = TopoDS::Vertex (aResult);
+ // Read the point geometry
+ theStream >> aTol;
+ gp_Pnt aPnt = theStream.ReadPnt();
+ aBuilder.MakeVertex (aV, aPnt, aTol);
+ Handle(BRep_TVertex) aTV = Handle(BRep_TVertex)::DownCast (aV.TShape());
+ BRep_ListOfPointRepresentation& aLpr = aTV->ChangePoints();
+ static TopLoc_Location anEmptyLoc;
+ while (theStream) {
+ Standard_Byte aPrsType = theStream.ReadByte();
+ if (aPrsType == 0) // end of the cycle
+ break;
+ Standard_Real aParam = theStream.ReadReal();
+ Handle(BRep_PointRepresentation) aPR;
+ switch (aPrsType) {
+ case 1:
+ {
+ Handle(Geom_Curve) aCurve = ReadCurve (theStream);
+ if (!aCurve.IsNull())
+ aPR = new BRep_PointOnCurve (aParam, aCurve, anEmptyLoc);
+ break;
+ }
+ case 2:
+ {
+ Handle(Geom2d_Curve) aCurve2d = ReadCurve2d (theStream);
+ Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+ if (!aCurve2d.IsNull() && aSurface.IsNull())
+ aPR = new BRep_PointOnCurveOnSurface (aParam, aCurve2d, aSurface, anEmptyLoc);
+ break;
+ }
+ case 3:
+ {
+ Standard_Real aParam2 = theStream.ReadReal();
+ Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+ if (!aSurface.IsNull())
+ aPR = new BRep_PointOnSurface (aParam, aParam2, aSurface, anEmptyLoc);
+ break;
+ }
+ default:
+ {
+ Standard_SStream aMsg;
+ aMsg << "BinTools_ShapeReader::Read: UnExpected BRep_PointRepresentation = " << aPrsType << std::endl;
+ throw Standard_Failure (aMsg.str().c_str());
+ }
+ }
+ const TopLoc_Location* aPRLoc = ReadLocation (theStream);
+ if (!aPR.IsNull())
+ {
+ aPR->Location (*aPRLoc);
+ aLpr.Append (aPR);
+ }
+ }
+ break;
+ }
+ case TopAbs_EDGE:
+ {
+ TopoDS_Edge& aE = TopoDS::Edge (aResult);
+ aBuilder.MakeEdge(aE);
+ // Read the curve geometry
+ theStream >> aTol;
+ Standard_Boolean aSameParameter, aSameRange, aDegenerated;
+ theStream.ReadBools (aSameParameter, aSameRange, aDegenerated);
+ aBuilder.SameParameter (aE, aSameParameter);
+ aBuilder.SameRange (aE, aSameRange);
+ aBuilder.Degenerated (aE, aDegenerated);
+ Standard_Real aFirst, aLast;
+ while (theStream) {
+ Standard_Byte aPrsType = theStream.ReadByte(); //{0|1|2|3|4|5|6|7}
+ if (aPrsType == 0)
+ break;
+ switch (aPrsType)
+ {
+ case 1: // -1- Curve 3D
+ {
+ Handle(Geom_Curve) aCurve = ReadCurve (theStream);
+ const TopLoc_Location* aLoc = ReadLocation (theStream);
+ theStream >> aFirst;
+ theStream >> aLast;
+ if (!aCurve.IsNull())
+ {
+ aBuilder.UpdateEdge (aE, aCurve, *aLoc, aTol);
+ aBuilder.Range (aE, aFirst, aLast, Standard_True);
+ }
+ break;
+ }
+ case 2: // -2- Curve on surf
+ case 3: // -3- Curve on closed surf
+ {
+ Standard_Boolean aClosed = (aPrsType == 3);
+ Handle(Geom2d_Curve) aCurve2d_2, aCurve2d_1 = ReadCurve2d (theStream);
+ GeomAbs_Shape aReg = GeomAbs_C0;
+ if (aClosed) {
+ aCurve2d_2 = ReadCurve2d (theStream);
+ aReg = (GeomAbs_Shape)theStream.ReadByte();
+ }
+ Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+ const TopLoc_Location* aLoc = ReadLocation (theStream);
+ // range
+ theStream >> aFirst;
+ theStream >> aLast;
+ if (!aCurve2d_1.IsNull() && (!aClosed || !aCurve2d_2.IsNull()) && !aSurface.IsNull())
+ {
+ if (aClosed)
+ {
+ aBuilder.UpdateEdge (aE, aCurve2d_1, aCurve2d_2, aSurface, *aLoc, aTol);
+ aBuilder.Continuity (aE, aSurface, aSurface, *aLoc, *aLoc, aReg);
+ }
+ else
+ aBuilder.UpdateEdge (aE, aCurve2d_1, aSurface, *aLoc, aTol);
+ aBuilder.Range (aE, aSurface, *aLoc, aFirst, aLast);
+ }
+ break;
+ }
+ case 4: // -4- Regularity
+ {
+ GeomAbs_Shape aReg = (GeomAbs_Shape)theStream.ReadByte();
+ Handle(Geom_Surface) aSurface1 = ReadSurface (theStream);
+ const TopLoc_Location* aLoc1 = ReadLocation (theStream);
+ Handle(Geom_Surface) aSurface2 = ReadSurface (theStream);
+ const TopLoc_Location* aLoc2 = ReadLocation (theStream);
+ if (!aSurface1.IsNull() && !aSurface2.IsNull())
+ aBuilder.Continuity (aE, aSurface1, aSurface2, *aLoc1, *aLoc2, aReg);
+ break;
+ }
+ case 5: // -5- Polygon3D
+ {
+ Handle(Poly_Polygon3D) aPolygon = ReadPolygon3d (theStream);
+ const TopLoc_Location* aLoc = ReadLocation (theStream);
+ aBuilder.UpdateEdge (aE, aPolygon, *aLoc);
+ break;
+ }
+ case 6: // -6- Polygon on triangulation
+ case 7: // -7- Polygon on closed triangulation
+ {
+ Standard_Boolean aClosed = (aPrsType == 7);
+ Handle(Poly_PolygonOnTriangulation) aPoly2, aPoly1 = ReadPolygon (theStream);
+ if (aClosed)
+ aPoly2 = ReadPolygon (theStream);
+ Handle(Poly_Triangulation) aTriangulation = ReadTriangulation (theStream);
+ const TopLoc_Location* aLoc = ReadLocation (theStream);
+ if (aClosed)
+ aBuilder.UpdateEdge (aE, aPoly1, aPoly2, aTriangulation, *aLoc);
+ else
+ aBuilder.UpdateEdge (aE, aPoly1, aTriangulation, *aLoc);
+ // range
+ break;
+ }
+ default:
+ {
+ Standard_SStream aMsg;
+ aMsg << "Unexpected Curve Representation =" << aPrsType << std::endl;
+ throw Standard_Failure (aMsg.str().c_str());
+ }
+
+ }
+ }
+ break;
+ }
+ case TopAbs_WIRE:
+ aBuilder.MakeWire (TopoDS::Wire (aResult));
+ break;
+ case TopAbs_FACE:
+ {
+ TopoDS_Face& aF = TopoDS::Face (aResult);
+ aBuilder.MakeFace (aF);
+ Standard_Boolean aNatRes = theStream.ReadBool();
+ theStream >> aTol;
+ Handle(Geom_Surface) aSurface = ReadSurface (theStream);
+ const TopLoc_Location* aLoc = ReadLocation (theStream);
+ aBuilder.UpdateFace (aF, aSurface, *aLoc, aTol);
+ aBuilder.NaturalRestriction (aF, aNatRes);
+ if (theStream.ReadByte() == 2) // triangulation
+ aBuilder.UpdateFace (aF, ReadTriangulation (theStream));
+ break;
+ }
+ case TopAbs_SHELL:
+ aBuilder.MakeShell (TopoDS::Shell (aResult));
+ break;
+ case TopAbs_SOLID:
+ aBuilder.MakeSolid (TopoDS::Solid (aResult));
+ break;
+ case TopAbs_COMPSOLID:
+ aBuilder.MakeCompSolid (TopoDS::CompSolid (aResult));
+ break;
+ case TopAbs_COMPOUND:
+ aBuilder.MakeCompound (TopoDS::Compound (aResult));
+ break;
+ default:
+ {
+ Standard_SStream aMsg;
+ aMsg << "Unexpected topology type = " << aShapeType << std::endl;
+ throw Standard_Failure (aMsg.str().c_str());
+ break;
+ }
+ }
+ }
+ catch (Standard_Failure const& anException)
+ {
+ Standard_SStream aMsg;
+ aMsg << "EXCEPTION in BinTools_ShapeReader::Read" << std::endl;
+ aMsg << anException << std::endl;
+ throw Standard_Failure (aMsg.str().c_str());
+ }
+ // read flags and subs
+ Standard_Boolean aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv;
+ theStream.ReadBools (aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv);
+ // sub-shapes
+ for(TopoDS_Shape aSub = ReadShape (theStream); !aSub.IsNull(); aSub = ReadShape (theStream))
+ aBuilder.Add (aResult, aSub);
+ aResult.Free (aFree);
+ aResult.Modified (aMod);
+ aResult.Checked (aChecked);
+ aResult.Orientable (anOrient);
+ aResult.Closed (aClosed);
+ aResult.Infinite (anInf);
+ aResult.Convex (aConv);
+ myShapePos.Bind (aPosition, aResult);
+ aResult.Orientation (aShapeOrientation);
+ aResult.Location (*aShapeLocation);
+ return aResult;
+}
+
+//=======================================================================
+//function : ReadLocation
+//purpose :
+//=======================================================================
+const TopLoc_Location* BinTools_ShapeReader::ReadLocation (BinTools_IStream& theStream)
+{
+ static const TopLoc_Location* anEmptyLoc = new TopLoc_Location;
+
+ uint64_t aPosition = theStream.Position();
+ const BinTools_ObjectType& aType = theStream.ReadType();
+ if (aType == BinTools_ObjectType_EmptyLocation || aType == BinTools_ObjectType_LocationEnd)
+ return anEmptyLoc;
+ if (theStream.IsReference())
+ {
+ uint64_t aRef = theStream.ReadReference();
+ const TopLoc_Location* aFound = myLocationPos.Seek (aRef);
+ if (aFound) // the location is already retrieved
+ return aFound;
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ const TopLoc_Location* aResult = ReadLocation (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ return aResult;
+ }
+ // read the location directly from the stream
+ TopLoc_Location aLoc;
+ if (aType == BinTools_ObjectType_SimpleLocation)
+ {
+ gp_Trsf aTrsf;
+ theStream >> aTrsf;
+ aLoc = aTrsf;
+ }
+ else if (aType == BinTools_ObjectType_Location)
+ {
+ for(const TopLoc_Location* aNextLoc = ReadLocation (theStream); !aNextLoc->IsIdentity();
+ aNextLoc = ReadLocation (theStream))
+ aLoc = aNextLoc->Powered (theStream.ReadInteger()) * aLoc;
+ }
+ myLocationPos.Bind (aPosition, aLoc);
+ return myLocationPos.Seek (aPosition);
+}
+
+//=======================================================================
+//function : ReadCurve
+//purpose :
+//=======================================================================
+Handle(Geom_Curve) BinTools_ShapeReader::ReadCurve (BinTools_IStream& theStream)
+{
+ Handle(Geom_Curve) aResult;
+ uint64_t aPosition = theStream.Position();
+ theStream.ReadType();
+ if (theStream.IsReference())
+ { // get by reference
+ uint64_t aRef = theStream.ReadReference();
+ const Handle(Geom_Curve)* aFound = myCurvePos.Seek (aRef);
+ if (aFound) // the location is already retrieved
+ return *aFound;
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ aResult = ReadCurve (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ }
+ else if (theStream.LastType() == BinTools_ObjectType_Curve)
+ { // read from the stream
+ BinTools_CurveSet::ReadCurve (theStream.Stream(), aResult);
+ theStream.UpdatePosition();
+ myCurvePos.Bind (aPosition, aResult);
+ }
+ return aResult;
+}
+
+//=======================================================================
+//function : ReadCurve2d
+//purpose :
+//=======================================================================
+Handle(Geom2d_Curve) BinTools_ShapeReader::ReadCurve2d (BinTools_IStream& theStream)
+{
+ Handle(Geom2d_Curve) aResult;
+ uint64_t aPosition = theStream.Position();
+ theStream.ReadType();
+ if (theStream.IsReference())
+ { // get by reference
+ uint64_t aRef = theStream.ReadReference();
+ const Handle(Geom2d_Curve)* aFound = myCurve2dPos.Seek (aRef);
+ if (aFound) // the location is already retrieved
+ return *aFound;
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ aResult = ReadCurve2d (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ }
+ else if (theStream.LastType() == BinTools_ObjectType_Curve2d)
+ { // read from the stream
+ BinTools_Curve2dSet::ReadCurve2d (theStream.Stream(), aResult);
+ theStream.UpdatePosition();
+ myCurve2dPos.Bind (aPosition, aResult);
+ }
+ return aResult;
+}
+
+//=======================================================================
+//function : ReadSurface
+//purpose :
+//=======================================================================
+Handle(Geom_Surface) BinTools_ShapeReader::ReadSurface (BinTools_IStream& theStream)
+{
+ Handle(Geom_Surface) aResult;
+ uint64_t aPosition = theStream.Position();
+ theStream.ReadType();
+ if (theStream.IsReference())
+ { // get by reference
+ uint64_t aRef = theStream.ReadReference();
+ const Handle(Geom_Surface)* aFound = mySurfacePos.Seek (aRef);
+ if (aFound) // the location is already retrieved
+ return *aFound;
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ aResult = ReadSurface (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ }
+ else if (theStream.LastType() == BinTools_ObjectType_Surface)
+ { // read from the stream
+ BinTools_SurfaceSet::ReadSurface (theStream.Stream(), aResult);
+ theStream.UpdatePosition();
+ mySurfacePos.Bind (aPosition, aResult);
+ }
+ return aResult;
+}
+
+//=======================================================================
+//function : ReadPolygon3d
+//purpose :
+//=======================================================================
+Handle(Poly_Polygon3D) BinTools_ShapeReader::ReadPolygon3d (BinTools_IStream& theStream)
+{
+ Handle(Poly_Polygon3D) aResult;
+ uint64_t aPosition = theStream.Position();
+ theStream.ReadType();
+ if (theStream.IsReference())
+ { // get by reference
+ uint64_t aRef = theStream.ReadReference();
+ const Handle(Poly_Polygon3D)* aFound = myPolygon3dPos.Seek (aRef);
+ if (aFound) // the location is already retrieved
+ return *aFound;
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ aResult = ReadPolygon3d (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ }
+ else if (theStream.LastType() == BinTools_ObjectType_Polygon3d)
+ { // read from the stream
+ Standard_Integer aNbNodes = theStream.ReadInteger();
+ Standard_Boolean aHasParameters = theStream.ReadBool();
+ aResult = new Poly_Polygon3D (aNbNodes, aHasParameters);
+ aResult->Deflection (theStream.ReadReal());
+ TColgp_Array1OfPnt& aNodes = aResult->ChangeNodes();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream >> aNodes.ChangeValue (aNodeIter);
+ if (aHasParameters)
+ {
+ TColStd_Array1OfReal& aParam = aResult->ChangeParameters();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream >> aParam.ChangeValue (aNodeIter);
+ }
+ myPolygon3dPos.Bind (aPosition, aResult);
+ }
+ return aResult;
+}
+
+//=======================================================================
+//function : ReadPolygon
+//purpose :
+//=======================================================================
+Handle(Poly_PolygonOnTriangulation) BinTools_ShapeReader::ReadPolygon (BinTools_IStream& theStream)
+{
+ Handle(Poly_PolygonOnTriangulation) aResult;
+ uint64_t aPosition = theStream.Position();
+ theStream.ReadType();
+ if (theStream.IsReference())
+ { // get by reference
+ uint64_t aRef = theStream.ReadReference();
+ const Handle(Poly_PolygonOnTriangulation)* aFound = myPolygonPos.Seek (aRef);
+ if (aFound) // the location is already retrieved
+ return *aFound;
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ aResult = ReadPolygon (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ }
+ else if (theStream.LastType() == BinTools_ObjectType_PolygonOnTriangulation)
+ { // read from the stream
+ Standard_Integer aNbNodes = theStream.ReadInteger();
+ aResult = new Poly_PolygonOnTriangulation (aNbNodes, Standard_False);
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ aResult->SetNode(aNodeIter, theStream.ReadInteger());
+ aResult->Deflection (theStream.ReadReal());
+ if (theStream.ReadBool())
+ {
+ Handle(TColStd_HArray1OfReal) aParams = new TColStd_HArray1OfReal (1, aNbNodes);
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream >> aParams->ChangeValue (aNodeIter);
+ aResult->SetParameters (aParams);
+ }
+ myPolygonPos.Bind (aPosition, aResult);
+ }
+ return aResult;
+}
+
+//=======================================================================
+//function : ReadTriangulation
+//purpose :
+//=======================================================================
+Handle(Poly_Triangulation) BinTools_ShapeReader::ReadTriangulation (BinTools_IStream& theStream)
+{
+ Handle(Poly_Triangulation) aResult;
+ uint64_t aPosition = theStream.Position();
+ const BinTools_ObjectType& aType = theStream.ReadType();
+ if (theStream.IsReference())
+ { // get by reference
+ uint64_t aRef = theStream.ReadReference();
+ const Handle(Poly_Triangulation)* aFound = myTriangulationPos.Seek (aRef);
+ if (aFound) // the location is already retrieved
+ return *aFound;
+ uint64_t aCurrent = theStream.Position();
+ theStream.GoTo (aRef); // go to the referenced position
+ aResult = ReadTriangulation (theStream);
+ theStream.GoTo (aCurrent); // returns to the current position
+ }
+ else if (aType == BinTools_ObjectType_Triangulation)
+ { // read from the stream
+ Standard_Integer aNbNodes = theStream.ReadInteger();
+ Standard_Integer aNbTriangles = theStream.ReadInteger();
+ Standard_Boolean aHasUV = theStream.ReadBool();
+ Standard_Boolean aHasNormals = theStream.ReadBool();
+ aResult = new Poly_Triangulation (aNbNodes, aNbTriangles, aHasUV, aHasNormals);
+ aResult->Deflection (theStream.ReadReal());
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ aResult->SetNode(aNodeIter, theStream.ReadPnt());
+ if (aHasUV)
+ {
+ gp_Pnt2d anUV;
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ {
+ theStream >> anUV.ChangeCoord().ChangeCoord (1);
+ theStream >> anUV.ChangeCoord().ChangeCoord (2);
+ aResult->SetUVNode(aNodeIter, anUV);
+ }
+ }
+ // read the triangles
+ Poly_Triangle aTriangle;
+ for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
+ {
+ theStream >> aTriangle.ChangeValue (1);
+ theStream >> aTriangle.ChangeValue (2);
+ theStream >> aTriangle.ChangeValue (3);
+ aResult->SetTriangle(aTriIter, aTriangle);
+ }
+ if (aHasNormals)
+ {
+ gp_Vec3f aNormal;
+ for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes; ++aNormalIter)
+ {
+ theStream >> aNormal.x();
+ theStream >> aNormal.y();
+ theStream >> aNormal.z();
+ aResult->SetNormal (aNormalIter, aNormal);
+ }
+ }
+
+ myTriangulationPos.Bind (aPosition, aResult);
+ }
+ return aResult;
+}
--- /dev/null
+// 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 _BinTools_ShapeReader_HeaderFile
+#define _BinTools_ShapeReader_HeaderFile
+
+#include <BinTools_ShapeSetBase.hxx>
+#include <BinTools_IStream.hxx>
+#include <NCollection_DataMap.hxx>
+
+class TopLoc_Location;
+class Geom_Curve;
+class Geom2d_Curve;
+class Geom_Surface;
+class Poly_Polygon3D;
+class Poly_PolygonOnTriangulation;
+class Poly_Triangulation;
+
+//! Reads topology from IStream in binary format without grouping of objects by types
+//! and using relative positions in a file as references.
+class BinTools_ShapeReader : public BinTools_ShapeSetBase
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+ //! Initializes a shape reader.
+ Standard_EXPORT BinTools_ShapeReader();
+
+ Standard_EXPORT virtual ~BinTools_ShapeReader();
+
+ //! Clears the content of the set.
+ Standard_EXPORT virtual void Clear() override;
+
+ //! Reads the shape from stream using previously restored shapes and objects by references.
+ Standard_EXPORT void Read (Standard_IStream& theStream, TopoDS_Shape& theShape) override;
+
+ //! Reads location from the stream.
+ Standard_EXPORT const TopLoc_Location* ReadLocation (BinTools_IStream& theStream);
+
+private:
+ //! Reads the shape from stream using previously restored shapes and objects by references.
+ TopoDS_Shape ReadShape (BinTools_IStream& theStream);
+ //! Reads curve from the stream.
+ Handle(Geom_Curve) ReadCurve (BinTools_IStream& theStream);
+ //! Reads curve2d from the stream.
+ Handle(Geom2d_Curve) ReadCurve2d (BinTools_IStream& theStream);
+ //! Reads surface from the stream.
+ Handle(Geom_Surface) ReadSurface (BinTools_IStream& theStream);
+ //! Reads ploygon3d from the stream.
+ Handle(Poly_Polygon3D) ReadPolygon3d (BinTools_IStream& theStream);
+ //! Reads polygon on triangulation from the stream.
+ Handle(Poly_PolygonOnTriangulation) ReadPolygon (BinTools_IStream& theStream);
+ //! Reads triangulation from the stream.
+ Handle(Poly_Triangulation) ReadTriangulation (BinTools_IStream& theStream);
+
+ /// position of the shape previously restored
+ NCollection_DataMap<uint64_t, TopoDS_Shape> myShapePos;
+ NCollection_DataMap<uint64_t, TopLoc_Location> myLocationPos;
+ NCollection_DataMap<uint64_t, Handle(Geom_Curve)> myCurvePos;
+ NCollection_DataMap<uint64_t, Handle(Geom2d_Curve)> myCurve2dPos;
+ NCollection_DataMap<uint64_t, Handle(Geom_Surface)> mySurfacePos;
+ NCollection_DataMap<uint64_t, Handle(Poly_Polygon3D)> myPolygon3dPos;
+ NCollection_DataMap<uint64_t, Handle(Poly_PolygonOnTriangulation)> myPolygonPos;
+ NCollection_DataMap<uint64_t, Handle(Poly_Triangulation)> myTriangulationPos;
+};
+
+#endif // _BinTools_ShapeReader_HeaderFile
#include <Message_ProgressRange.hxx>
#include <string.h>
-//#define MDTV_DEB 1
-const Standard_CString BinTools_ShapeSet::THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1] =
-{
- "",
- "Open CASCADE Topology V1 (c)",
- "Open CASCADE Topology V2 (c)",
- "Open CASCADE Topology V3 (c)",
- "Open CASCADE Topology V4, (c) Open Cascade"
-};
-
-//=======================================================================
-//function : operator << (gp_Pnt)
-//purpose :
-//=======================================================================
-
-static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt P)
-{
- BinTools::PutReal(OS, P.X());
- BinTools::PutReal(OS, P.Y());
- BinTools::PutReal(OS, P.Z());
- return OS;
-}
//=======================================================================
//function : BinTools_ShapeSet
//purpose :
//=======================================================================
BinTools_ShapeSet::BinTools_ShapeSet ()
-: myFormatNb (BinTools_FormatVersion_CURRENT),
- myWithTriangles (Standard_False),
- myWithNormals(Standard_False)
+ : BinTools_ShapeSetBase ()
{}
//=======================================================================
BinTools_ShapeSet::~BinTools_ShapeSet()
{}
-//=======================================================================
-//function : SetFormatNb
-//purpose :
-//=======================================================================
-void BinTools_ShapeSet::SetFormatNb(const Standard_Integer theFormatNb)
-{
- Standard_ASSERT_RETURN(theFormatNb >= BinTools_FormatVersion_LOWER &&
- theFormatNb <= BinTools_FormatVersion_UPPER,
- "Error: unsupported BinTools version.", );
-
- myFormatNb = theFormatNb;
-}
-
-//=======================================================================
-//function : FormatNb
-//purpose :
-//=======================================================================
-Standard_Integer BinTools_ShapeSet::FormatNb() const
-{
- return myFormatNb;
-}
-
//=======================================================================
//function : Clear
//purpose :
//purpose :
//=======================================================================
-Standard_Integer BinTools_ShapeSet::Add(const TopoDS_Shape& theShape)
+Standard_Integer BinTools_ShapeSet::Add (const TopoDS_Shape& theShape)
{
if (theShape.IsNull()) return 0;
myLocations.Add(theShape.Location());
TopoDS_Shape aS2 = theShape;
- aS2.Location(TopLoc_Location());
- Standard_Integer anIndex = myShapes.FindIndex(aS2);
+ aS2.Location (TopLoc_Location());
+ Standard_Integer anIndex = myShapes.FindIndex (aS2);
if (anIndex == 0) {
- AddGeometry(aS2);
- for (TopoDS_Iterator its(aS2,Standard_False,Standard_False);its.More(); its.Next())
- Add(its.Value());
- anIndex = myShapes.Add(aS2);
+ AddShape (aS2);
+ for (TopoDS_Iterator its (aS2, Standard_False, Standard_False); its.More(); its.Next())
+ Add (its.Value());
+ anIndex = myShapes.Add (aS2);
}
return anIndex;
}
//purpose :
//=======================================================================
-const TopoDS_Shape& BinTools_ShapeSet::Shape(const Standard_Integer theIndx)const
+const TopoDS_Shape& BinTools_ShapeSet::Shape (const Standard_Integer theIndx)
{
- return myShapes(theIndx);
+ return myShapes (theIndx);
}
//=======================================================================
//purpose :
//=======================================================================
-Standard_Integer BinTools_ShapeSet::Index(const TopoDS_Shape& theShape) const
+Standard_Integer BinTools_ShapeSet::Index (const TopoDS_Shape& theShape) const
{
- return myShapes.FindIndex(theShape);
+ return myShapes.FindIndex (theShape);
}
//=======================================================================
//purpose :
//=======================================================================
-const BinTools_LocationSet& BinTools_ShapeSet::Locations()const
+const BinTools_LocationSet& BinTools_ShapeSet::Locations() const
{
return myLocations;
}
//purpose :
//=======================================================================
-void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
+void BinTools_ShapeSet::AddShape (const TopoDS_Shape& S)
{
// Add the geometry
mySurfaces.Add(CR->Surface2());
ChangeLocations().Add(CR->Location2());
}
- else if (myWithTriangles) {
+ else if (IsWithTriangles()) {
if (CR->IsPolygon3D()) {
if (!CR->Polygon3D().IsNull()) {
myPolygons3D.Add(CR->Polygon3D());
else if (S.ShapeType() == TopAbs_FACE) {
// Add the surface geometry
- Standard_Boolean needNormals(myWithNormals);
+ Standard_Boolean needNormals (IsWithNormals());
Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
if (!TF->Surface().IsNull())
{
{
needNormals = Standard_True;
}
- if (myWithTriangles
- || TF->Surface().IsNull())
+ if (IsWithTriangles() || TF->Surface().IsNull())
{
Handle(Poly_Triangulation) Tr = TF->Triangulation();
if (!Tr.IsNull()) myTriangulations.Add(Tr, needNormals);
//=======================================================================
void BinTools_ShapeSet::Write (Standard_OStream& OS,
- const Message_ProgressRange& theRange)const
+ const Message_ProgressRange& theRange)
{
// write the copyright
- OS << "\n" << THE_ASCII_VERSIONS[myFormatNb] << "\n";
+ OS << "\n" << THE_ASCII_VERSIONS[FormatNb()] << "\n";
//-----------------------------------------
// write the locations
// subshapes are written first
for (i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next()) {
- const TopoDS_Shape& S = myShapes(i);
+ const TopoDS_Shape& S = myShapes (i);
// Type
OS << (Standard_Byte)S.ShapeType();
// Geometry
- WriteGeometry(S,OS);
+ WriteShape (S, OS);
// Flags
BinTools::PutBool(OS, S.Free()? 1:0);
//function : Read
//purpose :
//=======================================================================
-
void BinTools_ShapeSet::Read (Standard_IStream& IS,
const Message_ProgressRange& theRange)
{
-
Clear();
// Check the version
//-----------------------------------------
// read the locations
//-----------------------------------------
-
myLocations.Read(IS);
//-----------------------------------------
// read the geometry
IS >> nbShapes;
IS.get();//remove lf
Message_ProgressScope aPSinner(aPSouter.Next(), "Reading Shapes", nbShapes);
- for (int i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next()) {
-
+ for (int i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next())
+ {
TopoDS_Shape S;
-
- //Read type and create empty shape.
-
- TopAbs_ShapeEnum T = (TopAbs_ShapeEnum) IS.get();
-
- ReadGeometry(T,IS,S);
-
- // Set the flags
- Standard_Boolean aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv;
- BinTools::GetBool(IS, aFree);
- BinTools::GetBool(IS, aMod);
- BinTools::GetBool(IS, aChecked);
- BinTools::GetBool(IS, anOrient);
- BinTools::GetBool(IS, aClosed);
- BinTools::GetBool(IS, anInf);
- BinTools::GetBool(IS, aConv);
-
- // sub-shapes
- TopoDS_Shape SS;
- do {
- Read(SS,IS,nbShapes);
- if (!SS.IsNull())
- AddShapes(S,SS);
- } while(!SS.IsNull());
-
- S.Free(aFree);
- S.Modified(aMod);
- if (myFormatNb != BinTools_FormatVersion_VERSION_2
- && myFormatNb != BinTools_FormatVersion_VERSION_3)
- {
- aChecked = false; // force check at reading
- }
- S.Checked (aChecked);
- S.Orientable(anOrient);
- S.Closed (aClosed);
- S.Infinite (anInf);
- S.Convex (aConv);
- // check
-
- if (myFormatNb == BinTools_FormatVersion_VERSION_1)
- if(T == TopAbs_FACE) {
- const TopoDS_Face& F = TopoDS::Face(S);
- BRepTools::Update(F);
- }
- myShapes.Add(S);
+ TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
+ ReadShape (T, IS, S);
+ ReadFlagsAndSubs (S, T, IS, nbShapes);
+ myShapes.Add (S);
}
}
//=======================================================================
void BinTools_ShapeSet::Write (const TopoDS_Shape& S,
- Standard_OStream& OS)const
+ Standard_OStream& OS)
{
if (S.IsNull())
else {
// {TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL}
OS << (Standard_Byte) S.Orientation();
- BinTools::PutInteger(OS, myShapes.Extent() - myShapes.FindIndex(S.Located(TopLoc_Location())) + 1);
- BinTools::PutInteger(OS, Locations().Index(S.Location()));
+ BinTools::PutInteger (OS, myShapes.Extent() - myShapes.FindIndex (S.Located (TopLoc_Location())) + 1);
+ BinTools::PutInteger (OS, Locations().Index (S.Location()));
}
}
//=======================================================================
-//function : Read
+//function : ReadFlagsAndSubs
//purpose :
//=======================================================================
-void BinTools_ShapeSet::Read (TopoDS_Shape& S, Standard_IStream& IS,
- const Standard_Integer nbshapes)const
+void BinTools_ShapeSet::ReadFlagsAndSubs(TopoDS_Shape& S, const TopAbs_ShapeEnum T,
+ Standard_IStream& IS, const Standard_Integer nbShapes)
+{
+ // Set the flags
+ Standard_Boolean aFree, aMod, aChecked, anOrient, aClosed, anInf, aConv;
+ BinTools::GetBool(IS, aFree);
+ BinTools::GetBool(IS, aMod);
+ BinTools::GetBool(IS, aChecked);
+ BinTools::GetBool(IS, anOrient);
+ BinTools::GetBool(IS, aClosed);
+ BinTools::GetBool(IS, anInf);
+ BinTools::GetBool(IS, aConv);
+
+ // sub-shapes
+ TopoDS_Shape SS;
+ do {
+ ReadSubs(SS, IS, nbShapes);
+ if (!SS.IsNull())
+ AddShapes(S, SS);
+ } while (!SS.IsNull());
+
+ S.Free(aFree);
+ S.Modified(aMod);
+ if (FormatNb() != BinTools_FormatVersion_VERSION_2 &&
+ FormatNb() != BinTools_FormatVersion_VERSION_3)
+ {
+ aChecked = false; // force check at reading
+ }
+ S.Checked (aChecked);
+ S.Orientable (anOrient);
+ S.Closed (aClosed);
+ S.Infinite (anInf);
+ S.Convex (aConv);
+ // check
+
+ if (FormatNb() == BinTools_FormatVersion_VERSION_1)
+ if (T == TopAbs_FACE) {
+ const TopoDS_Face& F = TopoDS::Face(S);
+ BRepTools::Update(F);
+ }
+}
+
+//=======================================================================
+//function : ReadSubs
+//purpose :
+//=======================================================================
+void BinTools_ShapeSet::ReadSubs(TopoDS_Shape& S, Standard_IStream& IS,
+ const Standard_Integer nbshapes)
{
Standard_Character aChar = '\0';
IS >> aChar;
- if(aChar == '*')
+ if (aChar == '*')
S = TopoDS_Shape();
else {
TopAbs_Orientation anOrient;
anOrient = (TopAbs_Orientation)aChar;
Standard_Integer anIndx;
BinTools::GetInteger(IS, anIndx);
- S = myShapes(nbshapes - anIndx + 1);
+ S = Shape (nbshapes - anIndx + 1);
S.Orientation(anOrient);
Standard_Integer l;
//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());
}
//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 {
BinTools::PutReal(OS, last);
// Write UV Points for higher performance
- if (myFormatNb == BinTools_FormatVersion_VERSION_2
- || myFormatNb == BinTools_FormatVersion_VERSION_3)
+ if (FormatNb() == BinTools_FormatVersion_VERSION_2
+ || FormatNb() == BinTools_FormatVersion_VERSION_3)
{
gp_Pnt2d Pf,Pl;
if (CR->IsCurveOnClosedSurface()) {
}
- else if (myWithTriangles) {
+ else if (IsWithTriangles()) {
if (CR->IsPolygon3D()) {
Handle(BRep_Polygon3D) GC = Handle(BRep_Polygon3D)::DownCast(itrc.Value());
if (!GC->Polygon3D().IsNull()) {
: 0);
BinTools::PutInteger (OS, Locations().Index (TF->Location()));
- if (myWithTriangles
- || TF->Surface().IsNull())
+ if (IsWithTriangles() || TF->Surface().IsNull())
{
if (!(TF->Triangulation()).IsNull()) {
OS << (Standard_Byte) 2;
}
//=======================================================================
-//function : ReadGeometry
+//function : ReadShape
//purpose :
//=======================================================================
-void BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
- Standard_IStream& IS,
- TopoDS_Shape& S)
+void BinTools_ShapeSet::ReadShape (const TopAbs_ShapeEnum T,
+ Standard_IStream& IS,
+ TopoDS_Shape& S)
{
// Read the geometry
- Standard_Integer val, c,pc,pc2 = 0,s,s2,l,l2,t, pt, pt2 = 0;
- Standard_Real tol,X,Y,Z,first,last,p1 = 0.,p2;
- Standard_Real PfX,PfY,PlX,PlY;
+ Standard_Integer val, c, pc, pc2 = 0, s, s2, l, l2, t, pt, pt2 = 0;
+ Standard_Real tol, X, Y, Z, first, last, p1 = 0., p2;
+ Standard_Real PfX, PfY, PlX, PlY;
gp_Pnt2d aPf, aPl;
Standard_Boolean closed, bval;
GeomAbs_Shape reg = GeomAbs_C0;
try {
OCC_CATCH_SIGNALS
- switch (T) {
+ switch (T) {
- //---------
- // vertex
- //---------
+ //---------
+ // vertex
+ //---------
- case TopAbs_VERTEX :
+ case TopAbs_VERTEX:
{
-// Standard_Integer aPos = IS.tellg();
-// std::cout << "\nPOS = " << aPos << std::endl;
- TopoDS_Vertex& V = TopoDS::Vertex(S);
-
- // Read the point geometry
- BinTools::GetReal(IS, tol);
- BinTools::GetReal(IS, X);
- BinTools::GetReal(IS, Y);
- BinTools::GetReal(IS, Z);
- gp_Pnt aPnt (X, Y, Z);
- myBuilder.MakeVertex (V, aPnt, tol);
- Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V.TShape());
-
- BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
- TopLoc_Location L;
- do {
- if(myFormatNb == BinTools_FormatVersion_VERSION_3) {
- val = (Standard_Integer)IS.get();//case {0|1|2|3}
- if (val > 0 && val <= 3)
- BinTools::GetReal(IS, p1);
- } else {
- std::streampos aPos = IS.tellg();
- BinTools::GetReal(IS, p1);
- val = (Standard_Integer)IS.get();//case {0|1|2|3}
+ TopoDS_Vertex& V = TopoDS::Vertex(S);
+
+ // Read the point geometry
+ BinTools::GetReal(IS, tol);
+ BinTools::GetReal(IS, X);
+ BinTools::GetReal(IS, Y);
+ BinTools::GetReal(IS, Z);
+ gp_Pnt aPnt(X, Y, Z);
+ myBuilder.MakeVertex(V, aPnt, tol);
+ Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V.TShape());
+
+ BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
+ TopLoc_Location L;
+ do {
+ if (FormatNb() == BinTools_FormatVersion_VERSION_3) {
+ val = (Standard_Integer)IS.get();//case {0|1|2|3}
+ if (val > 0 && val <= 3)
+ BinTools::GetReal(IS, p1);
+ }
+ else {
+ std::streampos aPos = IS.tellg();
+ BinTools::GetReal(IS, p1);
+ val = (Standard_Integer)IS.get();//case {0|1|2|3}
#ifdef OCCT_DEBUG
- std::cout << "\nVal = " << val <<std::endl;
+ std::cout << "\nVal = " << val << std::endl;
#endif
- if(val != 1 && val !=2 && val !=3){
- IS.seekg(aPos);
- val = (Standard_Integer)IS.get();
- if (val > 0 && val <= 3)
- BinTools::GetReal(IS, p1);
- }
- }
- Handle(BRep_PointRepresentation) PR;
- switch (val) {
- case 0 :
- break;
-
- case 1 :
- {
- BinTools::GetInteger(IS, c);
- if (myCurves.Curve(c).IsNull())
- break;
- Handle(BRep_PointOnCurve) POC =
- new BRep_PointOnCurve(p1,
- myCurves.Curve(c),
- L);
- PR = POC;
- }
- break;
-
- case 2 :
- {
- BinTools::GetInteger(IS, pc);
- BinTools::GetInteger(IS, s);
- if (myCurves2d.Curve2d(pc).IsNull() ||
- mySurfaces.Surface(s).IsNull())
- break;
-
- Handle(BRep_PointOnCurveOnSurface) POC =
- new BRep_PointOnCurveOnSurface(p1,
- myCurves2d.Curve2d(pc),
- mySurfaces.Surface(s),
- L);
- PR = POC;
- }
- break;
-
- case 3 :
- {
- BinTools::GetReal(IS, p2);
- BinTools::GetInteger(IS, s);
- if (mySurfaces.Surface(s).IsNull())
- break;
-
- Handle(BRep_PointOnSurface) POC =
- new BRep_PointOnSurface(p1,p2,
- mySurfaces.Surface(s),
- L);
- PR = POC;
- }
- break;
-
- default:
- {
- Standard_SStream aMsg;
- aMsg << "BinTools_SurfaceSet::ReadGeometry: UnExpected BRep_PointRepresentation = "<< val <<std::endl;
- throw Standard_Failure(aMsg.str().c_str());
- }
- }
-
- if (val > 0) {
- BinTools::GetInteger(IS, l);//Locations index
-
- if (!PR.IsNull()) {
- PR->Location(Locations().Location(l));
- lpr.Append(PR);
- }
- }
- } while (val > 0);
+ if (val != 1 && val != 2 && val != 3) {
+ IS.seekg(aPos);
+ val = (Standard_Integer)IS.get();
+ if (val > 0 && val <= 3)
+ BinTools::GetReal(IS, p1);
+ }
+ }
+ Handle(BRep_PointRepresentation) PR;
+ switch (val) {
+ case 0:
+ break;
+
+ case 1:
+ {
+ BinTools::GetInteger(IS, c);
+ if (myCurves.Curve(c).IsNull())
+ break;
+ Handle(BRep_PointOnCurve) POC =
+ new BRep_PointOnCurve(p1,
+ myCurves.Curve(c),
+ L);
+ PR = POC;
+ }
+ break;
+
+ case 2:
+ {
+ BinTools::GetInteger(IS, pc);
+ BinTools::GetInteger(IS, s);
+ if (myCurves2d.Curve2d(pc).IsNull() ||
+ mySurfaces.Surface(s).IsNull())
+ break;
+
+ Handle(BRep_PointOnCurveOnSurface) POC =
+ new BRep_PointOnCurveOnSurface(p1,
+ myCurves2d.Curve2d(pc),
+ mySurfaces.Surface(s),
+ L);
+ PR = POC;
+ }
+ break;
+
+ case 3:
+ {
+ BinTools::GetReal(IS, p2);
+ BinTools::GetInteger(IS, s);
+ if (mySurfaces.Surface(s).IsNull())
+ break;
+
+ Handle(BRep_PointOnSurface) POC =
+ new BRep_PointOnSurface(p1, p2,
+ mySurfaces.Surface(s),
+ L);
+ PR = POC;
+ }
+ break;
+
+ default:
+ {
+ Standard_SStream aMsg;
+ aMsg << "BinTools_SurfaceSet::ReadGeometry: UnExpected BRep_PointRepresentation = " << val << std::endl;
+ throw Standard_Failure(aMsg.str().c_str());
+ }
+ }
+
+ if (val > 0) {
+ BinTools::GetInteger(IS, l);//Locations index
+
+ if (!PR.IsNull()) {
+ PR->Location(Locations().Location(l));
+ lpr.Append(PR);
+ }
+ }
+ } while (val > 0);
}
break;
-
+
//---------
// edge
//---------
- case TopAbs_EDGE :
+ case TopAbs_EDGE:
- // Create an edge
+ // Create an edge
{
TopoDS_Edge& E = TopoDS::Edge(S);
-
+
myBuilder.MakeEdge(E);
-
+
// Read the curve geometry
- BinTools::GetReal(IS, tol);
- BinTools::GetBool(IS, bval);
+ BinTools::GetReal(IS, tol);
+ BinTools::GetBool(IS, bval);
myBuilder.SameParameter(E, bval);
- BinTools::GetBool(IS, bval);
- myBuilder.SameRange(E,bval);
+ BinTools::GetBool(IS, bval);
+ myBuilder.SameRange(E, bval);
+
+ BinTools::GetBool(IS, bval);
+ myBuilder.Degenerated(E, bval);
- BinTools::GetBool(IS, bval);
- myBuilder.Degenerated(E,bval);
-
do {
- val = (Standard_Integer)IS.get();//{0|1|2|3|4|5|6|7}
- // -0- no representation
- // -1- Curve 3D
- // -2- Curve on surf
- // -3- Curve on closed surf
- // -4- Regularity
- // -5- Polygon3D
- // -6- Polygon on triangulation
- // -7- Polygon on closed triangulation
+ val = (Standard_Integer)IS.get();//{0|1|2|3|4|5|6|7}
+ // -0- no representation
+ // -1- Curve 3D
+ // -2- Curve on surf
+ // -3- Curve on closed surf
+ // -4- Regularity
+ // -5- Polygon3D
+ // -6- Polygon on triangulation
+ // -7- Polygon on closed triangulation
switch (val) {
- case 0:
- break;
-
- case 1 : // -1- Curve 3D
- BinTools::GetInteger(IS, c);
- BinTools::GetInteger(IS, l);
- if (!myCurves.Curve(c).IsNull()) {
- myBuilder.UpdateEdge(E,myCurves.Curve(c),
- Locations().Location(l),tol);
- }
- BinTools::GetReal(IS, first);
- BinTools::GetReal(IS, last);
- if (!myCurves.Curve(c).IsNull()) {
- Standard_Boolean Only3d = Standard_True;
- myBuilder.Range(E,first,last,Only3d);
- }
+ case 0:
+ break;
+
+ case 1: // -1- Curve 3D
+ BinTools::GetInteger(IS, c);
+ BinTools::GetInteger(IS, l);
+ if (!myCurves.Curve(c).IsNull()) {
+ myBuilder.UpdateEdge(E, myCurves.Curve(c),
+ Locations().Location(l), tol);
+ }
+ BinTools::GetReal(IS, first);
+ BinTools::GetReal(IS, last);
+ if (!myCurves.Curve(c).IsNull()) {
+ Standard_Boolean Only3d = Standard_True;
+ myBuilder.Range(E, first, last, Only3d);
+ }
break;
-
-
- case 2 : // -2- Curve on surf
- case 3 : // -3- Curve on closed surf
+
+
+ case 2: // -2- Curve on surf
+ case 3: // -3- Curve on closed surf
closed = (val == 3);
- BinTools::GetInteger(IS, pc);
+ BinTools::GetInteger(IS, pc);
if (closed) {
- BinTools::GetInteger(IS, pc2);
- reg = (GeomAbs_Shape)IS.get();
+ BinTools::GetInteger(IS, pc2);
+ reg = (GeomAbs_Shape)IS.get();
}
// surface, location
- BinTools::GetInteger(IS, s);
- BinTools::GetInteger(IS, l);
+ BinTools::GetInteger(IS, s);
+ BinTools::GetInteger(IS, l);
// range
- BinTools::GetReal(IS, first);
- BinTools::GetReal(IS, last);
+ BinTools::GetReal(IS, first);
+ BinTools::GetReal(IS, last);
// read UV Points // for XML Persistence higher performance
- if (myFormatNb == BinTools_FormatVersion_VERSION_2
- || myFormatNb == BinTools_FormatVersion_VERSION_3)
+ if (FormatNb() == BinTools_FormatVersion_VERSION_2
+ || FormatNb() == BinTools_FormatVersion_VERSION_3)
{
- BinTools::GetReal(IS, PfX);
- BinTools::GetReal(IS, PfY);
- BinTools::GetReal(IS, PlX);
- BinTools::GetReal(IS, PlY);
- aPf = gp_Pnt2d(PfX,PfY);
- aPl = gp_Pnt2d(PlX,PlY);
+ BinTools::GetReal(IS, PfX);
+ BinTools::GetReal(IS, PfY);
+ BinTools::GetReal(IS, PlX);
+ BinTools::GetReal(IS, PlY);
+ aPf = gp_Pnt2d(PfX, PfY);
+ aPl = gp_Pnt2d(PlX, PlY);
}
- if (myCurves2d.Curve2d(pc).IsNull() ||
- (closed && myCurves2d.Curve2d(pc2).IsNull()) ||
- mySurfaces.Surface(s).IsNull())
- break;
-
+ if (myCurves2d.Curve2d(pc).IsNull() ||
+ (closed && myCurves2d.Curve2d(pc2).IsNull()) ||
+ mySurfaces.Surface(s).IsNull())
+ break;
+
if (closed) {
- if (myFormatNb == BinTools_FormatVersion_VERSION_2
- || myFormatNb == BinTools_FormatVersion_VERSION_3)
+ if (FormatNb() == BinTools_FormatVersion_VERSION_2
+ || FormatNb() == BinTools_FormatVersion_VERSION_3)
{
- myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
- myCurves2d.Curve2d(pc2),
- mySurfaces.Surface(s),
- Locations().Location(l),tol,
- aPf, aPl);
+ myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+ myCurves2d.Curve2d(pc2),
+ mySurfaces.Surface(s),
+ Locations().Location(l), tol,
+ aPf, aPl);
}
else
{
- myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
- myCurves2d.Curve2d(pc2),
- mySurfaces.Surface(s),
- Locations().Location(l),tol);
+ myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+ myCurves2d.Curve2d(pc2),
+ mySurfaces.Surface(s),
+ Locations().Location(l), tol);
}
myBuilder.Continuity(E,
- mySurfaces.Surface(s),
- mySurfaces.Surface(s),
- Locations().Location(l),
- Locations().Location(l),
- reg);
+ mySurfaces.Surface(s),
+ mySurfaces.Surface(s),
+ Locations().Location(l),
+ Locations().Location(l),
+ reg);
}
else
{
- if (myFormatNb == BinTools_FormatVersion_VERSION_2
- || myFormatNb == BinTools_FormatVersion_VERSION_3)
+ if (FormatNb() == BinTools_FormatVersion_VERSION_2
+ || FormatNb() == BinTools_FormatVersion_VERSION_3)
{
- myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
- mySurfaces.Surface(s),
- Locations().Location(l),tol,
- aPf, aPl);
+ myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+ mySurfaces.Surface(s),
+ Locations().Location(l), tol,
+ aPf, aPl);
}
else
{
- myBuilder.UpdateEdge(E,myCurves2d.Curve2d(pc),
- mySurfaces.Surface(s),
- Locations().Location(l),tol);
+ myBuilder.UpdateEdge(E, myCurves2d.Curve2d(pc),
+ mySurfaces.Surface(s),
+ Locations().Location(l), tol);
}
}
myBuilder.Range(E,
- mySurfaces.Surface(s),
- Locations().Location(l),
- first,last);
+ mySurfaces.Surface(s),
+ Locations().Location(l),
+ first, last);
break;
-
- case 4 : // -4- Regularity
- reg = (GeomAbs_Shape)IS.get();
- BinTools::GetInteger(IS, s);
- BinTools::GetInteger(IS, l);
- BinTools::GetInteger(IS, s2);
- BinTools::GetInteger(IS, l2);
- if (mySurfaces.Surface(s).IsNull() ||
- mySurfaces.Surface(s2).IsNull())
- break;
+
+ case 4: // -4- Regularity
+ reg = (GeomAbs_Shape)IS.get();
+ BinTools::GetInteger(IS, s);
+ BinTools::GetInteger(IS, l);
+ BinTools::GetInteger(IS, s2);
+ BinTools::GetInteger(IS, l2);
+ if (mySurfaces.Surface(s).IsNull() ||
+ mySurfaces.Surface(s2).IsNull())
+ break;
myBuilder.Continuity(E,
- mySurfaces.Surface(s),
- mySurfaces.Surface(s2),
- Locations().Location(l),
- Locations().Location(l2),
- reg);
+ mySurfaces.Surface(s),
+ mySurfaces.Surface(s2),
+ Locations().Location(l),
+ Locations().Location(l2),
+ reg);
break;
-
- case 5 : // -5- Polygon3D
- BinTools::GetInteger(IS, c);
- BinTools::GetInteger(IS, l);
-//??? Bug? myBuilder.UpdateEdge(E,myPolygons3D(c));
- myBuilder.UpdateEdge(E, myPolygons3D(c), Locations().Location(l));
+
+ case 5: // -5- Polygon3D
+ BinTools::GetInteger(IS, c);
+ BinTools::GetInteger(IS, l);
+ //??? Bug? myBuilder.UpdateEdge(E,myPolygons3D(c));
+ myBuilder.UpdateEdge(E, myPolygons3D(c), Locations().Location(l));
break;
- case 6 : // -6- Polygon on triangulation
- case 7 : // -7- Polygon on closed triangulation
+ case 6: // -6- Polygon on triangulation
+ case 7: // -7- Polygon on closed triangulation
closed = (val == 7);
- BinTools::GetInteger(IS, pt);
- if (closed)
- BinTools::GetInteger(IS, pt2);
+ BinTools::GetInteger(IS, pt);
+ if (closed)
+ BinTools::GetInteger(IS, pt2);
- BinTools::GetInteger(IS, t);
- BinTools::GetInteger(IS, l);
+ BinTools::GetInteger(IS, t);
+ BinTools::GetInteger(IS, l);
if (closed)
{
myBuilder.UpdateEdge (E, myNodes(pt), myNodes(pt2), myTriangulations.FindKey(t), Locations().Location(l));
}
// range
break;
- default:
- {
- Standard_SStream aMsg;
- aMsg <<"Unexpected Curve Representation ="<< val << std::endl;
- throw Standard_Failure(aMsg.str().c_str());
- }
-
+ default:
+ {
+ Standard_SStream aMsg;
+ aMsg << "Unexpected Curve Representation =" << val << std::endl;
+ throw Standard_Failure(aMsg.str().c_str());
+ }
+
}
} while (val > 0);
}
break;
- //---------
- // wire
- //---------
+ //---------
+ // wire
+ //---------
- case TopAbs_WIRE :
- myBuilder.MakeWire(TopoDS::Wire(S));
- break;
+ case TopAbs_WIRE:
+ myBuilder.MakeWire(TopoDS::Wire(S));
+ break;
- //---------
- // face
- //---------
+ //---------
+ // face
+ //---------
- case TopAbs_FACE :
+ case TopAbs_FACE:
{
- // create a face :
- TopoDS_Face& F = TopoDS::Face(S);
- myBuilder.MakeFace(F);
- BinTools::GetBool(IS, bval); //NaturalRestriction flag
- BinTools::GetReal(IS, tol);
- BinTools::GetInteger(IS, s); //surface indx
- BinTools::GetInteger(IS, l); //location indx
- myBuilder.UpdateFace (F,
- s > 0 ? mySurfaces.Surface(s) : Handle(Geom_Surface)(),
- Locations().Location(l),
- tol);
- myBuilder.NaturalRestriction (F, bval);
-
- Standard_Byte aByte = (Standard_Byte)IS.get();
- // cas triangulation
- if(aByte == 2) {
- BinTools::GetInteger(IS, s);
+ // create a face :
+ TopoDS_Face& F = TopoDS::Face(S);
+ myBuilder.MakeFace(F);
+ BinTools::GetBool(IS, bval); //NaturalRestriction flag
+ BinTools::GetReal(IS, tol);
+ BinTools::GetInteger(IS, s); //surface indx
+ BinTools::GetInteger(IS, l); //location indx
+ myBuilder.UpdateFace(F,
+ s > 0 ? mySurfaces.Surface(s) : Handle(Geom_Surface)(),
+ Locations().Location(l),
+ tol);
+ myBuilder.NaturalRestriction(F, bval);
+
+ Standard_Byte aByte = (Standard_Byte)IS.get();
+ // cas triangulation
+ if (aByte == 2) {
+ BinTools::GetInteger(IS, s);
myBuilder.UpdateFace(TopoDS::Face(S), myTriangulations.FindKey(s));
- }
+ }
}
break;
- //---------
- // shell
- //---------
+ //---------
+ // shell
+ //---------
- case TopAbs_SHELL :
- myBuilder.MakeShell(TopoDS::Shell(S));
- break;
+ case TopAbs_SHELL:
+ myBuilder.MakeShell(TopoDS::Shell(S));
+ break;
- //---------
- // solid
- //---------
+ //---------
+ // solid
+ //---------
- case TopAbs_SOLID :
- myBuilder.MakeSolid(TopoDS::Solid(S));
- break;
+ case TopAbs_SOLID:
+ myBuilder.MakeSolid(TopoDS::Solid(S));
+ break;
- //---------
- // compsolid
- //---------
+ //---------
+ // compsolid
+ //---------
- case TopAbs_COMPSOLID :
- myBuilder.MakeCompSolid(TopoDS::CompSolid(S));
- break;
+ case TopAbs_COMPSOLID:
+ myBuilder.MakeCompSolid(TopoDS::CompSolid(S));
+ break;
- //---------
- // compound
- //---------
+ //---------
+ // compound
+ //---------
- case TopAbs_COMPOUND :
- myBuilder.MakeCompound(TopoDS::Compound(S));
- break;
+ case TopAbs_COMPOUND:
+ myBuilder.MakeCompound(TopoDS::Compound(S));
+ break;
- default:
+ default:
{
Standard_SStream aMsg;
- aMsg << "Unexpected topology type = "<< T <<std::endl;
+ aMsg << "Unexpected topology type = " << T << std::endl;
throw Standard_Failure(aMsg.str().c_str());
break;
}
- }
+ }
}
- catch(Standard_Failure const& anException) {
+ catch (Standard_Failure const& anException) {
Standard_SStream aMsg;
aMsg << "EXCEPTION in BinTools_ShapeSet::ReadGeometry(S,OS)" << std::endl;
aMsg << anException << std::endl;
}
}
-
-
//=======================================================================
//function : AddShapes
//purpose :
//=======================================================================
-void BinTools_ShapeSet::AddShapes(TopoDS_Shape& S1,
- const TopoDS_Shape& S2)
+void BinTools_ShapeSet::AddShapes(TopoDS_Shape& S1,
+ const TopoDS_Shape& S2)
{
myBuilder.Add(S1,S2);
}
-
//=======================================================================
//function : WritePolygonOnTriangulation
//purpose :
BinTools::PutInteger(OS, aNbNodes);
BinTools::PutInteger(OS, aNbTriangles);
BinTools::PutBool(OS, aTriangulation->HasUVNodes() ? 1 : 0);
- if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+ if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
{
BinTools::PutBool(OS, (aTriangulation->HasNormals() && NeedToWriteNormals) ? 1 : 0);
}
}
// write the normals
- if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+ if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
{
if (aTriangulation->HasNormals() && NeedToWriteNormals)
{
BinTools::GetInteger(IS, aNbNodes);
BinTools::GetInteger(IS, aNbTriangles);
BinTools::GetBool(IS, hasUV);
- if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+ if (FormatNb() >= BinTools_FormatVersion_VERSION_4)
{
BinTools::GetBool(IS, hasNormals);
}
BinTools::GetInteger(IS, aTriNodes[2]);
aTriangulation->SetTriangle (aTriIter, Poly_Triangle (aTriNodes[0], aTriNodes[1], aTriNodes[2]));
}
+ //IS.ignore(sizeof(Standard_Real) * (hasUV ? 5 : 3) * aNbNodes + sizeof(Standard_Integer) * 3 * aNbTriangles);
if (hasNormals)
{
#ifndef _BinTools_ShapeSet_HeaderFile
#define _BinTools_ShapeSet_HeaderFile
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
+#include <BinTools_ShapeSetBase.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
-#include <BinTools_FormatVersion.hxx>
#include <BinTools_LocationSet.hxx>
-#include <Standard_Integer.hxx>
#include <BRep_Builder.hxx>
#include <BinTools_SurfaceSet.hxx>
#include <BinTools_CurveSet.hxx>
#include <BinTools_Curve2dSet.hxx>
#include <TColStd_IndexedMapOfTransient.hxx>
-#include <Standard_Boolean.hxx>
#include <Standard_OStream.hxx>
#include <Standard_IStream.hxx>
-#include <TopAbs_ShapeEnum.hxx>
-
-class TopoDS_Shape;
-class BinTools_LocationSet;
//! Writes topology in OStream in binary format
-class BinTools_ShapeSet
+class BinTools_ShapeSet : public BinTools_ShapeSetBase
{
public:
Standard_EXPORT virtual ~BinTools_ShapeSet();
- //! Return true if shape should be stored with triangles.
- Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
- //! Return true if shape should be stored triangulation with normals.
- Standard_Boolean IsWithNormals() const { return myWithNormals; }
-
-
- //! Define if shape will be stored with triangles.
- //! Ignored (always written) if face defines only triangulation (no surface).
- void SetWithTriangles (const Standard_Boolean theWithTriangles) { myWithTriangles = theWithTriangles; }
- //! Define if shape will be stored triangulation with normals.
- //! Ignored (always written) if face defines only triangulation (no surface).
- void SetWithNormals(const Standard_Boolean theWithNormals) { myWithNormals = theWithNormals; }
-
- //! Sets the BinTools_FormatVersion.
- Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
-
- //! Returns the BinTools_FormatVersion.
- Standard_EXPORT Standard_Integer FormatNb() const;
-
//! Clears the content of the set.
Standard_EXPORT virtual void Clear();
Standard_EXPORT Standard_Integer Add (const TopoDS_Shape& S);
//! Returns the sub-shape of index <I>.
- Standard_EXPORT const TopoDS_Shape& Shape (const Standard_Integer I) const;
+ Standard_EXPORT const TopoDS_Shape& Shape (const Standard_Integer I);
//! Returns the index of <S>.
Standard_EXPORT Standard_Integer Index (const TopoDS_Shape& S) const;
//! Write the flags, the subshapes.
Standard_EXPORT virtual void Write
(Standard_OStream& OS,
- const Message_ProgressRange& theRange = Message_ProgressRange()) const;
+ const Message_ProgressRange& theRange = Message_ProgressRange());
//! Reads the content of me from the binary stream <IS>. me
//! is first cleared.
//! Reads the flag, the subshapes.
Standard_EXPORT virtual void Read
(Standard_IStream& IS,
- const Message_ProgressRange& theRange = Message_ProgressRange());
+ const Message_ProgressRange& theRange = Message_ProgressRange());
//! Writes on <OS> the shape <S>. Writes the
//! orientation, the index of the TShape and the index
//! of the Location.
- Standard_EXPORT virtual void Write (const TopoDS_Shape& S, Standard_OStream& OS) const;
+ Standard_EXPORT virtual void Write (const TopoDS_Shape& S, Standard_OStream& OS);
//! Writes the geometry of me on the stream <OS> in a
//! binary format that can be read back by Read.
Standard_EXPORT virtual void WriteGeometry
(Standard_OStream& OS,
- const Message_ProgressRange& theRange = Message_ProgressRange()) const;
+ const Message_ProgressRange& theRange = Message_ProgressRange()) const;
//! Reads the geometry of me from the stream <IS>.
Standard_EXPORT virtual void ReadGeometry
(Standard_IStream& IS,
- const Message_ProgressRange& theRange = Message_ProgressRange());
+ const Message_ProgressRange& theRange = Message_ProgressRange());
- //! Reads from <IS> a shape and returns it in S.
+ //! Reads from <IS> a shape flags and sub-shapes and modifies S.
+ Standard_EXPORT virtual void ReadFlagsAndSubs
+ (TopoDS_Shape& S, const TopAbs_ShapeEnum T,
+ Standard_IStream& IS, const Standard_Integer NbShapes);
+
+ //! Reads from <IS> a shape and returns it in S.
//! <NbShapes> is the number of tshapes in the set.
- Standard_EXPORT virtual void Read
- (TopoDS_Shape& S,
- Standard_IStream& IS, const Standard_Integer NbShapes) const;
-
- //! Writes the geometry of <S> on the stream <OS> in a
+ Standard_EXPORT virtual void ReadSubs
+ (TopoDS_Shape& S, Standard_IStream& IS, const Standard_Integer NbShapes);
+
+ //! An empty virtual method for redefinition in shape-reader.
+ Standard_EXPORT virtual void Read (Standard_IStream& /*theStream*/, TopoDS_Shape& /*theShape*/) {};
+
+ //! Writes the shape <S> on the stream <OS> in a
//! binary format that can be read back by Read.
- Standard_EXPORT virtual void WriteGeometry (const TopoDS_Shape& S, Standard_OStream& OS) const;
-
- //! Reads the geometry of a shape of type <T> from the
- //! stream <IS> and returns it in <S>.
- Standard_EXPORT virtual void ReadGeometry (const TopAbs_ShapeEnum T, Standard_IStream& IS, TopoDS_Shape& S);
+ Standard_EXPORT virtual void WriteShape (const TopoDS_Shape& S, Standard_OStream& OS) const;
- //! Stores the goemetry of <S>.
- Standard_EXPORT virtual void AddGeometry (const TopoDS_Shape& S);
+ //! Reads a shape of type <T> from the stream <IS> and returns it in <S>.
+ Standard_EXPORT virtual void ReadShape (const TopAbs_ShapeEnum T, Standard_IStream& IS, TopoDS_Shape& S);
+
+ //! Stores the shape <S>.
+ Standard_EXPORT virtual void AddShape (const TopoDS_Shape& S);
- //! Inserts the shape <S2> in the shape <S1>.
+ //! Inserts the shape <S2> in the shape <S1>.
Standard_EXPORT virtual void AddShapes (TopoDS_Shape& S1, const TopoDS_Shape& S2);
//! Reads the 3d polygons of me
(Standard_OStream& OS,
const Message_ProgressRange& theRange = Message_ProgressRange()) const;
-public:
-
- static const Standard_CString THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1];
-
private:
- TopTools_IndexedMapOfShape myShapes;
+ TopTools_IndexedMapOfShape myShapes; ///< index and its shape (started from 1)
BinTools_LocationSet myLocations;
- Standard_Integer myFormatNb;
BRep_Builder myBuilder;
BinTools_SurfaceSet mySurfaces;
BinTools_CurveSet myCurves;
Standard_Boolean> myTriangulations; //!< Contains a boolean flag with information
//! to save normals for triangulation
NCollection_IndexedMap<Handle(Poly_PolygonOnTriangulation), TColStd_MapTransientHasher> myNodes;
- Standard_Boolean myWithTriangles;
- Standard_Boolean myWithNormals;
-
};
#endif // _BinTools_ShapeSet_HeaderFile
--- /dev/null
+// 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 <BinTools.hxx>
+#include <BinTools_ShapeSetBase.hxx>
+#include <TopoDS_Shape.hxx>
+
+const Standard_CString BinTools_ShapeSetBase::THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1] =
+{
+ "",
+ "Open CASCADE Topology V1 (c)",
+ "Open CASCADE Topology V2 (c)",
+ "Open CASCADE Topology V3 (c)",
+ "Open CASCADE Topology V4, (c) Open Cascade"
+};
+
+//=======================================================================
+//function : operator << (gp_Pnt)
+//purpose :
+//=======================================================================
+Standard_OStream& operator << (Standard_OStream& OS, const gp_Pnt P)
+{
+ BinTools::PutReal (OS, P.X());
+ BinTools::PutReal (OS, P.Y());
+ BinTools::PutReal (OS, P.Z());
+ return OS;
+}
+
+//=======================================================================
+//function : BinTools_ShapeSetBase
+//purpose :
+//=======================================================================
+
+BinTools_ShapeSetBase::BinTools_ShapeSetBase()
+ : myFormatNb (BinTools_FormatVersion_CURRENT),
+ myWithTriangles (Standard_False),
+ myWithNormals (Standard_False)
+{}
+
+//=======================================================================
+//function : ~BinTools_ShapeSetBase
+//purpose :
+//=======================================================================
+
+BinTools_ShapeSetBase::~BinTools_ShapeSetBase()
+{}
+
+//=======================================================================
+//function : SetFormatNb
+//purpose :
+//=======================================================================
+void BinTools_ShapeSetBase::SetFormatNb (const Standard_Integer theFormatNb)
+{
+ Standard_ASSERT_RETURN(theFormatNb >= BinTools_FormatVersion_LOWER &&
+ theFormatNb <= BinTools_FormatVersion_UPPER,
+ "Error: unsupported BinTools version.", );
+
+ myFormatNb = theFormatNb;
+}
--- /dev/null
+// 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 _BinTools_ShapeSetBase_HeaderFile
+#define _BinTools_ShapeSetBase_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+#include <Standard_OStream.hxx>
+#include <Standard_IStream.hxx>
+#include <Message_ProgressRange.hxx>
+#include <BinTools_FormatVersion.hxx>
+
+class TopoDS_Shape;
+class gp_Pnt;
+
+//! Writes to the stream a gp_Pnt data
+Standard_OStream& operator << (Standard_OStream& OS, const gp_Pnt P);
+
+//! Computes a hash code for the given value of the uint64_t type, in range [1, theUpperBound]
+inline Standard_Integer HashCode (const uint64_t theValue, const Standard_Integer theUpperBound)
+{
+ return IntegerHashCode(theValue, 0xffffffffffffffff, theUpperBound);
+}
+
+//! A base class for all readers/writers of TopoDS_Shape into/from stream.
+class BinTools_ShapeSetBase
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+
+ //! A default constructor.
+ Standard_EXPORT BinTools_ShapeSetBase();
+
+ Standard_EXPORT virtual ~BinTools_ShapeSetBase();
+
+ //! Return true if shape should be stored with triangles.
+ Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
+ //! Return true if shape should be stored triangulation with normals.
+ Standard_Boolean IsWithNormals() const { return myWithNormals; }
+
+ //! Define if shape will be stored with triangles.
+ //! Ignored (always written) if face defines only triangulation (no surface).
+ void SetWithTriangles (const Standard_Boolean theWithTriangles) { myWithTriangles = theWithTriangles; }
+ //! Define if shape will be stored triangulation with normals.
+ //! Ignored (always written) if face defines only triangulation (no surface).
+ void SetWithNormals(const Standard_Boolean theWithNormals) { myWithNormals = theWithNormals; }
+
+ //! Sets the BinTools_FormatVersion.
+ Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
+
+ //! Returns the BinTools_FormatVersion.
+ Standard_EXPORT Standard_Integer FormatNb() const { return myFormatNb; }
+
+ //! Clears the content of the set.
+ Standard_EXPORT virtual void Clear() {}
+
+ //! Writes the content of me on the stream <OS> in binary
+ //! format that can be read back by Read.
+ //!
+ //! Writes the locations.
+ //!
+ //! Writes the geometry calling WriteGeometry.
+ //!
+ //! Dumps the shapes from last to first.
+ //! For each shape :
+ //! Write the type.
+ //! calls WriteGeometry(S).
+ //! Write the flags, the subshapes.
+ Standard_EXPORT virtual void Write
+ (Standard_OStream& /*OS*/, const Message_ProgressRange& /*theRange*/ = Message_ProgressRange()) {}
+
+ //! Reads the content of me from the binary stream <IS>. me
+ //! is first cleared.
+ //!
+ //! Reads the locations.
+ //!
+ //! Reads the geometry calling ReadGeometry.
+ //!
+ //! Reads the shapes.
+ //! For each shape
+ //! Reads the type.
+ //! calls ReadGeometry(T,S).
+ //! Reads the flag, the subshapes.
+ Standard_EXPORT virtual void Read
+ (Standard_IStream& /*IS*/, const Message_ProgressRange& /*theRange*/ = Message_ProgressRange()) {}
+
+ //! Writes on <OS> the shape <S>. Writes the
+ //! orientation, the index of the TShape and the index
+ //! of the Location.
+ Standard_EXPORT virtual void Write (const TopoDS_Shape& /*theShape*/, Standard_OStream& /*theStream*/) {}
+
+ //! An empty virtual method for redefinition in shape-reader.
+ Standard_EXPORT virtual void Read (Standard_IStream& /*theStream*/, TopoDS_Shape& /*theShape*/) {}
+
+ static const Standard_CString THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1];
+private:
+
+ Standard_Integer myFormatNb;
+ Standard_Boolean myWithTriangles;
+ Standard_Boolean myWithNormals;
+};
+
+#endif // _BinTools_ShapeSet_HeaderFile
--- /dev/null
+// 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 <BinTools_ShapeWriter.hxx>
+#include <BinTools_LocationSet.hxx>
+
+#include <TopoDS.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRep_GCurve.hxx>
+#include <BRep_Polygon3D.hxx>
+#include <BRep_PolygonOnTriangulation.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRep_Tool.hxx>
+#include <BRep_TVertex.hxx>
+#include <BRep_PointRepresentation.hxx>
+#include <BRep_TFace.hxx>
+#include <BinTools_CurveSet.hxx>
+#include <BinTools_Curve2dSet.hxx>
+#include <BinTools_SurfaceSet.hxx>
+
+//=======================================================================
+//function : BinTools_ShapeWriter
+//purpose :
+//=======================================================================
+BinTools_ShapeWriter::BinTools_ShapeWriter()
+ : BinTools_ShapeSetBase()
+{}
+
+//=======================================================================
+//function : ~BinTools_ShapeWriter
+//purpose :
+//=======================================================================
+BinTools_ShapeWriter::~BinTools_ShapeWriter()
+{}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::Clear()
+{
+ BinTools_ShapeSetBase::Clear();
+ myShapePos.Clear();
+ myLocationPos.Clear();
+ myCurvePos.Clear();
+ myCurve2dPos.Clear();
+ mySurfacePos.Clear();
+ myPolygon3dPos.Clear();
+ myPolygonPos.Clear();
+ myTriangulationPos.Clear();
+}
+
+//=======================================================================
+//function : Write
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::Write (const TopoDS_Shape& theShape, Standard_OStream& theStream)
+{
+ WriteShape (theStream, theShape);
+}
+
+//=======================================================================
+//function : WriteShape
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::WriteShape (Standard_OStream& theStream, const TopoDS_Shape& theShape)
+{
+ if (theShape.IsNull())
+ {
+ BinTools_Position (theStream).WriteObject (BinTools_ObjectType_EmptyShape);
+ return;
+ }
+ TopoDS_Shape aShape = theShape.Located (TopLoc_Location());
+ const BinTools_Position* anExisting = myShapePos.Seek (aShape);
+ if (anExisting) // shape is already there, so, write reference to it
+ {
+ anExisting->WriteReference();
+ WriteLocation (theStream, theShape.Location());
+ theStream << Standard_Byte (theShape.Orientation ());
+ return;
+ }
+ BinTools_Position aNewPos (theStream);
+ myShapePos.Bind (aShape, aNewPos);
+ aNewPos.WriteShape (aShape.ShapeType(), aShape.Orientation());
+ WriteLocation (theStream, theShape.Location());
+
+ try {
+ OCC_CATCH_SIGNALS
+ switch (aShape.ShapeType())
+ {
+ case TopAbs_VERTEX:
+ {
+ TopoDS_Vertex aV = TopoDS::Vertex (aShape);
+ BinTools::PutReal (theStream, BRep_Tool::Tolerance (aV));
+ gp_Pnt aP = BRep_Tool::Pnt (aV);
+ theStream << aP;
+ Handle(BRep_TVertex) aTV = Handle(BRep_TVertex)::DownCast (aShape.TShape());
+ for(BRep_ListIteratorOfListOfPointRepresentation anIter (aTV->Points()); anIter.More(); anIter.Next())
+ {
+ const Handle(BRep_PointRepresentation)& aPR = anIter.Value();
+ if (aPR->IsPointOnCurve())
+ {
+ theStream << (Standard_Byte)1; // 1
+ BinTools::PutReal (theStream, aPR->Parameter());
+ WriteCurve (theStream, aPR->Curve());
+ }
+ else if (aPR->IsPointOnCurveOnSurface())
+ {
+ theStream << (Standard_Byte)2;// 2
+ BinTools::PutReal (theStream, aPR->Parameter());
+ WriteCurve (theStream, aPR->PCurve());
+ WriteSurface (theStream, aPR->Surface());
+ }
+ else if (aPR->IsPointOnSurface())
+ {
+ theStream << (Standard_Byte)3;// 3
+ BinTools::PutReal (theStream, aPR->Parameter2());
+ BinTools::PutReal (theStream, aPR->Parameter());
+ WriteSurface (theStream, aPR->Surface());
+ }
+ WriteLocation (theStream, aPR->Location());
+ }
+ theStream.put ((Standard_Byte)0);
+ }
+ break;
+ case TopAbs_EDGE:
+ {
+ Handle(BRep_TEdge) aTE = Handle(BRep_TEdge)::DownCast (aShape.TShape());
+ BinTools::PutReal (theStream, aTE->Tolerance());
+ BinTools::PutBools (theStream, aTE->SameParameter(), aTE->SameRange(), aTE->Degenerated());
+ Standard_Real aFirst, aLast;
+ for(BRep_ListIteratorOfListOfCurveRepresentation anIter = aTE->Curves(); anIter.More(); anIter.Next())
+ {
+ const Handle(BRep_CurveRepresentation)& aCR = anIter.Value();
+ if (aCR->IsCurve3D())
+ {
+ if (!aCR->Curve3D().IsNull())
+ {
+ Handle(BRep_GCurve) aGC = Handle(BRep_GCurve)::DownCast (aCR);
+ aGC->Range (aFirst, aLast);
+ theStream << (Standard_Byte)1;//CURVE_3D;
+ WriteCurve (theStream, aCR->Curve3D());
+ WriteLocation (theStream, aCR->Location());
+ BinTools::PutReal (theStream, aFirst);
+ BinTools::PutReal (theStream, aLast);
+ }
+ }
+ else if (aCR->IsCurveOnSurface()) {
+ Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast (aCR);
+ GC->Range (aFirst, aLast);
+ if (!aCR->IsCurveOnClosedSurface())
+ // -2- Curve on surf
+ theStream << (Standard_Byte)2;
+ else
+ // -3- Curve on closed surf
+ theStream << (Standard_Byte)3;
+ WriteCurve (theStream, aCR->PCurve());
+
+ if (aCR->IsCurveOnClosedSurface()) {//+ int|char
+ WriteCurve (theStream, aCR->PCurve2());
+ theStream << (Standard_Byte)aCR->Continuity();
+ }
+ WriteSurface (theStream, aCR->Surface());
+ WriteLocation (theStream, aCR->Location());
+ BinTools::PutReal (theStream, aFirst);
+ BinTools::PutReal (theStream, aLast);
+ }
+ else if (aCR->IsRegularity())
+ {
+ // -4- Regularity
+ theStream << (Standard_Byte)4;
+ theStream << (Standard_Byte)aCR->Continuity();
+ WriteSurface (theStream, aCR->Surface());
+ WriteLocation (theStream, aCR->Location());
+ WriteSurface (theStream, aCR->Surface2());
+ WriteLocation (theStream, aCR->Location2());
+ }
+ else if (IsWithTriangles())
+ {
+ if (aCR->IsPolygon3D())
+ {
+ Handle(BRep_Polygon3D) aGC = Handle(BRep_Polygon3D)::DownCast (aCR);
+ if (!aGC->Polygon3D().IsNull())
+ {
+ // -5- Polygon3D
+ theStream << (Standard_Byte)5;
+ WritePolygon (theStream, aCR->Polygon3D());
+ WriteLocation (theStream, aCR->Location());
+ }
+ }
+ else if (aCR->IsPolygonOnTriangulation())
+ {
+ Handle(BRep_PolygonOnTriangulation) aPT = Handle(BRep_PolygonOnTriangulation)::DownCast (aCR);
+ if (!aCR->IsPolygonOnClosedTriangulation())
+ // -6- Polygon on triangulation
+ theStream << (Standard_Byte)6;
+ else
+ // -7- Polygon on closed triangulation
+ theStream << (Standard_Byte)7;
+ WritePolygon (theStream, aPT->PolygonOnTriangulation());
+
+ if (aCR->IsPolygonOnClosedTriangulation())
+ WritePolygon (theStream, aPT->PolygonOnTriangulation2());
+ // edge triangulation does not need normals
+ WriteTriangulation (theStream, aPT->Triangulation(), Standard_False);
+ WriteLocation (theStream, aCR->Location());
+ }
+ }
+ }
+ theStream << (Standard_Byte)0;
+ }
+ break;
+ case TopAbs_FACE:
+ {
+
+ Handle(BRep_TFace) aTF = Handle(BRep_TFace)::DownCast (aShape.TShape());
+ const TopoDS_Face& aF = TopoDS::Face (aShape);
+
+ // Write the surface geometry
+ Standard_Boolean aNatRes = BRep_Tool::NaturalRestriction (aF);
+ BinTools::PutBool (theStream, aNatRes);
+ BinTools::PutReal (theStream, aTF->Tolerance());
+ WriteSurface (theStream, aTF->Surface());
+ WriteLocation (theStream, aTF->Location());
+
+ if (IsWithTriangles() || aTF->Surface().IsNull())
+ {
+ if (!(aTF->Triangulation()).IsNull())
+ {
+ theStream << (Standard_Byte)2;
+ WriteTriangulation (theStream, aTF->Triangulation(), IsWithNormals() || aTF->Surface().IsNull());
+ }
+ else
+ theStream << (Standard_Byte)1;
+ }
+ else
+ theStream << (Standard_Byte)0;//without triangulation
+ }
+ break;
+ default:
+ {
+ Standard_SStream aMsg;
+ aMsg << "Unexpected topology type = " << aShape.ShapeType() << std::endl;
+ }
+ }
+ }
+ catch (Standard_Failure const& anException)
+ {
+ Standard_SStream aMsg;
+ aMsg << "EXCEPTION in BinTools_ShapeWriter::WriteShape" << std::endl;
+ aMsg << anException << std::endl;
+ throw Standard_Failure(aMsg.str().c_str());
+ }
+ BinTools::PutBools (theStream, aShape.Free(), aShape.Modified(), aShape.Checked(),
+ aShape.Orientable(), aShape.Closed(), aShape.Infinite(), aShape.Convex());
+ // process sub-shapes
+ for (TopoDS_Iterator aSub (aShape, Standard_False, Standard_False); aSub.More(); aSub.Next())
+ WriteShape (theStream, aSub.Value());
+ aNewPos.WriteObject (BinTools_ObjectType_EndShape);
+}
+
+//=======================================================================
+//function : WriteLocation
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::WriteLocation (Standard_OStream& theStream, const TopLoc_Location& theLocation)
+{
+ if (theLocation.IsIdentity())
+ {
+ BinTools_Position (theStream).WriteObject (BinTools_ObjectType_EmptyLocation);
+ return;
+ }
+ const BinTools_Position* aLoc = myLocationPos.Seek (theLocation);
+ if (aLoc)
+ {
+ aLoc->WriteReference();
+ return;
+ }
+ BinTools_Position aNewLoc (theStream);
+ try
+ {
+ OCC_CATCH_SIGNALS
+ TopLoc_Location aL2 = theLocation.NextLocation();
+ Standard_Boolean isSimple = aL2.IsIdentity();
+ Standard_Integer aPower = theLocation.FirstPower();
+ TopLoc_Location aL1 = theLocation.FirstDatum();
+ Standard_Boolean elementary = (isSimple && aPower == 1);
+ if (elementary)
+ {
+ aNewLoc.WriteObject (BinTools_ObjectType_SimpleLocation);
+ theStream << theLocation.Transformation();
+ }
+ else
+ {
+ aNewLoc.WriteObject (BinTools_ObjectType_Location);
+ WriteLocation (theStream, aL1);
+ BinTools::PutInteger (theStream, aPower);
+ while (!aL2.IsIdentity()) {
+ aL1 = aL2.FirstDatum();
+ aPower = aL2.FirstPower();
+ aL2 = aL2.NextLocation();
+ WriteLocation (theStream, aL1);
+ BinTools::PutInteger (theStream, aPower);
+ }
+ aNewLoc.WriteObject (BinTools_ObjectType_LocationEnd);
+ }
+ myLocationPos.Bind (theLocation, aNewLoc);
+ }
+ catch (Standard_Failure const& anException) {
+ Standard_SStream aMsg;
+ aMsg << "EXCEPTION in BinTools_ShapeWriter::WriteLocation" << std::endl;
+ aMsg << anException << std::endl;
+ throw Standard_Failure (aMsg.str().c_str());
+ }
+}
+
+//=======================================================================
+//function : WriteCurve
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::WriteCurve (Standard_OStream& theStream, const Handle(Geom_Curve)& theCurve)
+{
+ if (theCurve.IsNull())
+ {
+ BinTools_Position (theStream).WriteObject (BinTools_ObjectType_EmptyCurve);
+ return;
+ }
+ const BinTools_Position* aCurve = myCurvePos.Seek (theCurve);
+ if (aCurve)
+ {
+ aCurve->WriteReference();
+ return;
+ }
+ BinTools_Position aNewCurve (theStream);
+ aNewCurve.WriteObject (BinTools_ObjectType_Curve);
+ BinTools_CurveSet::WriteCurve (theCurve, theStream);
+ myCurvePos.Bind (theCurve, aNewCurve);
+}
+
+//=======================================================================
+//function : WriteCurve
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::WriteCurve (Standard_OStream& theStream, const Handle(Geom2d_Curve)& theCurve)
+{
+ if (theCurve.IsNull())
+ {
+ BinTools_Position (theStream).WriteObject (BinTools_ObjectType_EmptyCurve2d);
+ return;
+ }
+ const BinTools_Position* aCurve = myCurve2dPos.Seek (theCurve);
+ if (aCurve)
+ {
+ aCurve->WriteReference();
+ return;
+ }
+ BinTools_Position aNewCurve (theStream);
+ aNewCurve.WriteObject (BinTools_ObjectType_Curve2d);
+ BinTools_Curve2dSet::WriteCurve2d (theCurve, theStream);
+ myCurve2dPos.Bind (theCurve, aNewCurve);
+}
+
+//=======================================================================
+//function : WriteSurface
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::WriteSurface (Standard_OStream& theStream, const Handle(Geom_Surface)& theSurface)
+{
+ if (theSurface.IsNull())
+ {
+ BinTools_Position (theStream).WriteObject (BinTools_ObjectType_EmptySurface);
+ return;
+ }
+ const BinTools_Position* aSurface = mySurfacePos.Seek (theSurface);
+ if (aSurface)
+ {
+ aSurface->WriteReference();
+ return;
+ }
+ BinTools_Position aNewSurface (theStream);
+ aNewSurface.WriteObject (BinTools_ObjectType_Surface);
+ BinTools_SurfaceSet::WriteSurface (theSurface, theStream);
+ mySurfacePos.Bind (theSurface, aNewSurface);
+}
+
+//=======================================================================
+//function : WritePolygon
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::WritePolygon (Standard_OStream& theStream, const Handle(Poly_Polygon3D)& thePolygon)
+{
+ if (thePolygon.IsNull())
+ {
+ BinTools_Position (theStream).WriteObject (BinTools_ObjectType_EmptyPolygon3d);
+ return;
+ }
+ const BinTools_Position* aPolygon = myPolygon3dPos.Seek (thePolygon);
+ if (aPolygon)
+ {
+ aPolygon->WriteReference();
+ return;
+ }
+ BinTools_Position aNewPolygon (theStream);
+ aNewPolygon.WriteObject (BinTools_ObjectType_Polygon3d);
+
+ const Standard_Integer aNbNodes = thePolygon->NbNodes();
+ BinTools::PutInteger (theStream, aNbNodes);
+ BinTools::PutBool (theStream, thePolygon->HasParameters());
+ BinTools::PutReal (theStream, thePolygon->Deflection());
+ const TColgp_Array1OfPnt& aNodes = thePolygon->Nodes();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream << aNodes.Value (aNodeIter);
+ if (thePolygon->HasParameters())
+ {
+ const TColStd_Array1OfReal& aParam = thePolygon->Parameters();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ BinTools::PutReal (theStream, aParam.Value (aNodeIter));
+ }
+
+ myPolygon3dPos.Bind (thePolygon, aNewPolygon);
+}
+
+//=======================================================================
+//function : WritePolygon
+//purpose :
+//=======================================================================
+void BinTools_ShapeWriter::WritePolygon (Standard_OStream& theStream,
+ const Handle(Poly_PolygonOnTriangulation)& thePolygon)
+{
+ if (thePolygon.IsNull())
+ {
+ BinTools_Position (theStream).WriteObject (BinTools_ObjectType_EmptyPolygonOnTriangulation);
+ return;
+ }
+ const BinTools_Position* aPolygon = myPolygonPos.Seek (thePolygon);
+ if (aPolygon)
+ {
+ aPolygon->WriteReference();
+ return;
+ }
+ BinTools_Position aNewPolygon (theStream);
+ aNewPolygon.WriteObject (BinTools_ObjectType_PolygonOnTriangulation);
+
+ const TColStd_Array1OfInteger& aNodes = thePolygon->Nodes();
+ BinTools::PutInteger (theStream, aNodes.Length());
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNodes.Length(); ++aNodeIter)
+ BinTools::PutInteger (theStream, aNodes.Value(aNodeIter));
+ BinTools::PutReal (theStream, thePolygon->Deflection());
+ if (const Handle(TColStd_HArray1OfReal)& aParam = thePolygon->Parameters())
+ {
+ BinTools::PutBool (theStream, Standard_True);
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aParam->Length(); ++aNodeIter)
+ BinTools::PutReal (theStream, aParam->Value(aNodeIter));
+ }
+ else
+ BinTools::PutBool (theStream, Standard_False);
+
+ myPolygonPos.Bind (thePolygon, aNewPolygon);
+}
+
+void BinTools_ShapeWriter::WriteTriangulation (Standard_OStream& theStream,
+ const Handle(Poly_Triangulation)& theTriangulation,
+ const Standard_Boolean theNeedToWriteNormals)
+{
+ if (theTriangulation.IsNull())
+ {
+ BinTools_Position(theStream).WriteObject (BinTools_ObjectType_EmptyTriangulation);
+ return;
+ }
+ const BinTools_Position* aTriangulation = myTriangulationPos.Seek (theTriangulation);
+ if (aTriangulation)
+ {
+ aTriangulation->WriteReference();
+ return;
+ }
+ BinTools_Position aNewTriangulation (theStream);
+ aNewTriangulation.WriteObject (BinTools_ObjectType_Triangulation);
+
+ const Standard_Integer aNbNodes = theTriangulation->NbNodes();
+ const Standard_Integer aNbTriangles = theTriangulation->NbTriangles();
+ BinTools::PutInteger (theStream, aNbNodes);
+ BinTools::PutInteger (theStream, aNbTriangles);
+ BinTools::PutBool (theStream, theTriangulation->HasUVNodes() ? 1 : 0);
+ BinTools::PutBool (theStream, theNeedToWriteNormals ? 1 : 0);
+ BinTools::PutReal (theStream, theTriangulation->Deflection());
+ // write the 3d nodes
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream << theTriangulation->Node (aNodeIter);
+ if (theTriangulation->HasUVNodes())
+ {
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ {
+ const gp_Pnt2d aUV = theTriangulation->UVNode (aNodeIter);
+ BinTools::PutReal (theStream, aUV.X());
+ BinTools::PutReal (theStream, aUV.Y());
+ }
+ }
+ for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
+ {
+ const Poly_Triangle& aTri = theTriangulation->Triangle (aTriIter);
+ BinTools::PutInteger (theStream, aTri.Value (1));
+ BinTools::PutInteger (theStream, aTri.Value (2));
+ BinTools::PutInteger (theStream, aTri.Value (3));
+ }
+ if (theNeedToWriteNormals)
+ {
+ gp_Vec3f aNormal;
+ for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes; ++aNormalIter)
+ {
+ theTriangulation->Normal (aNormalIter, aNormal);
+ BinTools::PutShortReal (theStream, aNormal.x());
+ BinTools::PutShortReal (theStream, aNormal.y());
+ BinTools::PutShortReal (theStream, aNormal.z());
+ }
+ }
+
+ myTriangulationPos.Bind (theTriangulation, aNewTriangulation);
+}
--- /dev/null
+// 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 _BinTools_ShapeWriter_HeaderFile
+#define _BinTools_ShapeWriter_HeaderFile
+
+#include <BinTools_ShapeSetBase.hxx>
+#include <BinTools_Position.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Map.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+
+class TopLoc_Location;
+class Geom_Curve;
+class Geom2d_Curve;
+class Geom_Surface;
+class Poly_Polygon3D;
+class Poly_PolygonOnTriangulation;
+class Poly_Triangulation;
+
+//! Writes topology in OStream in binary format without grouping of objects by types
+//! and using relative positions in a file as references.
+class BinTools_ShapeWriter : public BinTools_ShapeSetBase
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+ //! Builds an empty ShapeSet.
+ //! Parameter <theWithTriangles> is added for XML Persistence
+ Standard_EXPORT BinTools_ShapeWriter();
+
+ Standard_EXPORT virtual ~BinTools_ShapeWriter();
+
+ //! Clears the content of the set.
+ Standard_EXPORT virtual void Clear() override;
+
+ //! Writes the shape to stream using previously stored shapes and objects to refer them.
+ Standard_EXPORT virtual void Write (const TopoDS_Shape& theShape, Standard_OStream& theStream) override;
+
+ //! Writes location to the stream (all the needed sub-information or reference if it is already used).
+ Standard_EXPORT virtual void WriteLocation (Standard_OStream& theStream, const TopLoc_Location& theLocation);
+
+private:
+ //! Writes shape to the stream (all the needed sub-information or reference if it is already used).
+ virtual void WriteShape (Standard_OStream& theStream, const TopoDS_Shape& theShape);
+ //! Writes curve to the stream (all the needed sub-information or reference if it is already used).
+ void WriteCurve (Standard_OStream& theStream, const Handle(Geom_Curve)& theCurve);
+ //! Writes curve2d to the stream (all the needed sub-information or reference if it is already used).
+ void WriteCurve (Standard_OStream& theStream, const Handle(Geom2d_Curve)& theCurve);
+ //! Writes surface to the stream.
+ void WriteSurface (Standard_OStream& theStream, const Handle(Geom_Surface)& theSurface);
+ //! Writes ploygon3d to the stream.
+ void WritePolygon (Standard_OStream& theStream, const Handle(Poly_Polygon3D)& thePolygon);
+ //! Writes polygon on triangulation to the stream.
+ void WritePolygon (Standard_OStream& theStream, const Handle(Poly_PolygonOnTriangulation)& thePolygon);
+ //! Writes triangulation to the stream.
+ void WriteTriangulation (Standard_OStream& theStream, const Handle(Poly_Triangulation)& theTriangulation,
+ const Standard_Boolean theNeedToWriteNormals);
+
+ /// position of the shape previously stored
+ NCollection_DataMap<TopoDS_Shape, BinTools_Position, TopTools_ShapeMapHasher> myShapePos;
+ NCollection_DataMap<TopLoc_Location, BinTools_Position> myLocationPos;
+ NCollection_DataMap<Handle(Geom_Curve), BinTools_Position> myCurvePos;
+ NCollection_DataMap<Handle(Geom2d_Curve), BinTools_Position> myCurve2dPos;
+ NCollection_DataMap<Handle(Geom_Surface), BinTools_Position> mySurfacePos;
+ NCollection_DataMap<Handle(Poly_Polygon3D), BinTools_Position> myPolygon3dPos;
+ NCollection_DataMap<Handle(Poly_PolygonOnTriangulation), BinTools_Position> myPolygonPos;
+ NCollection_DataMap<Handle(Poly_Triangulation), BinTools_Position> myTriangulationPos;
+};
+
+#endif // _BinTools_ShapeWriter_HeaderFile
BinTools_CurveSet.cxx
BinTools_CurveSet.hxx
BinTools_FormatVersion.hxx
+BinTools_IStream.cxx
+BinTools_IStream.hxx
BinTools_LocationSet.cxx
BinTools_LocationSet.hxx
BinTools_LocationSetPtr.hxx
BinTools_ShapeSet.cxx
BinTools_ShapeSet.hxx
+BinTools_ShapeSetBase.cxx
+BinTools_ShapeSetBase.hxx
BinTools_SurfaceSet.cxx
BinTools_SurfaceSet.hxx
+BinTools_ObjectType.hxx
+BinTools_Position.hxx
+BinTools_Position.cxx
+BinTools_ShapeReader.hxx
+BinTools_ShapeReader.cxx
+BinTools_ShapeWriter.hxx
+BinTools_ShapeWriter.cxx
#include <PCDM_ReadWriter.hxx>
#include <PCDM_RetrievalDriver.hxx>
#include <PCDM_StorageDriver.hxx>
+#include <PCDM_ReaderFilter.hxx>
#include <Plugin.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_GUID.hxx>
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);
}
//=======================================================================
//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;
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);
//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
//=======================================================================
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);
}
//=======================================================================
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))
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;
}
//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;
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)
{
}
myRetrievableStatus = aReader->GetStatus();
-
- return aDoc;
}
//=======================================================================
//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);
}
//=======================================================================
(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.
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.
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:
class CDM_Document;
class Resource_Manager;
class Message_Messenger;
+class PCDM_ReaderFilter;
class CDM_Application;
DEFINE_STANDARD_HANDLE(CDM_Application, Standard_Transient)
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.
#include <TDF_Data.hxx>
#include <TDF_ChildIterator.hxx>
#include <TDF_Tool.hxx>
+#include <PCDM_ReaderFilter.hxx>
#include <OSD_Path.hxx>
#include <OSD_OpenFile.hxx>
{
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
__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",
PCDM_Reader.cxx
PCDM_Reader.hxx
PCDM_Reader.lxx
+PCDM_ReaderFilter.cxx
+PCDM_ReaderFilter.hxx
PCDM_ReaderStatus.hxx
PCDM_ReadWriter.cxx
PCDM_ReadWriter.hxx
class CDM_Document;
class TCollection_ExtendedString;
class CDM_Application;
-
+class PCDM_ReaderFilter;
class PCDM_Reader;
DEFINE_STANDARD_HANDLE(PCDM_Reader, Standard_Transient)
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;
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <PCDM_ReaderFilter.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(PCDM_ReaderFilter,Standard_Transient)
+
+PCDM_ReaderFilter::PCDM_ReaderFilter (const Handle(Standard_Type)& theSkipped) : myAppend (AppendMode_Forbid)
+{
+ mySkip.Add(theSkipped->Name());
+}
+
+PCDM_ReaderFilter::PCDM_ReaderFilter (const TCollection_AsciiString& theEntryToRead) : myAppend (AppendMode_Forbid)
+{
+ mySubTrees.Append(theEntryToRead);
+}
+
+PCDM_ReaderFilter::PCDM_ReaderFilter (const AppendMode theAppend) : myAppend (theAppend)
+{}
+
+void PCDM_ReaderFilter::Clear()
+{
+ mySkip.Clear();
+ myRead.Clear();
+ mySubTrees.Clear();
+}
+
+PCDM_ReaderFilter::~PCDM_ReaderFilter()
+{
+ ClearTree();
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassed (const Handle(Standard_Type)& theAttributeID) const
+{
+ return IsPassedAttr(theAttributeID->Name());
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassedAttr (const TCollection_AsciiString& theAttributeType) const
+{
+ return myRead.IsEmpty() ? !mySkip.Contains (theAttributeType) :
+ myRead.Contains (theAttributeType);
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassed (const TCollection_AsciiString& theEntry) const
+{
+ if (mySubTrees.IsEmpty())
+ return true;
+ for (NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees); anEntry.More(); anEntry.Next())
+ {
+ if (theEntry.StartsWith (anEntry.Value()))
+ {
+ if (theEntry.Length() > anEntry.Value().Length() &&
+ theEntry.Value (anEntry.Value().Length() + 1) != ':') // case when theEntry="0:10" should not match "0:1"
+ continue;
+ return true;
+ }
+ }
+ return false;
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsSubPassed (const TCollection_AsciiString& theEntry) const
+{
+ if (mySubTrees.IsEmpty() || theEntry.Length() == 2) // root is always passed if any sub is defined
+ return true;
+ for (NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees); anEntry.More(); anEntry.Next())
+ {
+ if (theEntry.Length() < anEntry.Value().Length() &&
+ anEntry.Value().Value (theEntry.Length() + 1) == ':' && // case when theEntry="0:1" should not match "0:10"
+ anEntry.Value().StartsWith (theEntry))
+ return true;
+ }
+ return false;
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPartTree()
+{
+ return !(mySubTrees.IsEmpty() || (mySubTrees.Size() == 1 && mySubTrees.First().Length() < 3));
+}
+
+void PCDM_ReaderFilter::StartIteration()
+{
+ myCurrent = &myTree;
+ myCurrentDepth = 0;
+ ClearTree();
+ myTree.Bind(-1, NULL);
+ if (mySubTrees.IsEmpty())
+ return;
+ // create an iteration-tree by the mySubTrees entries
+ for (NCollection_List<TCollection_AsciiString>::Iterator aTreeIter (mySubTrees); aTreeIter.More(); aTreeIter.Next())
+ {
+ TagTree* aMap = &myTree;
+ TCollection_AsciiString aTagStr, anEntry = aTreeIter.Value();
+ for (Standard_Integer aTagIndex = 2; Standard_True; ++aTagIndex) // skip the root tag
+ {
+ aTagStr = anEntry.Token(":", aTagIndex);
+ if (aTagStr.IsEmpty())
+ break;
+ Standard_Integer aTag = aTagStr.IntegerValue();
+ if (aMap->IsBound (aTag))
+ {
+ aMap = (TagTree*)aMap->Find (aTag);
+ }
+ else
+ {
+ TagTree* aNewMap = new TagTree;
+ aNewMap->Bind (-1, aMap); // to be able to iterate up, keep father map in the child
+ aMap->Bind(aTag, aNewMap);
+ aMap = aNewMap;
+ }
+ }
+ aMap->Bind (-2, NULL); // identifier that this node is in subtrees definition
+ }
+}
+
+void PCDM_ReaderFilter::Up()
+{
+ if (myCurrentDepth == 0)
+ myCurrent = (TagTree*)myCurrent->Find(-1);
+ else
+ myCurrentDepth--;
+}
+
+void PCDM_ReaderFilter::Down (const int& theTag)
+{
+ if (myCurrentDepth== 0)
+ {
+ if (myCurrent->IsBound (theTag))
+ myCurrent= (TagTree*)myCurrent->Find (theTag);
+ else
+ ++myCurrentDepth;
+ }
+ else
+ ++myCurrentDepth;
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsPassed() const
+{
+ return myCurrent->IsBound(-2);
+}
+
+Standard_Boolean PCDM_ReaderFilter::IsSubPassed() const
+{
+ return myCurrentDepth == 0;
+}
+
+void PCDM_ReaderFilter::ClearSubTree (const Standard_Address theMap)
+{
+ if (theMap)
+ {
+ TagTree* aMap = (TagTree*)theMap;
+ for (TagTree::Iterator aTagIter (*aMap); aTagIter.More(); aTagIter.Next())
+ if (aTagIter.Key() != -1)
+ ClearSubTree (aTagIter.Value());
+ delete aMap;
+ }
+}
+
+void PCDM_ReaderFilter::ClearTree()
+{
+ for (TagTree::Iterator aTagIter (myTree); aTagIter.More(); aTagIter.Next())
+ if (aTagIter.Key() != -1)
+ ClearSubTree (aTagIter.Value());
+ myTree.Clear();
+}
--- /dev/null
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _PCDM_ReaderFilter_HeaderFile
+#define _PCDM_ReaderFilter_HeaderFile
+
+#include <Standard_Type.hxx>
+#include <Standard_Transient.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <NCollection_Map.hxx>
+#include <NCollection_List.hxx>
+
+class PCDM_ReaderFilter;
+DEFINE_STANDARD_HANDLE (PCDM_ReaderFilter, Standard_Transient)
+
+
+//! Class represents a document reading filter.
+//!
+//! It allows to set attributes (by class names) that must be skipped during the document reading
+//! or attributes that must be retrieved only.
+//! In addition it is possible to define one or several subtrees (by entry) which must be
+//! retrieved during the reading. Other labels are created, but no one attribute on them.
+class PCDM_ReaderFilter : public Standard_Transient
+{
+public:
+
+ //! Supported modes of appending the file content into existing document
+ enum AppendMode
+ {
+ AppendMode_Forbid = 0, //!< do not allow append, default mode
+ AppendMode_Protect = 1, //!< keeps existing attributes, reads only new ones
+ AppendMode_Overwrite = 2, //!< overwrites the existing attributes by the loaded ones
+ };
+
+
+ //! Creates an empty filter, so, all will be retrieved if nothing else is defined.
+ inline PCDM_ReaderFilter() : myAppend(AppendMode_Forbid) {}
+
+ //! Creates a filter to skip only one type of attributes.
+ Standard_EXPORT PCDM_ReaderFilter (const Handle(Standard_Type)& theSkipped);
+
+ //! Creates a filter to read only sub-labels of a label-path.
+ //! Like, for "0:2" it will read all attributes for labels "0:2", "0:2:1", etc.
+ Standard_EXPORT PCDM_ReaderFilter (const TCollection_AsciiString& theEntryToRead);
+
+ //! Creates a filter to append the content of file to open to existing document.
+ Standard_EXPORT PCDM_ReaderFilter (const AppendMode theAppend);
+
+ //! Destructor for the filter content
+ Standard_EXPORT ~PCDM_ReaderFilter();
+
+ //! Adds skipped attribute by type.
+ Standard_EXPORT void AddSkipped (const Handle(Standard_Type)& theSkipped) { mySkip.Add(theSkipped->Name()); }
+ //! Adds skipped attribute by type name.
+ Standard_EXPORT void AddSkipped (const TCollection_AsciiString& theSkipped) { mySkip.Add (theSkipped); }
+
+ //! Adds attribute to read by type. Disables the skipped attributes added.
+ Standard_EXPORT void AddRead (const Handle(Standard_Type)& theRead) { myRead.Add(theRead->Name()); }
+ //! Adds attribute to read by type name. Disables the skipped attributes added.
+ Standard_EXPORT void AddRead (const TCollection_AsciiString& theRead) { myRead.Add (theRead); }
+
+ //! Adds sub-tree path (like "0:2").
+ Standard_EXPORT void AddPath (const TCollection_AsciiString& theEntryToRead) { mySubTrees.Append (theEntryToRead); }
+
+ //! Makes filter pass all data.
+ Standard_EXPORT void Clear();
+
+ //! Returns true if attribute must be read.
+ Standard_EXPORT virtual Standard_Boolean IsPassed (const Handle(Standard_Type)& theAttributeID) const;
+ //! Returns true if attribute must be read.
+ Standard_EXPORT virtual Standard_Boolean IsPassedAttr (const TCollection_AsciiString& theAttributeType) const;
+ //! Returns true if content of the label must be read.
+ Standard_EXPORT virtual Standard_Boolean IsPassed (const TCollection_AsciiString& theEntry) const;
+ //! Returns true if some sub-label of the given label is passed.
+ Standard_EXPORT virtual Standard_Boolean IsSubPassed (const TCollection_AsciiString& theEntry) const;
+ //! Returns true if only part of the document tree will be retrieved.
+ Standard_EXPORT virtual Standard_Boolean IsPartTree();
+
+ //! Returns the append mode.
+ Standard_EXPORT AppendMode& Mode() { return myAppend; }
+ //! Returns true if appending to the document is performed.
+ Standard_EXPORT Standard_Boolean IsAppendMode() { return myAppend != PCDM_ReaderFilter::AppendMode_Forbid; }
+
+ //! Starts the tree iterator. It is used for fast searching of passed labels if the whole tree of labels
+ //! is parsed. So, on each iteration step the methods Up and Down must be called after the iteration start.
+ Standard_EXPORT virtual void StartIteration();
+ //! Iteration to the child label.
+ Standard_EXPORT virtual void Up();
+ //! Iteration to the child with defined tag.
+ Standard_EXPORT virtual void Down (const int& theTag);
+ //! Returns true if content of the currently iterated label must be read.
+ Standard_EXPORT virtual Standard_Boolean IsPassed() const;
+ //! Returns true if some sub-label of the currently iterated label is passed.
+ Standard_EXPORT virtual Standard_Boolean IsSubPassed() const;
+
+ DEFINE_STANDARD_RTTIEXT (PCDM_ReaderFilter, Standard_Transient)
+
+private:
+ //! Clears the iteration tree
+ Standard_EXPORT void ClearTree();
+ //! Clears the iteration sub-tree
+ Standard_EXPORT static void ClearSubTree (const Standard_Address theMap);
+
+protected:
+ //! Append mode for reading files into existing document
+ AppendMode myAppend;
+ //! Class names of attributes that must be skipped during the read
+ NCollection_Map<TCollection_AsciiString> mySkip;
+ //! Class names of only attributes to read (if it is not empty, mySkip is unused)
+ NCollection_Map<TCollection_AsciiString> myRead;
+ //! Paths to the labels that must be read. If it is empty, read all.
+ NCollection_List<TCollection_AsciiString> mySubTrees;
+
+ //! Map from tag of a label to sub-tree of this tag. Used for fast browsing the tree
+ //! and compare with entities that must be read.
+ typedef NCollection_DataMap<Standard_Integer, Standard_Address> TagTree;
+ //! Whole tree that correspond to retrieved document.
+ TagTree myTree;
+ //! Pointer to the current node of the iterator.
+ TagTree* myCurrent;
+ //! If a node does not described in the read-entries, the iterator goes inside of this subtree just by
+ //! keeping the depth of iteration.
+ Standard_Integer myCurrentDepth;
+};
+
+#endif // _PCDM_ReaderFilter_HeaderFile
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
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");
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)
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)
#include <CDF_Store.hxx>
#include <PCDM_RetrievalDriver.hxx>
#include <PCDM_StorageDriver.hxx>
+#include <PCDM_ReaderFilter.hxx>
#include <Plugin.hxx>
#include <Plugin_Failure.hxx>
#include <Resource_Manager.hxx>
//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;
if (index == current) {
Handle(TDocStd_Document) D =
Handle(TDocStd_Document)::DownCast(it.Document());
- aDoc = D;
+ theDoc = D;
return;
}
}
//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;
}
//=======================================================================
// : 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);
}
//=======================================================================
//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);
}
//=======================================================================
//=======================================================================
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;
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)
{
{
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)
{
//=======================================================================
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);
}
}
//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)
{
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 ");
}
}
if(storer.StoreStatus() == PCDM_SS_OK)
- D->SetSaved();
+ theDoc->SetSaved();
#ifdef OCCT_DEBUG
std::cout<<"TDocStd_Application::SaveAs(): The status = "<<storer.StoreStatus()<<std::endl;
#endif
//! the events during the Open/Store operation, a MessageDriver
//! based on Message_PrinterOStream may be used. In case of need client
//! can implement his own version inheriting from Message_Printer class
-//! and add it to the Messanger.
+//! and add it to the Messenger.
//! Also the trace level of messages can be tuned by setting trace level (SetTraceLevel (Gravity )) for the used Printer.
//! By default, trace level is Message_Info, so that all messages are output.
//! In order not to override a version of aDoc which
//! is already in memory, this method can be made
//! to depend on the value returned by IsInSession.
+ //! It is possible to filter out some attributes or
+ //! parts of the retrieved tree by theFilter.
Standard_EXPORT PCDM_ReaderStatus Open (const TCollection_ExtendedString& path,
- Handle(TDocStd_Document)& aDoc,
+ Handle(TDocStd_Document)& theDoc,
+ const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
const Message_ProgressRange& theRange = Message_ProgressRange());
//! Retrieves aDoc from standard SEEKABLE stream theIStream.
//! the stream should support SEEK fuctionality
- Standard_EXPORT PCDM_ReaderStatus Open (Standard_IStream& theIStream, Handle(TDocStd_Document)& theDoc,
+ //! It is possible to filter out some attributes or
+ //! parts of the retrieved tree by theFilter.
+ Standard_EXPORT PCDM_ReaderStatus Open (Standard_IStream& theIStream, Handle(TDocStd_Document)& theDoc,
+ const Handle(PCDM_ReaderFilter)& theFilter = Handle(PCDM_ReaderFilter)(),
const Message_ProgressRange& theRange = Message_ProgressRange());
//! Save the active document in the file <name> in the
//! path <path> ; o verwrites the file if it already exists.
- Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& aDoc,
+ Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& theDoc,
const TCollection_ExtendedString& path,
const Message_ProgressRange& theRange = Message_ProgressRange());
//! Exceptions:
//! Standard_NotImplemented if the document
//! was not retrieved in the applicative session by using Open.
- Standard_EXPORT PCDM_StoreStatus Save (const Handle(TDocStd_Document)& aDoc,
+ Standard_EXPORT PCDM_StoreStatus Save (const Handle(TDocStd_Document)& theDoc,
const Message_ProgressRange& theRange = Message_ProgressRange());
//! Save the active document in the file <name> in the
//! path <path> . overwrite the file if it
//! already exist.
- Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& aDoc,
+ Standard_EXPORT PCDM_StoreStatus SaveAs (const Handle(TDocStd_Document)& theDoc,
const TCollection_ExtendedString& path,
TCollection_ExtendedString& theStatusMessage,
const Message_ProgressRange& theRange = Message_ProgressRange());
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());
}
- // 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);
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);
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);
//=======================================================================
//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!
{
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
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);
//=======================================================================
//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()
{
//!< * BIN, XML: TopTools_FormatVersion_CURRENT changed to 3 and
//!< BinTools_FormatVersion_CURRENT changed to 4 to preserve per-vertex normal
//!< information in case of triangulation-only Faces [#0031136]
- TDocStd_FormatVersion_CURRENT = TDocStd_FormatVersion_VERSION_11 //!< Current version
+ TDocStd_FormatVersion_VERSION_12, //!< OCCT 7.6.0
+ //!< * BIN: New binary format for fast reading part of OCAF document [#0031918]
+
+ TDocStd_FormatVersion_CURRENT = TDocStd_FormatVersion_VERSION_12 //!< Current version
};
enum
{
TDocStd_FormatVersion_LOWER = TDocStd_FormatVersion_VERSION_2,
- TDocStd_FormatVersion_UPPER = TDocStd_FormatVersion_VERSION_11
+ TDocStd_FormatVersion_UPPER = TDocStd_FormatVersion_VERSION_12
};
#include <TDocStd_Application.hxx>
#include <TDocStd_Document.hxx>
#include <TDocStd_Owner.hxx>
+#include <PCDM_ReaderFilter.hxx>
#include <TNaming_NamedShape.hxx>
#include <TopoDS_Shape.hxx>
#include <TPrsStd_AISPresentation.hxx>
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";
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);
(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;
if (aFileStream.is_open() && aFileStream.good())
{
- Read (aFileStream, NULL, theNewDocument, theApplication, theRange);
+ Read (aFileStream, NULL, theNewDocument, theApplication, theFilter, theRange);
}
else
{
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();
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);
--- /dev/null
+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
--- /dev/null
+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)"
+}
--- /dev/null
+puts "==========="
+puts "0031918: Application Framework - New binary format for fast reading part of OCAF document"
+puts "==========="
+
+set docname ${imagedir}/doc_${casename}.cbfl
+
+NewDocument D0 BinLOcaf
+UndoLimit D0 10
+
+NewCommand D0
+
+# set an array 1000 values from 100 to 1099
+set values "100 "
+for {set i 101} {$i < 1100} {incr i} {set values "$values $i"}
+
+# set 100 arrays to sub-labels of 0:1 0:2 0:3 and 0:4
+for {set lab 1} {$lab <= 4} {incr lab} {
+ for {set sublab 1} {$sublab <= 100} {incr sublab} {
+ set command "SetIntArray D0 0:$lab:$sublab 0 1 1000 $values"
+ eval $command
+ SetReal D0 0:$lab:$sublab 0.1
+ }
+}
+
+CommitCommand D0
+
+SaveAs D0 ${docname}
+Close D0
+
+set whole_time [lindex [time {
+ Open ${docname} D1
+ Close D1
+} 20] 0]
+puts "Whole document open time $whole_time mcs"
+
+set quater_time [lindex [time {
+ Open ${docname} D2 -read0:2
+ Close D2
+} 20] 0]
+puts "Quater of document open time $quater_time mcs"
+
+# Check that open of quater of the document is at least twice faster than open of whole.
+if { [expr $quater_time * 2] > $whole_time } {
+ puts "Error : loading of quater of the document content too slow relatively to the whole document load"
+}
+
+set four_quaters_time [lindex [time {
+ Open ${docname} D3 -read0:1 -read0:2 -read0:3 -read0:4
+ Close D3
+} 20] 0]
+puts "Four quaters of document open time $four_quaters_time mcs"
+
+# Check that open of four quaters of the document is not too much slower than opening of the whole document.
+if { [expr $four_quaters_time * 0.9] > $whole_time } {
+ puts "Error : loading of four quaters of the document content too slow relatively to the whole document load"
+}
+
+set no_arrays_time [lindex [time {
+ Open ${docname} D4 -skipTDataStd_IntegerArray -read0:2
+}] 0]
+puts "Quater of document without arrays open time $no_arrays_time mcs"
+
+set attrs [Attributes D4 0:2:13]
+if {"${attrs}" != "TDataStd_Real "} {
+ puts "Error : loading of document skipping arrays contains invalid attributes list '${attrs}'"
+}
+
+if {![catch {Attributes D4 0:1:1:13}] || ![catch {Attributes D4 0:1:3:14}] || ![catch {Attributes D4 0:1:4:1}]} {
+ puts "Error : loading of document skipping arrays and sub-trees contains invalid attributes list"
+}
+
+set append_arrays_time [lindex [time {
+ Open ${docname} D4 -append -readTDataStd_IntegerArray -read0:2 -read0:3
+}] 0]
+puts "Half of document arrays open time $append_arrays_time mcs"
+
+set attrs [Attributes D4 0:2:13]
+if {"${attrs}" != "TDataStd_Real TDataStd_IntegerArray "} {
+ puts "Error : loading of document reading arrays separately contains invalid attributes list '${attrs}'"
+}
+set attrs [Attributes D4 0:3:1]
+if {"${attrs}" != "TDataStd_IntegerArray "} {
+ puts "Error : loading of document reading arrays separately contains invalid attributes list on subtree 3 '${attrs}'"
+}
+if {![catch {Attributes D4 0:1:1:13}] || ![catch {Attributes D4 0:1:4:1}]} {
+ puts "Error : loading of document reading arrays separately contains invalid attributes list on 1 and 4 subtrees"
+}
+
+Close D4
--- /dev/null
+puts "==========="
+puts "0031918: Application Framework - New binary format for fast reading part of OCAF document"
+puts "==========="
+
+pload XDE
+
+NewDocument D0 BinOcaf
+
+# creates part-shape by the given sizes
+proc store_part {nx ny dx dy dz entry} {
+ global D0
+ box b1 0 0 0 [expr $nx + .5] [expr $ny + .5] 1
+ box b2 0.5 0.5 0 [expr $nx - .5] [expr $nx - .5] 0.4
+ cut base b1 b2
+
+ set command "compound"
+ for {set x 0} {$x < $nx} {incr x} {
+ for {set y 0} {$y < $ny} {incr y} {
+ pcylinder c${x}_$y 0.25 1.01
+ ttranslate c${x}_$y [expr $x+.75] [expr $y+.75] 0.39
+ set command "$command c${x}_$y"
+ }
+ }
+ eval "$command cc"
+ bop base cc
+ bopfuse part
+ ttranslate part $dx $dy $dz
+ Label D0 $entry
+ SetShape D0 $entry part
+}
+
+store_part 16 16 0 0 0 0:1:1
+
+for {set n 1} {$n < 5} {incr n} {
+ store_part 4 4 $n $n $n 0:2:$n
+ store_part 4 4 [expr 16-4-$n] $n $n 0:2:[expr $n+4]
+ store_part 4 4 $n [expr 16-4-$n] $n 0:2:[expr $n+8]
+ store_part 4 4 [expr 16-4-$n] [expr 16-4-$n] $n 0:2:[expr $n+12]
+}
+store_part 6 6 5 5 5 0:3:1
+store_part 4 4 6 6 6 0:3:2
+GetShape D0 0:3:2 top2
+
+set docname ${imagedir}/doc_${casename}.cbf
+set save_time [lindex [time {
+ SaveAs D0 ${docname}
+}] 0]
+puts "Save time $save_time mcs"
+
+Close D0
+
+set whole_time [lindex [time {
+ Open ${docname} D1
+ Close D1
+} 20] 0]
+puts "Whole document open time $whole_time mcs"
+
+set half_time1 [lindex [time {
+ Open ${docname} D2 -read0:1 -read0:3
+ Close D2
+} 20] 0]
+puts "First half of document open time $half_time1 mcs"
+
+set half_time2 [lindex [time {
+ Open ${docname} D3 -read0:2
+ Close D3
+} 20] 0]
+puts "Second half of document open time $half_time2 mcs"
+
+# Check that open of two halfs of the document separately is not too much slower than open of the whole
+if { [expr ($half_time1 + $half_time2) * 0.9] > $whole_time } {
+ puts "Error : loading of half of the document content is too slow relatively to the whole document load"
+}
+
+Open ${docname} D4 -read0:3:2
+GetShape D4 0:3:2 opened_top2
+checkshape opened_top2
+
+# check shapes are the same before open and after
+if {[string first [whatis top2] [whatis opened_top2]] != 7} {
+ puts "Error : saved and opened shapes are different"
+}
+Open ${docname} D4 -append -read0:1 -read0:2
+GetShape D4 0:1:1 s
+checkshape s
+for {set n 1} {$n < 16} {incr n} {
+ GetShape D4 0:2:$n s
+ checkshape s
+}
+Close D4
+
+set no_shapes_time [lindex [time {
+ Open ${docname} D5 -skipTNaming_NamedShape
+ Close D5
+} 20] 0]
+puts "Document without shapes open time $no_shapes_time mcs"
+
+# Check that open of the document without shapes is much faster than open of the whole
+if { [expr $no_shapes_time * 20] > $whole_time } {
+ puts "Error : loading of the document without shapes is too slow relatively to the whole document load"
+}
+
+# check shapes storage with triangulations
+set length_wo_tirangulation [string length [dump s]]
+vinit
+vdisplay top2 -displaymode 1
+NewDocument D6 BinOcaf
+UndoLimit D6 10
+SetShape D6 0:1 top2
+StoreTriangulation 1
+SaveAs D6 ${docname}
+Close D6
+
+Open ${docname} D7
+GetShape D7 0:1 top3
+Close D7
+
+checkshape top3
+
+set length_with_tirangulation [string length [dump top3]]
+if { [expr $length_with_tirangulation / 7] < $length_wo_tirangulation } {
+ puts "Error : looks like shape stored with triangulation loaded without trianulation"
+}
Close Doc
# Test data
-set ctr { "0%" "Writing document" "Writing sub tree"
- "Writing geometry" "Writing 2D curves" "Writing curves"
- "Writing surfases" "Writing shapes" "100%" }
+set ctr { "0%" "Writing document" "Writing sub tree" "100%" }
foreach data ${ctr} {
if ![regexp $data $output] {
Close Doc
# Test data
-set ctr {"0%" "Reading data" "Reading geomentry" "Reading curves 2d"
- "Reading surfaces" "Reading Shapes" "Reading sub tree" "100%" }
+set ctr {"0%" "Reading data" "Reading sub tree" "100%" }
foreach data ${ctr} {
if ![regexp $data $output] {
Close Doc
# Test data
-set ctr { "0%" "Writing document" "Writing sub tree"
- "Writing geometry" "Writing 2D curves" "Writing curves"
- "Writing surfases" "Writing shapes" "100%" }
+set ctr { "0%" "Writing document" "Writing sub tree" "100%" }
foreach data ${ctr} {
if ![regexp $data $output] {