mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0031136: Modeling Data - BinXCAF persistence loses normals from triangulation-only Faces
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
This commit is contained in:
@@ -176,10 +176,13 @@ Standard_IStream& BinTools::GetBool(Standard_IStream& IS, Standard_Boolean& aVal
|
||||
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);
|
||||
@@ -194,7 +197,8 @@ void BinTools::Write (const TopoDS_Shape& theShape,
|
||||
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());
|
||||
}
|
||||
@@ -206,6 +210,7 @@ void BinTools::Read (TopoDS_Shape& theShape, Standard_IStream& theStream,
|
||||
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)
|
||||
{
|
||||
@@ -215,7 +220,7 @@ Standard_Boolean BinTools::Write (const TopoDS_Shape& theShape,
|
||||
if (!aStream.good())
|
||||
return Standard_False;
|
||||
|
||||
Write (theShape, aStream, theWithTriangles, theVersion, theRange);
|
||||
Write (theShape, aStream, theWithTriangles, theWithNormals, theVersion, theRange);
|
||||
aStream.close();
|
||||
return aStream.good();
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -82,10 +82,13 @@ public:
|
||||
//! @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());
|
||||
|
||||
@@ -101,7 +104,7 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -110,11 +113,14 @@ public:
|
||||
//! @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());
|
||||
|
||||
|
@@ -23,8 +23,16 @@ enum BinTools_FormatVersion
|
||||
//! 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
|
||||
|
@@ -55,9 +55,15 @@
|
||||
|
||||
#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)
|
||||
@@ -75,9 +81,10 @@ static Standard_OStream& operator <<(Standard_OStream& OS, const gp_Pnt P)
|
||||
//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)
|
||||
{}
|
||||
|
||||
//=======================================================================
|
||||
@@ -94,9 +101,8 @@ BinTools_ShapeSet::~BinTools_ShapeSet()
|
||||
//=======================================================================
|
||||
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;
|
||||
@@ -261,7 +267,11 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
|
||||
}
|
||||
}
|
||||
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())
|
||||
@@ -282,14 +292,21 @@ void BinTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
|
||||
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());
|
||||
@@ -332,18 +349,7 @@ void BinTools_ShapeSet::Write (Standard_OStream& OS,
|
||||
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
|
||||
@@ -413,6 +419,7 @@ void BinTools_ShapeSet::Read (Standard_IStream& IS,
|
||||
|
||||
// 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
|
||||
@@ -422,27 +429,28 @@ void BinTools_ShapeSet::Read (Standard_IStream& IS,
|
||||
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
|
||||
//-----------------------------------------
|
||||
@@ -1111,11 +1119,11 @@ void BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
|
||||
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;
|
||||
@@ -1164,7 +1172,7 @@ void BinTools_ShapeSet::ReadGeometry(const TopAbs_ShapeEnum T,
|
||||
// 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;
|
||||
@@ -1477,11 +1485,16 @@ void BinTools_ShapeSet::WriteTriangulation (Standard_OStream& OS,
|
||||
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
|
||||
@@ -1513,6 +1526,20 @@ void BinTools_ShapeSet::WriteTriangulation (Standard_OStream& OS,
|
||||
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)
|
||||
@@ -1549,12 +1576,17 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
|
||||
{
|
||||
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();
|
||||
@@ -1587,7 +1619,19 @@ void BinTools_ShapeSet::ReadTriangulation (Standard_IStream& IS,
|
||||
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)
|
||||
|
@@ -47,16 +47,22 @@ public:
|
||||
|
||||
//! 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);
|
||||
@@ -193,9 +199,7 @@ public:
|
||||
|
||||
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:
|
||||
|
||||
@@ -208,9 +212,12 @@ 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;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user