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 "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 = basename ((pchar)ficname);
126 static const int NbExt = 3;
127 static cpchar t_ext [NbExt] = { ".xml", ".XML", ".Xml" };
130 for (int nx = 0; nx < NbExt && noext ; nx++)
132 ici = el_name.rfind (t_ext[nx]);
133 noext = ici < 0 || ici > el_name.size();
139 el_name.erase (ici, 4);
141 int ier = xml.parseFile (filename);
145 ier = parseXml (xml);
148 // ======================================================== setXml
149 int Document::setXml (cpchar flux)
152 int ier = setXml (flux, posit);
155 // ======================================================== setXml
156 int Document::setXml (cpchar flux, int& posit)
160 int ier = xml.parseStream (flux, posit);
164 ier = parseXml (xml);
170 // ======================================================== parseXml
171 int Document::parseXml (XmlTree& xml)
175 map <std::string, Vertex*> t_vertex;
176 map <std::string, Edge*> t_edge;
177 map <std::string, Quad*> t_quad;
178 map <std::string, Hexa*> t_hexa;
179 map <std::string, Vector*> t_vector;
180 vector <string> tname;
182 const string& version = xml.findValue ("version");
185 cout << " **** Format du fichier XML perime"
189 const string& name = xml.findValue ("name");
191 setName (name.c_str());
195 XmlTree* rubrique = xml.findChild ("ListVertices");
196 int nbrelts = count_children (rubrique);
198 Vertex* vertex = NULL;
199 for (int nro=0 ; nro < nbrelts ; nro++)
201 XmlTree* node = rubrique->getChild (nro);
202 const string& type = node->getName();
206 const string& nom = node->findValue ("id");
207 const string& coords = node->findValue ("coord");
208 get_coords (coords, px, py, pz);
210 vertex = addVertex (px, py, pz);
211 parse_name (node, nom, vertex);
212 t_vertex [nom] = vertex;
214 else if (type=="Asso")
216 parseAssociation (node, vertex);
220 rubrique = xml.findChild ("ListEdges");
221 nbrelts = count_children (rubrique);
224 for (int nro=0 ; nro < nbrelts ; nro++)
226 XmlTree* node = rubrique->getChild (nro);
227 const string& type = node->getName();
230 const string& nom = node->findValue ("id");
231 const string& vertices = node->findValue ("vertices");
232 get_names (vertices, V_TWO, tname);
233 edge = new Edge (t_vertex [tname[0]], t_vertex [tname[1]]);
235 parse_name (node, nom, edge);
237 else if (type=="Asso")
239 parseAssociation (node, edge);
243 rubrique = xml.findChild ("ListQuads");
244 nbrelts = count_children (rubrique);
247 for (int nro=0 ; nro < nbrelts ; nro++)
249 XmlTree* node = rubrique->getChild (nro);
250 const string& type = node->getName();
253 const string& nom = node->findValue ("id");
254 const string& edges = node->findValue ("edges");
255 get_names (edges, V_TWO, tname);
257 quad = new Quad (t_edge [tname[0]], t_edge [tname[1]],
258 t_edge [tname[2]], t_edge [tname[3]]);
260 parse_name (node, nom, quad);
262 else if (type=="Asso")
264 parseAssociation (node, quad);
268 rubrique = xml.findChild ("ListHexas");
269 nbrelts = count_children (rubrique);
271 for (int nro=0 ; nro < nbrelts ; nro++)
273 XmlTree* node = rubrique->getChild (nro);
274 const string& nom = node->findValue ("id");
275 const string& quads = node->findValue ("quads");
276 get_names (quads, V_TWO, tname);
278 Hexa* hexa = new Hexa (t_quad [tname[0]], t_quad [tname[1]],
279 t_quad [tname[2]], t_quad [tname[3]],
280 t_quad [tname[4]], t_quad [tname[5]]);
282 parse_name (node, nom, hexa);
285 rubrique = xml.findChild ("ListVectors");
286 nbrelts = count_children (rubrique);
288 for (int nro=0 ; nro < nbrelts ; nro++)
290 XmlTree* node = rubrique->getChild (nro);
292 const string& nom = node->findValue ("id");
293 const string& coords = node->findValue ("coord");
294 get_coords (coords, px, py, pz);
296 Vector* vector = addVector (px, py, pz);
297 t_vector [nom] = vector;
298 parse_name (node, nom, vector);
301 rubrique = xml.findChild ("ListDicretizationLaws");
302 nbrelts = count_children (rubrique);
304 for (int nro=0 ; nro < nbrelts ; nro++)
306 XmlTree* node = rubrique->getChild (nro);
307 const string& id = node->findValue ("id");
308 const string& kind = node->findValue ("kind");
309 const string& nodes = node->findValue ("nodes");
310 const string& coeff = node->findValue ("coeff");
312 int nbnodes = atoi (nodes.c_str());
313 double koeff = atof (coeff.c_str());
314 if (id != "DefaultLaw")
316 Law* law = addLaw (id.c_str(), nbnodes);
317 law->setCoefficient (koeff);
318 law->setKind (kind.c_str());
322 rubrique = xml.findChild ("ListPropagations");
323 nbrelts = count_children (rubrique);
325 for (int nro=0 ; nro < nbrelts ; nro++)
327 XmlTree* node = rubrique->getChild (nro);
328 const string& nmedge = node->findValue ("edge");
329 const string& nmlaw = node->findValue ("law");
330 // const string& nmway = node->findValue ("way");
332 edge = t_edge [nmedge];
333 Law* law = findLaw (nmlaw.c_str());
334 // bool way = nmway == "true";
340 rubrique = xml.findChild ("ListGroups");
341 int nbrgroups = count_children (rubrique);
343 for (int nro=0 ; nro < nbrgroups ; nro++)
345 XmlTree* ndgroup = rubrique->getChild (nro);
346 XmlTree* node = ndgroup ->getChild (0);
347 const string& nom = node->findValue ("name");
348 const string& ckind = node->findValue ("kind");
350 EnumGroup kind = Group::getKind (ckind);
351 Group* groupe = addGroup (nom.c_str(), kind);
352 EnumElt type = groupe->getTypeElt ();
354 nbrelts = count_children (ndgroup);
355 for (int nelt=1 ; nelt < nbrelts ; nelt++)
357 node = ndgroup ->getChild (nelt);
358 const string& id = node->findValue ("id");
361 case EL_HEXA : groupe->addElement (t_hexa [id]);
363 case EL_QUAD : groupe->addElement (t_quad [id]);
365 case EL_EDGE : groupe->addElement (t_edge [id]);
368 default : groupe->addElement (t_vertex [id]);
377 // ======================================================== save
378 int Document::save (const char* ficxml)
380 DumpStart ("save", ficxml);
383 doc_xml = new XmlWriter ();
385 int ier = doc_xml->setFileName (ficxml);
392 // ======================================================== appendXml
393 int Document::appendXml (pfile fstudy)
396 doc_xml = new XmlWriter ();
398 doc_xml->setFile (fstudy);
403 // ======================================================== getXml
404 cpchar Document::getXml ()
407 doc_xml = new XmlWriter ();
409 doc_xml->setStream ();
414 return doc_xml->getXml ();
416 // ======================================================== genXml
417 int Document::genXml ()
419 const int HexVersion = 1;
420 // -- 1) Raz numerotation precedente
421 markAll (NO_COUNTED);
426 doc_xml = new XmlWriter ();
428 doc_xml->startXml ();
429 doc_xml->openMark ("Document");
430 doc_xml->addAttribute ("name", el_name);
431 doc_xml->addAttribute ("version", HexVersion);
434 cpchar balise [] = {"ListXXXX",
435 "ListVertices", "ListEdges", "ListQuads", "ListHexas", "ListVectors",
438 for (int type=EL_VERTEX ; type <= EL_VECTOR ; type++)
440 doc_xml->addMark (balise [type]);
441 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
444 if (elt !=NULL && elt->isHere())
445 elt->saveXml (doc_xml);
447 doc_xml->closeMark (true);
450 doc_xml->addMark ("ListDicretizationLaws");
451 for (int nro=0 ; nro<nbr_laws ; nro++)
452 doc_laws [nro]->saveXml (doc_xml);
453 doc_xml->closeMark (true);
455 doc_xml->addMark ("ListPropagations");
456 for (int nro=0 ; nro<nbr_propagations ; nro++)
457 doc_propagation[nro]->saveXml (doc_xml);
458 doc_xml->closeMark (true);
460 int nombre = countGroup();
461 doc_xml->addMark ("ListGroups");
462 for (int nro=0 ; nro<nombre ; nro++)
463 doc_group[nro]->saveXml (doc_xml);
464 doc_xml->closeMark (true);
466 nombre = countShape ();
467 doc_xml->addMark ("ListShapes");
468 for (int nro=0 ; nro<nombre ; nro++)
469 doc_tab_shape[nro]->saveXml (doc_xml);
470 doc_xml->closeMark ();
472 doc_xml->closeMark ();
473 doc_xml->closeXml ();
477 // ======================================================== markAll
478 void Document::markAll (int marque, int type)
480 int debut = EL_VERTEX;
482 if (type>=0 && type<EL_MAXI)
485 for (int type=debut ; type <= fin ; type++)
487 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
489 elt->setMark (marque);
492 // ====================================================== saveVtk
493 int Document::saveVtk0 (cpchar nomfic)
495 // -- 1) Raz numerotation precedente
496 markAll (NO_COUNTED, EL_VERTEX);
501 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
504 Hexa* cell = static_cast <Hexa*> (elt);
505 if (cell!=NULL && cell->isHere())
508 nbnodes += cell->countNodes ();
512 pfile vtk = fopen (nomfic, "w");
515 cout << " ****" << endl;
516 cout << " **** Document::saveVtk : " << endl;
517 cout << " **** Can't open file " << endl;
518 cout << " ****" << endl;
521 fprintf (vtk, "# vtk DataFile Version 3.1\n");
522 fprintf (vtk, "%s \n", nomfic);
523 fprintf (vtk, "ASCII\n");
524 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
525 fprintf (vtk, "POINTS %d float\n", nbnodes);
529 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
532 Hexa* cell = static_cast <Hexa*> (elt);
533 if (cell!=NULL && cell->isHere())
534 cell->printNodes (vtk, nronode);
538 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
540 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
543 Hexa* cell = static_cast <Hexa*> (elt);
544 if (cell!=NULL && cell->isHere())
545 cell->printHexa (vtk);
548 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
549 for (int nro=0 ; nro<nbcells ; nro++)
550 fprintf (vtk, "%d\n", HE_MAXI);
552 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
553 fprintf (vtk, "SCALARS A float\n");
554 fprintf (vtk, "LOOKUP_TABLE default\n");
556 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
559 Hexa* cell = static_cast <Hexa*> (elt);
560 if (cell!=NULL && cell->isHere())
561 cell->colorNodes (vtk);
568 // ====================================================== saveVtk
569 // ==== Nouvelle formule qui conserve les numeros de vertex
570 int Document::saveVtk (cpchar nomfic)
572 DumpStart ("saveVtk", nomfic);
573 int nbnodes = doc_nbr_elt [EL_VERTEX];
574 int nbcells = countHexa ();
576 pfile vtk = fopen (nomfic, "w");
579 cout << " ****" << endl;
580 cout << " **** Document::saveVtk : " << endl;
581 cout << " **** Can't open file " << endl;
582 cout << " ****" << endl;
585 fprintf (vtk, "# vtk DataFile Version 3.1\n");
586 fprintf (vtk, "%s \n", nomfic);
587 fprintf (vtk, "ASCII\n");
588 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
589 fprintf (vtk, "POINTS %d float\n", nbnodes);
593 static const double minvtk = 1e-30;
594 #define Koord(p) koord[p]<minvtk && koord[p]>-minvtk ? 0 : koord[p]
596 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
599 Vertex* node = static_cast <Vertex*> (elt);
602 node->getPoint (koord);
603 fprintf (vtk, "%g %g %g\n", Koord(dir_x), Koord(dir_y), Koord(dir_z));
606 fprintf (vtk, "0 0 0\n");
610 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
612 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
615 Hexa* cell = static_cast <Hexa*> (elt);
616 if (cell!=NULL && cell->isHere())
617 cell->printHexaVtk (vtk);
620 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
621 for (int nro=0 ; nro<nbcells ; nro++)
622 fprintf (vtk, "%d\n", HE_MAXI);
624 fprintf (vtk, "POINT_DATA %d \n", nbnodes);
625 fprintf (vtk, "SCALARS A float\n");
626 fprintf (vtk, "LOOKUP_TABLE default\n");
627 for (EltBase* elt = doc_first_elt[EL_VERTEX]->next (); elt!=NULL;
630 Vertex* node = static_cast <Vertex*> (elt);
633 double color = 100*(node->getScalar()+1);
634 fprintf (vtk, "%g\n", color);
637 fprintf (vtk, "100\n");
644 // ====================================================== purge
645 void Document::purge ()
647 purge_elements = false;
648 // ------------------- Raz marques
651 // ------------------- Marquage elements utilises
652 for (EltBase* elt = doc_first_elt[EL_HEXA]->next (); elt!=NULL;
655 Hexa* cell = static_cast <Hexa*> (elt);
656 if (cell!=NULL && cell->isHere())
657 cell->markElements (IS_USED);
659 // ------------------- Elimination elements inutilises
660 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
662 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
665 if (elt->getMark () == NO_USED)
669 // ------------------- Sortie elements inutilises
671 /* ****************************************************************
672 EltBase* trash = doc_last_elt [EL_REMOVED];
674 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
676 doc_nbr_elt [type] = 0;
677 EltBase* last = doc_first_elt [type];
678 for (EltBase* elt = last->next (); elt!=NULL; elt = last->next())
682 doc_nbr_elt [type] ++;
687 last -> setNext (elt -> next());
688 trash -> setNext (elt);
690 trash -> setNext (NULL);
693 doc_last_elt [type] = last;
696 doc_last_elt [EL_REMOVED] = trash;
697 **************************************************************** */
700 // ======================================================== majReferences
701 void Document::majReferences ()
703 maj_connection = false;
705 for (int type=EL_VERTEX ; type <= EL_QUAD ; type++)
707 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
710 elt->razReferences ();
714 for (int type=EL_EDGE ; type <= EL_HEXA ; type++)
716 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
720 elt->majReferences ();
724 // ======================================================== dump
725 void Document::dump ()
727 cpchar nom_type [] = { "Elments non classes",
728 "Sommets", "Aretes", "Faces", "Hexaedres", "Elements detruits" };
730 for (int type=EL_VERTEX ; type <= EL_HEXA ; type++)
733 printf (" ++++ Liste des %s\n", nom_type[type]);
736 for (EltBase* elt = doc_first_elt[type]->next (); elt!=NULL;
744 printf (" ++++ End od dump\n");
746 // ======================================================== putError
747 void Document::putError (cpchar mess, cpchar info1, cpchar info2)
750 printf (" ********************************************************** \n");
751 printf (" **** HexaBlocks Error nro %d :\n", nbr_errors);
753 printf (mess, info1, info2);
756 printf (" ********************************************************** \n");
758 // ======================================================== hputError
759 void Document::hputError (cpchar mess, EltBase* e1, EltBase* e2)
761 char name1 [32] = { 0 };
762 char name2 [32] = { 0 };
764 if (e1!=NULL) e1->getName (name1);
765 if (e2!=NULL) e2->getName (name2);
767 putError (mess, name1, name2);
769 // ======================================================== parseSubShape
770 SubShape* Document::parseSubShape (XmlTree* node)
772 const string& name = node->findValue ("shape");
773 int subid = node->findInteger ("subid");
774 NewShape* shape = findShape (name);
778 SubShape* sub_shape = shape->findSubShape (subid);
781 // ======================================================== parseAssociation (v)
782 void Document::parseAssociation (XmlTree* node, Vertex* vertex)
784 SubShape* shape = parseSubShape (node);
785 if (shape==NULL || vertex==NULL)
788 if (shape->getDim()!=0)
790 VertexShape* vshape = static_cast <VertexShape*> (shape);
791 vertex->setAssociation (vshape);
793 // ======================================================== parseAssociation (e)
794 void Document::parseAssociation (XmlTree* node, Edge* edge)
796 SubShape* shape = parseSubShape (node);
797 if (shape==NULL || edge==NULL)
800 if (shape->getDim()!=1)
803 const string& inter = node->findValue ("interval");
805 get_coords (inter, pdeb, pfin);
807 EdgeShape* line = static_cast <EdgeShape*> (shape);
808 edge->addAssociation (line, pdeb, pfin);
810 // ======================================================== parseAssociation (q)
811 void Document::parseAssociation (XmlTree* node, Quad* quad)
813 SubShape* shape = parseSubShape (node);
814 if (shape==NULL || quad==NULL)
817 if (shape->getDim()!=2)
819 FaceShape* face = static_cast <FaceShape*> (shape);
820 quad->addAssociation (face);
822 // ======================================================== parseShapes
823 void Document::parseShapes (XmlTree& root)
825 XmlTree* rubrique = root.findChild ("ListShapes");
826 int nbrelts = count_children (rubrique);
828 for (int nro=0 ; nro < nbrelts ; nro++)
830 XmlTree* node = rubrique->getChild (nro);
831 const string& type = node->getName();
834 const string& nom = node->findValue ("id" );
835 int orig = node->findInteger ("type");
836 const string& brep = node->findValue ("brep");
837 NewShape* shape = new NewShape (this, (EnumShape)orig);
839 parse_name (node, nom, shape);
840 shape->setBrep (brep);
841 doc_tab_shape.push_back (shape);
843 else if (type=="Cloud")
845 int nbvert = count_children (node);
846 for (int nv=0 ; nv < nbvert ; nv++)
849 XmlTree* sommet = node->getChild (nv);
850 const string& coords = sommet->findValue ("coord");
851 get_coords (coords, point[dir_x], point[dir_y], point[dir_z]);
852 doc_cloud->addPoint (point);