Information about normals are stored in BinOCAF, XmlOCAF, BRep and BBRep (in case of triangulation-only Faces).
Versions of formats have been changed (11 for TDocStd, 4 for BRep Shape and 3 for Binary BRep Shape)
theWithNormals parameter added to BRepTools::Write()
IsWithNormals()/SetWithNormals() function added to BRepTools_ShapeSet
-normals/-noNormals option added to StoreTriangulation DRAW command
-normals/-noNormals option added to writebrep DRAW command
Tests for writing to brep/binary brep/BinXCaf/XmlXCaf added
Test for StoreTriangulation options -normals/-noNormals added
* \<flag\>: = "0" | "1";
* \<int\>: It is an integer number from -2<sup>31</sup> to 2<sup>31</sup>-1 which is written in denary system;
* \<real\>: It is a real from -1.7976931348623158 @f$\cdot@f$ 10<sup>308</sup> to 1.7976931348623158 @f$\cdot@f$ 10<sup>308</sup> which is written in decimal or E form with base 10.The point is used as a delimiter of the integer and fractional parts;
+ * \<short real\>: It is a real from -3.402823 @f$\cdot@f$ 10<sup>38</sup> to 3.402823 @f$\cdot@f$ 10<sup>38</sup> which is written in decimal or E form with base 10.The point is used as a delimiter of the integer and fractional parts;
* \<2D point\>: = \<real\>\<_\>\<real\>;
* \<3D point\>: = \<real\>(\<_\>\<real)\><sup>2</sup>;
* \<2D direction\>: It is a \<2D point\> *x y* so that *x<sup>2</sup> + y<sup>2</sup>* = 1;
\<content type\> = "DBRep_DrawableShape" \<_\\n\>\<_\\n\>;
\<content type\> have other values [1].
- \<version\> = ("CASCADE Topology V1, (c) Matra-Datavision" | "CASCADE Topology V2, (c) Matra-Datavision")\<_\\n\>;
+ \<version\> = ("CASCADE Topology V1, (c) Matra-Datavision" | "CASCADE Topology V2, (c) Matra-Datavision" | "CASCADE Topology V3, (c) Open Cascade")\<_\\n\>;
The difference of the versions is described in the document.
Sections \<locations\>, \<geometry\> and \<shapes\> are described below in separate chapters of the document.
<triangulation records> = <triangulation record> ^ <triangulation count>;
- <triangulation record> = <triangulation node count> <_> <triangulation triangle count> <_> <triangulation parameter presence flag> <_> <triangulation deflection> <_\n>
- <triangulation nodes> [<_> <triangulation u v parameters>] <_> <triangulation triangles> <_\n>;
+ <triangulation record> = <triangulation node count> <_> <triangulation triangle count> <_> <triangulation parameter presence flag> [<_> <need to write normals flag>] <_> <triangulation deflection> <_\n>
+ <triangulation nodes> [<_> <triangulation u v parameters>] <_> <triangulation triangles> [<_> <triangulation normals>] <_\n>;
<triangulation node count> = <int>;
<triangulation parameter presence flag> = <flag>;
+ <need to write normals flag> = <flag>;
+
<triangulation deflection> = <real>;
<triangulation nodes> = (<triangulation node> <_>) ^ <triangulation node count>;
<triangulation triangles> = (<triangulation triangle> <_>) ^ <triangulation triangle count>;
- <triangulation triangle> = <int> <_> <int> <_> <int>.
+ <triangulation triangle> = <int> <_> <int> <_> <int>;
+
+ <triangulation normals> = (<triangulation normal> <_>) ^ <triangulation node count> ^ 3;
+
+ <triangulation normal> = <short real>.
~~~~
**Description**
+
+\<triangulation u v parameters\> are used in version 2 or later.
+\<need to write normals flag\> and \<triangulation normals\> are used in version 3.
\<triangulation record\> describes a triangulation *T* which approximates a surface *S*. The triangulation data consist of a node count @f$ m \geq 3 @f$, a triangle count @f$ k \geq 1 @f$, a parameter presence flag *p*, a deflection @f$ d \geq 0 @f$, nodes @f$ N_{i}\; (1\leq i \leq m) @f$, parameter pairs @f$ u_{i}\; v_{i}\; (1\leq i \leq m) @f$, triangles @f$ n_{j,1}\; n_{j,2}\; n_{j,3}\; (1\leq j \leq k,\; n_{j,l} \in \left \{1,...,m \right \}\; (1\leq l\leq 3)) @f$. The parameters are present only if *p*=1. The deflection describes the triangulation deflection from the surface:
* @f$ f_{1} @f$ -- free;
* @f$ f_{2} @f$ -- modified;
- * @f$ f_{3} @f$ -- IGNORED(version 1) \\ checked (version 2);
+ * @f$ f_{3} @f$ -- IGNORED(version 1 only) \\ checked (version 2 or later);
* @f$ f_{4} @f$ -- orientable;
* @f$ f_{5} @f$ -- closed;
* @f$ f_{6} @f$ -- infinite;
\<edge data representation data 1\> describes a 3D curve.
\<edge data representation data 2\> describes a 2D curve on a surface.
-\<curve values for parameter minimal and maximal values\> are used only in version 2.
+\<curve values for parameter minimal and maximal values\> are used in version 2 or later.
\<edge data representation data 3\> describes a 2D curve on a closed surface.
-\<curve values for parameter minimal and maximal values\> are used only in version 2.
+\<curve values for parameter minimal and maximal values\> are used in version 2 or later.
\<edge data representation data 5\> describes a 3D polyline.
@subsection upgrade_760_createdocument New OCAF document
A new OCAF document may be created only by means of the method *NewDocument()* from CDF_Application (redefined in TDocStd_Application). The methods *CreateDocument()* are deleted in all retrieval drivers.
+
+@subsection upgrade_760_changesInStorageOfShapes Changes in storage of shapes
+
+Information about per-vertex triangulations normals is now stored in BinOCAF and XmlOCAF document,
+BRep and Binary BRep Shape formats (only in case of triangulation-only Faces, with no analytical geometry to restore normals).
+
+Versions of formats have been changed (11 for BinOCAF, 10 for XmlOCAF, 4 for BRep Shape and 3 for Binary BRep Shape).
+Files written with the new version will not be readable by applications of old versions.
void BRepTools::Write (const TopoDS_Shape& theShape,
Standard_OStream& theStream,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const TopTools_FormatVersion theVersion,
const Message_ProgressRange& theProgress)
{
- BRepTools_ShapeSet aShapeSet (theWithTriangles);
+ BRepTools_ShapeSet aShapeSet (theWithTriangles, theWithNormals);
aShapeSet.SetFormatNb (theVersion);
aShapeSet.Add (theShape);
aShapeSet.Write (theStream, theProgress);
Standard_Boolean BRepTools::Write (const TopoDS_Shape& theShape,
const Standard_CString theFile,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const TopTools_FormatVersion theVersion,
const Message_ProgressRange& theProgress)
{
if(!isGood)
return isGood;
- BRepTools_ShapeSet SS (theWithTriangles);
+ BRepTools_ShapeSet SS (theWithTriangles, theWithNormals);
SS.SetFormatNb (theVersion);
SS.Add (theShape);
Standard_OStream& theStream,
const Message_ProgressRange& theProgress = Message_ProgressRange())
{
- Write (theShape, theStream, Standard_True,
- TopTools_FormatVersion_VERSION_1, theProgress);
+ Write (theShape, theStream, Standard_True, Standard_False,
+ TopTools_FormatVersion_CURRENT, theProgress);
}
//! Writes the shape to the stream in an ASCII format of specified version.
//! @param theStream [in][out] the stream to output shape into
//! @param theWithTriangles [in] flag which specifies whether to save shape with (TRUE) or without (FALSE) triangles;
//! has no effect on triangulation-only geometry
+ //! @param theWithNormals [in] flag which specifies whether to save triangulation with (TRUE) or without (FALSE) normals;
+ //! has no effect on triangulation-only geometry
//! @param theVersion [in] the TopTools format version
//! @param theRange the range of progress indicator to fill in
Standard_EXPORT static void Write (const TopoDS_Shape& theShape,
Standard_OStream& theStream,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const TopTools_FormatVersion theVersion,
const Message_ProgressRange& theProgress = Message_ProgressRange());
const Standard_CString theFile,
const Message_ProgressRange& theProgress = Message_ProgressRange())
{
- return Write (theShape, theFile, Standard_True,
- TopTools_FormatVersion_VERSION_1, theProgress);
+ return Write (theShape, theFile, Standard_True, Standard_False,
+ TopTools_FormatVersion_CURRENT, theProgress);
}
//! Writes the shape to the file in an ASCII format of specified version.
//! @param theFile [in] the path to file to output shape into
//! @param theWithTriangles [in] flag which specifies whether to save shape with (TRUE) or without (FALSE) triangles;
//! has no effect on triangulation-only geometry
+ //! @param theWithNormals [in] flag which specifies whether to save triangulation with (TRUE) or without (FALSE) normals;
+ //! has no effect on triangulation-only geometry
//! @param theVersion [in] the TopTools format version
//! @param theRange the range of progress indicator to fill in
Standard_EXPORT static Standard_Boolean Write (const TopoDS_Shape& theShape,
const Standard_CString theFile,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const TopTools_FormatVersion theVersion,
const Message_ProgressRange& theProgress = Message_ProgressRange());
//function : BRepTools_ShapeSet
//purpose :
//=======================================================================
-BRepTools_ShapeSet::BRepTools_ShapeSet (const Standard_Boolean theWithTriangles)
-: myWithTriangles (theWithTriangles)
+BRepTools_ShapeSet::BRepTools_ShapeSet (const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals)
+: myWithTriangles (theWithTriangles),
+ myWithNormals (theWithNormals)
{
}
//purpose :
//=======================================================================
BRepTools_ShapeSet::BRepTools_ShapeSet (const BRep_Builder& theBuilder,
- const Standard_Boolean theWithTriangles)
+ const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals)
: myBuilder (theBuilder),
- myWithTriangles (theWithTriangles)
+ myWithTriangles (theWithTriangles),
+ myWithNormals(theWithNormals)
{
}
}
}
else if (CR->IsPolygonOnTriangulation()) {
- myTriangulations.Add(CR->Triangulation());
+ // NCollection_IndexedDataMap::Add() function use is correct because
+ // Bin(Brep)Tools_ShapeSet::AddGeometry() is called from Bin(Brep)Tools_ShapeSet::Add()
+ // that processes shapes recursively from complex to elementary ones.
+ // As a result, the TopAbs_FACE's will be processed earlier than the TopAbs_EDGE's.
+ myTriangulations.Add(CR->Triangulation(), Standard_False); // edge triangulation does not need normals
myNodes.Add(CR->PolygonOnTriangulation());
ChangeLocations().Add(CR->Location());
if (CR->IsPolygonOnClosedTriangulation())
else if (S.ShapeType() == TopAbs_FACE) {
// Add the surface geometry
+ Standard_Boolean needNormals(myWithNormals);
Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
- if (!TF->Surface().IsNull()) mySurfaces.Add(TF->Surface());
-
+ if (!TF->Surface().IsNull())
+ {
+ mySurfaces.Add(TF->Surface());
+ }
+ else
+ {
+ needNormals = Standard_True;
+ }
if (myWithTriangles || TF->Surface().IsNull()) { // for XML Persistence
Handle(Poly_Triangulation) Tr = TF->Triangulation();
- if (!Tr.IsNull()) myTriangulations.Add(Tr);
+ if (!Tr.IsNull()) myTriangulations.Add(Tr, needNormals);
}
ChangeLocations().Add(TF->Location());
myBuilder.UpdateEdge
(E, Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt)),
Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt2)),
- Handle(Poly_Triangulation)::DownCast(myTriangulations(t)),
+ myTriangulations.FindKey(t),
Locations().Location(l));
}
else {
pt > 0 && pt <= myNodes.Extent())
myBuilder.UpdateEdge
(E,Handle(Poly_PolygonOnTriangulation)::DownCast(myNodes(pt)),
- Handle(Poly_Triangulation)::DownCast(myTriangulations(t)),
+ myTriangulations.FindKey(t),
Locations().Location(l));
}
// range
//only triangulation
IS >> s;
myBuilder.UpdateFace(TopoDS::Face(S),
- Handle(Poly_Triangulation)::DownCast(myTriangulations(s)));
+ myTriangulations.FindKey(s));
}
// else pos = IS.tellg();
s = atoi ( &string[2] );
if (s > 0 && s <= myTriangulations.Extent())
myBuilder.UpdateFace(TopoDS::Face(S),
- Handle(Poly_Triangulation)::DownCast(myTriangulations(s)));
+ myTriangulations.FindKey(s));
}
// else IS.seekg(pos);
}
Handle(Poly_Triangulation) T;
for (i = 1; i <= nbtri && aPS.More(); i++, aPS.Next()) {
- T = Handle(Poly_Triangulation)::DownCast(myTriangulations(i));
+ T = myTriangulations.FindKey(i);
+ const Standard_Boolean toWriteNormals = myTriangulations(i);
if (Compact) {
OS << T->NbNodes() << " " << T->NbTriangles() << " ";
OS << ((T->HasUVNodes()) ? "1" : "0") << " ";
+ if (FormatNb() >= TopTools_FormatVersion_VERSION_3)
+ {
+ OS << ((T->HasNormals() && toWriteNormals) ? "1" : "0") << " ";
+ }
}
else {
OS << " "<< i << " : Triangulation with " << T->NbNodes() << " Nodes and "
<< T->NbTriangles() <<" Triangles\n";
OS << " "<<((T->HasUVNodes()) ? "with" : "without") << " UV nodes\n";
-
+ if (FormatNb() >= TopTools_FormatVersion_VERSION_3)
+ {
+ OS << " " << ((T->HasNormals() && toWriteNormals) ? "with" : "without") << " normals\n";
+ }
}
// write the deflection
if (!Compact) OS << "\n";
else OS << " ";
}
+
+ if (FormatNb() >= TopTools_FormatVersion_VERSION_3)
+ {
+ if (T->HasNormals() && toWriteNormals)
+ {
+ if (!Compact) OS << "\nNormals :\n";
+ const TShort_Array1OfShortReal& Normals = T->Normals();
+ for (j = 1; j <= nbNodes * 3; j++)
+ {
+ if (!Compact)
+ {
+ OS << std::setw(10) << j << " : ";
+ OS << std::setw(17);
+ }
+ OS << Normals(j) << " ";
+ if (!Compact)
+ {
+ OS << "\n";
+ }
+ else
+ {
+ OS << " ";
+ }
+ }
+ }
+ }
OS << "\n";
}
}
// Standard_Integer i, j, val, nbtri;
Standard_Integer i, j, nbtri =0;
Standard_Real d, x, y, z;
+ Standard_Real normal;
Standard_Integer nbNodes =0, nbTriangles=0;
Standard_Boolean hasUV= Standard_False;
+ Standard_Boolean hasNormals= Standard_False;
Handle(Poly_Triangulation) T;
for (i=1; i<=nbtri && aPS.More();i++, aPS.Next()) {
IS >> nbNodes >> nbTriangles >> hasUV;
+ if (FormatNb() >= TopTools_FormatVersion_VERSION_3)
+ {
+ IS >> hasNormals;
+ }
GeomTools::GetReal(IS, d);
TColgp_Array1OfPnt Nodes(1, nbNodes);
TColgp_Array1OfPnt2d UVNodes(1, nbNodes);
-
+ Handle(TShort_HArray1OfShortReal) Normals;
+ if (hasNormals)
+ {
+ Normals = new TShort_HArray1OfShortReal(1, nbNodes * 3);
+ }
for (j = 1; j <= nbNodes; j++) {
GeomTools::GetReal(IS, x);
GeomTools::GetReal(IS, y);
IS >> n1 >> n2 >> n3;
Triangles(j).Set(n1,n2,n3);
}
-
+
+ if (hasNormals)
+ {
+ for (j = 1; j <= nbNodes * 3; j++)
+ {
+ GeomTools::GetReal(IS, normal);
+ Normals->SetValue(j, static_cast<Standard_ShortReal>(normal));
+ }
+ }
+
if (hasUV) T = new Poly_Triangulation(Nodes,UVNodes,Triangles);
else T = new Poly_Triangulation(Nodes,Triangles);
T->Deflection(d);
-
- myTriangulations.Add(T);
+ if (hasNormals)
+ {
+ T->SetNormals(Normals);
+ }
+ myTriangulations.Add(T, hasNormals);
}
}
//! Builds an empty ShapeSet.
//! @param theWithTriangles flag to write triangulation data
- Standard_EXPORT BRepTools_ShapeSet (const Standard_Boolean theWithTriangles = Standard_True);
+ Standard_EXPORT BRepTools_ShapeSet (const Standard_Boolean theWithTriangles = Standard_True,
+ const Standard_Boolean theWithNormals = Standard_False);
//! Builds an empty ShapeSet.
//! @param theWithTriangles flag to write triangulation data
Standard_EXPORT BRepTools_ShapeSet (const BRep_Builder& theBuilder,
- const Standard_Boolean theWithTriangles = Standard_True);
+ const Standard_Boolean theWithTriangles = Standard_True,
+ const Standard_Boolean theWithNormals = Standard_False);
Standard_EXPORT virtual ~BRepTools_ShapeSet();
//! Return true if shape should be stored with triangles.
Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
+ //! Return true if shape should be stored triangulation with normals.
+ Standard_Boolean IsWithNormals() const { return myWithNormals; }
//! Define if shape will be stored with triangles.
//! Ignored (always written) if face defines only triangulation (no surface).
void SetWithTriangles (const Standard_Boolean theWithTriangles) { myWithTriangles = theWithTriangles; }
+ //! Define if shape will be stored triangulation with normals.
+ //! Ignored (always written) if face defines only triangulation (no surface).
+ void SetWithNormals (const Standard_Boolean theWithNormals) { myWithNormals = theWithNormals; }
//! Clears the content of the set.
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
GeomTools_Curve2dSet myCurves2d;
TColStd_IndexedMapOfTransient myPolygons2D;
TColStd_IndexedMapOfTransient myPolygons3D;
- TColStd_IndexedMapOfTransient myTriangulations;
+ NCollection_IndexedDataMap<Handle(Poly_Triangulation),
+ Standard_Boolean> myTriangulations; //!< Contains a boolean flag with information
+ //! to save normals for triangulation
TColStd_IndexedMapOfTransient myNodes;
Standard_Boolean myWithTriangles;
+ Standard_Boolean myWithNormals;
};
aShapesDriver->SetWithTriangles (theWithTriangulation);
}
+//=======================================================================
+//function : IsWithNormals
+//purpose :
+//=======================================================================
+Standard_Boolean BinDrivers_DocumentStorageDriver::IsWithNormals() const
+{
+ if (myDrivers.IsNull())
+ {
+ return Standard_False;
+ }
+
+ Handle(BinMDF_ADriver) aDriver;
+ myDrivers->GetDriver(STANDARD_TYPE(TNaming_NamedShape), aDriver);
+ Handle(BinMNaming_NamedShapeDriver) aShapesDriver = Handle(BinMNaming_NamedShapeDriver)::DownCast(aDriver);
+ return !aShapesDriver.IsNull()
+ && aShapesDriver->IsWithNormals();
+}
+
+//=======================================================================
+//function : SetWithNormals
+//purpose :
+//=======================================================================
+void BinDrivers_DocumentStorageDriver::SetWithNormals(const Handle(Message_Messenger)& theMessageDriver,
+ const Standard_Boolean theWithNormals)
+{
+ 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->SetWithNormals(theWithNormals);
+}
+
//=======================================================================
//function : WriteShapeSection
//purpose : Implements WriteShapeSection
void BinDrivers_DocumentStorageDriver::WriteShapeSection
(BinLDrivers_DocumentSection& theSection,
Standard_OStream& theOS,
- const Standard_Integer theDocVer,
+ const TDocStd_FormatVersion theDocVer,
const Message_ProgressRange& theRange)
{
const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp();
OCC_CATCH_SIGNALS
Handle(BinMNaming_NamedShapeDriver) aNamedShapeDriver =
Handle(BinMNaming_NamedShapeDriver)::DownCast (aDriver);
- aNamedShapeDriver->WriteShapeSection (theOS, theRange);
+ aNamedShapeDriver->WriteShapeSection (theOS, theDocVer, theRange);
}
catch(Standard_Failure const& anException) {
TCollection_ExtendedString anErrorStr ("BinDrivers_DocumentStorageDriver, Shape Section :");
Standard_EXPORT virtual void WriteShapeSection
(BinLDrivers_DocumentSection& theDocSection,
Standard_OStream& theOS,
- const Standard_Integer theDocVer,
+ const TDocStd_FormatVersion theDocVer,
const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
//! Return true if shape should be stored with triangles.
Standard_EXPORT Standard_Boolean IsWithTriangles() const;
+ //! Return true if shape should be stored with triangulation normals.
+ Standard_EXPORT Standard_Boolean IsWithNormals() const;
//! Set if triangulation should be stored or not.
Standard_EXPORT void SetWithTriangles (const Handle(Message_Messenger)& theMessageDriver,
const Standard_Boolean theWithTriangulation);
+ //! Set if triangulation should be stored with normals or not.
+ Standard_EXPORT void SetWithNormals(const Handle(Message_Messenger)& theMessageDriver,
+ const Standard_Boolean theWithTriangulation);
DEFINE_STANDARD_RTTIEXT(BinDrivers_DocumentStorageDriver,BinLDrivers_DocumentStorageDriver)
myReaderStatus = PCDM_RS_FormatFailure;
return;
}
- Standard_Integer aFileVer = aHeaderData->StorageVersion().IntegerValue();
- Standard_Integer aCurrVer = TDocStd_Document::CurrentStorageFormatVersion();
+ TDocStd_FormatVersion aFileVer = static_cast<TDocStd_FormatVersion>(aHeaderData->StorageVersion().IntegerValue());
+ TDocStd_FormatVersion aCurrVer = TDocStd_Document::CurrentStorageFormatVersion();
// maintain one-way compatibility starting from version 2+
if (!CheckDocumentVersion(aFileVer, aCurrVer)) {
myReaderStatus = PCDM_RS_NoVersion;
const Standard_Integer theFileVersion,
const Standard_Integer theCurVersion)
{
- if (theFileVersion < TDocStd_FormatVersion_VERSION_2 || theFileVersion > theCurVersion) {
+ if (theFileVersion < TDocStd_FormatVersion_LOWER || theFileVersion > theCurVersion) {
// file was written with another version
return Standard_False;
}
//=======================================================================
void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream,
- const Standard_Integer theDocFormatVersion)
+ const TDocStd_FormatVersion theDocFormatVersion)
{
char aBuf[512];
void BinLDrivers_DocumentSection::Write (Standard_OStream& theStream,
const uint64_t theOffset,
- const Standard_Integer theDocFormatVersion)
+ const TDocStd_FormatVersion theDocFormatVersion)
{
const uint64_t aSectionEnd = (uint64_t) theStream.tellp();
theStream.seekp((std::streamsize)myValue[0]);
void BinLDrivers_DocumentSection::ReadTOC
(BinLDrivers_DocumentSection& theSection,
Standard_IStream& theStream,
- const Standard_Integer theDocFormatVersion)
+ const TDocStd_FormatVersion theDocFormatVersion)
{
char aBuf[512];
Standard_Integer aNameBufferSize;
#include <Standard_OStream.hxx>
#include <Standard_IStream.hxx>
#include <Message_ProgressIndicator.hxx>
+#include <TDocStd_FormatVersion.hxx>
class TCollection_AsciiString;
//! Create a Section entry in the Document TOC (list of sections)
Standard_EXPORT void WriteTOC (Standard_OStream& theOS,
- const Standard_Integer theDocFormatVersion);
+ const TDocStd_FormatVersion theDocFormatVersion);
//! Save Offset and Length data into the Section entry
//! in the Document TOC (list of sections)
Standard_EXPORT void Write (Standard_OStream& theOS, const uint64_t theOffset,
- const Standard_Integer theDocFormatVersion);
+ const TDocStd_FormatVersion theDocFormatVersion);
//! Fill a DocumentSection instance from the data that are read
//! from TOC.
Standard_EXPORT static void ReadTOC (BinLDrivers_DocumentSection& theSection, Standard_IStream& theIS,
- const Standard_Integer theDocFormatVersion);
+ const TDocStd_FormatVersion theDocFormatVersion);
}
// 2. Write the Table of Contents of Sections
- const Standard_Integer aDocVer = aDoc->StorageFormatVersion();
+ const TDocStd_FormatVersion aDocVer = aDoc->StorageFormatVersion();
BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
for (; anIterS.More(); anIterS.Next())
anIterS.ChangeValue().WriteTOC (theOStream, aDocVer);
void BinLDrivers_DocumentStorageDriver::WriteShapeSection
(BinLDrivers_DocumentSection& theSection,
Standard_OStream& theOS,
- const Standard_Integer theDocVer,
+ const TDocStd_FormatVersion theDocVer,
const Message_ProgressRange& /*theRange*/)
{
const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp();
#include <Standard_OStream.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Type.hxx>
+#include <TDocStd_FormatVersion.hxx>
class BinMDF_ADriverTable;
class Message_Messenger;
class TCollection_ExtendedString;
//! defines the procedure of writing a shape section to file
Standard_EXPORT virtual void WriteShapeSection (BinLDrivers_DocumentSection& theDocSection,
Standard_OStream& theOS,
- const Standard_Integer theDocVer,
+ const TDocStd_FormatVersion theDocVer,
const Message_ProgressRange& theRange = Message_ProgressRange());
Handle(BinMDF_ADriverTable) myDrivers;
#include <TCollection_AsciiString.hxx>
#include <TDF_Attribute.hxx>
#include <TDF_Label.hxx>
+#include <TDocStd_FormatVersion.hxx>
#include <TNaming_Builder.hxx>
#include <TNaming_Evolution.hxx>
#include <TNaming_Iterator.hxx>
BinMNaming_NamedShapeDriver::BinMNaming_NamedShapeDriver
(const Handle(Message_Messenger)& theMsgDriver)
-: BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name()),
- myShapeSet (Standard_False),
- myFormatNb (BinTools_FormatVersion_VERSION_1)
+: BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TNaming_NamedShape)->Name())
{
}
//=======================================================================
void BinMNaming_NamedShapeDriver::WriteShapeSection (Standard_OStream& theOS,
+ const Standard_Integer theDocVer,
const Message_ProgressRange& theRange)
{
theOS << SHAPESET;
- myShapeSet.SetFormatNb(myFormatNb);
+ if (theDocVer >= TDocStd_FormatVersion_VERSION_11)
+ {
+ myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_4);
+ }
+ else
+ {
+ myShapeSet.SetFormatNb(BinTools_FormatVersion_VERSION_1);
+ }
+
myShapeSet.Write (theOS, theRange);
myShapeSet.Clear();
}
if(aSectionTitle.Length() > 0 && aSectionTitle == SHAPESET) {
myShapeSet.Clear();
myShapeSet.Read (theIS, theRange);
- SetFormatNb(myShapeSet.FormatNb());
}
else
theIS.seekg(aPos); // no shape section is present, try to return to initial point
const Message_ProgressRange& therange = Message_ProgressRange());
//! Output the shapes into Bin Document file
- Standard_EXPORT void WriteShapeSection (Standard_OStream& theOS,
- const Message_ProgressRange& therange = Message_ProgressRange());
+ Standard_EXPORT void WriteShapeSection(Standard_OStream& theOS,
+ const Standard_Integer theDocVer,
+ const Message_ProgressRange& therange = Message_ProgressRange());
//! Clear myShapeSet
Standard_EXPORT void Clear();
//! Return true if shape should be stored with triangles.
Standard_Boolean IsWithTriangles() const { return myShapeSet.IsWithTriangles(); }
+ //! Return true if shape should be stored with triangulation normals.
+ Standard_Boolean IsWithNormals() const { return myShapeSet.IsWithNormals(); }
//! set whether to store triangulation
- void SetWithTriangles (const Standard_Boolean isWithTriangles);
-
- //! set the format of topology
- //! 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 SetWithTriangles (const Standard_Boolean isWithTriangles) { myShapeSet.SetWithTriangles(isWithTriangles); }
+ //! set whether to store triangulation with normals
+ void SetWithNormals (const Standard_Boolean isWithNormals) { myShapeSet.SetWithNormals(isWithNormals); }
- //! get the format of topology
- Standard_Integer GetFormatNb() const;
- //! get the format of topology
- BinTools_LocationSet& GetShapesLocations();
+ //! get the shapes locations
+ BinTools_LocationSet& GetShapesLocations();
BinTools_ShapeSet myShapeSet;
- Standard_Integer myFormatNb;
-
};
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-//=======================================================================
-//function : GetFormat
-//purpose :
-//=======================================================================
-
-inline Standard_Integer BinMNaming_NamedShapeDriver::GetFormatNb() const
-{
- return myFormatNb;
-}
-
-//=======================================================================
-//function : SetFormat
-//purpose :
-//=======================================================================
-
-inline void BinMNaming_NamedShapeDriver::SetFormatNb(const Standard_Integer theFormatNb)
-{
- myFormatNb = theFormatNb;
-}
-
-//=======================================================================
-//function : SetWithTriangles
-//purpose :
-//=======================================================================
-
-inline void BinMNaming_NamedShapeDriver::SetWithTriangles(const Standard_Boolean isWithTriangles)
-{
- myShapeSet.SetWithTriangles(isWithTriangles);
-}
//=======================================================================
//function : GetShapesLocations
void BinTools::Write (const TopoDS_Shape& theShape,
Standard_OStream& theStream,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const BinTools_FormatVersion theVersion,
const Message_ProgressRange& theRange)
{
- BinTools_ShapeSet aShapeSet (theWithTriangles);
+ BinTools_ShapeSet aShapeSet;
+ aShapeSet.SetWithTriangles(theWithTriangles);
+ aShapeSet.SetWithNormals(theWithNormals);
aShapeSet.SetFormatNb (theVersion);
aShapeSet.Add (theShape);
aShapeSet.Write (theStream, theRange);
void BinTools::Read (TopoDS_Shape& theShape, Standard_IStream& theStream,
const Message_ProgressRange& theRange)
{
- BinTools_ShapeSet aShapeSet(Standard_True);
+ BinTools_ShapeSet aShapeSet;
+ aShapeSet.SetWithTriangles(Standard_True);
aShapeSet.Read (theStream, theRange);
aShapeSet.Read (theShape, theStream, aShapeSet.NbShapes());
}
Standard_Boolean BinTools::Write (const TopoDS_Shape& theShape,
const Standard_CString theFile,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const BinTools_FormatVersion theVersion,
const Message_ProgressRange& theRange)
{
if (!aStream.good())
return Standard_False;
- Write (theShape, aStream, theWithTriangles, theVersion, theRange);
+ Write (theShape, aStream, theWithTriangles, theWithNormals, theVersion, theRange);
aStream.close();
return aStream.good();
}
Standard_OStream& theStream,
const Message_ProgressRange& theRange = Message_ProgressRange())
{
- Write (theShape, theStream, Standard_True,
+ Write (theShape, theStream, Standard_True, Standard_False,
BinTools_FormatVersion_CURRENT, theRange);
}
//! @param theStream [in][out] the stream to output shape into
//! @param theWithTriangles [in] flag which specifies whether to save shape with (TRUE) or without (FALSE) triangles;
//! has no effect on triangulation-only geometry
+ //! @param theWithNormals [in] flag which specifies whether to save triangulation with (TRUE) or without (FALSE) normals;
+ //! has no effect on triangulation-only geometry
//! @param theVersion [in] the BinTools format version
//! @param theRange the range of progress indicator to fill in
Standard_EXPORT static void Write(const TopoDS_Shape& theShape, Standard_OStream& theStream,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const BinTools_FormatVersion theVersion,
const Message_ProgressRange& theRange = Message_ProgressRange());
const Standard_CString theFile,
const Message_ProgressRange& theRange = Message_ProgressRange())
{
- return Write (theShape, theFile, Standard_True,
+ return Write (theShape, theFile, Standard_True, Standard_False,
BinTools_FormatVersion_CURRENT, theRange);
}
//! @param theFile [in] the path to file to output shape into
//! @param theWithTriangles [in] flag which specifies whether to save shape with (TRUE) or without (FALSE) triangles;
//! has no effect on triangulation-only geometry
+ //! @param theWithNormals [in] flag which specifies whether to save triangulation with (TRUE) or without (FALSE) normals;
+ //! has no effect on triangulation-only geometry
//! @param theVersion [in] the BinTools format version
//! @param theRange the range of progress indicator to fill in
Standard_EXPORT static Standard_Boolean Write (const TopoDS_Shape& theShape,
const Standard_CString theFile,
const Standard_Boolean theWithTriangles,
+ const Standard_Boolean theWithNormals,
const BinTools_FormatVersion theVersion,
const Message_ProgressRange& theRange = Message_ProgressRange());
//! On reading format is recognized from Version string.
BinTools_FormatVersion_VERSION_3 = 3, //!< (OCCT 6.2.1) Correctly processes geometry with points on Curve,
//! or point on Surface, or points on curve of surface [#0009745]
+ BinTools_FormatVersion_VERSION_4 = 4, //!< Stores per-vertex normal information in case
+ //! of triangulation-only Faces, because
+ //! no analytical geometry to restore normals
+ BinTools_FormatVersion_CURRENT = BinTools_FormatVersion_VERSION_4 //!< Current version
+};
- BinTools_FormatVersion_CURRENT = BinTools_FormatVersion_VERSION_1 //!< The current version.
+enum
+{
+ BinTools_FormatVersion_LOWER = BinTools_FormatVersion_VERSION_1,
+ BinTools_FormatVersion_UPPER = BinTools_FormatVersion_VERSION_4
};
#endif
#include <string.h>
//#define MDTV_DEB 1
-Standard_CString BinTools_ShapeSet::Version_1 = "Open CASCADE Topology V1 (c)";
-Standard_CString BinTools_ShapeSet::Version_2 = "Open CASCADE Topology V2 (c)";
-Standard_CString BinTools_ShapeSet::Version_3 = "Open CASCADE Topology V3 (c)";
+
+const Standard_CString BinTools_ShapeSet::THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1] =
+{
+ "",
+ "Open CASCADE Topology V1 (c)",
+ "Open CASCADE Topology V2 (c)",
+ "Open CASCADE Topology V3 (c)",
+ "Open CASCADE Topology V4, (c) Open Cascade"
+};
//=======================================================================
//function : operator << (gp_Pnt)
//function : BinTools_ShapeSet
//purpose :
//=======================================================================
-BinTools_ShapeSet::BinTools_ShapeSet (const Standard_Boolean theWithTriangles)
+BinTools_ShapeSet::BinTools_ShapeSet ()
: myFormatNb (BinTools_FormatVersion_CURRENT),
- myWithTriangles (theWithTriangles)
+ myWithTriangles (Standard_False),
+ myWithNormals(Standard_False)
{}
//=======================================================================
//=======================================================================
void BinTools_ShapeSet::SetFormatNb(const Standard_Integer theFormatNb)
{
- Standard_ASSERT_RETURN(theFormatNb == BinTools_FormatVersion_VERSION_1 ||
- theFormatNb == BinTools_FormatVersion_VERSION_2 ||
- theFormatNb == BinTools_FormatVersion_VERSION_3,
+ Standard_ASSERT_RETURN(theFormatNb >= BinTools_FormatVersion_LOWER &&
+ theFormatNb <= BinTools_FormatVersion_UPPER,
"Error: unsupported BinTools version.", );
myFormatNb = theFormatNb;
}
}
else if (CR->IsPolygonOnTriangulation()) {
- myTriangulations.Add(CR->Triangulation());
+ // NCollection_IndexedDataMap::Add() function use is correct because
+ // Bin(Brep)Tools_ShapeSet::AddGeometry() is called from Bin(Brep)Tools_ShapeSet::Add()
+ // that processes shapes recursively from complex to elementary ones.
+ // As a result, the TopAbs_FACE's will be processed earlier than the TopAbs_EDGE's.
+ myTriangulations.Add(CR->Triangulation(), Standard_False); // edge triangulation does not need normals
myNodes.Add(CR->PolygonOnTriangulation());
ChangeLocations().Add(CR->Location());
if (CR->IsPolygonOnClosedTriangulation())
else if (S.ShapeType() == TopAbs_FACE) {
// Add the surface geometry
+ Standard_Boolean needNormals(myWithNormals);
Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
- if (!TF->Surface().IsNull()) mySurfaces.Add(TF->Surface());
-
+ if (!TF->Surface().IsNull())
+ {
+ mySurfaces.Add(TF->Surface());
+ }
+ else
+ {
+ needNormals = Standard_True;
+ }
if (myWithTriangles
|| TF->Surface().IsNull())
{
Handle(Poly_Triangulation) Tr = TF->Triangulation();
- if (!Tr.IsNull()) myTriangulations.Add(Tr);
+ if (!Tr.IsNull()) myTriangulations.Add(Tr, needNormals);
}
ChangeLocations().Add(TF->Location());
const Message_ProgressRange& theRange)const
{
// write the copyright
- if (myFormatNb == BinTools_FormatVersion_VERSION_3)
- {
- OS << "\n" << Version_3 << "\n";
- }
- else if (myFormatNb == BinTools_FormatVersion_VERSION_2)
- {
- OS << "\n" << Version_2 << "\n";
- }
- else
- {
- OS << "\n" << Version_1 << "\n";
- }
+ OS << "\n" << THE_ASCII_VERSIONS[myFormatNb] << "\n";
//-----------------------------------------
// write the locations
// Check the version
char vers[101];
+ Standard_Boolean anIsSetFormat = Standard_False;
do {
IS.getline(vers,100,'\n');
// BUC60769 PTV 18.10.2000: remove possible '\r' at the end of the line
for (lv--; lv > 0 && (vers[lv] == '\r' || vers[lv] == '\n'); lv--)
vers[lv] = '\0';
}
-
- } while ( ! IS.fail() && strcmp(vers,Version_1) && strcmp(vers,Version_2) &&
- strcmp(vers,Version_3));
+
+ for (Standard_Integer i = BinTools_FormatVersion_LOWER;
+ i <= BinTools_FormatVersion_UPPER; ++i)
+ {
+ if (!strcmp(vers, THE_ASCII_VERSIONS[i]))
+ {
+ SetFormatNb(i);
+ anIsSetFormat = Standard_True;
+ break;
+ }
+ }
+ if (anIsSetFormat)
+ {
+ break;
+ }
+ }
+ while ( ! IS.fail());
if (IS.fail()) {
std::cout << "BinTools_ShapeSet::Read: File was not written with this version of the topology" << std::endl;
return;
}
- if (strcmp (vers, Version_3) == 0)
- {
- SetFormatNb (BinTools_FormatVersion_VERSION_3);
- }
- else if (strcmp (vers, Version_2) == 0)
- {
- SetFormatNb (BinTools_FormatVersion_VERSION_2);
- }
- else
- {
- SetFormatNb (BinTools_FormatVersion_VERSION_1);
- }
-
//-----------------------------------------
// read the locations
//-----------------------------------------
BinTools::GetInteger(IS, l);
if (closed)
{
- myBuilder.UpdateEdge (E, myNodes(pt), myNodes(pt2), myTriangulations(t), Locations().Location(l));
+ myBuilder.UpdateEdge (E, myNodes(pt), myNodes(pt2), myTriangulations.FindKey(t), Locations().Location(l));
}
else
{
- myBuilder.UpdateEdge (E, myNodes(pt), myTriangulations(t), Locations().Location(l));
+ myBuilder.UpdateEdge (E, myNodes(pt), myTriangulations.FindKey(t), Locations().Location(l));
}
// range
break;
// cas triangulation
if(aByte == 2) {
BinTools::GetInteger(IS, s);
- myBuilder.UpdateFace(TopoDS::Face(S), myTriangulations(s));
+ myBuilder.UpdateFace(TopoDS::Face(S), myTriangulations.FindKey(s));
}
}
break;
for (Standard_Integer aTriangulationIter = 1; aTriangulationIter <= aNbTriangulations && aPS.More(); ++aTriangulationIter, aPS.Next())
{
const Handle(Poly_Triangulation)& aTriangulation = myTriangulations.FindKey (aTriangulationIter);
+ Standard_Boolean NeedToWriteNormals = myTriangulations.FindFromIndex(aTriangulationIter);
const Standard_Integer aNbNodes = aTriangulation->NbNodes();
const Standard_Integer aNbTriangles = aTriangulation->NbTriangles();
BinTools::PutInteger(OS, aNbNodes);
BinTools::PutInteger(OS, aNbTriangles);
BinTools::PutBool(OS, aTriangulation->HasUVNodes() ? 1 : 0);
+ if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+ {
+ BinTools::PutBool(OS, (aTriangulation->HasNormals() && NeedToWriteNormals) ? 1 : 0);
+ }
BinTools::PutReal(OS, aTriangulation->Deflection());
// write the 3d nodes
BinTools::PutInteger(OS, aTri.Value (2));
BinTools::PutInteger(OS, aTri.Value (3));
}
+
+ // write the normals
+ if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+ {
+ if (aTriangulation->HasNormals() && NeedToWriteNormals)
+ {
+ const TShort_Array1OfShortReal& aNormals = aTriangulation->Normals();
+ for (Standard_Integer aNormalIter = 1; aNormalIter <= 3 * aNbNodes; ++aNormalIter)
+ {
+ const Standard_ShortReal& aNormal = aNormals.Value(aNormalIter);
+ BinTools::PutShortReal(OS, aNormal);
+ }
+ }
+ }
}
}
catch (Standard_Failure const& anException)
{
Standard_Integer aNbNodes = 0, aNbTriangles = 0;
Standard_Boolean hasUV = Standard_False;
+ Standard_Boolean hasNormals = Standard_False;
Standard_Real aDefl = 0.0;
BinTools::GetInteger(IS, aNbNodes);
BinTools::GetInteger(IS, aNbTriangles);
BinTools::GetBool(IS, hasUV);
+ if (myFormatNb >= BinTools_FormatVersion_VERSION_4)
+ {
+ BinTools::GetBool(IS, hasNormals);
+ }
BinTools::GetReal(IS, aDefl); //deflection
- Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation (aNbNodes, aNbTriangles, hasUV);
+ Handle(Poly_Triangulation) aTriangulation = new Poly_Triangulation (aNbNodes, aNbTriangles, hasUV, hasNormals);
aTriangulation->Deflection (aDefl);
TColgp_Array1OfPnt& aNodes = aTriangulation->ChangeNodes();
BinTools::GetInteger(IS, aTri.ChangeValue (3));
}
- myTriangulations.Add (aTriangulation);
+ if (hasNormals)
+ {
+ TShort_Array1OfShortReal& aNormals = aTriangulation->ChangeNormals();
+ for (Standard_Integer aNormalIter = 1; aNormalIter <= aNbNodes*3; ++aNormalIter)
+ {
+ Standard_ShortReal aNormalFromFile;
+ BinTools::GetShortReal(IS, aNormalFromFile);
+ Standard_ShortReal& aNormalCoordinate = aNormals.ChangeValue(aNormalIter);
+ aNormalCoordinate = aNormalFromFile;
+ }
+ }
+
+ myTriangulations.Add (aTriangulation, hasNormals);
}
}
catch (Standard_Failure const& anException)
//! Builds an empty ShapeSet.
//! @param theWithTriangles [in] flag to write triangulation data
- Standard_EXPORT BinTools_ShapeSet (const Standard_Boolean theWithTriangles = Standard_False);
+ Standard_EXPORT BinTools_ShapeSet ();
Standard_EXPORT virtual ~BinTools_ShapeSet();
//! Return true if shape should be stored with triangles.
Standard_Boolean IsWithTriangles() const { return myWithTriangles; }
+ //! Return true if shape should be stored triangulation with normals.
+ Standard_Boolean IsWithNormals() const { return myWithNormals; }
+
//! Define if shape will be stored with triangles.
//! Ignored (always written) if face defines only triangulation (no surface).
void SetWithTriangles (const Standard_Boolean theWithTriangles) { myWithTriangles = theWithTriangles; }
+ //! Define if shape will be stored triangulation with normals.
+ //! Ignored (always written) if face defines only triangulation (no surface).
+ void SetWithNormals(const Standard_Boolean theWithNormals) { myWithNormals = theWithNormals; }
//! Sets the BinTools_FormatVersion.
Standard_EXPORT void SetFormatNb (const Standard_Integer theFormatNb);
public:
- static Standard_CString Version_1;
- static Standard_CString Version_2;
- static Standard_CString Version_3;
+ static const Standard_CString THE_ASCII_VERSIONS[BinTools_FormatVersion_UPPER + 1];
private:
BinTools_Curve2dSet myCurves2d;
NCollection_IndexedMap<Handle(Poly_Polygon2D), TColStd_MapTransientHasher> myPolygons2D;
NCollection_IndexedMap<Handle(Poly_Polygon3D), TColStd_MapTransientHasher> myPolygons3D;
- NCollection_IndexedMap<Handle(Poly_Triangulation), TColStd_MapTransientHasher> myTriangulations;
+ NCollection_IndexedDataMap<Handle(Poly_Triangulation),
+ Standard_Boolean> myTriangulations; //!< Contains a boolean flag with information
+ //! to save normals for triangulation
NCollection_IndexedMap<Handle(Poly_PolygonOnTriangulation), TColStd_MapTransientHasher> myNodes;
Standard_Boolean myWithTriangles;
+ Standard_Boolean myWithNormals;
};
Standard_Integer aVersion = -1;
TCollection_AsciiString aShapeName, aFileName;
TopoDS_Shape aShape;
- bool isBinaryFormat = false, isWithTriangles = true;
+ Standard_Boolean isBinaryFormat(Standard_False);
+ Standard_Boolean isWithTriangles(Standard_True);
+ Standard_Boolean isWithNormals(Standard_False);
if (!strcasecmp (theArgVec[0], "binsave"))
{
- isBinaryFormat = true;
+ isBinaryFormat = Standard_True;
}
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
aParam.LowerCase();
if (aParam == "-binary")
{
- isBinaryFormat = true;
+ isBinaryFormat = Standard_True;
if (anArgIter + 1 < theNbArgs
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], isBinaryFormat))
{
else if (aParam == "-notriangles"
|| aParam == "-triangles")
{
- isWithTriangles = true;
+ isWithTriangles = Standard_True;
if (anArgIter + 1 < theNbArgs
&& Draw::ParseOnOff (theArgVec[anArgIter + 1], isWithTriangles))
{
isWithTriangles = !isWithTriangles;
}
}
+ else if (aParam == "-nonormals"
+ || aParam == "-normals")
+ {
+ isWithNormals = Standard_True;
+ if (anArgIter + 1 < theNbArgs
+ && Draw::ParseOnOff (theArgVec[anArgIter + 1], isWithNormals))
+ {
+ ++anArgIter;
+ }
+ if (aParam == "-nonormals")
+ {
+ isWithNormals = !isWithNormals;
+ }
+ }
else if (aShapeName.IsEmpty())
{
aShapeName = theArgVec[anArgIter];
BinTools_FormatVersion aBinToolsVersion = aVersion > 0
? static_cast<BinTools_FormatVersion> (aVersion)
: BinTools_FormatVersion_CURRENT;
- if (!BinTools::Write (aShape, aFileName.ToCString(), isWithTriangles, aBinToolsVersion, aProgress->Start()))
+ if (!BinTools::Write (aShape, aFileName.ToCString(), isWithTriangles, isWithNormals, aBinToolsVersion, aProgress->Start()))
{
theDI << "Cannot write to the file " << aFileName;
return 1;
TopTools_FormatVersion aTopToolsVersion = aVersion > 0
? static_cast<TopTools_FormatVersion> (aVersion)
: TopTools_FormatVersion_CURRENT;
- if (!BRepTools::Write (aShape, aFileName.ToCString(), isWithTriangles, aTopToolsVersion, aProgress->Start()))
+ if (!BRepTools::Write (aShape, aFileName.ToCString(), isWithTriangles, isWithNormals, aTopToolsVersion, aProgress->Start()))
{
theDI << "Cannot write to the file " << aFileName;
return 1;
"\n\t\t +|-g : switch on/off graphical mode of Progress Indicator",
XProgress,"DE: General");
theCommands.Add("writebrep",
- "writebrep shape filename [-binary] [-version Version] [-noTriangles]"
+ "writebrep shape filename [-binary=off] [-version Version=4] [-noTriangles=off]"
"\n\t\t: Save the shape in the ASCII (default) or binary format file."
"\n\t\t: -binary write into the binary format (ASCII when unspecified)"
"\n\t\t: -version a number of format version to save;"
- "\n\t\t: ASCII versions: 1, 2 (1 for ASCII when unspecified);"
- "\n\t\t: Binary versions: 1, 2 and 3 (1 for Binary when unspecified)."
- "\n\t\t: -noTriangles skip triangulation data (OFF when unspecified).",
+ "\n\t\t: ASCII versions: 1, 2 and 3 (3 for ASCII when unspecified);"
+ "\n\t\t: Binary versions: 1, 2, 3 and 4 (4 for Binary when unspecified)."
+ "\n\t\t: -noTriangles skip triangulation data (OFF when unspecified)."
+ "\n\t\t: Ignored (always written) if face defines only triangulation (no surface).",
__FILE__, writebrep, g);
theCommands.Add("readbrep",
"readbrep filename shape"
theDi << (aDriverXCaf->IsWithTriangles() ? "1" : "0");
return 0;
}
- else if (theNbArgs != 2)
+
+ for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
- std::cout << "Syntax error: wrong number of arguments\n";
- return 1;
- }
+ TCollection_AsciiString aParam(theArgVec[anArgIter]);
+ aParam.LowerCase();
+
+ // toStore optional positional parameter
+ Standard_Integer aParsedIntegerValue(0);
+ if (anArgIter == 1 && Draw::ParseInteger(aParam.ToCString(), aParsedIntegerValue))
+ {
+ const Standard_Boolean toEnable = (aParsedIntegerValue != 0);
+ aDriverXCaf->SetWithTriangles(anApp->MessageDriver(), toEnable);
+ aDriverOcaf->SetWithTriangles(anApp->MessageDriver(), toEnable);
+ continue;
+ }
- const Standard_Boolean toEnable = (Draw::Atoi (theArgVec[1]) != 0);
- aDriverXCaf->SetWithTriangles (anApp->MessageDriver(), toEnable);
- aDriverOcaf->SetWithTriangles (anApp->MessageDriver(), toEnable);
+ if (aParam == "-nonormals"
+ || aParam == "-normals")
+ {
+ Standard_Boolean isWithNormals(Standard_True);
+ if (anArgIter + 1 < theNbArgs
+ && Draw::ParseOnOff(theArgVec[anArgIter + 1], isWithNormals))
+ {
+ ++anArgIter;
+ }
+ if (aParam == "-nonormals")
+ {
+ isWithNormals = !isWithNormals;
+ }
+ aDriverXCaf->SetWithNormals(anApp->MessageDriver(), isWithNormals);
+ aDriverOcaf->SetWithNormals(anApp->MessageDriver(), isWithNormals);
+ }
+ if (aParam == "-getnormals")
+ {
+ theDi << (aDriverXCaf->IsWithNormals() ? "1" : "0");
+ continue;
+ }
+ }
return 0;
}
__FILE__, DDocStd_DumpDocument, g);
theCommands.Add ("StoreTriangulation",
- "StoreTriangulation [toStore={0|1}]"
+ "StoreTriangulation [toStore={0|1}] [-normals=off] [-noNormals=on]"
+ "\n\t\t: -normals -noNormals write triangulation normals."
+ "\n\t\t: Ignored (always off) if toStore=0 or skipped"
"\nSetup BinXCAF/BinOcaf storage drivers to write triangulation",
__FILE__, DDocStd_StoreTriangulation, g);
//=======================================================================
//function : Poly_Triangulation
-//purpose :
+//purpose :
//=======================================================================
+Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
+ const Standard_Integer theNbTriangles,
+ const Standard_Boolean theHasUVNodes,
+ const Standard_Boolean theHasNormals)
+: myDeflection(0),
+ myNodes (1, theNbNodes),
+ myTriangles (1, theNbTriangles)
+{
+ if (theHasUVNodes)
+ {
+ myUVNodes = new TColgp_HArray1OfPnt2d(1, theNbNodes);
+ }
+ if (theHasNormals)
+ {
+ myNormals = new TShort_HArray1OfShortReal(1, theNbNodes * 3);
+ }
+}
+//=======================================================================
+//function : Poly_Triangulation
+//purpose :
+//=======================================================================
Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt& theNodes,
const Poly_Array1OfTriangle& theTriangles)
: myDeflection(0),
//! enable a 2D representation).
Standard_EXPORT Poly_Triangulation(const Standard_Integer nbNodes, const Standard_Integer nbTriangles, const Standard_Boolean UVNodes);
+ //! Constructs a triangulation from a set of triangles.
+ //! The triangulation is initialized without a triangle or a node,
+ //! but capable of containing nbNodes nodes, and nbTriangles triangles.
+ //! Here the UVNodes flag indicates whether 2D nodes will be associated with 3D ones,
+ //! (i.e. to enable a 2D representation).
+ //! Here the hasNormals flag indicates whether normals will be given and associated with nodes.
+ Standard_EXPORT Poly_Triangulation(const Standard_Integer nbNodes,
+ const Standard_Integer nbTriangles,
+ const Standard_Boolean UVNodes,
+ const Standard_Boolean hasNormals);
+
//! Constructs a triangulation from a set of triangles. The
//! triangulation is initialized with 3D points from Nodes and triangles
//! from Triangles.
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, XML: TopTools_FormatVersion_CURRENT changed to 3 and
+ //!< BinTools_FormatVersion_CURRENT changed to 4 to preserve per-vertex normal
+ //!< information in case of triangulation-only Faces [#0031136]
+ TDocStd_FormatVersion_CURRENT = TDocStd_FormatVersion_VERSION_11 //!< Current version
};
+enum
+{
+ TDocStd_FormatVersion_LOWER = TDocStd_FormatVersion_VERSION_2,
+ TDocStd_FormatVersion_UPPER = TDocStd_FormatVersion_VERSION_11
+};
+
+
#endif // _TDocStdFormatVersion_HeaderFile
//! This is default version.
TopTools_FormatVersion_VERSION_2 = 2, //!< Stores CurveOnSurface UV Points.
//! On reading format is recognized from Version string.
+ TopTools_FormatVersion_VERSION_3 = 3, //!< Stores per-vertex normal information in case of triangulation-only Faces,
+ //! because no analytical geometry to restore normals
+ TopTools_FormatVersion_CURRENT = TopTools_FormatVersion_VERSION_3 //!< Current version
+};
- TopTools_FormatVersion_CURRENT = TopTools_FormatVersion_VERSION_1 //!< The current version.
+enum
+{
+ TopTools_FormatVersion_LOWER = TopTools_FormatVersion_VERSION_1,
+ TopTools_FormatVersion_UPPER = TopTools_FormatVersion_VERSION_3
};
+
#endif
#include <locale.h>
#include <string.h>
-Standard_CString TopTools_ShapeSet::Version_1 = "CASCADE Topology V1, (c) Matra-Datavision";
-Standard_CString TopTools_ShapeSet::Version_2 = "CASCADE Topology V2, (c) Matra-Datavision";
+
+const Standard_CString TopTools_ShapeSet::THE_ASCII_VERSIONS[TopTools_FormatVersion_UPPER + 1] =
+{
+ "",
+ "CASCADE Topology V1, (c) Matra-Datavision",
+ "CASCADE Topology V2, (c) Matra-Datavision",
+ "CASCADE Topology V3, (c) Open Cascade"
+};
//=======================================================================
//function : TopTools_ShapeSet
//=======================================================================
void TopTools_ShapeSet::SetFormatNb(const Standard_Integer theFormatNb)
{
- Standard_ASSERT_RETURN(theFormatNb == TopTools_FormatVersion_VERSION_1 ||
- theFormatNb == TopTools_FormatVersion_VERSION_2,
+ Standard_ASSERT_RETURN(theFormatNb >= TopTools_FormatVersion_LOWER &&
+ theFormatNb <= TopTools_FormatVersion_UPPER,
"Error: unsupported TopTools version.", );
myFormatNb = theFormatNb;
std::streamsize prec = OS.precision(15);
// write the copyright
- if (myFormatNb == TopTools_FormatVersion_VERSION_2)
- {
- OS << "\n" << Version_2 << "\n";
- }
- else
- {
- OS << "\n" << Version_1 << "\n";
- }
+ OS << "\n" << THE_ASCII_VERSIONS[myFormatNb] << "\n";
//-----------------------------------------
// write the locations
// Check the version
char vers[101];
+ Standard_Boolean anIsSetFormat = Standard_False;
do {
IS.getline(vers,100,'\n');
// BUC60769 PTV 18.10.2000: remove possible '\r' at the end of the line
for (lv--; lv > 0 && (vers[lv] == '\r' || vers[lv] == '\n') ;lv--)
vers[lv] = '\0';
}
+ for (Standard_Integer i = TopTools_FormatVersion_LOWER;
+ i <= TopTools_FormatVersion_UPPER; ++i)
+ {
+ if (!strcmp(vers, THE_ASCII_VERSIONS[i]))
+ {
+ SetFormatNb(i);
+ anIsSetFormat = Standard_True;
+ break;
+ }
+ }
+ if (anIsSetFormat)
+ {
+ break;
+ }
- } while (!IS.fail()
- && strcmp(vers, Version_1)
- && strcmp(vers, Version_2));
+ } while (!IS.fail());
if (IS.fail()) {
std::cout << "File was not written with this version of the topology"<<std::endl;
IS.imbue (anOldLocale);
return;
}
- else if (strcmp(vers, Version_2) == 0)
- {
- SetFormatNb(TopTools_FormatVersion_VERSION_2);
- }
- else
- {
- SetFormatNb(TopTools_FormatVersion_VERSION_1);
- }
//-----------------------------------------
// read the locations
public:
- static Standard_CString Version_1;
- static Standard_CString Version_2;
+ static const Standard_CString THE_ASCII_VERSIONS[TopTools_FormatVersion_VERSION_3 + 1];
private:
//=======================================================================
Standard_Boolean XmlDrivers_DocumentStorageDriver::WriteShapeSection
(XmlObjMgt_Element& theElement,
+ const TDocStd_FormatVersion theStorageFormatVersion,
const Message_ProgressRange& theRange)
{
Standard_Boolean isShape(Standard_False);
{
Handle(XmlMNaming_NamedShapeDriver) aNamedShapeDriver =
Handle(XmlMNaming_NamedShapeDriver)::DownCast (aDriver);
- aNamedShapeDriver->WriteShapeSection (theElement, theRange);
+ aNamedShapeDriver->WriteShapeSection (theElement, theStorageFormatVersion, theRange);
isShape = Standard_True;
}
return isShape;
(const Handle(Message_Messenger)& theMsgDriver) Standard_OVERRIDE;
Standard_EXPORT virtual Standard_Boolean WriteShapeSection
- (XmlObjMgt_Element& thePDoc,
+ (XmlObjMgt_Element& thePDoc,
+ const TDocStd_FormatVersion theStorageFormatVersion,
const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
DEFINE_STANDARD_RTTIEXT(XmlDrivers_DocumentStorageDriver,XmlLDrivers_DocumentStorageDriver)
// Document version
Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast (theDocument);
- Standard_Integer aFormatVersion = TDocStd_Document::CurrentStorageFormatVersion(); // the last version of the format
+ TDocStd_FormatVersion aFormatVersion = TDocStd_Document::CurrentStorageFormatVersion(); // the last version of the format
if (TDocStd_Document::CurrentStorageFormatVersion() < aDoc->StorageFormatVersion())
{
TCollection_ExtendedString anErrorString("Unacceptable storage format version, the last verson is used");
myRelocTable.Clear();
// 4. Write Shapes section
- if (WriteShapeSection(theElement, aPS.Next()))
+ if (WriteShapeSection(theElement, aFormatVersion, aPS.Next()))
::take_time (0, " +++ Fin DOM data for Shapes : ", aMessageDriver);
if (!aPS.More())
{
//=======================================================================
Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteShapeSection
(XmlObjMgt_Element& /*theElement*/,
- const Message_ProgressRange& /*theRange*/)
+ const TDocStd_FormatVersion /*theStorageFormatVersion*/,
+ const Message_ProgressRange& /*theRange*/)
{
// empty; should be redefined in subclasses
return Standard_False;
#include <Standard_Boolean.hxx>
#include <XmlObjMgt_Element.hxx>
#include <Standard_Integer.hxx>
+#include <TDocStd_FormatVersion.hxx>
class XmlMDF_ADriverTable;
class TCollection_ExtendedString;
Standard_EXPORT virtual Standard_Boolean WriteShapeSection
(XmlObjMgt_Element& thePDoc,
+ const TDocStd_FormatVersion theStorageFormatVersion,
const Message_ProgressRange& theRange = Message_ProgressRange());
Handle(XmlMDF_ADriverTable) myDrivers;
#include <TNaming_NamedShape.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_LocationSet.hxx>
+#include <XmlLDrivers.hxx>
#include <XmlMNaming_NamedShapeDriver.hxx>
#include <XmlMNaming_Shape1.hxx>
#include <XmlObjMgt.hxx>
//=======================================================================
void XmlMNaming_NamedShapeDriver::WriteShapeSection (XmlObjMgt_Element& theElement,
+ TDocStd_FormatVersion theStorageFormatVersion,
const Message_ProgressRange& theRange)
{
// Create "shapes" element and append it as child
theElement.appendChild (anElement);
// Add text to the "shapes" element
- if (myShapeSet.NbShapes() > 0) {
- myShapeSet.SetFormatNb(TopTools_FormatVersion_VERSION_1);
+ if (myShapeSet.NbShapes() > 0)
+ {
+ if (theStorageFormatVersion >= TDocStd_FormatVersion_VERSION_11)
+ {
+ myShapeSet.SetFormatNb(TopTools_FormatVersion_VERSION_3);
+ }
+ else
+ {
+ myShapeSet.SetFormatNb(TopTools_FormatVersion_VERSION_1);
+ }
+
LDOM_OSStream aStream (16 * 1024);
// ostrstream aStream;
// aStream.rdbuf() -> setbuf (0, 16380);
#include <BRepTools_ShapeSet.hxx>
#include <XmlMDF_ADriver.hxx>
#include <Standard_Boolean.hxx>
+#include <TDocStd_FormatVersion.hxx>
#include <XmlObjMgt_RRelocationTable.hxx>
#include <XmlObjMgt_SRelocationTable.hxx>
#include <XmlObjMgt_Element.hxx>
//! Output the shapes into DOM element
Standard_EXPORT void WriteShapeSection (XmlObjMgt_Element& anElement,
+ TDocStd_FormatVersion theStorageFormatVersion,
const Message_ProgressRange& theRange = Message_ProgressRange());
//! Clear myShapeSet
--- /dev/null
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload MODELING XDE OCAF VISUALIZATION
+source $env(CSF_OCCTSamplesPath)/tcl/cad.tcl
+trinfo res
+wavefront res $imagedir/${test_image}
+readobj o $imagedir/${test_image}.obj
+
+# binary format
+set test_image_bbrep ${test_image}_bbrep
+binsave o $imagedir/${test_image_bbrep}.bbrep
+binrestore $imagedir/${test_image_bbrep}.bbrep b1
+vclear
+vclose ALL
+vinit v1/v1
+vbottom
+vdisplay -dispMode 1 b1
+vfit
+vrenderparams -shadingModel phong
+checkview -screenshot -3d -path ${imagedir}/${test_image_bbrep}.png
--- /dev/null
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload MODELING XDE OCAF VISUALIZATION
+source $env(CSF_OCCTSamplesPath)/tcl/cad.tcl
+trinfo res
+wavefront res $imagedir/${test_image}
+readobj o $imagedir/${test_image}.obj
+
+# ASCII format
+set test_image_brep ${test_image}_brep
+save o $imagedir/${test_image_brep}.brep
+restore $imagedir/${test_image_brep}.brep b2
+vclear
+vclose ALL
+vinit v1/v1
+vbottom
+vdisplay -dispMode 1 b2
+vfit
+vrenderparams -shadingModel phong
+checkview -screenshot -3d -path ${imagedir}/${test_image_brep}.png
+
--- /dev/null
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload MODELING XDE OCAF VISUALIZATION
+source $env(CSF_OCCTSamplesPath)/tcl/cad.tcl
+trinfo res
+wavefront res $imagedir/${test_image}
+readobj o $imagedir/${test_image}.obj
+
+# XBF format
+set test_image_XBF ${test_image}_XBF
+XNewDoc D1
+XAddShape D1 o
+XSave D1 $imagedir/${test_image_XBF}.xbf
+Close D1
+XOpen $imagedir/${test_image_XBF}.xbf D2
+vclear
+vclose ALL
+vinit v1/v1
+vbottom
+XDisplay -dispMode 1 D2
+Close D2
+vfit
+vrenderparams -shadingModel phong
+checkview -screenshot -3d -path ${imagedir}/${test_image_XBF}.png
--- /dev/null
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload MODELING XDE OCAF VISUALIZATION
+source $env(CSF_OCCTSamplesPath)/tcl/cad.tcl
+trinfo res
+wavefront res $imagedir/${test_image}
+readobj o $imagedir/${test_image}.obj
+
+
+# XML format
+set test_image_XML ${test_image}_XML
+NewDocument D1 XmlXCAF
+XAddShape D1 o
+# SetStorageFormatVersion D1 10
+SaveAs D1 $imagedir/${test_image_XML}.xml
+Close D1
+Open $imagedir/${test_image_XML}.xml D2
+vclear
+vclose ALL
+vinit v1/v1
+vbottom
+XDisplay -dispMode 1 D2
+Close D2
+vfit
+vrenderparams -shadingModel phong
+checkview -screenshot -3d -path ${imagedir}/${test_image_XML}.png
--- /dev/null
+puts "=========="
+puts "0031136: BinXCAF persistence loses normals from triangulation-only Faces"
+puts "=========="
+puts ""
+
+pload XDE OCAF
+
+StoreTriangulation 1 -normals
+set res [StoreTriangulation -getnormals]
+if { $res != 1 } {
+ puts "Error : normals not on"
+}
+StoreTriangulation 1 -normals 0
+set res [StoreTriangulation -getnormals]
+if { $res != 0 } {
+ puts "Error : normals not off"
+}
+StoreTriangulation 1 -normals 1
+set res [StoreTriangulation -getnormals]
+if { $res != 1 } {
+ puts "Error : normals not on"
+}
+StoreTriangulation 1 -nonormals
+set res [StoreTriangulation -getnormals]
+if { $res != 0 } {
+ puts "Error : normals not off"
+}
+StoreTriangulation 1 -nonormals 0
+set res [StoreTriangulation -getnormals]
+if { $res != 1 } {
+ puts "Error : normals not on"
+}
+StoreTriangulation 1 -nonormals 1
+set res [StoreTriangulation -getnormals]
+if { $res != 0 } {
+ puts "Error : normals not off"
+}
+StoreTriangulation -normals
+set res [StoreTriangulation -getnormals]
+if { $res != 1 } {
+ puts "Error : normals not on"
+}
+StoreTriangulation -normals 0
+set res [StoreTriangulation -getnormals]
+if { $res != 0 } {
+ puts "Error : normals not off"
+}
+StoreTriangulation -normals 1
+set res [StoreTriangulation -getnormals]
+if { $res != 1 } {
+ puts "Error : normals not on"
+}
+StoreTriangulation -nonormals
+set res [StoreTriangulation -getnormals]
+if { $res != 0 } {
+ puts "Error : normals not off"
+}
+StoreTriangulation -nonormals 0
+set res [StoreTriangulation -getnormals]
+if { $res != 1 } {
+ puts "Error : normals not on"
+}
+StoreTriangulation -nonormals 1
+set res [StoreTriangulation -getnormals]
+if { $res != 0 } {
+ puts "Error : normals not off"
+}
+
+puts "OK"
\ No newline at end of file