1 // SMESH DriverMED : driver to read and write 'med' files
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : DriverMED_W_SMESHDS_Mesh.cxx
28 #include "DriverMED_W_SMESHDS_Mesh.h"
29 #include "DriverMED_W_SMDS_Mesh.h"
30 #include "SMDS_MeshElement.hxx"
31 #include "SMDS_MeshNode.hxx"
34 #include "utilities.h"
36 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh()
41 DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh()
46 void DriverMED_W_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh)
51 void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile)
56 void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId)
61 void DriverMED_W_SMESHDS_Mesh::SetMeshId(int aMeshId)
66 void DriverMED_W_SMESHDS_Mesh::Write()
69 string myClass = string("SMDS_Mesh");
70 string myExtension = string("MED");
72 DriverMED_W_SMDS_Mesh *myWriter = new DriverMED_W_SMDS_Mesh;
74 myWriter->SetMesh(myMesh);
75 // myWriter->SetFile(myFile);
76 myWriter->SetMeshId(myMeshId);
77 myWriter->SetFileId(myFileId);
83 void DriverMED_W_SMESHDS_Mesh::Add()
91 /* nombre d'objets MED */
92 char nom_universel[MED_TAILLE_LNOM + 1];
93 med_int long_fichier_en_tete;
94 char *fichier_en_tete;
97 med_int nmaa, mdim, nnoe;
98 med_int nmai[MED_NBR_GEOMETRIE_MAILLE], nfac[MED_NBR_GEOMETRIE_FACE];
99 med_int nare[MED_NBR_GEOMETRIE_ARETE];
100 /* nom du maillage */
101 char nommaa[MED_TAILLE_NOM + 1];
104 // PN : Initilialisation de nomcoo et unicoo pour lisibilite du maillage
105 char nomcoo[3 * MED_TAILLE_PNOM + 1] = "x y z ";
106 char unicoo[3 * MED_TAILLE_PNOM + 1] = "m m m ";
111 med_booleen inonoe, inunoe;
112 med_mode_switch mode_coo;
113 char str[MED_TAILLE_PNOM + 1];
119 med_int elem_id, myId;
120 med_int *connectivite;
124 med_booleen inoele, inuele;
125 med_connectivite typ_con;
126 med_geometrie_element typgeo;
127 med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] =
128 { MED_POINT1, MED_SEG2,
130 MED_TRIA6, MED_QUAD4,
131 MED_QUAD8, MED_TETRA4,
132 MED_TETRA10, MED_HEXA8,
133 MED_HEXA20, MED_PENTA6,
134 MED_PENTA15, MED_PYRA5,
137 med_int desmai[MED_NBR_GEOMETRIE_MAILLE] =
138 { 0, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5 };
139 med_int nmailles[MED_NBR_GEOMETRIE_MAILLE];
140 char nommai[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] = { "MED_POINT1",
156 med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] =
157 { MED_TRIA3, MED_TRIA6,
160 med_int desfac[MED_NBR_GEOMETRIE_FACE] = { 3, 3, 4, 4 };
161 med_int nfaces[MED_NBR_GEOMETRIE_FACE];
162 char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM + 1] =
163 { "MED_TRIA3", "MED_TRIA6",
164 "MED_QUAD4", "MED_QUAD8"
166 med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] =
167 { MED_SEG2, MED_SEG3 };
168 med_int desare[MED_NBR_GEOMETRIE_ARETE] = { 2, 3 };
169 med_int naretes[MED_NBR_GEOMETRIE_ARETE];
170 char nomare[MED_NBR_GEOMETRIE_ARETE][MED_TAILLE_NOM + 1] =
171 { "MED_SEG2", "MED_SEG3" };
174 mode_coo = MED_FULL_INTERLACE;
177 //---- provisoire : switch pour ecrire les familles de mailles
178 int besoinfamilledemaille = 1;
179 //---- provisoire : switch pour ecrire les familles de mailles
181 /****************************************************************************
182 * OUVERTURE DU FICHIER EN ECRITURE *
183 ****************************************************************************/
184 char *file2Read = (char *)myFile.c_str();
186 MESSAGE(" file2Read " << file2Read)
187 myFileId = MEDouvrir(file2Read, MED_REMP);
190 fprintf(stderr, ">> ERREUR : ouverture du fichier %s \n", file2Read);
194 /****************************************************************************
195 * NOMBRES D'OBJETS MED *
196 ****************************************************************************/
197 MESSAGE("(****************************)");
198 MESSAGE("(* INFORMATIONS GENERALES : *)");
199 MESSAGE("(****************************)");
201 /* calcul de la dimension */
203 double epsilon = 0.00001;
213 SMDS_Iterator<const SMDS_MeshNode *> * myItNodes=myMesh->nodesIterator();
214 while(myItNodes->more())
216 const SMDS_MeshNode * node = myItNodes->next();
219 nodeRefX = fabs(node->X());
220 nodeRefY = fabs(node->Y());
221 nodeRefZ = fabs(node->Z());
230 if ((fabs(fabs(node->X()) - nodeRefX) > epsilon) && dimX)
232 if ((fabs(fabs(node->Y()) - nodeRefY) > epsilon) && dimY)
234 if ((fabs(fabs(node->Z()) - nodeRefZ) > epsilon) && dimZ)
237 if (!dimX && !dimY && !dimZ)
247 if (dimX && dimY && dimZ)
253 else if ((dimY && !dimZ) || (!dimY && dimZ))
260 else if ((dimX && !dimZ) || (!dimX && dimZ))
267 else if ((dimY && !dimX) || (!dimY && dimX))
272 MESSAGE(" mdim " << mdim);
274 /* creation du maillage */
276 sprintf(nommaa, "Mesh %d", numero);
278 ret = MEDmaaCr(myFileId, nommaa, mdim);
283 /* Combien de noeuds ? */
284 nnoe = myMesh->NbNodes();
286 /* Combien de mailles, faces ou aretes ? */
287 for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
290 int nb_of_nodes, nb_of_faces, nb_of_edges;
291 vector < int >elem_Id[MED_NBR_GEOMETRIE_MAILLE];
293 nb_of_edges = myMesh->NbEdges();
294 SMDS_Iterator<const SMDS_MeshEdge *> * itEdges=myMesh->edgesIterator();
295 while(itEdges->more())
297 const SMDS_MeshEdge * elem = itEdges->next();
299 nb_of_nodes = elem->NbNodes();
305 elem_Id[1].push_back(elem->GetID());
311 elem_Id[2].push_back(elem->GetID());
318 nb_of_faces = myMesh->NbFaces();
319 SMDS_Iterator<const SMDS_MeshFace *> * itFaces=myMesh->facesIterator();
320 while(itFaces->more())
322 const SMDS_MeshElement * elem = itFaces->next();
324 nb_of_nodes = elem->NbNodes();
330 elem_Id[3].push_back(elem->GetID());
336 elem_Id[5].push_back(elem->GetID());
342 elem_Id[4].push_back(elem->GetID());
350 SMDS_Iterator<const SMDS_MeshVolume *> * itVolumes=myMesh->volumesIterator();
351 while(itVolumes->more())
353 const SMDS_MeshElement * elem = itVolumes->next();
355 nb_of_nodes = elem->NbNodes();
360 elem_Id[9].push_back(elem->GetID());
367 /****************************************************************************
368 * ECRITURE DES NOEUDS *
369 ****************************************************************************/
370 MESSAGE("(************************)");
371 MESSAGE("(* NOEUDS DU MAILLAGE : *)");
372 MESSAGE("(************************)");
374 /* Allocations memoires */
375 /* table des coordonnees
376 * profil : (dimension * nombre de noeuds ) */
377 coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim);
378 /* table des numeros, des numeros de familles des noeuds
379 * profil : (nombre de noeuds) */
380 numnoe = (med_int *) malloc(sizeof(med_int) * nnoe);
381 nufano = (med_int *) malloc(sizeof(med_int) * nnoe);
382 /* table des noms des noeuds
383 * profil : (nnoe*MED_TAILLE_PNOM+1) */
386 /* PN pour aster, il faut une famille 0 pour les noeuds et une autre pour les elements */
387 /* PN : Creation de la famille 0 */
388 char *nomfam = "FAMILLE_0";
396 med_int attvalabs = 1;
398 MEDfamCr(myFileId, nommaa, nomfam, numfam, &attide, &attval, attdes,
402 /* PN : FIN Creation de la famille 0 */
404 map < int, int >mapNoeud;
405 typedef pair < set < int >::iterator, bool > IsFamily;
409 set < int >FamilySet;
411 int verifienbnoeuds = 0;
414 SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
415 while(itNodes->more())
417 const SMDS_MeshNode * node = itNodes->next();
421 coo[i * 3] = node->X();
422 coo[i * 3 + 1] = node->Y();
423 coo[i * 3 + 2] = node->Z();
429 coo[i * 2] = node->Y();
430 coo[i * 2 + 1] = node->Z();
434 coo[i * 2] = node->X();
435 coo[i * 2 + 1] = node->Z();
439 coo[i * 2] = node->X();
440 coo[i * 2 + 1] = node->Y();
447 coo[i * 2] = node->Y();
448 coo[i * 2 + 1] = node->Z();
452 coo[i * 2] = node->X();
453 coo[i * 2 + 1] = node->Z();
457 coo[i * 2] = node->X();
458 coo[i * 2 + 1] = node->Y();
461 mapNoeud[node->GetID()] = i + 1;
463 // renvoie 0 pour les noeuds internes du volume
464 int numfamille = node->GetPosition()->GetShapeId();
465 nufano[i] = numfamille;
470 //SCRUTE(coo[i*3+1]);
471 //SCRUTE(coo[i*3+2]);
474 IsFamily deja = FamilySet.insert(nufano[i]); // insert if new, or gives existant
475 if (deja.second) // actually inserted
477 char famille[MED_TAILLE_NOM + 1];
478 sprintf(famille, "F%d", nufano[i]);
479 // CreateFamily(strdup(nommaa),strdup(famille),nufano[i],attvalabs++);
481 CreateFamily(strdup(nommaa), strdup(famille), nufano[i],
483 //MESSAGE("---famille-noeud--- "<<nbFamillesNoeud<<" "<<nufano[i]);
491 ret = MEDnoeudsEcr(myFileId, nommaa, mdim, coo, mode_coo, MED_CART,
492 nomcoo, unicoo, nomnoe, MED_FAUX, rien, MED_FAUX,
493 nufano, nnoe, MED_REMP);
495 MESSAGE("--- Creation de " << verifienbnoeuds << " noeuds");
496 ASSERT(verifienbnoeuds == nnoe);
497 MESSAGE("--- Creation de " << nbFamillesNoeud << " familles de noeuds");
499 /* liberation memoire */
504 /****************************************************************************
505 * ECRITURE DES ELEMENTS *
506 ****************************************************************************/
507 MESSAGE("(**************************)");
508 MESSAGE("(* ELEMENTS DU MAILLAGE : *)");
509 MESSAGE("(**************************)");
511 /* Ecriture des connectivites, noms, numeros des mailles */
515 int nbFamillesElts = 0;
516 SMESHDS_Mesh * mySMESHDSMesh = dynamic_cast<SMESHDS_Mesh *>(myMesh);
517 TopTools_IndexedMapOfShape myIndexToShape;
518 TopExp::MapShapes(mySMESHDSMesh->ShapeToMesh(), myIndexToShape);
520 map<int,int> mapFamille;
522 if (besoinfamilledemaille == 1)
525 for (t = 1; t <= myIndexToShape.Extent(); t++)
527 const TopoDS_Shape S = myIndexToShape(t);
528 if (mySMESHDSMesh->HasMeshElements(S))
530 //MESSAGE ("********* Traitement de la Famille "<<-t);
532 SMESHDS_SubMesh * SM = mySMESHDSMesh->MeshElements(S);
533 const vector<int>& indElt = SM->GetIDElements();
534 vector<int>::const_iterator ite=indElt.begin();
537 for (; ite!=indElt.end(); ite++)
540 mapFamille[eltId] = -t;
546 char famille[MED_TAILLE_NOM + 1];
547 sprintf(famille, "E%d", t);
548 CreateFamily(strdup(nommaa), strdup(famille), -t,
556 for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
558 if (nmailles[i] > 0 && ret == 0)
560 MESSAGE(" Start " << typmai[i]);
562 /* dimension de la maille */
563 edim = typmai[i] / 100;
565 if (mdim == 2 || mdim == 3)
573 taille = nsup + typmai[i] % 100;
576 /* allocation memoire */
578 (med_int *) malloc(sizeof(med_int) * taille * nmailles[i]);
580 (char *)malloc(sizeof(char) * MED_TAILLE_PNOM *
582 numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
583 nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
585 nbNodes = typmai[i] % 100;
587 for (j = 0; j < nmailles[i]; j++)
589 myId = elem_Id[i][j];
590 const SMDS_MeshElement * elem =
591 myMesh->FindElement(myId);
592 //*(numele+j) = myId;
593 *(numele + j) = indice++;
595 SMDS_Iterator<const SMDS_MeshElement *> * itk=elem->nodesIterator();
596 for (k = 0; itk->more(); k++)
598 *(connectivite + j * taille + k) =
599 mapNoeud[itk->next()->GetID()];
604 *(connectivite + j * taille + nbNodes) = 0;
606 if (besoinfamilledemaille == 1)
608 if (mapFamille.find(myId) != mapFamille.end())
610 nufael[j] = mapFamille[myId];
627 /* ecriture des données */
631 MEDelementsEcr(myFileId, nommaa, mdim, connectivite,
632 mode_coo, nomele, MED_FAUX, numele, MED_VRAI, nufael,
633 nmailles[i], MED_MAILLE, typmai[i], typ_con, MED_REMP);
638 MESSAGE(">> ERREUR : ecriture des mailles \n");
640 /* liberation memoire */
644 MESSAGE(" End " << typmai[i]);
647 MESSAGE("--- Creation de " << nbFamillesElts << " familles d elements");
651 /****************************************************************************
652 * FERMETURE DU FICHIER *
653 ****************************************************************************/
655 ret = MEDfermer(myFileId);
658 fprintf(stderr, ">> ERREUR : erreur a la fermeture du fichier %s\n",
660 MESSAGE("fichier ferme");
664 void DriverMED_W_SMESHDS_Mesh::CreateFamily(char *nommaa, char *famille, int i,
672 char attdes[MED_TAILLE_DESC + 1];
673 char gro[MED_TAILLE_LNOM + 1];
674 char fam2[MED_TAILLE_LNOM + 1];
678 strcpy(fam2, famille);
680 med_int *attide = new med_int[1];
681 med_int *attval = new med_int[1];
685 //MESSAGE("-------- Creation de la Famille : "<< famille << "numero " << i << " --------------");
687 MEDfamCr(myFileId, nommaa, fam2, i, attide, attval, attdes, natt, gro,