Salome HOME
ab69867400fad4c8de9164ab96e6fab83130a382
[plugins/ghs3dprlplugin.git] / src / tepal2med / tepal2med.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // ---
21 // File   : tepal2med.cxx
22 // Author : Christian VAN WAMBEKE (CEA) 
23 // ---
24 //
25 /*
26 ** prog principal de ghs3dprl
27 */
28
29 #include <stdio.h> /* printf clrscr fopen fread fwrite fclose */
30 #include <string>
31 #include <cstring>
32 #include <cstdlib>
33 #include <iostream>
34 #include <sstream>
35 #include <fstream>
36 #include <vector>
37 #ifndef WIN32
38 #include <unistd.h>
39 #endif
40
41 #include <qstring.h>
42
43 #include <QXmlSimpleReader>
44 #include <QXmlInputSource>
45 #include <QApplication>
46
47 #include "ghs3dprl_msg_parser.h"
48 #include "dlg_ghs3dmain.h"
49
50 #ifdef WIN32
51 #include <io.h>
52 #include <windows.h>
53 #define F_OK 0
54 #endif
55
56 //#include "MEDMEM_Exception.hxx"
57 //#include "MEDMEM_define.hxx"
58
59 extern "C" {
60 #include <med.h>
61 //#include <med_config.h>
62 //#include <med_utils.h>
63 //#include <med_misc.h>
64 }
65
66 //************************************
67 med_idt ouvre_fichier_MED(char *fichier,int verbose)
68 {
69   med_idt fid = 0;
70   med_err ret = 0;
71   med_int majeur,mineur,release;
72
73   /* on regarde si le fichier existe */
74   ret = (int) access(fichier,F_OK);
75   if (ret < 0) return fid;
76
77   /* on regarde s'il s'agit d'un fichier au format HDF5 */
78   med_bool hdfok,medok;
79   ret = MEDfileCompatibility(fichier,&hdfok,&medok);
80   if (ret < 0){
81      std::cerr<<"File "<<fichier<<" not MED or HDF V5 formatted\n";
82      return fid;
83   }
84
85   /* Quelle version de MED est utilise par mdump ? */
86   MEDlibraryNumVersion(&majeur,&mineur,&release);
87   if (verbose>0)fprintf(stdout,"\nReading %s with MED V%d.%d.%d",
88                         fichier,majeur,mineur,release);
89
90   /* Ouverture du fichier MED en lecture seule */
91   fid = MEDfileOpen(fichier,MED_ACC_RDONLY);
92   if (ret < 0) return fid;
93
94   MEDfileNumVersionRd(fid, &majeur, &mineur, &release);
95   if (majeur < 2 || majeur == 2 && mineur < 2) {
96     fprintf(stderr,"File %s from MED V%d.%d.%d not assumed\n",
97                    fichier,majeur,mineur,release);
98     //" version est ant�ieure �la version 2.2";
99     ret = MEDfileClose(fid);
100     fid=0; }
101   else {
102     if (verbose>0)fprintf(stdout,", file from MED V%d.%d.%d\n",majeur,mineur,release); }
103
104   return fid;
105 }
106
107 //************************************
108 bool ReadFileMED(QString nomfilemed,ghs3dprl_mesh_wrap *mymailw)
109 {
110    med_err ret;
111    med_idt fid=0;
112    med_int i,j,sdim,mdim,nmaa,edim,majeur_lu,mineur_lu,release_lu,nprofils,nstep;
113    med_mesh_type type_maillage;
114    char dtunit[MED_SNAME_SIZE+1];
115    char axisname[MED_SNAME_SIZE+1];
116    char axisunit[MED_SNAME_SIZE*3+1];
117    med_sorting_type sortingtype;
118    med_axis_type axistype;
119    int numero=1;
120    QString key,tmp;
121    med_bool chan;
122    med_bool tran;
123    
124    //version qt3
125    char* chaine = (char*)malloc((nomfilemed.length()+1)*sizeof(char));
126    strncpy(chaine,nomfilemed.toLatin1().constData(),nomfilemed.length()+1);
127    //std::cout<<"*** ReadFileMED *** "<<chaine<<"\n";
128
129    fid=ouvre_fichier_MED(chaine,mymailw->verbose);
130    free(chaine);
131    if (fid == 0) {
132       std::cerr<<"Problem opening file "<<nomfilemed.toLatin1().constData()<<"\n";
133       return false;
134    }
135
136    nmaa = MEDnMesh(fid);
137    if (nmaa <= 0){
138       std::cerr<<"No meshes in "<<nomfilemed.toLatin1().constData()<<"\n";
139       ret = MEDfileClose(fid);
140       return false;
141    }
142    if (nmaa > 1) std::cout<<"More than one mesh in "<<nomfilemed.toLatin1().constData()<<", first one taken\n";
143    ret = MEDmeshInfo(fid,numero,mymailw->nommaa,&sdim,&mdim,&type_maillage,mymailw->maillage_description,
144                         dtunit,&sortingtype,&nstep,&axistype,axisname,axisunit);
145    if (ret < 0){
146       std::cerr<<"Problem MEDmeshInfo in "<<nomfilemed.toLatin1().constData()<<"\n";
147       ret = MEDfileClose(fid);
148       return false;
149    }
150    if (mdim != 3){
151       std::cerr<<"Problem mesh dimension should be 3: "<<mdim<<"\n";
152       ret = MEDfileClose(fid);
153       return false;
154    }
155    if (sdim != 3){
156       std::cerr<<"Problem space dimension should be 3: "<<sdim<<"\n";
157       ret = MEDfileClose(fid);
158       return false;
159    }
160    if (type_maillage != MED_UNSTRUCTURED_MESH){
161       std::cerr<<"Problem type mesh should be MED_NON_STRUCTURE: "<<type_maillage<<std::endl;
162       ret = MEDfileClose(fid);
163       return false;
164    }
165
166    //lecture nb de noeuds
167    //cf med-3.0.0_install/share/doc/html/maillage_utilisateur.html
168    med_int nnoe=MEDmeshnEntity(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
169       MED_NODE,MED_NO_GEOTYPE,MED_COORDINATE,MED_NO_CMODE,&chan,&tran);
170               //(med_geometrie_element)0,(med_connectivite)0);
171    if (nnoe<1){
172       std::cerr<<"Problem number of Vertices < 1\n";
173       ret = MEDfileClose(fid);
174       return false;
175    }
176
177    //nombre d'objets MED : mailles, faces, aretes , ... 
178    med_int nmailles[MED_N_CELL_GEO],nbtria3;
179    med_int nfaces[MED_N_FACE_GEO];
180    med_int naretes[MED_N_EDGE_FIXED_GEO],nbseg2;
181    //med_int nmailles[MED_NBR_GEOMETRIE_MAILLE],nbtria3;
182    //med_int nfaces[MED_NBR_GEOMETRIE_FACE];
183    //med_int naretes[MED_NBR_GEOMETRIE_ARETE],nbseg2;
184    //polygones et polyedres familles equivalences joints
185    med_int nmpolygones,npolyedres,nfpolygones,nfam,nequ,njnt;
186
187    //Combien de mailles, faces ou aretes pour chaque type geometrique ?
188    /*for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++){
189       nmailles[i]=MEDnEntMaa(fid,mymailw->nommaa,MED_CONN,MED_MAILLE,typmai[i],typ_con);
190       //lecture_nombre_mailles_standards(fid,nommaa,typmai[i],typ_con,i);
191       if (mymailw->verbose>6) std::cout<<"NumberOf"<<nommai[i]<<"="<<nmailles[i]<<std::endl;
192    }*/
193    
194    nbtria3=MEDmeshnEntity(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
195       MED_CELL,MED_TRIA3,MED_CONNECTIVITY,MED_NODAL,&chan,&tran);
196    nbseg2=MEDmeshnEntity(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
197       MED_CELL,MED_SEG2,MED_CONNECTIVITY,MED_NODAL,&chan,&tran);
198
199    //combien de familles ?
200    nfam=MEDnFamily(fid,mymailw->nommaa);
201    if (mymailw->verbose>2) {
202       std::cout<<"\nNumberOfFamilies="<<nfam<<std::endl;
203       std::cout<<"NumberOfVertices="<<nnoe<<std::endl;
204       std::cout<<"NumberOfMED_SEG2="<<nbseg2<<std::endl;
205       std::cout<<"NumberOfMED_TRIA3="<<nbtria3<<"\n\n";
206    }
207    if (nbtria3<3){
208       std::cerr<<"Problem number of MED_TRIA3 < 3, not a skin of a volume\n";
209       ret = MEDfileClose(fid);
210       return false;
211    }
212
213 med_int ifamdelete=0,idelete;
214 std::vector<med_int> famdelete = std::vector<med_int>(nfam);
215 {
216   med_int ngro;
217   char *gro;
218   char nomfam[MED_NAME_SIZE+1];
219   med_int numfam;
220   char str1[MED_COMMENT_SIZE+1];
221   char str2[MED_LNAME_SIZE+1];
222   med_err ret = 0;
223   
224   for (i=0;i<nfam;i++) famdelete[i]=0;
225   for (i=0;i<nfam;i++) {
226
227     //nombre de groupes
228     ngro = MEDnFamilyGroup(fid,mymailw->nommaa,i+1);
229     if (ngro < 0){
230        std::cerr<<"Problem reading number of groups of family\n";
231        continue;
232     }
233
234     //atributs obsolete MED3
235     //allocation memoire par exces
236     gro = (char*) malloc(MED_LNAME_SIZE*(ngro+1));
237     
238     ret = MEDfamilyInfo(fid,mymailw->nommaa,i+1,nomfam,&numfam,gro);
239     if (ret < 0){
240        std::cerr<<"Problem reading informations of family\n";
241        continue;
242     }
243
244     if (mymailw->verbose>8) {
245      std::cout<<"Family "<<numfam<<" have "<<ngro<<" groups\n";
246      //affichage des resultats
247      for (j=0;j<ngro;j++) {
248       if (j==0) std::cout<<"  Groups :\n";
249       strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
250       str2[MED_LNAME_SIZE] = '\0';
251       fprintf(stdout,"    name = %s\n",str2);
252      }
253      if (i==nfam-1) std::cout<<std::endl;
254     }
255     QString sfam,sgro;
256     sfam=sfam.sprintf("%d",numfam);
257     idelete=0;
258     for (j=0;j<ngro;j++){
259        strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
260        str2[MED_LNAME_SIZE]='\0';
261        sgro=str2;
262        if (sgro.contains(mymailw->deletegroups)>0) {
263           //std::cout<<"idelete++ "<<sgro<<std::endl;
264           idelete++;
265        }
266     }
267
268     if (idelete==ngro && ngro>0) { //only delete family whith all delete groups
269        //std::cout<<"famdelete++ "<<numfam<<" "<<ifamdelete<<" "<<ngro<<std::endl;
270        famdelete[ifamdelete]=numfam;
271        ifamdelete++;
272     }
273
274     else {
275      for (j=0;j<ngro;j++){
276        strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
277        str2[MED_LNAME_SIZE]='\0';
278        sgro=str2;
279        QRegExp qgroup=QRegExp("Group_Of_All",Qt::CaseSensitive,QRegExp::RegExp);
280        if (sgro.contains(mymailw->deletegroups)==0){
281           if (sgro.contains(qgroup)>0) {
282              sgro="Skin_"+sgro; //pas sur que ce soit pertinent
283           }
284           if (mymailw->verbose>8) std::cout<<"families.add("<<sfam.toLatin1().constData()<<
285                                         ","<<sgro.toLatin1().constData()<<")\n";
286           mymailw->families.add(sfam,sgro);
287        }
288        else {
289           //sgro="Skin_"+sgro; //pas sur que ce soit pertinent
290           //std::cout<<"--deletegroups matches \""<<sfam<<","<<sgro<<"\"\n";
291           if (mymailw->verbose>3) std::cout<<"--deletegroups matches \""<<
292                                         sgro.toLatin1().constData()<<
293                                         "\" in family "<<numfam<<std::endl;
294        }
295      }
296     }
297     
298     /*for (j=0;j<ngro;j++){
299        strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
300        str2[MED_LNAME_SIZE]='\0';
301        sgro=str2;
302        //std::cout<<"families.add("<<sfam<<","<<sgro<<")\n";
303        if (sgro.contains(mymailw->deletegroups)==0){
304           //sgro="Skin_"+sgro; //pas sur que ce soit pertinent
305           std::cout<<"families.add("<<sfam<<","<<sgro<<")\n";
306           mymailw->families.add(sfam,sgro);
307        }
308        else {
309           std::cout<<"--deletegroups matches \""<<sgro<<"\"\n";
310           famdelete[ifamdelete]=numfam
311           ifamdelete++;
312        }
313     }*/
314
315     //on libere la memoire
316     free(gro);
317   }
318 }
319
320 //std::cout<<"famdelete"; for (j=0;j<ifamdelete;j++) std::cout<<" "<<famdelete[j]; std::cout<<std::endl;
321
322 if (mymailw->verbose>3){
323    std::cout<<"\nFamiliesAndGroupsOf "<<nomfilemed.toLatin1().constData()<<std::endl;
324    mymailw->families.write();
325 }
326    /* Allocations memoires */
327    /* table des coordonnees profil : (space dimension * nombre de noeuds ) */
328    med_float *coo=new med_float[nnoe*sdim];
329    /* table des numeros de familles des noeuds profil : (nombre de noeuds) */
330    med_int *famnodesskin=new med_int[nnoe];
331    med_int *pfltab=new med_int[1]; //inutilise car on lit tout 
332    //lecture des noeuds : coordonnees
333    ret=MEDmeshNodeCoordinateRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_FULL_INTERLACE,coo);
334           //mdim,coo,mode_coo,MED_ALL,pfltab,0,&rep,mymailw->nomcoo,mymailw->unicoo);
335    if (ret < 0){
336       std::cerr<<"Problem reading nodes\n";
337       ret = MEDfileClose(fid);
338       //return false;
339    }
340    ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_NODE,MED_NONE,famnodesskin);
341       //famnodesskin,nnoe,MED_NOEUD,(med_geometrie_element) 0);
342    if (ret < 0){
343       std::cerr<<"Problem reading families of nodes\n";
344       ret = MEDfileClose(fid);
345       return false;
346    }
347    if (mymailw->verbose>9) {
348      std::cout<<"\nVertices: no x y z family\n";
349      for (i=0;i<nnoe*mdim;i=i+3) {
350       fprintf(stdout,"%5d %13.5e %13.5e %13.5e %5d \n",
351           (i/3+1), coo[i], coo[i+1], coo[i+2], famnodesskin[i/3]);
352      } 
353      std::cout<<std::endl;
354    }
355
356    med_int *conn2=new med_int[nbseg2*2];
357    ret=MEDmeshElementConnectivityRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
358            MED_CELL,MED_SEG2,MED_NODAL,MED_FULL_INTERLACE,conn2);
359             //mdim,conn2,mode_coo,pfltab,0,MED_MAILLE,MED_SEG2,MED_NOD);
360    if (ret < 0){
361       std::cerr<<"Problem reading MED_SEG2\n";
362       ret = MEDfileClose(fid);
363       //return false;
364    }
365    med_int *famseg2skin=new med_int[nbseg2];
366    ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_SEG2,famseg2skin);
367       //MEDfamLire(fid,mymailw->nommaa,famseg2skin,nbseg2,MED_MAILLE,MED_SEG2);
368    if (ret < 0){
369       std::cerr<<"Problem reading families of MED_SEG2\n";
370       ret = MEDfileClose(fid);
371       return false;
372    }
373    if (mymailw->verbose>9) {
374      std::cout<<"\nConnectivity MED_SEG2: no node1 node2 family\n";
375      for (i=0;i<nbseg2*2;i=i+2) {
376       fprintf(stdout,"%5d %5d %5d %5d \n",
377           (i/2+1), conn2[i], conn2[i+1], famseg2skin[i/2]);
378      } 
379      std::cout<<std::endl;
380    }
381
382    med_int *conn3=new med_int[nbtria3*3];
383    ret=MEDmeshElementConnectivityRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
384            MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,pfltab);
385            //MEDconnLire(fid,mymailw->nommaa,mdim,conn3,mode_coo,pfltab,0,MED_MAILLE,MED_TRIA3,MED_NOD);
386    if (ret < 0){
387       std::cerr<<"Problem reading MED_TRIA3\n";
388       ret = MEDfileClose(fid);
389       //return false;
390    }
391    med_int *famtria3skin=new med_int[nbtria3];
392    ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,famtria3skin);
393         //MEDfamLire(fid,mymailw->nommaa,famtria3skin,nbtria3,MED_MAILLE,MED_TRIA3);
394    if (ret < 0){
395       std::cerr<<"Problem reading families of MED_TRIA3\n";
396       ret = MEDfileClose(fid);
397       return false;
398    }
399    if (mymailw->verbose>9) {
400      std::cout<<"\nConnectivity MED_TRIA3: no node1 node2 node3 family\n";
401      for (i=0;i<nbtria3*3;i=i+3) {
402       fprintf(stdout,"%5d %5d %5d %5d %5d \n",
403           (i/3+1), conn3[i], conn3[i+1], conn3[i+2], famtria3skin[i/3]);
404      } 
405      std::cout<<std::endl;
406    }
407
408   /*liberation memoire?
409   delete[] coo;
410   delete[] nomnoe;
411   delete[] numnoe;
412   delete[] nufano;*/
413
414   if (ifamdelete>0) {
415    //std::cout<<"!!!!!!!!nodes "<<famnodesskin[0]<<" "<<nnoe<<famdelete[1]<<std::endl;
416    for (i=0;i<nnoe;i++) {
417     for (j=0;j<ifamdelete;j++) {
418       if (famnodesskin[i]==famdelete[j]) {
419        //std::cout<<"nodes "<<famnodesskin[i]<<" "<<i<<" "<<famdelete[j]<<std::endl;
420        famnodesskin[i]=0; }
421     }
422    }
423    for (i=0;i<nbseg2;i++) {
424     for (j=0;j<ifamdelete;j++) {
425       if (famseg2skin[i]==famdelete[j]) famseg2skin[i]=0;
426     }
427    }
428    for (i=0;i<nbtria3;i++) {
429     for (j=0;j<ifamdelete;j++) {
430       if (famtria3skin[i]==famdelete[j]) famtria3skin[i]=0;
431     }
432    }
433   }
434    //stocks data for future use 
435    CVWtab *montab;
436    bool ok;
437
438    montab=new CVWtab(nnoe*mdim,coo);
439    tmp="SKIN_VERTICES_COORDINATES";
440    ok=mymailw->insert_key(tmp,montab);
441
442    montab=new CVWtab(nnoe,famnodesskin);
443    tmp="SKIN_VERTICES_FAMILIES";
444    ok=mymailw->insert_key(tmp,montab);
445    
446    montab=new CVWtab(nbseg2*2,conn2);
447    tmp="SKIN_SEG2_CONNECTIVITIES";
448    ok=mymailw->insert_key(tmp,montab);
449
450    montab=new CVWtab(nbtria3,famseg2skin);
451    tmp="SKIN_SEG2_FAMILIES";
452    ok=mymailw->insert_key(tmp,montab);
453
454    montab=new CVWtab(nbtria3*3,conn3);
455    tmp="SKIN_TRIA3_CONNECTIVITIES";
456    ok=mymailw->insert_key(tmp,montab);
457
458    montab=new CVWtab(nbtria3,famtria3skin);
459    tmp="SKIN_TRIA3_FAMILIES";
460    ok=mymailw->insert_key(tmp,montab);
461
462    //if (mymailw->verbose>6) ok=mymailw->list_keys_mesh_wrap();
463
464    ret = MEDfileClose(fid);
465    if (ret < 0){
466       std::cerr<<"Problem closing "<<nomfilemed.toLatin1().constData()<<"\n";
467       return false;
468    }
469    return true;
470 }
471
472 /*
473 //************************************
474 string char2string(char *d, int lg)
475 {
476    string fin;
477    for (int i=0;i<lg-1;i++){
478        fin=fin+d[i];
479    }
480    return fin;
481 }
482
483 //************************************
484 bool string2int(const string &s, int *v)
485 //string s=argv[1] ; int ii;
486 //ok=string2int(s,&ii);
487 //std::cout<<"test "<<ii<<" "<<ok<<std::endl;
488 {
489    string splus=s + " -1"; //evite conversion ok sur "+9truc" qui passe sinon
490    istringstream ss(splus);
491    int v2;
492    if (ss >> *v >> v2) return true; else {*v=0 ;return false;}
493 }
494
495 //************************************
496 bool string2float(const string &s, float *v)
497 //float ff;
498 //ok=string2float(s,&ff);
499 //std::cout<<"test3 "<<ff<<" "<<ok<<std::endl;
500 {
501    string splus=s + " -1"; //evite conversion ok sur "+9truc" qui passe sinon
502    istringstream ss(splus);
503    float v2;
504    if (ss >> *v >> v2) return true; else {*v=0. ;return false;}
505 }
506
507 //************************************
508 string int2string(const int &v)
509 {
510    ostringstream ss;
511    ss<<v;
512    return ss.str();
513 }
514
515 //************************************
516 string float2string(const float &v)
517 {
518    ostringstream ss;
519    ss<<v;
520    return ss.str();
521 }
522 */
523
524 //************************************
525 int main(int argc, char *argv[])
526 {
527    bool ok;
528    int i,nb,nbfiles,limit_swap,nbelem_limit_swap,limit_swap_defaut,verbose;
529    QString path,pathini,casename,casenamemed,fileskinmed,
530            tmp,cmd,format,
531            test,menu,launchtepal,background,deletegroups,
532            version="V2.0 (MED3)";
533    
534    char *chelp=NULL,
535         *ccasename=NULL,
536         *cnumber=NULL,
537         *cmedname=NULL,
538         *climitswap=NULL,
539         *cverbose=NULL,
540         *ctest=NULL,
541         *cmenu=NULL,
542         *claunchtepal=NULL,
543         *cbackground=NULL,
544         *cdeletegroups=NULL;
545
546    for (i = 0; i < argc; i++){
547       if (!strncmp (argv[i], "--help", sizeof ("--help"))) chelp = &(argv[i][0]);
548       else if (!strncmp (argv[i], "--casename=", sizeof ("--casename"))) ccasename = &(argv[i][sizeof ("--casename")]);
549       else if (!strncmp (argv[i], "--number=", sizeof ("--number"))) cnumber = &(argv[i][sizeof ("--number")]);
550       else if (!strncmp (argv[i], "--medname=", sizeof ("--medname"))) cmedname = &(argv[i][sizeof ("--medname")]);
551       else if (!strncmp (argv[i], "--limitswap=", sizeof ("--limitswap"))) climitswap = &(argv[i][sizeof ("--limitswap")]);
552       else if (!strncmp (argv[i], "--verbose=", sizeof ("--verbose"))) cverbose = &(argv[i][sizeof ("--verbose")]);
553       else if (!strncmp (argv[i], "--test=", sizeof ("--test"))) ctest = &(argv[i][sizeof ("--test")]);
554       else if (!strncmp (argv[i], "--menu=", sizeof ("--menu"))) cmenu = &(argv[i][sizeof ("--menu")]);
555       else if (!strncmp (argv[i], "--launchtepal=", sizeof ("--launchtepal"))) claunchtepal = &(argv[i][sizeof ("--launchtepal")]);
556       else if (!strncmp (argv[i], "--background=", sizeof ("--background"))) cbackground = &(argv[i][sizeof ("--background")]);
557       else if (!strncmp (argv[i], "--deletegroups=", sizeof ("--deletegroups"))) cdeletegroups = &(argv[i][sizeof ("--deletegroups")]);
558       }
559
560    if (argc < 2 || chelp){
561       std::cout<<"tepal2med "<<version.toLatin1().constData()<<" Available options:\n"
562       "   --help         : produces this help message\n"<<
563       "   --casename     : path and name of input tepal2med files which are\n"<<
564       "                       - output files of tepal .msg .noboite .faces .points .glo\n"<<
565       "                       - output file of GHS3DPRL_Plugin casename_skin.med (optional)\n"<<
566       "                         with initial skin and its initial groups\n"<<
567       "   --number       : number of partitions\n"<<
568       "   --medname      : path and name of output MED files\n"<<
569       "   --limitswap    : max size of working cpu memory (Mo) (before swapping on .temp files)\n"<<
570       "   --verbose      : trace of execution (0->6)\n"<<
571       "   --test         : more tests about joints, before generation of output files\n"<<
572       "   --menu         : a GUI menu for option number\n"<<
573       "   --launchtepal  : also launch tepal on files casename.faces and casename.points and option number\n"<<
574       "   --background   : force background mode from launch tepal and generation of final MED files (big meshes)\n"<<
575       "   --deletegroups : regular expression (see QRegExp) which matches unwanted groups in final MED files\n"<<
576       "                    (try --deletegroups=\"(\\bJOINT)\"\n"<<
577       "                    (try --deletegroups=\"(\\bAll_Nodes|\\bAll_Faces)\"\n"<<
578       "                    (try --deletegroups=\"((\\bAll_|\\bNew_)(N|F|T))\"\n";
579       std::cout<<"example:\n   tepal2med --casename=/tmp/GHS3DPRL --number=2 --medname=DOMAIN "<<
580                                     "--limitswap=1000 --verbose=0 --test=yes --menu=no --launchtepal=no\n\n";
581       return 1;  //no output files
582    }
583    
584    if (!ccasename){
585       std::cerr<<"--casename: a path/name is expected\n\n";
586       return 1;
587    }
588    casename=ccasename;
589    if (!cnumber){
590       std::cerr<<"--number: an integer is expected\n\n";
591       return 1;
592    }
593    tmp=cnumber;
594    nbfiles=tmp.toLong(&ok,10);
595    if (!ok){
596       std::cerr<<"--number: an integer is expected\n\n";
597       return 1;
598    }
599    if (nbfiles<=0){
600       std::cerr<<"--number: a positive integer is expected\n\n";
601       return 1;
602    }
603    if (nbfiles>2048){ //delirium in 2008
604       std::cerr<<"--number: a positive integer <= 2048 is expected\n\n";
605       return 1;
606    }
607    if (!cmedname) cmedname=ccasename;
608    casenamemed=cmedname;
609    limit_swap_defaut=1000; //1000Mo
610    limit_swap=limit_swap_defaut;
611    if (climitswap){
612       tmp=climitswap;
613       limit_swap=tmp.toLong(&ok,10);
614       if (!ok){
615          std::cerr<<"--limitswap: an integer is expected. try 1000\n\n";
616          return 1;
617       }
618       if (limit_swap<1 || limit_swap>32000){
619          std::cerr<<"--limitswap: [1->32000] expected. try 1000\n\n";
620          return 1;
621       }
622    }
623    //default 1GOctet/8(for float)
624    nbelem_limit_swap=limit_swap*1000000; //100%
625    CVWtab::memorymax=nbelem_limit_swap;
626
627    verbose=1; //default
628    if (cverbose){
629       tmp=cverbose;
630       verbose=tmp.toLong(&ok,10);
631       if (!ok){
632          std::cerr<<"--verbose: an integer is expected\n\n";
633          return 1;
634       }
635       if (verbose<0){
636          std::cerr<<"--verbose: a positive integer is expected\n\n";
637          return 1;
638       }
639    }
640
641    test="no"; //default
642    if (ctest){
643       tmp=ctest;
644       if (tmp=="yes") test="yes";
645    }
646
647    menu="no"; //default
648    if (cmenu){
649       tmp=cmenu;
650       if (tmp=="yes") menu="yes";
651    }
652
653    launchtepal="no"; //default
654    if (claunchtepal){
655       tmp=claunchtepal;
656       if (tmp=="yes") launchtepal="yes";
657    }
658    
659    background="no"; //default
660    if (cbackground){
661       tmp=cbackground;
662       if (tmp=="yes") background="yes";
663    }
664
665    
666    // We must always have an application
667    if (menu=="yes") {
668     QApplication a(argc,argv);
669     dlg_ghs3dmain *m = new dlg_ghs3dmain();
670     m->setWindowTitle("tepal2med 2.1");
671     m->show();
672     a.exec();
673     if ( m->result() == QDialog::Accepted ) {
674       std::cout<<"parameters "<<m->KeepFiles()<<" "<<m->NbPart()<<std::endl;
675       nbfiles=m->NbPart();
676     }
677     else {
678       return 1;
679     }
680     delete m;
681    }
682
683    int n=casenamemed.count('/');
684    if (n>0)
685       path=casenamemed.section('/',-n-1,-2)+"/";
686    else
687       path="./";
688       casenamemed=casenamemed.section('/',-1);
689    if (casenamemed.length()>20){
690       std::cerr<<"--medname truncated (no more 20 characters)"<<std::endl;
691       casenamemed.truncate(20);
692    }
693
694    n=casename.count('/');
695    if (n>0)
696       pathini=casename.section('/',-n-1,-2)+"/";
697    else
698       pathini="./";
699       casename=casename.section('/',-1);
700    if (casename.length()>20){
701       std::cerr<<"--casename truncated (no more 20 characters)"<<std::endl;
702       casename.truncate(20);
703    }
704
705    /*std::cout<<"CaseNameMed="<<casenamemed<<std::endl;
706    std::cout<<"PathMed="<<path<<std::endl;*/
707
708    deletegroups="(\\bxyz)"; //default improbable name
709    if (cdeletegroups){
710       deletegroups=cdeletegroups;
711    }
712    
713    //verbose=5;
714    if (verbose>0)
715    std::cout<<"tepal2med "<<version.toLatin1().constData()<<" parameters:"<<
716          "\n   --casename="<<pathini.toLatin1().constData()<<casename.toLatin1().constData()<<
717          "\n   --number="<<nbfiles<<
718          "\n   --medname="<<path.toLatin1().constData()<<casenamemed.toLatin1().constData()<<
719          "\n   --limitswap="<<limit_swap<<
720          "\n   --verbose="<<verbose<<
721          "\n   --test="<<test.toLatin1().constData()<<
722          "\n   --menu="<<menu.toLatin1().constData()<<
723          "\n   --launchtepal="<<launchtepal.toLatin1().constData()<<
724          "\n   --background="<<background.toLatin1().constData()<<
725          "\n   --deletegroups=\""<<deletegroups.toLatin1().constData()<<"\"\n";
726    
727    //utile si appel par plugin ghs3dprl sur big meshes et tepal sur plusieurs jours
728 #ifndef WIN32
729    if (background=="yes"){
730       pid_t pid = fork();
731       if (pid > 0) {
732          //Process father
733          exit(0); //temporary ok for plugin
734       }
735       //process children
736       //On rend le fils independant de tout terminal
737       //from here everything in background: tepal AND generation of final MED files
738       setsid();
739       system("sleep 10");  //for debug
740    }
741 #else
742    printf("background mode is not supported on win32 platform !\n");
743 #endif
744
745    //"tepal -f exemple1 -n 4"
746    if (launchtepal=="yes"){
747       //tepal64.exe  -f /home/wambeke/tmp/GHS3DPRL -n 5 --tetmesh_args  "-c 0" 
748       //cmd="tepal --tetmesh_args \"-c 0\" -f "+pathini+casename+" -n "+cmd.sprintf("%d",nbfiles)+" > "+path+"tepal.log";
749       cmd="tepal -f "+pathini+casename+" -n "+cmd.sprintf("%d",nbfiles)+" > "+path+"tepal.log";
750       std::cout<<"\nlaunchtepal command: background="<<cbackground<<
751             "\n      "<<cmd.toLatin1().constData()<<std::endl;
752       system(cmd.toLatin1().constData()); // run
753       //sometimes it is better to wait flushing files on slow filesystem...
754       system("sleep 3");
755    }
756    ghs3dprl_mesh_wrap *mymailw=new ghs3dprl_mesh_wrap;
757    //no constructor, later maybe
758    mymailw->nbfiles=0;
759    mymailw->nbfilestot=nbfiles;
760    //for huge cases big array swap in huge binary files
761    mymailw->nbelem_limit_swap=nbelem_limit_swap;
762    mymailw->verbose=verbose;
763    mymailw->casename=casename;
764    mymailw->medname=casenamemed;
765    mymailw->path=path;
766    mymailw->pathini=pathini;
767    mymailw->deletegroups=QRegExp(deletegroups,Qt::CaseSensitive,QRegExp::RegExp);
768    ghs3dprl_msg_parser handler;
769    //constructor later maybe
770    //handler.verbose=true;
771    handler.mailw=mymailw;
772    mymailw->families.no=1;
773    //std::cout<<"coucou1 "<<mymailw->families.no<<std::endl;
774    //mymailw->families.add(casename,casenamemed);
775    format=format.sprintf("%d",nbfiles);
776    int nbf=format.length();
777    format=format.sprintf(".%%.%dd.%%.%dd",nbf,nbf);
778    mymailw->format=format;
779    
780    //something like "/home/wambeke/tmp/GHS3DPRL_skin.med"
781    fileskinmed=pathini+casename+"_skin.med";
782    //fileskinmed="/home/wambeke/tmp/GHS3DPRL_skin.med";
783    /*for debug
784    {
785    char ctmp[fileskinmed.length()+1] ; strcpy(ctmp,fileskinmed);
786    int res=dumpMED(&ctmp[0],1);
787    }*/
788    int ret = access(fileskinmed.toLatin1().constData(),F_OK); //on regarde si le fichier existe
789    if (ret >= 0) {
790       ok=ReadFileMED(fileskinmed,mymailw); }
791    else {
792       if (verbose>0)std::cout<<"Initial skin file <"<<fileskinmed.toLatin1().constData()<<"> does not exist\n"; }
793    
794
795 //if test read all files before (only small files)
796  if (test=="yes"){
797    if (verbose>0) std::cout<<"\nReading output files of tepal as input files of tepal2med...\n";
798    
799    //read files .msg
800    //supposed big files big arrays so don't read with parser
801    mymailw->nbfiles=0;
802    for (int i=1; i<=nbfiles; i++){
803       mymailw->nofile=i;
804       tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfiles,i)+".msg";
805       if (verbose>0) std::cout<<"FileName="<<tmp.toLatin1().constData()<<std::endl;
806       ok=mymailw->ReadFileMSGnew(tmp);
807    }
808    if (verbose>0)
809       std::cout<<"NumberOfFilesMSGacquired="<<mymailw->nbfiles<<"\n\n";
810    if (mymailw->nbfiles != nbfiles){
811       std::cerr<<"NumberOfFiles != NumberOfFilesAcquired is unexpected\n\n";
812       return 1;
813    }
814
815    /*old version with xml parser too slow
816    QXmlSimpleReader reader;
817    reader.setContentHandler(&handler);
818    //read files .msg
819    for (int i=1; i<=nbfiles; i++)
820    {
821       mymailw->nofile=i;
822       //tmp=casename+tmp.sprintf(".%d.%d.msg",nbfiles,i);
823       tmp=pathini+casename+tmp.sprintf(format,nbfiles,i)+".msg";
824       if (verbose>0) std::cout<<"FileName="<<tmp<<std::endl;
825       QFile File(tmp);
826       QXmlInputSource source(&File);
827       reader.parse(source);
828       File.close();
829    }
830    if (verbose>0)
831       std::cout<<"NumberOfFilesMSGAcquired="<<mymailw->nbfiles<<"\n";
832    if (mymailw->nbfiles != nbfiles){
833       std::cerr<<"Problem NumberOfFiles != NumberOfFilesAcquired\n";
834       return 1;
835    }
836
837    if (test=="yes"){
838       ok=mymailw->test_msg_wrap();
839       if (ok){
840          if (verbose>0) std::cout<<"\nResult_test_msg_wrap=ok\n\n";
841       }
842       else{
843          std::cerr<<"\nResult_test_msg_wrap=NO_OK!\n\n";
844          return 1;
845       }
846    }
847    */
848
849    //after verification remove unusued data
850    //"NE0 FI" for/from <version>1.0</version>
851    //after verification remove duplicates data
852    //for debug but don't do that because reliability
853    // and locality of datas files
854    //" RE " for duplicates <receive>
855    //int nb=mymailw->remove_key_mesh_wrap(QRegExp("( NE0 | RE)",true,false));
856
857    //because <send> equals <receive>
858    nb=0;
859    nb=mymailw->remove_key_mesh_wrap(QRegExp("RE",Qt::CaseSensitive,QRegExp::RegExp));
860    if (verbose>3) std::cout<<"NumberOfKeysRemoved="<<nb<<std::endl;
861    if (verbose>3) ok=mymailw->list_keys_mesh_wrap();
862
863    //test read files .noboiteb
864    //tmp=casename+".noboiteb";
865    //ok=mymailw->ReadFileNOBOITEB(tmp);
866
867    //read files .noboite
868    //supposed big files
869    mymailw->nbfiles=0;
870    for (int i=1; i<=nbfiles; i++){
871       mymailw->nofile=i;
872       tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfiles,i)+".noboite";
873       if (verbose>0) std::cout<<"FileName="<<tmp.toLatin1().constData()<<std::endl;
874       ok=mymailw->ReadFileNOBOITE(tmp);
875    }
876    if (verbose>0)
877       std::cout<<"NumberOfFilesNOBOITEAcquired="<<mymailw->nbfiles<<"\n";
878    if (mymailw->nbfiles != nbfiles){
879       std::cerr<<"NumberOfFiles != NumberOfFilesAcquired is unexpected\n";
880       return 1;
881    }
882
883    //if (test=="yes"){
884       ok=mymailw->test_vertices_wrap();
885       if (ok){
886          if (verbose>0) std::cout<<"\nResult_test_vertices_wrap=ok\n\n";
887       }
888       else{
889          std::cerr<<"\nResult_test_vertices_wrap=NO_OK!\n\n";
890          return 1;
891       }
892    //}
893
894    //read files .faces
895    mymailw->nbfiles=0;
896    for (int i=1; i<=nbfiles; i++){
897       mymailw->nofile=i;
898       tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfiles,i)+".faces";
899       if (verbose>0) std::cout<<"FileName="<<tmp.toLatin1().constData()<<std::endl;
900       ok=mymailw->ReadFileFACES(tmp);
901    }
902    if (verbose>0)
903       std::cout<<"NumberOfFilesFACESAcquired="<<mymailw->nbfiles<<"\n\n";
904    if (mymailw->nbfiles != nbfiles){
905       std::cerr<<"NumberOfFiles != NumberOfFilesAcquired is unexpected\n\n";
906       return 1;
907    }
908
909    /*
910    //read files .points
911    mymailw->nbfiles=0;
912    for (int i=1; i<=nbfiles; i++){
913       mymailw->nofile=i;
914       tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfiles,i)+".points";
915       if (verbose>0) std::cout<<"FileName="<<tmp.toLatin1().constData()<<std::endl;
916       ok=mymailw->ReadFilePOINTS(tmp);
917    }
918    if (verbose>0)
919       std::cout<<"NumberOfFilesPOINTSAcquired="<<mymailw->nbfiles<<"\n\n";
920    if (mymailw->nbfiles != nbfiles)
921    {
922       std::cerr<<"NumberOfFiles != NumberOfFilesAcquired is unexpected\n\n";
923       return 1;
924    }
925    */
926    
927    //read files .glo
928    //supposed big files big arrays so don't read with parser
929    mymailw->nbfiles=0;
930    for (int i=1; i<=nbfiles; i++){
931       mymailw->nofile=i;
932       tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfiles,i)+".glo";
933       if (verbose>0) std::cout<<"FileName="<<tmp.toLatin1().constData()<<std::endl;
934       ok=mymailw->ReadFileGLO(tmp);
935       //mymailw->SwapOutOfMemory_key_mesh_wrap(QRegExp("GL",true,false));
936    }
937    if (verbose>0)
938       std::cout<<"NumberOfFilesGLOAcquired="<<mymailw->nbfiles<<"\n\n";
939    if (mymailw->nbfiles != nbfiles){
940       std::cerr<<"NumberOfFiles != NumberOfFilesAcquired is unexpected\n\n";
941       return 1;
942    }
943
944    /*exemples
945    ok=mymailw->list_keys_mesh_wrap();
946    tmp="FA RE NE4 FI1";
947    ok=mymailw->list_onekey_mesh_wrap(tmp);
948    tmp="FA SE NE4 FI1";
949    ok=mymailw->list_onekey_mesh_wrap(tmp);
950    tmp="FA RE NE1 FI4";
951    ok=mymailw->list_onekey_mesh_wrap(tmp);
952    tmp="FA SE NE1 FI4";
953    ok=mymailw->list_onekey_mesh_wrap(tmp);
954
955    tmp="FA RE NE4 FI1";
956    ok=mymailw->list_onekey_mesh_wrap(tmp);*/
957
958    //test remove points (type 3)
959    //nb=mymailw->remove_key_mesh_wrap(QRegExp("PO",true,false));
960    //std::cout<<"***remove_key_mesh_wrap*** remove nb="<<nb<<std::endl;
961    //ok=mymailw->list_keys_mesh_wrap();
962
963    ok=mymailw->Find_VerticesDomainToVerticesSkin();
964  }  //end if test
965  
966    ok=mymailw->Write_MEDfiles_v2(true); //deletekeys=true
967    
968    nb=mymailw->remove_all_keys_mesh_wrap();
969    if (verbose>3)std::cout<<"***remove_all_key_mesh_wrap*** "<<nb<<" keys removed\n";
970    if (verbose>0)std::cout<<std::endl<<"===end of "<<argv[0]<<"==="<<std::endl;
971
972    //for debug
973    //int res=dumpMED("/home/wambeke/tmp/DOMAIN_1.med",1);
974
975    return 0; //ok
976 }