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