2 // C++ : Classe Document : methodes internes
4 // Copyright (C) 2009-2016 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, or (at your option) any later version.
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 <Basics_DirUtils.hxx>
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 "HexMatrix.hxx"
36 #include "HexCloner.hxx"
37 #include "HexPropagation.hxx"
39 #include "HexGroup.hxx"
41 #include "HexNewShape.hxx"
42 #include "HexVertexShape.hxx"
43 #include "HexEdgeShape.hxx"
44 #include "HexFaceShape.hxx"
46 #include "HexXmlWriter.hxx"
47 #include "HexXmlTree.hxx"
48 #include "HexGlobale.hxx"
52 // ======================================================== get_coords
53 int get_coords (const string& chaine, double& x, double& y, double& z)
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;
61 // ======================================================== get_coords
62 int get_coords (const string& chaine, double& x, double& y)
64 cpchar buffer = chaine.c_str ();
65 int nv = sscanf (buffer, "%lg %lg", &x, &y);
66 if (nv!=2) return HERR;
69 // ======================================================== parse_name
70 int parse_name (XmlTree* node, const string& nom, EltBase* elt)
74 for (int nc=1 ; nc<lg ; nc++)
75 nroid = 10*nroid + nom[nc] - '0';
79 const string& name = node->findValue ("name");
86 // ======================================================== get_names
87 void get_names (const string& chaine, int size, vector<string>& table)
90 int lg = chaine.size();
94 for (int nc=0 ; nc<lg ; nc++)
96 char car = chaine[nc];
104 table.push_back (mot);
111 table.push_back (mot);
113 // ======================================================== count_children
114 int count_children (XmlTree* dad)
116 int nbre = dad==NULL ? 0 : dad->getNbrChildren ();
119 // ======================================================== loadXml
120 int Document::loadXml (cpchar ficname)
123 string filename = ficname;
124 //el_name = Kernel_Utils::GetBaseName ((pchar)ficname);
125 make_basename (ficname, el_name);
127 static const int NbExt = 3;
128 static cpchar t_ext [NbExt] = { ".xml", ".XML", ".Xml" };
131 for (int nx = 0; nx < NbExt && noext ; nx++)
133 ici = el_name.rfind (t_ext[nx]);
134 noext = ici < 0 || ici > el_name.size();
140 el_name.erase (ici, 4);
142 int ier = xml.parseFile (filename);
146 ier = parseXml (xml);
149 // ======================================================== setXml
150 int Document::setXml (cpchar flux)
153 int ier = setXml (flux, posit);
156 // ======================================================== setXml
157 int Document::setXml (cpchar flux, int& posit)
161 int ier = xml.parseStream (flux, posit);
165 ier = parseXml (xml);
171 // ======================================================== parseXml
172 int Document::parseXml (XmlTree& xml)
176 map <std::string, Vertex*> t_vertex;
177 map <std::string, Edge*> t_edge;
178 map <std::string, Quad*> t_quad;
179 map <std::string, Hexa*> t_hexa;
180 map <std::string, Vector*> t_vector;
181 vector <string> tname;
183 const string& version = xml.findValue ("version");
186 cout << " **** Format du fichier XML perime"
190 const string& name = xml.findValue ("name");
192 setName (name.c_str());
196 XmlTree* rubrique = xml.findChild ("ListVertices");
197 int nbrelts = count_children (rubrique);
199 Vertex* vertex = NULL;
200 for (int nro=0 ; nro < nbrelts ; nro++)
202 XmlTree* node = rubrique->getChild (nro);
203 const string& type = node->getName();
207 const string& nom = node->findValue ("id");
208 const string& coords = node->findValue ("coord");
209 get_coords (coords, px, py, pz);
211 vertex = addVertex (px, py, pz);
212 parse_name (node, nom, vertex);
213 t_vertex [nom] = vertex;
215 else if (type=="Asso")
217 parseAssociation (node, vertex);
221 rubrique = xml.findChild ("ListEdges");
222 nbrelts = count_children (rubrique);
225 for (int nro=0 ; nro < nbrelts ; nro++)
227 XmlTree* node = rubrique->getChild (nro);
228 const string& type = node->getName();
231 const string& nom = node->findValue ("id");
232 const string& vertices = node->findValue ("vertices");
233 get_names (vertices, V_TWO, tname);
234 edge = new Edge (t_vertex [tname[0]], t_vertex [tname[1]]);
236 parse_name (node, nom, edge);
238 else if (type=="Asso")
240 parseAssociation (node, edge);
244 rubrique = xml.findChild ("ListQuads");
245 nbrelts = count_children (rubrique);
248 for (int nro=0 ; nro < nbrelts ; nro++)
250 XmlTree* node = rubrique->getChild (nro);
251 const string& type = node->getName();
254 const string& nom = node->findValue ("id");
255 const string& edges = node->findValue ("edges");
256 get_names (edges, V_TWO, tname);
258 quad = new Quad (t_edge [tname[0]], t_edge [tname[1]],
259 t_edge [tname[2]], t_edge [tname[3]]);
261 parse_name (node, nom, quad);
263 else if (type=="Asso")
265 parseAssociation (node, quad);
269 rubrique = xml.findChild ("ListHexas");
270 nbrelts = count_children (rubrique);
272 for (int nro=0 ; nro < nbrelts ; nro++)
274 XmlTree* node = rubrique->getChild (nro);
275 const string& nom = node->findValue ("id");
276 const string& quads = node->findValue ("quads");
277 get_names (quads, V_TWO, tname);
279 Hexa* hexa = new Hexa (t_quad [tname[0]], t_quad [tname[1]],
280 t_quad [tname[2]], t_quad [tname[3]],
281 t_quad [tname[4]], t_quad [tname[5]]);
283 parse_name (node, nom, hexa);
286 rubrique = xml.findChild ("ListVectors");
287 nbrelts = count_children (rubrique);
289 for (int nro=0 ; nro < nbrelts ; nro++)
291 XmlTree* node = rubrique->getChild (nro);
293 const string& nom = node->findValue ("id");
294 const string& coords = node->findValue ("coord");
295 get_coords (coords, px, py, pz);
297 Vector* vector = addVector (px, py, pz);
298 t_vector [nom] = vector;
299 parse_name (node, nom, vector);
302 rubrique = xml.findChild ("ListDicretizationLaws");
303 nbrelts = count_children (rubrique);
305 for (int nro=0 ; nro < nbrelts ; nro++)
307 XmlTree* node = rubrique->getChild (nro);
308 const string& id = node->findValue ("id");
309 const string& kind = node->findValue ("kind");
310 const string& nodes = node->findValue ("nodes");
311 const string& coeff = node->findValue ("coeff");
313 int nbnodes = atoi (nodes.c_str());
314 double koeff = atof (coeff.c_str());
315 if (id != "DefaultLaw")
317 Law* law = addLaw (id.c_str(), nbnodes);
318 law->setCoefficient (koeff);
319 law->setKind (kind.c_str());
323 rubrique = xml.findChild ("ListPropagations");
324 nbrelts = count_children (rubrique);
326 for (int nro=0 ; nro < nbrelts ; nro++)
328 XmlTree* node = rubrique->getChild (nro);
329 const string& nmedge = node->findValue ("edge");
330 const string& nmlaw = node->findValue ("law");
331 // const string& nmway = node->findValue ("way");
333 edge = t_edge [nmedge];
334 Law* law = findLaw (nmlaw.c_str());
335 // bool way = nmway == "true";
341 rubrique = xml.findChild ("ListGroups");
342 int nbrgroups = count_children (rubrique);
344 for (int nro=0 ; nro < nbrgroups ; nro++)
346 XmlTree* ndgroup = rubrique->getChild (nro);
347 XmlTree* node = ndgroup ->getChild (0);
348 const string& nom = node->findValue ("name");
349 const string& ckind = node->findValue ("kind");
351 EnumGroup kind = Group::getKind (ckind);
352 Group* groupe = addGroup (nom.c_str(), kind);
353 EnumElt type = groupe->getTypeElt ();
355 nbrelts = count_children (ndgroup);
356 for (int nelt=1 ; nelt < nbrelts ; nelt++)
358 node = ndgroup ->getChild (nelt);
359 const string& id = node->findValue ("id");
362 case EL_HEXA : groupe->addElement (t_hexa [id]);
364 case EL_QUAD : groupe->addElement (t_quad [id]);
366 case EL_EDGE : groupe->addElement (t_edge [id]);
369 default : groupe->addElement (t_vertex [id]);
378 // ======================================================== save
379 int Document::save (const char* ficxml)
381 DumpStart ("save", ficxml);
384 doc_xml = new XmlWriter ();
386 int ier = doc_xml->setFileName (ficxml);
393 // ======================================================== appendXml
394 int Document::appendXml (pfile fstudy)
397 doc_xml = new XmlWriter ();
399 doc_xml->setFile (fstudy);
404 // ======================================================== getXml
405 cpchar Document::getXml ()
408 doc_xml = new XmlWriter ();
410 doc_xml->setStream ();
415 return doc_xml->getXml ();
417 // ======================================================== genXml
418 int Document::genXml ()
420 const int HexVersion = 1;
421 // -- 1) Raz numerotation precedente
422 markAll (NO_COUNTED);
427 doc_xml = new XmlWriter ();
429 doc_xml->startXml ();
430 doc_xml->openMark ("Document");
431 doc_xml->addAttribute ("name", el_name);
432 doc_xml->addAttribute ("version", HexVersion);
435 cpchar balise [] = {"ListXXXX",
436 "ListVertices", "ListEdges", "ListQuads", "ListHexas", "ListVectors",
439 for (int type=EL_VERTEX ; type <= EL_VECTOR ; type++)
441 doc_xml->addMark (balise [type]);
442 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
445 if (elt !=NULL && elt->isHere())
446 elt->saveXml (doc_xml);
448 doc_xml->closeMark (true);
451 doc_xml->addMark ("ListDicretizationLaws");
452 for (int nro=0 ; nro<nbr_laws ; nro++)
453 doc_laws [nro]->saveXml (doc_xml);
454 doc_xml->closeMark (true);
456 doc_xml->addMark ("ListPropagations");
457 for (int nro=0 ; nro<nbr_propagations ; nro++)
458 doc_propagation[nro]->saveXml (doc_xml);
459 doc_xml->closeMark (true);
461 int nombre = countGroup();
462 doc_xml->addMark ("ListGroups");
463 for (int nro=0 ; nro<nombre ; nro++)
464 doc_group[nro]->saveXml (doc_xml);
465 doc_xml->closeMark (true);
467 nombre = countShape ();
468 doc_xml->addMark ("ListShapes");
469 for (int nro=0 ; nro<nombre ; nro++)
470 doc_tab_shape[nro]->saveXml (doc_xml);
471 doc_xml->closeMark ();
473 doc_xml->closeMark ();
474 doc_xml->closeXml ();
478 // ======================================================== markAll
479 void Document::markAll (int marque, int type)
481 int debut = EL_VERTEX;
483 if (type>=0 && type<EL_MAXI)
486 for (int type=debut ; type <= fin ; type++)
488 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
490 elt->setMark (marque);
493 // ====================================================== saveVtk
494 int Document::saveVtk0 (cpchar nomfic)
496 // -- 1) Raz numerotation precedente
497 markAll (NO_COUNTED, EL_VERTEX);
502 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
505 Hexa* cell = static_cast <Hexa*> (elt);
506 if (cell!=NULL && cell->isHere())
509 nbnodes += cell->countNodes ();
513 pfile vtk = fopen (nomfic, "w");
516 cout << " ****" << endl;
517 cout << " **** Document::saveVtk : " << endl;
518 cout << " **** Can't open file " << endl;
519 cout << " ****" << endl;
522 fprintf (vtk, "# vtk DataFile Version 3.1\n");
523 fprintf (vtk, "%s \n", nomfic);
524 fprintf (vtk, "ASCII\n");
525 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
526 fprintf (vtk, "POINTS %d float\n", nbnodes);
530 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
533 Hexa* cell = static_cast <Hexa*> (elt);
534 if (cell!=NULL && cell->isHere())
535 cell->printNodes (vtk, nronode);
539 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
541 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
544 Hexa* cell = static_cast <Hexa*> (elt);
545 if (cell!=NULL && cell->isHere())
546 cell->printHexa (vtk);
549 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
550 for (int nro=0 ; nro<nbcells ; nro++)
551 fprintf (vtk, "%d\n", HE_MAXI);
553 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
554 fprintf (vtk, "SCALARS A float\n");
555 fprintf (vtk, "LOOKUP_TABLE default\n");
557 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
560 Hexa* cell = static_cast <Hexa*> (elt);
561 if (cell!=NULL && cell->isHere())
562 cell->colorNodes (vtk);
569 // ====================================================== saveVtk
570 // ==== Nouvelle formule qui conserve les numeros de vertex
571 int Document::saveVtk (cpchar nomfic)
573 DumpStart ("saveVtk", nomfic);
574 int nbnodes = doc_nbr_elt [EL_VERTEX];
575 int nbcells = countHexa ();
577 pfile vtk = fopen (nomfic, "w");
580 cout << " ****" << endl;
581 cout << " **** Document::saveVtk : " << endl;
582 cout << " **** Can't open file " << endl;
583 cout << " ****" << endl;
586 fprintf (vtk, "# vtk DataFile Version 3.1\n");
587 fprintf (vtk, "%s \n", nomfic);
588 fprintf (vtk, "ASCII\n");
589 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
590 fprintf (vtk, "POINTS %d float\n", nbnodes);
594 static const double minvtk = 1e-30;
595 #define Koord(p) koord[p]<minvtk && koord[p]>-minvtk ? 0 : koord[p]
597 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
600 Vertex* node = static_cast <Vertex*> (elt);
603 node->getPoint (koord);
604 fprintf (vtk, "%g %g %g\n", Koord(dir_x), Koord(dir_y), Koord(dir_z));
607 fprintf (vtk, "0 0 0\n");
611 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
613 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
616 Hexa* cell = static_cast <Hexa*> (elt);
617 if (cell!=NULL && cell->isHere())
618 cell->printHexaVtk (vtk);
621 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
622 for (int nro=0 ; nro<nbcells ; nro++)
623 fprintf (vtk, "%d\n", HE_MAXI);
625 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
626 fprintf (vtk, "SCALARS A float\n");
627 fprintf (vtk, "LOOKUP_TABLE default\n");
628 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
631 Vertex* node = static_cast <Vertex*> (elt);
634 double color = 100*(node->getScalar()+1);
635 fprintf (vtk, "%g\n", color);
638 fprintf (vtk, "100\n");
645 // ====================================================== purge
646 void Document::purge ()
648 purge_elements = false;
649 // ------------------- Raz marques
652 // ------------------- Marquage elements utilises
653 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
656 Hexa* cell = static_cast <Hexa*> (elt);
657 if (cell!=NULL && cell->isHere())
658 cell->markElements (IS_USED);
660 // ------------------- Elimination elements inutilises
661 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
663 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
666 if (elt->getMark () == NO_USED)
670 // ------------------- Sortie elements inutilises
672 /* ****************************************************************
673 EltBase* trash = doc_last_elt [EL_REMOVED];
675 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
677 doc_nbr_elt [type] = 0;
678 EltBase* last = doc_first_elt [type];
679 for (EltBase* elt = last->next (); elt!=NULL; elt = last->next())
683 doc_nbr_elt [type] ++;
688 last -> setNext (elt -> next());
689 trash -> setNext (elt);
691 trash -> setNext (NULL);
694 doc_last_elt [type] = last;
697 doc_last_elt [EL_REMOVED] = trash;
698 **************************************************************** */
701 // ======================================================== majReferences
702 void Document::majReferences ()
704 maj_connection = false;
706 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
708 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
711 elt->razReferences ();
715 for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
717 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
721 elt->majReferences ();
725 // ======================================================== dump
726 void Document::dump ()
728 cpchar nom_type [] = { "Elments non classes",
729 "Sommets", "Aretes", "Faces", "Hexaedres", "Elements detruits" };
731 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
734 printf (" ++++ Liste des %s\n", nom_type[type]);
737 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
745 printf (" ++++ End od dump\n");
747 // ======================================================== putError
748 void Document::putError (cpchar mess, cpchar info1, cpchar info2)
751 printf (" ********************************************************** \n");
752 printf (" **** HexaBlocks Error nro %d :\n", nbr_errors);
754 printf (mess, info1, info2);
757 printf (" ********************************************************** \n");
759 // ======================================================== hputError
760 void Document::hputError (cpchar mess, EltBase* e1, EltBase* e2)
762 char name1 [32] = { 0 };
763 char name2 [32] = { 0 };
765 if (e1!=NULL) e1->getName (name1);
766 if (e2!=NULL) e2->getName (name2);
768 putError (mess, name1, name2);
770 // ======================================================== parseSubShape
771 SubShape* Document::parseSubShape (XmlTree* node)
773 const string& name = node->findValue ("shape");
774 int subid = node->findInteger ("subid");
775 NewShape* shape = findShape (name);
779 SubShape* sub_shape = shape->findSubShape (subid);
782 // ======================================================== parseAssociation (v)
783 void Document::parseAssociation (XmlTree* node, Vertex* vertex)
785 SubShape* shape = parseSubShape (node);
786 if (shape==NULL || vertex==NULL)
789 if (shape->getDim()!=0)
791 VertexShape* vshape = static_cast <VertexShape*> (shape);
792 vertex->setAssociation (vshape);
794 // ======================================================== parseAssociation (e)
795 void Document::parseAssociation (XmlTree* node, Edge* edge)
797 SubShape* shape = parseSubShape (node);
798 if (shape==NULL || edge==NULL)
801 if (shape->getDim()!=1)
804 const string& inter = node->findValue ("interval");
806 get_coords (inter, pdeb, pfin);
808 EdgeShape* line = static_cast <EdgeShape*> (shape);
809 edge->addAssociation (line, pdeb, pfin);
811 // ======================================================== parseAssociation (q)
812 void Document::parseAssociation (XmlTree* node, Quad* quad)
814 SubShape* shape = parseSubShape (node);
815 if (shape==NULL || quad==NULL)
818 if (shape->getDim()!=2)
820 FaceShape* face = static_cast <FaceShape*> (shape);
821 quad->addAssociation (face);
823 // ======================================================== parseShapes
824 void Document::parseShapes (XmlTree& root)
826 XmlTree* rubrique = root.findChild ("ListShapes");
827 int nbrelts = count_children (rubrique);
829 for (int nro=0 ; nro < nbrelts ; nro++)
831 XmlTree* node = rubrique->getChild (nro);
832 const string& type = node->getName();
835 const string& nom = node->findValue ("id" );
836 int orig = node->findInteger ("type");
837 const string& brep = node->findValue ("brep");
838 NewShape* shape = new NewShape (this, (EnumShape)orig);
840 parse_name (node, nom, shape);
841 shape->setBrep (brep);
842 doc_tab_shape.push_back (shape);
844 else if (type=="Cloud")
846 int nbvert = count_children (node);
847 for (int nv=0 ; nv < nbvert ; nv++)
850 XmlTree* sommet = node->getChild (nv);
851 const string& coords = sommet->findValue ("coord");
852 get_coords (coords, point[dir_x], point[dir_y], point[dir_z]);
853 doc_cloud->addPoint (point);