Initial 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 12 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.
# Conflicts:
# src/BinMNaming/BinMNaming_NamedShapeDriver.cxx
# src/BinMXCAFDoc/BinMXCAFDoc_LocationDriver.cxx
# src/BinTools/BinTools_ShapeSet.cxx
# src/BinTools/BinTools_ShapeSet.hxx
# src/BinTools/FILES
#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_DocumentSection& /*theSection*/,
Standard_IStream& theIS,
const Standard_Boolean /*isMess*/,
- const Standard_Boolean thePostponeShapes,
const Message_ProgressRange& theRange)
{
OCC_CATCH_SIGNALS
Handle(BinMNaming_NamedShapeDriver) aNamedShapeDriver =
Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
- aNamedShapeDriver->ReadShapeSection (theIS, thePostponeShapes, theRange);
+ aNamedShapeDriver->ReadShapeSection (theIS, theRange);
}
catch(Standard_Failure const& anException) {
const TCollection_ExtendedString aMethStr
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);
+}
(BinLDrivers_DocumentSection& theSection,
Standard_IStream& theIS,
const Standard_Boolean isMess = Standard_False,
- const Standard_Boolean thePostponeShapes = Standard_False,
const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
Standard_EXPORT virtual void CheckShapeSection
//! 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);
+
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 : WriteShapeSection
//purpose : Implements WriteShapeSection
Standard_EXPORT void SetWithTriangles (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)
};
IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentRetrievalDriver,PCDM_RetrievalDriver)
#define SHAPESECTION_POS "SHAPE_SECTION_POS:"
+#define ENDSECTION_POS ":"
#define SIZEOFSHAPELABEL 18
#define DATATYPE_MIGRATION
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;
Handle(TDF_Data) aData = (!theFilter.IsNull() && theFilter->IsAppendMode()) ? aDoc->GetData() : new TDF_Data();
std::streampos aDocumentPos = -1;
- Message_ProgressScope aPS(theRange, "Reading data", 3);
- Standard_Boolean aPostponeShapes = !theFilter.IsNull() && (theFilter->IsPartTree() || !theFilter->IsPassedAttr("TNaming_NamedShape"));
+ Message_ProgressScope aPS (theRange, "Reading data", 3);
+ Standard_Boolean aQuickPart = IsQuickPart (aFileVer);
// 2b. Read the TOC of Sections
if (aFileVer >= 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.
theIStream.seekg ((std::streampos) aCurSection.Offset());
if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS))
{
- ReadShapeSection (aCurSection, theIStream, false, aPostponeShapes, aPS.Next());
+ ReadShapeSection (aCurSection, theIStream, false, aPS.Next());
if (!aPS.More())
{
myReaderStatus = PCDM_RS_UserBreak;
return;
}
}
- else
+ else if (!aCurSection.Name().IsEqual ((Standard_CString)ENDSECTION_POS))
ReadSection (aCurSection, theDoc, theIStream);
}
}
CheckShapeSection(aShapeSectionPos, theIStream);
// Read Shapes
BinLDrivers_DocumentSection aCurSection;
- ReadShapeSection (aCurSection, theIStream, Standard_False, aPostponeShapes, aPS.Next());
+ ReadShapeSection (aCurSection, theIStream, Standard_False, aPS.Next());
if (!aPS.More())
{
myReaderStatus = PCDM_RS_UserBreak;
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(), theFilter, 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;
(Standard_IStream& theIS,
const TDF_Label& theLabel,
const Handle(PCDM_ReaderFilter)& theFilter,
+ const Standard_Boolean& theQuickPart,
const Message_ProgressRange& theRange)
{
Standard_Integer nbRead = 0;
Message_ProgressScope aPS(theRange, "Reading sub tree", 2, true);
- TCollection_AsciiString anEntry;
bool aSkipAttrs = Standard_False;
if (!theFilter.IsNull() && theFilter->IsPartTree())
+ aSkipAttrs = !theFilter->IsPassed();
+
+ if (theQuickPart)
{
- TDF_Tool::Entry(theLabel, anEntry);
- aSkipAttrs = !theFilter->IsPassed(anEntry);
+ 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:
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());
if (!aDriver.IsNull()) {
- if (!theFilter.IsNull() && !theFilter->IsPassed(aDriver->SourceType())) {
- continue;
- }
// 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()))
// read sub-tree
- Standard_Integer nbSubRead = ReadSubTree(theIS, aLab, theFilter, 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;
myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
return -1;
}
+ if (!theFilter.IsNull())
+ theFilter->Up();
return nbRead;
}
(BinLDrivers_DocumentSection& theSection,
Standard_IStream& /*theIS*/,
const Standard_Boolean isMess,
- const Standard_Boolean /*thePostponeShapes*/,
const Message_ProgressRange &/*theRange*/)
{
//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 < 2 || 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_11;
+}
(Standard_IStream& theIS,
const TDF_Label& theData,
const Handle(PCDM_ReaderFilter)& theFilter,
+ const Standard_Boolean& theQuickPart,
const Message_ProgressRange& theRanges = Message_ProgressRange());
(BinLDrivers_DocumentSection& theSection,
Standard_IStream& theIS,
const Standard_Boolean isMess = Standard_False,
- const Standard_Boolean thePostponeShapes = Standard_False,
const Message_ProgressRange& theRange = Message_ProgressRange());
//! checks the shapes section can be correctly retreived.
//! 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 () : myIsQuickPart(Standard_True)
{
}
{
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_11;
+}
+
+//=======================================================================
+//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 Standard_Integer 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;
-
+ Standard_Boolean myIsQuickPart;
+ //! 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"
#define FORMAT_NUMBER 3
//=======================================================================
-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()), myShapeSet(Standard_False),myFormatNb(FORMAT_NUMBER)
+ : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()),
+ myShapeSet (NULL),
+ myFormatNb (BinTools_FormatVersion_VERSION_1),
+ myIsQuickPart (Standard_False),
+ myWithTriangles (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++;
}
void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS,
const Message_ProgressRange& theRange)
{
- theOS << SHAPESET;
- myShapeSet.SetFormatNb(myFormatNb);
- myShapeSet.Write (theOS, theRange);
- myShapeSet.Clear();
+ myIsQuickPart = Standard_False;
+ theOS << SHAPESET;
+ ShapeSet (Standard_False)->SetFormatNb (myFormatNb);
+ 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 Standard_Boolean thePostponeShapes,
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, thePostponeShapes, theRange);
- SetFormatNb(myShapeSet.FormatNb());
+ BinTools_ShapeSetBase* aShapeSet = ShapeSet (Standard_True);
+ aShapeSet->Clear();
+ aShapeSet->Read (theIS, theRange);
+ SetFormatNb (aShapeSet->FormatNb());
}
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 (myWithTriangles);
+ else
+ myShapeSet = new BinTools_ShapeSet (myWithTriangles);
+ 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();
}
//! Input the shapes from Bin Document file
Standard_EXPORT void ReadShapeSection (Standard_IStream& theIS,
- const Standard_Boolean thePostponeShapes = Standard_False,
const Message_ProgressRange& therange = Message_ProgressRange());
//! Output the shapes into Bin Document file
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; }
//! set whether to store triangulation
void SetWithTriangles (const Standard_Boolean isWithTriangles);
//! First : does not write CurveOnSurface UV Points into the file
//! on reading calls Check() method.
//! Second: stores CurveOnSurface UV Points.
- void SetFormatNb (const Standard_Integer theFormat);
+ void SetFormatNb (const Standard_Integer theFormat);
//! get the format of topology
- Standard_Integer GetFormatNb() const;
+ Standard_Integer GetFormatNb() const;
//! get the format of topology
- 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_Integer myFormatNb;
+ Standard_Boolean myWithTriangles;
+ //! Enables storing of whole shape data just in the attribute, not in a separated shapes section
+ Standard_Boolean myIsQuickPart;
};
inline void BinMNaming_NamedShapeDriver::SetWithTriangles(const Standard_Boolean isWithTriangles)
{
- myShapeSet.SetWithTriangles(isWithTriangles);
+ myWithTriangles = isWithTriangles;
+ if (myShapeSet)
+ myShapeSet->SetWithTriangles (isWithTriangles);
}
-
-//=======================================================================
-//function : GetShapesLocations
-//purpose :
-//=======================================================================
-inline BinTools_LocationSet& BinMNaming_NamedShapeDriver::GetShapesLocations()
-{
- return myShapeSet.ChangeLocations();
-}
-
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 > 5 && 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 > 5 )
+ 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),
+ myIStream (NULL),
+ myOStream (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) {
+ if (myDirectWritingIsEnabled = (aData[1] < 0))
+ 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 :
const Message_ProgressRange& theRange)
{
BinTools_ShapeSet aShapeSet(Standard_True);
- aShapeSet.Read (theStream, Standard_False, theRange);
+ aShapeSet.Read (theStream, theRange);
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->operator bool();
+}
+
+//=======================================================================
+//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);
+ TColStd_Array1OfInteger& aNodes = aResult->ChangeNodes();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream >> aNodes.ChangeValue (aNodeIter);
+ 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();
+ aResult = new Poly_Triangulation (aNbNodes, aNbTriangles, aHasUV);
+ aResult->Deflection (theStream.ReadReal());
+ TColgp_Array1OfPnt& aNodes = aResult->ChangeNodes();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream >> aNodes.ChangeValue (aNodeIter);
+ if (aHasUV)
+ {
+ TColgp_Array1OfPnt2d& aUVNodes = aResult->ChangeUVNodes();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ {
+ gp_XY& anUV = aUVNodes.ChangeValue (aNodeIter).ChangeCoord();
+ theStream >> anUV.ChangeCoord (1);
+ theStream >> anUV.ChangeCoord (2);
+ }
+ }
+ // read the triangles
+ Poly_Array1OfTriangle& aTriangles = aResult->ChangeTriangles();
+ for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
+ {
+ Poly_Triangle& aTri = aTriangles.ChangeValue (aTriIter);
+ theStream >> aTri.ChangeValue (1);
+ theStream >> aTri.ChangeValue (2);
+ theStream >> aTri.ChangeValue (3);
+ }
+ 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 char* Version_1 = "Open CASCADE Topology V1 (c)";
-const char* Version_2 = "Open CASCADE Topology V2 (c)";
-const char* Version_3 = "Open CASCADE Topology V3 (c)";
-//=======================================================================
-//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(const Standard_Boolean isWithTriangles)
- :myFormatNb(3), myWithTriangles(isWithTriangles)
+BinTools_ShapeSet::BinTools_ShapeSet (const Standard_Boolean theWithTriangles)
+ : BinTools_ShapeSetBase (theWithTriangles)
{}
//=======================================================================
BinTools_ShapeSet::~BinTools_ShapeSet()
{}
-//=======================================================================
-//function : SetFormatNb
-//purpose :
-//=======================================================================
-void BinTools_ShapeSet::SetFormatNb(const Standard_Integer theFormatNb)
-{
- myFormatNb = theFormatNb;
-}
-
-//=======================================================================
-//function : FormatNb
-//purpose :
-//=======================================================================
-Standard_Integer BinTools_ShapeSet::FormatNb() const
-{
- return myFormatNb;
-}
-
//=======================================================================
//function : Clear
//purpose :
if (theShape.IsNull()) return 0;
myLocations.Add(theShape.Location());
TopoDS_Shape aS2 = theShape;
- aS2.Location(TopLoc_Location());
-
- const int* anIndex = myShapes.Seek2(aS2);
- if (!anIndex)
- {
- AddShape (aS2);
+ aS2.Location (TopLoc_Location());
+ Standard_Integer anIndex = myShapes.FindIndex (aS2);
+ if (anIndex == 0) {
+ AddShape (aS2);
for (TopoDS_Iterator its (aS2, Standard_False, Standard_False); its.More(); its.Next())
Add (its.Value());
- int aNewIndex = myShapes.Size() + 1;
- myShapes.Bind(aNewIndex, aS2);
- return aNewIndex;
+ anIndex = myShapes.Add (aS2);
}
- return *anIndex;
+ return anIndex;
}
//purpose :
//=======================================================================
-const TopoDS_Shape& BinTools_ShapeSet::Shape(const Standard_Integer theIndx)
+const TopoDS_Shape& BinTools_ShapeSet::Shape (const Standard_Integer theIndx)
{
- const TopoDS_Shape* aShape = myShapes.Seek1 (theIndx);
- if (!aShape && myStream)
- {
- std::streampos aCurrentPos = myStream->tellg();
- myStream->seekg(myShapesPositions.Value(theIndx));
- TopoDS_Shape aNewShape;
- TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)myStream->get();
- ReadShape (T, *myStream, aNewShape);
- ReadFlagsAndSubs (aNewShape, T, *myStream, myShapesPositions.Length());
- myShapes.Bind(theIndx, aNewShape);
- myStream->seekg(aCurrentPos);
- return myShapes.Find1(theIndx);
- }
- return *aShape;
+ 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.Find2(theShape);
+ return myShapes.FindIndex (theShape);
}
//=======================================================================
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());
Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
if (!TF->Surface().IsNull()) mySurfaces.Add(TF->Surface());
- if (myWithTriangles
- || TF->Surface().IsNull())
+ if (IsWithTriangles() || TF->Surface().IsNull())
{
Handle(Poly_Triangulation) Tr = TF->Triangulation();
if (!Tr.IsNull()) myTriangulations.Add(Tr);
//=======================================================================
void BinTools_ShapeSet::Write (Standard_OStream& OS,
- const Message_ProgressRange& theRange) const
+ const Message_ProgressRange& theRange)
{
// write the copyright
- if (myFormatNb == 3)
+ if (FormatNb() == BinTools_FormatVersion_VERSION_3)
+ {
OS << "\n" << Version_3 << "\n";
- else if (myFormatNb == 2)
+ }
+ else if (FormatNb() == BinTools_FormatVersion_VERSION_2)
+ {
OS << "\n" << Version_2 << "\n";
else
OS << "\n" << Version_1 << "\n";
// subshapes are written first
for (i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next()) {
- const TopoDS_Shape& S = myShapes.Find1(i);
+ const TopoDS_Shape& S = myShapes (i);
// Type
OS << (Standard_Byte)S.ShapeType();
//purpose :
//=======================================================================
void BinTools_ShapeSet::Read (Standard_IStream& IS,
- const Standard_Boolean thePostponeShapes,
const Message_ProgressRange& theRange)
{
- myPostponed = thePostponeShapes;
Clear();
// Check the version
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()) {
-
- if (myPostponed)
- {
- std::streampos aCurrentPos = IS.tellg();
- myShapesPositions.Append (aCurrentPos);
- TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
- PassShape (T, IS);
- PassFlagsAndSubs (IS);
- }
- else {
- TopoDS_Shape S;
- TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
- ReadShape (T, IS, S);
- ReadFlagsAndSubs (S, T, IS, nbShapes);
- myShapes.Bind(i, S);
- }
+ for (int i = 1; i <= nbShapes && aPSinner.More(); i++, aPSinner.Next())
+ {
+ TopoDS_Shape S;
+ TopAbs_ShapeEnum T = (TopAbs_ShapeEnum)IS.get();
+ ReadShape (T, IS, S);
+ ReadFlagsAndSubs (S, T, IS, nbShapes);
+ myShapes.Add (S);
}
- if (myPostponed)
- myStream = &IS;
}
//=======================================================================
//=======================================================================
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.Find2(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 :
//=======================================================================
S.Free(aFree);
S.Modified(aMod);
- if (myFormatNb != BinTools_FormatVersion_VERSION_2
- && myFormatNb != BinTools_FormatVersion_VERSION_3)
+ if (FormatNb() != BinTools_FormatVersion_VERSION_2 &&
+ FormatNb() != BinTools_FormatVersion_VERSION_3)
{
aChecked = false; // force check at reading
}
S.Convex (aConv);
// check
- if (myFormatNb == BinTools_FormatVersion_VERSION_1)
+ 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)
{
}
}
-
-void BinTools_ShapeSet::PassFlagsAndSubs(Standard_IStream& IS)
-{
- IS.ignore(7 * sizeof(Standard_Byte)); // 7 shape flags
- Standard_Character aChar = '\0';
- for (IS >> aChar; aChar != '*'; IS >> aChar)
- if (aChar != '*')
- IS.ignore(2 * sizeof(Standard_Integer)); // sub-shape and its location indices
-}
-
//=======================================================================
//function : ReadGeometry
//purpose :
BinTools::PutReal(OS, last);
// Write UV Points for higher performance
- if (FormatNb() >= 2)
+ 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 :
//=======================================================================
BRep_ListOfPointRepresentation& lpr = TV->ChangePoints();
TopLoc_Location L;
do {
- if (myFormatNb == BinTools_FormatVersion_VERSION_3) {
+ 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);
BinTools::GetReal(IS, last);
// read UV Points // for XML Persistence higher performance
- if (FormatNb() >= 2)
+ if (FormatNb() == BinTools_FormatVersion_VERSION_2
+ || FormatNb() == BinTools_FormatVersion_VERSION_3)
{
BinTools::GetReal(IS, PfX);
BinTools::GetReal(IS, PfY);
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),
}
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),
}
}
-//=======================================================================
-//function : PassShape
-//purpose :
-//=======================================================================
-
-void BinTools_ShapeSet::PassShape (const TopAbs_ShapeEnum T, Standard_IStream& IS)
-{
- Standard_Integer val;
-
- switch (T) {
- case TopAbs_VERTEX:
- IS.ignore(4 * sizeof(Standard_Real)); // tolerance + 3 coordinates
- do {
- if (myFormatNb > 2) {
- val = (Standard_Integer)IS.get();
- if (val > 0 && val <= 3)
- IS.ignore(sizeof(Standard_Real)); // parameter
- }
- else {
- std::streampos aPos = IS.tellg();
- IS.ignore(sizeof(Standard_Real));
- val = (Standard_Integer)IS.get();
- if (val != 1 && val != 2 && val != 3) {
- IS.seekg(aPos);
- val = (Standard_Integer)IS.get();
- if (val > 0 && val <= 3)
- IS.ignore(sizeof(Standard_Real)); // parameter
- }
- }
- switch (val) {
- case 0:
- break;
- case 1:
- IS.ignore(sizeof(Standard_Integer)); // index of curve
- break;
- case 2:
- IS.ignore(sizeof(Standard_Integer) * 2); // curve 2d and surface indices
- break;
- case 3:
- IS.ignore(sizeof(Standard_Real) + sizeof(Standard_Integer)); // parameter + surface index
- break;
- default:
- {
- Standard_SStream aMsg;
- aMsg << "BinTools_SurfaceSet::ReadGeometry: UnExpected BRep_PointRepresentation = " << val << std::endl;
- throw Standard_Failure(aMsg.str().c_str());
- }
- }
-
- if (val > 0)
- IS.ignore(sizeof(Standard_Integer));//Locations index
- } while (val > 0);
- break;
- case TopAbs_EDGE:
- IS.ignore(sizeof(Standard_Real) + 3); // tolerance + 3 flags
- do {
- val = (Standard_Integer)IS.get();
- switch (val) {
- case 0:
- break;
- case 1:
- IS.ignore(2 * sizeof(Standard_Integer) + 2 * sizeof(Standard_Real)); // curve and location indices + 2 parameters
- break;
- case 2: // -2- Curve on surf
- case 3: // -3- Curve on closed surf
- IS.ignore((val == 3 ? 4 : 3) * sizeof(Standard_Integer) + (val == 3 ? 1 : 0) + (FormatNb() >= 2 ? 6 : 2) * sizeof(Standard_Real));
- break;
- case 4: // -4- Regularity
- IS.ignore(1 + 4 * sizeof(Standard_Integer)); // reg byte + surace + location + surface + location indices
- break;
- case 5: // -5- Polygon3D
- IS.ignore(2 * sizeof(Standard_Integer)); // polygon + location indices
- break;
- case 6: // -6- Polygon on triangulation
- case 7: // -7- Polygon on closed triangulation
- IS.ignore((val == 7 ? 4 : 3) * sizeof(Standard_Integer)); // polygon + triangulation + location indices
- break;
- default:
- {
- Standard_SStream aMsg;
- aMsg << "Unexpected Curve Representation =" << val << std::endl;
- throw Standard_Failure(aMsg.str().c_str());
- }
- }
- } while (val > 0);
- break;
- case TopAbs_WIRE:
- break;
- case TopAbs_FACE:
- IS.ignore(1 + sizeof(Standard_Real) + 2 * sizeof(Standard_Integer)); // flag + tolerance + surface and location indices
- if ((Standard_Byte)IS.get() == 2)
- IS.ignore(sizeof(Standard_Integer)); // triangulation index
- break;
- case TopAbs_SHELL:
- break;
- case TopAbs_SOLID:
- break;
- case TopAbs_COMPSOLID:
- break;
- case TopAbs_COMPOUND:
- break;
- default:
- {
- Standard_SStream aMsg;
- aMsg << "Unexpected topology type = " << T << std::endl;
- throw Standard_Failure(aMsg.str().c_str());
- break;
- }
- }
-}
-
//=======================================================================
//function : AddShapes
//purpose :
myBuilder.Add(S1,S2);
}
-
//=======================================================================
//function : WritePolygonOnTriangulation
//purpose :
Standard_Integer BinTools_ShapeSet::NbShapes() const
{
- return myPostponed ? myShapesPositions.Length() : myShapes.Extent();
+ return myShapes.Extent();
}
#ifndef _BinTools_ShapeSet_HeaderFile
#define _BinTools_ShapeSet_HeaderFile
-#include <Standard.hxx>
-#include <Standard_DefineAlloc.hxx>
-#include <Standard_Handle.hxx>
+#include <BinTools_ShapeSetBase.hxx>
-#include <NCollection_DoubleMap.hxx>
-#include <BinTools_FormatVersion.hxx>
-#include <NCollection_Sequence.hxx>
+#include <TopTools_IndexedMapOfShape.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>
-#include <TopTools_ShapeMapHasher.hxx>
-#include <TColStd_MapIntegerHasher.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; }
-
- //! Define if shape will be stored with triangles.
- //! Ignored (always written) if face defines only triangulation (no surface).
- void SetWithTriangles (const Standard_Boolean isWithTriangles) { myWithTriangles = isWithTriangles; }
-
- Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
-
- //! two formats available for the moment:
- //! First: does not write CurveOnSurface UV Points into the file
- //! on reading calls Check() method.
- //! Second: stores CurveOnSurface UV Points.
- //! On reading format is recognized from Version string.
- Standard_EXPORT Standard_Integer FormatNb() const;
-
//! Clears the content of the set.
Standard_EXPORT virtual void Clear();
//! 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 Standard_Boolean thePostponeShapes = Standard_False,
const Message_ProgressRange& theRange = Message_ProgressRange());
//! Writes on <OS> the shape <S>. Writes the
//! orientation, the index of the TShape and the index
//! 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 ReadSubs
(TopoDS_Shape& S, Standard_IStream& IS, const Standard_Integer NbShapes);
- //! Passes in <IS> a shape flags and sub-shapes indices.
- Standard_EXPORT virtual void PassFlagsAndSubs(Standard_IStream& IS);
+ //! 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.
//! Reads a shape of type <T> from the stream <IS> and returns it in <S>.
Standard_EXPORT virtual void ReadShape (const TopAbs_ShapeEnum T, Standard_IStream& IS, TopoDS_Shape& S);
- //! Passes in the input stream of a shape of type <T>.
- Standard_EXPORT virtual void PassShape (const TopAbs_ShapeEnum T, Standard_IStream& IS);
-
//! Stores the shape <S>.
Standard_EXPORT virtual void AddShape (const TopoDS_Shape& S);
private:
- NCollection_DoubleMap<int, TopoDS_Shape, TColStd_MapIntegerHasher, TopTools_ShapeMapHasher> myShapes; ///< index and its shape (started from 1)
- NCollection_Sequence<std::streampos> myShapesPositions; ///< positions in the file of the shape start for postponed reading
- Standard_Boolean myPostponed; ///< postponed reading stores buffer positions, but does not create shapes
- Standard_IStream* myStream; ///< stream used for postponed reading of shapes
+ 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;
NCollection_IndexedMap<Handle(Poly_Polygon3D), TColStd_MapTransientHasher> myPolygons3D;
NCollection_IndexedMap<Handle(Poly_Triangulation), TColStd_MapTransientHasher> myTriangulations;
NCollection_IndexedMap<Handle(Poly_PolygonOnTriangulation), TColStd_MapTransientHasher> myNodes;
- Standard_Boolean myWithTriangles;
};
#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>
+
+Standard_CString BinTools_ShapeSetBase::Version_1 = "Open CASCADE Topology V1 (c)";
+Standard_CString BinTools_ShapeSetBase::Version_2 = "Open CASCADE Topology V2 (c)";
+Standard_CString BinTools_ShapeSetBase::Version_3 = "Open CASCADE Topology V3 (c)";
+
+//=======================================================================
+//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 (const Standard_Boolean theWithTriangles)
+ : myFormatNb (BinTools_FormatVersion_CURRENT), myWithTriangles (theWithTriangles)
+{}
+
+//=======================================================================
+//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_VERSION_1 ||
+ theFormatNb == BinTools_FormatVersion_VERSION_2 ||
+ theFormatNb == BinTools_FormatVersion_VERSION_3,
+ "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);
+
+//! A base class for all readers/writers of TopoDS_Shape into/from stream.
+class BinTools_ShapeSetBase
+{
+public:
+
+ DEFINE_STANDARD_ALLOC
+
+
+ //! A default constructor..
+ //! Parameter <theWithTriangles> is added for XML Persistence
+ Standard_EXPORT BinTools_ShapeSetBase (const Standard_Boolean theWithTriangles = Standard_False);
+
+ Standard_EXPORT virtual ~BinTools_ShapeSetBase();
+
+ //! Return true if shape should be stored with triangles.
+ Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
+
+ //! 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; }
+
+ //! 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 Standard_CString Version_1;
+ static Standard_CString Version_2;
+ static Standard_CString Version_3;
+
+private:
+
+ Standard_Integer myFormatNb;
+ Standard_Boolean myWithTriangles;
+};
+
+#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 (const Standard_Boolean theWithTriangles)
+ : BinTools_ShapeSetBase (theWithTriangles)
+{}
+
+//=======================================================================
+//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());
+ 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());
+ }
+ else
+ theStream << (Standard_Byte)1;
+ }
+ else
+ theStream << (Standard_Byte)0;//without triangulation
+ }
+ break;
+ }
+ }
+ 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)
+{
+ 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::PutReal (theStream, theTriangulation->Deflection());
+ // write the 3d nodes
+ const TColgp_Array1OfPnt& aNodes = theTriangulation->Nodes();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ theStream << aNodes.Value (aNodeIter);
+ if (theTriangulation->HasUVNodes())
+ {
+ const TColgp_Array1OfPnt2d& aUVNodes = theTriangulation->UVNodes();
+ for (Standard_Integer aNodeIter = 1; aNodeIter <= aNbNodes; ++aNodeIter)
+ {
+ const gp_Pnt2d aUV = aUVNodes.Value (aNodeIter);
+ BinTools::PutReal (theStream, aUV.X());
+ BinTools::PutReal (theStream, aUV.Y());
+ }
+ }
+ const Poly_Array1OfTriangle& aTriangles = theTriangulation->Triangles();
+ for (Standard_Integer aTriIter = 1; aTriIter <= aNbTriangles; ++aTriIter)
+ {
+ const Poly_Triangle& aTri = aTriangles.Value (aTriIter);
+ BinTools::PutInteger (theStream, aTri.Value (1));
+ BinTools::PutInteger (theStream, aTri.Value (2));
+ BinTools::PutInteger (theStream, aTri.Value (3));
+ }
+ 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 <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 (const Standard_Boolean theWithTriangles = Standard_False);
+
+ 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);
+
+ /// 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_Curve2dSet.hxx
BinTools_CurveSet.cxx
BinTools_CurveSet.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
mySubTrees.Clear();
}
+PCDM_ReaderFilter::~PCDM_ReaderFilter()
+{
+ ClearTree();
+}
+
Standard_Boolean PCDM_ReaderFilter::IsPassed (const Handle(Standard_Type)& theAttributeID) const
{
return IsPassedAttr(theAttributeID->Name());
{
if (mySubTrees.IsEmpty())
return true;
- NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees);
- for (; anEntry.More(); anEntry.Next()) {
+ for (NCollection_List<TCollection_AsciiString>::Iterator anEntry (mySubTrees); anEntry.More(); anEntry.Next())
+ {
if (theEntry.StartsWith (anEntry.Value()))
{
- if (theEntry.Length() > anEntry.Value().Length() && // case when theEntry="0:10" should not match "0:1"
- theEntry.Value (anEntry.Value().Length() + 1) != ':')
+ 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();
+}
//! 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()); }
+ 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); }
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 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
+ //! Append mode for reading files into existing document
AppendMode myAppend;
- // Class names of attributes that must be skipped during the read
+ //! 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)
+ //! 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.
+ //! 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
TDocStd_FormatVersion_VERSION_10, //!< OCCT 7.2.0
//!< * BIN: ReadTOC changed to handle 64-bit file length [#0028736]
- TDocStd_FormatVersion_CURRENT = TDocStd_FormatVersion_VERSION_10 //!< The latest version
+ TDocStd_FormatVersion_VERSION_11, //!< OCCT 7.6.0
+ //!< * BIN: New binary format for fast reading part of OCAF document [#0031918]
+
+ TDocStd_FormatVersion_CURRENT = TDocStd_FormatVersion_VERSION_11 //!< The latest version
};
#endif // _TDocStdFormatVersion_HeaderFile
--- /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"
+}