Salome HOME
Update copyrights 2014.
[plugins/ghs3dprlplugin.git] / src / tepal2med / ghs3dprl_mesh_wrap.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   : ghs3dprl_mesh_wrap.cxx
22 // Author : Christian VAN WAMBEKE (CEA) 
23 // ---
24 //
25 #include "ghs3dprl_mesh_wrap.h"
26
27 #include <string>
28 #include <iostream>
29 #include <sstream>
30 #include <fstream>
31 #ifndef WIN32
32 #include <unistd.h>
33 #endif
34
35 #include <libxml/tree.h>
36 #include <libxml/parser.h>
37 #include <libxml/xpath.h>
38 #include <libxml/xpathInternals.h>
39 #ifdef WIN32
40 #include <io.h>
41 #include <windows.h>
42 #include <time.h>
43 #define F_OK 0
44 #undef max
45 #undef min
46 #endif
47
48 #include <QFile>
49 #include <QRegExp>
50 #include <limits>
51
52 extern "C" {
53 #include <med.h>
54 //#include <med_config.h>
55 //#include <med_utils.h>
56 //#include <med_misc.h>
57 }
58
59 //utils procedures
60
61 //************************************
62 std::string i2a(const int &v)
63 {
64    std::ostringstream ss;
65    ss<<v;
66    return ss.str();
67 }
68
69 //************************************
70 QString endspace(QString deb,int lg)
71 //better fill by spaces for char unicoo[3*MED_TAILLE_PNOM+1]; etc...
72 {
73    QString fin,spa;
74    //spa.fill(' ',lg);
75    //fin=deb+spa;
76    //fin.truncate(lg);
77    fin=deb.leftJustified(lg,' ',true);
78    return fin;
79 }
80
81 //************************************
82 void charendnull(char *p, QString deb, int lg)
83 {
84    QString fin;
85    fin=deb;
86    fin.truncate(lg-1);
87    strcpy(p,fin.toLatin1().constData()); // 0 at end
88    for (int i=fin.length();i<lg-1;i++){
89        p[i]='\0';
90    }
91 }
92
93 //class familles
94 //************************************
95    void familles::newfam(QString nom){
96       //std::cout<<"newfam "<<nom<<std::endl;
97       if (fam.find(nom)!=fam.end()){
98          std::cout<<"***newfam*** "<<nom.toLatin1().constData()<<" deja present\n";
99          return;
100       }
101       fend gb;
102       fam[nom]=gb;
103    }
104
105 //************************************
106    void familles::newgro(QString nom){
107       //std::cout<<"newgro "<<nom<<std::endl;
108       if (gro.find(nom)!=gro.end()){
109          std::cout<<"***newgro*** "<<nom.toLatin1().constData()<<" deja present\n";
110          return;
111       }
112       fend gb;
113       gro[nom]=gb;
114    }
115    
116 //************************************
117    void familles::write(){
118       fend gb;
119       fagr::iterator it1;
120       fend::iterator it2;
121       int nbf=0,nbg=0;
122       for (it1=fam.begin(); it1!=fam.end(); ++it1){
123          nbf++;
124          std::cout<<"Family=<"<<(*it1).first.toLatin1().constData()<<">\tGroups=";
125          gb=(*it1).second;
126          for (it2=gb.begin(); it2!=gb.end(); ++it2){
127             std::cout<<"<"<<(*it2).first.toLatin1().constData()<<"> ";
128          }
129          std::cout<<std::endl;
130       }
131       if (nbf==0) std::cout<<"no families"<<std::endl;
132       for (it1=gro.begin(); it1!=gro.end(); ++it1){
133          nbg++;
134          std::cout<<"Group=<"<<(*it1).first.toLatin1().constData()<<">\tFamilies=";
135          gb=(*it1).second;
136          for (it2=gb.begin(); it2!=gb.end(); ++it2){
137             std::cout<<"<"<<(*it2).first.toLatin1().constData()<<"> ";
138          }
139          std::cout<<std::endl;
140       }
141       if (nbg==0) std::cout<<"no groups"<<std::endl;
142    }
143
144 //************************************
145    xmlNodePtr familles::xml_groups(){
146       fend gb;
147       fagr::iterator it1;
148       fend::iterator it2;
149       int nb=0,nbf;
150       std::string ss;
151       xmlNodePtr res,node;
152       res=xmlNewNode(NULL, BAD_CAST "groups");
153       for (it1=gro.begin(); it1!=gro.end(); ++it1){
154          node = xmlNewChild(res, 0, BAD_CAST "group",0);
155          ss=(*it1).first.toLatin1().constData();
156          xmlNewProp(node, BAD_CAST "name", BAD_CAST ss.c_str());
157          nb++;
158          gb=(*it1).second;
159          nbf=0; ss="";
160          for (it2=gb.begin(); it2!=gb.end(); ++it2){
161             ss=ss+" "+(*it2).first.toLatin1().constData();
162             nbf++;
163          }
164          xmlNewProp(node, BAD_CAST "families_number", BAD_CAST i2a(nbf).c_str());
165          xmlNewProp(node, BAD_CAST "families", BAD_CAST ss.substr(1).c_str());
166          //std::cout<<std::endl;
167       }
168       xmlNewProp(res, BAD_CAST "number", BAD_CAST i2a(nb).c_str());
169       return res;
170    }
171
172 //************************************
173    void familles::add(QString nomfam, QString nomgro)
174    {
175       //std::cout<<"add family <"<<nomfam<<">\t<"<<nomgro<<">\n";
176       fagr::iterator it;
177       it=fam.find(nomfam);
178       if (it==fam.end()){
179          //std::cout<<"add new family <"<<nomfam<<">\t<"<<nomgro<<">\n";
180          newfam(nomfam);
181          it=fam.find(nomfam);
182       }
183       if (nomgro=="") return; //no group
184       (*it).second[nomgro]=0;
185       it=gro.find(nomgro);
186       if (it==gro.end()){
187          //std::cout<<"***new*** "<<nomgro<<" non present\n";
188          newgro(nomgro);
189          it=gro.find(nomgro);
190       }
191       (*it).second[nomfam]=0;
192
193    }
194
195
196 //************************************
197 bool familles::get_number_of_new_family(int sign, med_int *ires, QString *tmp)
198 //if sign < 0 families faces or tria3 etc...
199 //if sign >= 0 family zero and family nodes
200 //outputs in *ires and *tmp
201 {
202    int pas,i,ii;
203    QString nomfam;
204    fagr::iterator it;
205    if (sign>=0) pas=1; else pas=-1;
206    *tmp="0"; *ires=0;
207    ii=pas;
208    for (i=0;i<10000;i++) { //mefiance
209       nomfam=nomfam.sprintf("%d",ii);
210       it=fam.find(nomfam);
211       if (it==fam.end()) {
212          *tmp=nomfam; *ires=ii;
213          //std::cout<<"NewFamily Found<"<<*ires<<"><"<<*tmp<<">\n";
214          return true;
215       }
216       ii=ii+pas;
217    }
218    std::cerr<<"***get_number_of_new_family*** Problem new family not found"<<std::endl;
219    return false;
220 }
221
222 //************************************
223    med_int familles::find_family_on_groups(med_int fam1, med_int fam2)
224    {
225       med_int ires=0;
226       if (fam1==fam2) {ires=fam1; return ires;}
227       //find one family whith groups of fam1 and groups of fam2
228       fend gb=fuse_goups(fam1,fam2);
229       //find if one family have theses groups
230       fagr::iterator it1;
231       fend::iterator it2;
232       for (it1=fam.begin(); it1!=fam.end(); ++it1){
233          if (gb==(*it1).second){
234             ires=(*it1).first.toLong();
235             //std::cout<<"find_family_on_groups old <"<<ires<<"> from <"<<
236             //       fam1<<"><"<<fam2<<">\n";
237             return ires;
238          }
239       }
240       //std::cout<<"no family found!!! - groups of "<<fam1<<" and "<<fam2<<std::endl;
241       QString tmp;
242       //fam1 positive for nodes negative faces & mailles
243       bool oktmp=get_number_of_new_family(fam1,&ires,&tmp);
244       fend::iterator it;
245       for (it=gb.begin(); it!=gb.end(); ++it){
246           this->add(tmp,(*it).first);
247       }
248       //std::cout<<"new family <"<<ires<<"> intersection of <"<<fam1<<"><"<<fam2<<">\n";
249       return ires;
250    }
251    
252 //************************************
253    fend familles::fuse_goups(med_int fam1, med_int fam2)
254    //concatenation/fusion deux map groupes
255    {
256       QString nom1,nom2;
257       fagr::iterator it1,it2;
258       nom1=nom1.sprintf("%d",fam1);
259       it1=fam.find(nom1);
260       nom2=nom2.sprintf("%d",fam2);
261       it2=fam.find(nom2);
262       if ( (it1==fam.end())||(it2==fam.end()) ) {
263          std::cerr<<"***fuse_goups*** non existing family "<<fam1<<" or "<<fam2<<std::endl;
264          fend gb;
265          return gb; //empty
266       }
267       fend gb=(*it1).second; //firt groups
268       gb.insert((*it2).second.begin(),(*it2).second.end()); //other groups
269       return gb;
270       //for debug
271       std::cout<<"fuse_goups "<<fam1<<" "<<fam2<<" ";
272       fend::iterator it;
273       for (it=gb.begin(); it!=gb.end(); ++it){
274             std::cout<<"<"<<(*it).first.toLatin1().constData()<<"> ";
275       }
276       std::cout<<std::endl;
277       return gb;
278    }
279
280 long CVWtab::memoryuse=0; //static
281 long CVWtab::memorymax=1000*1000000; //static
282
283 //************************************
284 CVWtab::CVWtab(long nb, med_int *pmint)
285 //constructor with pmint allocated yet with new
286 {
287    //std::cout"***constructor med_int CVWtab***\n";
288    size=nb;
289    type=1;  //only tmint valide
290    tmint=pmint;
291    tmflo=NULL;
292    memoryuse=memoryuse+sizeof(med_int)*nb;
293    //std::cout<<"memoryuse int "<<sizeof(med_int)<<" "<<nb<<" "<<memoryuse<<" "<<memorymax<<std::endl;
294    if (memoryuse>memorymax) {
295       std::cout<<"***WARNING*** memory max reached "<<memorymax<<std::endl;
296       //std::cout<<"memoryuse int "<<sizeof(med_int)<<" "<<nb<<" "<<memoryuse<<std::endl;
297    }
298 }
299
300 //************************************
301 CVWtab::CVWtab(long nb, med_float *pmflo)
302 //constructor with pmflo allocated yet with new
303 {
304    //std::cout<<"***constructor med_float CVWtab***\n";
305    size=nb;
306    type=2;   //only tmflo valide
307    tmint=NULL;
308    tmflo=pmflo;
309    memoryuse=memoryuse+sizeof(med_float)*nb;
310    //std::cout<<"memoryuse float "<<sizeof(med_float)<<" "<<nb<<" "<<memoryuse<<" "<<memorymax<<std::endl;
311    if (memoryuse>memorymax) {
312       std::cout<<"***WARNING*** memory max reached "<<memorymax<<std::endl;
313       //std::cout<<"memoryuse float "<<sizeof(med_float)<<" "<<nb<<" "<<memoryuse<<std::endl;
314    }
315 }
316
317 //************************************
318 CVWtab::~CVWtab()
319 {
320    bool ok;
321    //std::cout<<"   destructor CVWtab *** "<<this->filename<<std::endl;
322    ok=this->CVWtab_deallocate();
323    //remove temporary file
324    if (this->filename!="_NO_FILE")
325    {
326       remove(this->filename.toLatin1().constData()); //#include <stdio.h>
327       //std::cout<<this->filename<<" successfully deleted\n";
328    }
329
330 }
331
332 //************************************
333 bool CVWtab::CVWtab_deallocate()
334 {
335    //std::cout<<"   deallocate CVWtab*** "<<size<<std::endl;
336    if (size <= 0) return false;
337    if (tmint)
338    {
339       delete[] tmint;
340       memoryuse=memoryuse-sizeof(med_int)*size;
341       size=-size; //precaution
342    }
343    if (tmflo)
344    {
345       delete[] tmflo;
346       memoryuse=memoryuse-sizeof(med_float)*size;
347       size=-size; //precaution
348    }
349    if (memoryuse<0) std::cout<<"***WARNING*** memoryuse <0 "<<memoryuse<<std::endl;
350    if (memoryuse==0) std::cout<<"***CVWtab_deallocate*** memoryuse=0 "<<std::endl;
351    return true;
352 }
353
354 //************************************
355 bool CVWtab::is_equal(CVWtab *tab2)
356 {
357    //std::cout<<"is_equal tab1 tab2 type="<<this->type<<"  size="<<this->size<<" "<<tab2->size<<std::endl;
358    //if (this->type==1) std::cout<<"med_int tab1[0]="<<this->tmint[0]<<std::endl;
359    //if (this->type==2) std::cout<<"med_float tab1[0]="<<this->tmflo[0]<<std::endl;
360    if (this->size!=tab2->size) return false;
361    if (this->type!=tab2->type) return false;
362    if (this->type==1)
363    {
364       if (!this->tmint)
365       {  std::cout<<"***is_equal*** pb pointer NULL with tmint size="<<this->size<<std::endl;
366          return false;
367       }
368       for (long i=0; i < this->size; i++)
369          if (this->tmint[i]!=tab2->tmint[i]) return false;
370    }
371    if (this->type==2)
372    {
373       if (!this->tmflo)
374       {  std::cout<<"***is_equal*** pb pointer NULL with tmflo size="<<this->size<<std::endl;
375          return false;
376       }
377       for (long i=0; i < this->size; i++)
378          if (this->tmflo[i]!=tab2->tmflo[i]) return false;
379    }
380    return true;
381 }
382
383 //************************************
384 bool CVW_is_equal_vertices(CVWtab *tab1, long i1,
385                        CVWtab *tab2, long i2, int verbose)
386 //verbose 0 for no prints
387 //verbose 1 for print vertices not equals
388 //verbose 2 for print also vertices equals (debug)
389 {
390    //std::cout<<"is_equal_vertice size="<<tab1->size<<" "<<tab2->size<<std::endl;
391    bool ok=false;
392    med_float *p1,*p2;
393    //vertices indices from 1 not 0!
394    long di1=(i1-1)*3, di2=(i2-1)*3;
395    if (di1<0 || di1>=tab1->size)
396    {
397       std::cerr<<"BadIndice tab1 in is_equal_vertices "<<
398             di1<<" not in "<<tab1->size<<std::endl;
399       return false;
400    }
401    if (di2<0 || di2>=tab2->size)
402    {
403       std::cerr<<"BadIndice tab2 in is_equal_vertices "<<
404             di2<<" not in "<<tab2->size<<std::endl;
405       return false;
406    }
407    p1=(tab1->tmflo+di1);
408    p2=(tab2->tmflo+di2);
409    if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]) ok=true ;
410    if (!ok && verbose>0) printf(
411       "Vertices differents (%.16g %.16g %.16g) (%.16g %.16g %.16g)\n",
412       p1[0],p1[1],p1[2],p2[0],p2[1],p2[2]);
413    else
414       if (verbose>1) printf(
415       "Vertices equals     (%.16g %.16g %.16g)\n",
416       p1[0],p1[1],p1[2]);
417    return ok;
418 }
419
420 //************************************
421 bool CVW_FindString(const std::string &str,std::fstream &Ff, long &count)
422 //find in file first line with string str in first position of line
423 //converts count value expected after "='" in line found
424 {
425    std::string line;
426    QString tmp;
427    do
428    {
429       if (getline(Ff,line))
430       {
431          if (line[0]==str[0]) //faster
432          {
433             if (line.find(str)==0)
434             {
435             tmp=line.c_str();
436             bool ok;
437             count=tmp.section('\'',1,1).toLong(&ok);
438             return ok;
439             }
440          }
441       }
442       else
443       {
444          std::cerr<<"Problem line '"<<str<<"' not found in file\n"<<std::endl;
445          return false;
446       }
447    } while (1);
448    return true;
449 }
450
451 //************************************
452 bool ghs3dprl_mesh_wrap::ReadFileMSGnew(const QString FileName)
453 //read file .glo with no parser xml because big file (volume)
454 //no read of <receive> for speed (and so no test)
455 {
456    QString tmp;
457    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
458    std::string line;
459    long i,count,nbneighbour,ineighbour;
460    bool ok;
461
462    if (!Ff.is_open())
463    {
464       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
465       return false;
466    }
467
468    //Lit les donn�s :
469    if (!CVW_FindString("<neighbours count=",Ff,nbneighbour)) return false;
470    if (verbose>2) std::cout<<"NeighboursCountDomain_"<<this->nofile<<"="<<nbneighbour<<std::endl;
471    for (i=1; i<=nbneighbour; i++)
472    {
473       if (!CVW_FindString("<neighbour indice=",Ff,ineighbour)) return false;
474       if (!CVW_FindString("<vertices count=",Ff,count)) return false;
475       if (count>0){
476          med_int *tmint=new med_int[count];
477          for (int i=0; i<count; i++) Ff>>tmint[i];
478          if (verbose>4) std::cout<<"Vertices "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
479
480          CVWtab *montab=new CVWtab(count,tmint);
481          tmp=tmp.sprintf("MS%ld NE%ld VE SE",this->nofile,ineighbour);
482          ok=this->insert_key(tmp,montab);
483       }
484       if (!CVW_FindString("<edges count=",Ff,count)) return false;
485       if (count>0){
486          med_int *tmint=new med_int[count];
487          for (int i=0; i<count; i++) Ff>>tmint[i];
488          if (verbose>4) std::cout<<"Edges "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
489
490          CVWtab *montab=new CVWtab(count,tmint);
491          tmp=tmp.sprintf("MS%ld NE%ld ED SE",this->nofile,ineighbour);
492          ok=this->insert_key(tmp,montab);
493       }
494       if (!CVW_FindString("<faces count=",Ff,count)) return false;
495       if (count>0){
496          med_int *tmint=new med_int[count];
497          for (int i=0; i<count; i++) Ff>>tmint[i];
498          if (verbose>4) std::cout<<"Faces "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
499
500          CVWtab *montab=new CVWtab(count,tmint);
501          tmp=tmp.sprintf("MS%ld NE%ld FA SE",this->nofile,ineighbour);
502          ok=this->insert_key(tmp,montab);
503       }
504       if (!CVW_FindString("<elements count=",Ff,count)) return false;
505       if (count>0){
506          med_int *tmint=new med_int[count];
507          for (int i=0; i<count; i++) Ff>>tmint[i];
508          if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
509
510          CVWtab *montab=new CVWtab(count,tmint);
511          tmp=tmp.sprintf("MS%ld NE%ld EL SE",this->nofile,ineighbour);
512          ok=this->insert_key(tmp,montab);
513       }
514    }
515
516    //Ferme le fichier :
517    Ff.close();
518    this->nbfiles++;
519    return true;
520 }
521
522 ///************************************
523 bool ghs3dprl_mesh_wrap::ReadFileGLO(const QString FileName)
524 //read file .glo with no parser xml because big file (volume)
525 {
526    QString tmp;
527    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
528    std::string line;
529    long count;
530    bool ok;
531
532    if (!Ff.is_open())
533    {
534       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
535       return false;
536    }
537
538    //Lit les donn�s :
539    if (!CVW_FindString("<vertices count=",Ff,count)) return false;
540    if (verbose>3) std::cout<<"GloVerticesCount="<<count<<std::endl;
541    if (count>0)
542    {
543       med_int *tmint=new med_int[count];
544       for (int i=0; i<count; i++) Ff>>tmint[i];
545       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
546
547       CVWtab *montab=new CVWtab(count,tmint);
548       tmp=tmp.sprintf("GL%ld VE",this->nofile);
549       ok=this->insert_key(tmp,montab);
550    }
551
552    if (!CVW_FindString("<edges count=",Ff,count)) return false;
553    if (verbose>3) std::cout<<"GloEdgesCount="<<count<<std::endl;
554    if (count>0)
555    {
556       med_int *tmint=new med_int[count];
557       for (int i=0; i<count; i++) Ff>>tmint[i];
558       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
559
560       CVWtab *montab=new CVWtab(count,tmint);
561       tmp=tmp.sprintf("GL%ld ED",this->nofile);
562       ok=this->insert_key(tmp,montab);
563    }
564
565    if (!CVW_FindString("<faces count=",Ff,count)) return false;
566    if (verbose>3) std::cout<<"GloFacesCount="<<count<<std::endl;
567    if (count>0)
568    {
569       med_int *tmint=new med_int[count];
570       for (int i=0; i<count; i++) Ff>>tmint[i];
571       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
572
573       CVWtab *montab=new CVWtab(count,tmint);
574       tmp=tmp.sprintf("GL%ld FA",this->nofile);
575       ok=this->insert_key(tmp,montab);
576    }
577
578    if (!CVW_FindString("<elements count=",Ff,count)) return false;
579    if (verbose>3) std::cout<<"GloElementsCount="<<count<<std::endl;
580    if (count>0)
581    {
582       med_int *tmint=new med_int[count];
583       for (int i=0; i<count; i++) Ff>>tmint[i];
584       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
585
586       CVWtab *montab=new CVWtab(count,tmint);
587       tmp=tmp.sprintf("GL%ld EL",this->nofile);
588       ok=this->insert_key(tmp,montab);
589    }
590    //Ferme le fichier :
591    Ff.close();
592    this->nbfiles++;
593    return true;
594 }
595
596 //************************************
597 bool ghs3dprl_mesh_wrap::ReadFileFACES(const QString FileName)
598 //read file .faces (wrap)
599 {
600    QString tmp;
601    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
602    std::string line;
603    long nbelem,ntype;
604    bool ok;
605
606    if (!Ff.is_open())
607    {
608       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
609       return false;
610    }
611
612    //Lit les donn�s :
613    //Replace le pointeur de fichier au d�ut :f.seekg(0);
614    if (getline(Ff,line))
615    {
616       tmp=line.c_str();
617       nbelem=tmp.section(' ',0,0).toLong(&ok);
618    }
619    else
620    {
621       std::cerr<<"Problem on first line of file"<<std::endl;
622       return false;
623    }
624    if (verbose>3) std::cout<<"FacesNumberOfElements="<<nbelem<<std::endl;
625    med_int *tmint=new med_int[nbelem*7];
626    for (int i=0; i<nbelem*7; i=i+7)
627    {
628       Ff>>ntype;
629       if (ntype!=3) //only triangles
630       {
631          std::cerr<<"Problem on ntype != 3"<<std::endl;
632          return false;
633       }
634       for (int j=0; j<7; j++) Ff>>tmint[i+j];
635       //for (int j=0; j<7; j++) std::cout<<tmint[i+j]<<' '; std::cout<<std::endl;
636    }
637    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[nbelem*7-1]<<std::endl;
638
639    CVWtab *montab=new CVWtab(nbelem*7,tmint);
640    tmp=tmp.sprintf("FC%ld",this->nofile);
641    ok=this->insert_key(tmp,montab);
642
643    Ff.close();
644    this->nbfiles++;
645    return true;
646 }
647
648 //************************************
649 bool ghs3dprl_mesh_wrap::ReadFileNOBOITE(const QString FileName)
650 //read file .noboite (volume)
651 //for huge files it could be better use ReadFileNOBOITEB (B=binary format)
652 //(parameter option of ghs3d but NOT tepal)
653 {
654    QString tmp;
655    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
656    long ne,np,npfixe,subnumber,reste;
657    bool ok;
658
659    if (!Ff.is_open()){
660       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
661       return false;
662    }
663
664    //lit les donn�s :
665    Ff>>ne>>np>>npfixe;
666    if (verbose>3){
667       std::cout<<"NoboiteNumberOfElements="<<ne<<std::endl;
668       std::cout<<"NoboiteNumberOfVertices="<<np<<std::endl;
669       std::cout<<"NoboiteNumberOfSpecifiedPoints="<<npfixe<<std::endl;
670    }
671
672    for (int i=1; i<=17-3; i++) Ff>>reste;
673    //printf("reste %ld\n",reste);
674    med_int *tmint=new med_int[ne*4];
675    for (int i=0; i<ne*4; i++) Ff>>tmint[i];
676    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[ne*4-1]<<std::endl;
677
678    CVWtab *montab=new CVWtab(ne*4,tmint);
679    tmp=tmp.sprintf("NB%ld EV",this->nofile);
680    ok=this->insert_key(tmp,montab);
681
682    med_float *tmflo=new med_float[np*3];
683    for (int i=0; i<np*3; i++) Ff>>tmflo[i];
684    if (verbose>4) std::cout<<"Vertices "<<tmflo[0]<<" "<<tmflo[1]<<"... "<<tmflo[np*3-1]<<std::endl;
685
686    montab=new CVWtab(np*3,tmflo);
687    tmp=tmp.sprintf("NB%ld VC",this->nofile);
688    ok=this->insert_key(tmp,montab);
689
690    Ff>>subnumber;
691    if (verbose>2) std::cout<<"NumberOfSubdomains="<<subnumber<<std::endl;
692    //tmint=new med_int[subnumber*3];
693    tmint=new  med_int[subnumber*3];
694    long onelong,maxint;
695    maxint=std::numeric_limits<int>::max();
696    //pb from tepalv2
697    bool isproblem=true;
698    for (int i=0; i<subnumber*3; i++) {
699      Ff>>onelong;
700      //pb from tepalv2
701      if (onelong<0) {
702       if (isproblem && verbose>1) std::cout<<"There is one or more negative med_int value in NumberOfSubdomains "<<onelong<<std::endl;
703       isproblem=false;
704       onelong=-1;
705       }
706      if (onelong>maxint) {
707       if (isproblem && verbose>1) std::cout<<"There is one or more truncated med_int value in NumberOfSubdomains "<<onelong<<std::endl;
708       isproblem=false;
709       onelong=-2;
710       }
711      tmint[i]=(int)onelong;
712      }
713    if (verbose>4) std::cout<<"Subdomains "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[subnumber*3-1]<<std::endl;
714
715    montab=new CVWtab(subnumber*3,tmint);
716    tmp=tmp.sprintf("NB%ld SN",this->nofile);
717    ok=this->insert_key(tmp,montab);
718
719    //swap on file if too big for memory in one cpu
720    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
721    if (np*3>this->nbelem_limit_swap)
722      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
723    //beware record 6 lenght 1
724    //ferme le fichier :
725    Ff.close();
726    this->nbfiles++;
727    return true;
728 }
729
730 //************************************
731 bool ghs3dprl_mesh_wrap::ReadFileNOBOITEB(const QString FileName)
732 //read file .noboiteb (volume)
733 //for huge files it could be better use ReadFileNOBOITEB (B=binary format)
734 //but NOT parameter option of tepal
735 //idem ReadFileNOBOITE with read unformatted
736 {
737    bool ok;
738    QString tmp;
739    std::cerr<<"Problem function ReadFileNOBOITEB\n"
740        <<"(no FORTRAN binary format files in tepal)\n\n";
741    //file binary
742    FILE *Ff=fopen(FileName.toLatin1().constData(),"rb");
743    long ne,np,npfixe,reste,subnumber;
744
745    //http://www.math.utah.edu/software/c-with-fortran.html
746    //record 1 from format FORTRAN begins and ends with lengh of record
747    //=> 2*long(68)     (68=17*4octets)
748    long r1[17+2];
749    if (!Ff){
750       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
751       return false;
752    }
753    //read datas :
754    fread(&r1,sizeof(long),17+2,Ff);
755    for (long i=1; i<18; i++) std::cout<<"R1("<<i<<")="<<r1[i]<<std::endl;
756
757    if (r1[0]!=68){
758       std::cerr<<"First FORTRAN record of File '"<<FileName.toLatin1().constData()<<"' not length 17*long"<<std::endl;
759       return false;
760    }
761    ne=r1[1];
762    np=r1[2];
763    npfixe=r1[3];
764    if (verbose>3){
765       std::cout<<"NoboitebNumberOfElements="<<ne<<std::endl;
766       std::cout<<"NoboitebNumberOfVertices="<<np<<std::endl;
767       std::cout<<"NoboitebNumberOfSpecifiedPoints="<<npfixe<<std::endl;
768    }
769    //etc...could be done if necessary not debugged
770    fread(&reste,sizeof(long),1,Ff);
771    long *tlong=new long[ne*4];
772    med_int *tmint=new med_int[ne*4];
773    fread(tlong,sizeof(long),ne*4,Ff);
774    fread(&reste,sizeof(long),1,Ff);
775    for (long i=0; i<ne*4; i++) tmint[i]=tlong[i];
776    delete tlong;
777    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[ne*4-1]<<std::endl;
778
779    CVWtab *montab=new CVWtab(ne*4,tmint);
780    tmp=tmp.sprintf("NB%ld EV",this->nofile);
781    ok=this->insert_key(tmp,montab);
782
783    fread(&reste,sizeof(long),1,Ff);
784    //std::cout<<"info "<<reste<<" "<<np*3<<" "<<sizeof(med_float)<<std::endl;
785    float *tfloat=new float[np*3];
786    med_float *tmflo=new med_float[np*3];
787    fread(tfloat,sizeof(float),np*3,Ff);
788    fread(&reste,sizeof(long),1,Ff);
789    for (long i=0; i<np*3; i++) tmflo[i]=tfloat[i];
790    delete tfloat;
791    if (verbose>4) printf("Vertices %g %g ... %g \n",tmflo[0],tmflo[1],tmflo[np*3-1]);
792
793    montab=new CVWtab(np*3,tmflo);
794    tmp=tmp.sprintf("NB%ld VC",this->nofile);
795    ok=this->insert_key(tmp,montab);
796
797    fread(&reste,sizeof(long),1,Ff);
798    fread(&subnumber,sizeof(long),1,Ff);
799    fread(&reste,sizeof(long),1,Ff);
800    if (verbose>2) std::cout<<"NumberOfSubdomains="<<subnumber<<std::endl;
801    fread(&reste,sizeof(long),1,Ff);
802    tlong=new long[subnumber*3];
803    fread(tlong,sizeof(long),subnumber*3,Ff);
804    fread(&reste,sizeof(long),1,Ff);
805    if (verbose>4) printf("Subdomains %ld %ld ... %ld \n",tlong[0],tlong[1],tlong[subnumber*3-1]);
806
807    tmint=new med_int[subnumber*3];
808    for (long i=0; i<subnumber*3; i++) tmint[i]=tlong[i];
809    delete tlong;
810    montab=new CVWtab(subnumber*3,tmint);
811    tmp=tmp.sprintf("NB%ld SN",this->nofile);
812    ok=this->insert_key(tmp,montab);
813
814    //swap on file if too big for memory in one cpu
815    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
816    if (np*3>this->nbelem_limit_swap)
817      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
818
819    //beware record 6 lenght 1
820    //ferme le fichier :
821    fclose(Ff);
822    this->nbfiles++;
823    return true;
824 }
825
826 //************************************
827 bool ghs3dprl_mesh_wrap::ReadFilePOINTS(const QString FileName)
828 //read file .points (wrap)
829 {
830    QString tmp;
831    long nb;
832    long maxlen=128;
833    bool ok=true;
834
835    //Lit les donn�s :
836    QFile Ff(FileName);
837    //NOT Raw because Raw=non-buffered file access
838    //qt3 ok=Ff.open(IO_ReadOnly|IO_Translate);
839    ok=Ff.open(QIODevice::ReadOnly|QIODevice::Text);
840    if (!ok){
841       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
842       return false;
843    }
844    tmp=Ff.readLine(maxlen);
845    tmp=tmp.simplified();
846    nb=tmp.toLong(&ok);
847    if (!ok){
848       std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
849       return false;
850    }
851    if (verbose>2) std::cout<<"NumberOfVertices="<<nb<<std::endl;
852    med_float *tmflo=new med_float[3*nb]; //coordinates
853    med_int *tmint=new med_int[nb];         //nrs (attribute of point)
854    long il3=0;
855    for ( long il=0; il<nb; il++ ){
856       tmp=Ff.readLine(maxlen);
857       tmp=tmp.simplified();
858       for ( int j=0; j<3; j++ ){
859          tmflo[il3]=tmp.section(' ',j,j).toDouble(&ok);
860          //std::cout<<"cv '"<<tmflo[il3]<<"' "<<il3<<std::endl;
861          il3++;
862          if (!ok){
863             std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
864             return false;
865          }
866       }
867       //nrs is vertex attribute
868       tmint[il]=tmp.section(' ',3,3).toLong(&ok);
869       if (!ok){
870          std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
871          return false;
872       }
873    }
874    //beware no examples with each specified points (if any) here
875    CVWtab *montab=new CVWtab(nb,tmint); //init montab->tmint nrs
876    tmp=tmp.sprintf("PO%ld NRS",this->nofile);
877    ok=this->insert_key(tmp,montab);
878
879    montab=new CVWtab(nb,tmflo); //init montab->tmflo xyz
880    tmp=tmp.sprintf("PO%ld XYZ",this->nofile);
881    ok=this->insert_key(tmp,montab);
882
883    //Ferme le fichier :
884    Ff.close();
885    this->nbfiles++;
886    return true;
887 }
888
889 //************************************
890 bool ghs3dprl_mesh_wrap::list_keys_mesh_wrap()
891 {
892    QHashIterator<QString,CVWtab*> it( this->mestab);
893    while ( it.hasNext() ) {
894      it.next();
895      QString nom = it.key().leftJustified(32,' ');
896      std::cout<<nom.toLatin1().constData()<<"-> size="<<it.value()->size<<std::endl;
897    }
898    return true;
899 }
900
901 //************************************
902 long ghs3dprl_mesh_wrap::remove_all_keys_mesh_wrap()
903 {
904    long nb=this->remove_key_mesh_wrap(QRegExp(".",Qt::CaseSensitive,QRegExp::RegExp));
905    return nb;
906 }
907
908 //************************************
909 long ghs3dprl_mesh_wrap::remove_key_mesh_wrap(const QRegExp &rxp)
910 {
911    long nbremove=0;
912    QMutableHashIterator<QString,CVWtab*> it(this->mestab);
913    while ( it.hasNext() ){
914      it.next();
915      if (it.key().contains(rxp)) {
916         nbremove++;
917         if (this->verbose>6) std::cout<<"remove key "<<it.key().toLatin1().constData()<<std::endl;
918         delete it.value();
919         it.remove();
920      }
921    }
922    return nbremove;
923 }
924
925 //************************************
926 long ghs3dprl_mesh_wrap::nb_key_mesh_wrap(const QRegExp &rxp)
927 {
928    long nbremove=0;
929    //std::cout<<"nb_key_mesh_wrap on "<<std::endl;
930    QMutableHashIterator<QString,CVWtab*> it(this->mestab);
931    while ( it.hasNext() ){
932      it.next();
933      if (it.key().contains(rxp)) nbremove++;
934    }
935    //std::cout<<"nb_key_mesh_wrap found "<<nbremove<<std::endl;
936    return nbremove;
937 }
938
939 //************************************
940 bool SwapOnFile(const QString &key,const QString &path,CVWtab *tab,int verbose)
941 //
942 {
943    //return true;
944    if (tab->filename=="_NO_FILE"){
945       tab->filename=path+key+".tmp";
946       tab->filename.replace(" ","_"); //replace " " by "_"
947
948       //swap disque binaire
949       //montab->tmint=new long[10]; //for test
950       //for (int i=0; i<10; i++) montab->tmint[i]=i*2;
951       FILE *fichier=fopen(tab->filename.toLatin1().constData(),"wb");
952       long taille;
953       taille=tab->size;
954       fwrite(&taille,sizeof(taille),1,fichier);
955       if (tab->tmint){
956          if (verbose>3)
957          std::cout<<"SwapOnFile_binary "<<tab->filename.toLatin1().constData()<<
958          " NbElements "<<taille<<
959          " SizeElement_med_int   "<<sizeof(med_int)<<
960          " TotalSizeBinary " <<taille*sizeof(med_int)<<std::endl;
961          fwrite(tab->tmint,sizeof(med_int),taille,fichier);
962          //fread(&gagnants,sizeof(gagnants),1,fichier);
963       }
964       if (tab->tmflo){
965          if (verbose>3)
966          std::cout<<"SwapOnFile_binary "<<tab->filename.toLatin1().constData()<<
967          " NbElements "<<taille<<
968          " SizeElement_med_float "<<sizeof(med_float)<<
969          " TotalSizeBinary " <<taille*sizeof(med_float)<<std::endl;
970          fwrite(tab->tmflo,sizeof(med_float),taille,fichier);
971       }
972       fclose(fichier);
973    }
974    else{
975       if (verbose>3) std::cout<<"SwapOnFile in binary file done yet "<<
976          tab->filename.toLatin1().constData()<<std::endl;
977    }
978    //deallocate because swap disk binary mode
979    tab->CVWtab_deallocate(); //free memory
980    return true;
981 }
982
983 //************************************
984 long ghs3dprl_mesh_wrap::SwapOutOfMemory_key_mesh_wrap(const QRegExp &rxp,
985                                                        long ifgreaterthan)
986 //swap on file if not yet and if size greater than ifgreaterthan
987 {
988    long nb=0;
989    bool ok;
990    QHashIterator<QString,CVWtab*> it(this->mestab);
991    while ( it.hasNext() ) {
992      it.next();
993      if (it.key().contains(rxp)) {
994         nb++;
995         if ((it.value()->size>0)&&(it.value()->size>ifgreaterthan)){
996            if (verbose>3)
997               std::cout<<"SwapOutOfMemory_key_mesh_wrap on demand "<<
998                    it.key().toLatin1().constData()<<
999                    " size "<<it.value()->size<<">"<<ifgreaterthan<<std::endl;
1000            //free memory
1001            ok=SwapOnFile(it.key(),this->path,it.value(),this->verbose);
1002        }
1003      }
1004    }
1005    return nb;
1006 }
1007 //************************************
1008 bool ghs3dprl_mesh_wrap::list_onekey_mesh_wrap(const QString &key)
1009 {
1010    CVWtab *montab=this->mestab[key];
1011    if (montab){
1012       //std::cout<<"key "<<key<<"trouvee -> size="<<montab->size<<std::endl;
1013       if (montab->type==1)
1014          for ( long i=0; i<montab->size; i++ )
1015             std::cout<<montab->tmint[i]<<" ";
1016       if (montab->type==2)
1017          for ( long i=0; i<montab->size; i++ )
1018             std::cout<<montab->tmflo[i]<<" ";
1019       std::cout<<std::endl;
1020    }
1021    else
1022       std::cout<<"key "<<key.toLatin1().constData()<<" not found"<<std::endl;
1023    return true;
1024 }
1025
1026 //************************************
1027 bool ghs3dprl_mesh_wrap::insert_key(const QString &key,CVWtab *tab)
1028 //insertion conditionn� par limite this->nbelem_limit_swap
1029 //si tableaux contenus on dimension superieure
1030 //alors swap disque dans getenv(tmp) fichier temporaire binaire
1031 {
1032    bool ok;
1033    if (verbose>4)
1034       std::cout<<"insert key "<<key.toLatin1().constData()<<
1035             " size="<<tab->size<<std::endl;
1036    tab->filename="_NO_FILE";
1037    if (this->nbelem_limit_swap<tab->size) {
1038       if (verbose>3) std::cout<<"insert key automatic SwapOnFile "<<
1039                            key.toLatin1().constData()<<std::endl;
1040       ok=SwapOnFile(key,this->path,tab,this->verbose);
1041    }
1042    this->mestab.insert(key,tab);
1043    return true;
1044 }
1045 //************************************
1046 CVWtab* ghs3dprl_mesh_wrap::restore_key(const QString &key)
1047 //retauration conditionn� par limite nbelem
1048 //si tableaux contenus on dimension superieure a nbelem
1049 //alors swap disque dans getenv(tmp) fichier temporaire
1050 //alors lecture du fichier (et reallocate memory)
1051 {
1052    CVWtab *tab=NULL;
1053    tab=this->mestab[key];
1054    /*if (tab) std::cout<<" -> size in proc "<<tab->size<<std::endl;
1055    else std::cout<<" -> tab NULL\n";*/
1056    if (!tab) //it is NOT a problem
1057    {
1058       if (verbose>6) std::cout<<"restore key not found "<<key.toLatin1().constData()<<std::endl;
1059       return NULL;
1060    }
1061    if (tab->size > 0){
1062       if (verbose>5) std::cout<<"restore key direct from memory "<<key.toLatin1().constData()<<" size="<<tab->size<<std::endl;
1063       return tab;
1064    }
1065    //restore from binary file
1066    if ((tab->type<1)||(tab->type>2)){
1067       std::cerr<<"Problem restore key from binary file "<<tab->filename.toLatin1().constData()<<
1068                " type unexpexted "<<tab->type<<std::endl;
1069       return NULL;
1070    }
1071    //std::cout<<"restore_key from binary file "<<tab->filename<<std::endl;
1072
1073    //swap disque binaire
1074    FILE *fichier=fopen(tab->filename.toLatin1().constData(),"rb");
1075    long taille;
1076    fread(&taille,sizeof(long),1,fichier);
1077    if (taille!=-tab->size){
1078       std::cerr<<"Problem restore_key from binary file "<<tab->filename.toLatin1().constData()<<
1079             " size unexpexted "<<taille<<" expected "<<-tab->size<<std::endl;
1080       fclose(fichier);
1081       return NULL;
1082    }
1083    if (tab->type==1){
1084       if (verbose>5)
1085       std::cout<<"restore key from binary file "<<tab->filename.toLatin1().constData()<<
1086             " number of elements "<<taille<<
1087             " size_element med_float "<<sizeof(med_float)<<
1088             " total_size_binary " <<taille*sizeof(med_float)<<std::endl;
1089
1090       //allocate because swap disque binaire
1091       tab->tmint=new med_int[taille]; //allocate memory
1092       fread(tab->tmint,sizeof(med_int),taille,fichier);
1093    }
1094    if (tab->type==2){
1095       if (verbose>5)
1096       std::cout<<"restore key from binary file "<<tab->filename.toLatin1().constData()<<
1097             " number of elements "<<taille<<
1098             " size_element med_float "<<sizeof(med_float)<<
1099             " total_size_binary " <<taille*sizeof(med_float)<<std::endl;
1100       //allocate because swap disque binaire
1101       tab->tmflo=new med_float[taille]; //allocate memory
1102       for (int i=0; i<taille ; i++) tab->tmflo[i]=-1e0;
1103       fread(tab->tmflo,sizeof(med_float),taille,fichier);
1104       /*for (int i=0; i<taille ; i++) std::cout<<tab->tmflo[i]<<"/";
1105       std::cout<<std::endl;*/
1106    }
1107    fclose(fichier);
1108    tab->size=-tab->size;
1109    return tab;
1110 }
1111
1112 //************************************
1113 bool ghs3dprl_mesh_wrap::test_msg_wrap()
1114 //tests sur resultats fichiers msg
1115 {
1116    QString key1,key2,typ="FA VE ED EL"; //pour faces vertice edges elements
1117    CVWtab *tab1,*tab2;
1118    bool ok=true;
1119    //test send=receive
1120    //numerotations locales sont identiques
1121    long nb=typ.count(' ',Qt::CaseSensitive) + 1; //nb chiffres detectes
1122    for (long i=0; i < nb; i++)
1123    for (long ifile=1; ifile <= this->nbfiles; ifile++)
1124    for (long ineig=1; ineig <= this->nbfiles; ineig++)
1125    {
1126       if (ifile==ineig) continue; //impossible
1127       key1=key1.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" SE";
1128       key2=key2.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" RE";
1129       //std::cout<<"key "<<key1<<" et key "<<key2<<std::endl;
1130       tab1=this->restore_key(key1);
1131       //tab1=this->mestab[key1];
1132       tab2=this->restore_key(key2);
1133       //tab2=this->mestab[key2];
1134       //std::cout<<"sortie key "<<key1<<" et key "<<key2<<std::endl;
1135       if (!tab1 && !tab2) continue; //case not neighbours
1136       if (!tab1)
1137       {  std::cout<<"key "<<key1.toLatin1().constData()<<" inexistante avec key "<<key2.toLatin1().constData()<<" existante"<<std::endl;
1138          ok=false;
1139       }
1140       else
1141       {
1142        if (!tab2)
1143        {  std::cout<<"key "<<key2.toLatin1().constData()<<" inexistante avec key "<<key1.toLatin1().constData()<<" existante"<<std::endl;
1144           ok=false;
1145        }
1146        else
1147         if (!tab1->is_equal(tab2))
1148         {  std::cout<<"key "<<key1.toLatin1().constData()<<" et key "<<key2.toLatin1().constData()<<" de contenu differents"<<std::endl;
1149            ok=false;
1150         }
1151       }
1152       /*else
1153          printf("key '%s' et key '%s' identiques \n",
1154                            (const char *)key2,(const char *)key1);*/
1155    }
1156
1157    //test size neighbourg=ifile
1158    //numerotations locales sont differentes mais de tailles identiques
1159    //pas besoin de verifier " RE " car deja fait au dessus
1160    for (long i=0; i < nb; i++)
1161    for (long ifile=1; ifile <= this->nbfiles; ifile++)
1162    for (long ineig=ifile+1; ineig <= this->nbfiles; ineig++)
1163    {
1164       if (ifile==ineig) continue; //cas impossible
1165       key1=key1.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" SE";
1166       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1167       key2=key2.sprintf("MS%ld NE%ld ",ineig,ifile)+typ.section(' ',i,i)+" SE";
1168       tab2=this->restore_key(key2); //tab2=this->mestab[key2];
1169       if (!tab1 && !tab2) continue; //case not neighbours
1170       if (!tab1)
1171       {  std::cout<<"key "<<key1.toLatin1().constData()<<" inexistante avec key "<<key2.toLatin1().constData()<<" existante"<<std::endl;
1172          ok=false;
1173       }
1174       else
1175       {
1176        if (!tab2)
1177        {  std::cout<<"key "<<key2.toLatin1().constData()<<" inexistante avec key "<<key1.toLatin1().constData()<<" existante"<<std::endl;
1178           ok=false;
1179        }
1180        else
1181         if ((tab1->type!=tab2->type)||(tab1->size!=tab2->size))
1182         {  std::cout<<"key "<<key1.toLatin1().constData()<<" et key "<<key2.toLatin1().constData()<<" de type ou tailles differents"<<std::endl;
1183            ok=false;
1184         }
1185       }
1186    }
1187    return ok;
1188 }
1189
1190 //************************************
1191 bool ghs3dprl_mesh_wrap::test_vertices_wrap()
1192 //tests sur vertices
1193 {
1194    QString key1,key2,key11,key22,key11old,key22old;
1195    CVWtab *tab1,*tab2,*tab11,*tab22;
1196    bool ok=true;
1197    key11old="_NO_KEY";key22old="_NO_KEY";
1198    //test size neighbourg=ifile
1199    //numerotations locales sont differentes mais de tailles identiques
1200    //pas besoin de verifier " RE " car deja fait au dessus
1201    //for (int ifile=1; ifile <= this->nbfiles; ifile++)
1202    //for (int ineig=ifile+1; ineig <= this->nbfiles; ineig++)
1203    bool swap=false;
1204    for (int ifile=this->nbfiles; ifile >= 1; ifile--)
1205    for (int ineig=this->nbfiles; ineig >= ifile+1; ineig--)
1206    {
1207       if (ifile==ineig) continue; //cas impossible
1208       key1=key1.sprintf("MS%d NE%d VE SE",ifile,ineig);
1209       key11=key11.sprintf("NB%d VC",ifile);
1210       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1211       key2=key2.sprintf("MS%d NE%d VE SE",ineig,ifile);
1212       key22=key22.sprintf("NB%d VC",ineig);
1213       tab2=this->restore_key(key2); //tab2=this->mestab[key2];
1214       if (!tab1 && !tab2) continue; //cas non voisins
1215       if (!tab1)
1216       {
1217          std::cerr<<"TestEqualityCoordinates key "<<key1.toLatin1().constData()<<
1218                " NOT existing but key "<<key2.toLatin1().constData()<<" existing"<<std::endl;
1219          ok=false; continue;
1220       }
1221       if (!tab2)
1222       {
1223          std::cerr<<"TestEqualityCoordinates key "<<key2.toLatin1().constData()<<
1224                " NOT existing but key "<<key1.toLatin1().constData()<<" existing"<<std::endl;
1225          ok=false; continue;
1226       }
1227       if (tab1->size!=tab2->size)
1228       {
1229          std::cerr<<"TestEqualityCoordinates key "<<key1.toLatin1().constData()<<
1230                " and key "<<key2.toLatin1().constData()<<" NOT same size"<<std::endl;
1231          ok=false; continue;
1232       }
1233       if (ok)
1234       {
1235          if (swap) {
1236             //Swap out of memory if no use
1237             if ((key11old!=key11)&&(key11old!=key22))
1238                this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key11old,Qt::CaseSensitive,QRegExp::RegExp));
1239             if ((key22old!=key11)&&(key22old!=key22))
1240                this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key22old,Qt::CaseSensitive,QRegExp::RegExp));
1241          }
1242          tab11=this->restore_key(key11); //tab11=this->mestab[key11];
1243          tab22=this->restore_key(key22); //tab22=this->mestab[key22];
1244          if (tab11->size>this->nbelem_limit_swap ||
1245              tab22->size>this->nbelem_limit_swap) swap=true ;
1246          long i1,i2;
1247          bool ok1=true;
1248          //test on equality of xyz_coordinates of commons vertices
1249          for  (long j=0; j < tab1->size-1; j++)
1250          {
1251             i1=tab1->tmint[j];
1252             i2=tab2->tmint[j];
1253             //1 for print vertices not equals
1254             if (!CVW_is_equal_vertices(tab11,i1,tab22,i2,1))
1255             {
1256                std::cerr<<j<<" Vertice "<<i1<<" != Vertice "<<i2<<"\n"<<std::endl;
1257                ok=false; ok1=false;
1258             }
1259          }
1260          if ((verbose>2)&&(ok1))
1261             std::cout<<"TestEqualityCoordinates "<<tab1->size<<
1262                   " Vertices "<<key1.toLatin1().constData()<<" and "<<key2.toLatin1().constData()<<" ok"<<std::endl;
1263          if (!ok1)
1264             std::cerr<<"TestEqualityCoordinates "<<tab1->size<<
1265                   " Vertices "<<key1.toLatin1().constData()<<" and "<<key2.toLatin1().constData()<<" NO_OK"<<std::endl;
1266          key11old=key11; key22old=key22;
1267       }
1268    }
1269    //Swap out of memory (supposed no use?)
1270    //NO because NB1&NB2 VC supposed future use
1271    //YES precaution
1272    if (swap) {
1273       this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key11old,Qt::CaseSensitive,QRegExp::RegExp));
1274       this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key22old,Qt::CaseSensitive,QRegExp::RegExp));
1275    }
1276    return ok;
1277 }
1278
1279 //************************************
1280 bool ghs3dprl_mesh_wrap::Find_VerticesDomainToVerticesSkin()
1281 //initialise correspondances vertice skin et vertices locaux pour chaque domaine
1282 //calcule un med_int new tab[nb_vertices_of_domain]
1283 //avec nieme vertice of skin=tab[ieme vertice de domain]
1284 //apres verification tepal garde bien dans la global numbering "GLi VE"
1285 //les indices initiaux des noeuds (attention: de 1 a nbNodes) 
1286 {
1287    QString key1,key2,tmp;
1288    CVWtab *cooskin,*coodom,*glodom,*montab;
1289    bool ok=true;
1290    med_float *p1,*p2;
1291    med_int i,nb,jd,js;
1292
1293    cooskin=this->restore_key(QString("SKIN_VERTICES_COORDINATES"));
1294    if (!cooskin) return false;
1295    if (verbose>4)std::cout<<"NumberVerticesSKIN="<<cooskin->size/3<<std::endl;
1296    //ici pourrait creer BBtree sur skin
1297    for (int ifile=1; ifile<=this->nbfiles; ifile++)
1298    {
1299       key1=key1.sprintf("NB%ld VC",ifile);
1300       coodom=this->restore_key(key1);
1301       if (!coodom) continue; //Problem
1302       key2=key2.sprintf("GL%ld VE",ifile);
1303       glodom=this->restore_key(key2);
1304       if (verbose>4)
1305          std::cout<<"NumberVerticesDOMAIN_"<<ifile<<"="<<glodom->size<<std::endl;
1306       if (coodom->size!=glodom->size*3)
1307       {
1308          std::cerr<<"Find_VerticesDomainToVerticesSkin key "<<key1.toLatin1().constData()<<
1309                " and key "<<key2.toLatin1().constData()<<" NOT coherent sizes"<<std::endl;
1310          ok=false; continue;
1311       }
1312       //test on equality of xyz_coordinates of commons vertices
1313       med_int *tab=new med_int[glodom->size];
1314       i=0;
1315       nb=0; //nb equals vertices
1316     if (verbose>8){
1317       std::cout<<"\nglobal numbering nodes: no iglo\n";
1318       for  (jd=0; jd < glodom->size; jd++) 
1319            std::cout<<"\t"<<jd<<"\t"<<glodom->tmint[jd]<<std::endl;
1320       std::cout<<"\nresults: no i js iglo\n";
1321       for  (jd=0; jd < coodom->size; jd=jd+3)
1322       {
1323          p2=(coodom->tmflo+jd);
1324          tab[i]=0;
1325          //ici pourrait utiliser BBtree
1326          for  (js=0; js < cooskin->size; js=js+3)
1327          {
1328             p1=(cooskin->tmflo+js);
1329             if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]) 
1330             {
1331                std::cout<<"\t"<<nb<<"\t"<<i<<"\t"<<js/3<<"\t"<<glodom->tmint[i]-1<<
1332                  key2.sprintf("\t%13.5e%13.5e%13.5e",p1[0],p1[1],p1[2]).toLatin1().constData()<<std::endl;
1333                tab[i]=js/3; nb++; continue;
1334             }
1335          }
1336          i++;
1337       }
1338       montab=new CVWtab(glodom->size,tab);
1339       tmp=tmp.sprintf("NB%ld GL_SKIN",ifile);
1340       ok=this->insert_key(tmp,montab);
1341       if (verbose>4){
1342          std::cout<<"NumberOfEqualsVerticesDOMAIN_"<<ifile<<"="<<nb<<std::endl;
1343       }
1344     }
1345    }
1346    return ok;
1347 }
1348
1349 //fin utils procedures
1350
1351 //************************************
1352 bool ghs3dprl_mesh_wrap::Write_masterxmlMEDfile()
1353 {
1354    QString tmp;
1355
1356    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!first call
1357    if (idom==1)
1358    {
1359    //define master file (.xml) in memory
1360    tmp=path+medname+".xml";
1361    filemaster=tmp.toLatin1().constData();
1362    domainname=medname.toLatin1().constData();
1363    char buff[256];
1364
1365    //Creating the XML document
1366    master_doc = xmlNewDoc(BAD_CAST "1.0");
1367    root_node = xmlNewNode(0, BAD_CAST "root");
1368    xmlDocSetRootElement(master_doc,root_node);
1369
1370    //Creating child nodes
1371    //Version tag
1372    med_int majeur,mineur,release;
1373    //Quelle version de MED est utilis�
1374    MEDlibraryNumVersion(&majeur,&mineur,&release);
1375    if (verbose>0) fprintf(stdout,"Files write with MED V%d.%d.%d\n",majeur,mineur,release);
1376    node = xmlNewChild(root_node, 0, BAD_CAST "version",0);
1377    //xmlNewProp(node, BAD_CAST "maj", BAD_CAST int2string2(majeur).c_str());
1378    xmlNewProp(node, BAD_CAST "maj", BAD_CAST i2a(majeur).c_str());
1379    xmlNewProp(node, BAD_CAST "min", BAD_CAST i2a(mineur).c_str());
1380    xmlNewProp(node, BAD_CAST "ver", BAD_CAST i2a(release).c_str());
1381
1382    //Description tag
1383    node = xmlNewChild(root_node,0, BAD_CAST "description",0);
1384    xmlNewProp(node, BAD_CAST "what", BAD_CAST "tetrahedral mesh by tepal");
1385 #ifdef WIN32
1386   SYSTEMTIME  present;
1387   GetLocalTime ( &present );
1388   sprintf(buff,"%04d/%02d/%02d %02dh%02dm",
1389           present.wYear,present.wMonth,present.wDay,
1390           present.wHour,present.wMinute);
1391 #else
1392    time_t present;
1393    time(&present);
1394    struct tm *time_asc = localtime(&present);
1395    sprintf(buff,"%04d/%02d/%02d %02dh%02dm",
1396            time_asc->tm_year+1900,time_asc->tm_mon+1,time_asc->tm_mday,
1397            time_asc->tm_hour,time_asc->tm_min);
1398 #endif
1399    xmlNewProp(node, BAD_CAST "when", BAD_CAST buff);
1400    xmlNewProp(node, BAD_CAST "from", BAD_CAST "tepal2med");
1401
1402    //Content tag
1403    node =xmlNewChild(root_node,0, BAD_CAST "content",0);
1404    node2 = xmlNewChild(node, 0, BAD_CAST "mesh",0);
1405    xmlNewProp(node2, BAD_CAST "name", BAD_CAST domainname.c_str());
1406    info_node = xmlNewChild(node, 0, BAD_CAST "tepal2med_info",0);
1407
1408    //Splitting tag
1409    node=xmlNewChild(root_node,0,BAD_CAST "splitting",0);
1410    node2=xmlNewChild(node,0,BAD_CAST "subdomain",0);
1411    xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbfilestot).c_str());
1412    node2=xmlNewChild(node,0,BAD_CAST "global_numbering",0);
1413    xmlNewProp(node2, BAD_CAST "present", BAD_CAST "yes");
1414
1415    //Files tag
1416    files_node=xmlNewChild(root_node,0,BAD_CAST "files",0);
1417
1418    //Mapping tag
1419    node = xmlNewChild(root_node,0,BAD_CAST "mapping",0);
1420    mesh_node = xmlNewChild(node, 0, BAD_CAST "mesh",0);
1421    xmlNewProp(mesh_node, BAD_CAST "name", BAD_CAST domainname.c_str());
1422    }
1423
1424    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!all calls
1425    {
1426    char *hostname = getenv("HOSTNAME");
1427    node = xmlNewChild(files_node,0,BAD_CAST "subfile",0);
1428    xmlNewProp(node, BAD_CAST "id", BAD_CAST i2a(idom).c_str());
1429    node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST distfilename);
1430    if (hostname == NULL)
1431       node2 = xmlNewChild(node, 0, BAD_CAST "machine",BAD_CAST "localhost");
1432    else
1433       node2 = xmlNewChild(node, 0, BAD_CAST "machine",BAD_CAST hostname);
1434
1435    node = xmlNewChild(mesh_node,0,BAD_CAST "chunk",0);
1436    xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST i2a(idom).c_str());
1437    node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST nomfinal);
1438
1439    //tepal2med_info
1440    node = xmlNewChild(info_node, 0, BAD_CAST "chunk",0);
1441    xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST i2a(idom).c_str());
1442    xmlNewProp(node, BAD_CAST "nodes_number", BAD_CAST i2a(nbnodes).c_str());
1443    xmlNewProp(node, BAD_CAST "faces_number", BAD_CAST i2a(nbtria3).c_str());
1444    xmlNewProp(node, BAD_CAST "tetrahedra_number", BAD_CAST i2a(nbtetra4).c_str());
1445    //node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST nomfinal);
1446
1447    //node2 = xmlNewChild(node, 0, BAD_CAST "nodes", 0);
1448    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbnodes).c_str());
1449    //node2 = xmlNewChild(node, 0, BAD_CAST "faces", 0);
1450    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtria3).c_str());
1451    //node2 = xmlNewChild(node, 0, BAD_CAST "tetrahedra", 0);
1452    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtetra4).c_str());
1453
1454    //tepal2med_info about joints of one subdomain
1455    xmlAddChild(node,joints_node);
1456    //tepal2med_info about groups and families of one subdomain
1457    xmlAddChild(node,families.xml_groups());
1458    }
1459
1460    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!last call
1461    if (idom==nbfilestot)
1462    {
1463    node2 = xmlNewChild(info_node, 0, BAD_CAST "global",0);
1464    xmlNewProp(node2, BAD_CAST "tetrahedra_number", BAD_CAST i2a(nbtetrastotal).c_str());
1465    //save masterfile
1466    xmlSaveFormatFileEnc(filemaster.c_str(), master_doc, "UTF-8", 1);
1467    xmlFreeDoc(master_doc);
1468    xmlCleanupParser();
1469    }
1470    return true;
1471 }
1472
1473
1474 //************************************
1475 bool ghs3dprl_mesh_wrap::Write_MEDfiles_v2(bool deletekeys)
1476 //deletekeys=true to delete non utils keys and arrays "au fur et a mesure"
1477 {
1478    bool ok=true,oktmp;
1479    QString tmp,cmd;
1480    char description[MED_COMMENT_SIZE];
1481    char dtunit[MED_SNAME_SIZE+1]="_NO_UNIT";
1482    char axisname[MED_SNAME_SIZE*3+1]="x               y               z               ";
1483    char axisunit[MED_SNAME_SIZE*3+1]="_NO_UNIT        _NO_UNIT        _NO_UNIT        ";
1484    med_int nb;
1485    
1486    //remove path
1487    //precaution because casename->med_nomfinal no more 32 character
1488    //if path, in this->path.
1489    //20 preserve for add postfixes "_idom" etc...
1490    if (verbose>0)std::cout<<"\nWrite_MEDfiles_v2\n";
1491    if (verbose>6){std::cout<<"\nInitialFamilies\n"; families.write();}
1492
1493    medname=medname.section('/',-1);
1494    if (medname.length()>20) {
1495       std::cerr<<"CaseNameMed truncated (no more 20 characters)"<<std::endl;
1496       medname.truncate(20);
1497    }
1498
1499    //create file resume DOMAIN.joints.med of all joints for quick display (...may be...)
1500    tmp=path+medname+tmp.sprintf("_joints.med",idom);
1501    charendnull(distfilename,tmp,MED_COMMENT_SIZE);
1502    fidjoint=MEDfileOpen(distfilename,MED_ACC_CREAT);
1503    if (fidjoint<0) std::cerr<<"Problem MEDfileOpen "<<distfilename<<std::endl;
1504    if (verbose>0) std::cout<<"CreateMEDFile for all joints <"<<distfilename<<">\n";
1505
1506    //copy file source/GHS3DPRL_skin.med as destination/DOMAIN.skin.med
1507    tmp=path+medname+"_skin.med";
1508    cmd=pathini+casename+"_skin.med";
1509    int ret = access(cmd.toLatin1().constData(),F_OK); //on regarde si le fichier existe
1510    if (ret >= 0) {
1511 #ifdef WIN32
1512       cmd="copy ";
1513 #else 
1514       cmd="cp ";
1515 #endif
1516       cmd = cmd+pathini+casename+"_skin.med "+tmp;
1517       //std::cout<<"Copy skin.med Command = "<<cmd<<std::endl;
1518       system(cmd.toLatin1().constData()); 
1519       if (verbose>0) std::cout<<"CreateMEDFile for initial skin <"<<tmp.toLatin1().constData()<<">\n"; }
1520    else {
1521       if (verbose>0) std::cout<<"No CreateMEDFile <"<<tmp.toLatin1().constData()<<"> for initial skin because <"<<
1522                                                 cmd.toLatin1().constData()<<"> does not exist\n"; }
1523
1524    //define family 0 if not existing, no groups
1525    families.add("0","");
1526    //define family Group_of_New_Nodes (which not exists before tetrahedra)
1527    famallnodes=0;
1528    if (QString("All_Nodes").contains(deletegroups)==0){
1529       oktmp=families.get_number_of_new_family(1,&famallnodes,&tmp);
1530       families.add(tmp,"All_Nodes");
1531    }
1532    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Nodes\"\n";
1533    
1534    famalltria3=0;
1535    if (QString("All_Faces").contains(deletegroups)==0){
1536       oktmp=families.get_number_of_new_family(-1,&famalltria3,&tmp);
1537       families.add(tmp,"All_Faces");
1538    }
1539    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Faces\"\n";
1540
1541    famalltetra4=0;
1542    if (QString("All_Tetrahedra").contains(deletegroups)==0){
1543       oktmp=families.get_number_of_new_family(-1,&famalltetra4,&tmp);
1544       families.add(tmp,"All_Tetrahedra");
1545    }
1546    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Tetrahedra\"\n";
1547
1548    famnewnodes=0;
1549    if (QString("New_Nodes").contains(deletegroups)==0){
1550       oktmp=families.get_number_of_new_family(1,&famnewnodes,&tmp);
1551       families.add(tmp,"New_Nodes");
1552    }
1553    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Nodes\"\n";
1554    
1555    famnewtria3=0;
1556    if (QString("New_Faces").contains(deletegroups)==0){
1557       oktmp=families.get_number_of_new_family(-1,&famnewtria3,&tmp);
1558       families.add(tmp,"New_Faces");
1559    }
1560    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Faces\"\n";
1561    
1562    famnewtetra4=0;
1563    if (QString("New_Tetrahedra").contains(deletegroups)==0){
1564       oktmp=families.get_number_of_new_family(-1,&famnewtetra4,&tmp);
1565       families.add(tmp,"New_Tetrahedra");
1566    }
1567    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Tetrahedra\"\n";
1568
1569    if (verbose>6){std::cout<<"\nIntermediatesFamilies\n"; families.write();}
1570    if (verbose>6) std::cout<<"\nNumber0fFiles="<<nbfilestot<<std::endl;
1571    familles intermediatesfamilies=families;
1572    //initialisations on all domains
1573    nbtetrastotal=0;
1574
1575    //loop on the domains
1576    //for (idom=1; idom<=nbfilestot; idom++) {
1577    for (idom=1; idom<=nbfilestot; idom++) {
1578    
1579       this->nofile=idom;
1580       //restore initial context of families
1581       if (idom>1) families=intermediatesfamilies;
1582       //if (idom>1) continue;
1583       tmp=path+medname+tmp.sprintf("_%d.med",idom);
1584       charendnull(distfilename,tmp,MED_COMMENT_SIZE);
1585
1586       //std::cout<<"<"<<distfilename<<">"<<std::endl;
1587       fid=MEDfileOpen(distfilename,MED_ACC_CREAT);
1588       if (fid<0) {std::cerr<<"Problem MEDfileOpen "<<distfilename<<std::endl; goto erreur;}
1589       if (verbose>0){
1590          if (verbose>2) std::cout<<std::endl;
1591          std::cout<<"CreateMEDFile "<<idom<<" <"<<distfilename<<">\n";
1592       }
1593  
1594       //create mesh
1595       tmp=medname+tmp.sprintf("_%d",idom);
1596       charendnull(nomfinal,tmp,MED_NAME_SIZE);
1597       tmp=tmp.sprintf("domain %d among %d",idom,nbfilestot);
1598       charendnull(description,tmp,MED_COMMENT_SIZE);
1599
1600       if (verbose>4) std::cout<<"Description : "<<description<<std::endl;
1601       err=MEDmeshCr(fid,nomfinal,3,3,MED_UNSTRUCTURED_MESH,description,dtunit,MED_SORT_DTIT,MED_CARTESIAN,axisname,axisunit);
1602       if (err<0) {std::cerr<<"Problem MEDmeshCr"<<nomfinal<<std::endl; goto erreur;}
1603
1604       if (!idom_nodes()) {std::cerr<<"Problem on Nodes"<<std::endl; goto erreur;}
1605       if (!idom_edges()) {std::cerr<<"Problem on Edges"<<std::endl; goto erreur;}
1606       if (!idom_faces()) {std::cerr<<"Problem on Faces"<<std::endl; goto erreur;}
1607       if (!idom_tetras()) {std::cerr<<"Problem on tetrahedra"<<std::endl; goto erreur;}
1608       if (!idom_joints()) {std::cerr<<"Problem on Joints"<<std::endl; goto erreur;}
1609
1610       if (verbose>6){std::cout<<"\nFinalsFamilies\n"; families.write();}
1611       //for nodes families
1612       nb=create_families(fid,1);
1613       if (verbose>5)std::cout<<"NumberOfFamiliesNodes="<<nb<<std::endl;
1614
1615       err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,famnodes);
1616       if (verbose>8)
1617          std::cout<<"MEDmeshEntityFamilyNumberWr nodes "<<nbnodes<<":"<<
1618                famnodes[0]<<"..."<<famnodes[nbnodes-1]<<" "<<std::endl;
1619       delete[] famnodes;
1620       if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr nodes"<<std::endl;
1621
1622       //for others families
1623       nb=create_families(fid,-1);
1624       if (verbose>5)std::cout<<"NumberOfFamiliesFacesAndEdgesEtc="<<nb<<std::endl;
1625
1626       err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3,famtria3);
1627       if (verbose>8)
1628          std::cout<<"MEDmeshEntityFamilyNumberWr tria3 "<<nbtria3<<":"<<
1629                famtria3[0]<<"..."<<famtria3[nbtria3-1]<<" "<<std::endl;
1630       delete[] famtria3;
1631       if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr tria3"<<std::endl;
1632
1633       err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,nbtetra4,famtetra4);
1634       if (verbose>8)
1635          std::cout<<"MEDmeshEntityFamilyNumberWr tetra4 "<<nbtetra4<<":"<<
1636                famtetra4[0]<<"..."<<famtetra4[nbtria3-1]<<" "<<std::endl;
1637       delete[] famtetra4;
1638       if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr tria3"<<std::endl;
1639
1640       MEDfileClose(fid); //no error
1641       //master.xml writings
1642       oktmp=Write_masterxmlMEDfile();
1643       continue;       //and loop on others domains
1644
1645       erreur:         //error
1646       ok=false;
1647       MEDfileClose(fid); //but loop on others domains
1648
1649    }
1650    MEDfileClose(fidjoint); //no error
1651    if (verbose>0)std::cout<<"\nTotalNumberOftetrahedra="<<nbtetrastotal<<std::endl;
1652
1653    return ok;
1654 }
1655
1656 //************************************
1657 bool ghs3dprl_mesh_wrap::idom_nodes()
1658 {
1659    bool ok=true;
1660    QString tmp,key,key1,key2,key3;
1661    CVWtab *tab,*tab1,*tab2,*tab3;
1662    med_int i,j,*arrayi;
1663    int xx;
1664
1665       //writing node(vertices) coordinates
1666       //NBx VC=files.NoBoite Vertex Coordinates
1667       key=key.sprintf("NB%d VC",idom); //files.NoBoite Vertex Coordinates
1668       tab=this->restore_key(key); //tab1=this->mestab[key1];
1669       if (!tab) {
1670          tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".noboite";
1671          ok=this->ReadFileNOBOITE(tmp);
1672          tab=this->restore_key(key); //tab1=this->mestab[key1];
1673          if (!tab) return false;
1674       }
1675       tmp=tmp.sprintf("NB%d SN",idom);
1676       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
1677       xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
1678       nbnodes=tab->size/3;
1679       err=MEDmeshNodeCoordinateWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_FULL_INTERLACE,nbnodes,tab->tmflo);
1680       if (err<0) {std::cerr<<"Problem MEDmeshNodeCoordinateWr"<<std::endl; return false;}
1681       if (verbose>4)std::cout<<"NumberOfNodes="<<nbnodes<<std::endl;
1682
1683       //writing indices of nodes
1684       arrayi=new med_int[nbnodes];
1685       for (i=0; i<nbnodes ; i++) arrayi[i]=i+1;
1686       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,arrayi);
1687       delete[] arrayi;
1688       if (err<0) {std::cerr<<"Problem MEDmeshEntityNumberWr of nodes"<<std::endl; return false;}
1689
1690       key1=key1.sprintf("GL%d VE",idom); //global numerotation 
1691       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1692       if (!tab1) {
1693          tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
1694          ok=this->ReadFileGLO(tmp);
1695          if (!ok) {std::cerr<<"Problem file "<<tmp.toLatin1().constData()<<std::endl; return false;}
1696          tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1697          if (!tab1) return false;
1698       }
1699       if (nbnodes!=tab1->size){std::cerr<<"Problem size GLi VE!=nbnodes!"<<std::endl; return false;}
1700
1701       key2=key2.sprintf("SKIN_VERTICES_FAMILIES",idom); //on global numerotation 
1702       tab2=this->restore_key(key2); //tab1=this->mestab[key1];
1703       med_int nbskin=0; 
1704       if (tab2) med_int nbskin=tab2->size;
1705       //for (i=0; i<nbskin; i++) std::cout<<i<<" "<<tab2->tmint[i]<<std::endl;
1706
1707       //set families of nodes existing in GHS3DPRL_skin.med
1708       med_int nb=nbnodes;
1709       famnodes=new med_int[nb];
1710       for (i=0; i<nb ; i++) famnodes[i]=famallnodes;
1711       med_int * fammore=new med_int[nb];
1712       for (i=0; i<nb ; i++) fammore[i]=famnewnodes;
1713
1714       //set families of nodes of skin
1715       for (i=0; i<nb ; i++){
1716          j=tab1->tmint[i]-1; //
1717          if (j<nbskin){
1718             fammore[i]=tab2->tmint[j];
1719          }
1720       }
1721       ok=set_one_more_family(famnodes,fammore,nb);
1722       delete[] fammore;
1723
1724       //std::cout<<"nodes loc "<<i<<" = gl "<<j<<"\t << "<<tab2->tmint[j]<<
1725       //      tmp.sprintf("\t%23.15e%23.15e%23.15e",tab3->tmflo[i*3],
1726       //      tab3->tmflo[i*3+1],tab3->tmflo[i*3+2])<<std::endl;
1727
1728       //writing nodes(vertices) global numbering
1729       err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,tab1->tmint);
1730       if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr nodes"<<std::endl; return false;}
1731
1732    return ok;
1733 }
1734
1735 /*
1736 //************************************
1737 bool ghs3dprl_mesh_wrap::set_one_more_family_old(med_int *fami, med_int *more, med_int nb)
1738 //fuse array of med_int families more et fami as kind of groups 
1739 //because there are possibilities of intersections
1740 {
1741    QString tmp;
1742    med_int i,newfam,morfam,oldfam;
1743    for (i=0; i<nb ; i++) {
1744       if (more[i]==0) continue;
1745       if (fami[i]==0) {
1746          fami[i]=more[i];
1747          //std::cout<<"sur "<<i<<" en plus "<<more[i]<<std::endl;
1748       }
1749       else { //intersection
1750          if (fami[i]==more[i]) continue; //same families
1751          oldfam=fami[i];
1752          morfam=more[i];
1753          //create new family intersection if needed
1754          newfam=families.find_family_on_groups(oldfam,morfam);
1755          //std::cout<<"oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
1756          fami[i]=newfam;
1757       }
1758    }
1759    return true;
1760 }*/
1761
1762 //************************************
1763 bool ghs3dprl_mesh_wrap::set_one_more_family(med_int *fami, med_int *more, med_int nb)
1764 //fuse array of med_int families more et fami as kind of groups 
1765 //because there are possibilities of intersections
1766 {
1767    QString tmp;
1768    med_int i,ii,j,newfam,morfam,oldfam,morfami,oldfami,i_zero,nb_fam,nb_max,nb_tot,nb_mess;
1769    med_int *newfami;
1770
1771    nb_fam=families.fam.size(); //on families negative and positive
1772    //std::cout<<"size families "<<nb_fam<<std::endl;
1773    if (nb_fam<=0) nb_fam=5;    //precaution
1774    i_zero=nb_fam*2;            //offset for negative indices of families
1775    nb_max=nb_fam*4;
1776    if (nb_fam>300) std::cout<<
1777       "***set_one_more_family*** warning many initial families could decrease speed "<<nb_fam<<std::endl;
1778    nb_tot=nb_max*nb_max;       //max oversizing *2 on families
1779    //newfami is for speed (avoid calls find_family_on_groups)
1780    //it is an array[nb_fam*4][nb_fam*4] implemented on vector[nb_max]
1781    //to memorize newfam in array[oldfam][morfam]
1782    newfami=new med_int[nb_tot];
1783    for (i=0; i<nb_tot ; i++) newfami[i]=0; //not yet met!
1784
1785    nb_mess=0;
1786    for (i=0; i<nb ; i++) {
1787       if (more[i]==0) continue;
1788       if (fami[i]==0) {
1789          fami[i]=more[i];
1790          //std::cout<<"sur "<<i<<" en plus "<<more[i]<<std::endl;
1791       }
1792       else { //intersection
1793          if (fami[i]==more[i]) continue; //same families
1794          oldfam=fami[i]; oldfami=oldfam+i_zero;
1795          morfam=more[i]; morfami=morfam+i_zero;
1796          //not yet met?
1797          ii=oldfami+morfami*nb_max; //array 2d on vector
1798          if ((ii>=0)&&(ii<nb_tot)) {
1799             newfam=newfami[ii];
1800          }
1801          else {
1802             if (nb_mess<3) {
1803                nb_mess++;
1804                std::cout<<"***set_one_more_family*** warning many new families decrease speed "<<nb_fam<<std::endl;
1805             }
1806             ii=-1;
1807             newfam=0;
1808          }
1809          if (newfam==0) {
1810             //create new family intersection if needed
1811             newfam=families.find_family_on_groups(oldfam,morfam);
1812             //std::cout<<"new oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
1813             if (ii>=0) newfami[ii]=newfam;
1814          }
1815          /*else {
1816             std::cout<<"!!! oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
1817          }*/
1818          fami[i]=newfam;
1819       }
1820    }
1821    delete[] newfami;
1822    return true;
1823 }
1824
1825 //************************************
1826 bool ghs3dprl_mesh_wrap::idom_edges()
1827 {
1828    bool ok=true;
1829    QString tmp;
1830    nbseg2=0;
1831    return ok;
1832 }
1833
1834 //************************************
1835 bool ghs3dprl_mesh_wrap::idom_faces()
1836 {
1837    bool ok=true;
1838    QString tmp,key,key1,key2,key3;
1839    CVWtab *tab,*tab1,*tab2,*tab3;
1840    med_int ii,i,j,*arrayi;
1841    int xx;
1842
1843       //writing connectivity of faces triangles of wrap by nodes
1844       key1=key1.sprintf("FC%d",idom); //files.FaCes faces (wrap and triangles only)
1845       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1846       if (!tab1) {
1847          tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".faces";
1848          ok=this->ReadFileFACES(tmp);
1849          tab1=this->restore_key(key1);
1850          if (!tab1) return false;
1851       }
1852       nbtria3=tab1->size/7;
1853       if (verbose>4) std::cout<<"NumberOfTriangles="<<nbtria3<<std::endl;
1854       arrayi=new med_int[nbtria3*3];
1855       ii=0,i=0 ;
1856       for (j=0; j<nbtria3 ; j++){
1857          arrayi[ii]=tab1->tmint[i]; ii++;
1858          arrayi[ii]=tab1->tmint[i+1]; ii++;
1859          arrayi[ii]=tab1->tmint[i+2]; ii++;
1860          i=i+7;
1861       }
1862       err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3,arrayi);
1863       delete[] arrayi; //need immediately more little array
1864       if (err<0){std::cerr<<"Problem MEDmeshElementConnectivityWr for triangles connectivity"<<std::endl; return false;}
1865       
1866       //writing indices of faces triangles of wrap
1867       //caution!
1868       //generate "overlapping of numbers of elements" in "import med file" in salome
1869       //if not in "//writing indices of tetrahedra" -> arrayi[i]=!NBFACES!+i+1
1870       arrayi=new med_int[nbtria3]; 
1871       for (i=0; i<nbtria3 ; i++) arrayi[i]=nbseg2+i+1;
1872       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3,arrayi);
1873       delete[] arrayi;
1874       if (err<0){std::cerr<<"Problem MEDmeshEntityNumberWr of triangles"<<std::endl; return false;}
1875
1876       //GLx FA=files.GLo FAces
1877       key1=key1.sprintf("GL%d FA",idom);
1878       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1879       if (nbtria3!=tab1->size){std::cerr<<"Problem size GLi FA!=nbtria3!"<<std::endl; return false;}
1880
1881       key2=key2.sprintf("SKIN_TRIA3_FAMILIES",idom); //on global numerotation 
1882       tab2=this->restore_key(key2); //tab1=this->mestab[key1];
1883       med_int nbskin=0; 
1884       if (tab2) nbskin=tab2->size;
1885       
1886       //set families of faces existing in GHS3DPRL_skin.med
1887       med_int nb=nbtria3;
1888       famtria3=new med_int[nb];
1889       for (i=0; i<nb ; i++) famtria3[i]=famalltria3;
1890       med_int * fammore=new med_int[nb];
1891       for (i=0; i<nb ; i++) fammore[i]=famnewtria3;
1892
1893       //set families of faces of skin
1894       for (i=0; i<nb ; i++){
1895          j=tab1->tmint[i]-1; //
1896          if (j<nbskin){
1897             fammore[i]=tab2->tmint[j];
1898          }
1899       }
1900       ok=set_one_more_family(famtria3,fammore,nb);
1901       delete[] fammore;
1902       
1903       //writing faces(triangles) global numbering
1904       if (verbose>2)
1905          std::cout<<"CreateMEDglobalNumerotation_Faces "<<key1.toLatin1().constData()<<" "<<tab1->size<<std::endl;
1906       err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,tab1->size,tab1->tmint);
1907       if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr faces"<<std::endl; return false;}
1908
1909       //xx=this->remove_key_mesh_wrap(QRegExp("FC*",true,true));
1910       tmp=tmp.sprintf("GL%d FA",idom);
1911       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
1912       xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
1913       tmp=tmp.sprintf("GL%d VE",idom);
1914       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
1915       xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
1916
1917    return ok;
1918 }
1919
1920 //************************************
1921 bool ghs3dprl_mesh_wrap::idom_joints()
1922 {
1923    bool ok=true;
1924    QString tmp,namejoint,key,key1,key2;
1925    CVWtab *tab,*tab1,*tab2;
1926    med_int ineig,ii,jj,i,j,k,*arrayi,nb,famjoint,*fammore,*inodes,*arrayfaces;
1927    med_float *arraynodes;
1928    char namejnt[MED_NAME_SIZE+1];  //no more 32
1929    char namedist[MED_NAME_SIZE+1];
1930    char descjnt[MED_COMMENT_SIZE+1];
1931    med_int numfam_ini_wrap=100;
1932    joints_node=xmlNewNode(NULL, BAD_CAST "joints");  //masterfile.xml
1933    med_int nbjoints=0,nbnodesneig,nbtria3neig;
1934    std::string sjoints=""; //which domains are neighbourg
1935    int xx;
1936    char dtunit[MED_SNAME_SIZE+1]="_NO_UNIT";
1937    char axisname[MED_SNAME_SIZE*3+1]="x               y               z               ";
1938    char axisunit[MED_SNAME_SIZE*3+1]="_NO_UNIT        _NO_UNIT        _NO_UNIT        ";
1939
1940       tmp=tmp.sprintf("MS%d *",idom);
1941       //read file .msg if not done
1942       //qt3 if (this->nb_key_mesh_wrap(QRegExp(tmp,true,true))<=0) {
1943       if (this->nb_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp))<=0) {
1944          this->nofile=idom;
1945          /*old version with xml parser too slow
1946          ghs3dprl_msg_parser handler;
1947          handler.mailw=this;
1948          QXmlSimpleReader reader;
1949          reader.setContentHandler(&handler);
1950          tmp=pathini+casename+tmp.sprintf(format,nbfilestot,idom)+".msg";
1951          QFile File(tmp);
1952          QXmlInputSource source(&File);
1953          reader.parse(source);
1954          File.close();*/
1955          tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".msg";
1956          ok=this->ReadFileMSGnew(tmp);
1957          if (!ok) {
1958             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<std::endl;
1959             return false;
1960          }
1961       }
1962
1963       //writing joints
1964       for (ineig=1; ineig <= nbfilestot; ineig++) {
1965          if (idom==ineig) continue; //impossible
1966
1967          //!*************nodes
1968          //std::cout<<"\n    nodes joints\n";
1969          key1=key1.sprintf("MS%d NE%d VE SE",idom,ineig); //SE or RE identicals
1970          tab1=restore_key(key1);
1971          if (!tab1) continue; //case (ifile,ineig) are not neighbours=>no joints
1972          key1=key1.sprintf("MS%d NE%d VE SE",ineig,idom); //SE or RE identicals
1973          tab2=this->restore_key(key1);
1974          //if not yet loaded (first time) try to load necessary file msg of neighbourg
1975          if (!tab2) {
1976             tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,ineig)+".msg";
1977             this->nofile=ineig; //neighbourg file
1978             ok=this->ReadFileMSGnew(tmp);
1979             this->nofile=idom;  //restaure initial domain
1980             if (!ok) {
1981                std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<std::endl;
1982                continue;
1983             }
1984             tab2=this->restore_key(key1);
1985          }
1986          if (!tab2) std::cerr<<"Problem existing nodes joint in domain "<<idom<<
1987                           " with none in neighbourg "<<ineig<<" files .msg"<<std::endl;
1988          nb=tab1->size; nbnodesneig=tab2->size;
1989          if (nb!=nbnodesneig) {
1990             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<
1991                   " number of nodes of joint "<<idom<<"<->"<<ineig<<" not equals"<<std::endl;
1992             continue;
1993          }
1994
1995          nbjoints++; //one more joint for this domain
1996          sjoints=sjoints+" "+i2a(ineig);
1997          if (verbose>4)
1998             std::cout<<"NumberOfNodesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
1999          namejoint=namejoint.sprintf("JOINT_%d_%d_Nodes",idom,ineig);
2000          strcpy(namejnt,namejoint.toLatin1().constData());
2001          tmp=tmp.sprintf("JOINT_%d_%d among %d domains of ",idom,ineig,nbfilestot)+nomfinal;
2002          strcpy(descjnt,tmp.toLatin1().constData());
2003          tmp=medname+tmp.sprintf("_%d",ineig);
2004          strcpy(namedist,tmp.toLatin1().constData());
2005          err=MEDsubdomainJointCr(fid,nomfinal,namejnt,descjnt,ineig,namedist);
2006          if (err<0) std::cerr<<"Problem MEDsubdomainJointCr"<<std::endl;
2007
2008          famjoint=0;
2009          if (namejoint.contains(deletegroups)==0){
2010             ok=families.get_number_of_new_family(1,&famjoint,&tmp);
2011             families.add(tmp,namejoint);
2012          }
2013
2014          key=key.sprintf("NB%d VC",idom); //files.NoBoite Vertex Coordinates
2015          tab=this->restore_key(key); //tab1=this->mestab[key1];
2016          //nbnodes=tab->size/3;
2017
2018          //writing correspondence nodes-nodes
2019          //two indices for one correspondence
2020          arrayi=new med_int[nb*2];
2021          arraynodes=new med_float[nbnodesneig*3];  //for file DOMAIN_join.med
2022          inodes=new med_int[nbnodes];            //for file DOMAIN_join.med
2023          med_int * fammore=new med_int[nbnodes];
2024          for (i=0; i<nbnodes ; i++) {fammore[i]=0; inodes[i]=-1;}
2025          ii=0; jj=0; k=0;
2026          for (i=0; i<nb ; i++){
2027             //no need because <send> equals <receive> tab1->tmint[i]==tab2->tmint[i]
2028             j=tab1->tmint[i]-1; //contents of tab1 1 to nb
2029             inodes[j]=k; k++;   //indices 0->n-1 of nodes of joint from nodes of domain
2030             arraynodes[jj]=tab->tmflo[j*3]; jj++;
2031             arraynodes[jj]=tab->tmflo[j*3+1]; jj++;
2032             arraynodes[jj]=tab->tmflo[j*3+2]; jj++;
2033
2034             fammore[j]=famjoint;
2035             arrayi[ii]=tab1->tmint[i]; ii++;
2036             arrayi[ii]=tab2->tmint[i]; ii++;
2037          }
2038          if (namejoint.contains(deletegroups)==0){
2039             ok=set_one_more_family(famnodes,fammore,nbnodes);
2040          }
2041          delete[] fammore;
2042
2043          err=MEDsubdomainCorrespondenceWr(fid,nomfinal,namejnt,MED_NO_DT,MED_NO_IT,
2044                  MED_NODE,MED_UNDEF_GEOMETRY_TYPE,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nb,arrayi);
2045          if (err<0) std::cerr<<"Problem MEDsubdomainCorrespondenceWr nodes"<<std::endl;
2046          delete[] arrayi;
2047
2048          //!*************TRIA3
2049          //writing correspondence triangles-triangles
2050          //std::cout<<"\n    faces joints\n";
2051          nbtria3neig=0;
2052          key1=key1.sprintf("MS%d NE%d FA SE",idom,ineig); //SE or RE identicals
2053          tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2054          if (!tab1){
2055             if (verbose>4)
2056                std::cout<<"NumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"=0"<<std::endl;
2057             //continue; //case (ifile,ineig) are not neighbours=>no joints
2058          }
2059          else //have to set xml may be no faces but nodes in a joint!
2060          {
2061          key1=key1.sprintf("MS%d NE%d FA SE",ineig,idom); //SE or RE identicals
2062          tab2=this->restore_key(key1);
2063          if (!tab2) std::cerr<<"Problem existing triangles of joint in domain "<<idom<<
2064                           " with none in neighbourg "<<ineig<<" files .msg"<<std::endl;
2065          nb=tab1->size; nbtria3neig=tab2->size;
2066          if (nb!=nbtria3neig) {
2067             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<
2068                   " number of triangles of joint "<<idom<<"<->"<<ineig<<" not equals"<<std::endl;
2069             continue;
2070          }
2071          namejoint=namejoint.sprintf("JOINT_%d_%d_Faces",idom,ineig);
2072          
2073          famjoint=0;
2074          if (namejoint.contains(deletegroups)==0){
2075             ok=families.get_number_of_new_family(-1,&famjoint,&tmp);
2076             families.add(tmp,namejoint);
2077          }
2078
2079          key=key.sprintf("FC%d",idom); //files.FaCes faces (wrap and triangles only)
2080          tab=this->restore_key(key); //tab1=this->mestab[key1];
2081
2082          med_int nb=tab1->size; nbtria3neig=nb;
2083          if (verbose>4)
2084             std::cout<<"NumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
2085          arrayi=new med_int[nb*2];
2086          arrayfaces=new med_int[nbtria3neig*3];  //for file DOMAIN_join.med
2087          fammore=new med_int[nbtria3];
2088          for (i=0; i<nbtria3 ; i++) fammore[i]=0;
2089          ii=0; jj=0;
2090          for (i=0; i<nb ; i++){
2091             arrayi[ii]=tab1->tmint[i]; ii++;
2092             fammore[tab1->tmint[i]-1]=famjoint;
2093             //famtria3[tab1->tmint[i]-1]=famjoint;
2094             arrayi[ii]=tab2->tmint[i]; ii++;
2095             //std::cout<<arrayi[ii-1]<<"="<<arrayi[ii-2]<<std::endl;
2096             k=(tab1->tmint[i]-1)*7; //indice of node connectivity
2097             arrayfaces[jj]=inodes[tab->tmint[k]-1]+1; jj++;
2098             arrayfaces[jj]=inodes[tab->tmint[k+1]-1]+1; jj++;
2099             arrayfaces[jj]=inodes[tab->tmint[k+2]-1]+1; jj++;
2100          }
2101          if (namejoint.contains(deletegroups)==0){
2102             ok=set_one_more_family(famtria3,fammore,nbtria3);
2103          }
2104          delete[] fammore;
2105
2106          err=MEDsubdomainCorrespondenceWr(fid,nomfinal,namejnt,MED_NO_DT,MED_NO_IT,
2107                  MED_CELL,MED_TRIA3,MED_CELL,MED_TRIA3,nb,arrayi);
2108          if (err<0) std::cerr<<"Problem MEDsubdomainCorrespondenceWr triangles"<<std::endl;
2109          delete[] arrayi;
2110          }
2111
2112          //!write in file resume DOMAIN.joints.med of all joints for quick display (...may be...)
2113          if (idom<=ineig) { //no duplicate joint_1_2 and joint_2_1
2114           //create mesh
2115           namejoint=namejoint.sprintf("JOINT_%d_%d",idom,ineig);
2116           charendnull(namejnt,namejoint,MED_NAME_SIZE);
2117           tmp=tmp.sprintf("joint between %d and %d",idom,ineig);
2118           charendnull(descjnt,tmp,MED_COMMENT_SIZE);
2119           err=MEDmeshCr(fidjoint,namejnt,3,3,MED_UNSTRUCTURED_MESH,descjnt,dtunit,MED_SORT_DTIT,MED_CARTESIAN,axisname,axisunit);
2120           if (err<0) std::cerr<<"Problem MEDmeshCr "<<namejnt<<std::endl;
2121           //write nodes
2122           err=MEDmeshNodeCoordinateWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,0.,MED_FULL_INTERLACE,nbnodesneig,arraynodes);
2123           if (err<0) std::cerr<<"Problem MEDmeshNodeCoordinateWr "<<namejnt<<std::endl;
2124           arrayi=new med_int[nbnodesneig];
2125           for (i=0; i<nbnodesneig ; i++) arrayi[i]=i+1;
2126           err=MEDmeshEntityNumberWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodesneig,arrayi);
2127           delete[] arrayi;
2128           if (err<0) std::cerr<<"Problem MEDmeshEntityNumberWr of nodes "<<namejnt<<std::endl;
2129
2130           //write tria3
2131           if (nbtria3neig>0) {
2132            //for (i=0; i<nbtria3neig ; i++) std::cout<<i+1<<" "<<
2133            //    arrayfaces[i*3]<<" "<<arrayfaces[i*3+1]<<" "<<arrayfaces[i*3+2]<<std::endl;
2134            err=MEDmeshElementConnectivityWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,0.,
2135                    MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3neig,arrayfaces);
2136            if (err<0) std::cerr<<"Problem MEDmeshElementConnectivityWr for triangles connectivity "<<namejnt<<std::endl;
2137            //writing indices of faces triangles of joint
2138            arrayi=new med_int[nbtria3neig]; 
2139            for (i=0; i<nbtria3neig ; i++) arrayi[i]=i+1;
2140            err=MEDmeshEntityNumberWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3neig,arrayi);
2141            delete[] arrayi;
2142            if (err<0) std::cerr<<"Problem MEDmeshEntityNumberWr of triangles "<<namejnt<<std::endl;
2143           }
2144          }
2145
2146          delete[] arraynodes;
2147          if (nbtria3neig>0) delete[] arrayfaces;
2148          delete[] inodes;
2149
2150          //!masterfile.xml
2151          node=xmlNewChild(joints_node, 0, BAD_CAST "joint", 0);
2152          xmlNewProp(node, BAD_CAST "id", BAD_CAST i2a(ineig).c_str());
2153          xmlNewProp(node, BAD_CAST "nodes_number", BAD_CAST i2a(nbnodesneig).c_str());
2154          xmlNewProp(node, BAD_CAST "faces_number", BAD_CAST i2a(nbtria3neig).c_str());
2155          //node2 = xmlNewChild(node, 0, BAD_CAST "nodes", 0);
2156          //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbnodesneig).c_str());
2157          //node2 = xmlNewChild(node, 0, BAD_CAST "faces", 0);
2158          //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtria3neig).c_str());
2159       }
2160
2161    //masterfile.xml
2162    xmlNewProp(joints_node, BAD_CAST "number", BAD_CAST i2a(nbjoints).c_str());
2163    xmlNewChild(joints_node, 0, BAD_CAST "id_neighbours", BAD_CAST sjoints.substr(1).c_str());
2164    
2165    tmp=tmp.sprintf("NB%d VC",idom);
2166    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2167    xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2168    //tmp=tmp.sprintf("MS%d NE*",idom);
2169    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2170    //xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2171    tmp=tmp.sprintf("FC%d",idom);
2172    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2173    xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2174    tmp=tmp.sprintf("GL%d *",idom);
2175    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2176    xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2177    return ok;
2178 }
2179
2180 //************************************
2181 bool ghs3dprl_mesh_wrap::idom_tetras()
2182 {
2183    bool ok=true;
2184    QString tmp,key1;
2185    CVWtab *tab1;
2186    med_int i,*arrayi;
2187    int xx;
2188
2189       //writing connectivity of tetrahedra by nodes
2190       key1=key1.sprintf("NB%d EV",idom); //files.NoBoite Elements Vertices (tetra only)
2191       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2192       nbtetra4=tab1->size/4;
2193       nbtetrastotal=nbtetrastotal + nbtetra4;
2194       if (verbose>5)std::cout<<"NumberOftetrahedra="<<nbtetra4<<std::endl;
2195       err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TETRA4,MED_NODAL,MED_FULL_INTERLACE,nbtetra4,tab1->tmint);
2196       if (err<0){std::cerr<<"Problem MEDmeshElementConnectivityWr for tetra connectivity"<<std::endl; return false;}
2197
2198       //writing indices of tetrahedra
2199       arrayi=new med_int[nbtetra4];
2200       for (i=0; i<nbtetra4 ; i++) arrayi[i]=nbseg2+nbtria3+i+1;
2201       //for (i=0; i<nbtria3 ; i++) std::cout<<i<<" "<<arrayi[i]<<std::endl;
2202       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,nbtetra4,arrayi);
2203       delete[] arrayi;
2204       if (err<0){std::cerr<<"Problem MEDmeshEntityNumberWr of tetrahedra"<<std::endl; return false;}
2205
2206       famtetra4=new med_int[nbtetra4];
2207       for (i=0; i<nbtetra4 ; i++) famtetra4[i]=famnewtetra4;
2208
2209       //writing tetrahedra global numbering
2210       //GLx EL=files.GLo ELements
2211       key1=key1.sprintf("GL%d EL",idom);
2212       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2213       if (!tab1) {
2214          tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
2215          ok=this->ReadFileGLO(tmp);
2216          tab1=this->restore_key(key1);
2217          if (!tab1) return false;
2218       }
2219
2220       if (tab1->size!=nbtetra4){
2221          std::cerr<<"Problem incorrect size of tetrahedra global numbering"<<std::endl; return false;}
2222       if (verbose>2)
2223          std::cout<<"CreateMEDglobalNumerotation_tetrahedra "<<key1.toLatin1().constData()<<" "<<tab1->size<<std::endl;
2224       err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,tab1->size,tab1->tmint);
2225       if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr tetrahedra"<<std::endl; return false;}
2226
2227       tmp=tmp.sprintf("NB%d EV",idom);
2228       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2229       xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2230    return ok;
2231 }
2232
2233 //************************************
2234 med_int ghs3dprl_mesh_wrap::create_families(med_idt fid, int sign)
2235 //if sign < 0 families faces or tria3 etc...
2236 //if sign >= 0 family zero and family nodes
2237 {
2238    med_int pas,ires;
2239    char nomfam[MED_NAME_SIZE+1];  //it.current()->name;
2240    char attdes[MED_COMMENT_SIZE+1]="_NO_DESCRIPTION";
2241    char *gro;
2242    med_int i,attide=1,attval=1,natt=1,num,ngro;
2243    
2244    if (sign>=0) pas=1; else pas=-1;
2245    ires=0;
2246    fend gb;
2247    fagr::iterator it1;
2248    fend::iterator it2;
2249    for (it1=families.fam.begin(); it1!=families.fam.end(); ++it1){
2250       num=(*it1).first.toLong();
2251       if ((pas==-1) && (num>=0)) continue; //not good families
2252       if ((pas== 1) && (num< 0)) continue; //not good families
2253       charendnull(nomfam,(*it1).first,MED_NAME_SIZE);
2254       ires++;
2255       //med_int natt=0;
2256       ngro=(*it1).second.size();
2257       if (verbose>5) 
2258          std::cout<<"CreateFamilyInMEDFile <"<<nomfam<<">\tNbGroups="<<ngro;
2259       gro=new char[MED_LNAME_SIZE*ngro+2];
2260       gb=(*it1).second;
2261       i=0;
2262       for (it2=gb.begin(); it2!=gb.end(); ++it2){
2263          charendnull(&gro[i*MED_LNAME_SIZE],(*it2).first,MED_LNAME_SIZE);
2264          if (verbose>5)std::cout<<" <"<<&gro[i*MED_LNAME_SIZE]<<"> ";
2265          i++;
2266       }
2267       if (verbose>5)std::cout<<std::endl;
2268       err=MEDfamilyCr(fid,nomfinal,nomfam,num,ngro,gro);
2269       if (err<0) std::cerr<<"Problem MEDfamilyCr"<<std::endl;
2270       delete[] gro;
2271       if (err<0) std::cerr<<"Problem MEDfamilyCr of "<<nomfam<<std::endl;
2272    }
2273    return ires;
2274 }
2275