Salome HOME
yfr : Merge with v1.2
[modules/smesh.git] / src / DriverMED / DriverMED_W_SMDS_Mesh.cxx
1 //  SMESH DriverMED : driver to read and write 'med' files
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : DriverMED_W_SMDS_Mesh.cxx
25 //  Module : SMESH
26
27 using namespace std;
28 #include "DriverMED_W_SMDS_Mesh.h"
29
30 #include "SMDS_MeshElement.hxx"
31 #include "SMDS_MeshNode.hxx"
32 #include "SMDS_MeshFacesIterator.hxx"
33 #include "SMDS_MeshNodesIterator.hxx"
34 #include "SMDS_MeshVolumesIterator.hxx"
35
36 #include "utilities.h"
37 #include <vector>
38
39 DriverMED_W_SMDS_Mesh::DriverMED_W_SMDS_Mesh() {
40 ;
41 }
42
43 DriverMED_W_SMDS_Mesh::~DriverMED_W_SMDS_Mesh() {
44 ;
45 }
46
47 void DriverMED_W_SMDS_Mesh::SetMesh(Handle(SMDS_Mesh)& aMesh) {
48   myMesh = aMesh;
49 }
50
51 void DriverMED_W_SMDS_Mesh::SetFile(string aFile) {
52   myFile = aFile;
53 }
54
55 void DriverMED_W_SMDS_Mesh::SetFileId(med_idt aFileId) {
56   myFileId = aFileId;
57 }
58
59 void DriverMED_W_SMDS_Mesh::SetMeshId(int aMeshId) {
60   myMeshId = aMeshId;
61 }
62
63 void DriverMED_W_SMDS_Mesh::Add() {
64   ;
65 }
66
67 void DriverMED_W_SMDS_Mesh::Write() {
68
69   med_err ret = 0;
70   int i,j,k,l;
71   int numero;
72   char message[200];
73   Standard_Boolean ok;
74   /* nombre d'objets MED */
75   char nom_universel[MED_TAILLE_LNOM+1];
76   med_int long_fichier_en_tete; 
77   char *fichier_en_tete;
78   char version_hdf[10];
79   char version_med[10];
80   med_int nmaa,mdim,nnoe;
81   med_int nmai[MED_NBR_GEOMETRIE_MAILLE],nfac[MED_NBR_GEOMETRIE_FACE];
82   med_int nare[MED_NBR_GEOMETRIE_ARETE];
83   /* nom du maillage */
84   char nommaa[MED_TAILLE_NOM+1];
85   /* noeuds */
86   med_float *coo;
87   char nomcoo[3*MED_TAILLE_PNOM+1];
88   char unicoo[3*MED_TAILLE_PNOM+1];
89   char *nomnoe;
90   med_int *numnoe;
91   med_int *nufano; 
92   med_repere rep;
93   med_booleen inonoe,inunoe;
94   med_mode_switch mode_coo;
95   char str[MED_TAILLE_PNOM+1];
96   med_int nbNodes;
97   /* elements */
98   med_int nsup;
99   med_int edim;
100   med_int taille;
101   med_int elem_id,myId;
102   med_int *connectivite;
103   char *nomele;
104   med_int *numele;
105   med_int *nufael;
106   med_booleen inoele, inuele;
107   med_connectivite typ_con;
108   med_geometrie_element typgeo;
109   med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = {MED_POINT1,MED_SEG2, 
110                                                    MED_SEG3,MED_TRIA3,
111                                                    MED_TRIA6,MED_QUAD4,
112                                                    MED_QUAD8,MED_TETRA4,
113                                                    MED_TETRA10,MED_HEXA8,
114                                                    MED_HEXA20,MED_PENTA6,
115                                                    MED_PENTA15,MED_PYRA5,
116                                                    MED_PYRA13};
117   med_int desmai[MED_NBR_GEOMETRIE_MAILLE] = {0,2,3,3,3,4,4,4,4,6,6,5,5,5,5};
118   med_int nmailles[MED_NBR_GEOMETRIE_MAILLE];
119   char nommai[MED_NBR_GEOMETRIE_MAILLE] [MED_TAILLE_NOM+1] = {"MED_POINT1",
120                                                           "MED_SEG2", 
121                                                           "MED_SEG3",
122                                                           "MED_TRIA3",
123                                                           "MED_TRIA6",
124                                                           "MED_QUAD4",
125                                                           "MED_QUAD8",
126                                                           "MED_TETRA4",
127                                                           "MED_TETRA10",
128                                                           "MED_HEXA8",
129                                                           "MED_HEXA20",
130                                                           "MED_PENTA6",
131                                                           "MED_PENTA15",
132                                                           "MED_PYRA5",
133                                                           "MED_PYRA13"};
134   med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] = {MED_TRIA3,MED_TRIA6,
135                                                  MED_QUAD4,MED_QUAD8};
136   med_int desfac[MED_NBR_GEOMETRIE_FACE] = {3,3,4,4};
137   med_int nfaces[MED_NBR_GEOMETRIE_FACE];
138   char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM+1] = {"MED_TRIA3","MED_TRIA6",
139                                                        "MED_QUAD4","MED_QUAD8"};
140   med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] = {MED_SEG2,MED_SEG3};
141   med_int desare[MED_NBR_GEOMETRIE_ARETE] = {2,3};
142   med_int naretes[MED_NBR_GEOMETRIE_ARETE];
143   char nomare[MED_NBR_GEOMETRIE_ARETE] [MED_TAILLE_NOM+1] = {"MED_SEG2","MED_SEG3"};
144   /* familles */
145   med_int nfam;
146   med_int natt,ngro;
147   char *attdes,*gro;
148   med_int *attval,*attide;
149   char nomfam[MED_TAILLE_NOM+1];
150   med_int numfam;
151   char str1[MED_TAILLE_DESC+1];
152   char str2[MED_TAILLE_LNOM+1];
153
154   /****************************************************************************
155   *                      OUVERTURE DU FICHIER EN ECRITURE                      *
156   ****************************************************************************/
157   /*!  char* file2Read = (char*)myFile.c_str();
158   myFileId = MEDouvrir(file2Read,MED_REMP);
159   if (myFileId < 0)
160     {
161       fprintf(stderr,">> ERREUR : ouverture du fichier %s \n",file2Read);
162       exit(EXIT_FAILURE);
163     }
164   */
165   typ_con = MED_NOD;
166   mode_coo = MED_FULL_INTERLACE;
167   numero = myMeshId;
168
169   /****************************************************************************
170   *                       NOMBRES D'OBJETS MED                                *
171   ****************************************************************************/
172   fprintf(stdout,"\n(****************************)\n");
173   fprintf(stdout,"(* INFORMATIONS GENERALES : *)\n");
174   fprintf(stdout,"(****************************)\n");
175
176   /* creation du maillage */
177   mdim=3;
178   //nommaa = QString("Mesh "+myMeshId).latin1();
179   //nommaa = "";
180   //plutot recuperer le nom du maillage dans l'etude
181   if (ret == 0)
182     ret = MEDmaaCr(myFileId,nommaa,mdim);
183   printf("%d\n",ret);
184
185       
186   /* Combien de noeuds ? */
187   nnoe = myMesh->NbNodes();
188   //SCRUTE(nnoe);
189   /* Combien de mailles, faces ou aretes ? */
190   for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
191     nmailles[i]=0;
192
193   SMDS_MeshFacesIterator itFaces(myMesh);
194   Standard_Integer nb_of_nodes, nb_of_faces;
195   nb_of_faces = myMesh->NbFaces();
196   //SCRUTE(nb_of_faces);
197
198   //med_int elem_Id[MED_NBR_GEOMETRIE_FACE][nb_of_faces];
199   vector<int> elem_Id[MED_NBR_GEOMETRIE_MAILLE];
200   //typedef vector<int> Integer_vector;
201   //vector<Integer_vector> elem_Id;
202   //elem_Id.resize(MED_NBR_GEOMETRIE_MAILLE);
203    
204   for (;itFaces.More();itFaces.Next()) {
205     const Handle(SMDS_MeshElement)& elem = itFaces.Value();
206
207     nb_of_nodes = elem->NbNodes();
208
209     switch (nb_of_nodes) {
210     case 3 : {
211       //elem_Id[3][nmailles[3]] = elem->GetID();
212       elem_Id[3].push_back(elem->GetID());
213       nmailles[3]++;
214       break;
215     }
216     case 4 : {
217       //elem_Id[5][nmailles[5]] = elem->GetID();
218       elem_Id[5].push_back(elem->GetID());
219       nmailles[5]++;
220       break;
221     }
222     case 6 : {
223       //elem_Id[4][nmailles[4]] = elem->GetID();
224       elem_Id[4].push_back(elem->GetID());
225       nmailles[4]++;
226       break;
227     }
228     }
229
230   }
231
232   SMDS_MeshVolumesIterator itVolumes(myMesh);
233    
234   for (;itVolumes.More();itVolumes.Next()) {
235     const Handle(SMDS_MeshElement)& elem = itVolumes.Value();
236
237     nb_of_nodes = elem->NbNodes();
238     switch (nb_of_nodes) {
239     case 8 : {
240       //elem_Id[9][nmailles[9]] = elem->GetID();
241       elem_Id[9].push_back(elem->GetID());
242       nmailles[9]++;
243       break;
244     }
245     }
246   }
247
248   /****************************************************************************
249   *                       ECRITURE DES NOEUDS                                  *
250   ****************************************************************************/
251   fprintf(stdout,"\n(************************)\n");
252   fprintf(stdout,"(* NOEUDS DU MAILLAGE : *)\n");
253   fprintf(stdout,"(************************)\n");
254
255   /* Allocations memoires */
256   /* table des coordonnees 
257      profil : (dimension * nombre de noeuds ) */
258   coo = (med_float*) malloc(sizeof(med_float)*nnoe*mdim);
259   /* table  des numeros, des numeros de familles des noeuds
260      profil : (nombre de noeuds) */
261   numnoe = (med_int*) malloc(sizeof(med_int)*nnoe);
262   nufano = (med_int*) malloc(sizeof(med_int)*nnoe);
263   /* table des noms des noeuds 
264      profil : (nnoe*MED_TAILLE_PNOM+1) */
265   nomnoe ="";
266
267   i = 0;
268   SMDS_MeshNodesIterator itNodes(myMesh);
269   for (;itNodes.More();itNodes.Next()) {
270     const Handle(SMDS_MeshElement)& elem = itNodes.Value();
271     const Handle(SMDS_MeshNode)& node = myMesh->GetNode(1,elem);
272  
273     coo[i*3]=node->X();
274     coo[i*3+1]=node->Y();
275     coo[i*3+2]=node->Z();
276     numnoe[i]=node->GetID();
277     nufano[i]=0;
278     i++;
279   }
280     
281   /* ecriture des noeuds : 
282      - coordonnees
283      - noms (optionnel dans un fichier MED) 
284      - numeros (optionnel dans un fichier MED) 
285      - numeros des familles */
286   ret = MEDnoeudsEcr(myFileId,nommaa,mdim,coo,mode_coo,MED_CART,
287                        nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI,
288                        nufano,nnoe,MED_REMP);
289
290   /* liberation memoire */
291   free(coo);
292   //free(nomnoe);
293   free(numnoe);
294   free(nufano);
295
296   /****************************************************************************
297   *                       ECRITURE DES ELEMENTS                                *
298   ****************************************************************************/
299   fprintf(stdout,"\n(**************************)\n");
300   fprintf(stdout,"(* ELEMENTS DU MAILLAGE : *)\n");
301   fprintf(stdout,"(**************************)");
302   //fprintf(Out,"CELLS\n");
303   /* Ecriture des connectivites, noms, numeros des mailles */
304
305   if (ret == 0)
306     for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
307       {
308         if (nmailles[i] > 0 && ret == 0)
309           {
310             MESSAGE ( " Start "<<typmai[i]);
311             /* dimension de la maille */
312             edim = typmai[i] / 100;
313             nsup = 0;
314             if (mdim  == 2 || mdim == 3)
315               if (edim == 1)
316                 nsup = 1;
317             if (mdim == 3)
318               if (edim == 2)
319                 nsup = 1;
320
321             taille = nsup+typmai[i]%100;
322             //taille = typmai[i]%100;
323             
324             /* allocation memoire */
325             connectivite = (med_int*)malloc(sizeof(med_int)*
326                                             taille*nmailles[i]);
327             nomele = (char*)malloc(sizeof(char)*MED_TAILLE_PNOM*
328                                    nmailles[i]+1);
329             numele = (med_int*)malloc(sizeof(med_int)*
330                                       nmailles[i]);
331             nufael = (med_int*)malloc(sizeof(med_int)*
332                                       nmailles[i]);
333             nomele="";
334             nbNodes=typmai[i]%100;
335
336             //penser a mater les (taille-nsup)
337             for (j=0;j<nmailles[i];j++) {
338               myId = elem_Id[i][j];
339               const Handle(SMDS_MeshElement)& elem = myMesh->FindElement(myId);
340               *(numele+j) = myId;
341               //elem_id=*(numele+j);
342               //fprintf(stdout,"%d \n",myId);
343
344               for (k=0; k<nbNodes; k++) {
345                 //*(connectivite+j*(taille-1)+k)=cnx[k];
346                 *(connectivite+j*(taille-nsup)+k) = elem->GetConnection(k+1);
347                 //fprintf(stdout,"%d ",*(connectivite+j*(taille-nsup)+k));
348               }
349               nufael[j]=0;
350               //fprintf(stdout,"\n");
351             }
352
353             /* ecriture des donnĂ©es */
354
355             ret=MEDelementsEcr(myFileId,nommaa,mdim,connectivite,mode_coo,nomele,MED_FAUX,numele,MED_VRAI,nufael,nmailles[i],MED_MAILLE,typmai[i],typ_con,MED_REMP);
356
357             if (ret < 0)
358               MESSAGE(">> ERREUR : lecture des mailles \n");
359
360             /* liberation memoire */
361             free(connectivite);
362             //free(nomele);
363             free(numele);
364             free(nufael);
365             MESSAGE ( " End "<<typmai[i]);
366           }
367       }
368
369   /****************************************************************************
370   *                      FERMETURE DU FICHIER                                 *
371   ****************************************************************************/
372
373             /*!  ret = MEDfermer(myFileId);
374
375   if (ret != 0)
376     fprintf(stderr,">> ERREUR : erreur a la fermeture du fichier %s\n",file2Read);
377             */
378
379 }