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:
@@ -668,10 +668,11 @@ void BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
|
||||
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);
|
||||
@@ -700,6 +701,7 @@ void BRepTools::Read(TopoDS_Shape& Sh,
|
||||
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)
|
||||
{
|
||||
@@ -712,7 +714,7 @@ Standard_Boolean BRepTools::Write (const TopoDS_Shape& theShape,
|
||||
if(!isGood)
|
||||
return isGood;
|
||||
|
||||
BRepTools_ShapeSet SS (theWithTriangles);
|
||||
BRepTools_ShapeSet SS (theWithTriangles, theWithNormals);
|
||||
SS.SetFormatNb (theVersion);
|
||||
SS.Add (theShape);
|
||||
|
||||
|
@@ -214,8 +214,8 @@ public:
|
||||
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.
|
||||
@@ -223,11 +223,14 @@ 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 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());
|
||||
|
||||
@@ -245,8 +248,8 @@ public:
|
||||
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.
|
||||
@@ -254,11 +257,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 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());
|
||||
|
||||
|
@@ -84,8 +84,10 @@
|
||||
//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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -94,9 +96,11 @@ BRepTools_ShapeSet::BRepTools_ShapeSet (const Standard_Boolean theWithTriangles)
|
||||
//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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -197,7 +201,11 @@ void BRepTools_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())
|
||||
@@ -218,12 +226,19 @@ void BRepTools_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()) { // 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());
|
||||
@@ -1002,7 +1017,7 @@ void BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
|
||||
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 {
|
||||
@@ -1010,7 +1025,7 @@ void BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
|
||||
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
|
||||
@@ -1062,7 +1077,7 @@ void BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
|
||||
//only triangulation
|
||||
IS >> s;
|
||||
myBuilder.UpdateFace(TopoDS::Face(S),
|
||||
Handle(Poly_Triangulation)::DownCast(myTriangulations(s)));
|
||||
myTriangulations.FindKey(s));
|
||||
}
|
||||
// else pos = IS.tellg();
|
||||
|
||||
@@ -1079,7 +1094,7 @@ void BRepTools_ShapeSet::ReadGeometry (const TopAbs_ShapeEnum T,
|
||||
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);
|
||||
}
|
||||
@@ -1422,16 +1437,24 @@ void BRepTools_ShapeSet::WriteTriangulation(Standard_OStream& OS,
|
||||
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
|
||||
@@ -1486,6 +1509,32 @@ void BRepTools_ShapeSet::WriteTriangulation(Standard_OStream& OS,
|
||||
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";
|
||||
}
|
||||
}
|
||||
@@ -1512,8 +1561,10 @@ void BRepTools_ShapeSet::ReadTriangulation(Standard_IStream& IS, const Message_P
|
||||
// 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;
|
||||
|
||||
@@ -1526,11 +1577,19 @@ void BRepTools_ShapeSet::ReadTriangulation(Standard_IStream& IS, const Message_P
|
||||
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);
|
||||
@@ -1553,12 +1612,24 @@ void BRepTools_ShapeSet::ReadTriangulation(Standard_IStream& IS, const Message_P
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@@ -48,21 +48,28 @@ public:
|
||||
|
||||
//! 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;
|
||||
@@ -167,9 +174,12 @@ private:
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user