Salome HOME
39cfb4b322a9f6c838a37804ce4da2cbfd3088ab
[modules/hexablock.git] / src / HEXABLOCK / HexDocument_Xml.cxx
1
2 // C++ : Classe Document : methodes internes
3
4 // Copyright (C) 2009-2013  CEA/DEN, EDF R&D
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "HexDocument.hxx"
23 #include <Basics_DirUtils.hxx>   
24 #include <cstdlib>               // Pour atoi et atof
25
26 #include "Hex.hxx"
27 #include "HexVertex.hxx"
28 #include "HexEdge.hxx"
29 #include "HexQuad.hxx"
30 #include "HexHexa.hxx"
31
32 #include "HexElements.hxx"
33
34 #include "HexVector.hxx"
35 #include "HexMatrix.hxx"
36 #include "HexCloner.hxx"
37 #include "HexPropagation.hxx"
38 #include "HexLaw.hxx"
39 #include "HexGroup.hxx"
40
41 #include "HexNewShape.hxx"
42 #include "HexVertexShape.hxx"
43 #include "HexEdgeShape.hxx"
44 #include "HexFaceShape.hxx"
45
46 #include "HexXmlWriter.hxx"
47 #include "HexXmlTree.hxx"
48 #include "HexGlobale.hxx"
49
50 BEGIN_NAMESPACE_HEXA
51
52 // ======================================================== get_coords
53 int get_coords (const string& chaine, double& x, double& y, double& z)
54 {
55    // int nv = sscanf (chaine.c_str (), "%lg %lg %lg", &x, &y, &z);
56    cpchar buffer = chaine.c_str ();
57    int nv = sscanf (buffer, "%lg %lg %lg", &x, &y, &z);
58    if (nv!=3) return HERR;
59    return HOK;
60 }
61 // ======================================================== get_coords
62 int get_coords (const string& chaine, double& x, double& y)
63 {
64    cpchar buffer = chaine.c_str ();
65    int nv = sscanf (buffer, "%lg %lg", &x, &y);
66    if (nv!=2) return HERR;
67    return HOK;
68 }
69 // ======================================================== parse_name
70 int parse_name (XmlTree* node, const string& nom, EltBase* elt)
71 {
72    int lg    = nom.size();
73    int nroid = 0;
74    for (int nc=1 ; nc<lg ; nc++)
75        nroid = 10*nroid + nom[nc] - '0';
76
77    elt->setId (nroid);
78
79    const  string& name = node->findValue ("name");
80    if (name=="")
81       return HERR;
82
83    elt->setName (name);
84    return HOK;
85 }
86 // ======================================================== get_names
87 void get_names (const string& chaine, int size, vector<string>& table)
88 {
89    table.clear ();
90    int    lg    = chaine.size();
91    string mot   = "";
92    bool encours = false;
93
94    for (int nc=0 ; nc<lg ; nc++)
95        {
96        char car  = chaine[nc];
97        if (isalnum (car))
98           {
99           mot += car;
100           encours = true;
101           }
102        else if (encours)
103           {
104           table.push_back (mot);
105           encours = false;
106           mot     = "";
107           }
108        }
109
110    if (encours)
111       table.push_back (mot);
112 }
113 // ======================================================== count_children
114 int count_children (XmlTree* dad)
115 {
116    int    nbre = dad==NULL ? 0 : dad->getNbrChildren ();
117    return nbre;
118 }
119 // ======================================================== loadXml
120 int Document::loadXml (cpchar ficname)
121 {
122    XmlTree xml("");
123    string filename = ficname;
124    el_name         = Kernel_Utils::GetBaseName ((pchar)ficname);
125
126    static const int NbExt = 3;
127    static cpchar t_ext [NbExt] = { ".xml", ".XML", ".Xml" };
128    size_t ici   = 0;
129    bool   noext = true;
130    for (int nx = 0; nx < NbExt && noext ; nx++)
131        {
132        ici   = el_name.rfind (t_ext[nx]);
133        noext = ici < 0 || ici > el_name.size();
134        }
135
136    if (noext)
137       filename += ".xml";
138    else
139       el_name.erase (ici, 4);
140
141    int ier = xml.parseFile (filename);
142    if (ier!=HOK)
143       return ier;
144
145    ier = parseXml (xml);
146    return ier;
147 }
148 // ======================================================== setXml
149 int Document::setXml (cpchar flux)
150 {
151    int posit = 0;
152    int ier   = setXml (flux, posit);
153    return ier;
154 }
155 // ======================================================== setXml
156 int Document::setXml (cpchar flux, int& posit)
157 {
158    XmlTree xml("");
159
160    int ier = xml.parseStream (flux, posit);
161    if (ier!=HOK)
162       return ier;
163
164    ier = parseXml (xml);
165    if (ier==HOK)
166       doc_saved = true;
167
168    return ier;
169 }
170 // ======================================================== parseXml
171 int Document::parseXml (XmlTree& xml)
172 {
173    // xml.dump ();
174
175    map <std::string, Vertex*> t_vertex;
176    map <std::string, Edge*>   t_edge;
177    map <std::string, Quad*>   t_quad;
178    map <std::string, Hexa*>   t_hexa;
179    map <std::string, Vector*> t_vector;
180    vector <string> tname;
181
182    const  string& version = xml.findValue ("version");
183    if (version == "")
184        {
185        cout << " **** Format du fichier XML perime"
186             << endl;
187        return HERR;
188        }
189    const  string& name = xml.findValue ("name");
190    if (name != el_name)
191        setName (name.c_str());
192
193    parseShapes (xml);
194
195    XmlTree* rubrique = xml.findChild ("ListVertices");
196    int nbrelts       = count_children (rubrique);
197
198    Vertex* vertex = NULL;
199    for (int nro=0 ; nro < nbrelts ; nro++)
200        {
201        XmlTree* node = rubrique->getChild (nro);
202        const string& type = node->getName();
203        double px, py, pz;
204        if (type=="Vertex")
205           {
206           const  string& nom    = node->findValue ("id");
207           const  string& coords = node->findValue ("coord");
208           get_coords (coords, px, py, pz);
209
210           vertex = addVertex (px, py, pz);
211           parse_name (node, nom, vertex);
212           t_vertex [nom] = vertex;
213           }
214        else if (type=="Asso")
215           {
216           parseAssociation (node, vertex);
217           }
218        }
219
220    rubrique = xml.findChild ("ListEdges");
221    nbrelts  = count_children (rubrique);
222    Edge* edge = NULL;
223
224    for (int nro=0 ; nro < nbrelts ; nro++)
225        {
226        XmlTree*      node = rubrique->getChild (nro);
227        const string& type = node->getName();
228        if (type=="Edge")
229           {
230           const  string& nom      = node->findValue ("id");
231           const  string& vertices = node->findValue ("vertices");
232           get_names (vertices, V_TWO, tname);
233           edge = new Edge (t_vertex [tname[0]], t_vertex [tname[1]]);
234           t_edge [nom] = edge;
235           parse_name (node, nom, edge);
236           }
237        else if (type=="Asso")
238           {
239           parseAssociation (node, edge);
240           }
241        }
242
243    rubrique = xml.findChild ("ListQuads");
244    nbrelts  = count_children (rubrique);
245    Quad* quad = NULL;
246
247    for (int nro=0 ; nro < nbrelts ; nro++)
248        {
249        XmlTree*      node = rubrique->getChild (nro);
250        const string& type = node->getName();
251        if (type=="Quad")
252           {
253           const string& nom   = node->findValue ("id");
254           const string& edges = node->findValue ("edges");
255           get_names (edges, V_TWO, tname);
256
257           quad = new Quad (t_edge [tname[0]], t_edge [tname[1]],
258                            t_edge [tname[2]], t_edge [tname[3]]);
259           t_quad [nom] = quad;
260           parse_name (node, nom, quad);
261           }
262        else if (type=="Asso")
263           {
264           parseAssociation (node, quad);
265           }
266        }
267
268    rubrique = xml.findChild ("ListHexas");
269    nbrelts  = count_children (rubrique);
270
271    for (int nro=0 ; nro < nbrelts ; nro++)
272        {
273        XmlTree* node = rubrique->getChild (nro);
274        const  string& nom   = node->findValue ("id");
275        const  string& quads = node->findValue ("quads");
276        get_names (quads, V_TWO, tname);
277
278        Hexa* hexa =  new Hexa (t_quad [tname[0]], t_quad [tname[1]],
279                                 t_quad [tname[2]], t_quad [tname[3]],
280                                 t_quad [tname[4]], t_quad [tname[5]]);
281        t_hexa [nom] = hexa;
282        parse_name (node, nom, hexa);
283        }
284
285    rubrique = xml.findChild ("ListVectors");
286    nbrelts  = count_children (rubrique);
287
288    for (int nro=0 ; nro < nbrelts ; nro++)
289        {
290        XmlTree* node = rubrique->getChild (nro);
291        double px, py, pz;
292        const  string& nom    = node->findValue ("id");
293        const  string& coords = node->findValue ("coord");
294        get_coords (coords, px, py, pz);
295
296        Vector* vector = addVector (px, py, pz);
297        t_vector [nom] = vector;
298        parse_name (node, nom, vector);
299        }
300
301    rubrique = xml.findChild ("ListDicretizationLaws");
302    nbrelts  = count_children (rubrique);
303
304    for (int nro=0 ; nro < nbrelts ; nro++)
305        {
306        XmlTree* node = rubrique->getChild (nro);
307        const  string& id    = node->findValue ("id");
308        const  string& kind  = node->findValue ("kind");
309        const  string& nodes = node->findValue ("nodes");
310        const  string& coeff = node->findValue ("coeff");
311
312        int    nbnodes = atoi (nodes.c_str());
313        double koeff   = atof (coeff.c_str());
314        if (id != "DefaultLaw")
315           {
316           Law*   law  = addLaw (id.c_str(), nbnodes);
317           law->setCoefficient (koeff);
318           law->setKind (kind.c_str());
319           }
320        }
321
322    rubrique = xml.findChild ("ListPropagations");
323    nbrelts  = count_children (rubrique);
324
325    for (int nro=0 ; nro < nbrelts ; nro++)
326        {
327        XmlTree* node = rubrique->getChild (nro);
328        const  string& nmedge  = node->findValue ("edge");
329        const  string& nmlaw   = node->findValue ("law");
330        //  const  string& nmway   = node->findValue ("way");
331
332        edge     = t_edge [nmedge];
333        Law* law = findLaw (nmlaw.c_str());
334        //  bool way = nmway == "true";
335
336        if (edge != NULL)
337            edge->setLaw (law);
338        }
339
340    rubrique = xml.findChild ("ListGroups");
341    int nbrgroups  = count_children (rubrique);
342
343    for (int nro=0 ; nro < nbrgroups ; nro++)
344        {
345        XmlTree*  ndgroup = rubrique->getChild (nro);
346        XmlTree*  node    = ndgroup ->getChild (0);
347        const  string& nom   = node->findValue ("name");
348        const  string& ckind = node->findValue ("kind");
349
350        EnumGroup kind   = Group::getKind (ckind);
351        Group*    groupe = addGroup (nom.c_str(), kind);
352        EnumElt   type   = groupe->getTypeElt ();
353
354        nbrelts = count_children (ndgroup);
355        for (int nelt=1 ; nelt < nbrelts ; nelt++)
356            {
357            node = ndgroup ->getChild (nelt);
358            const string& id = node->findValue ("id");
359            switch (type)
360               {
361               case EL_HEXA : groupe->addElement (t_hexa [id]);
362                    break;
363               case EL_QUAD : groupe->addElement (t_quad [id]);
364                    break;
365               case EL_EDGE : groupe->addElement (t_edge [id]);
366                    break;
367               case EL_VERTEX :
368               default      : groupe->addElement (t_vertex [id]);
369                    break;
370               }
371            }
372        }
373
374
375    return HOK;
376 }
377 // ======================================================== save
378 int Document::save (const char* ficxml)
379 {
380    DumpStart ("save", ficxml);
381
382    if (doc_xml==NULL)
383        doc_xml = new XmlWriter ();
384
385    int ier  = doc_xml->setFileName (ficxml);
386    if (ier == HOK)
387        ier =  genXml ();
388
389    DumpReturn (ier);
390    return ier;
391 }
392 // ======================================================== appendXml
393 int Document::appendXml (pfile fstudy)
394 {
395    if (doc_xml==NULL)
396        doc_xml = new XmlWriter ();
397
398    doc_xml->setFile (fstudy);
399
400    int    ier = genXml ();
401    return ier;
402 }
403 // ======================================================== getXml
404 cpchar Document::getXml ()
405 {
406    if (doc_xml==NULL)
407        doc_xml = new XmlWriter ();
408
409    doc_xml->setStream ();
410    int ier = genXml ();
411    if (ier!=HOK)
412       return NULL;
413
414    return doc_xml->getXml ();
415 }
416 // ======================================================== genXml
417 int Document::genXml ()
418 {
419    const int HexVersion = 1;
420                                        // -- 1) Raz numerotation precedente
421    markAll (NO_COUNTED);
422    if (maj_propagation)
423        majPropagation ();
424
425    if (doc_xml==NULL)
426        doc_xml = new XmlWriter ();
427
428    doc_xml->startXml ();
429    doc_xml->openMark ("Document");
430    doc_xml->addAttribute ("name",    el_name);
431    doc_xml->addAttribute ("version", HexVersion);
432    doc_xml->endMark ();
433
434    cpchar balise [] = {"ListXXXX",
435           "ListVertices", "ListEdges", "ListQuads", "ListHexas", "ListVectors",
436           "ListXXXX" };
437
438    for (int type=EL_VERTEX ; type <= EL_VECTOR ; type++)
439        {
440        doc_xml->addMark (balise [type]);
441        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
442                      elt = elt->next())
443            {
444            if (elt !=NULL && elt->isHere())
445               elt->saveXml (doc_xml);
446            }
447        doc_xml->closeMark (true);
448        }
449
450    doc_xml->addMark ("ListDicretizationLaws");
451    for (int nro=0 ; nro<nbr_laws ; nro++)
452        doc_laws [nro]->saveXml (doc_xml);
453    doc_xml->closeMark (true);
454
455    doc_xml->addMark ("ListPropagations");
456    for (int nro=0 ; nro<nbr_propagations ; nro++)
457        doc_propagation[nro]->saveXml (doc_xml);
458    doc_xml->closeMark (true);
459
460    int nombre = countGroup();
461    doc_xml->addMark ("ListGroups");
462    for (int nro=0 ; nro<nombre ; nro++)
463        doc_group[nro]->saveXml (doc_xml);
464    doc_xml->closeMark (true);
465
466    nombre = countShape ();
467    doc_xml->addMark ("ListShapes");
468    for (int nro=0 ; nro<nombre ; nro++)
469        doc_tab_shape[nro]->saveXml (doc_xml);
470    doc_xml->closeMark ();
471
472    doc_xml->closeMark ();
473    doc_xml->closeXml  ();
474    doc_saved = true;
475    return  HOK;
476 }
477 // ======================================================== markAll
478 void Document::markAll (int marque, int type)
479 {
480    int debut = EL_VERTEX;
481    int fin   = EL_HEXA;
482    if (type>=0 && type<EL_MAXI)
483       debut = fin = type;
484
485    for (int type=debut ; type <= fin ; type++)
486        {
487        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
488                      elt = elt->next())
489            elt->setMark (marque);
490        }
491 }
492 // ====================================================== saveVtk
493 int Document::saveVtk0 (cpchar nomfic)
494 {
495                                            // -- 1) Raz numerotation precedente
496    markAll (NO_COUNTED, EL_VERTEX);
497
498    int nbnodes = 0;
499    int nbcells = 0;
500
501    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
502                  elt = elt->next())
503        {
504        Hexa* cell = static_cast <Hexa*> (elt);
505        if (cell!=NULL && cell->isHere())
506           {
507           nbcells ++;
508           nbnodes += cell->countNodes ();
509           }
510        }
511
512    pfile vtk = fopen (nomfic, "w");
513    if (vtk==NULL)
514       {
515       cout << " ****" << endl;
516       cout << " **** Document::saveVtk : " << endl;
517       cout << " **** Can't open file "     << endl;
518       cout << " ****" << endl;
519
520       }
521    fprintf (vtk, "# vtk DataFile Version 3.1\n");
522    fprintf (vtk, "%s \n", nomfic);
523    fprintf (vtk, "ASCII\n");
524    fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
525    fprintf (vtk, "POINTS %d float\n", nbnodes);
526
527                                            // -- 2) Les noeuds
528    int nronode = 0;
529    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
530                  elt = elt->next())
531        {
532        Hexa* cell = static_cast <Hexa*> (elt);
533        if (cell!=NULL && cell->isHere())
534           cell->printNodes (vtk, nronode);
535        }
536                                            // -- 2) Les hexas
537
538    fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
539
540    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
541                  elt = elt->next())
542        {
543        Hexa* cell = static_cast <Hexa*> (elt);
544        if (cell!=NULL && cell->isHere())
545           cell->printHexa (vtk);
546        }
547
548    fprintf (vtk, "CELL_TYPES %d\n", nbcells);
549    for (int nro=0 ; nro<nbcells ; nro++)
550        fprintf (vtk, "%d\n", HE_MAXI);
551
552    fprintf (vtk, "POINT_DATA %d \n", nbnodes);
553    fprintf (vtk, "SCALARS A float\n");
554    fprintf (vtk, "LOOKUP_TABLE default\n");
555
556    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
557                  elt = elt->next())
558        {
559        Hexa* cell = static_cast <Hexa*> (elt);
560        if (cell!=NULL && cell->isHere())
561           cell->colorNodes (vtk);
562        }
563
564    fclose (vtk);
565    return HOK;
566 }
567
568 // ====================================================== saveVtk
569 // ==== Nouvelle formule qui conserve les numeros de vertex
570 int Document::saveVtk (cpchar nomfic)
571 {
572    DumpStart ("saveVtk", nomfic);
573    int nbnodes = doc_nbr_elt [EL_VERTEX];
574    int nbcells = countHexa ();
575
576    pfile vtk = fopen (nomfic, "w");
577    if (vtk==NULL)
578       {
579       cout << " ****" << endl;
580       cout << " **** Document::saveVtk : " << endl;
581       cout << " **** Can't open file "     << endl;
582       cout << " ****" << endl;
583
584       }
585    fprintf (vtk, "# vtk DataFile Version 3.1\n");
586    fprintf (vtk, "%s \n", nomfic);
587    fprintf (vtk, "ASCII\n");
588    fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
589    fprintf (vtk, "POINTS %d float\n", nbnodes);
590
591                                            // -- 1) Les noeuds
592    Real3 koord;
593    static const double minvtk = 1e-30;
594 #define Koord(p) koord[p]<minvtk && koord[p]>-minvtk ? 0 : koord[p]
595
596    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
597                  elt = elt->next())
598        {
599        Vertex* node = static_cast <Vertex*> (elt);
600        if (node->isHere())
601           {
602           node->getPoint (koord);
603           fprintf (vtk, "%g %g %g\n", Koord(dir_x), Koord(dir_y), Koord(dir_z));
604           }
605        else
606           fprintf (vtk, "0 0 0\n");
607        }
608                                            // -- 2) Les hexas
609
610    fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
611
612    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
613                  elt = elt->next())
614        {
615        Hexa* cell = static_cast <Hexa*> (elt);
616        if (cell!=NULL && cell->isHere())
617           cell->printHexaVtk (vtk);
618        }
619
620    fprintf (vtk, "CELL_TYPES %d\n", nbcells);
621    for (int nro=0 ; nro<nbcells ; nro++)
622        fprintf (vtk, "%d\n", HE_MAXI);
623
624    fprintf (vtk, "POINT_DATA %d \n", nbnodes);
625    fprintf (vtk, "SCALARS A float\n");
626    fprintf (vtk, "LOOKUP_TABLE default\n");
627    for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
628                  elt = elt->next())
629        {
630        Vertex* node = static_cast <Vertex*> (elt);
631        if (node->isHere())
632           {
633           double color = 100*(node->getScalar()+1);
634           fprintf (vtk, "%g\n", color);
635           }
636        else 
637           fprintf (vtk, "100\n");
638        }
639
640    fclose (vtk);
641    DumpReturn (HOK);
642    return HOK;
643 }
644 // ====================================================== purge
645 void Document::purge ()
646 {
647    purge_elements = false;
648                        // ------------------- Raz marques
649    markAll (NO_USED);
650
651                        // ------------------- Marquage elements utilises
652    for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
653                  elt = elt->next())
654        {
655        Hexa* cell = static_cast <Hexa*> (elt);
656        if (cell!=NULL && cell->isHere())
657           cell->markElements (IS_USED);
658        }
659                        // ------------------- Elimination elements inutilises
660    for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
661        {
662        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
663                      elt = elt->next())
664            {
665            if (elt->getMark  () == NO_USED)
666                elt->suppress ();
667            }
668        }
669                        // ------------------- Sortie elements inutilises
670
671 /* ****************************************************************
672    EltBase* trash = doc_last_elt [EL_REMOVED];
673
674    for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
675        {
676        doc_nbr_elt [type] = 0;
677        EltBase* last = doc_first_elt [type];
678        for (EltBase* elt = last->next (); elt!=NULL; elt = last->next())
679            {
680            if (elt->isHere  ())
681                {
682                doc_nbr_elt  [type] ++;
683                last = elt;
684                }
685            else
686                {
687                last  -> setNext (elt -> next());
688                trash -> setNext (elt);
689                trash = elt;
690                trash -> setNext (NULL);
691                }
692            }
693        doc_last_elt [type] = last;
694        }
695
696    doc_last_elt [EL_REMOVED] = trash;
697    **************************************************************** */
698    update ();
699 }
700 // ======================================================== majReferences
701 void Document::majReferences ()
702 {
703    maj_connection = false;
704
705    for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
706        {
707        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
708                      elt = elt->next())
709            {
710            elt->razReferences ();
711            }
712        }
713
714    for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
715        {
716        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
717                      elt = elt->next())
718            {
719            if (elt->isHere ())
720                elt->majReferences ();
721            }
722        }
723 }
724 // ======================================================== dump
725 void Document::dump ()
726 {
727    cpchar nom_type [] = { "Elments non classes",
728           "Sommets", "Aretes", "Faces", "Hexaedres", "Elements detruits" };
729
730    for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
731        {
732        printf ("\n");
733        printf (" ++++ Liste des %s\n", nom_type[type]);
734        printf ("\n");
735
736        for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
737                      elt = elt->next())
738            {
739            if (elt->isHere())
740                elt->dump ();
741            }
742        }
743
744    printf (" ++++ End od dump\n");
745 }
746 // ======================================================== putError
747 void Document::putError (cpchar mess, cpchar info1, cpchar info2)
748 {
749      nbr_errors ++;
750      printf (" ********************************************************** \n");
751      printf (" ****  HexaBlocks Error nro %d :\n", nbr_errors);
752      printf (" **** ");
753      printf (mess, info1, info2);
754      printf ("\n");
755      printf (" **** \n");
756      printf (" ********************************************************** \n");
757 }
758 // ======================================================== hputError
759 void Document::hputError (cpchar mess, EltBase* e1, EltBase* e2)
760 {
761    char name1 [32] = { 0 };
762    char name2 [32] = { 0 };
763
764    if (e1!=NULL) e1->getName (name1);
765    if (e2!=NULL) e2->getName (name2);
766
767    putError (mess, name1, name2);
768 }
769 // ======================================================== parseSubShape
770 SubShape* Document::parseSubShape (XmlTree* node)
771 {
772    const string& name  = node->findValue   ("shape");
773    int           subid = node->findInteger ("subid");
774    NewShape*     shape = findShape (name);
775    if (shape==NULL)
776        return NULL;
777
778    SubShape* sub_shape = shape->findSubShape (subid);
779    return    sub_shape;
780 }
781 // ======================================================== parseAssociation (v)
782 void Document::parseAssociation (XmlTree* node, Vertex* vertex)
783 {
784    SubShape* shape = parseSubShape (node);
785    if (shape==NULL || vertex==NULL)
786        return;
787
788    if (shape->getDim()!=0)
789       return;
790    VertexShape* vshape = static_cast <VertexShape*> (shape);
791    vertex->setAssociation (vshape);
792 }
793 // ======================================================== parseAssociation (e)
794 void Document::parseAssociation (XmlTree* node, Edge* edge)
795 {
796    SubShape* shape = parseSubShape (node);
797    if (shape==NULL || edge==NULL)
798        return;
799
800    if (shape->getDim()!=1)
801       return;
802
803    const  string& inter = node->findValue ("interval");
804    double pdeb, pfin;
805    get_coords (inter, pdeb, pfin);
806
807    EdgeShape* line = static_cast <EdgeShape*> (shape);
808    edge->addAssociation (line, pdeb, pfin);
809 }
810 // ======================================================== parseAssociation (q)
811 void Document::parseAssociation (XmlTree* node, Quad* quad)
812 {
813    SubShape* shape = parseSubShape (node);
814    if (shape==NULL || quad==NULL)
815        return;
816
817    if (shape->getDim()!=2)
818       return;
819    FaceShape* face = static_cast <FaceShape*> (shape);
820    quad->addAssociation (face);
821 }
822 // ======================================================== parseShapes
823 void Document::parseShapes (XmlTree& root)
824 {
825    XmlTree* rubrique = root.findChild ("ListShapes");
826    int nbrelts       = count_children (rubrique);
827
828    for (int nro=0 ; nro < nbrelts ; nro++)
829        {
830        XmlTree*      node = rubrique->getChild (nro);
831        const string& type = node->getName();
832        if (type=="Shape")
833           {
834           const string& nom   = node->findValue   ("id"  );
835           int           orig  = node->findInteger ("type");
836           const string& brep  = node->findValue   ("brep");
837           NewShape*     shape = new NewShape (this, (EnumShape)orig);
838
839           parse_name (node, nom, shape);
840           shape->setBrep (brep);
841           doc_tab_shape.push_back (shape);
842           }
843        else if (type=="Cloud")
844           {
845           int nbvert = count_children (node);
846           for (int nv=0 ; nv < nbvert ; nv++)
847               {
848               Real3    point;
849               XmlTree* sommet = node->getChild (nv);
850               const  string& coords = sommet->findValue ("coord");
851               get_coords (coords, point[dir_x], point[dir_y], point[dir_z]);
852               doc_cloud->addPoint (point);
853               }
854           }
855        }
856 }
857 END_NAMESPACE_HEXA