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