Salome HOME
Updated copyright comment
[modules/hexablock.git] / src / HEXABLOCK / HexDocument_Xml.cxx
old mode 100755 (executable)
new mode 100644 (file)
index db201a9..9e3d076
@@ -1,9 +1,29 @@
 
 // C++ : Classe Document : methodes internes
 
+// Copyright (C) 2009-2024  CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 #include "HexDocument.hxx"
+// #include <Basics_DirUtils.hxx>   
+#include <cstdlib>               // Pour atoi et atof
 
-#include "HexEltBase.hxx"
+#include "Hex.hxx"
 #include "HexVertex.hxx"
 #include "HexEdge.hxx"
 #include "HexQuad.hxx"
 #include "HexElements.hxx"
 
 #include "HexVector.hxx"
-#include "HexCylinder.hxx"
-#include "HexPipe.hxx"
 #include "HexMatrix.hxx"
 #include "HexCloner.hxx"
 #include "HexPropagation.hxx"
 #include "HexLaw.hxx"
+#include "HexGroup.hxx"
+
+#include "HexNewShape.hxx"
+#include "HexVertexShape.hxx"
+#include "HexEdgeShape.hxx"
+#include "HexFaceShape.hxx"
 
 #include "HexXmlWriter.hxx"
 #include "HexXmlTree.hxx"
+#include "HexGlobale.hxx"
 
 BEGIN_NAMESPACE_HEXA
 
 // ======================================================== get_coords
-int get_coords (const string& chaine, double& x, double& y, double& z)
+int get_coords (const std::string& chaine, double& x, double& y, double& z)
 {
    // int nv = sscanf (chaine.c_str (), "%lg %lg %lg", &x, &y, &z);
    cpchar buffer = chaine.c_str ();
@@ -33,178 +58,421 @@ int get_coords (const string& chaine, double& x, double& y, double& z)
    if (nv!=3) return HERR;
    return HOK;
 }
-// ======================================================== get_values
-int get_values (const string& chaine, int size, int table[])
+// ======================================================== get_coords
+int get_coords (const std::string& chaine, double& x, double& y)
+{
+   cpchar buffer = chaine.c_str ();
+   int nv = sscanf (buffer, "%lg %lg", &x, &y);
+   if (nv!=2) return HERR;
+   return HOK;
+}
+// ======================================================== parse_name
+int parse_name (XmlTree* node, const std::string& nom, EltBase* elt)
 {
-   int lg  = chaine.size();
-   int nv  = 0;
-   int val = 0;
+   int lg    = nom.size();
+   int nroid = 0;
+   for (int nc=1 ; nc<lg ; nc++)
+       nroid = 10*nroid + nom[nc] - '0';
+
+   elt->setId (nroid);
+
+   const  std::string& name = node->findValue ("name");
+   if (name=="")
+      return HERR;
+
+   elt->setName (name);
+   return HOK;
+}
+// ======================================================== get_names
+void get_names (const std::string& chaine, int size, std::vector<std::string>& table)
+{
+   table.clear ();
+   int    lg    = chaine.size();
+   std::string mot   = "";
    bool encours = false;
 
    for (int nc=0 ; nc<lg ; nc++)
        {
        char car  = chaine[nc];
-       if (car >= '0' && car <= '9')
+       if (isalnum (car))
           {
-          val = 10* val + car - '0';
+          mot += car;
           encours = true;
           }
        else if (encours)
           {
-          table [nv] = val;
+          table.push_back (mot);
           encours = false;
-          val     = 0;
-          nv++;
-          if (nv >= size) 
-             return nv;
+          mot     = "";
           }
        }
 
    if (encours)
-      table [nv] = val;
-   return nv;
+      table.push_back (mot);
 }
-// ======================================================== get_int
-int get_int (const string& chaine)
+// ======================================================== count_children
+int count_children (XmlTree* dad)
 {
-   int val [2] = {0, 0};
-   get_values (chaine, 1, val);
-   return val[0];
+   int    nbre = dad==NULL ? 0 : dad->getNbrChildren ();
+   return nbre;
 }
 // ======================================================== loadXml
-int Document::loadXml ()
+int Document::loadXml (cpchar ficname)
+{
+   XmlTree xml("");
+   std::string filename = ficname;
+   //el_name         = Kernel_Utils::GetBaseName ((pchar)ficname);
+   make_basename (ficname, el_name);
+
+   static const int NbExt = 3;
+   static cpchar t_ext [NbExt] = { ".xml", ".XML", ".Xml" };
+   size_t ici   = 0;
+   bool   noext = true;
+   for (int nx = 0; nx < NbExt && noext ; nx++)
+       {
+       ici   = el_name.rfind (t_ext[nx]);
+       noext = ici < 0 || ici > el_name.size();
+       }
+
+   if (noext)
+      filename += ".xml";
+   else
+      el_name.erase (ici, 4);
+
+   int ier = xml.parseFile (filename);
+   if (ier!=HOK)
+      return ier;
+
+   ier = parseXml (xml);
+   return ier;
+}
+// ======================================================== setXml
+int Document::setXml (cpchar flux)
+{
+   int posit = 0;
+   int ier   = setXml (flux, posit);
+   return ier;
+}
+// ======================================================== setXml
+int Document::setXml (cpchar flux, int& posit)
 {
    XmlTree xml("");
-   xml.parseFile (doc_name + ".xml");
-   xml.dump ();
 
-   vector <Vertex*> t_vertex;
-   vector <Edge*>   t_edge;
-   vector <Quad*>   t_quad;
-   vector <Hexa*>   t_hexa;
-   int table [10];
+   int ier = xml.parseStream (flux, posit);
+   if (ier!=HOK)
+      return ier;
+
+   ier = parseXml (xml);
+   if (ier==HOK)
+      doc_saved = true;
+
+   return ier;
+}
+// ======================================================== parseXml
+int Document::parseXml (XmlTree& xml)
+{
+   // xml.dump ();
+
+   std::map <std::string, Vertex*> t_vertex;
+   std::map <std::string, Edge*>   t_edge;
+   std::map <std::string, Quad*>   t_quad;
+   std::map <std::string, Hexa*>   t_hexa;
+   std::map <std::string, Vector*> t_vector;
+   std::vector <std::string> tname;
+
+   const  std::string& version = xml.findValue ("version");
+   if (version == "")
+       {
+       std::cout << " **** Format du fichier XML perime"
+                << std::endl;
+       return HERR;
+       }
+   const  std::string& name = xml.findValue ("name");
+   if (name != el_name)
+       setName (name.c_str());
+
+   parseShapes (xml);
 
    XmlTree* rubrique = xml.findChild ("ListVertices");
-   int nbrelts       = rubrique->getNbrChildren ();
-   t_vertex.resize (nbrelts);
+   int nbrelts       = count_children (rubrique);
 
+   Vertex* vertex = NULL;
    for (int nro=0 ; nro < nbrelts ; nro++)
        {
        XmlTree* node = rubrique->getChild (nro);
+       const std::string& type = node->getName();
        double px, py, pz;
-       const  string& nom    = node->findValue ("id");
-       const  string& coords = node->findValue ("coord");
-       get_coords (coords, px, py, pz);
+       if (type=="Vertex")
+          {
+          const  std::string& nom    = node->findValue ("id");
+          const  std::string& coords = node->findValue ("coord");
+          get_coords (coords, px, py, pz);
 
-       int nver = get_int (nom);
-       t_vertex [nver] = addVertex (px, py, pz);
-       Display  (nver);
+          vertex = addVertex (px, py, pz);
+          parse_name (node, nom, vertex);
+          t_vertex [nom] = vertex;
+          }
+       else if (type=="Asso")
+          {
+          parseAssociation (node, vertex);
+          }
        }
 
-
    rubrique = xml.findChild ("ListEdges");
-   nbrelts  = rubrique->getNbrChildren ();
-   t_edge.resize (nbrelts);
+   nbrelts  = count_children (rubrique);
+   Edge* edge = NULL;
+
+   for (int nro=0 ; nro < nbrelts ; nro++)
+       {
+       XmlTree*      node = rubrique->getChild (nro);
+       const std::string& type = node->getName();
+       if (type=="Edge")
+          {
+          const  std::string& nom      = node->findValue ("id");
+          const  std::string& vertices = node->findValue ("vertices");
+          get_names (vertices, V_TWO, tname);
+          edge = new Edge (t_vertex [tname[0]], t_vertex [tname[1]]);
+          t_edge [nom] = edge;
+          parse_name (node, nom, edge);
+          }
+       else if (type=="Asso")
+          {
+          parseAssociation (node, edge);
+          }
+       }
+
+   rubrique = xml.findChild ("ListQuads");
+   nbrelts  = count_children (rubrique);
+   Quad* quad = NULL;
+
+   for (int nro=0 ; nro < nbrelts ; nro++)
+       {
+       XmlTree*      node = rubrique->getChild (nro);
+       const std::string& type = node->getName();
+       if (type=="Quad")
+          {
+          const std::string& nom   = node->findValue ("id");
+          const std::string& edges = node->findValue ("edges");
+          get_names (edges, V_TWO, tname);
+
+          quad = new Quad (t_edge [tname[0]], t_edge [tname[1]],
+                           t_edge [tname[2]], t_edge [tname[3]]);
+          t_quad [nom] = quad;
+          parse_name (node, nom, quad);
+          }
+       else if (type=="Asso")
+          {
+          parseAssociation (node, quad);
+          }
+       }
+
+   rubrique = xml.findChild ("ListHexas");
+   nbrelts  = count_children (rubrique);
 
    for (int nro=0 ; nro < nbrelts ; nro++)
        {
        XmlTree* node = rubrique->getChild (nro);
-       const  string& nom      = node->findValue ("id");
-       const  string& vertices = node->findValue ("vertices");
-       get_values (vertices, V_TWO, table);
+       const  std::string& nom   = node->findValue ("id");
+       const  std::string& quads = node->findValue ("quads");
+       get_names (quads, V_TWO, tname);
+
+       Hexa* hexa =  new Hexa (t_quad [tname[0]], t_quad [tname[1]],
+                                t_quad [tname[2]], t_quad [tname[3]],
+                                t_quad [tname[4]], t_quad [tname[5]]);
+       t_hexa [nom] = hexa;
+       parse_name (node, nom, hexa);
+       }
 
-       int ned = get_int (nom);
-       t_edge [ned] = new Edge (t_vertex [table[0]], t_vertex [table[1]]);
-       Display  (ned);
+   rubrique = xml.findChild ("ListVectors");
+   nbrelts  = count_children (rubrique);
+
+   for (int nro=0 ; nro < nbrelts ; nro++)
+       {
+       XmlTree* node = rubrique->getChild (nro);
+       double px, py, pz;
+       const  std::string& nom    = node->findValue ("id");
+       const  std::string& coords = node->findValue ("coord");
+       get_coords (coords, px, py, pz);
+
+       Vector* vector = addVector (px, py, pz);
+       t_vector [nom] = vector;
+       parse_name (node, nom, vector);
        }
 
-   rubrique = xml.findChild ("ListQuads");
-   nbrelts  = rubrique->getNbrChildren ();
-   t_quad.resize (nbrelts);
+   rubrique = xml.findChild ("ListDicretizationLaws");
+   nbrelts  = count_children (rubrique);
 
    for (int nro=0 ; nro < nbrelts ; nro++)
        {
        XmlTree* node = rubrique->getChild (nro);
-       const string& nom   = node->findValue ("id");
-       const string& edges = node->findValue ("edges");
-       get_values (edges, QUAD4, table);
-
-       int nquad = get_int (nom);
-       t_quad [nquad] = new Quad (t_edge [table[0]], t_edge [table[1]],
-                                  t_edge [table[2]], t_edge [table[3]]);
-       Display  (nquad);
+       const  std::string& id    = node->findValue ("id");
+       const  std::string& kind  = node->findValue ("kind");
+       const  std::string& nodes = node->findValue ("nodes");
+       const  std::string& coeff = node->findValue ("coeff");
+
+       int    nbnodes = atoi (nodes.c_str());
+       double koeff   = atof (coeff.c_str());
+       if (id != "DefaultLaw")
+          {
+          Law*   law  = addLaw (id.c_str(), nbnodes);
+          law->setCoefficient (koeff);
+          law->setKind (kind.c_str());
+          }
        }
 
-   rubrique = xml.findChild ("ListHexas");
-   nbrelts  = rubrique->getNbrChildren ();
-   t_hexa.resize (nbrelts);
+   rubrique = xml.findChild ("ListPropagations");
+   nbrelts  = count_children (rubrique);
 
    for (int nro=0 ; nro < nbrelts ; nro++)
        {
        XmlTree* node = rubrique->getChild (nro);
-       const  string& nom   = node->findValue ("id");
-       const  string& quads = node->findValue ("quads");
-       get_values (quads, HQ_MAXI, table);
-
-       int nhexa      = get_int (nom);
-       t_hexa [nhexa] = new Hexa (t_quad [table[0]], t_quad [table[1]],
-                                  t_quad [table[2]], t_quad [table[3]],
-                                  t_quad [table[4]], t_quad [table[5]]);
-       Display  (nhexa);
+       const  std::string& nmedge  = node->findValue ("edge");
+       const  std::string& nmlaw   = node->findValue ("law");
+       //  const  std::string& nmway   = node->findValue ("way");
+
+       edge     = t_edge [nmedge];
+       Law* law = findLaw (nmlaw.c_str());
+       //  bool way = nmway == "true";
+
+       if (edge != NULL)
+           edge->setLaw (law);
+       }
+
+   rubrique = xml.findChild ("ListGroups");
+   int nbrgroups  = count_children (rubrique);
+
+   for (int nro=0 ; nro < nbrgroups ; nro++)
+       {
+       XmlTree*  ndgroup = rubrique->getChild (nro);
+       XmlTree*  node    = ndgroup ->getChild (0);
+       const  std::string& nom   = node->findValue ("name");
+       const  std::string& ckind = node->findValue ("kind");
+
+       EnumGroup kind   = Group::getKind (ckind);
+       Group*    groupe = addGroup (nom.c_str(), kind);
+       EnumElt   type   = groupe->getTypeElt ();
+
+       nbrelts = count_children (ndgroup);
+       for (int nelt=1 ; nelt < nbrelts ; nelt++)
+           {
+           node = ndgroup ->getChild (nelt);
+           const std::string& id = node->findValue ("id");
+           switch (type)
+              {
+              case EL_HEXA : groupe->addElement (t_hexa [id]);
+                   break;
+              case EL_QUAD : groupe->addElement (t_quad [id]);
+                   break;
+              case EL_EDGE : groupe->addElement (t_edge [id]);
+                   break;
+              case EL_VERTEX :
+              default      : groupe->addElement (t_vertex [id]);
+                   break;
+              }
+           }
        }
 
 
    return HOK;
 }
-// ======================================================== renumeroter
-void Document::renumeroter ()
+// ======================================================== save
+int Document::save (const char* ficxml)
 {
-   doc_modified = true;
-                                       // -- 1) Raz numerotation precedente
-   markAll (NO_COUNTED);
+   DumpStart ("save", ficxml);
+
+   if (doc_xml==NULL)
+       doc_xml = new XmlWriter ();
+
+   int ier  = doc_xml->setFileName (ficxml);
+   if (ier == HOK)
+       ier =  genXml ();
+
+   DumpReturn (ier);
+   return ier;
+}
+// ======================================================== appendXml
+int Document::appendXml (pfile fstudy)
+{
+   if (doc_xml==NULL)
+       doc_xml = new XmlWriter ();
+
+   doc_xml->setFile (fstudy);
+
+   int    ier = genXml ();
+   return ier;
 }
-// ======================================================== saveFile
-int Document::saveFile ()
+// ======================================================== getXml
+cpchar Document::getXml ()
 {
+   if (doc_xml==NULL)
+       doc_xml = new XmlWriter ();
+
+   doc_xml->setStream ();
+   int ier = genXml ();
+   if (ier!=HOK)
+      return NULL;
+
+   return doc_xml->getXml ();
+}
+// ======================================================== genXml
+int Document::genXml ()
+{
+   const int HexVersion = 1;
                                        // -- 1) Raz numerotation precedente
-   renumeroter ();
+   markAll (NO_COUNTED);
    if (maj_propagation)
        majPropagation ();
 
-   doc_modified = false;
-   XmlWriter xml;
-   xml.openXml  (doc_name);
-   xml.openMark ("Document");
-   xml.addAttribute ("name", doc_name);
-   xml.endMark ();
+   if (doc_xml==NULL)
+       doc_xml = new XmlWriter ();
 
-   cpchar balise [] = {"ListXXX", 
-          "ListVertices", "ListEdges", "ListQuads", "ListHexas", "ListXXXX" };
+   doc_xml->startXml ();
+   doc_xml->openMark ("Document");
+   doc_xml->addAttribute ("name",    el_name);
+   doc_xml->addAttribute ("version", HexVersion);
+   doc_xml->endMark ();
 
-   for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
+   cpchar balise [] = {"ListXXXX",
+          "ListVertices", "ListEdges", "ListQuads", "ListHexas", "ListVectors",
+          "ListXXXX" };
+
+   for (int type=EL_VERTEX ; type <= EL_VECTOR ; type++)
        {
-       xml.addMark (balise [type]);
+       doc_xml->addMark (balise [type]);
        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
                      elt = elt->next())
            {
            if (elt !=NULL && elt->isHere())
-              elt->saveXml (xml);
+              elt->saveXml (doc_xml);
            }
-       xml.closeMark (true);
+       doc_xml->closeMark (true);
        }
 
-   xml.addMark ("ListDicretizationLaws");
+   doc_xml->addMark ("ListDicretizationLaws");
    for (int nro=0 ; nro<nbr_laws ; nro++)
-       doc_laws [nro]->saveXml (xml);
-   xml.closeMark (true);
+       doc_laws [nro]->saveXml (doc_xml);
+   doc_xml->closeMark (true);
 
-   xml.addMark ("ListPropagations");
+   doc_xml->addMark ("ListPropagations");
    for (int nro=0 ; nro<nbr_propagations ; nro++)
-       doc_propagation[nro]->saveXml (xml);
-   xml.closeMark ();
-
-   xml.closeMark ();
-   xml.closeXml  ();
+       doc_propagation[nro]->saveXml (doc_xml);
+   doc_xml->closeMark (true);
+
+   int nombre = countGroup();
+   doc_xml->addMark ("ListGroups");
+   for (int nro=0 ; nro<nombre ; nro++)
+       doc_group[nro]->saveXml (doc_xml);
+   doc_xml->closeMark (true);
+
+   nombre = countShape ();
+   doc_xml->addMark ("ListShapes");
+   for (int nro=0 ; nro<nombre ; nro++)
+       doc_tab_shape[nro]->saveXml (doc_xml);
+   doc_xml->closeMark ();
+
+   doc_xml->closeMark ();
+   doc_xml->closeXml  ();
+   doc_saved = true;
    return  HOK;
 }
 // ======================================================== markAll
@@ -223,14 +491,14 @@ void Document::markAll (int marque, int type)
        }
 }
 // ====================================================== saveVtk
-int Document::saveVtk (cpchar nomfic)
+int Document::saveVtk0 (cpchar nomfic)
 {
                                            // -- 1) Raz numerotation precedente
    markAll (NO_COUNTED, EL_VERTEX);
 
    int nbnodes = 0;
    int nbcells = 0;
-                                           // -- 2) Comptage
+
    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
                  elt = elt->next())
        {
@@ -242,7 +510,15 @@ int Document::saveVtk (cpchar nomfic)
           }
        }
 
-   pfile    vtk = fopen (nomfic, "w");
+   pfile vtk = fopen (nomfic, "w");
+   if (vtk==NULL)
+      {
+      std::cout << " ****" << std::endl;
+      std::cout << " **** Document::saveVtk : " << std::endl;
+      std::cout << " **** Can't open file "     << std::endl;
+      std::cout << " ****" << std::endl;
+
+      }
    fprintf (vtk, "# vtk DataFile Version 3.1\n");
    fprintf (vtk, "%s \n", nomfic);
    fprintf (vtk, "ASCII\n");
@@ -289,10 +565,87 @@ int Document::saveVtk (cpchar nomfic)
    fclose (vtk);
    return HOK;
 }
+
+// ====================================================== saveVtk
+// ==== Nouvelle formule qui conserve les numeros de vertex
+int Document::saveVtk (cpchar nomfic)
+{
+   DumpStart ("saveVtk", nomfic);
+   int nbnodes = doc_nbr_elt [EL_VERTEX];
+   int nbcells = countHexa ();
+
+   pfile vtk = fopen (nomfic, "w");
+   if (vtk==NULL)
+      {
+      std::cout << " ****" << std::endl;
+      std::cout << " **** Document::saveVtk : " << std::endl;
+      std::cout << " **** Can't open file "     << std::endl;
+      std::cout << " ****" << std::endl;
+
+      }
+   fprintf (vtk, "# vtk DataFile Version 3.1\n");
+   fprintf (vtk, "%s \n", nomfic);
+   fprintf (vtk, "ASCII\n");
+   fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
+   fprintf (vtk, "POINTS %d float\n", nbnodes);
+
+                                           // -- 1) Les noeuds
+   Real3 koord;
+   static const double minvtk = 1e-30;
+#define Koord(p) koord[p]<minvtk && koord[p]>-minvtk ? 0 : koord[p]
+
+   for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
+                 elt = elt->next())
+       {
+       Vertex* node = static_cast <Vertex*> (elt);
+       if (node->isHere())
+          {
+          node->getPoint (koord);
+          fprintf (vtk, "%g %g %g\n", Koord(dir_x), Koord(dir_y), Koord(dir_z));
+          }
+       else
+          fprintf (vtk, "0 0 0\n");
+       }
+                                           // -- 2) Les hexas
+
+   fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
+
+   for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
+                 elt = elt->next())
+       {
+       Hexa* cell = static_cast <Hexa*> (elt);
+       if (cell!=NULL && cell->isHere())
+          cell->printHexaVtk (vtk);
+       }
+
+   fprintf (vtk, "CELL_TYPES %d\n", nbcells);
+   for (int nro=0 ; nro<nbcells ; nro++)
+       fprintf (vtk, "%d\n", HE_MAXI);
+
+   fprintf (vtk, "POINT_DATA %d \n", nbnodes);
+   fprintf (vtk, "SCALARS A float\n");
+   fprintf (vtk, "LOOKUP_TABLE default\n");
+   for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
+                 elt = elt->next())
+       {
+       Vertex* node = static_cast <Vertex*> (elt);
+       if (node->isHere())
+          {
+          double color = 100*(node->getScalar()+1);
+          fprintf (vtk, "%g\n", color);
+          }
+       else 
+          fprintf (vtk, "100\n");
+       }
+
+   fclose (vtk);
+   DumpReturn (HOK);
+   return HOK;
+}
 // ====================================================== purge
 void Document::purge ()
 {
-   purge_elements = true;
+   purge_elements = false;
                        // ------------------- Raz marques
    markAll (NO_USED);
 
@@ -316,6 +669,7 @@ void Document::purge ()
        }
                        // ------------------- Sortie elements inutilises
 
+/* ****************************************************************
    EltBase* trash = doc_last_elt [EL_REMOVED];
 
    for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
@@ -329,7 +683,7 @@ void Document::purge ()
                doc_nbr_elt  [type] ++;
                last = elt;
                }
-          else
+           else
                {
                last  -> setNext (elt -> next());
                trash -> setNext (elt);
@@ -341,6 +695,7 @@ void Document::purge ()
        }
 
    doc_last_elt [EL_REMOVED] = trash;
+   **************************************************************** */
    update ();
 }
 // ======================================================== majReferences
@@ -370,7 +725,7 @@ void Document::majReferences ()
 // ======================================================== dump
 void Document::dump ()
 {
-   cpchar nom_type [] = { "Elments non classes", 
+   cpchar nom_type [] = { "Elments non classes",
           "Sommets", "Aretes", "Faces", "Hexaedres", "Elements detruits" };
 
    for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
@@ -382,7 +737,8 @@ void Document::dump ()
        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
                      elt = elt->next())
            {
-           elt->dump ();
+           if (elt->isHere())
+               elt->dump ();
            }
        }
 
@@ -400,5 +756,103 @@ void Document::putError (cpchar mess, cpchar info1, cpchar info2)
      printf (" **** \n");
      printf (" ********************************************************** \n");
 }
+// ======================================================== hputError
+void Document::hputError (cpchar mess, EltBase* e1, EltBase* e2)
+{
+   char name1 [32] = { 0 };
+   char name2 [32] = { 0 };
+
+   if (e1!=NULL) e1->getName (name1);
+   if (e2!=NULL) e2->getName (name2);
 
+   putError (mess, name1, name2);
+}
+// ======================================================== parseSubShape
+SubShape* Document::parseSubShape (XmlTree* node)
+{
+   const std::string& name  = node->findValue   ("shape");
+   int           subid = node->findInteger ("subid");
+   NewShape*     shape = findShape (name);
+   if (shape==NULL)
+       return NULL;
+
+   SubShape* sub_shape = shape->findSubShape (subid);
+   return    sub_shape;
+}
+// ======================================================== parseAssociation (v)
+void Document::parseAssociation (XmlTree* node, Vertex* vertex)
+{
+   SubShape* shape = parseSubShape (node);
+   if (shape==NULL || vertex==NULL)
+       return;
+
+   if (shape->getDim()!=0)
+      return;
+   VertexShape* vshape = static_cast <VertexShape*> (shape);
+   vertex->setAssociation (vshape);
+}
+// ======================================================== parseAssociation (e)
+void Document::parseAssociation (XmlTree* node, Edge* edge)
+{
+   SubShape* shape = parseSubShape (node);
+   if (shape==NULL || edge==NULL)
+       return;
+
+   if (shape->getDim()!=1)
+      return;
+
+   const  std::string& inter = node->findValue ("interval");
+   double pdeb, pfin;
+   get_coords (inter, pdeb, pfin);
+
+   EdgeShape* line = static_cast <EdgeShape*> (shape);
+   edge->addAssociation (line, pdeb, pfin);
+}
+// ======================================================== parseAssociation (q)
+void Document::parseAssociation (XmlTree* node, Quad* quad)
+{
+   SubShape* shape = parseSubShape (node);
+   if (shape==NULL || quad==NULL)
+       return;
+
+   if (shape->getDim()!=2)
+      return;
+   FaceShape* face = static_cast <FaceShape*> (shape);
+   quad->addAssociation (face);
+}
+// ======================================================== parseShapes
+void Document::parseShapes (XmlTree& root)
+{
+   XmlTree* rubrique = root.findChild ("ListShapes");
+   int nbrelts       = count_children (rubrique);
+
+   for (int nro=0 ; nro < nbrelts ; nro++)
+       {
+       XmlTree*      node = rubrique->getChild (nro);
+       const std::string& type = node->getName();
+       if (type=="Shape")
+          {
+          const std::string& nom   = node->findValue   ("id"  );
+          int           orig  = node->findInteger ("type");
+          const std::string& brep  = node->findValue   ("brep");
+          NewShape*     shape = new NewShape (this, (EnumShape)orig);
+
+          parse_name (node, nom, shape);
+          shape->setBrep (brep);
+          doc_tab_shape.push_back (shape);
+          }
+       else if (type=="Cloud")
+          {
+          int nbvert = count_children (node);
+          for (int nv=0 ; nv < nbvert ; nv++)
+              {
+              Real3    point;
+              XmlTree* sommet = node->getChild (nv);
+              const  std::string& coords = sommet->findValue ("coord");
+              get_coords (coords, point[dir_x], point[dir_y], point[dir_z]);
+              doc_cloud->addPoint (point);
+              }
+          }
+       }
+}
 END_NAMESPACE_HEXA