0026007: Standard attribute for surface meshes in TDataStd
authorakz <akz@opencascade.com>
Fri, 11 Nov 2016 14:59:23 +0000 (17:59 +0300)
committerapn <apn@opencascade.com>
Thu, 26 Jan 2017 10:43:59 +0000 (13:43 +0300)
19 files changed:
src/BinMDataXtd/BinMDataXtd.cxx
src/BinMDataXtd/BinMDataXtd.hxx
src/BinMDataXtd/BinMDataXtd_TriangulationDriver.cxx [new file with mode: 0644]
src/BinMDataXtd/BinMDataXtd_TriangulationDriver.hxx [new file with mode: 0644]
src/BinMDataXtd/FILES
src/DDataStd/DDataStd_BasicCommands.cxx
src/Poly/Poly_Triangulation.cxx
src/Poly/Poly_Triangulation.hxx
src/TDataXtd/FILES
src/TDataXtd/TDataXtd.hxx
src/TDataXtd/TDataXtd_Triangulation.cxx [new file with mode: 0644]
src/TDataXtd/TDataXtd_Triangulation.hxx [new file with mode: 0644]
src/XmlMDataXtd/FILES
src/XmlMDataXtd/XmlMDataXtd.cxx
src/XmlMDataXtd/XmlMDataXtd.hxx
src/XmlMDataXtd/XmlMDataXtd_TriangulationDriver.cxx [new file with mode: 0644]
src/XmlMDataXtd/XmlMDataXtd_TriangulationDriver.hxx [new file with mode: 0644]
tests/caf/basic/N1 [new file with mode: 0644]
tests/caf/basic/N2 [new file with mode: 0644]

index c4c1871..10402c0 100644 (file)
@@ -28,6 +28,7 @@
 #include <CDM_MessageDriver.hxx>
 #include <BinMDataXtd_PresentationDriver.hxx>
 #include <BinMDataXtd_PositionDriver.hxx>
+#include <BinMDataXtd_TriangulationDriver.hxx>
 
 static Standard_Integer myDocumentVersion = -1;
 //=======================================================================
@@ -38,17 +39,18 @@ static Standard_Integer myDocumentVersion = -1;
 void BinMDataXtd::AddDrivers (const Handle(BinMDF_ADriverTable)& theDriverTable,
                               const Handle(CDM_MessageDriver)&   theMsgDriver)
 {
-  theDriverTable->AddDriver (new BinMDataXtd_ConstraintDriver  (theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_GeometryDriver    (theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_PatternStdDriver  (theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_ShapeDriver       (theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_PointDriver       (theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_AxisDriver        (theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_PlaneDriver       (theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_PlacementDriver   (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_ConstraintDriver   (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_GeometryDriver     (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_PatternStdDriver   (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_ShapeDriver        (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_PointDriver        (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_AxisDriver         (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_PlaneDriver        (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_PlacementDriver    (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_TriangulationDriver(theMsgDriver) );
 
-  theDriverTable->AddDriver (new BinMDataXtd_PresentationDriver(theMsgDriver) );
-  theDriverTable->AddDriver (new BinMDataXtd_PositionDriver    (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_PresentationDriver (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataXtd_PositionDriver     (theMsgDriver) );
 }
 
 //=======================================================================
index 126e56f..cddf90b 100644 (file)
@@ -31,7 +31,7 @@ class BinMDataXtd_ConstraintDriver;
 class BinMDataXtd_PlacementDriver;
 class BinMDataXtd_PatternStdDriver;
 class BinMDataXtd_ShapeDriver;
-
+class BinMDataXtd_TriangulationDriver;
 
 //! Storage and Retrieval drivers for modelling attributes.
 class BinMDataXtd 
@@ -70,6 +70,7 @@ friend class BinMDataXtd_ConstraintDriver;
 friend class BinMDataXtd_PlacementDriver;
 friend class BinMDataXtd_PatternStdDriver;
 friend class BinMDataXtd_ShapeDriver;
+friend class BinMDataXtd_TriangulationDriver;
 
 };
 
diff --git a/src/BinMDataXtd/BinMDataXtd_TriangulationDriver.cxx b/src/BinMDataXtd/BinMDataXtd_TriangulationDriver.cxx
new file mode 100644 (file)
index 0000000..6aa7aaf
--- /dev/null
@@ -0,0 +1,158 @@
+// Created on: 2016-11-10
+// Created by: Anton KOZULIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BinMDataXtd_TriangulationDriver.hxx>
+#include <BinObjMgt_Persistent.hxx>
+#include <CDM_MessageDriver.hxx>
+#include <Standard_Type.hxx>
+#include <TDataXtd_Triangulation.hxx>
+#include <TDF_Attribute.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(BinMDataXtd_TriangulationDriver,BinMDF_ADriver)
+
+//=======================================================================
+//function : BinMDataXtd_TriangulationDriver
+//purpose  : Constructor
+//=======================================================================
+BinMDataXtd_TriangulationDriver::BinMDataXtd_TriangulationDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
+  : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TDataXtd_Triangulation)->Name())
+{
+
+}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  : 
+//=======================================================================
+Handle(TDF_Attribute) BinMDataXtd_TriangulationDriver::NewEmpty() const
+{
+  return new TDataXtd_Triangulation();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : persistent -> transient (retrieve)
+//=======================================================================
+Standard_Boolean BinMDataXtd_TriangulationDriver::Paste(const BinObjMgt_Persistent&  theSource,
+                                                        const Handle(TDF_Attribute)& theTarget,
+                                                        BinObjMgt_RRelocationTable&  ) const
+{
+  Handle(TDataXtd_Triangulation) attrubute = Handle(TDataXtd_Triangulation)::DownCast(theTarget);
+
+  Standard_Integer i;
+  Standard_Real deflection, x, y, z;
+  Standard_Integer n1, n2, n3;
+  Standard_Integer nbNodes(0), nbTriangles(0);
+  Standard_Boolean hasUV(Standard_False);
+  gp_Pnt p;
+
+  theSource >> nbNodes;
+  theSource >> nbTriangles;
+  theSource >> hasUV;
+  theSource >> deflection;
+
+  // allocate the mesh
+  Handle(Poly_Triangulation) PT = new Poly_Triangulation(nbNodes, nbTriangles, hasUV);
+
+  // deflection
+  PT->Deflection(deflection);
+
+  // read nodes
+  for (i = 1; i <= nbNodes; i++)
+  {
+    theSource >> x;
+    theSource >> y;
+    theSource >> z;
+    PT->ChangeNode(i).SetCoord(x, y, z);
+  }
+
+  // read 2d nodes
+  if (hasUV)
+  {
+    for (i = 1; i <= nbNodes; i++)
+    {
+      theSource >> x;
+      theSource >> y;
+      PT->ChangeUVNode(i).SetCoord(x,y);
+    }
+  }
+
+  // read triangles
+  for (i = 1; i <= nbTriangles; i++)
+  {
+    theSource >> n1;
+    theSource >> n2;
+    theSource >> n3;
+    PT->ChangeTriangle(i).Set(n1, n2, n3);
+  }
+
+  // set triangulation to Ocaf attribute
+  attrubute->Set(PT);
+  return !PT.IsNull();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : transient -> persistent (store)
+//=======================================================================
+void BinMDataXtd_TriangulationDriver::Paste(const Handle(TDF_Attribute)& theSource,
+                                            BinObjMgt_Persistent&        theTarget,
+                                            BinObjMgt_SRelocationTable&  ) const
+{
+  const Handle(TDataXtd_Triangulation) attribute = Handle(TDataXtd_Triangulation)::DownCast(theSource);
+  const Handle(Poly_Triangulation)& PT = attribute->Get();
+  if (!PT.IsNull())
+  {
+    Standard_Integer nbNodes = PT->NbNodes();
+    Standard_Integer nbTriangles = PT->NbTriangles();
+    Standard_Integer n1, n2, n3;
+
+    // write number of elements
+    theTarget << nbNodes;
+    theTarget << nbTriangles;
+    theTarget << (PT->HasUVNodes() ? 1 : 0);
+    // write the deflection
+    theTarget << PT->Deflection();
+
+    // write 3d nodes
+    Standard_Integer i;
+    for (i = 1; i <= nbNodes; i++)
+    {
+      theTarget << PT->Node(i).X();
+      theTarget << PT->Node(i).Y();
+      theTarget << PT->Node(i).Z();
+    }
+
+    // write 2d nodes
+    if (PT->HasUVNodes())
+    {
+      for (i = 1; i <= nbNodes; i++)
+      {
+        theTarget << PT->UVNode(i).X();
+        theTarget << PT->UVNode(i).Y();
+      }
+    }
+
+    // Write triangles
+    const Poly_Array1OfTriangle& Triangles = PT->Triangles();
+    for (int i = 1; i <= nbTriangles; i++)
+    {
+      Triangles(i).Get(n1, n2, n3);
+      theTarget << n1;
+      theTarget << n2;
+      theTarget << n3;
+    }
+  }
+}
diff --git a/src/BinMDataXtd/BinMDataXtd_TriangulationDriver.hxx b/src/BinMDataXtd/BinMDataXtd_TriangulationDriver.hxx
new file mode 100644 (file)
index 0000000..66476b8
--- /dev/null
@@ -0,0 +1,49 @@
+// Created on: 2016-11-10
+// Created by: Anton KOZULIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BinMDataXtd_TriangulationDriver_HeaderFile
+#define _BinMDataXtd_TriangulationDriver_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+
+#include <BinMDF_ADriver.hxx>
+#include <Standard_Boolean.hxx>
+#include <BinObjMgt_RRelocationTable.hxx>
+#include <BinObjMgt_SRelocationTable.hxx>
+class CDM_MessageDriver;
+class TDF_Attribute;
+class BinObjMgt_Persistent;
+
+DEFINE_STANDARD_HANDLE(BinMDataXtd_TriangulationDriver, BinMDF_ADriver)
+
+//! TDataXtd_Triangulation attribute bin Driver.
+class BinMDataXtd_TriangulationDriver : public BinMDF_ADriver
+{
+
+public:
+
+  Standard_EXPORT BinMDataXtd_TriangulationDriver(const Handle(CDM_MessageDriver)& theMessageDriver);
+
+  Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Standard_Boolean Paste (const BinObjMgt_Persistent& Source, const Handle(TDF_Attribute)& Target, BinObjMgt_RRelocationTable& RelocTable) const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& Source, BinObjMgt_Persistent& Target, BinObjMgt_SRelocationTable& RelocTable) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT(BinMDataXtd_TriangulationDriver,BinMDF_ADriver)
+};
+
+#endif // _BinMDataXtd_TriangulationDriver_HeaderFile
index 57782cd..a66405e 100644 (file)
@@ -20,3 +20,5 @@ BinMDataXtd_PresentationDriver.hxx
 BinMDataXtd_PresentationDriver.cxx
 BinMDataXtd_PositionDriver.hxx
 BinMDataXtd_PositionDriver.cxx
+BinMDataXtd_TriangulationDriver.cxx
+BinMDataXtd_TriangulationDriver.hxx
index 3e1cdfc..89f06e6 100644 (file)
@@ -32,6 +32,7 @@
 #include <TDF_AttributeList.hxx>
 #include <TDF_ListIteratorOfAttributeList.hxx>
 
+#include <BRep_Tool.hxx>
 #include <DBRep.hxx>
 #include <TopAbs.hxx>
 #include <TopoDS.hxx>
@@ -52,6 +53,7 @@
 
 // LES ATTRIBUTES
 #include <TDataStd.hxx>
+#include <TDataXtd_Triangulation.hxx>
 #include <TDataStd_Comment.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDataStd_Integer.hxx>
@@ -3814,6 +3816,94 @@ static Standard_Integer DDataStd_GetRefArrayValue (Draw_Interpretor& di,
 } 
 
 //=======================================================================
+//function : DDataStd_SetTriangulation
+//purpose  : SetTriangulation (DF, entry, face)
+//=======================================================================
+
+static Standard_Integer DDataStd_SetTriangulation (Draw_Interpretor& di,
+                                                   Standard_Integer nb,
+                                                   const char** arg)
+{
+  if (nb == 4)
+  {
+    Handle(TDF_Data) DF;
+    if (!DDF::GetDF(arg[1],DF))
+      return 1;
+
+    TDF_Label L;
+    if (!DDF::AddLabel(DF, arg[2], L))
+      return 1;
+
+    // Get face.
+    TopoDS_Shape face = DBRep::Get(arg[3]);
+    if (face.IsNull() ||
+        face.ShapeType() != TopAbs_FACE)
+    {
+      di << "The face is null or not a face.\n";
+      return 1;
+    }
+
+    // Get triangulation of the face.
+    TopLoc_Location loc;
+    Handle(Poly_Triangulation) tris = BRep_Tool::Triangulation(TopoDS::Face(face), loc);
+    if (tris.IsNull())
+    {
+      di << "No triangulation in the face.\n";
+      return 1;
+    }
+
+    // Set the attribute.
+    TDataXtd_Triangulation::Set(L, tris);
+    return 0;
+  }
+  di << "DDataStd_SetTriangulation : Error\n";
+  return 1;
+}
+
+//=======================================================================
+//function : DDataStd_DumpTriangulation
+//purpose  : DumpTriangulation (DF, entry)
+//=======================================================================
+
+static Standard_Integer DDataStd_DumpMesh (Draw_Interpretor& di,
+                                           Standard_Integer nb,
+                                           const char** arg)
+{
+  if (nb == 3)
+  {
+    Handle(TDF_Data) DF;
+    if (!DDF::GetDF(arg[1],DF))
+      return 1;
+
+    Handle(TDataXtd_Triangulation) PT;
+    if (!DDF::Find(DF,arg[2], TDataXtd_Triangulation::GetID(), PT))
+    {
+      di << "The attribute doesn't exist at the label.\n";
+      return 1;
+    }
+
+    // Dump of the triangulation.
+    if (PT->Get().IsNull())
+    {
+      di << "No triangulation in the attribute.\n";
+      return 1;
+    }
+
+    di << "Deflection            " << PT->Deflection() <<"\n";
+    di << "Number of nodes       " << PT->NbNodes() << "\n";
+    di << "Number of triangles   " << PT->NbTriangles() << "\n";
+    if (PT->HasUVNodes())
+        di << "It has 2d-nodes\n";
+    if (PT->HasNormals())
+        di << "It has normals\n";
+
+    return 0;
+  }
+  di << "DDataStd_DumpTriangulation : Error\n";
+  return 1;
+}
+
+//=======================================================================
 //function : BasicCommands
 //purpose  : 
 //=======================================================================
@@ -3930,6 +4020,13 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands)
                    "SetReferenceList (DF, entry, elmt1, elmt2, ...  )",
                    __FILE__, DDataStd_SetReferenceList, g);
 
+  theCommands.Add ("SetTriangulation", 
+                   "SetTriangulation (DF, entry, face) - adds label with passed entry to \
+                    DF and put an attribute with the triangulation from passed face",
+                   __FILE__, DDataStd_SetTriangulation, g);
+
+   // Insert before and after (for lists)
+
    theCommands.Add ("InsertBeforeExtStringList", 
                    "InsertBeforeExtStringList (DF, entry, index, value )",
                    __FILE__, DDataStd_InsertBeforeExtStringList, g);
@@ -4236,6 +4333,10 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands)
 
 //=========================================================
 
+   theCommands.Add ("DumpTriangulation", 
+                   "DumpTriangulations (DF, entry) - dumps info about triangulation that \
+                    stored in DF in triangulation attribute of a label with the passed entry",
+                    __FILE__, DDataStd_DumpMesh, g);
 
 //======================================================================
 //======= for internal use
index 5bd7944..b9c7419 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <Poly_Triangulation.hxx>
 
 #include <gp_Pnt.hxx>
 #include <Poly_Triangle.hxx>
-#include <Poly_Triangulation.hxx>
 #include <Standard_DomainError.hxx>
 #include <Standard_NullObject.hxx>
 #include <Standard_Type.hxx>
 
-IMPLEMENT_STANDARD_RTTIEXT(Poly_Triangulation,MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT (Poly_Triangulation, MMgt_TShared)
 
 //=======================================================================
 //function : Poly_Triangulation
@@ -57,8 +57,6 @@ Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    Nodes,
   myTriangles = Triangles;
 }
 
-
-
 //=======================================================================
 //function : Poly_Triangulation
 //purpose  : 
@@ -99,13 +97,23 @@ Handle(Poly_Triangulation) Poly_Triangulation::Copy() const
 }
 
 //=======================================================================
-//function : Deflection
+//function : Poly_Triangulation
 //purpose  : 
 //=======================================================================
 
-Standard_Real Poly_Triangulation::Deflection() const 
+Poly_Triangulation::Poly_Triangulation (const Handle(Poly_Triangulation)& theTriangulation)
+: myDeflection ( theTriangulation->myDeflection ),
+  myNodes(theTriangulation->Nodes()),
+  myTriangles(theTriangulation->Triangles())
 {
-  return myDeflection;
+  if (theTriangulation->HasUVNodes())
+  {
+    myUVNodes = new TColgp_HArray1OfPnt2d(theTriangulation->myUVNodes->Array1());
+  }
+  if (theTriangulation->HasNormals())
+  {
+    myNormals = new TShort_HArray1OfShortReal(theTriangulation->myNormals->Array1());
+  }
 }
 
 //=======================================================================
@@ -113,12 +121,20 @@ Standard_Real Poly_Triangulation::Deflection() const
 //purpose  : 
 //=======================================================================
 
-void Poly_Triangulation::Deflection(const Standard_Real D)
+Standard_Real Poly_Triangulation::Deflection() const
 {
-  myDeflection = D;
+  return myDeflection;
 }
 
+//=======================================================================
+//function : Deflection
+//purpose  : 
+//=======================================================================
 
+void Poly_Triangulation::Deflection (const Standard_Real theDeflection)
+{
+  myDeflection = theDeflection;
+}
 
 //=======================================================================
 //function : RemoveUVNodes
@@ -135,7 +151,7 @@ void Poly_Triangulation::RemoveUVNodes()
 //purpose  : 
 //=======================================================================
 
-const TColgp_Array1OfPnt& Poly_Triangulation::Nodes() const 
+const TColgp_Array1OfPnt& Poly_Triangulation::Nodes() const
 {
   return myNodes;
 }
@@ -151,11 +167,39 @@ TColgp_Array1OfPnt& Poly_Triangulation::ChangeNodes()
 }
 
 //=======================================================================
+//function : Node
+//purpose  : 
+//=======================================================================
+
+const gp_Pnt& Poly_Triangulation::Node (const Standard_Integer theIndex) const
+{
+  if (theIndex < 1 || theIndex > myNodes.Size())
+  {
+    Standard_OutOfRange::Raise ("Poly_Triangulation::Node : index out of range");
+  }
+  return myNodes.Value (theIndex);
+}
+
+//=======================================================================
+//function : ChangeNode
+//purpose  : 
+//=======================================================================
+
+gp_Pnt& Poly_Triangulation::ChangeNode (const Standard_Integer theIndex)
+{
+  if (theIndex < 1 || theIndex > myNodes.Size())
+  {
+    Standard_OutOfRange::Raise ("Poly_Triangulation::ChangeNode : index out of range");
+  }
+  return myNodes.ChangeValue (theIndex);
+}
+
+//=======================================================================
 //function : UVNodes
 //purpose  : 
 //=======================================================================
 
-const TColgp_Array1OfPnt2d& Poly_Triangulation::UVNodes() const 
+const TColgp_Array1OfPnt2d& Poly_Triangulation::UVNodes() const
 {
   return myUVNodes->Array1();
 }
@@ -171,11 +215,39 @@ TColgp_Array1OfPnt2d& Poly_Triangulation::ChangeUVNodes()
 }
 
 //=======================================================================
+//function : UVNode
+//purpose  : 
+//=======================================================================
+
+const gp_Pnt2d& Poly_Triangulation::UVNode (const Standard_Integer theIndex) const
+{
+  if (myUVNodes.IsNull() || theIndex < 1 || theIndex > myUVNodes->Size())
+  {
+    Standard_OutOfRange::Raise ("Poly_Triangulation::UVNode : index out of range");
+  }
+  return myUVNodes->Value (theIndex);
+}
+
+//=======================================================================
+//function : ChangeUVNode
+//purpose  : 
+//=======================================================================
+
+gp_Pnt2d& Poly_Triangulation::ChangeUVNode (const Standard_Integer theIndex)
+{
+  if (myUVNodes.IsNull() || theIndex < 1 || theIndex > myUVNodes->Size())
+  {
+    Standard_OutOfRange::Raise ("Poly_Triangulation::ChangeUVNode : index out of range");
+  }
+  return myUVNodes->ChangeValue (theIndex);
+}
+
+//=======================================================================
 //function : Triangles
 //purpose  : 
 //=======================================================================
 
-const Poly_Array1OfTriangle& Poly_Triangulation::Triangles() const 
+const Poly_Array1OfTriangle& Poly_Triangulation::Triangles() const
 {
   return myTriangles;
 }
@@ -190,14 +262,40 @@ Poly_Array1OfTriangle& Poly_Triangulation::ChangeTriangles()
   return myTriangles;
 }
 
+//=======================================================================
+//function : Triangle
+//purpose  : 
+//=======================================================================
+
+const Poly_Triangle& Poly_Triangulation::Triangle (const Standard_Integer theIndex) const
+{
+  if (theIndex < 1 || theIndex > myTriangles.Size())
+  {
+    Standard_OutOfRange::Raise ("Poly_Triangulation::Triangle : index out of range");
+  }
+  return myTriangles.Value (theIndex);
+}
+
+//=======================================================================
+//function : ChangeTriangle
+//purpose  : 
+//=======================================================================
+
+Poly_Triangle& Poly_Triangulation::ChangeTriangle (const Standard_Integer theIndex)
+{
+  if (theIndex < 1 || theIndex > myTriangles.Size())
+  {
+    Standard_OutOfRange::Raise ("Poly_Triangulation::ChangeTriangle : index out of range");
+  }
+  return myTriangles.ChangeValue (theIndex);
+}
 
 //=======================================================================
 //function : SetNormals
 //purpose  : 
 //=======================================================================
 
-void Poly_Triangulation::SetNormals
-                        (const Handle(TShort_HArray1OfShortReal)& theNormals)
+void Poly_Triangulation::SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals)
 {
 
   if(theNormals.IsNull() || theNormals->Length() != 3*myNbNodes) {
@@ -205,7 +303,6 @@ void Poly_Triangulation::SetNormals
   }
 
   myNormals = theNormals;
-
 }
 
 //=======================================================================
@@ -222,7 +319,6 @@ const TShort_Array1OfShortReal& Poly_Triangulation::Normals() const
   }
 
   return myNormals->Array1();
-
 }
 
 //=======================================================================
@@ -230,7 +326,7 @@ const TShort_Array1OfShortReal& Poly_Triangulation::Normals() const
 //purpose  : 
 //=======================================================================
 
-TShort_Array1OfShortReal& Poly_Triangulation::ChangeNormals() 
+TShort_Array1OfShortReal& Poly_Triangulation::ChangeNormals()
 {
 
   if(myNormals.IsNull() || myNormals->Length() != 3*myNbNodes) {
@@ -239,7 +335,6 @@ TShort_Array1OfShortReal& Poly_Triangulation::ChangeNormals()
   }
 
   return myNormals->ChangeArray1();
-
 }
 
 //=======================================================================
@@ -249,12 +344,45 @@ TShort_Array1OfShortReal& Poly_Triangulation::ChangeNormals()
 
 Standard_Boolean Poly_Triangulation::HasNormals() const
 {
-
   if(myNormals.IsNull() || myNormals->Length() != 3*myNbNodes) {
     return Standard_False;
   }
   return Standard_True;
 }
 
+//=======================================================================
+//function : SetNormal
+//purpose  : 
+//=======================================================================
+
+void Poly_Triangulation::SetNormal (const Standard_Integer theIndex, const gp_Dir& theNormal)
+{
+  if (myNormals.IsNull() || theIndex < 1 || theIndex > myNodes.Size())
+  {
+    Standard_NullObject::Raise("Poly_Triangulation::SetNormal : empty array or index out of range");
+  }
+
+  myNormals->ChangeValue (theIndex * 3 - 2) = (Standard_ShortReal) theNormal.X();
+  myNormals->ChangeValue (theIndex * 3 - 1) = (Standard_ShortReal) theNormal.Y();
+  myNormals->ChangeValue (theIndex * 3)     = (Standard_ShortReal) theNormal.Z();
+}
+
+//=======================================================================
+//function : Normal
+//purpose  : 
+//=======================================================================
+
+const gp_Dir Poly_Triangulation::Normal (const Standard_Integer theIndex) const
+{
+  if (myNormals.IsNull() || theIndex < 1 || theIndex > myNodes.Size())
+  {
+    Standard_NullObject::Raise("Poly_Triangulation::Normal : empty array or index out of range");
+  }
 
+  gp_Dir N;
+  N.SetX(myNormals->Value(theIndex * 3 - 2));
+  N.SetY(myNormals->Value(theIndex * 3 - 1));
+  N.SetZ(myNormals->Value(theIndex * 3));
 
+  return N;
+}
index b4857d2..b605130 100644 (file)
@@ -18,8 +18,7 @@
 #define _Poly_Triangulation_HeaderFile
 
 #include <Standard.hxx>
-#include <Standard_Type.hxx>
-
+#include <Standard_DefineHandle.hxx>
 #include <Standard_Real.hxx>
 #include <Standard_Integer.hxx>
 #include <TColgp_Array1OfPnt.hxx>
@@ -67,7 +66,8 @@ class Poly_Triangulation : public MMgt_TShared
 
 public:
 
-  
+  DEFINE_STANDARD_RTTIEXT(Poly_Triangulation, MMgt_TShared)
+
   //! 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
@@ -75,12 +75,12 @@ public:
   //! 2D nodes will be associated with 3D ones, (i.e. to
   //! 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 with 3D points from Nodes and triangles
   //! from Triangles.
   Standard_EXPORT Poly_Triangulation(const TColgp_Array1OfPnt& Nodes, const Poly_Array1OfTriangle& Triangles);
-  
+
   //! Constructs a triangulation from a set of triangles. The
   //! triangulation is initialized with 3D points from Nodes, 2D points from
   //! UVNodes and triangles from Triangles, where
@@ -89,49 +89,57 @@ public:
   //! from Nodes on the surface approximated by the
   //! constructed triangulation.
   Standard_EXPORT Poly_Triangulation(const TColgp_Array1OfPnt& Nodes, const TColgp_Array1OfPnt2d& UVNodes, const Poly_Array1OfTriangle& Triangles);
-  
+
   //! Creates full copy of current triangulation
   Standard_EXPORT virtual Handle(Poly_Triangulation) Copy() const;
-  
+
+  //! Copy constructor for triangulation.
+  Standard_EXPORT Poly_Triangulation (const Handle(Poly_Triangulation)& theTriangulation);
+
   //! Returns the deflection of this triangulation.
   Standard_EXPORT Standard_Real Deflection() const;
-  
-  //! Sets the deflection of this triangulation to D.
+
+  //! Sets the deflection of this triangulation to theDeflection.
   //! See more on deflection in Polygon2D
-  Standard_EXPORT void Deflection (const Standard_Real D);
-  
+  Standard_EXPORT void Deflection (const Standard_Real theDeflection);
+
   //! Deallocates the UV nodes.
   Standard_EXPORT void RemoveUVNodes();
-  
+
   //! Returns the number of nodes for this triangulation.
-  //! Null if the nodes are not yet defined.
-    Standard_Integer NbNodes() const;
-  
+  Standard_Integer NbNodes() const { return myNbNodes; }
+
   //! Returns the number of triangles for this triangulation.
-  //! Null if the Triangles are not yet defined.
-    Standard_Integer NbTriangles() const;
-  
-  //! Returns true if 2D nodes are associated with 3D nodes for
-  //! this triangulation.
-    Standard_Boolean HasUVNodes() const;
-  
+  Standard_Integer NbTriangles() const { return myNbTriangles; }
+
+  //! Returns Standard_True if 2D nodes are associated with 3D nodes for this triangulation.
+  Standard_Boolean HasUVNodes() const { return !myUVNodes.IsNull(); }
+
   //! Returns the table of 3D nodes (3D points) for this triangulation.
   Standard_EXPORT const TColgp_Array1OfPnt& Nodes() const;
-  
+
   //! Returns the table of 3D nodes (3D points) for this triangulation.
   //! The returned array is
   //! shared. Therefore if the table is selected by reference, you
   //! can, by simply modifying it, directly modify the data
   //! structure of this triangulation.
   Standard_EXPORT TColgp_Array1OfPnt& ChangeNodes();
-  
+
+  //! Returns node at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT const gp_Pnt& Node (const Standard_Integer theIndex) const;
+
+  //! Give access to the node at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT gp_Pnt& ChangeNode (const Standard_Integer theIndex);
+
   //! Returns the table of 2D nodes (2D points) associated with
   //! each 3D node of this triangulation.
   //! The function HasUVNodes  checks if 2D nodes
   //! are associated with the 3D nodes of this triangulation.
   //! Const reference on the 2d nodes values.
   Standard_EXPORT const TColgp_Array1OfPnt2d& UVNodes() const;
-  
+
   //! Returns the table of 2D nodes (2D points) associated with
   //! each 3D node of this triangulation.
   //! Function ChangeUVNodes shares  the returned array.
@@ -139,56 +147,65 @@ public:
   //! you can, by simply modifying it, directly modify the data
   //! structure of this triangulation.
   Standard_EXPORT TColgp_Array1OfPnt2d& ChangeUVNodes();
-  
+
+  //! Returns UVNode at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT const gp_Pnt2d& UVNode (const Standard_Integer theIndex) const;
+
+  //! Give access to the UVNode at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT gp_Pnt2d& ChangeUVNode (const Standard_Integer theIndex);
+
   //! Returns the table of triangles for this triangulation.
   Standard_EXPORT const Poly_Array1OfTriangle& Triangles() const;
-  
+
   //! Returns the table of triangles for this triangulation.
   //! Function ChangeUVNodes shares  the returned array.
   //! Therefore if the table is selected by reference,
   //! you can, by simply modifying it, directly modify the data
   //! structure of this triangulation.
   Standard_EXPORT Poly_Array1OfTriangle& ChangeTriangles();
-  
+
+  //! Returns triangle at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbTriangles.
+  Standard_EXPORT const Poly_Triangle& Triangle (const Standard_Integer theIndex) const;
+
+  //! Give access to the triangle at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbTriangles.
+  Standard_EXPORT Poly_Triangle& ChangeTriangle (const Standard_Integer theIndex);
+
   //! Sets the table of node normals.
   //! raises exception if length of theNormals != 3*NbNodes
   Standard_EXPORT void SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals);
-  
+
+  //! Returns the table of node normals.
   Standard_EXPORT const TShort_Array1OfShortReal& Normals() const;
-  
-  Standard_EXPORT TShort_Array1OfShortReal& ChangeNormals();
-  
-  Standard_EXPORT Standard_Boolean HasNormals() const;
 
+  //! Gives access to the table of node normals.
+  Standard_EXPORT TShort_Array1OfShortReal& ChangeNormals();
 
+  //! Returns Standard_True if nodal normals are defined.
+  Standard_EXPORT Standard_Boolean HasNormals() const;
 
+  //! @return normal at the given index.
+  //! Raises Standard_OutOfRange exception.
+  Standard_EXPORT const gp_Dir Normal (const Standard_Integer theIndex) const;
 
-  DEFINE_STANDARD_RTTIEXT(Poly_Triangulation,MMgt_TShared)
+  //! Changes normal at the given index.
+  //! Raises Standard_OutOfRange exception.
+  Standard_EXPORT void SetNormal (const Standard_Integer theIndex,
+                                  const gp_Dir&          theNormal);
 
 protected:
 
-
-
-
-private:
-
-
-  Standard_Real myDeflection;
-  Standard_Integer myNbNodes;
-  Standard_Integer myNbTriangles;
-  TColgp_Array1OfPnt myNodes;
-  Handle(TColgp_HArray1OfPnt2d) myUVNodes;
-  Poly_Array1OfTriangle myTriangles;
-  Handle(TShort_HArray1OfShortReal) myNormals;
-
+  Standard_Real                      myDeflection;
+  Standard_Integer                   myNbNodes;
+  Standard_Integer                   myNbTriangles;
+  TColgp_Array1OfPnt                 myNodes;
+  Handle(TColgp_HArray1OfPnt2d)      myUVNodes;
+  Poly_Array1OfTriangle              myTriangles;
+  Handle(TShort_HArray1OfShortReal)  myNormals;
 
 };
 
-
-#include <Poly_Triangulation.lxx>
-
-
-
-
-
 #endif // _Poly_Triangulation_HeaderFile
index 1c2ca6c..28cddb1 100644 (file)
@@ -27,3 +27,5 @@ TDataXtd_Presentation.hxx
 TDataXtd_Presentation.cxx
 TDataXtd_Shape.cxx
 TDataXtd_Shape.hxx
+TDataXtd_Triangulation.cxx
+TDataXtd_Triangulation.hxx
index 12ee640..1be8efb 100644 (file)
@@ -34,7 +34,7 @@ class TDataXtd_Plane;
 class TDataXtd_Pattern;
 class TDataXtd_PatternStd;
 class TDataXtd_Shape;
-
+class TDataXtd_Triangulation;
 
 //! This  package  defines  extension of standard attributes for
 //! modelling  (mainly for work with geometry).
@@ -84,6 +84,7 @@ friend class TDataXtd_Plane;
 friend class TDataXtd_Pattern;
 friend class TDataXtd_PatternStd;
 friend class TDataXtd_Shape;
+friend class TDataXtd_Triangulation;
 
 };
 
diff --git a/src/TDataXtd/TDataXtd_Triangulation.cxx b/src/TDataXtd/TDataXtd_Triangulation.cxx
new file mode 100644 (file)
index 0000000..60d0249
--- /dev/null
@@ -0,0 +1,322 @@
+// Created on: 2016-11-10
+// Created by: Anton KOZULIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <TDataXtd_Triangulation.hxx>
+#include <Standard_GUID.hxx>
+#include <Standard_Type.hxx>
+#include <TDF_Attribute.hxx>
+#include <TDF_Label.hxx>
+#include <TDF_RelocationTable.hxx>
+
+//=======================================================================
+//function : GetID
+//purpose  : Returns the ID of the triangulation attribute.
+//=======================================================================
+const Standard_GUID& TDataXtd_Triangulation::GetID()
+{
+  static Standard_GUID TDataXtd_TriangulationID ("27AE2C44-60B0-41AE-AC18-BA3FDA538D03");
+  return TDataXtd_TriangulationID; 
+}
+
+//=======================================================================
+//function : Set
+//purpose  : Finds or creates a triangulation attribute.
+//=======================================================================
+Handle(TDataXtd_Triangulation) TDataXtd_Triangulation::Set(const TDF_Label& theLabel)
+{
+  Handle(TDataXtd_Triangulation) A;
+  if (!theLabel.FindAttribute (TDataXtd_Triangulation::GetID(), A))
+  {
+    A = new TDataXtd_Triangulation;
+    theLabel.AddAttribute(A);
+  }
+  return A;
+}
+
+//=======================================================================
+//function : Set
+//purpose  : Finds or creates a triangulation attribute.
+//           Initializes the attribute by a Poly_Triangulation object.
+//=======================================================================
+Handle(TDataXtd_Triangulation) TDataXtd_Triangulation::Set(const TDF_Label& theLabel, const Handle(Poly_Triangulation)& theMesh)
+{
+  Handle(TDataXtd_Triangulation) M = TDataXtd_Triangulation::Set(theLabel);
+  M->Set(theMesh);
+  return M;
+}
+
+//=======================================================================
+//function : TDataXtd_Triangulation
+//purpose  : A constructor.
+//           Don't use it directly, 
+//           use please the static method Set(),
+//           which returns the attribute attached to a label.
+//=======================================================================
+TDataXtd_Triangulation::TDataXtd_Triangulation()
+{
+
+}
+
+//=======================================================================
+//function : TDataXtd_Triangulation
+//purpose  : Sets the triangulation.
+//=======================================================================
+void TDataXtd_Triangulation::Set(const Handle(Poly_Triangulation)& theTriangulation)
+{
+  Backup();
+  myTriangulation = theTriangulation;
+}
+
+//=======================================================================
+//function : TDataXtd_Triangulation
+//purpose  : Returns the underlying mesh.
+//=======================================================================
+const Handle(Poly_Triangulation)& TDataXtd_Triangulation::Get() const
+{
+  return myTriangulation;
+}
+
+// Poly_Triangulation methods
+
+// The methods are "covered" by this attribute to prevent direct modification of the mesh.
+// There is no performance problem to call Poly_Triangulation method through this attribute.
+// The most of the methods are considered as "inline" by the compiler in release mode.
+
+//=======================================================================
+//function : Deflection
+//purpose  : Returns the deflection of this triangulation.
+//=======================================================================
+Standard_Real TDataXtd_Triangulation::Deflection() const
+{
+  return myTriangulation->Deflection();
+}
+
+//=======================================================================
+//function : Deflection
+//purpose  : Sets the deflection of this triangulation to theDeflection.
+//           See more on deflection in Polygon2D
+//=======================================================================
+void TDataXtd_Triangulation::Deflection (const Standard_Real theDeflection)
+{
+  Backup();
+  myTriangulation->Deflection(theDeflection);
+}
+
+//=======================================================================
+//function : RemoveUVNodes
+//purpose  : Deallocates the UV nodes.
+//=======================================================================
+void TDataXtd_Triangulation::RemoveUVNodes()
+{
+  Backup();
+  myTriangulation->RemoveUVNodes();
+}
+
+//=======================================================================
+//function : NbNodes
+//purpose  : return the number of nodes for this triangulation.
+//=======================================================================
+Standard_Integer TDataXtd_Triangulation::NbNodes() const
+{
+  return myTriangulation->NbNodes();
+}
+
+//=======================================================================
+//function : NbTriangles
+//purpose  : return the number of triangles for this triangulation.
+//=======================================================================
+Standard_Integer TDataXtd_Triangulation::NbTriangles() const
+{
+  return myTriangulation->NbTriangles();
+}
+
+//=======================================================================
+//function : HasUVNodes
+//purpose  : return Standard_True if 2D nodes are associated with 3D nodes for this triangulation.
+//=======================================================================
+Standard_Boolean TDataXtd_Triangulation::HasUVNodes() const
+{
+  return myTriangulation->HasUVNodes();
+}
+
+//=======================================================================
+//function : Node
+//purpose  : return node at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+//=======================================================================
+const gp_Pnt& TDataXtd_Triangulation::Node (const Standard_Integer theIndex) const
+{
+  return myTriangulation->Node(theIndex);
+}
+
+//=======================================================================
+//function : SetNode
+//purpose  : The method differs from Poly_Triangulation
+//           Sets a node at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+//=======================================================================
+void TDataXtd_Triangulation::SetNode (const Standard_Integer theIndex, const gp_Pnt& theNode)
+{
+  Backup();
+  myTriangulation->ChangeNode(theIndex) = theNode;
+}
+
+//=======================================================================
+//function : UVNode
+//purpose  : return UVNode at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+//=======================================================================
+const gp_Pnt2d& TDataXtd_Triangulation::UVNode (const Standard_Integer theIndex) const
+{
+  return myTriangulation->UVNode(theIndex);
+}
+
+//=======================================================================
+//function : SetUVNode
+//purpose  : The method differs from Poly_Triangulation
+//           Sets a UVNode at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+//=======================================================================
+void TDataXtd_Triangulation::SetUVNode (const Standard_Integer theIndex, const gp_Pnt2d& theUVNode)
+{
+  Backup();
+  myTriangulation->ChangeUVNode(theIndex) = theUVNode;
+}
+
+//=======================================================================
+//function : Triangle
+//purpose  : return triangle at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbTriangles.
+//=======================================================================
+const Poly_Triangle& TDataXtd_Triangulation::Triangle (const Standard_Integer theIndex) const
+{
+  return myTriangulation->Triangle(theIndex);
+}
+
+//=======================================================================
+//function : SetTriangle
+//purpose  : The method differs from Poly_Triangulation
+//           Sets a triangle at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbTriangles.
+//=======================================================================
+void TDataXtd_Triangulation::SetTriangle (const Standard_Integer theIndex, const Poly_Triangle& theTriangle)
+{
+  Backup();
+  myTriangulation->ChangeTriangle(theIndex) = theTriangle;
+}
+
+//=======================================================================
+//function : SetNormals
+//purpose  : Sets the table of node normals.
+//           Raises exception if length of theNormals = 3 * NbNodes
+//=======================================================================
+void TDataXtd_Triangulation::SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals)
+{
+  Backup();
+  myTriangulation->SetNormals(theNormals);
+}
+
+//=======================================================================
+//function : SetNormal
+//purpose  : Changes normal at the given index.
+//           Raises Standard_OutOfRange exception.
+//=======================================================================
+void TDataXtd_Triangulation::SetNormal (const Standard_Integer theIndex,
+                               const gp_Dir&          theNormal)
+{
+  Backup();
+  myTriangulation->SetNormal(theIndex, theNormal);
+}
+
+//=======================================================================
+//function : HasNormals
+//purpose  : Returns Standard_True if nodal normals are defined.
+//=======================================================================
+Standard_Boolean TDataXtd_Triangulation::HasNormals() const
+{
+  return myTriangulation->HasNormals();
+}
+
+//=======================================================================
+//function : Normal
+//purpose  : return normal at the given index.
+//           Raises Standard_OutOfRange exception.
+//=======================================================================
+const gp_Dir TDataXtd_Triangulation::Normal (const Standard_Integer theIndex) const
+{
+  return myTriangulation->Normal(theIndex);
+}
+
+//=======================================================================
+//function : ID
+//purpose  : 
+//=======================================================================
+const Standard_GUID& TDataXtd_Triangulation::ID () const
+{
+  return GetID();
+}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  : 
+//=======================================================================
+Handle(TDF_Attribute) TDataXtd_Triangulation::NewEmpty () const
+{  
+  return new TDataXtd_Triangulation(); 
+}
+
+//=======================================================================
+//function : Restore
+//purpose  : 
+//=======================================================================
+void TDataXtd_Triangulation::Restore(const Handle(TDF_Attribute)& theAttribute)
+{
+  myTriangulation.Nullify();
+  Handle(TDataXtd_Triangulation) M = Handle(TDataXtd_Triangulation)::DownCast(theAttribute);
+  if (!M->myTriangulation.IsNull())
+  {
+    Handle(Poly_Triangulation) T = M->myTriangulation->Copy();
+    if (!T.IsNull())
+      myTriangulation = T;
+  }
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : 
+//=======================================================================
+void TDataXtd_Triangulation::Paste (const Handle(TDF_Attribute)& theIntoAttribute,
+                                    const Handle(TDF_RelocationTable)& ) const
+{
+  Handle(TDataXtd_Triangulation) M = Handle(TDataXtd_Triangulation)::DownCast(theIntoAttribute);
+  M->myTriangulation.Nullify();
+  if (!myTriangulation.IsNull())
+  {
+      Handle(Poly_Triangulation) T = myTriangulation->Copy();
+      if (!T.IsNull())
+        M->myTriangulation = T;
+  }
+}
+
+//=======================================================================
+//function : Dump
+//purpose  : 
+//=======================================================================
+Standard_OStream& TDataXtd_Triangulation::Dump (Standard_OStream& anOS) const
+{
+  anOS << "Triangulation";
+  //TODO: Make a good dump.
+  return anOS;
+}
diff --git a/src/TDataXtd/TDataXtd_Triangulation.hxx b/src/TDataXtd/TDataXtd_Triangulation.hxx
new file mode 100644 (file)
index 0000000..b127dd8
--- /dev/null
@@ -0,0 +1,162 @@
+// Created on: 2016-11-10
+// Created by: Anton KOZULIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _TDataXtd_Triangulation_HeaderFile
+#define _TDataXtd_Triangulation_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+
+#include <Poly_Triangulation.hxx>
+#include <TDF_Attribute.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_Integer.hxx>
+#include <Standard_OStream.hxx>
+class Standard_GUID;
+class TDF_Label;
+class TDF_Attribute;
+class TDF_RelocationTable;
+
+class TDataXtd_Triangulation;
+DEFINE_STANDARD_HANDLE(TDataXtd_Triangulation, TDF_Attribute)
+
+//! An Ocaf attribute containing a mesh (Poly_Triangulation).
+//! It duplicates all methods from Poly_Triangulation.
+//! It is highly recommended to modify the mesh through the methods of this attribute,
+//! but not directly via the underlying Poly_Triangulation object.
+//! In this case Undo/Redo will work fine and robust.
+class TDataXtd_Triangulation : public TDF_Attribute
+{
+public:
+
+  //! Static methods
+  //  ==============
+
+  //! Returns the ID of the triangulation attribute.
+  Standard_EXPORT static const Standard_GUID& GetID();
+  
+  //! Finds or creates a triangulation attribute.
+  Standard_EXPORT static Handle(TDataXtd_Triangulation) Set(const TDF_Label& theLabel);
+
+  //! Finds or creates a triangulation attribute.
+  //! Initializes the attribute by a Poly_Triangulation object.
+  Standard_EXPORT static Handle(TDataXtd_Triangulation) Set(const TDF_Label& theLabel, const Handle(Poly_Triangulation)& theTriangulation);
+
+  //! Object methods
+  //  ==============
+
+  //! A constructor.
+  //! Don't use it directly, 
+  //! use please the static method Set(),
+  //! which returns the attribute attached to a label.
+  Standard_EXPORT TDataXtd_Triangulation();
+
+  //! Sets the triangulation.
+  Standard_EXPORT void Set(const Handle(Poly_Triangulation)& theTriangulation);
+
+  //! Returns the underlying triangulation.
+  Standard_EXPORT const Handle(Poly_Triangulation)& Get() const;
+
+
+  //! Poly_Triangulation methods
+  //  =================
+
+  //! The methods are "covered" by this attribute to prevent direct modification of the mesh.
+  //! There is no performance problem to call Poly_Triangulation method through this attribute.
+  //! The most of the methods are considered as "inline" by the compiler in release mode.
+
+  //! Returns the deflection of this triangulation.
+  Standard_EXPORT Standard_Real Deflection() const;
+
+  //! Sets the deflection of this triangulation to theDeflection.
+  //! See more on deflection in Polygon2D
+  Standard_EXPORT void Deflection (const Standard_Real theDeflection);
+
+  //! Deallocates the UV nodes.
+  Standard_EXPORT void RemoveUVNodes();
+
+  //! @return the number of nodes for this triangulation.
+  Standard_EXPORT Standard_Integer NbNodes() const;
+
+  //! @return the number of triangles for this triangulation.
+  Standard_EXPORT Standard_Integer NbTriangles() const;
+
+  //! @return Standard_True if 2D nodes are associated with 3D nodes for this triangulation.
+  Standard_EXPORT Standard_Boolean HasUVNodes() const;
+
+  //! @return node at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT const gp_Pnt& Node (const Standard_Integer theIndex) const;
+
+  //! The method differs from Poly_Triangulation!
+  //! Sets a node at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT void SetNode (const Standard_Integer theIndex, const gp_Pnt& theNode);
+
+  //! @return UVNode at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT const gp_Pnt2d& UVNode (const Standard_Integer theIndex) const;
+
+  //! The method differs from Poly_Triangulation!
+  //! Sets a UVNode at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+  Standard_EXPORT void SetUVNode (const Standard_Integer theIndex, const gp_Pnt2d& theUVNode);
+
+  //! @return triangle at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbTriangles.
+  Standard_EXPORT const Poly_Triangle& Triangle (const Standard_Integer theIndex) const;
+
+  //! The method differs from Poly_Triangulation!
+  //! Sets a triangle at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbTriangles.
+  Standard_EXPORT void SetTriangle (const Standard_Integer theIndex, const Poly_Triangle& theTriangle);
+
+  //! Sets the table of node normals.
+  //! Raises exception if length of theNormals != 3 * NbNodes
+  Standard_EXPORT void SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals);
+
+  //! Changes normal at the given index.
+  //! Raises Standard_OutOfRange exception.
+  Standard_EXPORT void SetNormal (const Standard_Integer theIndex,
+                                  const gp_Dir&          theNormal);
+
+  //! Returns Standard_True if nodal normals are defined.
+  Standard_EXPORT Standard_Boolean HasNormals() const;
+
+  //! @return normal at the given index.
+  //! Raises Standard_OutOfRange exception.
+  Standard_EXPORT const gp_Dir Normal (const Standard_Integer theIndex) const;
+
+  //! Inherited attribute methods
+  //  ===========================
+
+  Standard_EXPORT const Standard_GUID& ID() const Standard_OVERRIDE;
+
+  Standard_EXPORT void Restore (const Handle(TDF_Attribute)& theAttribute) Standard_OVERRIDE;
+
+  Standard_EXPORT Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE;
+
+  Standard_EXPORT void Paste (const Handle(TDF_Attribute)& Into, const Handle(TDF_RelocationTable)& RT) const Standard_OVERRIDE;
+
+  Standard_EXPORT virtual Standard_OStream& Dump (Standard_OStream& anOS) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTI_INLINE(TDataXtd_Triangulation,TDF_Attribute)
+
+private:
+
+  Handle(Poly_Triangulation) myTriangulation;
+};
+
+#endif // _TDataXtd_Triangulation_HeaderFile
index da67ae8..cffce8e 100644 (file)
@@ -20,3 +20,5 @@ XmlMDataXtd_PositionDriver.hxx
 XmlMDataXtd_PositionDriver.cxx
 XmlMDataXtd_PresentationDriver.hxx
 XmlMDataXtd_PresentationDriver.cxx
+XmlMDataXtd_TriangulationDriver.cxx
+XmlMDataXtd_TriangulationDriver.hxx
index 7059f9c..17f28e2 100644 (file)
@@ -25,6 +25,7 @@
 #include <XmlMDataXtd_PlaneDriver.hxx>
 #include <XmlMDataXtd_PointDriver.hxx>
 #include <XmlMDataXtd_ShapeDriver.hxx>
+#include <XmlMDataXtd_TriangulationDriver.hxx>
 #include <XmlMDF_ADriverTable.hxx>
 
 #include <XmlMDataXtd_PresentationDriver.hxx>
@@ -46,6 +47,7 @@ void XmlMDataXtd::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
   aDriverTable->AddDriver(new XmlMDataXtd_ConstraintDriver    (anMsgDrv));
   aDriverTable->AddDriver(new XmlMDataXtd_PlacementDriver     (anMsgDrv));
   aDriverTable->AddDriver(new XmlMDataXtd_PatternStdDriver    (anMsgDrv));
+  aDriverTable->AddDriver(new XmlMDataXtd_TriangulationDriver (anMsgDrv));
 
   aDriverTable->AddDriver(new XmlMDataXtd_PresentationDriver  (anMsgDrv));
   aDriverTable->AddDriver(new XmlMDataXtd_PositionDriver      (anMsgDrv));
index 18a2d2f..9c32ada 100644 (file)
@@ -29,7 +29,7 @@ class XmlMDataXtd_GeometryDriver;
 class XmlMDataXtd_ConstraintDriver;
 class XmlMDataXtd_PlacementDriver;
 class XmlMDataXtd_PatternStdDriver;
-
+class XmlMDataXtd_TriangulationDriver;
 
 //! Storage and Retrieval drivers for modelling attributes.
 //! Transient attributes are defined in package TDataXtd.
@@ -69,6 +69,7 @@ friend class XmlMDataXtd_GeometryDriver;
 friend class XmlMDataXtd_ConstraintDriver;
 friend class XmlMDataXtd_PlacementDriver;
 friend class XmlMDataXtd_PatternStdDriver;
+friend class XmlMDataXtd_TriangulationDriver;
 
 };
 
diff --git a/src/XmlMDataXtd/XmlMDataXtd_TriangulationDriver.cxx b/src/XmlMDataXtd/XmlMDataXtd_TriangulationDriver.cxx
new file mode 100644 (file)
index 0000000..082cdb2
--- /dev/null
@@ -0,0 +1,213 @@
+// Created on: 2016-11-10
+// Created by: Anton KOZULIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <XmlMDataXtd_TriangulationDriver.hxx>
+#include <CDM_MessageDriver.hxx>
+#include <NCollection_LocalArray.hxx>
+#include <Standard_Type.hxx>
+#include <TDF_Attribute.hxx>
+#include <XmlObjMgt.hxx>
+#include <XmlObjMgt_Persistent.hxx>
+#include <TDataXtd_Triangulation.hxx>
+#include <LDOM_OSStream.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(XmlMDataXtd_TriangulationDriver,XmlMDF_ADriver)
+IMPLEMENT_DOMSTRING (TriangString, "triangulation")
+IMPLEMENT_DOMSTRING (NullString, "null")
+IMPLEMENT_DOMSTRING (ExistString, "exists")
+
+//=======================================================================
+//function : XmlMDataXtd_TriangulationDriver
+//purpose  : Constructor
+//=======================================================================
+XmlMDataXtd_TriangulationDriver::XmlMDataXtd_TriangulationDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
+  : XmlMDF_ADriver (theMsgDriver, NULL)
+{
+
+}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  : 
+//=======================================================================
+Handle(TDF_Attribute) XmlMDataXtd_TriangulationDriver::NewEmpty() const
+{
+  return new TDataXtd_Triangulation();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : persistent -> transient (retrieve)
+//=======================================================================
+Standard_Boolean XmlMDataXtd_TriangulationDriver::Paste(const XmlObjMgt_Persistent&  theSource,
+                                                        const Handle(TDF_Attribute)& theTarget,
+                                                        XmlObjMgt_RRelocationTable&  ) const
+{
+  const XmlObjMgt_Element& element = theSource;
+  Handle(TDataXtd_Triangulation) attribute = Handle(TDataXtd_Triangulation)::DownCast(theTarget);
+
+  // Read the FirstIndex; if the attribute is absent initialize to 1
+  XmlObjMgt_DOMString triangStatus = element.getAttribute(::TriangString());
+  if (triangStatus == NULL ||
+      triangStatus.Type() != LDOMBasicString::LDOM_AsciiDoc ||
+      strcmp(triangStatus.GetString(), ::ExistString().GetString()))
+  {
+    // No triangulation.
+    return Standard_True;
+  }
+
+  // Get mesh as a string.
+  const XmlObjMgt_DOMString& data = XmlObjMgt::GetStringValue(element);
+  std::stringstream stream(std::string(data.GetString()));
+
+  Standard_Integer i, n1, n2, n3;
+  Standard_Integer nbNodes, nbTriangles, hasUV;
+  Standard_Real deflection, x, y, z;
+
+  stream >> nbNodes >> nbTriangles >> hasUV;
+  GetReal(stream, deflection);
+
+  TColgp_Array1OfPnt Nodes(1, nbNodes);
+  TColgp_Array1OfPnt2d UVNodes(1, nbNodes);
+
+  for (i = 1; i <= nbNodes; i++)
+  {
+    GetReal(stream, x);
+    GetReal(stream, y);
+    GetReal(stream, z);
+    Nodes(i).SetCoord(x, y, z);
+  }
+
+  if (hasUV)
+  {
+    for (i = 1; i <= nbNodes; i++) {
+      GetReal(stream, x);
+      GetReal(stream, y);
+      UVNodes(i).SetCoord(x,y);
+    }
+  }
+
+  // read the triangles
+  Poly_Array1OfTriangle Triangles(1, nbTriangles);
+  for (i = 1; i <= nbTriangles; i++)
+  {
+    stream >> n1 >> n2 >> n3;
+    Triangles(i).Set(n1, n2, n3);
+  }
+
+  Handle(Poly_Triangulation) PT;
+  if (hasUV) PT =  new Poly_Triangulation(Nodes, UVNodes, Triangles);
+  else PT = new Poly_Triangulation(Nodes, Triangles);
+  PT->Deflection(deflection);
+
+  attribute->Set(PT);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : transient -> persistent (store)
+//=======================================================================
+void XmlMDataXtd_TriangulationDriver::Paste(const Handle(TDF_Attribute)& theSource,
+                                            XmlObjMgt_Persistent&        theTarget,
+                                            XmlObjMgt_SRelocationTable&  ) const
+{
+  const Handle(TDataXtd_Triangulation) attribute = Handle(TDataXtd_Triangulation)::DownCast(theSource);
+  if (attribute->Get().IsNull())
+    theTarget.Element().setAttribute(::TriangString(), ::NullString());
+  else
+  {
+    theTarget.Element().setAttribute(::TriangString(), ::ExistString());
+
+    Standard_Integer i, n1, n2, n3;
+
+    // Analyse the size of the triangulation
+    // (to allocate properly the string array).
+    const Handle(Poly_Triangulation)& PT = attribute->Get();
+    Standard_Integer nbNodes = PT->NbNodes();
+    Standard_Integer nbTriangles = PT->NbTriangles();
+    Standard_Integer size = PT->NbNodes();
+    size *= 3 * 25; // 3 coordinates for a node * 25 characters are used to represent a coordinate (double) in XML
+    if (PT->HasUVNodes()) 
+      size += 2 * 25 * nbNodes; // 2 coordinates for a 2D node * 25 characters are used to represent a coordinate (double) in XML
+    size += 3 * 10 * nbTriangles; // space for triangles
+    size *= 2; // just in case :-)
+    if (!size)
+      size = 1;
+
+    // Allocate a string stream.
+    LDOM_OSStream stream(size);
+    stream.precision(17);
+
+    stream << nbNodes << " " << nbTriangles << " ";
+    stream << ((PT->HasUVNodes()) ? "1" : "0") << " ";
+
+    stream << PT->Deflection() << "\n";
+
+    // write the 3d nodes
+    const TColgp_Array1OfPnt& Nodes = PT->Nodes();
+    for (i = 1; i <= nbNodes; i++)
+    {
+      stream << Nodes(i).X() << " "
+             << Nodes(i).Y() << " "
+             << Nodes(i).Z() << " ";
+    }
+
+    if (PT->HasUVNodes())
+    {
+      const TColgp_Array1OfPnt2d& UVNodes = PT->UVNodes();
+      for (i = 1; i <= nbNodes; i++)
+      {
+        stream << UVNodes(i).X() << " "
+               << UVNodes(i).Y() << " ";
+      }
+    }
+
+    const Poly_Array1OfTriangle& Triangles = PT->Triangles();
+    for (i = 1; i <= nbTriangles; i++)
+    {
+      Triangles(i).Get(n1, n2, n3);
+      stream << n1 << " "
+             << n2 << " "
+             << n3 << " ";
+    }
+
+    stream << ends;
+
+    Standard_Character* dump = (Standard_Character*)stream.str(); // copying! Don't forget to delete it.
+    XmlObjMgt::SetStringValue(theTarget, dump, Standard_True);
+    delete[] dump;
+  }
+}
+
+//=======================================================================
+//function : GetReal
+//purpose  : 
+//=======================================================================
+
+void XmlMDataXtd_TriangulationDriver::GetReal(Standard_IStream& IS,Standard_Real& theValue) const
+{
+  theValue = 0.;
+  if (IS.eof()) 
+    return;
+
+  char buffer[256];
+  buffer[0] = '\0';
+  std::streamsize anOldWide = IS.width(256);
+  IS >> buffer;
+  IS.width(anOldWide);
+  theValue = Strtod(buffer, NULL);
+}
diff --git a/src/XmlMDataXtd/XmlMDataXtd_TriangulationDriver.hxx b/src/XmlMDataXtd/XmlMDataXtd_TriangulationDriver.hxx
new file mode 100644 (file)
index 0000000..a3707d3
--- /dev/null
@@ -0,0 +1,53 @@
+// Created on: 2016-11-10
+// Created by: Anton KOZULIN
+// Copyright (c) 2016 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _XmlMDataXtd_TriangulationDriver_HeaderFile
+#define _XmlMDataXtd_TriangulationDriver_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+
+#include <XmlMDF_ADriver.hxx>
+#include <Standard_Boolean.hxx>
+#include <XmlObjMgt_RRelocationTable.hxx>
+#include <XmlObjMgt_SRelocationTable.hxx>
+class CDM_MessageDriver;
+class TDF_Attribute;
+class XmlObjMgt_Persistent;
+
+DEFINE_STANDARD_HANDLE(XmlMDataXtd_TriangulationDriver, XmlMDF_ADriver)
+
+//! TDataStd_Mesh attribute XML Driver.
+class XmlMDataXtd_TriangulationDriver : public XmlMDF_ADriver
+{
+
+public:
+
+  Standard_EXPORT XmlMDataXtd_TriangulationDriver(const Handle(CDM_MessageDriver)& theMessageDriver);
+
+  Standard_EXPORT Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE;
+
+  Standard_EXPORT Standard_Boolean Paste (const XmlObjMgt_Persistent& Source, const Handle(TDF_Attribute)& Target, XmlObjMgt_RRelocationTable& RelocTable) const Standard_OVERRIDE;
+
+  Standard_EXPORT void Paste (const Handle(TDF_Attribute)& Source, XmlObjMgt_Persistent& Target, XmlObjMgt_SRelocationTable& RelocTable) const Standard_OVERRIDE;
+
+  DEFINE_STANDARD_RTTIEXT(XmlMDataXtd_TriangulationDriver,XmlMDF_ADriver)
+
+private:
+
+  void GetReal(Standard_IStream& IS, Standard_Real& theValue) const;
+};
+
+#endif // _XmlMDataXtd_TriangulationDriver_HeaderFile
diff --git a/tests/caf/basic/N1 b/tests/caf/basic/N1
new file mode 100644 (file)
index 0000000..3ab536f
--- /dev/null
@@ -0,0 +1,70 @@
+#INTERFACE CAF
+# Basic attributes
+#
+# Testing attribute: TDataStd_Triangulation
+#
+# Testing command:   SetTriangulation
+# Testing command:   DumpTriangulation
+#
+
+puts "caf001-N1"
+set FileName_1 $imagedir/caf001-N1_1.cbf
+set FileName_2 $imagedir/caf001-N1_2.cbf
+
+# Make a box and produce triangulation
+psphere s 10
+explode s f
+incmesh s_1 10 -a 90
+
+# Set triangulation from the box's face
+Format D BinOcaf
+SetTriangulation D 0:1 s_1
+CommitCommand D
+
+# Save document on disk.
+# First transaction before Undo/Redo
+SaveAs D $FileName_1
+
+incmesh s_1 1 -a 15
+
+OpenCommand D
+SetTriangulation D 0:1 s_1
+CommitCommand D
+
+# Save document on disk.
+# Second transaction before Undo/Redo
+SaveAs D $FileName_2
+
+# Test Undo/Redo.
+Undo D
+
+# Print the mesh data after first transaction
+set dump1_bfr [DumpTriangulation D 0:1]
+
+Redo D
+
+# Print the mesh data after second transaction
+set dump2_bfr [DumpTriangulation D 0:1]
+
+Close D
+
+# Restore data after first and second transactions
+Open $FileName_1 D_1
+Open $FileName_2 D_2
+
+set dump1_aft [DumpTriangulation D_1 0:1]
+set dump2_aft [DumpTriangulation D_2 0:1]
+
+Close D_1
+Close D_2
+
+# Check data
+if { ${dump1_bfr}!=${dump1_aft} } {
+  puts "TDataStd_Triangulation attribute: Error"
+  return
+}
+if { ${dump2_bfr}!=${dump2_aft} } {
+  puts "TDataStd_Triangulation attribute: Error"
+  return
+}
+puts "TDataStd_Triangulation attribute: OK"
diff --git a/tests/caf/basic/N2 b/tests/caf/basic/N2
new file mode 100644 (file)
index 0000000..96c692c
--- /dev/null
@@ -0,0 +1,70 @@
+#INTERFACE CAF
+# Basic attributes
+#
+# Testing attribute: TDataStd_Triangulation
+#
+# Testing command:   SetTriangulation
+# Testing command:   DumpTriangulation
+#
+
+puts "caf001-N2"
+set FileName_1 $imagedir/caf001-N2_1.xml
+set FileName_2 $imagedir/caf001-N2_2.xml
+
+# Make a box and produce triangulation
+psphere s 10
+explode s f
+incmesh s_1 10 -a 90
+
+# Set triangulation from the box's face
+Format D XmlOcaf
+SetTriangulation D 0:1 s_1
+CommitCommand D
+
+# Save document on disk.
+# First transaction before Undo/Redo
+SaveAs D $FileName_1
+
+incmesh s_1 1 -a 15
+
+OpenCommand D
+SetTriangulation D 0:1 s_1
+CommitCommand D
+
+# Save document on disk.
+# Second transaction before Undo/Redo
+SaveAs D $FileName_2
+
+# Test Undo/Redo.
+Undo D
+
+# Print the mesh data after first transaction
+set dump1_bfr [DumpTriangulation D 0:1]
+
+Redo D
+
+# Print the mesh data after second transaction
+set dump2_bfr [DumpTriangulation D 0:1]
+
+Close D
+
+# Restore data after first and second transactions
+Open $FileName_1 D_1
+Open $FileName_2 D_2
+
+set dump1_aft [DumpTriangulation D_1 0:1]
+set dump2_aft [DumpTriangulation D_2 0:1]
+
+Close D_1
+Close D_2
+
+# Check data
+if { ${dump1_bfr}!=${dump1_aft} } {
+  puts "TDataStd_Triangulation attribute: Error"
+  return
+}
+if { ${dump2_bfr}!=${dump2_aft} } {
+  puts "TDataStd_Triangulation attribute: Error"
+  return
+}
+puts "TDataStd_Triangulation attribute: OK"