2 // C++ : Classe Document : methodes internes
4 // Copyright (C) 2009-2012 CEA/DEN, EDF R&D
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include "HexDocument.hxx"
23 #include <libgen.h> // Pour basename
24 #include <cstdlib> // Pour atoi et atof
27 #include "HexVertex.hxx"
28 #include "HexEdge.hxx"
29 #include "HexQuad.hxx"
30 #include "HexHexa.hxx"
32 #include "HexElements.hxx"
34 #include "HexVector.hxx"
35 #include "HexCylinder.hxx"
36 #include "HexPipe.hxx"
37 #include "HexMatrix.hxx"
38 #include "HexCloner.hxx"
39 #include "HexPropagation.hxx"
41 #include "HexGroup.hxx"
43 #include "HexNewShape.hxx"
44 #include "HexVertexShape.hxx"
45 #include "HexEdgeShape.hxx"
46 #include "HexFaceShape.hxx"
48 #include "HexXmlWriter.hxx"
49 #include "HexXmlTree.hxx"
53 // ======================================================== get_coords
54 int get_coords (const string& chaine, double& x, double& y, double& z)
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;
62 // ======================================================== get_coords
63 int get_coords (const string& chaine, double& x, double& y)
65 cpchar buffer = chaine.c_str ();
66 int nv = sscanf (buffer, "%lg %lg", &x, &y);
67 if (nv!=2) return HERR;
70 // ======================================================== parseName
71 int parseName (XmlTree* node, const string& nom, EltBase* elt)
75 for (int nc=1 ; nc<lg ; nc++)
76 nroid = 10*nroid + nom[nc] - '0';
80 const string& name = node->findValue ("name");
87 // ======================================================== get_names
88 void get_names (const string& chaine, int size, vector<string>& table)
91 int lg = chaine.size();
95 for (int nc=0 ; nc<lg ; nc++)
97 char car = chaine[nc];
105 table.push_back (mot);
112 table.push_back (mot);
114 // ======================================================== loadXml
115 int Document::loadXml (cpchar ficname)
118 string filename = ficname;
119 el_name = basename ((pchar)ficname);
121 static const int NbExt = 3;
122 static cpchar t_ext [NbExt] = { ".xml", ".XML", ".Xml" };
125 for (int nx = 0; nx < NbExt && noext ; nx++)
127 ici = el_name.rfind (t_ext[nx]);
128 noext = ici < 0 || ici > el_name.size();
134 el_name.erase (ici, 4);
136 int ier = xml.parseFile (filename);
140 ier = parseXml (xml);
143 // ======================================================== setXml
144 int Document::setXml (cpchar flux)
147 int ier = setXml (flux, posit);
150 // ======================================================== setXml
151 int Document::setXml (cpchar flux, int& posit)
155 int ier = xml.parseStream (flux, posit);
159 ier = parseXml (xml);
165 // ======================================================== parseXml
166 int Document::parseXml (XmlTree& xml)
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;
177 const string& version = xml.findValue ("version");
180 cout << " **** Format du fichier XML perime"
184 const string& name = xml.findValue ("name");
186 setName (name.c_str());
190 XmlTree* rubrique = xml.findChild ("ListVertices");
191 int nbrelts = rubrique->getNbrChildren ();
193 Vertex* vertex = NULL;
194 for (int nro=0 ; nro < nbrelts ; nro++)
196 XmlTree* node = rubrique->getChild (nro);
197 const string& type = node->getName();
201 const string& nom = node->findValue ("id");
202 const string& coords = node->findValue ("coord");
203 get_coords (coords, px, py, pz);
205 vertex = addVertex (px, py, pz);
206 parseName (node, nom, vertex);
207 t_vertex [nom] = vertex;
209 else if (type=="Asso")
211 parseAssociation (node, vertex);
215 rubrique = xml.findChild ("ListEdges");
216 nbrelts = rubrique->getNbrChildren ();
219 for (int nro=0 ; nro < nbrelts ; nro++)
221 XmlTree* node = rubrique->getChild (nro);
222 const string& type = node->getName();
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]]);
230 parseName (node, nom, edge);
232 else if (type=="Asso")
234 parseAssociation (node, edge);
238 rubrique = xml.findChild ("ListQuads");
239 nbrelts = rubrique->getNbrChildren ();
242 for (int nro=0 ; nro < nbrelts ; nro++)
244 XmlTree* node = rubrique->getChild (nro);
245 const string& type = node->getName();
248 const string& nom = node->findValue ("id");
249 const string& edges = node->findValue ("edges");
250 get_names (edges, V_TWO, tname);
252 quad = new Quad (t_edge [tname[0]], t_edge [tname[1]],
253 t_edge [tname[2]], t_edge [tname[3]]);
255 parseName (node, nom, quad);
257 else if (type=="Asso")
259 parseAssociation (node, quad);
263 rubrique = xml.findChild ("ListHexas");
264 nbrelts = rubrique->getNbrChildren ();
266 for (int nro=0 ; nro < nbrelts ; nro++)
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);
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]]);
277 parseName (node, nom, hexa);
280 rubrique = xml.findChild ("ListVectors");
281 nbrelts = rubrique == NULL ? 0 : rubrique->getNbrChildren ();
283 for (int nro=0 ; nro < nbrelts ; nro++)
285 XmlTree* node = rubrique->getChild (nro);
287 const string& nom = node->findValue ("id");
288 const string& coords = node->findValue ("coord");
289 get_coords (coords, px, py, pz);
291 Vector* vector = addVector (px, py, pz);
292 t_vector [nom] = vector;
293 parseName (node, nom, vector);
296 rubrique = xml.findChild ("ListDicretizationLaws");
297 nbrelts = rubrique == NULL ? 0 : rubrique->getNbrChildren ();
299 for (int nro=0 ; nro < nbrelts ; nro++)
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");
307 int nbnodes = atoi (nodes.c_str());
308 double koeff = atof (coeff.c_str());
309 if (id != "DefaultLaw")
311 Law* law = addLaw (id.c_str(), nbnodes);
312 law->setCoefficient (koeff);
313 law->setKind (kind.c_str());
317 rubrique = xml.findChild ("ListPropagations");
318 nbrelts = rubrique == NULL ? 0 : rubrique->getNbrChildren ();
320 for (int nro=0 ; nro < nbrelts ; nro++)
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");
327 edge = t_edge [nmedge];
328 Law* law = findLaw (nmlaw.c_str());
329 // bool way = nmway == "true";
335 for (int pipe=0 ; pipe<2 ; pipe++)
337 rubrique = pipe ? xml.findChild ("ListPipes")
338 : xml.findChild ("ListCylinders");
340 nbrelts = rubrique == NULL ? 0 : rubrique->getNbrChildren ();
342 for (int nro=0 ; nro < nbrelts ; nro++)
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");
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());
357 const string& cradius1 = node->findValue ("c_int_radius");
358 double radius1 = atof (cradius1.c_str());
359 addPipe (base, dir, radius1, radius, height);
363 addCylinder (base, dir, radius, height);
368 rubrique = xml.findChild ("ListGroups");
369 int nbrgroups = rubrique == NULL ? 0 : rubrique->getNbrChildren ();
371 for (int nro=0 ; nro < nbrgroups ; nro++)
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");
378 EnumGroup kind = Group::getKind (ckind);
379 Group* groupe = addGroup (nom.c_str(), kind);
380 EnumElt type = groupe->getTypeElt ();
382 nbrelts = ndgroup->getNbrChildren ();
383 for (int nelt=1 ; nelt < nbrelts ; nelt++)
385 node = ndgroup ->getChild (nelt);
386 const string& id = node->findValue ("id");
389 case EL_HEXA : groupe->addElement (t_hexa [id]);
391 case EL_QUAD : groupe->addElement (t_quad [id]);
393 case EL_EDGE : groupe->addElement (t_edge [id]);
396 default : groupe->addElement (t_vertex [id]);
405 // ======================================================== save
406 int Document::save (const char* ficxml)
409 doc_xml = new XmlWriter ();
411 int ier = doc_xml->setFileName (ficxml);
418 // ======================================================== appendXml
419 int Document::appendXml (pfile fstudy)
422 doc_xml = new XmlWriter ();
424 doc_xml->setFile (fstudy);
429 // ======================================================== getXml
430 cpchar Document::getXml ()
433 doc_xml = new XmlWriter ();
435 doc_xml->setStream ();
440 return doc_xml->getXml ();
442 // ======================================================== genXml
443 int Document::genXml ()
445 const int HexVersion = 1;
446 // -- 1) Raz numerotation precedente
447 markAll (NO_COUNTED);
452 doc_xml = new XmlWriter ();
454 doc_xml->startXml ();
455 doc_xml->openMark ("Document");
456 doc_xml->addAttribute ("name", el_name);
457 doc_xml->addAttribute ("version", HexVersion);
460 cpchar balise [] = {"ListXXXX",
461 "ListVertices", "ListEdges", "ListQuads", "ListHexas", "ListVectors",
464 for (int type=EL_VERTEX ; type <= EL_VECTOR ; type++)
466 doc_xml->addMark (balise [type]);
467 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
470 if (elt !=NULL && elt->isHere())
471 elt->saveXml (doc_xml);
473 doc_xml->closeMark (true);
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);
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);
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);
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);
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);
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 ();
510 doc_xml->closeMark ();
511 doc_xml->closeXml ();
515 // ======================================================== markAll
516 void Document::markAll (int marque, int type)
518 int debut = EL_VERTEX;
520 if (type>=0 && type<EL_MAXI)
523 for (int type=debut ; type <= fin ; type++)
525 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
527 elt->setMark (marque);
530 // ====================================================== saveVtk
531 int Document::saveVtk0 (cpchar nomfic)
533 // -- 1) Raz numerotation precedente
534 markAll (NO_COUNTED, EL_VERTEX);
539 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
542 Hexa* cell = static_cast <Hexa*> (elt);
543 if (cell!=NULL && cell->isHere())
546 nbnodes += cell->countNodes ();
550 pfile vtk = fopen (nomfic, "w");
553 cout << " ****" << endl;
554 cout << " **** Document::saveVtk : " << endl;
555 cout << " **** Can't open file " << endl;
556 cout << " ****" << endl;
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);
567 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
570 Hexa* cell = static_cast <Hexa*> (elt);
571 if (cell!=NULL && cell->isHere())
572 cell->printNodes (vtk, nronode);
576 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
578 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
581 Hexa* cell = static_cast <Hexa*> (elt);
582 if (cell!=NULL && cell->isHere())
583 cell->printHexa (vtk);
586 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
587 for (int nro=0 ; nro<nbcells ; nro++)
588 fprintf (vtk, "%d\n", HE_MAXI);
590 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
591 fprintf (vtk, "SCALARS A float\n");
592 fprintf (vtk, "LOOKUP_TABLE default\n");
594 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
597 Hexa* cell = static_cast <Hexa*> (elt);
598 if (cell!=NULL && cell->isHere())
599 cell->colorNodes (vtk);
606 // ====================================================== saveVtk
607 // ==== Nouvelle formule
608 int Document::saveVtk (cpchar nomfic)
610 int nbnodes = doc_nbr_elt [EL_VERTEX];
611 int nbcells = countHexa ();
613 pfile vtk = fopen (nomfic, "w");
616 cout << " ****" << endl;
617 cout << " **** Document::saveVtk : " << endl;
618 cout << " **** Can't open file " << endl;
619 cout << " ****" << endl;
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);
630 static const double minvtk = 1e-30;
631 #define Koord(p) koord[p]<minvtk && koord[p]>-minvtk ? 0 : koord[p]
634 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
637 Vertex* node = static_cast <Vertex*> (elt);
640 int nro = node->getId ();
641 for (int np = last_nro ; np < nro ; np++)
642 fprintf (vtk, "0 0 0\n");
644 node->getPoint (koord);
645 fprintf (vtk, "%g %g %g\n", Koord(dir_x), Koord(dir_y), Koord(dir_z));
650 for (int np = last_nro ; np < nbnodes ; np++)
651 fprintf (vtk, "0 0 0\n");
655 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
657 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
660 Hexa* cell = static_cast <Hexa*> (elt);
661 if (cell!=NULL && cell->isHere())
662 cell->printHexaVtk (vtk);
665 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
666 for (int nro=0 ; nro<nbcells ; nro++)
667 fprintf (vtk, "%d\n", HE_MAXI);
669 /****************************
670 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
671 fprintf (vtk, "SCALARS A float\n");
672 fprintf (vtk, "LOOKUP_TABLE default\n");
674 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
677 Hexa* cell = static_cast <Hexa*> (elt);
678 if (cell!=NULL && cell->isHere())
679 cell->colorNodes (vtk);
681 *********************************/
685 // ====================================================== purge
686 void Document::purge ()
688 purge_elements = false;
689 // ------------------- Raz marques
692 // ------------------- Marquage elements utilises
693 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
696 Hexa* cell = static_cast <Hexa*> (elt);
697 if (cell!=NULL && cell->isHere())
698 cell->markElements (IS_USED);
700 // ------------------- Elimination elements inutilises
701 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
703 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
706 if (elt->getMark () == NO_USED)
710 // ------------------- Sortie elements inutilises
712 /* ****************************************************************
713 EltBase* trash = doc_last_elt [EL_REMOVED];
715 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
717 doc_nbr_elt [type] = 0;
718 EltBase* last = doc_first_elt [type];
719 for (EltBase* elt = last->next (); elt!=NULL; elt = last->next())
723 doc_nbr_elt [type] ++;
728 last -> setNext (elt -> next());
729 trash -> setNext (elt);
731 trash -> setNext (NULL);
734 doc_last_elt [type] = last;
737 doc_last_elt [EL_REMOVED] = trash;
738 **************************************************************** */
741 // ======================================================== majReferences
742 void Document::majReferences ()
744 maj_connection = false;
746 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
748 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
751 elt->razReferences ();
755 for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
757 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
761 elt->majReferences ();
765 // ======================================================== dump
766 void Document::dump ()
768 cpchar nom_type [] = { "Elments non classes",
769 "Sommets", "Aretes", "Faces", "Hexaedres", "Elements detruits" };
771 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
774 printf (" ++++ Liste des %s\n", nom_type[type]);
777 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
785 printf (" ++++ End od dump\n");
787 // ======================================================== putError
788 void Document::putError (cpchar mess, cpchar info1, cpchar info2)
791 printf (" ********************************************************** \n");
792 printf (" **** HexaBlocks Error nro %d :\n", nbr_errors);
794 printf (mess, info1, info2);
797 printf (" ********************************************************** \n");
799 // ======================================================== hputError
800 void Document::hputError (cpchar mess, EltBase* e1, EltBase* e2)
802 char name1 [32] = { 0 };
803 char name2 [32] = { 0 };
805 if (e1!=NULL) e1->getName (name1);
806 if (e2!=NULL) e2->getName (name2);
808 putError (mess, name1, name2);
810 // ======================================================== parseSubShape
811 SubShape* Document::parseSubShape (XmlTree* node)
813 const string& name = node->findValue ("shape");
814 int subid = node->findInteger ("subid");
815 NewShape* shape = findShape (name);
819 SubShape* sub_shape = shape->findSubShape (subid);
822 // ======================================================== parseAssociation (v)
823 void Document::parseAssociation (XmlTree* node, Vertex* vertex)
825 SubShape* shape = parseSubShape (node);
826 if (shape==NULL || vertex==NULL)
829 if (shape->getDim()!=0)
831 VertexShape* vshape = static_cast <VertexShape*> (shape);
832 vertex->setAssociation (vshape);
834 // ======================================================== parseAssociation (e)
835 void Document::parseAssociation (XmlTree* node, Edge* edge)
837 SubShape* shape = parseSubShape (node);
838 if (shape==NULL || edge==NULL)
841 if (shape->getDim()!=1)
844 const string& inter = node->findValue ("interval");
846 get_coords (inter, pdeb, pfin);
848 EdgeShape* line = static_cast <EdgeShape*> (shape);
849 edge->addAssociation (line, pdeb, pfin);
851 // ======================================================== parseAssociation (q)
852 void Document::parseAssociation (XmlTree* node, Quad* quad)
854 SubShape* shape = parseSubShape (node);
855 if (shape==NULL || quad==NULL)
858 if (shape->getDim()!=2)
860 FaceShape* face = static_cast <FaceShape*> (shape);
861 quad->addAssociation (face);
863 // ======================================================== parseShapes
864 void Document::parseShapes (XmlTree& root)
866 XmlTree* rubrique = root.findChild ("ListShapes");
867 int nbrelts = rubrique==NULL ? 0 : rubrique->getNbrChildren ();
869 for (int nro=0 ; nro < nbrelts ; nro++)
871 XmlTree* node = rubrique->getChild (nro);
872 const string& type = node->getName();
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);
880 parseName (node, nom, shape);
881 shape->setBrep (brep);
882 doc_tab_shape.push_back (shape);
884 else if (type=="Cloud")
886 int nbvert = node->getNbrChildren ();
887 for (int nv=0 ; nv < nbvert ; nv++)
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);