1
0
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:
asuraven
2020-11-17 20:37:01 +03:00
committed by bugmaster
parent 6fab0b3428
commit 9f45d35b6b
40 changed files with 703 additions and 209 deletions

View File

@@ -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);

View File

@@ -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());

View File

@@ -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);
}
}

View File

@@ -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;
};