2 // C++ : Classe Document : methodes internes
4 // Copyright (C) 2009-2013 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"
50 #include "HexGlobale.hxx"
54 // ======================================================== get_coords
55 int get_coords (const string& chaine, double& x, double& y, double& z)
57 // int nv = sscanf (chaine.c_str (), "%lg %lg %lg", &x, &y, &z);
58 cpchar buffer = chaine.c_str ();
59 int nv = sscanf (buffer, "%lg %lg %lg", &x, &y, &z);
60 if (nv!=3) return HERR;
63 // ======================================================== get_coords
64 int get_coords (const string& chaine, double& x, double& y)
66 cpchar buffer = chaine.c_str ();
67 int nv = sscanf (buffer, "%lg %lg", &x, &y);
68 if (nv!=2) return HERR;
71 // ======================================================== parse_name
72 int parse_name (XmlTree* node, const string& nom, EltBase* elt)
76 for (int nc=1 ; nc<lg ; nc++)
77 nroid = 10*nroid + nom[nc] - '0';
81 const string& name = node->findValue ("name");
88 // ======================================================== get_names
89 void get_names (const string& chaine, int size, vector<string>& table)
92 int lg = chaine.size();
96 for (int nc=0 ; nc<lg ; nc++)
98 char car = chaine[nc];
106 table.push_back (mot);
113 table.push_back (mot);
115 // ======================================================== count_children
116 int count_children (XmlTree* dad)
118 int nbre = dad==NULL ? 0 : dad->getNbrChildren ();
121 // ======================================================== loadXml
122 int Document::loadXml (cpchar ficname)
125 string filename = ficname;
126 el_name = basename ((pchar)ficname);
128 static const int NbExt = 3;
129 static cpchar t_ext [NbExt] = { ".xml", ".XML", ".Xml" };
132 for (int nx = 0; nx < NbExt && noext ; nx++)
134 ici = el_name.rfind (t_ext[nx]);
135 noext = ici < 0 || ici > el_name.size();
141 el_name.erase (ici, 4);
143 int ier = xml.parseFile (filename);
147 ier = parseXml (xml);
150 // ======================================================== setXml
151 int Document::setXml (cpchar flux)
154 int ier = setXml (flux, posit);
157 // ======================================================== setXml
158 int Document::setXml (cpchar flux, int& posit)
162 int ier = xml.parseStream (flux, posit);
166 ier = parseXml (xml);
172 // ======================================================== parseXml
173 int Document::parseXml (XmlTree& xml)
177 map <std::string, Vertex*> t_vertex;
178 map <std::string, Edge*> t_edge;
179 map <std::string, Quad*> t_quad;
180 map <std::string, Hexa*> t_hexa;
181 map <std::string, Vector*> t_vector;
182 vector <string> tname;
184 const string& version = xml.findValue ("version");
187 cout << " **** Format du fichier XML perime"
191 const string& name = xml.findValue ("name");
193 setName (name.c_str());
197 XmlTree* rubrique = xml.findChild ("ListVertices");
198 int nbrelts = count_children (rubrique);
200 Vertex* vertex = NULL;
201 for (int nro=0 ; nro < nbrelts ; nro++)
203 XmlTree* node = rubrique->getChild (nro);
204 const string& type = node->getName();
208 const string& nom = node->findValue ("id");
209 const string& coords = node->findValue ("coord");
210 get_coords (coords, px, py, pz);
212 vertex = addVertex (px, py, pz);
213 parse_name (node, nom, vertex);
214 t_vertex [nom] = vertex;
216 else if (type=="Asso")
218 parseAssociation (node, vertex);
222 rubrique = xml.findChild ("ListEdges");
223 nbrelts = count_children (rubrique);
226 for (int nro=0 ; nro < nbrelts ; nro++)
228 XmlTree* node = rubrique->getChild (nro);
229 const string& type = node->getName();
232 const string& nom = node->findValue ("id");
233 const string& vertices = node->findValue ("vertices");
234 get_names (vertices, V_TWO, tname);
235 edge = new Edge (t_vertex [tname[0]], t_vertex [tname[1]]);
237 parse_name (node, nom, edge);
239 else if (type=="Asso")
241 parseAssociation (node, edge);
245 rubrique = xml.findChild ("ListQuads");
246 nbrelts = count_children (rubrique);
249 for (int nro=0 ; nro < nbrelts ; nro++)
251 XmlTree* node = rubrique->getChild (nro);
252 const string& type = node->getName();
255 const string& nom = node->findValue ("id");
256 const string& edges = node->findValue ("edges");
257 get_names (edges, V_TWO, tname);
259 quad = new Quad (t_edge [tname[0]], t_edge [tname[1]],
260 t_edge [tname[2]], t_edge [tname[3]]);
262 parse_name (node, nom, quad);
264 else if (type=="Asso")
266 parseAssociation (node, quad);
270 rubrique = xml.findChild ("ListHexas");
271 nbrelts = count_children (rubrique);
273 for (int nro=0 ; nro < nbrelts ; nro++)
275 XmlTree* node = rubrique->getChild (nro);
276 const string& nom = node->findValue ("id");
277 const string& quads = node->findValue ("quads");
278 get_names (quads, V_TWO, tname);
280 Hexa* hexa = new Hexa (t_quad [tname[0]], t_quad [tname[1]],
281 t_quad [tname[2]], t_quad [tname[3]],
282 t_quad [tname[4]], t_quad [tname[5]]);
284 parse_name (node, nom, hexa);
287 rubrique = xml.findChild ("ListVectors");
288 nbrelts = count_children (rubrique);
290 for (int nro=0 ; nro < nbrelts ; nro++)
292 XmlTree* node = rubrique->getChild (nro);
294 const string& nom = node->findValue ("id");
295 const string& coords = node->findValue ("coord");
296 get_coords (coords, px, py, pz);
298 Vector* vector = addVector (px, py, pz);
299 t_vector [nom] = vector;
300 parse_name (node, nom, vector);
303 rubrique = xml.findChild ("ListDicretizationLaws");
304 nbrelts = count_children (rubrique);
306 for (int nro=0 ; nro < nbrelts ; nro++)
308 XmlTree* node = rubrique->getChild (nro);
309 const string& id = node->findValue ("id");
310 const string& kind = node->findValue ("kind");
311 const string& nodes = node->findValue ("nodes");
312 const string& coeff = node->findValue ("coeff");
314 int nbnodes = atoi (nodes.c_str());
315 double koeff = atof (coeff.c_str());
316 if (id != "DefaultLaw")
318 Law* law = addLaw (id.c_str(), nbnodes);
319 law->setCoefficient (koeff);
320 law->setKind (kind.c_str());
324 rubrique = xml.findChild ("ListPropagations");
325 nbrelts = count_children (rubrique);
327 for (int nro=0 ; nro < nbrelts ; nro++)
329 XmlTree* node = rubrique->getChild (nro);
330 const string& nmedge = node->findValue ("edge");
331 const string& nmlaw = node->findValue ("law");
332 // const string& nmway = node->findValue ("way");
334 edge = t_edge [nmedge];
335 Law* law = findLaw (nmlaw.c_str());
336 // bool way = nmway == "true";
342 for (int pipe=0 ; pipe<2 ; pipe++)
344 rubrique = pipe ? xml.findChild ("ListPipes")
345 : xml.findChild ("ListCylinders");
347 nbrelts = count_children (rubrique);
349 for (int nro=0 ; nro < nbrelts ; nro++)
351 XmlTree* node = rubrique->getChild (nro);
352 const string& cbase = node->findValue ("c_base" );
353 const string& cdir = node->findValue ("c_dir" );
354 const string& cradius = node->findValue ("c_radius");
355 const string& cheight = node->findValue ("c_height");
357 Vertex* base = t_vertex [cbase];
358 Vector* dir = t_vector [cdir];
359 double radius = atof (cradius.c_str());
360 double height = atof (cheight.c_str());
364 const string& cradius1 = node->findValue ("c_int_radius");
365 double radius1 = atof (cradius1.c_str());
366 addPipe (base, dir, radius1, radius, height);
370 addCylinder (base, dir, radius, height);
375 rubrique = xml.findChild ("ListGroups");
376 int nbrgroups = count_children (rubrique);
378 for (int nro=0 ; nro < nbrgroups ; nro++)
380 XmlTree* ndgroup = rubrique->getChild (nro);
381 XmlTree* node = ndgroup ->getChild (0);
382 const string& nom = node->findValue ("name");
383 const string& ckind = node->findValue ("kind");
385 EnumGroup kind = Group::getKind (ckind);
386 Group* groupe = addGroup (nom.c_str(), kind);
387 EnumElt type = groupe->getTypeElt ();
389 nbrelts = count_children (ndgroup);
390 for (int nelt=1 ; nelt < nbrelts ; nelt++)
392 node = ndgroup ->getChild (nelt);
393 const string& id = node->findValue ("id");
396 case EL_HEXA : groupe->addElement (t_hexa [id]);
398 case EL_QUAD : groupe->addElement (t_quad [id]);
400 case EL_EDGE : groupe->addElement (t_edge [id]);
403 default : groupe->addElement (t_vertex [id]);
412 // ======================================================== save
413 int Document::save (const char* ficxml)
415 DumpStart ("save", ficxml);
418 doc_xml = new XmlWriter ();
420 int ier = doc_xml->setFileName (ficxml);
427 // ======================================================== appendXml
428 int Document::appendXml (pfile fstudy)
431 doc_xml = new XmlWriter ();
433 doc_xml->setFile (fstudy);
438 // ======================================================== getXml
439 cpchar Document::getXml ()
442 doc_xml = new XmlWriter ();
444 doc_xml->setStream ();
449 return doc_xml->getXml ();
451 // ======================================================== genXml
452 int Document::genXml ()
454 const int HexVersion = 1;
455 // -- 1) Raz numerotation precedente
456 markAll (NO_COUNTED);
461 doc_xml = new XmlWriter ();
463 doc_xml->startXml ();
464 doc_xml->openMark ("Document");
465 doc_xml->addAttribute ("name", el_name);
466 doc_xml->addAttribute ("version", HexVersion);
469 cpchar balise [] = {"ListXXXX",
470 "ListVertices", "ListEdges", "ListQuads", "ListHexas", "ListVectors",
473 for (int type=EL_VERTEX ; type <= EL_VECTOR ; type++)
475 doc_xml->addMark (balise [type]);
476 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
479 if (elt !=NULL && elt->isHere())
480 elt->saveXml (doc_xml);
482 doc_xml->closeMark (true);
485 doc_xml->addMark ("ListDicretizationLaws");
486 for (int nro=0 ; nro<nbr_laws ; nro++)
487 doc_laws [nro]->saveXml (doc_xml);
488 doc_xml->closeMark (true);
490 doc_xml->addMark ("ListPropagations");
491 for (int nro=0 ; nro<nbr_propagations ; nro++)
492 doc_propagation[nro]->saveXml (doc_xml);
493 doc_xml->closeMark (true);
495 int nombre = countCylinder();
496 doc_xml->addMark ("ListCylinders");
497 for (int nro=0 ; nro<nombre ; nro++)
498 doc_cylinder[nro]->saveXml (doc_xml);
499 doc_xml->closeMark (true);
501 nombre = countPipe();
502 doc_xml->addMark ("ListPipes");
503 for (int nro=0 ; nro<nombre ; nro++)
504 doc_pipe[nro]->saveXml (doc_xml);
505 doc_xml->closeMark (true);
507 nombre = countGroup();
508 doc_xml->addMark ("ListGroups");
509 for (int nro=0 ; nro<nombre ; nro++)
510 doc_group[nro]->saveXml (doc_xml);
511 doc_xml->closeMark (true);
513 nombre = countShape ();
514 doc_xml->addMark ("ListShapes");
515 for (int nro=0 ; nro<nombre ; nro++)
516 doc_tab_shape[nro]->saveXml (doc_xml);
517 doc_xml->closeMark ();
519 doc_xml->closeMark ();
520 doc_xml->closeXml ();
524 // ======================================================== markAll
525 void Document::markAll (int marque, int type)
527 int debut = EL_VERTEX;
529 if (type>=0 && type<EL_MAXI)
532 for (int type=debut ; type <= fin ; type++)
534 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
536 elt->setMark (marque);
539 // ====================================================== saveVtk
540 int Document::saveVtk0 (cpchar nomfic)
542 // -- 1) Raz numerotation precedente
543 markAll (NO_COUNTED, EL_VERTEX);
548 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
551 Hexa* cell = static_cast <Hexa*> (elt);
552 if (cell!=NULL && cell->isHere())
555 nbnodes += cell->countNodes ();
559 pfile vtk = fopen (nomfic, "w");
562 cout << " ****" << endl;
563 cout << " **** Document::saveVtk : " << endl;
564 cout << " **** Can't open file " << endl;
565 cout << " ****" << endl;
568 fprintf (vtk, "# vtk DataFile Version 3.1\n");
569 fprintf (vtk, "%s \n", nomfic);
570 fprintf (vtk, "ASCII\n");
571 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
572 fprintf (vtk, "POINTS %d float\n", nbnodes);
576 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
579 Hexa* cell = static_cast <Hexa*> (elt);
580 if (cell!=NULL && cell->isHere())
581 cell->printNodes (vtk, nronode);
585 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
587 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
590 Hexa* cell = static_cast <Hexa*> (elt);
591 if (cell!=NULL && cell->isHere())
592 cell->printHexa (vtk);
595 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
596 for (int nro=0 ; nro<nbcells ; nro++)
597 fprintf (vtk, "%d\n", HE_MAXI);
599 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
600 fprintf (vtk, "SCALARS A float\n");
601 fprintf (vtk, "LOOKUP_TABLE default\n");
603 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
606 Hexa* cell = static_cast <Hexa*> (elt);
607 if (cell!=NULL && cell->isHere())
608 cell->colorNodes (vtk);
615 // ====================================================== saveVtk
616 // ==== Nouvelle formule qui conserve les numeros de vertex
617 int Document::saveVtk (cpchar nomfic)
619 DumpStart ("saveVtk", nomfic);
620 int nbnodes = doc_nbr_elt [EL_VERTEX];
621 int nbcells = countHexa ();
623 pfile vtk = fopen (nomfic, "w");
626 cout << " ****" << endl;
627 cout << " **** Document::saveVtk : " << endl;
628 cout << " **** Can't open file " << endl;
629 cout << " ****" << endl;
632 fprintf (vtk, "# vtk DataFile Version 3.1\n");
633 fprintf (vtk, "%s \n", nomfic);
634 fprintf (vtk, "ASCII\n");
635 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
636 fprintf (vtk, "POINTS %d float\n", nbnodes);
640 static const double minvtk = 1e-30;
641 #define Koord(p) koord[p]<minvtk && koord[p]>-minvtk ? 0 : koord[p]
643 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
646 Vertex* node = static_cast <Vertex*> (elt);
649 node->getPoint (koord);
650 fprintf (vtk, "%g %g %g\n", Koord(dir_x), Koord(dir_y), Koord(dir_z));
653 fprintf (vtk, "0 0 0\n");
657 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
659 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
662 Hexa* cell = static_cast <Hexa*> (elt);
663 if (cell!=NULL && cell->isHere())
664 cell->printHexaVtk (vtk);
667 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
668 for (int nro=0 ; nro<nbcells ; nro++)
669 fprintf (vtk, "%d\n", HE_MAXI);
671 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
672 fprintf (vtk, "SCALARS A float\n");
673 fprintf (vtk, "LOOKUP_TABLE default\n");
674 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
677 Vertex* node = static_cast <Vertex*> (elt);
680 double color = 100*(node->getScalar()+1);
681 fprintf (vtk, "%g\n", color);
684 fprintf (vtk, "100\n");
691 // ====================================================== purge
692 void Document::purge ()
694 purge_elements = false;
695 // ------------------- Raz marques
698 // ------------------- Marquage elements utilises
699 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
702 Hexa* cell = static_cast <Hexa*> (elt);
703 if (cell!=NULL && cell->isHere())
704 cell->markElements (IS_USED);
706 // ------------------- Elimination elements inutilises
707 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
709 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
712 if (elt->getMark () == NO_USED)
716 // ------------------- Sortie elements inutilises
718 /* ****************************************************************
719 EltBase* trash = doc_last_elt [EL_REMOVED];
721 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
723 doc_nbr_elt [type] = 0;
724 EltBase* last = doc_first_elt [type];
725 for (EltBase* elt = last->next (); elt!=NULL; elt = last->next())
729 doc_nbr_elt [type] ++;
734 last -> setNext (elt -> next());
735 trash -> setNext (elt);
737 trash -> setNext (NULL);
740 doc_last_elt [type] = last;
743 doc_last_elt [EL_REMOVED] = trash;
744 **************************************************************** */
747 // ======================================================== majReferences
748 void Document::majReferences ()
750 maj_connection = false;
752 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
754 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
757 elt->razReferences ();
761 for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
763 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
767 elt->majReferences ();
771 // ======================================================== dump
772 void Document::dump ()
774 cpchar nom_type [] = { "Elments non classes",
775 "Sommets", "Aretes", "Faces", "Hexaedres", "Elements detruits" };
777 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
780 printf (" ++++ Liste des %s\n", nom_type[type]);
783 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
791 printf (" ++++ End od dump\n");
793 // ======================================================== putError
794 void Document::putError (cpchar mess, cpchar info1, cpchar info2)
797 printf (" ********************************************************** \n");
798 printf (" **** HexaBlocks Error nro %d :\n", nbr_errors);
800 printf (mess, info1, info2);
803 printf (" ********************************************************** \n");
805 // ======================================================== hputError
806 void Document::hputError (cpchar mess, EltBase* e1, EltBase* e2)
808 char name1 [32] = { 0 };
809 char name2 [32] = { 0 };
811 if (e1!=NULL) e1->getName (name1);
812 if (e2!=NULL) e2->getName (name2);
814 putError (mess, name1, name2);
816 // ======================================================== parseSubShape
817 SubShape* Document::parseSubShape (XmlTree* node)
819 const string& name = node->findValue ("shape");
820 int subid = node->findInteger ("subid");
821 NewShape* shape = findShape (name);
825 SubShape* sub_shape = shape->findSubShape (subid);
828 // ======================================================== parseAssociation (v)
829 void Document::parseAssociation (XmlTree* node, Vertex* vertex)
831 SubShape* shape = parseSubShape (node);
832 if (shape==NULL || vertex==NULL)
835 if (shape->getDim()!=0)
837 VertexShape* vshape = static_cast <VertexShape*> (shape);
838 vertex->setAssociation (vshape);
840 // ======================================================== parseAssociation (e)
841 void Document::parseAssociation (XmlTree* node, Edge* edge)
843 SubShape* shape = parseSubShape (node);
844 if (shape==NULL || edge==NULL)
847 if (shape->getDim()!=1)
850 const string& inter = node->findValue ("interval");
852 get_coords (inter, pdeb, pfin);
854 EdgeShape* line = static_cast <EdgeShape*> (shape);
855 edge->addAssociation (line, pdeb, pfin);
857 // ======================================================== parseAssociation (q)
858 void Document::parseAssociation (XmlTree* node, Quad* quad)
860 SubShape* shape = parseSubShape (node);
861 if (shape==NULL || quad==NULL)
864 if (shape->getDim()!=2)
866 FaceShape* face = static_cast <FaceShape*> (shape);
867 quad->addAssociation (face);
869 // ======================================================== parseShapes
870 void Document::parseShapes (XmlTree& root)
872 XmlTree* rubrique = root.findChild ("ListShapes");
873 int nbrelts = count_children (rubrique);
875 for (int nro=0 ; nro < nbrelts ; nro++)
877 XmlTree* node = rubrique->getChild (nro);
878 const string& type = node->getName();
881 const string& nom = node->findValue ("id" );
882 int orig = node->findInteger ("type");
883 const string& brep = node->findValue ("brep");
884 NewShape* shape = new NewShape (this, (EnumShape)orig);
886 parse_name (node, nom, shape);
887 shape->setBrep (brep);
888 doc_tab_shape.push_back (shape);
890 else if (type=="Cloud")
892 int nbvert = count_children (node);
893 for (int nv=0 ; nv < nbvert ; nv++)
896 XmlTree* sommet = node->getChild (nv);
897 const string& coords = sommet->findValue ("coord");
898 get_coords (coords, point[dir_x], point[dir_y], point[dir_z]);
899 doc_cloud->addPoint (point);