]> OCCT Git - occt-copy.git/commitdiff
0025936: Reusable data structure for 2D tesselation (3- and 4-nodal mesh) CR25936CAF
authorvro <vro@opencascade.com>
Tue, 22 Dec 2015 05:17:07 +0000 (08:17 +0300)
committervro <vro@opencascade.com>
Tue, 22 Dec 2015 05:17:07 +0000 (08:17 +0300)
13 files changed:
src/BRepTools/BRepTools_ShapeSet.cxx
src/BRepTools/BRepTools_ShapeSet.hxx
src/BinMDataStd/BinMDataStd.cxx
src/BinMDataStd/BinMDataStd_MeshDriver.cxx [new file with mode: 0644]
src/BinMDataStd/BinMDataStd_MeshDriver.hxx [new file with mode: 0644]
src/DDataStd/DDataStd_BasicCommands.cxx
src/TDataStd/TDataStd_Mesh.cxx [new file with mode: 0644]
src/TDataStd/TDataStd_Mesh.hxx [new file with mode: 0644]
src/XmlMDataStd/XmlMDataStd.cxx
src/XmlMDataStd/XmlMDataStd_MeshDriver.cxx [new file with mode: 0644]
src/XmlMDataStd/XmlMDataStd_MeshDriver.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 a89ebf538a25c844155897abc146712befa7c0cf..071e192f67c074e26bd7d5ed06a007827b714910 100644 (file)
@@ -55,6 +55,7 @@
 #include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
+#include <Poly_Mesh.hxx>
 
 #ifdef MacOS
 #define strcasecmp(p,q) strcmp(p,q)
@@ -1635,3 +1636,182 @@ void BRepTools_ShapeSet::ReadTriangulation(Standard_IStream& IS)
     myTriangulations.Add(T);
   }
 }
+
+// Writes meshes (Poly_Mesh).
+void BRepTools_ShapeSet::WriteMeshes(Standard_OStream& OS,
+                                     const TColStd_IndexedMapOfTransient& Meshes,
+                                     const Standard_Boolean Compact)
+{
+  // Progress indicator.
+  const Standard_Integer nbMeshes = Meshes.Extent();
+  //Message_ProgressSentry indicator(GetProgress(), "Meshes", 0, nbMeshes, 1);
+
+  if (Compact)
+    OS << "Meshes " << nbMeshes << "\n";
+  else {
+    OS << " -------\n";
+    OS <<"Dump of " << nbMeshes << " meshes\n";
+    OS << " -------\n";
+  }
+
+  Standard_Integer i = 1;
+  for (; i <= nbMeshes /*&& indicator.More()*/; i++/*, indicator.Next()*/)
+  {
+    const Handle(Poly_Mesh) M = Handle(Poly_Mesh)::DownCast(Meshes(i));
+    const Standard_Integer nbNodes = M->NbNodes();
+    const Standard_Integer nbElements = M->NbElements();
+    const Standard_Boolean hasUVNodes = M->HasUVNodes();
+
+    if (Compact)
+    {
+      OS << nbNodes << " " << nbElements << " ";
+      OS << (hasUVNodes ? "1" : "0") << " ";
+    }
+    else
+    {
+      OS << "  "<< i << " : Mesh with " << nbNodes << " Nodes, " << nbElements <<" Triangles and Quadrangles\n";
+      OS << "      "<<(hasUVNodes ? "with" : "without") << " UV nodes\n";
+    }
+    
+    // write the deflection
+    if (!Compact) 
+      OS << "  Deflection : ";
+    OS <<M->Deflection() << "\n";
+    
+    // write the 3d nodes
+    if (!Compact)
+      OS << "\n3D Nodes :\n";
+    
+    Standard_Integer j;
+    for (j = 1; j <= nbNodes; j++)
+    {
+      if (!Compact) OS << setw(10) << j << " : ";
+      if (!Compact) OS << setw(17);
+      OS << M->Node(j).X() << " ";
+      if (!Compact) OS << setw(17);
+      OS << M->Node(j).Y() << " ";
+      if (!Compact) OS << setw(17);
+      OS << M->Node(j).Z();
+      if (!Compact) OS << "\n";
+      else OS << " ";
+    }
+    
+    // write 2d nodes
+    if (hasUVNodes)
+    {
+      if (!Compact) OS << "\nUV Nodes :\n";
+      for (j = 1; j <= nbNodes; j++)
+      {
+        if (!Compact) OS << setw(10) << j << " : ";
+        if (!Compact) OS << setw(17);
+        OS << M->UVNode(j).X() << " ";
+        if (!Compact) OS << setw(17);
+        OS << M->UVNode(j).Y();
+        if (!Compact) OS << "\n";
+        else OS << " ";
+      }
+    }
+    
+    // write triangles and quadrangles
+    if (!Compact) OS << "\nElements :\n";
+    Standard_Integer n, n1, n2, n3, n4;
+    for (j = 1; j <= nbElements; j++)
+    {
+      if (!Compact) OS << setw(10) << j << " : ";
+      M->Element(j, n1, n2, n3, n4);
+      n = (n4 > 0) ? 4 : 3;
+      if (!Compact) OS << setw(10);
+      OS << n << " ";
+      if (!Compact) OS << setw(10);
+      OS << n1 << " ";
+      if (!Compact) OS << setw(10);
+      OS << n2 << " ";
+      if (!Compact) OS << setw(10);
+      OS << n3;
+      if (n4 > 0)
+      {
+        OS << " ";
+        if (!Compact) OS << setw(10);
+        OS << n4;
+      }
+      if (!Compact) OS << "\n";
+      else OS << " ";
+    }
+    OS << "\n";
+  }
+}
+
+// Reads meshes (Poly_Mesh).
+void BRepTools_ShapeSet::ReadMeshes(Standard_IStream& IS,
+                                    TColStd_IndexedMapOfTransient& Meshes)
+{
+  char buffer[255];
+  Standard_Integer i, j;
+  Standard_Integer n, n1, n2, n3, n4;
+  Standard_Real deflection, x, y, z;
+  Standard_Integer nbMeshes(0), nbNodes(0), nbElements(0);
+  Standard_Boolean hasUV(Standard_False);
+  gp_Pnt p;
+
+  // Read the "Meshes" head-line.
+  IS >> buffer;
+  if (strstr(buffer,"Meshes") == NULL)
+    return;
+
+  // Read number of meshes.
+  IS >> nbMeshes;
+
+  //TODO: Uncomment these lines to activate the progress indicator
+  //(when Poly_Mesh is included into BRep_TFace).
+  //Handle(Message_ProgressIndicator) progress = GetProgress();
+  //Message_ProgressSentry PS(progress, "Meshes", 0, nbMeshes, 1);
+  for (i = 1; i <= nbMeshes /*&& PS.More()*/; i++/*, PS.Next()*/)
+  {
+    IS >> nbNodes >> nbElements >> hasUV;
+    GeomTools::GetReal(IS, deflection);
+
+    // Allocate the mesh.
+    Handle(Poly_Mesh) M = new Poly_Mesh(hasUV);
+    M->Deflection(deflection);
+
+    // Read nodes.
+    for (j = 1; j <= nbNodes; j++)
+    {
+      GeomTools::GetReal(IS, x);
+      GeomTools::GetReal(IS, y);
+      GeomTools::GetReal(IS, z);
+      p.SetCoord(x, y, z);
+      M->AddNode(p);
+    }
+
+    // Reads 2d-nodes.
+    if (hasUV)
+    {
+      for (j = 1; j <= nbNodes; j++)
+      {
+        GeomTools::GetReal(IS, x);
+        GeomTools::GetReal(IS, y);
+        M->ChangeUVNode(j).SetCoord(x,y);
+      }
+    }
+
+    // Reads the triangles and quadrangles.
+    for (j = 1; j <= nbElements; j++)
+    {
+      // Read the element.
+      IS >> n;
+      if (n == 3)
+        IS >> n1 >> n2 >> n3;
+      else if (n == 4)
+        IS >> n1 >> n2 >> n3 >> n4;
+
+      // Set the element to the mesh.
+      if (n == 3)
+        M->AddElement(n1, n2, n3);
+      else if (n == 4)
+        M->AddElement(n1, n2, n3, n4);
+    }
+
+    Meshes.Add(M);
+  }
+}
index caf96de38355d2197f98be4a6e878bfa7b9819bc..a35d99def60f408d772f719a697b99763733e4cf 100644 (file)
@@ -127,7 +127,16 @@ public:
   //! on the stream <OS>.
   Standard_EXPORT void DumpPolygonOnTriangulation (Standard_OStream& OS) const;
 
-
+  //! Writes meshes (Poly_Mesh).
+  //! TODO: Call this method when BRep_TFace refers to a list of meshes of type Poly_Mesh.
+  Standard_EXPORT static void WriteMeshes(Standard_OStream& OS,
+                                          const TColStd_IndexedMapOfTransient& Meshes,
+                                          const Standard_Boolean Compact = Standard_True);
+
+  //! Reads meshes (Poly_Mesh).
+  //! TODO: Call this method when BRep_TFace refers to a list of meshes of type Poly_Mesh.
+  Standard_EXPORT static void ReadMeshes(Standard_IStream& IS,
+                                         TColStd_IndexedMapOfTransient& Meshes);
 
 
 protected:
index 9885934ebefa0884c54ce387b5e6cb8b750b3b33..147253c71e99538806e9fce5db34cc517121e888 100644 (file)
@@ -41,6 +41,7 @@
 #include <BinMDataStd_TreeNodeDriver.hxx>
 #include <BinMDataStd_UAttributeDriver.hxx>
 #include <BinMDataStd_VariableDriver.hxx>
+#include <BinMDataStd_MeshDriver.hxx>
 #include <BinMDF_ADriverTable.hxx>
 #include <CDM_MessageDriver.hxx>
 
@@ -80,6 +81,7 @@ void BinMDataStd::AddDrivers (const Handle(BinMDF_ADriverTable)& theDriverTable,
   theDriverTable->AddDriver (new BinMDataStd_NamedDataDriver     (theMsgDriver) );
   theDriverTable->AddDriver (new BinMDataStd_AsciiStringDriver   (theMsgDriver) );
   theDriverTable->AddDriver (new BinMDataStd_IntPackedMapDriver  (theMsgDriver) );
+  theDriverTable->AddDriver (new BinMDataStd_MeshDriver          (theMsgDriver) );
 }
 
 //=======================================================================
diff --git a/src/BinMDataStd/BinMDataStd_MeshDriver.cxx b/src/BinMDataStd/BinMDataStd_MeshDriver.cxx
new file mode 100644 (file)
index 0000000..2d1927f
--- /dev/null
@@ -0,0 +1,169 @@
+// Created on: 2015-12-17
+// Created by: Vlad Romashko
+// Copyright (c) 2007-2014 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 <BinMDataStd_MeshDriver.hxx>
+#include <BinObjMgt_Persistent.hxx>
+#include <CDM_MessageDriver.hxx>
+#include <Standard_Type.hxx>
+#include <TDataStd_Mesh.hxx>
+#include <TDF_Attribute.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(BinMDataStd_MeshDriver,BinMDF_ADriver)
+
+//=======================================================================
+//function : BinMDataStd_MeshDriver
+//purpose  : Constructor
+//=======================================================================
+BinMDataStd_MeshDriver::BinMDataStd_MeshDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
+     : BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(TDataStd_Mesh)->Name())
+{
+
+}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  : 
+//=======================================================================
+Handle(TDF_Attribute) BinMDataStd_MeshDriver::NewEmpty() const
+{
+  return new TDataStd_Mesh();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : persistent -> transient (retrieve)
+//=======================================================================
+Standard_Boolean BinMDataStd_MeshDriver::Paste(const BinObjMgt_Persistent&  theSource,
+                                               const Handle(TDF_Attribute)& theTarget,
+                                               BinObjMgt_RRelocationTable&  ) const
+{
+  Handle(TDataStd_Mesh) mesh = Handle(TDataStd_Mesh)::DownCast(theTarget);
+
+  Standard_Integer i;
+  Standard_Real d, x, y, z;
+  Standard_Integer n, n1, n2, n3, n4;
+  Standard_Integer nbNodes(0), nbElements(0);
+  Standard_Boolean hasUV(Standard_False);
+  gp_Pnt p;
+
+  theSource >> nbNodes;
+  theSource >> nbElements;
+  theSource >> hasUV;
+  theSource >> d; //deflection
+
+  // allocate the mesh
+  Handle(Poly_Mesh) M = new Poly_Mesh(hasUV);
+
+  // deflection
+  M->Deflection(d);
+
+  // read nodes
+  for (i = 1; i <= nbNodes; i++)
+  {
+    theSource >> x;
+    theSource >> y;
+    theSource >> z;
+    p.SetCoord(x, y, z);
+    M->AddNode(p);
+  }
+      
+  // read 2d nodes
+  if (hasUV)
+  {
+    for (i = 1; i <= nbNodes; i++)
+    {
+      theSource >> x;
+      theSource >> y;
+      M->ChangeUVNode(i).SetCoord(x,y);
+    }
+  }
+      
+  // read triangles and quadrangles
+  for (i = 1; i <= nbElements; i++)
+  {
+    theSource >> n;
+    theSource >> n1;
+    theSource >> n2;
+    theSource >> n3;
+    if (n == 3)
+        M->AddElement(n1, n2, n3);
+    else if (n == 4)
+    {
+        theSource >> n4;
+        M->AddElement(n1, n2, n3, n4);
+    }
+  }
+
+  // set mesh to Ocaf attribute
+  mesh->Set(M);
+  return !M.IsNull();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : transient -> persistent (store)
+//=======================================================================
+void BinMDataStd_MeshDriver::Paste(const Handle(TDF_Attribute)& theSource,
+                                   BinObjMgt_Persistent&        theTarget,
+                                   BinObjMgt_SRelocationTable&  ) const
+{
+  const Handle(TDataStd_Mesh) meshAttr = Handle(TDataStd_Mesh)::DownCast(theSource);
+  const Handle(Poly_Mesh)& M = meshAttr->Get();
+  if (!M.IsNull())
+  {
+    Standard_Integer nbNodes = M->NbNodes();
+    Standard_Integer nbElements = M->NbElements();
+
+    // write number of elements
+    theTarget << nbNodes;
+    theTarget << nbElements;
+    theTarget << (M->HasUVNodes() ? 1 : 0);
+    // write the deflection
+    theTarget << M->Deflection();
+
+    // write 3d nodes
+    Standard_Integer i;
+    for (i = 1; i <= nbNodes; i++)
+    {
+      theTarget << M->Node(i).X();
+      theTarget << M->Node(i).Y();
+      theTarget << M->Node(i).Z();
+    }
+
+    // write 2d nodes
+    if (M->HasUVNodes())
+    {
+      for (i = 1; i <= nbNodes; i++)
+      {
+        theTarget << M->UVNode(i).X();
+        theTarget << M->UVNode(i).Y();
+      }
+    }
+
+    // write triangles and quadrangles
+    Standard_Integer n, n1, n2, n3, n4;
+    for (i = 1; i <= nbElements; i++)
+    {
+      M->Element(i, n1, n2, n3, n4);
+      n = (n4 > 0) ? 4 : 3;
+      theTarget << n;
+      theTarget << n1;
+      theTarget << n2;
+      theTarget << n3;
+      if (n4 > 0)
+        theTarget << n4;
+    }
+  }
+}
diff --git a/src/BinMDataStd/BinMDataStd_MeshDriver.hxx b/src/BinMDataStd/BinMDataStd_MeshDriver.hxx
new file mode 100644 (file)
index 0000000..4f9fde5
--- /dev/null
@@ -0,0 +1,49 @@
+// Created on: 2015-12-17
+// Created by: Vlad Romashko
+// Copyright (c) 2007-2014 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 _BinMDataStd_MeshDriver_HeaderFile
+#define _BinMDataStd_MeshDriver_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;
+
+class BinMDataStd_MeshDriver;
+DEFINE_STANDARD_HANDLE(BinMDataStd_MeshDriver, BinMDF_ADriver)
+
+class BinMDataStd_MeshDriver : public BinMDF_ADriver
+{
+
+public:
+  
+  Standard_EXPORT BinMDataStd_MeshDriver(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(BinMDataStd_MeshDriver,BinMDF_ADriver)
+};
+
+#endif // _BinMDataStd_MeshDriver_HeaderFile
index 65ea9970ec26170deaea4903f155570e4073a13b..b3a9f81a361cc2c0054a23a04acdda596b605d16 100644 (file)
@@ -52,6 +52,7 @@
 
 // LES ATTRIBUTES
 #include <TDataStd.hxx>
+#include <TDataStd_Mesh.hxx>
 #include <TDataStd_Comment.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDataStd_Integer.hxx>
@@ -3733,6 +3734,103 @@ static Standard_Integer DDataStd_GetRefArrayValue (Draw_Interpretor& di,
   return 0; 
 } 
 
+//=======================================================================
+//function : DDataStd_SetMesh
+//purpose  : SetMesh (DF, entry, face)
+//=======================================================================
+
+static Standard_Integer DDataStd_SetMesh (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; //TODO: apply the location to the triangulation
+    Handle(Poly_Triangulation) tris = BRep_Tool::Triangulation(TopoDS::Face(face), loc);
+    if (tris.IsNull())
+    {
+      di << "No triangulation in the face.\n";
+      return 1;
+    }
+
+    // Convert the triangulation to tmp-triangulation
+    // (temporary solution while Poly_Triangulation is not updated everywhjere in Open CASCADE).
+    //TODO: remove the conversion when Poly_Triangulation is Ok.
+    Handle(Poly_TmpTriangulation) tmpTris = new Poly_TmpTriangulation(tris->Nodes(), tris->Triangles());
+
+    // Make a mesh.
+    Handle(Poly_Mesh) mesh = new Poly_Mesh(tmpTris);
+
+    // Set the attribute.
+    TDataStd_Mesh::Set(L, mesh);
+    return 0;
+  }
+  di << "DDataStd_SetMesh : Error\n";
+  return 1;
+}
+
+//=======================================================================
+//function : DDataStd_DumpMesh
+//purpose  : DumpMesh (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(TDataStd_Mesh) M;
+    if (!DDF::Find(DF,arg[2],TDataStd_Mesh::GetID(),M))
+    {
+      di << "The attribute mesh doesn't exist at the label.\n";
+      return 1;
+    }
+
+    // Dump of the mesh.
+    if (M->Get().IsNull())
+    {
+      di << "No mesh in the attribute.\n";
+      return 1;
+    }
+
+    di << "Deflection            " << M->Deflection() <<"\n";
+    di << "Number of nodes       " << M->NbNodes() << "\n";
+    di << "Number of triangles   " << M->NbTriangles() << "\n";
+    di << "Number of quadrangles " << M->NbQuads() << "\n";
+    if (M->HasUVNodes())
+        di << "It has 2d-nodes\n";
+    if (M->HasNormals())
+        di << "It has normals\n";
+
+    return 0;
+  }
+  di << "DDataStd_DumpMesh : Error\n";
+  return 1;
+}
+
 //=======================================================================
 //function : BasicCommands
 //purpose  : 
@@ -3850,6 +3948,12 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands)
                    "SetReferenceList (DF, entry, elmt1, elmt2, ...  )",
                    __FILE__, DDataStd_SetReferenceList, g);
 
+  theCommands.Add ("SetMesh", 
+                   "SetMesh (DF, entry, face)",
+                   __FILE__, DDataStd_SetMesh, g);
+
+   // Insert before and after (for lists)
+
    theCommands.Add ("InsertBeforeExtStringList", 
                    "InsertBeforeExtStringList (DF, entry, index, value )",
                    __FILE__, DDataStd_InsertBeforeExtStringList, g);
@@ -4156,6 +4260,9 @@ void DDataStd::BasicCommands (Draw_Interpretor& theCommands)
 
 //=========================================================
 
+   theCommands.Add ("DumpMesh", 
+                   "DumpMesh (DF, entry)",
+                    __FILE__, DDataStd_DumpMesh, g);
 
 //======================================================================
 //======= for internal use
diff --git a/src/TDataStd/TDataStd_Mesh.cxx b/src/TDataStd/TDataStd_Mesh.cxx
new file mode 100644 (file)
index 0000000..16ac63b
--- /dev/null
@@ -0,0 +1,436 @@
+// Created on: 2015-12-10
+// Created by: Vlad Romashko
+// Copyright (c) 2007-2014 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 <Standard_GUID.hxx>
+#include <Standard_Type.hxx>
+#include <TDataStd_Mesh.hxx>
+#include <TDF_Attribute.hxx>
+#include <TDF_Label.hxx>
+#include <TDF_RelocationTable.hxx>
+
+//=======================================================================
+//function : GetID
+//purpose  : Returns the ID of the mesh attribute.
+//=======================================================================
+const Standard_GUID& TDataStd_Mesh::GetID() 
+{ 
+  static Standard_GUID TDataStd_MeshID ("D7E3F1CF-38A4-4DCA-94F4-51C31F3FCBA5");
+  return TDataStd_MeshID; 
+}
+
+//=======================================================================
+//function : Set
+//purpose  : Finds or creates a mesh attribute.
+//=======================================================================
+Handle(TDataStd_Mesh) TDataStd_Mesh::Set(const TDF_Label& label) 
+{
+  Handle(TDataStd_Mesh) A;
+  if (!label.FindAttribute (TDataStd_Mesh::GetID(), A)) 
+  {
+    A = new TDataStd_Mesh;
+    label.AddAttribute(A);
+  }
+  return A;
+}
+
+//=======================================================================
+//function : Set
+//purpose  : Finds or creates a mesh attribute.
+//           Initializes the attribute by a mesh (Poly_Mesh) object.
+//           If the mesh consists of only triangles,
+//           you may put Poly_Triangulation object as a 2nd parameter of this method.
+//=======================================================================
+Handle(TDataStd_Mesh) TDataStd_Mesh::Set(const TDF_Label& label, const Handle(Poly_Mesh)& mesh)
+{
+   Handle(TDataStd_Mesh) M = TDataStd_Mesh::Set(label);
+   M->Set(mesh);
+   return M;
+}
+
+//=======================================================================
+//function : TDataStd_Mesh
+//purpose  : A constructor.
+//           Don't use it directly, 
+//           use please the static method Set(),
+//           which returns the attribute attached to a label.
+//=======================================================================
+TDataStd_Mesh::TDataStd_Mesh() 
+{
+
+}
+  
+//=======================================================================
+//function : TDataStd_Mesh
+//purpose  : Sets the mesh.
+//           If the mesh consists of only triangles,
+//           you may put Poly_Triangulation object.
+//=======================================================================
+void TDataStd_Mesh::Set(const Handle(Poly_Mesh)& mesh)
+{
+  Backup();
+  myMesh = mesh;
+}
+
+//=======================================================================
+//function : TDataStd_Mesh
+//purpose  : Returns the underlying mesh.
+//=======================================================================
+const Handle(Poly_Mesh)& TDataStd_Mesh::Get() const
+{
+  return myMesh;
+}
+
+// Poly_Mesh methods
+
+// The methods are "covered" by this attribute to prevent direct modification of the mesh.
+// There is no performance problem to call Poly_Mesh 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 TDataStd_Mesh::Deflection() const
+{
+  return myMesh->Deflection();
+}
+
+//=======================================================================
+//function : Deflection
+//purpose  : Sets the deflection of this triangulation to theDeflection.
+//           See more on deflection in Polygon2D
+//=======================================================================
+void TDataStd_Mesh::Deflection (const Standard_Real theDeflection)
+{
+  Backup();
+  myMesh->Deflection(theDeflection);
+}
+
+//=======================================================================
+//function : RemoveUVNodes
+//purpose  : Deallocates the UV nodes.
+//=======================================================================
+void TDataStd_Mesh::RemoveUVNodes()
+{
+  Backup();
+  myMesh->RemoveUVNodes();
+}
+
+//=======================================================================
+//function : NbNodes
+//purpose  : @return the number of nodes for this triangulation.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::NbNodes() const
+{
+  return myMesh->NbNodes();
+}
+
+//=======================================================================
+//function : NbTriangles
+//purpose  : @return the number of triangles for this triangulation.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::NbTriangles() const
+{
+  return myMesh->NbTriangles();
+}
+
+//=======================================================================
+//function : HasUVNodes
+//purpose  : @return Standard_True if 2D nodes are associated with 3D nodes for this triangulation.
+//=======================================================================
+Standard_Boolean TDataStd_Mesh::HasUVNodes() const
+{
+  return myMesh->HasUVNodes();
+}
+
+//=======================================================================
+//function : AddNode
+//purpose  : Adds Node to the triangulation. If triangulation has UVNodes or Normals
+//           they will be expanded and set to zero values to match the new number of nodes.
+//           @return index of the added Node.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::AddNode (const gp_Pnt& theNode)
+{
+  Backup();
+  return myMesh->AddNode(theNode);
+}
+
+//=======================================================================
+//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& TDataStd_Mesh::Node (const Standard_Integer theIndex) const
+{
+  return myMesh->Node(theIndex);
+}
+
+//=======================================================================
+//function : SetNode
+//purpose  : The method differs from Poly_Mesh
+//           Sets a node at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+//=======================================================================
+void TDataStd_Mesh::SetNode (const Standard_Integer theIndex, const gp_Pnt& theNode)
+{
+  Backup();
+  myMesh->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& TDataStd_Mesh::UVNode (const Standard_Integer theIndex) const
+{
+  return myMesh->UVNode(theIndex);
+}
+
+//=======================================================================
+//function : SetUVNode
+//purpose  : The method differs from Poly_Mesh
+//           Sets a UVNode at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbNodes.
+//=======================================================================
+void TDataStd_Mesh::SetUVNode (const Standard_Integer theIndex, const gp_Pnt2d& theUVNode)
+{
+  Backup();
+  myMesh->ChangeUVNode(theIndex) = theUVNode;
+}
+
+//=======================================================================
+//function : AddTriangle
+//purpose  : Adds triangle to the triangulation.
+//           @return index of the added triangle.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::AddTriangle (const Poly_Triangle& theTriangle)
+{
+  Backup();
+  return myMesh->AddTriangle(theTriangle);
+}
+
+//=======================================================================
+//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& TDataStd_Mesh::Triangle (const Standard_Integer theIndex) const
+{
+  return myMesh->Triangle(theIndex);
+}
+
+//=======================================================================
+//function : SetTriangle
+//purpose  : The method differs from Poly_Mesh
+//           Sets a triangle at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbTriangles.
+//=======================================================================
+void TDataStd_Mesh::SetTriangle (const Standard_Integer theIndex, const Poly_Triangle& theTriangle)
+{
+  Backup();
+  myMesh->ChangeTriangle(theIndex) = theTriangle;
+}
+
+//=======================================================================
+//function : SetNormals
+//purpose  : Sets the table of node normals.
+//           Raises exception if length of theNormals = 3 * NbNodes
+//=======================================================================
+void TDataStd_Mesh::SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals)
+{
+  Backup();
+  myMesh->SetNormals(theNormals);
+}
+
+//=======================================================================
+//function : SetNormal
+//purpose  : Changes normal at the given index.
+//           Raises Standard_OutOfRange exception.
+//=======================================================================
+void TDataStd_Mesh::SetNormal (const Standard_Integer theIndex,
+                               const gp_Dir&          theNormal)
+{
+  Backup();
+  myMesh->SetNormal(theIndex, theNormal);
+}
+
+//=======================================================================
+//function : HasNormals
+//purpose  : Returns Standard_True if nodal normals are defined.
+//=======================================================================
+Standard_Boolean TDataStd_Mesh::HasNormals() const
+{
+  return myMesh->HasNormals();
+}
+
+//=======================================================================
+//function : Normal
+//purpose  : @return normal at the given index.
+//           Raises Standard_OutOfRange exception.
+//=======================================================================
+const gp_Dir TDataStd_Mesh::Normal (const Standard_Integer theIndex) const
+{
+  return myMesh->Normal(theIndex);
+}
+
+//=======================================================================
+//function : AddElement
+//purpose  : Adds element to the mesh.
+//           @param theN1 index of the first node.
+//           @param theN2 index of the second node.
+//           @param theN3 index of the third node.
+//           @return index of the added element.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::AddElement (const Standard_Integer theN1,
+                                            const Standard_Integer theN2,
+                                            const Standard_Integer theN3)
+{
+  Backup();
+  return myMesh->AddElement(theN1, theN2, theN3);
+}
+
+//=======================================================================
+//function : AddElement
+//purpose  : Adds element to the mesh.
+//           @param theN1 index of the first node.
+//           @param theN2 index of the second node.
+//           @param theN3 index of the third node.
+//           @param theN4 index of the fourth node.
+//           @return index of the added element.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::AddElement (const Standard_Integer theN1,
+                                            const Standard_Integer theN2,
+                                            const Standard_Integer theN3,
+                                            const Standard_Integer theN4)
+{
+  Backup();
+  return myMesh->AddElement(theN1, theN2, theN3, theN4);
+}
+
+//=======================================================================
+//function : NbElements
+//purpose  : @return the number of elements for this mesh.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::NbElements() const
+{
+  return myMesh->NbElements();
+}
+
+//=======================================================================
+//function : NbQuads
+//purpose  : @return the number of quads for this mesh.
+//=======================================================================
+Standard_Integer TDataStd_Mesh::NbQuads() const
+{
+  return myMesh->NbQuads();
+}
+
+//=======================================================================
+//function : Element
+//purpose  : @return element at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbElements.
+//=======================================================================
+const Poly_Element& TDataStd_Mesh::Element (const Standard_Integer theIndex) const
+{
+  return myMesh->Element(theIndex);
+}
+
+//=======================================================================
+//function : Element
+//purpose  : @return nodes of the element at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbElements.
+//=======================================================================
+void TDataStd_Mesh::Element (const Standard_Integer theIndex,
+                            Standard_Integer& theN1,
+                            Standard_Integer& theN2,
+                            Standard_Integer& theN3,
+                            Standard_Integer& theN4) const
+{
+  myMesh->Element(theIndex, theN1, theN2, theN3, theN4);
+}
+
+//=======================================================================
+//function : SetElement
+//purpose  : Sets an element at the given index.
+//           Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbElements.
+//=======================================================================
+void TDataStd_Mesh::SetElement (const Standard_Integer theIndex, const Poly_Element& theElement)
+{
+  Backup();
+  myMesh->SetElement(theIndex, theElement);
+}
+
+//=======================================================================
+//function : ID
+//purpose  : 
+//=======================================================================
+const Standard_GUID& TDataStd_Mesh::ID () const 
+{ 
+  return GetID(); 
+}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  : 
+//=======================================================================
+Handle(TDF_Attribute) TDataStd_Mesh::NewEmpty () const
+{  
+  return new TDataStd_Mesh(); 
+}
+
+//=======================================================================
+//function : Restore
+//purpose  : 
+//=======================================================================
+void TDataStd_Mesh::Restore(const Handle(TDF_Attribute)& With) 
+{
+  myMesh.Nullify();
+  Handle(TDataStd_Mesh) M = Handle(TDataStd_Mesh)::DownCast(With);
+  if (!M->myMesh.IsNull())
+  {
+    Handle(Poly_TmpTriangulation) T = M->myMesh->Copy();
+    if (!T.IsNull())
+        myMesh = Handle(Poly_Mesh)::DownCast(T);
+  }
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : 
+//=======================================================================
+void TDataStd_Mesh::Paste (const Handle(TDF_Attribute)& Into,
+                           const Handle(TDF_RelocationTable)& ) const
+{
+  Handle(TDataStd_Mesh) M = Handle(TDataStd_Mesh)::DownCast(Into);
+  M->myMesh.Nullify();
+  if (!myMesh.IsNull())
+  {
+      Handle(Poly_TmpTriangulation) T = myMesh->Copy();
+      if (!T.IsNull())
+        M->myMesh = Handle(Poly_Mesh)::DownCast(T);
+  }
+}
+
+//=======================================================================
+//function : Dump
+//purpose  : 
+//=======================================================================
+Standard_OStream& TDataStd_Mesh::Dump (Standard_OStream& anOS) const
+{  
+  anOS << "Mesh";
+  //TODO: Make a good dump.
+  return anOS;
+}
diff --git a/src/TDataStd/TDataStd_Mesh.hxx b/src/TDataStd/TDataStd_Mesh.hxx
new file mode 100644 (file)
index 0000000..917040f
--- /dev/null
@@ -0,0 +1,218 @@
+// Created on: 2015-12-10
+// Created by: Vlad Romashko
+// Copyright (c) 2007-2014 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 _TDataStd_Mesh_HeaderFile
+#define _TDataStd_Mesh_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+
+#include <Poly_Mesh.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 TDataStd_Mesh;
+DEFINE_STANDARD_HANDLE(TDataStd_Mesh, TDF_Attribute)
+
+//! An Ocaf attribute containing a mesh (Poly_Mesh).
+//! It duplicates all methods from Poly_Mesh (and Poly_Triangulation).
+//! It is highly recommended to modify the mesh through the methods of this attribute,
+//! but not directly via the underlying Poly_Mesh object.
+//! In this case Undo/Redo will work fine and robust.
+class TDataStd_Mesh : public TDF_Attribute
+{
+public:
+  
+  //! Static methods
+  //  ==============
+
+  //! Returns the ID of the mesh attribute.
+  Standard_EXPORT static const Standard_GUID& GetID();
+  
+  //! Finds or creates a mesh attribute.
+  Standard_EXPORT static Handle(TDataStd_Mesh) Set(const TDF_Label& label);
+
+  //! Finds or creates a mesh attribute.
+  //! Initializes the attribute by a mesh (Poly_Mesh) object.
+  //! If the mesh consists of only triangles,
+  //! you may put Poly_Triangulation object as a 2nd parameter of this method.
+  Standard_EXPORT static Handle(TDataStd_Mesh) Set(const TDF_Label& label, const Handle(Poly_Mesh)& mesh);
+  
+  //! 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 TDataStd_Mesh();
+  
+  //! Sets the mesh.
+  //! If the mesh consists of only triangles,
+  //! you may put Poly_Triangulation object.
+  Standard_EXPORT void Set(const Handle(Poly_Mesh)& mesh);
+
+  //! Returns the underlying mesh.
+  Standard_EXPORT const Handle(Poly_Mesh)& Get() const;
+
+
+  //! Poly_Mesh methods
+  //  =================
+
+  //! The methods are "covered" by this attribute to prevent direct modification of the mesh.
+  //! There is no performance problem to call Poly_Mesh 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;
+
+  //! Adds Node to the triangulation. If triangulation has UVNodes or Normals
+  //! they will be expanded and set to zero values to match the new number of nodes.
+  //! @return index of the added Node.
+  Standard_EXPORT Standard_Integer AddNode (const gp_Pnt& theNode);
+
+  //! @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_Mesh!
+  //! 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_Mesh!
+  //! 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);
+
+  //! Adds triangle to the triangulation.
+  //! @return index of the added triangle.
+  Standard_EXPORT Standard_Integer AddTriangle (const Poly_Triangle& theTriangle);
+
+  //! @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_Mesh!
+  //! 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;
+
+  //! Adds element to the mesh.
+  //! @param theN1 index of the first node.
+  //! @param theN2 index of the second node.
+  //! @param theN3 index of the third node.
+  //! @return index of the added element.
+  Standard_EXPORT Standard_Integer AddElement (const Standard_Integer theN1,
+                                               const Standard_Integer theN2,
+                                               const Standard_Integer theN3);
+
+  //! Adds element to the mesh.
+  //! @param theN1 index of the first node.
+  //! @param theN2 index of the second node.
+  //! @param theN3 index of the third node.
+  //! @param theN4 index of the fourth node.
+  //! @return index of the added element.
+  Standard_EXPORT Standard_Integer AddElement (const Standard_Integer theN1,
+                                               const Standard_Integer theN2,
+                                               const Standard_Integer theN3,
+                                               const Standard_Integer theN4);
+
+  //! @return the number of elements for this mesh.
+  Standard_EXPORT Standard_Integer NbElements() const;
+
+  //! @return the number of quads for this mesh.
+  Standard_EXPORT Standard_Integer NbQuads() const;
+
+  //! @return element at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbElements.
+  Standard_EXPORT const Poly_Element& Element (const Standard_Integer theIndex) const;
+
+  //! @return nodes of the element at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbElements.
+  Standard_EXPORT void Element (const Standard_Integer theIndex,
+                                Standard_Integer& theN1,
+                                Standard_Integer& theN2,
+                                Standard_Integer& theN3,
+                                Standard_Integer& theN4) const;
+
+  //! Sets an element at the given index.
+  //! Raises Standard_OutOfRange exception if theIndex is less than 1 or greater than NbElements.
+  Standard_EXPORT void SetElement (const Standard_Integer theIndex, const Poly_Element& theElement);
+
+
+  //! Inherited attribute methods
+  //  ===========================
+
+  Standard_EXPORT const Standard_GUID& ID() const Standard_OVERRIDE;
+  
+  Standard_EXPORT void Restore (const Handle(TDF_Attribute)& With) 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(TDataStd_Mesh,TDF_Attribute)
+
+private:
+
+  Handle(Poly_Mesh) myMesh;
+};
+
+#endif // _TDataStd_Mesh_HeaderFile
index 8a10e98f0b52b93aebc8fca3968a8c1fc4f663ae..0bfd088e3e298150bd14c7b2dfe6976969a5d0a1 100644 (file)
@@ -43,6 +43,7 @@
 #include <XmlMDataStd_TreeNodeDriver.hxx>
 #include <XmlMDataStd_UAttributeDriver.hxx>
 #include <XmlMDataStd_VariableDriver.hxx>
+#include <XmlMDataStd_MeshDriver.hxx>
 #include <XmlMDF_ADriverTable.hxx>
 
 static Standard_Integer myDocumentVersion = -1;
@@ -80,6 +81,7 @@ void XmlMDataStd::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
   aDriverTable-> AddDriver (new XmlMDataStd_NamedDataDriver     (anMsgDrv));
   aDriverTable-> AddDriver (new XmlMDataStd_AsciiStringDriver   (anMsgDrv));
   aDriverTable-> AddDriver (new XmlMDataStd_IntPackedMapDriver  (anMsgDrv));
+  aDriverTable-> AddDriver (new XmlMDataStd_MeshDriver          (anMsgDrv));
 }
 
 //=======================================================================
diff --git a/src/XmlMDataStd/XmlMDataStd_MeshDriver.cxx b/src/XmlMDataStd/XmlMDataStd_MeshDriver.cxx
new file mode 100644 (file)
index 0000000..a4cbfa9
--- /dev/null
@@ -0,0 +1,133 @@
+// Created on: 2015-12-15
+// Created by: Vlad Romashko
+// Copyright (c) 2007-2014 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 <CDM_MessageDriver.hxx>
+#include <NCollection_LocalArray.hxx>
+#include <Standard_Type.hxx>
+#include <TDF_Attribute.hxx>
+#include <XmlMDataStd_MeshDriver.hxx>
+#include <XmlObjMgt.hxx>
+#include <XmlObjMgt_Persistent.hxx>
+#include <TDataStd_Mesh.hxx>
+#include <LDOM_OSStream.hxx>
+#include <BRepTools_ShapeSet.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(XmlMDataStd_MeshDriver,XmlMDF_ADriver)
+IMPLEMENT_DOMSTRING (MeshString, "mesh")
+IMPLEMENT_DOMSTRING (NullString, "null")
+IMPLEMENT_DOMSTRING (ExistString, "exists")
+
+//=======================================================================
+//function : XmlMDataStd_MeshDriver
+//purpose  : Constructor
+//=======================================================================
+XmlMDataStd_MeshDriver::XmlMDataStd_MeshDriver(const Handle(CDM_MessageDriver)& theMsgDriver)
+     : XmlMDF_ADriver (theMsgDriver, NULL)
+{
+
+}
+
+//=======================================================================
+//function : NewEmpty
+//purpose  : 
+//=======================================================================
+Handle(TDF_Attribute) XmlMDataStd_MeshDriver::NewEmpty() const
+{
+  return new TDataStd_Mesh();
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : persistent -> transient (retrieve)
+//=======================================================================
+Standard_Boolean XmlMDataStd_MeshDriver::Paste(const XmlObjMgt_Persistent&  theSource,
+                                               const Handle(TDF_Attribute)& theTarget,
+                                               XmlObjMgt_RRelocationTable&  ) const
+{
+  const XmlObjMgt_Element& element = theSource;
+  Handle(TDataStd_Mesh) mesh = Handle(TDataStd_Mesh)::DownCast(theTarget);
+
+  // Read the FirstIndex; if the attribute is absent initialize to 1
+  XmlObjMgt_DOMString meshStatus = element.getAttribute(::MeshString());
+  if (meshStatus == NULL ||
+      meshStatus.Type() != LDOMBasicString::LDOM_AsciiDoc ||
+      strcmp(meshStatus.GetString(), ::ExistString().GetString())) 
+  {
+    // No mesh.
+    return Standard_True;
+  }
+
+  // Get mesh as a string.
+  const XmlObjMgt_DOMString& data = XmlObjMgt::GetStringValue(element);
+  std::stringstream stream(std::string(data.GetString()));
+
+  // Read the mesh.
+  BRepTools_ShapeSet shapeSet;
+  TColStd_IndexedMapOfTransient meshes;
+  shapeSet.ReadMeshes(stream, meshes);
+
+  // Set mesh.
+  if (!meshes.IsEmpty())
+  {
+    // We expect only one mesh.
+    Handle(Poly_Mesh) M = Handle(Poly_Mesh)::DownCast(meshes(1));
+    if (!M.IsNull())
+      mesh->Set(M);
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : Paste
+//purpose  : transient -> persistent (store)
+//=======================================================================
+void XmlMDataStd_MeshDriver::Paste(const Handle(TDF_Attribute)& theSource,
+                                   XmlObjMgt_Persistent&        theTarget,
+                                   XmlObjMgt_SRelocationTable&  ) const
+{
+  const Handle(TDataStd_Mesh) meshAttr = Handle(TDataStd_Mesh)::DownCast(theSource);
+  if (meshAttr->Get().IsNull())
+    theTarget.Element().setAttribute(::MeshString(), ::NullString());
+  else
+  {
+    theTarget.Element().setAttribute(::MeshString(), ::ExistString());
+    
+    // Analyse the size of the mesh
+    // (to allocate properly the string array).
+    const Handle(Poly_Mesh)& mesh = meshAttr->Get();
+    Standard_Integer size = mesh->NbNodes();
+    size *= 3; // 3 coordinates for a node
+    size *= 8; // 8 characters are used to represent a coordinate (double) in XML
+    size += 4 * 5 * mesh->NbElements(); // space for elements (triangles and quadrangles)
+    size *= 2; // just in case :-)
+    if (!size)
+      size = 1;
+
+    // Allocate a string stream.
+    LDOM_OSStream stream(size);
+
+    // Write the mesh.
+    BRepTools_ShapeSet shapeSet;
+    TColStd_IndexedMapOfTransient meshes;
+    meshes.Add(mesh);
+    shapeSet.WriteMeshes(stream, meshes, Standard_True/*compact*/);
+    stream<<ends;
+
+    Standard_Character* dump = (Standard_Character*)stream.str(); // copying! Don't forget to delete it.
+    XmlObjMgt::SetStringValue(theTarget, dump, Standard_True);
+    delete[] dump;
+  }
+}
diff --git a/src/XmlMDataStd/XmlMDataStd_MeshDriver.hxx b/src/XmlMDataStd/XmlMDataStd_MeshDriver.hxx
new file mode 100644 (file)
index 0000000..1e52f17
--- /dev/null
@@ -0,0 +1,49 @@
+// Created on: 2015-12-15
+// Created by: Vlad Romashko
+// Copyright (c) 2007-2014 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 _XmlMDataStd_MeshDriver_HeaderFile
+#define _XmlMDataStd_MeshDriver_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;
+
+class XmlMDataStd_MeshDriver;
+DEFINE_STANDARD_HANDLE(XmlMDataStd_MeshDriver, XmlMDF_ADriver)
+
+class XmlMDataStd_MeshDriver : public XmlMDF_ADriver
+{
+
+public:
+  
+  Standard_EXPORT XmlMDataStd_MeshDriver(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(XmlMDataStd_MeshDriver,XmlMDF_ADriver)
+};
+
+#endif // _XmlMDataStd_MeshDriver_HeaderFile
diff --git a/tests/caf/basic/N1 b/tests/caf/basic/N1
new file mode 100644 (file)
index 0000000..03b327b
--- /dev/null
@@ -0,0 +1,41 @@
+#INTERFACE CAF
+# Basic attributes
+#
+# Testing attribute: TDataStd_Mesh
+#
+# Testing command:   SetMesh
+# Testing command:   DumpMesh
+#
+
+puts "caf001-N1"
+
+# Make a sphere and produce triangulation
+psphere s 100
+vdisplay s
+explode s f
+
+# Create a XML document
+NewDocument D XmlXCAF
+
+# Set mesh from the spherical face
+SetMesh D 0:1 s_1
+
+# Print the mesh data
+set dump1 [DumpMesh D 0:1]
+
+# Save document on disk.
+SaveAs D "test.xml"
+
+# Close and open the document again.
+Close D
+Open test.xml DD
+
+# Print mesh data
+set dump2 [DumpMesh DD 0:1]
+
+# Check data
+if { ${dump1}!=${dump2} } {
+       puts "TDataStd_Mesh(XML) attribute: Error"
+       return
+}
+puts "TDataStd_Mesh(XML) attribute: OK"
diff --git a/tests/caf/basic/N2 b/tests/caf/basic/N2
new file mode 100644 (file)
index 0000000..e2e91fa
--- /dev/null
@@ -0,0 +1,42 @@
+#INTERFACE CAF
+# Basic attributes
+#
+# Testing attribute: TDataStd_Mesh
+#
+# Testing command:   SetMesh
+# Testing command:   DumpMesh
+# Test           :   Binary file format
+#
+
+puts "caf001-N2"
+
+# Make a sphere and produce triangulation
+psphere s 100
+vdisplay s
+explode s f
+
+# Create a binary document
+NewDocument D BinXCAF
+
+# Set mesh from the spherical face
+SetMesh D 0:1 s_1
+
+# Print the mesh data
+set dump1 [DumpMesh D 0:1]
+
+# Save document on disk.
+SaveAs D "test.xbf"
+
+# Close and open the document again.
+Close D
+Open test.xbf DD
+
+# Print mesh data
+set dump2 [DumpMesh DD 0:1]
+
+# Check data
+if { ${dump1}!=${dump2} } {
+       puts "TDataStd_Mesh(BIN) attribute: Error"
+       return
+}
+puts "TDataStd_Mesh(BIN) attribute: OK"