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"
39 * Factory function which will be called by SMESHDriver
41 void * SMESH_createMEDMeshWriter()
43 return new DriverMED_W_SMESHDS_Mesh();
48 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh()
53 DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh()
58 void DriverMED_W_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh)
63 void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile)
68 void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId)
73 void DriverMED_W_SMESHDS_Mesh::SetMeshId(int aMeshId)
78 void DriverMED_W_SMESHDS_Mesh::Write()
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());
366 elem_Id[7].push_back(elem->GetID());
373 /****************************************************************************
374 * ECRITURE DES NOEUDS *
375 ****************************************************************************/
376 MESSAGE("(************************)");
377 MESSAGE("(* NOEUDS DU MAILLAGE : *)");
378 MESSAGE("(************************)");
380 /* Allocations memoires */
381 /* table des coordonnees
382 * profil : (dimension * nombre de noeuds ) */
383 coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim);
384 /* table des numeros, des numeros de familles des noeuds
385 * profil : (nombre de noeuds) */
386 numnoe = (med_int *) malloc(sizeof(med_int) * nnoe);
387 nufano = (med_int *) malloc(sizeof(med_int) * nnoe);
388 /* table des noms des noeuds
389 * profil : (nnoe*MED_TAILLE_PNOM+1) */
392 /* PN pour aster, il faut une famille 0 pour les noeuds et une autre pour les elements */
393 /* PN : Creation de la famille 0 */
394 char *nomfam = "FAMILLE_0";
402 med_int attvalabs = 1;
404 MEDfamCr(myFileId, nommaa, nomfam, numfam, &attide, &attval, attdes,
408 /* PN : FIN Creation de la famille 0 */
410 map < int, int >mapNoeud;
411 typedef pair < set < int >::iterator, bool > IsFamily;
415 set < int >FamilySet;
417 int verifienbnoeuds = 0;
420 SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
421 while(itNodes->more())
423 const SMDS_MeshNode * node = itNodes->next();
427 coo[i * 3] = node->X();
428 coo[i * 3 + 1] = node->Y();
429 coo[i * 3 + 2] = node->Z();
435 coo[i * 2] = node->Y();
436 coo[i * 2 + 1] = node->Z();
440 coo[i * 2] = node->X();
441 coo[i * 2 + 1] = node->Z();
445 coo[i * 2] = node->X();
446 coo[i * 2 + 1] = node->Y();
453 coo[i * 2] = node->Y();
454 coo[i * 2 + 1] = node->Z();
458 coo[i * 2] = node->X();
459 coo[i * 2 + 1] = node->Z();
463 coo[i * 2] = node->X();
464 coo[i * 2 + 1] = node->Y();
467 mapNoeud[node->GetID()] = i + 1;
469 // renvoie 0 pour les noeuds internes du volume
470 int numfamille = node->GetPosition()->GetShapeId();
471 nufano[i] = numfamille;
476 //SCRUTE(coo[i*3+1]);
477 //SCRUTE(coo[i*3+2]);
480 IsFamily deja = FamilySet.insert(nufano[i]); // insert if new, or gives existant
481 if (deja.second) // actually inserted
483 char famille[MED_TAILLE_NOM + 1];
484 sprintf(famille, "F%d", nufano[i]);
485 // CreateFamily(strdup(nommaa),strdup(famille),nufano[i],attvalabs++);
487 CreateFamily(strdup(nommaa), strdup(famille), nufano[i],
489 //MESSAGE("---famille-noeud--- "<<nbFamillesNoeud<<" "<<nufano[i]);
497 ret = MEDnoeudsEcr(myFileId, nommaa, mdim, coo, mode_coo, MED_CART,
498 nomcoo, unicoo, nomnoe, MED_FAUX, rien, MED_FAUX,
499 nufano, nnoe, MED_REMP);
501 MESSAGE("--- Creation de " << verifienbnoeuds << " noeuds");
502 ASSERT(verifienbnoeuds == nnoe);
503 MESSAGE("--- Creation de " << nbFamillesNoeud << " familles de noeuds");
505 /* liberation memoire */
510 /****************************************************************************
511 * ECRITURE DES ELEMENTS *
512 ****************************************************************************/
513 MESSAGE("(**************************)");
514 MESSAGE("(* ELEMENTS DU MAILLAGE : *)");
515 MESSAGE("(**************************)");
517 /* Ecriture des connectivites, noms, numeros des mailles */
521 int nbFamillesElts = 0;
522 SMESHDS_Mesh * mySMESHDSMesh = dynamic_cast<SMESHDS_Mesh *>(myMesh);
523 map<int,int> mapFamille;
525 if(!mySMESHDSMesh->ShapeToMesh().IsNull())
527 TopTools_IndexedMapOfShape myIndexToShape;
528 TopExp::MapShapes(mySMESHDSMesh->ShapeToMesh(), myIndexToShape);
531 if (besoinfamilledemaille == 1)
534 for (t = 1; t <= myIndexToShape.Extent(); t++)
536 const TopoDS_Shape S = myIndexToShape(t);
537 if (mySMESHDSMesh->HasMeshElements(S))
539 //MESSAGE ("********* Traitement de la Famille "<<-t);
541 SMESHDS_SubMesh * SM = mySMESHDSMesh->MeshElements(S);
542 SMDS_Iterator<const SMDS_MeshElement*> * ite=SM->GetElements();
546 mapFamille[ite->next()->GetID()] = -t;
552 char famille[MED_TAILLE_NOM + 1];
553 sprintf(famille, "E%d", t);
554 CreateFamily(strdup(nommaa), strdup(famille), -t,
561 else besoinfamilledemaille = 0;
564 for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
566 if (nmailles[i] > 0 && ret == 0)
568 MESSAGE(" Start " << typmai[i]);
570 /* dimension de la maille */
571 edim = typmai[i] / 100;
573 if (mdim == 2 || mdim == 3)
581 taille = nsup + typmai[i] % 100;
584 /* allocation memoire */
586 (med_int *) malloc(sizeof(med_int) * taille * nmailles[i]);
588 (char *)malloc(sizeof(char) * MED_TAILLE_PNOM *
591 numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
592 nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
593 nbNodes = typmai[i] % 100;
595 for (j = 0; j < nmailles[i]; j++)
597 myId = elem_Id[i][j];
598 const SMDS_MeshElement * elem =
599 myMesh->FindElement(myId);
600 //*(numele+j) = myId;
601 *(numele + j) = indice++;
603 SMDS_Iterator<const SMDS_MeshElement *> * itk=elem->nodesIterator();
604 for (k = 0; itk->more(); k++)
606 *(connectivite + j * taille + k) =
607 mapNoeud[itk->next()->GetID()];
612 *(connectivite + j * taille + nbNodes) = 0;
614 if (besoinfamilledemaille == 1)
616 if (mapFamille.find(myId) != mapFamille.end())
618 nufael[j] = mapFamille[myId];
635 /* ecriture des données */
639 MEDelementsEcr(myFileId, nommaa, mdim, connectivite,
640 mode_coo, nomele, MED_FAUX, numele, MED_VRAI, nufael,
641 nmailles[i], MED_MAILLE, typmai[i], typ_con, MED_REMP);
646 MESSAGE(">> ERREUR : ecriture des mailles \n");
648 /* liberation memoire */
652 MESSAGE(" End " << typmai[i]);
655 MESSAGE("--- Creation de " << nbFamillesElts << " familles d elements");
659 /****************************************************************************
660 * FERMETURE DU FICHIER *
661 ****************************************************************************/
663 ret = MEDfermer(myFileId);
666 fprintf(stderr, ">> ERREUR : erreur a la fermeture du fichier %s\n",
668 MESSAGE("fichier ferme");
672 void DriverMED_W_SMESHDS_Mesh::CreateFamily(char *nommaa, char *famille, int i,
680 char attdes[MED_TAILLE_DESC + 1];
681 char gro[MED_TAILLE_LNOM + 1];
682 char fam2[MED_TAILLE_LNOM + 1];
686 strcpy(fam2, famille);
688 med_int *attide = new med_int[1];
689 med_int *attval = new med_int[1];
693 //MESSAGE("-------- Creation de la Famille : "<< famille << "numero " << i << " --------------");
695 MEDfamCr(myFileId, nommaa, fam2, i, attide, attval, attdes, natt, gro,