Salome HOME
NRI : Add MODULE version info.
[modules/smesh.git] / src / DriverMED / DriverMED_W_SMESHDS_Mesh.cxx
1 using namespace std;
2 #include "DriverMED_W_SMESHDS_Mesh.h"
3 #include "DriverMED_W_SMDS_Mesh.h"
4
5 #include "SMDS_MeshElement.hxx"
6 #include "SMDS_MeshNode.hxx"
7 #include "SMDS_MeshFacesIterator.hxx"
8 #include "SMDS_MeshEdgesIterator.hxx"
9 #include "SMDS_MeshNodesIterator.hxx"
10 #include "SMDS_MeshVolumesIterator.hxx"
11 #include "SMESHDS_SubMesh.hxx"
12 #include "SMDS_MapIteratorOfExtendedMap.hxx"
13 #include "SMDS_MapOfMeshElement.hxx"
14 #include "SMDS_Position.hxx"
15
16 #include <TopExp.hxx>
17 #include <TopExp_Explorer.hxx>
18 #include <TopoDS.hxx>
19 #include <TopoDS_Iterator.hxx>
20 #include <TopoDS_Compound.hxx>
21 #include <TopoDS_CompSolid.hxx>
22 #include <TopoDS_Solid.hxx>
23 #include <TopoDS_Shell.hxx>
24 #include <TopoDS_Face.hxx>
25 #include <TopoDS_Wire.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Vertex.hxx>
28 #include <TopoDS_Shape.hxx>
29 #include <TopTools_MapOfShape.hxx>
30 #include <TColStd_ListIteratorOfListOfInteger.hxx>
31
32
33 #include <map>
34 #include <set>
35 #include <vector>
36 #include "utilities.h"
37
38 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh() {
39   ;
40 }
41
42 DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh() {
43   ;
44 }
45
46 void DriverMED_W_SMESHDS_Mesh::SetMesh(Handle(SMDS_Mesh)& aMesh) {
47   myMesh = aMesh;
48 }
49
50 void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile) {
51   myFile = aFile;
52 }
53
54 void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId) {
55   myFileId = aFileId;
56 }
57
58 void DriverMED_W_SMESHDS_Mesh::SetMeshId(int aMeshId) {
59   myMeshId = aMeshId;
60 }
61
62 void DriverMED_W_SMESHDS_Mesh::Write() {
63
64   string myClass = string("SMDS_Mesh");
65   string myExtension = string("MED");
66
67   DriverMED_W_SMDS_Mesh* myWriter = new DriverMED_W_SMDS_Mesh;
68
69   myWriter->SetMesh(myMesh);
70   //  myWriter->SetFile(myFile);
71   myWriter->SetMeshId(myMeshId);
72   myWriter->SetFileId(myFileId);
73
74   myWriter->Write();
75
76
77 }
78
79 void DriverMED_W_SMESHDS_Mesh::Add() {
80
81   med_err ret = 0;
82   int i,j,k,l;
83   int numero;
84   char message[200];
85   Standard_Boolean ok;
86   /* nombre d'objets MED */
87   char nom_universel[MED_TAILLE_LNOM+1];
88   med_int long_fichier_en_tete;
89   char *fichier_en_tete;
90   char version_hdf[10];
91   char version_med[10];
92   med_int nmaa,mdim,nnoe;
93   med_int nmai[MED_NBR_GEOMETRIE_MAILLE],nfac[MED_NBR_GEOMETRIE_FACE];
94   med_int nare[MED_NBR_GEOMETRIE_ARETE];
95   /* nom du maillage */
96   char nommaa[MED_TAILLE_NOM+1];
97   /* noeuds */
98   med_float *coo;
99   // PN : Initilialisation de nomcoo et unicoo pour lisibilite du maillage
100   char nomcoo[3*MED_TAILLE_PNOM+1]="x       y        z      ";
101   char unicoo[3*MED_TAILLE_PNOM+1]="m       m        m     ";
102   char *nomnoe;
103   med_int *numnoe;
104   med_int *nufano;
105   med_repere rep;
106   med_booleen inonoe,inunoe;
107   med_mode_switch mode_coo;
108   char str[MED_TAILLE_PNOM+1];
109   med_int nbNodes;
110   /* elements */
111   med_int nsup;
112   med_int edim;
113   med_int taille;
114   med_int elem_id,myId;
115   med_int *connectivite;
116   char *nomele;
117   med_int *numele;
118   med_int *nufael;
119   med_booleen inoele, inuele;
120   med_connectivite typ_con;
121   med_geometrie_element typgeo;
122   med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = {MED_POINT1,MED_SEG2,
123                                                             MED_SEG3,MED_TRIA3,
124                                                             MED_TRIA6,MED_QUAD4,
125                                                             MED_QUAD8,MED_TETRA4,
126                                                             MED_TETRA10,MED_HEXA8,
127                                                             MED_HEXA20,MED_PENTA6,
128                                                             MED_PENTA15,MED_PYRA5,
129                                                             MED_PYRA13};
130   med_int desmai[MED_NBR_GEOMETRIE_MAILLE] = {0,2,3,3,3,4,4,4,4,6,6,5,5,5,5};
131   med_int nmailles[MED_NBR_GEOMETRIE_MAILLE];
132   char nommai[MED_NBR_GEOMETRIE_MAILLE] [MED_TAILLE_NOM+1] = {"MED_POINT1",
133                                                               "MED_SEG2",
134                                                               "MED_SEG3",
135                                                               "MED_TRIA3",
136                                                               "MED_TRIA6",
137                                                               "MED_QUAD4",
138                                                               "MED_QUAD8",
139                                                               "MED_TETRA4",
140                                                               "MED_TETRA10",
141                                                               "MED_HEXA8",
142                                                               "MED_HEXA20",
143                                                               "MED_PENTA6",
144                                                               "MED_PENTA15",
145                                                               "MED_PYRA5",
146                                                               "MED_PYRA13"};
147   med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] = {MED_TRIA3,MED_TRIA6,
148                                                           MED_QUAD4,MED_QUAD8};
149   med_int desfac[MED_NBR_GEOMETRIE_FACE] = {3,3,4,4};
150   med_int nfaces[MED_NBR_GEOMETRIE_FACE];
151   char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM+1] = {"MED_TRIA3","MED_TRIA6",
152                                                            "MED_QUAD4","MED_QUAD8"};
153   med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] = {MED_SEG2,MED_SEG3};
154   med_int desare[MED_NBR_GEOMETRIE_ARETE] = {2,3};
155   med_int naretes[MED_NBR_GEOMETRIE_ARETE];
156   char nomare[MED_NBR_GEOMETRIE_ARETE] [MED_TAILLE_NOM+1] = {"MED_SEG2","MED_SEG3"};
157
158   typ_con = MED_NOD;
159   mode_coo = MED_FULL_INTERLACE;
160   numero = myMeshId;
161
162   //---- provisoire : switch pour ecrire les familles de mailles
163   int besoinfamilledemaille=1;
164   //---- provisoire : switch pour ecrire les familles de mailles
165
166   /****************************************************************************
167    *                      OUVERTURE DU FICHIER EN ECRITURE                    *
168    ****************************************************************************/
169   char* file2Read = (char*)myFile.c_str();
170
171   MESSAGE ( " file2Read " << file2Read )
172
173     myFileId = MEDouvrir(file2Read,MED_REMP);
174   if (myFileId < 0)
175     {
176       fprintf(stderr,">> ERREUR : ouverture du fichier %s \n",file2Read);
177       exit(EXIT_FAILURE);
178     }
179
180   /****************************************************************************
181    *                       NOMBRES D'OBJETS MED                               *
182    ****************************************************************************/
183   fprintf(stdout,"\n(****************************)\n");
184   fprintf(stdout,"(* INFORMATIONS GENERALES : *)\n");
185   fprintf(stdout,"(****************************)\n");
186
187   /* calcul de la dimension */
188   mdim=2;
189   double epsilon=0.00001;
190   double nodeRefX;
191   double nodeRefY;
192   double nodeRefZ;
193
194   bool dimX = true;
195   bool dimY = true;
196   bool dimZ = true;
197
198   SMDS_MeshNodesIterator myItNodes(myMesh);
199   int inode = 0;
200   for (;myItNodes.More();myItNodes.Next()) {
201     const Handle(SMDS_MeshElement)& elem = myItNodes.Value();
202     const Handle(SMDS_MeshNode)& node = myMesh->GetNode(1,elem);
203     if ( inode == 0 ) {
204       nodeRefX = fabs(node->X());
205       nodeRefY = fabs(node->Y());
206       nodeRefZ = fabs(node->Z());
207     }
208     SCRUTE( inode );
209     SCRUTE( nodeRefX );
210     SCRUTE( nodeRefY );
211     SCRUTE( nodeRefZ );
212
213     if ( inode !=0 ) {
214       if ( (fabs(fabs(node->X()) - nodeRefX) > epsilon ) && dimX )
215         dimX = false;
216       if ( (fabs(fabs(node->Y()) - nodeRefY) > epsilon ) && dimY )
217         dimY = false;
218       if ( (fabs(fabs(node->Z()) - nodeRefZ) > epsilon ) && dimZ )
219         dimZ = false;
220     }
221     if ( !dimX && !dimY && !dimZ ) {
222       mdim = 3;
223       break;
224     }
225     inode++;
226   }
227
228   if ( mdim != 3 ) {
229     if ( dimX && dimY && dimZ )
230       mdim = 0;
231     else if ( !dimX ) {
232       if ( dimY && dimZ )
233         mdim = 1;
234       else if (( dimY && !dimZ ) || ( !dimY && dimZ ) )
235         mdim = 2;
236     } else if ( !dimY ) {
237       if ( dimX && dimZ )
238         mdim = 1;
239       else if (( dimX && !dimZ ) || ( !dimX && dimZ ) )
240         mdim = 2;
241     } else if ( !dimZ ) {
242       if ( dimY && dimX )
243         mdim = 1;
244       else if (( dimY && !dimX ) || ( !dimY && dimX ) )
245         mdim = 2;
246     }
247   }
248
249   MESSAGE ( " mdim " << mdim );
250
251   /* creation du maillage */
252   //mdim=3;
253   sprintf(nommaa,"Mesh %d",numero);
254   SCRUTE(nommaa);
255   ret = MEDmaaCr(myFileId,nommaa,mdim);
256
257   ASSERT(ret == 0);
258   SCRUTE( ret );
259
260   /* Combien de noeuds ? */
261   nnoe = myMesh->NbNodes();
262   //SCRUTE(nnoe);
263   /* Combien de mailles, faces ou aretes ? */
264   for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
265     nmailles[i]=0;
266
267   Standard_Integer nb_of_nodes, nb_of_faces, nb_of_edges;
268   vector<int> elem_Id[MED_NBR_GEOMETRIE_MAILLE];
269
270   SMDS_MeshEdgesIterator itEdges(myMesh);
271   nb_of_edges = myMesh->NbEdges();
272   for (;itEdges.More();itEdges.Next()) {
273     const Handle(SMDS_MeshElement)& elem = itEdges.Value();
274
275     nb_of_nodes = elem->NbNodes();
276
277     switch (nb_of_nodes) {
278     case 2 : {
279       elem_Id[1].push_back(elem->GetID());
280       nmailles[1]++;
281       break;
282     }
283     case 3 : {
284       elem_Id[2].push_back(elem->GetID());
285       nmailles[2]++;
286       break;
287     }
288     }
289   }
290
291
292   SMDS_MeshFacesIterator itFaces(myMesh);
293   nb_of_faces = myMesh->NbFaces();
294   for (;itFaces.More();itFaces.Next()) {
295     const Handle(SMDS_MeshElement)& elem = itFaces.Value();
296
297     nb_of_nodes = elem->NbNodes();
298
299     switch (nb_of_nodes) {
300     case 3 : {
301       elem_Id[3].push_back(elem->GetID());
302       nmailles[3]++;
303       break;
304     }
305     case 4 : {
306       elem_Id[5].push_back(elem->GetID());
307       nmailles[5]++;
308       break;
309     }
310     case 6 : {
311       elem_Id[4].push_back(elem->GetID());
312       nmailles[4]++;
313       break;
314     }
315     }
316
317   }
318
319   SMDS_MeshVolumesIterator itVolumes(myMesh);
320   for (;itVolumes.More();itVolumes.Next()) {
321     const Handle(SMDS_MeshElement)& elem = itVolumes.Value();
322
323     nb_of_nodes = elem->NbNodes();
324     switch (nb_of_nodes) {
325     case 8 : {
326       elem_Id[9].push_back(elem->GetID());
327       nmailles[9]++;
328       break;
329     }
330     }
331   }
332
333
334
335   /****************************************************************************
336    *                       ECRITURE DES NOEUDS                                *
337    ****************************************************************************/
338   fprintf(stdout,"\n(************************)\n");
339   fprintf(stdout,"(* NOEUDS DU MAILLAGE : *)\n");
340   fprintf(stdout,"(************************)\n");
341
342   /* Allocations memoires */
343   /* table des coordonnees
344      profil : (dimension * nombre de noeuds ) */
345   coo = (med_float*) malloc(sizeof(med_float)*nnoe*mdim);
346   /* table  des numeros, des numeros de familles des noeuds
347      profil : (nombre de noeuds) */
348   numnoe = (med_int*) malloc(sizeof(med_int)*nnoe);
349   nufano = (med_int*) malloc(sizeof(med_int)*nnoe);
350   /* table des noms des noeuds
351      profil : (nnoe*MED_TAILLE_PNOM+1) */
352   nomnoe ="";
353
354   /* PN  pour aster, il faut une famille 0 pour les noeuds et une autre pour les elements*/
355   /* PN : Creation de la famille 0 */
356   char * nomfam="FAMILLE_0";
357   char *attdes="";
358   char *gro=0;
359   med_int ngro=0;
360   med_int natt=1;
361   med_int attide = 0;
362   med_int attval=0;
363   med_int numfam = 0;
364   med_int attvalabs=1;
365   ret = MEDfamCr(myFileId,nommaa,nomfam,numfam, &attide,&attval,attdes,natt,gro,ngro);
366   ASSERT(ret == 0);
367
368
369   /* PN : FIN Creation de la famille 0 */
370
371   map < int, int > mapNoeud;
372   typedef pair<set<int>::iterator, bool> IsFamily;
373   int nbFamillesNoeud;
374
375
376   i = 0;
377   set<int> FamilySet;
378   nbFamillesNoeud = 0;
379   int verifienbnoeuds = 0;
380   med_int* rien=0;
381
382   SMDS_MeshNodesIterator itNodes(myMesh);
383   for (;itNodes.More();itNodes.Next())
384     {
385       const Handle(SMDS_MeshElement)& elem = itNodes.Value();
386       const Handle(SMDS_MeshNode)& node = myMesh->GetNode(1,elem);
387
388       if(mdim==3){
389         coo[i*3]=node->X();
390         coo[i*3+1]=node->Y();
391         coo[i*3+2]=node->Z();
392       } else {
393         if ( dimX ) {
394           coo[i*2]=node->Y();
395           coo[i*2+1]=node->Z();
396         } 
397         if ( dimY ) {
398           coo[i*2]=node->X();
399           coo[i*2+1]=node->Z();
400         } 
401         if ( dimZ ) {
402           coo[i*2]=node->X();
403           coo[i*2+1]=node->Y();
404         } 
405       }
406       mapNoeud[node->GetID()] = i+1;
407
408       // renvoie 0 pour les noeuds internes du volume
409       int numfamille=node->GetPosition()->GetShapeId();
410       nufano[i]=numfamille;
411
412       //SCRUTE(i);
413       //SCRUTE(nufano[i]);
414       //SCRUTE(coo[i*3]);
415       //SCRUTE(coo[i*3+1]);
416       //SCRUTE(coo[i*3+2]);
417       if ( nufano[i] != 0 )
418         {
419           IsFamily deja = FamilySet.insert(nufano[i]); // insert if new, or gives existant
420           if (deja.second)                                    // actually inserted
421             {
422               char famille[MED_TAILLE_NOM+1];
423               sprintf(famille,"F%d",nufano[i]);
424               //              CreateFamily(strdup(nommaa),strdup(famille),nufano[i],attvalabs++);
425               attvalabs++;
426               CreateFamily(strdup(nommaa),strdup(famille),nufano[i],numfamille);
427               //MESSAGE("---famille-noeud--- "<<nbFamillesNoeud<<" "<<nufano[i]);
428               nbFamillesNoeud++;
429             }
430         }
431
432       i++;
433       verifienbnoeuds ++;
434     }
435   ret = MEDnoeudsEcr(myFileId,nommaa,mdim,coo,mode_coo,MED_CART,
436                      nomcoo,unicoo,nomnoe,MED_FAUX,rien,MED_FAUX,
437                      nufano,nnoe,MED_REMP);
438   ASSERT(ret == 0);
439   MESSAGE("--- Creation de " << verifienbnoeuds << " noeuds");
440   ASSERT(verifienbnoeuds == nnoe);
441   MESSAGE("--- Creation de " << nbFamillesNoeud << " familles de noeuds");
442
443   /* liberation memoire */
444   free(coo);
445   free(numnoe);
446   free(nufano);
447
448   /****************************************************************************
449    *                       ECRITURE DES ELEMENTS                              *
450    ****************************************************************************/
451   fprintf(stdout,"\n(**************************)\n");
452   fprintf(stdout,"(* ELEMENTS DU MAILLAGE : *)\n");
453   fprintf(stdout,"(**************************)\n");
454
455   /* Ecriture des connectivites, noms, numeros des mailles */
456
457   if (ret == 0)
458     {
459       int nbFamillesElts =0;
460       Handle(SMESHDS_Mesh) mySMESHDSMesh = Handle(SMESHDS_Mesh)::DownCast(myMesh);
461       TopTools_IndexedMapOfShape myIndexToShape;
462       TopExp::MapShapes(mySMESHDSMesh->ShapeToMesh(),myIndexToShape);
463
464       map < int, int > mapFamille;
465
466       if (besoinfamilledemaille == 1)
467         {
468           int t;
469           for (t =1; t <= myIndexToShape.Extent(); t++)
470             {
471               const TopoDS_Shape S = myIndexToShape(t);
472               if (mySMESHDSMesh->HasMeshElements(S))
473                 {
474                   //MESSAGE ("********* Traitement de la Famille "<<-t);
475                 
476                   Handle(SMESHDS_SubMesh) SM = mySMESHDSMesh->MeshElements(S);
477                   const TColStd_ListOfInteger& indElt = SM->GetIDElements();
478                   TColStd_ListIteratorOfListOfInteger ite(indElt);
479                 
480                   bool plein=false;
481                   for (; ite.More(); ite.Next())
482                     {
483                       int eltId = ite.Value();
484                       mapFamille [eltId] = - t;
485                       plein=true;
486                     }
487                   if (plein)
488                     {
489                       nbFamillesElts++;
490                       char famille[MED_TAILLE_NOM+1];
491                       sprintf(famille,"E%d",t);
492                       CreateFamily(strdup(nommaa),strdup(famille),-t,attvalabs++);
493                     }
494                 }
495             }
496         }
497
498       int indice=1;
499       for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++)
500         {
501           if (nmailles[i] > 0 && ret == 0)
502             {
503               MESSAGE ( " Start "<<typmai[i]);
504         
505               /* dimension de la maille */
506               edim = typmai[i] / 100;
507               nsup = 0;
508               if (mdim  == 2 || mdim == 3)
509                 if (edim == 1) nsup = 1;
510               if (mdim == 3)
511                 if (edim == 2) nsup = 1;
512               //SCRUTE(nsup);
513         
514               taille = nsup+typmai[i]%100;
515               //SCRUTE(taille);
516         
517               /* allocation memoire */
518               connectivite = (med_int*)malloc(sizeof(med_int)* taille*nmailles[i]);
519               nomele = (char*)malloc(sizeof(char)*MED_TAILLE_PNOM* nmailles[i]+1);
520               numele = (med_int*)malloc(sizeof(med_int)* nmailles[i]);
521               nufael = (med_int*)malloc(sizeof(med_int)* nmailles[i]);
522               nomele="";
523               nbNodes=typmai[i]%100;
524         
525               for (j=0;j<nmailles[i];j++)
526                 {
527                   myId = elem_Id[i][j];
528                   const Handle(SMDS_MeshElement)& elem = myMesh->FindElement(myId);
529                   //*(numele+j) = myId;
530                   *(numele+j) = indice ++;
531                 
532                   for (k=0; k<nbNodes; k++)
533                     {
534                       *(connectivite+j*taille+k) = mapNoeud[elem->GetConnection(k+1)];
535                       //SCRUTE(*(connectivite+j*taille+k));
536                     }
537                   if (nsup) *(connectivite+j*taille + nbNodes) = 0;
538                 
539                   if (besoinfamilledemaille == 1)
540                     {
541                       if (mapFamille.find(myId)!=mapFamille.end())
542                         {
543                           nufael[j]=mapFamille[myId];
544                         }
545                       else
546                         {
547                           nufael[j]=0;
548                         }
549                     }
550                   else
551                     {
552                       nufael[j]=0;
553                     }
554                 
555                   //SCRUTE(myId);
556                   //SCRUTE(j);
557                   //SCRUTE(nufael[j]);
558                 }
559         
560               /* ecriture des donnĂ©es */
561                 
562                     med_int* rien=0;
563                     ret=MEDelementsEcr( myFileId,nommaa,mdim,connectivite,mode_coo,nomele,MED_FAUX,numele,
564                                         MED_VRAI,nufael,nmailles[i],MED_MAILLE,typmai[i],typ_con,MED_REMP);
565                     ASSERT(ret == 0);
566                     //SCRUTE(ret);
567                 
568                     if (ret < 0) MESSAGE(">> ERREUR : ecriture des mailles \n");
569                 
570                     /* liberation memoire */
571                     free(connectivite);
572                     free(numele);
573                     free(nufael);
574                     MESSAGE ( " End "<<typmai[i]);
575             }
576       };
577           MESSAGE("--- Creation de " << nbFamillesElts << " familles d elements");
578
579     }
580
581       /****************************************************************************
582       *                      FERMETURE DU FICHIER                                *
583       ****************************************************************************/
584
585       ret = MEDfermer(myFileId);
586
587       if (ret != 0)
588         fprintf(stderr,">> ERREUR : erreur a la fermeture du fichier %s\n",file2Read);
589       MESSAGE ("fichier ferme");
590
591
592 }
593
594 void DriverMED_W_SMESHDS_Mesh::CreateFamily(char* nommaa, char* famille, int i,med_int k) {
595
596   med_int ngro=0;
597   med_int natt;
598
599   natt=1;
600   char attdes[MED_TAILLE_DESC+1];
601   char gro[MED_TAILLE_LNOM+1];
602   char fam2[MED_TAILLE_LNOM+1];
603
604   strcpy(attdes,"");
605   strcpy(gro,"");
606   strcpy(fam2,famille);
607
608   med_int * attide=new med_int[1];
609   med_int * attval=new med_int[1];
610   attide[0] = k;
611   attval[0] = k;
612
613
614   //MESSAGE("-------- Creation de la Famille : "<< famille << "numero " << i << " --------------");
615   med_int ret = MEDfamCr(myFileId, nommaa, fam2, i, attide, attval, attdes, natt, gro, ngro);
616   ASSERT(ret==0);
617   delete [] attide;
618   delete [] attval;
619
620 }
621
622
623