Salome HOME
f547f276246f1f0e19a78c156fd4259e95010531
[modules/smesh.git] / src / SMESH_I / SMESH_Homard_i.cxx
1 // Copyright (C) 2011-2021  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 #include "SMESH_Homard_i.hxx"
21 #include "SMESH_Homard.hxx"
22
23 #include <SMESH_Gen_i.hxx>
24 #include "SMESH_PythonDump.hxx"
25
26 //#include "FrontTrack.hxx"
27
28 #include "utilities.h"
29 #include "Basics_Utils.hxx"
30 #include "Basics_DirUtils.hxx"
31 #include "Utils_SINGLETON.hxx"
32 #include "Utils_CorbaException.hxx"
33 #include "SALOMEDS_Tool.hxx"
34 #include "SALOME_LifeCycleCORBA.hxx"
35 #include "SALOMEconfig.h"
36
37 #include <vector>
38 #include <cmath>
39 #include <cstdlib>
40 #include <stdlib.h>
41 #include <sys/stat.h>
42 #include <algorithm>
43
44 #include <med.h>
45
46 #ifdef WIN32
47 #include <direct.h>
48 #else
49 #include <dirent.h>
50 #endif
51
52 #include <string>
53 #include <cstring>
54 #include <iostream>
55 #include <fstream>
56 #include <iomanip>
57 #include <set>
58 #include <vector>
59 #include <stdio.h>
60
61 using namespace std;
62
63 SMESHHOMARD::HOMARD_Gen_ptr SMESH_Gen_i::CreateHOMARD_ADAPT()
64 {
65   SMESHHOMARD_I::HOMARD_Gen_i* aHomardGen = new SMESHHOMARD_I::HOMARD_Gen_i();
66   SMESHHOMARD::HOMARD_Gen_var anObj = aHomardGen->_this();
67   return anObj._retn();
68 }
69
70 namespace SMESHHOMARD_I
71 {
72
73 //=============================================================================
74 /*!
75  *  standard constructor
76  */
77 //=============================================================================
78 HOMARD_Boundary_i::HOMARD_Boundary_i()
79   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
80 {
81   MESSAGE("Default constructor, not for use");
82   ASSERT(0);
83 }
84 //=============================================================================
85 /*!
86  *  standard constructor
87  */
88 //=============================================================================
89 HOMARD_Boundary_i::HOMARD_Boundary_i(SMESHHOMARD::HOMARD_Gen_var engine)
90   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
91 {
92   MESSAGE("HOMARD_Boundary_i");
93   _gen_i = engine;
94   myHomardBoundary = new SMESHHOMARDImpl::HOMARD_Boundary();
95   ASSERT(myHomardBoundary);
96 }
97 //=============================================================================
98 /*!
99  *  standard destructor
100  */
101 //=============================================================================
102 HOMARD_Boundary_i::~HOMARD_Boundary_i()
103 {
104 }
105 //=============================================================================
106 //=============================================================================
107 // Generalites
108 //=============================================================================
109 //=============================================================================
110 void HOMARD_Boundary_i::SetName(const char* Name)
111 {
112   ASSERT(myHomardBoundary);
113   myHomardBoundary->SetName(Name);
114 }
115 //=============================================================================
116 char* HOMARD_Boundary_i::GetName()
117 {
118   ASSERT(myHomardBoundary);
119   return CORBA::string_dup(myHomardBoundary->GetName().c_str());
120 }
121 //=============================================================================
122 char* HOMARD_Boundary_i::GetDumpPython()
123 {
124   ASSERT(myHomardBoundary);
125   return CORBA::string_dup(myHomardBoundary->GetDumpPython().c_str());
126 }
127 //=============================================================================
128 //=============================================================================
129 // Caracteristiques
130 //=============================================================================
131 //=============================================================================
132 void HOMARD_Boundary_i::SetType(CORBA::Long Type)
133 {
134   ASSERT(myHomardBoundary);
135   myHomardBoundary->SetType(Type);
136 }
137 //=============================================================================
138 CORBA::Long HOMARD_Boundary_i::GetType()
139 {
140   ASSERT(myHomardBoundary);
141   return  CORBA::Long(myHomardBoundary->GetType());
142 }
143 //=============================================================================
144 void HOMARD_Boundary_i::SetMeshName(const char* MeshName)
145 {
146   ASSERT(myHomardBoundary);
147   myHomardBoundary->SetMeshName(MeshName);
148 }
149 //=============================================================================
150 char* HOMARD_Boundary_i::GetMeshName()
151 {
152   ASSERT(myHomardBoundary);
153   return CORBA::string_dup(myHomardBoundary->GetMeshName().c_str());
154 }
155 //=============================================================================
156 void HOMARD_Boundary_i::SetDataFile(const char* DataFile)
157 {
158   ASSERT(myHomardBoundary);
159   myHomardBoundary->SetDataFile(DataFile);
160 }
161 //=============================================================================
162 char* HOMARD_Boundary_i::GetDataFile()
163 {
164   ASSERT(myHomardBoundary);
165   return CORBA::string_dup(myHomardBoundary->GetDataFile().c_str());
166 }
167 //=============================================================================
168 void HOMARD_Boundary_i::SetCylinder(double X0, double X1, double X2, double X3, double X4, double X5, double X6)
169 {
170   ASSERT(myHomardBoundary);
171   myHomardBoundary->SetCylinder(X0, X1, X2, X3, X4, X5, X6);
172 }
173 //=============================================================================
174 void HOMARD_Boundary_i::SetSphere(double Xcentre, double Ycentre, double ZCentre, double rayon)
175 {
176   ASSERT(myHomardBoundary);
177   myHomardBoundary->SetSphere(Xcentre, Ycentre, ZCentre, rayon);
178 }
179 //=============================================================================
180 void HOMARD_Boundary_i::SetConeR(double Xcentre1, double Ycentre1, double Zcentre1, double Rayon1, double Xcentre2, double Ycentre2, double Zcentre2, double Rayon2)
181 {
182   ASSERT(myHomardBoundary);
183   myHomardBoundary->SetConeR(Xcentre1, Ycentre1, Zcentre1, Rayon1, Xcentre2, Ycentre2, Zcentre2, Rayon2);
184 }
185 //=============================================================================
186 void HOMARD_Boundary_i::SetConeA(double Xaxe, double Yaxe, double Zaxe, double Angle, double Xcentre, double Ycentre, double Zcentre)
187 {
188   ASSERT(myHomardBoundary);
189   myHomardBoundary->SetConeA(Xaxe, Yaxe, Zaxe, Angle, Xcentre, Ycentre, Zcentre);
190 }
191 //=============================================================================
192 void HOMARD_Boundary_i::SetTorus(double X0, double X1, double X2, double X3, double X4, double X5, double X6, double X7)
193 {
194   ASSERT(myHomardBoundary);
195   myHomardBoundary->SetTorus(X0, X1, X2, X3, X4, X5, X6, X7);
196 }
197 //=============================================================================
198 SMESHHOMARD::double_array* HOMARD_Boundary_i::GetCoords()
199 {
200   ASSERT(myHomardBoundary);
201   SMESHHOMARD::double_array_var aResult = new SMESHHOMARD::double_array();
202   std::vector<double> mesCoor = myHomardBoundary->GetCoords();
203   aResult->length(mesCoor .size());
204   std::vector<double>::const_iterator it;
205   int i = 0;
206   for (it = mesCoor.begin(); it != mesCoor.end(); it++)
207     aResult[i++] = (*it);
208   return aResult._retn();
209 }
210 //=============================================================================
211 void HOMARD_Boundary_i::SetLimit(double Xincr, double Yincr, double Zincr)
212 {
213   ASSERT(myHomardBoundary);
214   myHomardBoundary->SetLimit(Xincr, Yincr, Zincr);
215 }
216 //=============================================================================
217 SMESHHOMARD::double_array* HOMARD_Boundary_i::GetLimit()
218 {
219   ASSERT(myHomardBoundary);
220   SMESHHOMARD::double_array_var aResult = new SMESHHOMARD::double_array();
221   std::vector<double> mesCoor = myHomardBoundary->GetLimit();
222   aResult->length(mesCoor .size());
223   std::vector<double>::const_iterator it;
224   int i = 0;
225   for (it = mesCoor.begin(); it != mesCoor.end(); it++)
226     aResult[i++] = (*it);
227   return aResult._retn();
228 }
229 //=============================================================================
230 void HOMARD_Boundary_i::AddGroup(const char* Group)
231 {
232   ASSERT(myHomardBoundary);
233   myHomardBoundary->AddGroup(Group);
234 }
235 //=============================================================================
236 void HOMARD_Boundary_i::SetGroups(const SMESHHOMARD::ListGroupType& ListGroup)
237 {
238   ASSERT(myHomardBoundary);
239   std::list<std::string> ListString;
240   for (unsigned int i = 0; i < ListGroup.length(); i++) {
241     ListString.push_back(std::string(ListGroup[i]));
242   }
243   myHomardBoundary->SetGroups(ListString);
244 }
245 //=============================================================================
246 SMESHHOMARD::ListGroupType*  HOMARD_Boundary_i::GetGroups()
247 {
248   ASSERT(myHomardBoundary);
249   const std::list<std::string>& ListString = myHomardBoundary->GetGroups();
250   SMESHHOMARD::ListGroupType_var aResult = new SMESHHOMARD::ListGroupType;
251   aResult->length(ListString.size());
252   std::list<std::string>::const_iterator it;
253   int i = 0;
254   for (it = ListString.begin(); it != ListString.end(); it++)
255   {
256     aResult[i++] = CORBA::string_dup((*it).c_str());
257   }
258   return aResult._retn();
259 }
260 //=============================================================================
261 //=============================================================================
262 // Liens avec les autres structures
263 //=============================================================================
264 //=============================================================================
265 void HOMARD_Boundary_i::SetCaseCreation(const char* NomCaseCreation)
266 {
267   ASSERT(myHomardBoundary);
268   myHomardBoundary->SetCaseCreation(NomCaseCreation);
269 }
270 //=============================================================================
271 char* HOMARD_Boundary_i::GetCaseCreation()
272 {
273   ASSERT(myHomardBoundary);
274   return CORBA::string_dup(myHomardBoundary->GetCaseCreation().c_str());
275 }
276
277 //=============================================================================
278 /*!
279  *  standard constructor
280  */
281 //=============================================================================
282 HOMARD_Cas_i::HOMARD_Cas_i()
283   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
284 {
285   MESSAGE("Default constructor, not for use");
286   ASSERT(0);
287 }
288
289 //=============================================================================
290 /*!
291  *  standard constructor
292  */
293 //=============================================================================
294 HOMARD_Cas_i::HOMARD_Cas_i(SMESHHOMARD::HOMARD_Gen_var engine)
295   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
296 {
297   MESSAGE("HOMARD_Cas_i");
298   _gen_i = engine;
299   myHomardCas = new SMESHHOMARDImpl::HOMARD_Cas();
300   ASSERT(myHomardCas);
301   myHomardCas->SetName("Case_1");
302 }
303
304 //=============================================================================
305 /*!
306  *  standard destructor
307  */
308 //=============================================================================
309 HOMARD_Cas_i::~HOMARD_Cas_i()
310 {
311 }
312 //=============================================================================
313 //=============================================================================
314 // Generalites
315 //=============================================================================
316 //=============================================================================
317 char* HOMARD_Cas_i::GetName()
318 {
319   ASSERT(myHomardCas);
320   return CORBA::string_dup(myHomardCas->GetName().c_str());
321 }
322 //=============================================================================
323 char* HOMARD_Cas_i::GetDumpPython()
324 {
325   ASSERT(myHomardCas);
326   return CORBA::string_dup(myHomardCas->GetDumpPython().c_str());
327 }
328 //=============================================================================
329 //=============================================================================
330 // Caracteristiques
331 //=============================================================================
332 //=============================================================================
333 void HOMARD_Cas_i::SetDirName(const char* NomDir)
334 {
335   ASSERT(myHomardCas);
336   int codret;
337   // A. recuperation du nom; on ne fait rien si c'est le meme
338   char* oldrep = GetDirName();
339   if (strcmp(oldrep,NomDir) == 0) return;
340   MESSAGE ("SetDirName : passage de oldrep = "<< oldrep << " a NomDir = "<<NomDir);
341   // C. Changement/creation du repertoire
342   codret = myHomardCas->SetDirName(NomDir);
343   if (codret != 0) {
344     SALOME::ExceptionStruct es;
345     es.type = SALOME::BAD_PARAM;
346     std::string text;
347     if (codret == 1)
348       text = "The directory for the case cannot be modified because some iterations are already defined.";
349     else
350       text = "The directory for the case cannot be reached.";
351     es.text = CORBA::string_dup(text.c_str());
352     throw SALOME::SALOME_Exception(es);
353   }
354   // D. En cas de reprise, deplacement du point de depart
355   SMESHHOMARD::HOMARD_Iteration_ptr Iter0 = _gen_i->GetIteration(0);
356   int state = Iter0->GetNumber();
357   if (state != 0) { // GetState()
358     MESSAGE ("etat : " << state);
359     // D.1. Nom local du repertoire de l'iteration de depart dans le repertoire actuel du cas
360     char* DirNameIter = Iter0->GetDirNameLoc();
361     MESSAGE ("SetDirName : nom actuel pour le repertoire de l iteration, DirNameIter = "<< DirNameIter);
362     // D.2. Recherche d'un nom local pour l'iteration de depart dans le futur repertoire du cas
363     char* nomDirIter = _gen_i->CreateDirNameIter(NomDir, 0);
364     MESSAGE ("SetDirName : nom futur pour le repertoire de l iteration, nomDirIter = "<< nomDirIter);
365     // D.3. Creation du futur repertoire local pour l'iteration de depart
366     std::string nomDirIterTotal;
367     nomDirIterTotal = std::string(NomDir) + "/" + std::string(nomDirIter);
368 #ifndef WIN32
369     if (mkdir(nomDirIterTotal.c_str(), S_IRWXU|S_IRGRP|S_IXGRP) != 0)
370 #else
371     if (_mkdir(nomDirIterTotal.c_str()) != 0)
372 #endif
373     {
374       MESSAGE ("nomDirIterTotal : " << nomDirIterTotal);
375       SALOME::ExceptionStruct es;
376       es.type = SALOME::BAD_PARAM;
377       std::string text = "The directory for the starting iteration cannot be created.";
378       es.text = CORBA::string_dup(text.c_str());
379       throw SALOME::SALOME_Exception(es);
380     }
381     // D.4. Deplacement du contenu du repertoire
382     std::string oldnomDirIterTotal;
383     oldnomDirIterTotal = std::string(oldrep) + "/" + std::string(DirNameIter);
384     std::string commande = "mv " + std::string(oldnomDirIterTotal) + "/*" + " " + std::string(nomDirIterTotal);
385     codret = system(commande.c_str());
386     if (codret != 0)
387     {
388       SALOME::ExceptionStruct es;
389       es.type = SALOME::BAD_PARAM;
390       std::string text = "The starting point for the case cannot be moved into the new directory.";
391       es.text = CORBA::string_dup(text.c_str());
392       throw SALOME::SALOME_Exception(es);
393     }
394     commande = "rm -rf " + std::string(oldnomDirIterTotal);
395     codret = system(commande.c_str());
396     if (codret != 0)
397     {
398       SALOME::ExceptionStruct es;
399       es.type = SALOME::BAD_PARAM;
400       std::string text = "The starting point for the case cannot be deleted.";
401       es.text = CORBA::string_dup(text.c_str());
402       throw SALOME::SALOME_Exception(es);
403     }
404     // D.5. Memorisation du nom du repertoire de l'iteration
405     Iter0->SetDirNameLoc(nomDirIter);
406   }
407 }
408 //=============================================================================
409 char* HOMARD_Cas_i::GetDirName()
410 {
411   ASSERT(myHomardCas);
412   return CORBA::string_dup(myHomardCas->GetDirName().c_str());
413 }
414 //=============================================================================
415 void HOMARD_Cas_i::SetConfType(CORBA::Long ConfType)
416 {
417   ASSERT(myHomardCas);
418   //VERIFICATION((ConfType>=-2) && (ConfType<=3));
419   myHomardCas->SetConfType(ConfType);
420 }
421 //=============================================================================
422 CORBA::Long HOMARD_Cas_i::GetConfType()
423 {
424   ASSERT(myHomardCas);
425   return myHomardCas->GetConfType();
426 }
427 //=============================================================================
428 void HOMARD_Cas_i::SetBoundingBox(const SMESHHOMARD::extrema& LesExtrema)
429 {
430   ASSERT(myHomardCas);
431   std::vector<double> VExtrema;
432   ASSERT(LesExtrema.length() == 10);
433   VExtrema.resize(LesExtrema.length());
434   for (int i = 0; i < (int)LesExtrema.length(); i++) {
435     VExtrema[i] = LesExtrema[i];
436   }
437   myHomardCas->SetBoundingBox(VExtrema);
438 }
439 //=============================================================================
440 SMESHHOMARD::extrema* HOMARD_Cas_i::GetBoundingBox()
441 {
442   ASSERT(myHomardCas);
443   SMESHHOMARD::extrema_var aResult = new SMESHHOMARD::extrema();
444   std::vector<double> LesExtremes = myHomardCas->GetBoundingBox();
445   ASSERT(LesExtremes.size() == 10);
446   aResult->length(10);
447   for (int i = 0; i < (int)LesExtremes.size(); i++) {
448     aResult[i] = LesExtremes[i];
449   }
450   return aResult._retn();
451 }
452
453 //=============================================================================
454 void HOMARD_Cas_i::AddGroup(const char* Group)
455 {
456   ASSERT(myHomardCas);
457   myHomardCas->AddGroup(Group);
458 }
459 //=============================================================================
460 void HOMARD_Cas_i::SetGroups(const SMESHHOMARD::ListGroupType& ListGroup)
461 {
462   ASSERT(myHomardCas);
463   std::list<std::string> ListString;
464   for (int i = 0; i < ListGroup.length(); i++)
465   {
466     ListString.push_back(std::string(ListGroup[i]));
467   }
468   myHomardCas->SetGroups(ListString);
469 }
470 //=============================================================================
471 SMESHHOMARD::ListGroupType* HOMARD_Cas_i::GetGroups()
472 {
473   ASSERT(myHomardCas);
474   const std::list<std::string>& ListString = myHomardCas->GetGroups();
475   SMESHHOMARD::ListGroupType_var aResult = new SMESHHOMARD::ListGroupType();
476   aResult->length(ListString.size());
477   std::list<std::string>::const_iterator it;
478   int i = 0;
479   for (it = ListString.begin(); it != ListString.end(); it++) {
480     aResult[i++] = CORBA::string_dup((*it).c_str());
481   }
482   return aResult._retn();
483 }
484
485 //=============================================================================
486 void HOMARD_Cas_i::AddBoundary(const char* BoundaryName)
487 {
488   MESSAGE ("HOMARD_Cas_i::AddBoundary : BoundaryName = "<< BoundaryName);
489   const char * Group = "";
490   AddBoundaryGroup(BoundaryName, Group);
491 }
492 //=============================================================================
493 void HOMARD_Cas_i::AddBoundaryGroup(const char* BoundaryName, const char* Group)
494 {
495   MESSAGE ("HOMARD_Cas_i::AddBoundaryGroup : BoundaryName = "<< BoundaryName << ", Group = " << Group);
496   ASSERT(myHomardCas);
497   // A. Préalables
498   // A.1. Caractéristiques de la frontière Ã  ajouter
499   SMESHHOMARD::HOMARD_Boundary_ptr myBoundary = _gen_i->GetBoundary(BoundaryName);
500   ASSERT(!CORBA::is_nil(myBoundary));
501   int BoundaryType = myBoundary->GetType();
502   MESSAGE (". BoundaryType = " << BoundaryType);
503   // A.2. La liste des frontiere+groupes
504   const std::list<std::string>& ListBoundaryGroup = myHomardCas->GetBoundaryGroup();
505   std::list<std::string>::const_iterator it;
506   // B. Controles
507   const char * boun;
508   int erreur = 0;
509   while (erreur == 0)
510   {
511     // B.1. Si on ajoute une frontière CAO, elle doit Ãªtre la seule frontière
512     if (BoundaryType == -1)
513     {
514       for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
515       {
516         boun = (*it).c_str();
517         MESSAGE ("..  Frontiere enregistrée : "<< boun);
518         if (*it != BoundaryName)
519         { erreur = 1;
520           break; }
521         // On saute le nom du groupe
522         it++;
523       }
524     }
525     if (erreur != 0) { break; }
526     // B.2. Si on ajoute une frontière non CAO, il ne doit pas y avoir de frontière CAO
527     if (BoundaryType != -1)
528     {
529       for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
530       {
531         boun = (*it).c_str();
532         MESSAGE ("..  Frontiere enregistrée : "<< boun);
533         SMESHHOMARD::HOMARD_Boundary_ptr myBoundary_0 = _gen_i->GetBoundary(boun);
534         int BoundaryType_0 = myBoundary_0->GetType();
535         MESSAGE (".. BoundaryType_0 = " << BoundaryType_0);
536         if (BoundaryType_0 == -1)
537         { erreur = 2;
538           break; }
539         // On saute le nom du groupe
540         it++;
541       }
542       if (erreur != 0) { break; }
543     }
544     // B.3. Si on ajoute une frontière discrète, il ne doit pas y avoir d'autre frontière discrète
545     if (BoundaryType == 0)
546     {
547       for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
548       {
549         boun = (*it).c_str();
550         MESSAGE ("..  Frontiere enregistrée : "<< boun);
551         if (boun != BoundaryName)
552         {
553           SMESHHOMARD::HOMARD_Boundary_ptr myBoundary_0 = _gen_i->GetBoundary(boun);
554           int BoundaryType_0 = myBoundary_0->GetType();
555           MESSAGE (".. BoundaryType_0 = " << BoundaryType_0);
556           if (BoundaryType_0 == 0)
557           { erreur = 3;
558             break; }
559         }
560         // On saute le nom du groupe
561         it++;
562       }
563       if (erreur != 0) { break; }
564     }
565     // B.4. Pour une nouvelle frontiere, publication dans l'arbre d'etudes sous le cas
566     for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++) {
567       MESSAGE ("..  Frontiere : "<< *it);
568       // On saute le nom du groupe
569       it++;
570     }
571     // B.5. Le groupe est-il deja enregistre pour une frontiere de ce cas ?
572     for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++) {
573       boun = (*it).c_str();
574       it++;
575       MESSAGE ("..  Groupe enregistré : "<< *it);
576       if (*it == Group) {
577         erreur = 5;
578         break;
579       }
580     }
581     if (erreur != 0) { break; }
582     //
583     break;
584   }
585   // F. Si aucune erreur, enregistrement du couple (frontiere,groupe) dans la reference du cas
586   //    Sinon, arrêt
587   if (erreur == 0) {
588     myHomardCas->AddBoundaryGroup(BoundaryName, Group);
589   }
590   else {
591     std::stringstream ss;
592     ss << erreur;
593     std::string str = ss.str();
594     std::string texte;
595     texte = "Erreur numéro " + str + " pour la frontière Ã  enregistrer : " + std::string(BoundaryName);
596     if (erreur == 1) { texte += "\nIl existe déjà la frontière "; }
597     else if (erreur == 2) { texte += "\nIl existe déjà la frontière CAO "; }
598     else if (erreur == 3) { texte += "\nIl existe déjà une frontière discrète : "; }
599     else if (erreur == 5) { texte += "\nLe groupe " + std::string(Group) + " est déjà enregistré pour la frontière "; }
600     texte += std::string(boun);
601     //
602     SALOME::ExceptionStruct es;
603     es.type = SALOME::BAD_PARAM;
604 #ifdef _DEBUG_
605     texte += "\nInvalid AddBoundaryGroup";
606 #endif
607     INFOS(texte);
608     es.text = CORBA::string_dup(texte.c_str());
609     throw SALOME::SALOME_Exception(es);
610   }
611 }
612 //=============================================================================
613 SMESHHOMARD::ListBoundaryGroupType* HOMARD_Cas_i::GetBoundaryGroup()
614 {
615   MESSAGE ("GetBoundaryGroup");
616   ASSERT(myHomardCas);
617   const std::list<std::string>& ListBoundaryGroup = myHomardCas->GetBoundaryGroup();
618   SMESHHOMARD::ListBoundaryGroupType_var aResult = new SMESHHOMARD::ListBoundaryGroupType();
619   aResult->length(ListBoundaryGroup.size());
620   std::list<std::string>::const_iterator it;
621   int i = 0;
622   for (it = ListBoundaryGroup.begin(); it != ListBoundaryGroup.end(); it++)
623   {
624     aResult[i++] = CORBA::string_dup((*it).c_str());
625   }
626   return aResult._retn();
627 }
628 //=============================================================================
629 void HOMARD_Cas_i::SupprBoundaryGroup()
630 {
631   MESSAGE ("SupprBoundaryGroup");
632   ASSERT(myHomardCas);
633   myHomardCas->SupprBoundaryGroup();
634 }
635
636 void HOMARD_Cas_i::AddIteration(const char* NomIteration)
637 {
638   ASSERT(myHomardCas);
639   myHomardCas->AddIteration(NomIteration);
640 }
641
642 //=============================================================================
643 /*!
644  *  standard constructor
645  */
646 //=============================================================================
647 HOMARD_Hypothesis_i::HOMARD_Hypothesis_i()
648   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
649 {
650   MESSAGE("Default constructor, not for use");
651   ASSERT(0);
652 }
653
654 //=============================================================================
655 /*!
656  *  standard constructor
657  */
658 //=============================================================================
659 HOMARD_Hypothesis_i::HOMARD_Hypothesis_i(SMESHHOMARD::HOMARD_Gen_var engine)
660   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
661 {
662   MESSAGE("standard constructor");
663   _gen_i = engine;
664   myHomardHypothesis = new SMESHHOMARDImpl::HOMARD_Hypothesis();
665   ASSERT(myHomardHypothesis);
666
667   // SetUnifRefinUnRef(1)
668   int RefinType = 1;
669   int UnRefType = 0;
670   myHomardHypothesis->SetAdapType(-1);
671   myHomardHypothesis->SetRefinTypeDera(RefinType, UnRefType);
672
673   // Set name
674   myHomardHypothesis->SetName("Hypo_1");
675 }
676
677 //=============================================================================
678 /*!
679  *  standard destructor
680  */
681 //=============================================================================
682 HOMARD_Hypothesis_i::~HOMARD_Hypothesis_i()
683 {
684 }
685
686 //=============================================================================
687 void HOMARD_Hypothesis_i::SetExtraOutput(CORBA::Long ExtraOutput)
688 {
689   ASSERT(myHomardHypothesis);
690   myHomardHypothesis->SetExtraOutput(ExtraOutput);
691 }
692 //=============================================================================
693 CORBA::Long HOMARD_Hypothesis_i::GetExtraOutput()
694 {
695   ASSERT(myHomardHypothesis);
696   return myHomardHypothesis->GetExtraOutput();
697 }
698
699 //=============================================================================
700 //=============================================================================
701 // Liens avec les autres structures
702 //=============================================================================
703 //=============================================================================
704 void HOMARD_Hypothesis_i::LinkIteration(const char* NomIteration)
705 {
706   ASSERT(myHomardHypothesis);
707   myHomardHypothesis->LinkIteration(NomIteration);
708 }
709 //=============================================================================
710 void HOMARD_Hypothesis_i::UnLinkIteration(const char* NomIteration)
711 {
712   ASSERT(myHomardHypothesis);
713   myHomardHypothesis->UnLinkIteration(NomIteration);
714 }
715
716 //=============================================================================
717 /*!
718  *  standard constructor
719  */
720 //=============================================================================
721 HOMARD_Iteration_i::HOMARD_Iteration_i()
722   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
723 {
724   MESSAGE("Default constructor, not for use");
725   ASSERT(0);
726 }
727 //=============================================================================
728 /*!
729  *  standard constructor
730  */
731 //=============================================================================
732 HOMARD_Iteration_i::HOMARD_Iteration_i(SMESHHOMARD::HOMARD_Gen_var engine)
733   : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA())
734 {
735   MESSAGE("constructor");
736   _gen_i = engine;
737   myHomardIteration = new SMESHHOMARDImpl::HOMARD_Iteration();
738   ASSERT(myHomardIteration);
739 }
740 //=============================================================================
741 /*!
742  *  standard destructor
743  */
744 //=============================================================================
745 HOMARD_Iteration_i::~HOMARD_Iteration_i()
746 {
747 }
748 //=============================================================================
749 void HOMARD_Iteration_i::SetName(const char* Name)
750 {
751   ASSERT(myHomardIteration);
752   myHomardIteration->SetName(Name);
753 }
754 //=============================================================================
755 char* HOMARD_Iteration_i::GetName()
756 {
757   ASSERT(myHomardIteration);
758   return CORBA::string_dup(myHomardIteration->GetName().c_str());
759 }
760 //=============================================================================
761 void HOMARD_Iteration_i::SetDirNameLoc(const char* NomDir)
762 {
763   ASSERT(myHomardIteration);
764   myHomardIteration->SetDirNameLoc(NomDir);
765 }
766 //=============================================================================
767 char* HOMARD_Iteration_i::GetDirNameLoc()
768 {
769   ASSERT(myHomardIteration);
770   return CORBA::string_dup(myHomardIteration->GetDirNameLoc().c_str());
771 }
772 //=============================================================================
773 char* HOMARD_Iteration_i::GetDirName()
774 {
775   ASSERT(myHomardIteration);
776   SMESHHOMARD::HOMARD_Cas_ptr caseiter = _gen_i->GetCase();
777   std::string dirnamecase = caseiter->GetDirName();
778   std::string dirname = dirnamecase + "/" +  GetDirNameLoc();
779   return CORBA::string_dup(dirname.c_str());
780 }
781 //=============================================================================
782 void HOMARD_Iteration_i::SetNumber(CORBA::Long NumIter)
783 {
784   ASSERT(myHomardIteration);
785   myHomardIteration->SetNumber(NumIter);
786 }
787 //=============================================================================
788 CORBA::Long HOMARD_Iteration_i::GetNumber()
789 {
790   ASSERT(myHomardIteration);
791   return myHomardIteration->GetNumber();
792 }
793 //=============================================================================
794 void HOMARD_Iteration_i::SetState(CORBA::Long Etat)
795 {
796   ASSERT(myHomardIteration);
797   myHomardIteration->SetState(Etat);
798 }
799 //=============================================================================
800 CORBA::Long HOMARD_Iteration_i::GetState()
801 {
802   ASSERT(myHomardIteration);
803   return myHomardIteration->GetState();
804 }
805 //=============================================================================
806 void HOMARD_Iteration_i::SetMeshName(const char* NomMesh)
807 {
808   ASSERT(myHomardIteration);
809   myHomardIteration->SetMeshName(NomMesh);
810 }
811 //=============================================================================
812 char* HOMARD_Iteration_i::GetMeshName()
813 {
814   ASSERT(myHomardIteration);
815   return CORBA::string_dup(myHomardIteration->GetMeshName().c_str());
816 }
817 //=============================================================================
818 void HOMARD_Iteration_i::SetMeshFile(const char* MeshFile)
819 {
820   ASSERT(myHomardIteration);
821   myHomardIteration->SetMeshFile(MeshFile);
822 }
823 //=============================================================================
824 char* HOMARD_Iteration_i::GetMeshFile()
825 {
826   ASSERT(myHomardIteration);
827   return CORBA::string_dup(myHomardIteration->GetMeshFile().c_str());
828 }
829 //=============================================================================
830 void HOMARD_Iteration_i::SetLogFile(const char* LogFile)
831 {
832   ASSERT(myHomardIteration);
833   myHomardIteration->SetLogFile(LogFile);
834 }
835 //=============================================================================
836 char* HOMARD_Iteration_i::GetLogFile()
837 {
838   ASSERT(myHomardIteration);
839   return CORBA::string_dup(myHomardIteration->GetLogFile().c_str());
840 }
841 //=============================================================================
842 void HOMARD_Iteration_i::SetFileInfo(const char* FileInfo)
843 {
844   ASSERT(myHomardIteration);
845   myHomardIteration->SetFileInfo(FileInfo);
846 }
847 //=============================================================================
848 char* HOMARD_Iteration_i::GetFileInfo()
849 {
850   ASSERT(myHomardIteration);
851   return CORBA::string_dup(myHomardIteration->GetFileInfo().c_str());
852 }
853 //=============================================================================
854 //=============================================================================
855 // Liens avec les autres iterations
856 //=============================================================================
857 //=============================================================================
858 void HOMARD_Iteration_i::LinkNextIteration(const char* NomIteration)
859 {
860   ASSERT(myHomardIteration);
861   myHomardIteration->LinkNextIteration(NomIteration);
862 }
863 //=============================================================================
864 void HOMARD_Iteration_i::UnLinkNextIteration(const char* NomIteration)
865 {
866   ASSERT(myHomardIteration);
867   myHomardIteration->UnLinkNextIteration(NomIteration);
868 }
869 //=============================================================================
870 void HOMARD_Iteration_i::SetIterParentName(const char* NomIterParent)
871 {
872   ASSERT(myHomardIteration);
873   myHomardIteration->SetIterParentName(NomIterParent);
874 }
875 //=============================================================================
876 char* HOMARD_Iteration_i::GetIterParentName()
877 {
878   ASSERT(myHomardIteration);
879   return CORBA::string_dup(myHomardIteration->GetIterParentName().c_str());
880 }
881
882 //=============================================================================
883 //=============================================================================
884 // Liens avec les autres structures
885 //=============================================================================
886 //=============================================================================
887 void HOMARD_Iteration_i::SetCaseName(const char* NomCas)
888 {
889   ASSERT(myHomardIteration);
890   myHomardIteration->SetCaseName(NomCas);
891 }
892 //=============================================================================
893 char* HOMARD_Iteration_i::GetCaseName()
894 {
895   ASSERT(myHomardIteration);
896   return CORBA::string_dup(myHomardIteration->GetCaseName().c_str());
897 }
898 //=============================================================================
899 void HOMARD_Iteration_i::SetHypoName(const char* NomHypo)
900 {
901   ASSERT(myHomardIteration);
902   myHomardIteration->SetHypoName(NomHypo);
903 }
904 //=============================================================================
905 //=============================================================================
906 // Divers
907 //=============================================================================
908 //=============================================================================
909 void HOMARD_Iteration_i::SetInfoCompute(CORBA::Long MessInfo)
910 {
911   ASSERT(myHomardIteration);
912   myHomardIteration->SetInfoCompute(MessInfo);
913 }
914 //=============================================================================
915 CORBA::Long HOMARD_Iteration_i::GetInfoCompute()
916 {
917   ASSERT(myHomardIteration);
918   return myHomardIteration->GetInfoCompute();
919 }
920
921 //=============================================================================
922 /*!
923  *  standard constructor
924  */
925 //=============================================================================
926 HOMARD_Gen_i::HOMARD_Gen_i() : SALOME::GenericObj_i(SMESH_Gen_i::GetPOA()),
927                                _KeepMedOUT(true),
928                                _PublishMeshOUT(false),
929                                _KeepWorkingFiles(false),
930                                _LogInFile(false),
931                                _RemoveLogOnSuccess(false),
932                                _VerboseLevel(0),
933                                _MeshNameOUT(""),
934                                _MeshFileOUT(""),
935                                _LogFile(""),
936                                _CaseOnMedFile(true)
937 {
938   MESSAGE("constructor de HOMARD_Gen_i");
939   myHomard = new SMESHHOMARDImpl::HOMARD_Gen;
940 }
941
942 //=============================================================================
943 /*!
944  *  standard destructor
945  */
946 //=============================================================================
947 HOMARD_Gen_i::~HOMARD_Gen_i()
948 {
949 }
950
951 //=============================================================================
952 //=============================================================================
953 // Destruction des structures identifiees par leurs noms
954 //=============================================================================
955 //=============================================================================
956 CORBA::Long HOMARD_Gen_i::DeleteBoundary(const char* BoundaryName)
957 {
958   MESSAGE ("DeleteBoundary : BoundaryName = " << BoundaryName);
959   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
960   if (CORBA::is_nil(myBoundary)) {
961     SALOME::ExceptionStruct es;
962     es.type = SALOME::BAD_PARAM;
963     es.text = "Invalid boundary";
964     throw SALOME::SALOME_Exception(es);
965   }
966
967   // Boundaries should be deleted only after all cases deletion!!!
968
969   // comme on a un _var comme pointeur CORBA, on ne se preoccupe pas du delete
970   _mesBoundarys.erase(BoundaryName);
971
972   return 0;
973 }
974
975 //=============================================================================
976 CORBA::Long HOMARD_Gen_i::DeleteCase()
977 {
978   MESSAGE ("DeleteCase");
979   if (!CORBA::is_nil(myCase)) {
980     // Delete Iteration0
981     if (DeleteIteration(0) != 0) return 2;
982
983     myCase = SMESHHOMARD::HOMARD_Cas::_nil();
984   }
985   return 0;
986 }
987
988 //=============================================================================
989 CORBA::Long HOMARD_Gen_i::DeleteIteration(int numIter)
990 {
991   MESSAGE ("DeleteIteration : numIter = " << numIter);
992
993   if (numIter == 0) {
994     myIteration0 = SMESHHOMARD::HOMARD_Iteration::_nil();
995   }
996   else {
997     if (!CORBA::is_nil(myIteration1)) {
998       if (CORBA::is_nil(myIteration0)) {
999         SALOME::ExceptionStruct es;
1000         es.type = SALOME::BAD_PARAM;
1001         es.text = "Invalid iteration 0";
1002         throw SALOME::SALOME_Exception(es);
1003       }
1004
1005       // Invalide Iteration
1006       if (myIteration1->GetState() > 0) {
1007         myIteration1->SetState(1);
1008         if (!_KeepWorkingFiles) {
1009           std::string nomDir = myIteration1->GetDirName();
1010           std::string commande = "rm -rf " + nomDir;
1011           if (numIter > 0 && !_KeepMedOUT) {
1012             // Remove associated mesh file
1013             std::string nomFichier = myIteration1->GetMeshFile();
1014             commande = commande + ";rm -rf " + nomFichier;
1015           }
1016           MESSAGE ("commande = " << commande);
1017           if ((system(commande.c_str())) != 0) {
1018             SALOME::ExceptionStruct es;
1019             es.type = SALOME::BAD_PARAM;
1020             es.text = "The directory for the calculation cannot be cleared.";
1021             throw SALOME::SALOME_Exception(es);
1022           }
1023         }
1024       }
1025
1026       // Unlink from the parent iteration and from the hypothesis
1027       myIteration0->UnLinkNextIteration("Iter_1");
1028       ASSERT(!CORBA::is_nil(myHypothesis));
1029       myHypothesis->UnLinkIteration("Iter_1");
1030       myIteration1 = SMESHHOMARD::HOMARD_Iteration::_nil();
1031     }
1032   }
1033
1034   return 0;
1035 }
1036
1037 //=============================================================================
1038 //=============================================================================
1039 // Invalidation des structures identifiees par leurs noms
1040 //=============================================================================
1041 //=============================================================================
1042 void HOMARD_Gen_i::InvalideBoundary(const char* BoundaryName)
1043 {
1044   MESSAGE("InvalideBoundary : BoundaryName = " << BoundaryName);
1045   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
1046   if (CORBA::is_nil(myBoundary)) {
1047     SALOME::ExceptionStruct es;
1048     es.type = SALOME::BAD_PARAM;
1049     es.text = "Invalid boundary";
1050     throw SALOME::SALOME_Exception(es);
1051   }
1052   else {
1053     SALOME::ExceptionStruct es;
1054     es.type = SALOME::BAD_PARAM;
1055     es.text = "No change is allowed in a boundary. Ask for evolution.";
1056     throw SALOME::SALOME_Exception(es);
1057   }
1058 }
1059
1060 //=============================================================================
1061 //=============================================================================
1062 // Association de lien entre des structures identifiees par leurs noms
1063 //=============================================================================
1064 //=============================================================================
1065 void HOMARD_Gen_i::AssociateCaseIter(int numIter, const char* labelIter)
1066 {
1067   MESSAGE("AssociateCaseIter : " << numIter << ", "  << labelIter);
1068
1069   if (CORBA::is_nil(myCase)) {
1070     SALOME::ExceptionStruct es;
1071     es.type = SALOME::BAD_PARAM;
1072     es.text = "Invalid case";
1073     throw SALOME::SALOME_Exception(es);
1074   }
1075
1076   SMESHHOMARD::HOMARD_Iteration_var myIteration;
1077   if (numIter == 0) myIteration = myIteration0;
1078   else              myIteration = myIteration1;
1079   if (CORBA::is_nil(myIteration)) {
1080     SALOME::ExceptionStruct es;
1081     es.type = SALOME::BAD_PARAM;
1082     es.text = "Invalid iteration";
1083     throw SALOME::SALOME_Exception(es);
1084   }
1085
1086   myCase->AddIteration(myIteration->GetName());
1087   myIteration->SetCaseName("Case_1");
1088 }
1089
1090 //=============================================================================
1091 //=============================================================================
1092 // Recuperation des listes
1093 //=============================================================================
1094 //=============================================================================
1095 SMESHHOMARD::listeBoundarys* HOMARD_Gen_i::GetAllBoundarysName()
1096 {
1097   MESSAGE("GetAllBoundarysName");
1098
1099   SMESHHOMARD::listeBoundarys_var ret = new SMESHHOMARD::listeBoundarys;
1100   ret->length(_mesBoundarys.size());
1101   std::map<std::string, SMESHHOMARD::HOMARD_Boundary_var>::const_iterator it;
1102   int i = 0;
1103   for (it = _mesBoundarys.begin();
1104        it != _mesBoundarys.end(); it++) {
1105     ret[i++] = CORBA::string_dup((*it).first.c_str());
1106   }
1107
1108   return ret._retn();
1109 }
1110
1111 //=============================================================================
1112 //=============================================================================
1113 // Recuperation des structures identifiees par leurs noms
1114 //=============================================================================
1115 //=============================================================================
1116 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::GetBoundary(const char* nomBoundary)
1117 {
1118   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[nomBoundary];
1119   ASSERT(!CORBA::is_nil(myBoundary));
1120   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1121 }
1122 //=============================================================================
1123 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::GetCase()
1124 {
1125   ASSERT(!CORBA::is_nil(myCase));
1126   return SMESHHOMARD::HOMARD_Cas::_duplicate(myCase);
1127 }
1128 //=============================================================================
1129 SMESHHOMARD::HOMARD_Iteration_ptr HOMARD_Gen_i::GetIteration(int numIter)
1130 {
1131   if (numIter == 0) {
1132     ASSERT(!CORBA::is_nil(myIteration0));
1133     return SMESHHOMARD::HOMARD_Iteration::_duplicate(myIteration0);
1134   }
1135
1136   ASSERT(!CORBA::is_nil(myIteration1));
1137   return SMESHHOMARD::HOMARD_Iteration::_duplicate(myIteration1);
1138 }
1139
1140 //=============================================================================
1141 //=============================================================================
1142 // Nouvelles structures
1143 //=============================================================================
1144 //=============================================================================
1145 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::newCase()
1146 {
1147   SMESHHOMARD::HOMARD_Gen_var engine = POA_SMESHHOMARD::HOMARD_Gen::_this();
1148   HOMARD_Cas_i* aServant = new HOMARD_Cas_i(engine);
1149   SMESHHOMARD::HOMARD_Cas_var aCase = SMESHHOMARD::HOMARD_Cas::_narrow(aServant->_this());
1150   return aCase._retn();
1151 }
1152 //=============================================================================
1153 SMESHHOMARD::HOMARD_Iteration_ptr HOMARD_Gen_i::newIteration()
1154 {
1155   SMESHHOMARD::HOMARD_Gen_var engine = POA_SMESHHOMARD::HOMARD_Gen::_this();
1156   HOMARD_Iteration_i* aServant = new HOMARD_Iteration_i(engine);
1157   SMESHHOMARD::HOMARD_Iteration_var aIter =
1158     SMESHHOMARD::HOMARD_Iteration::_narrow(aServant->_this());
1159   return aIter._retn();
1160 }
1161 //=============================================================================
1162 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::newBoundary()
1163 {
1164   SMESHHOMARD::HOMARD_Gen_var engine = POA_SMESHHOMARD::HOMARD_Gen::_this();
1165   HOMARD_Boundary_i* aServant = new HOMARD_Boundary_i(engine);
1166   SMESHHOMARD::HOMARD_Boundary_var aBoundary =
1167     SMESHHOMARD::HOMARD_Boundary::_narrow(aServant->_this());
1168   return aBoundary._retn();
1169 }
1170
1171 //=============================================================================
1172 //=============================================================================
1173 // Creation des structures identifiees par leurs noms
1174 //=============================================================================
1175 //=============================================================================
1176
1177 //=============================================================================
1178 // Creation of a case
1179 // MeshName : name of the mesh
1180 // smeshMesh : correspondent mesh
1181 // theWorkingDir : path to working directory
1182 //=============================================================================
1183 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::CreateCaseOnMesh (const char* MeshName,
1184                                                             SMESH::SMESH_Mesh_ptr smeshMesh,
1185                                                             const char* theWorkingDir)
1186 {
1187   INFOS("CreateCaseOnMesh");
1188
1189   // A. Controles
1190   // A.1. Controle du nom :
1191   if (!myCase->_is_nil()) {
1192     CleanCase();
1193   }
1194
1195   // A.2. Controle du objet maillage
1196   if (CORBA::is_nil(smeshMesh)) {
1197     SALOME::ExceptionStruct es;
1198     es.type = SALOME::BAD_PARAM;
1199     es.text = "The mesh object is null.";
1200     throw SALOME::SALOME_Exception(es);
1201   }
1202   MESSAGE("CreateCaseOnMesh : smeshMesh is not nil");
1203
1204   // A.3. Write mesh object in a temporary file in the working directory
1205   std::string aTmpMeshFile (theWorkingDir);
1206   aTmpMeshFile += std::string("/") + std::string(MeshName) + "_saved_from_SMESH.med"; // TODO: unique
1207   const char* MeshFile = aTmpMeshFile.c_str();
1208   bool toOverwrite = true;
1209   bool toFindOutDim = true;
1210
1211   // Prevent dump of ExportMED
1212   {
1213     SMESH::TPythonDump pDump; // do not delete this line of code
1214     smeshMesh->ExportMED(MeshFile, false, -1, toOverwrite, toFindOutDim);
1215   }
1216
1217   // A.4. Controle du fichier du maillage
1218   med_idt medIdt = MEDfileOpen(MeshFile, MED_ACC_RDONLY);
1219   bool existeMeshFile = medIdt >= 0;
1220   if (existeMeshFile) MEDfileClose(medIdt);
1221   MESSAGE("CreateCaseOnMesh : existeMeshFile = " << existeMeshFile);
1222   if (!existeMeshFile) {
1223     SALOME::ExceptionStruct es;
1224     es.type = SALOME::BAD_PARAM;
1225     es.text = "The mesh file does not exist.";
1226     throw SALOME::SALOME_Exception(es);
1227   }
1228
1229   // B. Creation de l'objet cas
1230   myCase = newCase();
1231   _CaseOnMedFile = false;
1232   _SmeshMesh = SMESH::SMESH_Mesh::_duplicate(smeshMesh);
1233
1234   // C. Caracteristiques du maillage
1235   if (existeMeshFile) {
1236     // Les valeurs extremes des coordonnées
1237     //MESSAGE ("CreateCaseOnMesh : Les valeurs extremes des coordonnées");
1238     std::vector<double> LesExtremes = GetBoundingBoxInMedFile(MeshFile);
1239     SMESHHOMARD::extrema_var aSeq = new SMESHHOMARD::extrema();
1240     if (LesExtremes.size() != 10) { return 0; }
1241     aSeq->length(10);
1242     for (int i = 0; i < LesExtremes.size(); i++)
1243       aSeq[i] = LesExtremes[i];
1244     myCase->SetBoundingBox(aSeq);
1245     // Les groupes
1246     //MESSAGE ("CreateCaseOnMesh : Les groupes");
1247     std::set<std::string> LesGroupes = GetListeGroupesInMedFile(MeshFile);
1248     SMESHHOMARD::ListGroupType_var aSeqGroupe = new SMESHHOMARD::ListGroupType;
1249     aSeqGroupe->length(LesGroupes.size());
1250     std::set<std::string>::const_iterator it;
1251     int i = 0;
1252     for (it = LesGroupes.begin(); it != LesGroupes.end(); it++)
1253       aSeqGroupe[i++] = (*it).c_str();
1254     myCase->SetGroups(aSeqGroupe);
1255   }
1256
1257   // D. L'iteration initiale du cas
1258   MESSAGE ("CreateCaseOnMesh : iteration initiale du cas");
1259   // D.1. Recherche d'un nom : par defaut, on prend le nom du maillage correspondant.
1260   // Si ce nom d'iteration existe deja, on incremente avec 0, 1, 2, etc.
1261   MESSAGE("CreateCaseOnMesh : ==> NomIteration = " << MeshName);
1262
1263   // D.2. Creation de l'iteration 0
1264   myIteration0 = newIteration();
1265   myIteration0->SetName(MeshName);
1266   AssociateCaseIter(0, "IterationHomard");
1267
1268   // D.4. Maillage correspondant
1269   if (existeMeshFile) {
1270     myIteration0->SetMeshFile(MeshFile);
1271   }
1272   myIteration0->SetMeshName(MeshName);
1273   myIteration0->SetNumber(0);
1274   myIteration0->SetState(0);
1275
1276   // Only after full initialization of Iteration0
1277   myCase->SetDirName(theWorkingDir);
1278
1279   return SMESHHOMARD::HOMARD_Cas::_duplicate(myCase);
1280 }
1281
1282 //=============================================================================
1283 // Creation of a case
1284 // MeshName : name of the mesh
1285 // MeshFile : med file
1286 // theWorkingDir : path to working directory
1287 //=============================================================================
1288 SMESHHOMARD::HOMARD_Cas_ptr HOMARD_Gen_i::CreateCase(const char* MeshName,
1289                                                      const char* MeshFile,
1290                                                      const char* theWorkingDir)
1291 {
1292   INFOS("CreateCase : MeshName = " << MeshName << ", MeshFile = " << MeshFile);
1293
1294   // A. Controles
1295   // A.1. Controle du nom :
1296   if (!myCase->_is_nil()) {
1297     CleanCase();
1298   }
1299
1300   // A.3. Controle du fichier du maillage
1301   med_idt medIdt = MEDfileOpen(MeshFile, MED_ACC_RDONLY);
1302   bool existeMeshFile = medIdt >= 0;
1303   if (existeMeshFile) MEDfileClose(medIdt);
1304   MESSAGE("CreateCase : existeMeshFile = " << existeMeshFile);
1305   if (!existeMeshFile) {
1306     SALOME::ExceptionStruct es;
1307     es.type = SALOME::BAD_PARAM;
1308     es.text = "The mesh file does not exist.";
1309     throw SALOME::SALOME_Exception(es);
1310   }
1311
1312   // B. Creation de l'objet cas
1313   myCase = newCase();
1314   _CaseOnMedFile = true;
1315
1316   // C. Caracteristiques du maillage
1317   if (existeMeshFile) {
1318     // Les valeurs extremes des coordonnées
1319     //MESSAGE ("CreateCase : Les valeurs extremes des coordonnées");
1320     std::vector<double> LesExtremes = GetBoundingBoxInMedFile(MeshFile);
1321     SMESHHOMARD::extrema_var aSeq = new SMESHHOMARD::extrema();
1322     if (LesExtremes.size() != 10) { return 0; }
1323     aSeq->length(10);
1324     for (int i = 0; i < LesExtremes.size(); i++)
1325       aSeq[i] = LesExtremes[i];
1326     myCase->SetBoundingBox(aSeq);
1327     // Les groupes
1328     //MESSAGE ("CreateCase : Les groupes");
1329     std::set<std::string> LesGroupes = GetListeGroupesInMedFile(MeshFile);
1330     SMESHHOMARD::ListGroupType_var aSeqGroupe = new SMESHHOMARD::ListGroupType;
1331     aSeqGroupe->length(LesGroupes.size());
1332     std::set<std::string>::const_iterator it;
1333     int i = 0;
1334     for (it = LesGroupes.begin(); it != LesGroupes.end(); it++)
1335       aSeqGroupe[i++] = (*it).c_str();
1336     myCase->SetGroups(aSeqGroupe);
1337   }
1338
1339   // D. L'iteration initiale du cas
1340   MESSAGE ("CreateCase : iteration initiale du cas");
1341   // D.1. Recherche d'un nom : par defaut, on prend le nom du maillage correspondant.
1342   // Si ce nom d'iteration existe deja, on incremente avec 0, 1, 2, etc.
1343   MESSAGE("CreateCas : ==> NomIteration = " << MeshName);
1344
1345   // D.2. Creation de l'iteration
1346   myIteration0 = newIteration();
1347   myIteration0->SetName(MeshName);
1348   AssociateCaseIter(0, "IterationHomard");
1349
1350   // D.4. Maillage correspondant
1351   if (existeMeshFile) {
1352     myIteration0->SetMeshFile(MeshFile);
1353   }
1354   myIteration0->SetMeshName(MeshName);
1355   myIteration0->SetNumber(0);
1356   myIteration0->SetState(0);
1357
1358   // Only after full initialization of Iteration0
1359   myCase->SetDirName(theWorkingDir);
1360
1361   return SMESHHOMARD::HOMARD_Cas::_duplicate(myCase);
1362 }
1363
1364 //=============================================================================
1365 // Create Iteration1
1366 //=============================================================================
1367 SMESHHOMARD::HOMARD_Iteration_ptr HOMARD_Gen_i::CreateIteration()
1368 {
1369   if (CORBA::is_nil(myIteration0)) {
1370     SALOME::ExceptionStruct es;
1371     es.type = SALOME::BAD_PARAM;
1372     es.text = "The parent iteration is not defined.";
1373     throw SALOME::SALOME_Exception(es);
1374   }
1375
1376   if (CORBA::is_nil(myCase)) {
1377     SALOME::ExceptionStruct es;
1378     es.type = SALOME::BAD_PARAM;
1379     es.text = "Invalid case context";
1380     throw SALOME::SALOME_Exception(es);
1381   }
1382   const char* nomDirCase = myCase->GetDirName();
1383
1384   if (!myIteration1->_is_nil()) {
1385     DeleteIteration(1);
1386   }
1387
1388   myIteration1 = newIteration();
1389   if (CORBA::is_nil(myIteration1)) {
1390     SALOME::ExceptionStruct es;
1391     es.type = SALOME::BAD_PARAM;
1392     es.text = "Unable to create the iteration 1";
1393     throw SALOME::SALOME_Exception(es);
1394   }
1395
1396   // Nom de l'iteration et du maillage
1397   myIteration1->SetName("Iter_1");
1398   myIteration1->SetMeshName("Iter_1");
1399   myIteration1->SetState(1);
1400   myIteration1->SetNumber(1);
1401
1402   int nbitercase = 1; //myCase->GetNumberofIter()
1403   char* nomDirIter = CreateDirNameIter(nomDirCase, nbitercase);
1404   myIteration1->SetDirNameLoc(nomDirIter);
1405
1406   // Le nom du fichier du maillage MED est indice par le nombre d'iterations du cas.
1407   // Si on a une chaine unique depuis le depart, ce nombre est le meme que le
1408   // numero d'iteration dans la sucession : maill.01.med, maill.02.med, etc... C'est la
1409   // situation la plus frequente.
1410   // Si on a plusieurs branches, donc des iterations du meme niveau d'adaptation, utiliser
1411   // le nombre d'iterations du cas permet d'eviter les collisions.
1412   int jaux;
1413   if      (nbitercase <    100) { jaux = 2; }
1414   else if (nbitercase <   1000) { jaux = 3; }
1415   else if (nbitercase <  10000) { jaux = 4; }
1416   else if (nbitercase < 100000) { jaux = 5; }
1417   else                          { jaux = 9; }
1418   std::ostringstream iaux;
1419   iaux << std::setw(jaux) << std::setfill('0') << nbitercase;
1420   std::stringstream MeshFile;
1421   MeshFile << nomDirCase << "/maill." << iaux.str() << ".med";
1422   myIteration1->SetMeshFile(MeshFile.str().c_str());
1423
1424   // Association avec le cas
1425   std::string nomIterParent = myIteration0->GetName();
1426   std::string label = "IterationHomard_" + nomIterParent;
1427   AssociateCaseIter(1, label.c_str());
1428
1429   // Lien avec l'iteration precedente
1430   myIteration0->LinkNextIteration("Iter_1");
1431   myIteration1->SetIterParentName(nomIterParent.c_str());
1432
1433   // Associate hypothesis
1434   if (CORBA::is_nil(myHypothesis)) {
1435     SMESHHOMARD::HOMARD_Gen_var engine = POA_SMESHHOMARD::HOMARD_Gen::_this();
1436     HOMARD_Hypothesis_i* aServant = new HOMARD_Hypothesis_i(engine);
1437     myHypothesis = SMESHHOMARD::HOMARD_Hypothesis::_narrow(aServant->_this());
1438     if (CORBA::is_nil(myHypothesis)) {
1439       SALOME::ExceptionStruct es;
1440       es.type = SALOME::BAD_PARAM;
1441       es.text = "Unable to create the hypothesis";
1442       throw SALOME::SALOME_Exception(es);
1443     }
1444     //myHypothesis->SetNivMax(-1);
1445     //myHypothesis->SetDiamMin(-1.0);
1446     //myHypothesis->SetAdapInit(0);
1447     //myHypothesis->SetExtraOutput(1);
1448   }
1449   myIteration1->SetHypoName("Hypo_1");
1450   myHypothesis->LinkIteration("Iter_1");
1451
1452   return SMESHHOMARD::HOMARD_Iteration::_duplicate(myIteration1);
1453 }
1454 //=============================================================================
1455 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundary(const char* BoundaryName,
1456                                                               CORBA::Long BoundaryType)
1457 {
1458   MESSAGE ("CreateBoundary : BoundaryName  = " << BoundaryName <<
1459            ", BoundaryType = " << BoundaryType);
1460
1461   // Controle du nom :
1462   if ((_mesBoundarys).find(BoundaryName) != (_mesBoundarys).end()) {
1463     MESSAGE ("CreateBoundary : la frontiere " << BoundaryName << " existe deja");
1464     SALOME::ExceptionStruct es;
1465     es.type = SALOME::BAD_PARAM;
1466     es.text = "This boundary has already been defined";
1467     throw SALOME::SALOME_Exception(es);
1468   }
1469
1470   SMESHHOMARD::HOMARD_Boundary_var myBoundary = newBoundary();
1471   myBoundary->SetName(BoundaryName);
1472   myBoundary->SetType(BoundaryType);
1473
1474   _mesBoundarys[BoundaryName] = myBoundary;
1475
1476   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1477 }
1478 //=============================================================================
1479 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryCAO(const char* BoundaryName, const char* CAOFile)
1480 {
1481   MESSAGE ("CreateBoundaryCAO : BoundaryName  = " << BoundaryName << ", CAOFile = " << CAOFile);
1482   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, -1);
1483   myBoundary->SetDataFile(CAOFile);
1484
1485   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1486 }
1487 //=============================================================================
1488 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryDi(const char* BoundaryName, const char* MeshName, const char* MeshFile)
1489 {
1490   MESSAGE ("CreateBoundaryDi : BoundaryName  = " << BoundaryName << ", MeshName = " << MeshName << ", MeshFile = " << MeshFile);
1491   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 0);
1492   myBoundary->SetDataFile(MeshFile);
1493   myBoundary->SetMeshName(MeshName);
1494
1495   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1496 }
1497 //=============================================================================
1498 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryCylinder(const char* BoundaryName,
1499                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre,
1500                                       CORBA::Double Xaxe, CORBA::Double Yaxe, CORBA::Double Zaxe,
1501                                       CORBA::Double Rayon)
1502 {
1503   MESSAGE ("CreateBoundaryCylinder : BoundaryName  = " << BoundaryName);
1504 //
1505   SALOME::ExceptionStruct es;
1506   int error = 0;
1507   if (Rayon <= 0.0)
1508   { es.text = "The radius must be positive.";
1509     error = 1; }
1510   double daux = fabs(Xaxe) + fabs(Yaxe) + fabs(Zaxe);
1511   if (daux < 0.0000001)
1512   { es.text = "The axis must be a non 0 vector.";
1513     error = 2; }
1514   if (error != 0)
1515   {
1516     es.type = SALOME::BAD_PARAM;
1517     throw SALOME::SALOME_Exception(es);
1518     return 0;
1519   };
1520 //
1521   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 1);
1522   myBoundary->SetCylinder(Xcentre, Ycentre, Zcentre, Xaxe, Yaxe, Zaxe, Rayon);
1523
1524   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1525 }
1526 //=============================================================================
1527 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundarySphere(const char* BoundaryName,
1528                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre,
1529                                       CORBA::Double Rayon)
1530 {
1531   MESSAGE ("CreateBoundarySphere : BoundaryName  = " << BoundaryName);
1532 //
1533   SALOME::ExceptionStruct es;
1534   int error = 0;
1535   if (Rayon <= 0.0)
1536   { es.text = "The radius must be positive.";
1537     error = 1; }
1538   if (error != 0)
1539   {
1540     es.type = SALOME::BAD_PARAM;
1541     throw SALOME::SALOME_Exception(es);
1542     return 0;
1543   };
1544 //
1545   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 2);
1546   myBoundary->SetSphere(Xcentre, Ycentre, Zcentre, Rayon);
1547
1548   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1549 }
1550 //=============================================================================
1551 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryConeA(const char* BoundaryName,
1552                                       CORBA::Double Xaxe, CORBA::Double Yaxe, CORBA::Double Zaxe, CORBA::Double Angle,
1553                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre)
1554 {
1555   MESSAGE ("CreateBoundaryConeA : BoundaryName  = " << BoundaryName);
1556 //
1557   SALOME::ExceptionStruct es;
1558   int error = 0;
1559   if (Angle <= 0.0 || Angle >= 90.0)
1560   { es.text = "The angle must be included higher than 0 degree and lower than 90 degrees.";
1561     error = 1; }
1562   double daux = fabs(Xaxe) + fabs(Yaxe) + fabs(Zaxe);
1563   if (daux < 0.0000001)
1564   { es.text = "The axis must be a non 0 vector.";
1565     error = 2; }
1566   if (error != 0)
1567   {
1568     es.type = SALOME::BAD_PARAM;
1569     throw SALOME::SALOME_Exception(es);
1570     return 0;
1571   };
1572 //
1573   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 3);
1574   myBoundary->SetConeA(Xaxe, Yaxe, Zaxe, Angle, Xcentre, Ycentre, Zcentre);
1575
1576   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1577 }
1578 //=============================================================================
1579 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryConeR(const char* BoundaryName,
1580                                       CORBA::Double Xcentre1, CORBA::Double Ycentre1, CORBA::Double Zcentre1, CORBA::Double Rayon1,
1581                                       CORBA::Double Xcentre2, CORBA::Double Ycentre2, CORBA::Double Zcentre2, CORBA::Double Rayon2)
1582 {
1583   MESSAGE ("CreateBoundaryConeR : BoundaryName  = " << BoundaryName);
1584 //
1585   SALOME::ExceptionStruct es;
1586   int error = 0;
1587   if (Rayon1 < 0.0 || Rayon2 < 0.0)
1588   { es.text = "The radius must be positive.";
1589     error = 1; }
1590   double daux = fabs(Rayon2-Rayon1);
1591   if (daux < 0.0000001)
1592   { es.text = "The radius must be different.";
1593     error = 2; }
1594   daux = fabs(Xcentre2-Xcentre1) + fabs(Ycentre2-Ycentre1) + fabs(Zcentre2-Zcentre1);
1595   if (daux < 0.0000001)
1596   { es.text = "The centers must be different.";
1597     error = 3; }
1598   if (error != 0)
1599   {
1600     es.type = SALOME::BAD_PARAM;
1601     throw SALOME::SALOME_Exception(es);
1602     return 0;
1603   };
1604 //
1605   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 4);
1606   myBoundary->SetConeR(Xcentre1, Ycentre1, Zcentre1, Rayon1, Xcentre2, Ycentre2, Zcentre2, Rayon2);
1607
1608   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1609 }
1610 //=============================================================================
1611 SMESHHOMARD::HOMARD_Boundary_ptr HOMARD_Gen_i::CreateBoundaryTorus(const char* BoundaryName,
1612                                       CORBA::Double Xcentre, CORBA::Double Ycentre, CORBA::Double Zcentre,
1613                                       CORBA::Double Xaxe, CORBA::Double Yaxe, CORBA::Double Zaxe,
1614                                       CORBA::Double RayonRev, CORBA::Double RayonPri)
1615 {
1616   MESSAGE ("CreateBoundaryTorus : BoundaryName  = " << BoundaryName);
1617 //
1618   SALOME::ExceptionStruct es;
1619   int error = 0;
1620   if ((RayonRev <= 0.0) || (RayonPri <= 0.0))
1621   { es.text = "The radius must be positive.";
1622     error = 1; }
1623   double daux = fabs(Xaxe) + fabs(Yaxe) + fabs(Zaxe);
1624   if (daux < 0.0000001)
1625   { es.text = "The axis must be a non 0 vector.";
1626     error = 2; }
1627   if (error != 0)
1628   {
1629     es.type = SALOME::BAD_PARAM;
1630     throw SALOME::SALOME_Exception(es);
1631     return 0;
1632   };
1633 //
1634   SMESHHOMARD::HOMARD_Boundary_var myBoundary = CreateBoundary(BoundaryName, 5);
1635   myBoundary->SetTorus(Xcentre, Ycentre, Zcentre, Xaxe, Yaxe, Zaxe, RayonRev, RayonPri);
1636
1637   return SMESHHOMARD::HOMARD_Boundary::_duplicate(myBoundary);
1638 }
1639
1640 //=============================================================================
1641 //=============================================================================
1642 CORBA::Long HOMARD_Gen_i::Compute()
1643 {
1644   INFOS ("Compute");
1645   // A. Prealable
1646   int codret = 0;
1647
1648   // A.0. Create Iteration 1
1649   myIteration1 = CreateIteration();
1650   myIteration1->SetInfoCompute(_VerboseLevel);
1651   myIteration1->SetMeshName(_MeshNameOUT.c_str());
1652   myIteration1->SetMeshFile(_MeshFileOUT.c_str());
1653   if (_LogInFile) myIteration1->SetLogFile(_LogFile.c_str());
1654
1655   // A.1. L'objet iteration
1656   ASSERT(!CORBA::is_nil(myIteration1));
1657
1658   // A.2. Controle de la possibilite d'agir
1659   // A.2.1. Etat de l'iteration
1660   int etat = myIteration1->GetState();
1661   MESSAGE ("etat = " << etat);
1662   // A.2.2. On ne calcule pas l'iteration initiale, ni une iteration deja calculee
1663   if (etat == 2) {
1664     SALOME::ExceptionStruct es;
1665     es.type = SALOME::BAD_PARAM;
1666     es.text = "This iteration is already computed.";
1667     throw SALOME::SALOME_Exception(es);
1668   }
1669
1670   // A.3. Numero de l'iteration
1671   //     siterp1 : numero de l'iteration a traiter
1672   //     Si adaptation :
1673   //        siter: numero de l'iteration parent, ou 0 si deja au debut mais cela ne servira pas !
1674   //     Ou si information :
1675   //        siter = siterp1
1676   int NumeIter = myIteration1->GetNumber();
1677   std::string siterp1;
1678   std::stringstream saux1;
1679   saux1 << NumeIter;
1680   siterp1 = saux1.str();
1681   if (NumeIter < 10) { siterp1 = "0" + siterp1; }
1682
1683   std::string siter;
1684   std::stringstream saux0;
1685   int iaux = max(0, NumeIter-1);
1686   saux0 << iaux;
1687   siter = saux0.str();
1688   if (NumeIter < 11) { siter = "0" + siter; }
1689
1690   // A.4. Le cas
1691   ASSERT(!CORBA::is_nil(myCase));
1692
1693   // B. Les répertoires
1694   // B.1. Le répertoire courant
1695   std::string nomDirWork = getenv("PWD");
1696   // B.2. Le sous-répertoire de l'iteration a traiter
1697   char* DirCompute = ComputeDirManagement(myCase, myIteration1);
1698   MESSAGE(". DirCompute = " << DirCompute);
1699
1700   // C. Le fichier des messages
1701   // C.1. Le deroulement de l'execution de HOMARD
1702   std::string LogFile = myIteration1->GetLogFile();
1703   if (LogFile.empty()) {
1704     LogFile = DirCompute;
1705     LogFile += "/Liste." + siter + ".vers." + siterp1 + ".log";
1706     myIteration1->SetLogFile(LogFile.c_str());
1707   }
1708   MESSAGE (". LogFile = " << LogFile);
1709   // C.2. Le bilan de l'analyse du maillage
1710   std::string FileInfo = DirCompute;
1711   FileInfo += "/apad." + siterp1 + ".bilan";
1712   myIteration1->SetFileInfo(FileInfo.c_str());
1713
1714    // D. On passe dans le répertoire de l'iteration a calculer
1715   MESSAGE (". On passe dans DirCompute = " << DirCompute);
1716   CHDIR(DirCompute);
1717
1718   // E. Les données de l'exécution HOMARD
1719   // E.1. L'objet du texte du fichier de configuration
1720   SMESHHOMARDImpl::HomardDriver* myDriver = new SMESHHOMARDImpl::HomardDriver(siter, siterp1);
1721   myDriver->TexteInit(DirCompute, LogFile, "English");
1722
1723   // E.2. Le maillage associe a l'iteration
1724   const char* NomMesh = myIteration1->GetMeshName();
1725   MESSAGE (". NomMesh = " << NomMesh);
1726   const char* MeshFile = myIteration1->GetMeshFile();
1727   MESSAGE (". MeshFile = " << MeshFile);
1728
1729   // E.3. Les données du traitement HOMARD
1730   iaux = 1;
1731   myDriver->TexteMaillageHOMARD(DirCompute, siterp1, iaux);
1732   myDriver->TexteMaillage(NomMesh, MeshFile, 1);
1733   codret = ComputeAdap(myCase, myIteration1, myDriver);
1734
1735   // E.4. Ajout des informations liees a l'eventuel suivi de frontiere
1736   int BoundaryOption = DriverTexteBoundary(myCase, myDriver);
1737
1738   // E.5. Ecriture du texte dans le fichier
1739   MESSAGE (". Ecriture du texte dans le fichier de configuration; codret = "<<codret);
1740   if (codret == 0)
1741   { myDriver->CreeFichier(); }
1742
1743   // G. Execution
1744   //
1745   int codretexec = 1789;
1746   if (codret == 0) {
1747     codretexec = myDriver->ExecuteHomard();
1748     //
1749     MESSAGE ("Erreur en executant HOMARD : " << codretexec);
1750     // En mode adaptation, on ajuste l'etat de l'iteration
1751     if (codretexec == 0) { myIteration1->SetState(2); }
1752     else                 { myIteration1->SetState(1); }
1753   }
1754
1755   // H. Gestion des resultats
1756   if (codret == 0) {
1757     std::string Commentaire;
1758     // H.1. Le fichier des messages, dans tous les cas
1759     Commentaire = "log";
1760     Commentaire += " " + siterp1;
1761
1762     // H.2. Si tout s'est bien passe :
1763     if (codretexec == 0) {
1764       // H.2.1. Le fichier de bilan
1765       Commentaire = "Summary";
1766       Commentaire += " " + siterp1;
1767       // H.2.2. Le fichier de  maillage obtenu
1768       std::stringstream saux0;
1769       Commentaire = "Mesh";
1770       Commentaire += " " + siterp1;
1771       if (_PublishMeshOUT) PublishResultInSmesh(MeshFile, 1);
1772     }
1773     // H.3 Message d'erreur
1774     if (codretexec != 0) {
1775       std::string text = "";
1776       // Message d'erreur en cas de probleme en adaptation
1777       text = "Error during the adaptation.\n";
1778       bool stopvu = false;
1779       std::ifstream fichier(LogFile.c_str());
1780       if (fichier) { // ce test Ã©choue si le fichier n'est pas ouvert
1781         std::string ligne; // variable contenant chaque ligne lue
1782         while (std::getline(fichier, ligne)) {
1783           //INFOS(ligne);
1784           if (stopvu) { text += ligne+ "\n"; }
1785           else {
1786             int position = ligne.find("===== HOMARD ===== STOP =====");
1787             if (position > 0) { stopvu = true; }
1788           }
1789         }
1790       }
1791       text += "\n\nSee the file " + LogFile + "\n";
1792       INFOS (text);
1793       SALOME::ExceptionStruct es;
1794       es.type = SALOME::BAD_PARAM;
1795       es.text = CORBA::string_dup(text.c_str());
1796       throw SALOME::SALOME_Exception(es);
1797     }
1798   }
1799
1800   // I. Menage et retour dans le répertoire du cas
1801   if (codret == 0) {
1802     delete myDriver;
1803     MESSAGE (". On retourne dans nomDirWork = " << nomDirWork);
1804     CHDIR(nomDirWork.c_str());
1805   }
1806
1807   // J. Suivi de la frontière CAO
1808   if (codret == 0) {
1809     if ((BoundaryOption % 5 == 0) && (codretexec == 0)) {
1810       MESSAGE ("Suivi de frontière CAO");
1811       codret = ComputeCAO(myCase, myIteration1);
1812     }
1813   }
1814
1815   if (codretexec == 0) {
1816     // Python Dump
1817     PythonDump();
1818
1819     // Delete log file, if required
1820     MESSAGE("myIteration1->GetLogFile() = " << myIteration1->GetLogFile());
1821     if (_LogInFile && _RemoveLogOnSuccess) {
1822       // Remove log file on success
1823       // TODO: QFile(myIteration->GetLogFile()).remove();
1824     }
1825
1826     // Clean all data
1827     CleanCase();
1828   }
1829
1830   return codretexec;
1831 }
1832
1833 void HOMARD_Gen_i::CleanCase()
1834 {
1835   // Delete all boundaries
1836   std::map<std::string, SMESHHOMARD::HOMARD_Boundary_var>::const_iterator it_boundary;
1837   for (it_boundary  = _mesBoundarys.begin();
1838        it_boundary != _mesBoundarys.end(); ++it_boundary) {
1839     DeleteBoundary((*it_boundary).first.c_str());
1840   }
1841
1842   // Delete iteration
1843   DeleteIteration(1);
1844
1845   // Delete hypothesis
1846   // Hypothesis should be deleted only after iteration deletion
1847   myHypothesis = SMESHHOMARD::HOMARD_Hypothesis::_nil();
1848
1849   // Delete case
1850   DeleteCase();
1851 }
1852
1853 //=============================================================================
1854 // Calcul d'une iteration : partie spécifique Ã  l'adaptation
1855 //=============================================================================
1856 CORBA::Long HOMARD_Gen_i::ComputeAdap(SMESHHOMARD::HOMARD_Cas_var myCase,
1857                                       SMESHHOMARD::HOMARD_Iteration_var myIteration,
1858                                       SMESHHOMARDImpl::HomardDriver* myDriver)
1859 {
1860   MESSAGE ("ComputeAdap");
1861
1862   // A. Prealable
1863   // A.1. Bases
1864   int codret = 0;
1865   // Numero de l'iteration
1866   int NumeIter = myIteration->GetNumber();
1867   std::stringstream saux0;
1868   saux0 << NumeIter-1;
1869   std::string siter = saux0.str();
1870   if (NumeIter < 11) { siter = "0" + siter; }
1871
1872   // A.2. On verifie qu il y a une hypothese (erreur improbable);
1873   ASSERT(!CORBA::is_nil(myHypothesis));
1874
1875   // B. L'iteration parent
1876   //const char* nomIterationParent = myIteration->GetIterParentName();
1877   SMESHHOMARD::HOMARD_Iteration_var myIterationParent = myIteration0;
1878   ASSERT(!CORBA::is_nil(myIterationParent));
1879   // Si l'iteration parent n'est pas calculee, on le fait (recursivite amont)
1880   //if (myIterationParent->GetState() == 1) {
1881   //  int codret = Compute(nomIterationParent);
1882   //  if (codret != 0) VERIFICATION("Pb au calcul de l'iteration precedente" == 0);
1883   //}
1884
1885   // C. Le sous-répertoire de l'iteration precedente
1886   char* DirComputePa = ComputeDirPaManagement(myCase, myIteration);
1887   MESSAGE(". DirComputePa = " << DirComputePa);
1888
1889   // D. Les données de l'adaptation HOMARD
1890   // D.1. Le type de conformite
1891   int ConfType = myCase->GetConfType();
1892   MESSAGE (". ConfType = " << ConfType);
1893
1894   // D.3. Le maillage de depart
1895   const char* NomMeshParent = myIterationParent->GetMeshName();
1896   MESSAGE (". NomMeshParent = " << NomMeshParent);
1897   const char* MeshFileParent = myIterationParent->GetMeshFile();
1898   MESSAGE (". MeshFileParent = " << MeshFileParent);
1899
1900   // D.4. Le maillage associe a l'iteration
1901   const char* MeshFile = myIteration->GetMeshFile();
1902   MESSAGE (". MeshFile = " << MeshFile);
1903   FILE *file = fopen(MeshFile,"r");
1904   if (file != NULL) {
1905     fclose(file);
1906     // CleanOption = 0 : report an error if output mesh file exists
1907     // CleanOption = 1 : destruction du répertoire d'execution
1908     int CleanOption = 0;
1909     if (CleanOption == 0) {
1910       SALOME::ExceptionStruct es;
1911       es.type = SALOME::BAD_PARAM;
1912       std::string text = "MeshFile : " + std::string(MeshFile) + " already exists ";
1913       es.text = CORBA::string_dup(text.c_str());
1914       throw SALOME::SALOME_Exception(es);
1915     }
1916     else {
1917       std::string commande = "rm -f " + std::string(MeshFile);
1918       codret = system(commande.c_str());
1919       if (codret != 0) {
1920         SALOME::ExceptionStruct es;
1921         es.type = SALOME::BAD_PARAM;
1922         es.text = "The mesh file cannot be deleted.";
1923         throw SALOME::SALOME_Exception(es);
1924       }
1925     }
1926   }
1927
1928   // D.5. Les types de raffinement et de deraffinement
1929   // Les appels corba sont lourds, il vaut mieux les grouper
1930   //SMESHHOMARD::listeTypes* ListTypes = myHypothesis->GetAdapRefinUnRef();
1931   //ASSERT(ListTypes->length() == 3);
1932   int TypeAdap = -1; // HomardHypothesis->GetAdapType()
1933   int TypeRaff = 1; // HomardHypothesis->GetRefinType()
1934   int TypeDera = 0; // HomardHypothesis->GetUnRefType()
1935
1936   // E. Texte du fichier de configuration
1937   // E.1. Incontournables du texte
1938   myDriver->TexteAdap();
1939   int iaux = 0;
1940   myDriver->TexteMaillageHOMARD(DirComputePa, siter, iaux);
1941   myDriver->TexteMaillage(NomMeshParent, MeshFileParent, 0);
1942   myDriver->TexteConfRaffDera(ConfType, TypeAdap, TypeRaff, TypeDera);
1943
1944   // E.6. Ajout des options avancees
1945   //int NivMax = myHypo->GetNivMax();
1946   //MESSAGE (". NivMax = " << NivMax);
1947   //double DiamMin = myHypo->GetDiamMin();
1948   //MESSAGE (". DiamMin = " << DiamMin);
1949   //int AdapInit = myHypo->GetAdapInit();
1950   //MESSAGE (". AdapInit = " << AdapInit);
1951   //int ExtraOutput = myHypo->GetExtraOutput();
1952   //MESSAGE (". ExtraOutput = " << ExtraOutput);
1953   //myDriver->TexteAdvanced(NivMax, DiamMin, AdapInit, ExtraOutput);
1954   myDriver->TexteAdvanced(-1, -1.0, 0, 1);
1955
1956   // E.7. Ajout des informations sur le deroulement de l'execution
1957   int MessInfo = myIteration->GetInfoCompute();
1958   MESSAGE (". MessInfo = " << MessInfo);
1959   myDriver->TexteInfoCompute(MessInfo);
1960
1961   return codret;
1962 }
1963 //=============================================================================
1964 // Calcul d'une iteration : partie spécifique au suivi de frontière CAO
1965 //=============================================================================
1966 CORBA::Long HOMARD_Gen_i::ComputeCAO(SMESHHOMARD::HOMARD_Cas_var myCase,
1967                                      SMESHHOMARD::HOMARD_Iteration_var myIteration)
1968 {
1969   MESSAGE ("ComputeCAO");
1970
1971   // A. Prealable
1972   // A.1. Bases
1973   int codret = 0;
1974   // A.2. Le sous-répertoire de l'iteration en cours de traitement
1975   char* DirCompute = myIteration->GetDirName();
1976   // A.3. Le maillage résultat de l'iteration en cours de traitement
1977   char* MeshFile = myIteration->GetMeshFile();
1978
1979   // B. Les données pour FrontTrack
1980   // B.1. Le maillage Ã  modifier
1981   const std::string theInputMedFile = MeshFile;
1982   MESSAGE (". theInputMedFile  = " << theInputMedFile);
1983
1984   // B.2. Le maillage après modification : fichier identique
1985   const std::string theOutputMedFile = MeshFile;
1986   MESSAGE (". theOutputMedFile = " << theInputMedFile);
1987
1988   // B.3. La liste des fichiers contenant les numéros des noeuds Ã  bouger
1989   std::vector< std::string > theInputNodeFiles;
1990   MESSAGE (". DirCompute = " << DirCompute);
1991   std::basic_string<char>::size_type bilan;
1992   int icpt = 0;
1993 #ifndef WIN32
1994   DIR *dp;
1995   struct dirent *dirp;
1996   dp  = opendir(DirCompute);
1997   while ((dirp = readdir(dp)) != NULL)
1998   {
1999     std::string file_name(dirp->d_name);
2000     bilan = file_name.find("fr");
2001     if (bilan != string::npos)
2002     {
2003       std::stringstream filename_total;
2004       filename_total << DirCompute << "/" << file_name;
2005       theInputNodeFiles.push_back(filename_total.str());
2006       icpt += 1;
2007     }
2008   }
2009 #else
2010   HANDLE hFind = INVALID_HANDLE_VALUE;
2011   WIN32_FIND_DATA ffd;
2012   hFind = FindFirstFile(DirNameStart, &ffd);
2013   if (INVALID_HANDLE_VALUE != hFind) {
2014     while (FindNextFile(hFind, &ffd) != 0) {
2015       std::string file_name(ffd.cFileName);
2016       bilan = file_name.find("fr");
2017       if (bilan != string::npos)
2018       {
2019         std::stringstream filename_total;
2020         filename_total << DirCompute << "/" << file_name;
2021         theInputNodeFiles.push_back(filename_total.str());
2022         icpt += 1;
2023       }
2024     }
2025     FindClose(hFind);
2026   }
2027 #endif
2028   for (int i = 0; i < icpt; i++)
2029   { MESSAGE (". theInputNodeFiles["<< i << "] = " << theInputNodeFiles[i]); }
2030
2031   // B.4. Le fichier de la CAO
2032   SMESHHOMARD::ListBoundaryGroupType* ListBoundaryGroupType = myCase->GetBoundaryGroup();
2033   std::string BoundaryName = std::string((*ListBoundaryGroupType)[0]);
2034   MESSAGE (". BoundaryName = " << BoundaryName);
2035   SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
2036   const std::string theXaoFileName = myBoundary->GetDataFile();
2037   MESSAGE (". theXaoFileName = " << theXaoFileName);
2038
2039   // B.5. Parallélisme
2040   //bool theIsParallel = false;
2041
2042   // C. Lancement des projections
2043   MESSAGE (". Lancement des projections");
2044   //FrontTrack* myFrontTrack = new FrontTrack();
2045   //myFrontTrack->track(theInputMedFile, theOutputMedFile, theInputNodeFiles, theXaoFileName, theIsParallel);
2046
2047   // D. Transfert des coordonnées modifiées dans le fichier historique de HOMARD
2048   //    On lance une exécution spéciale de HOMARD en attendant de savoir le faire avec MEDCoupling
2049   MESSAGE (". Transfert des coordonnées");
2050   codret = ComputeCAObis(myIteration);
2051
2052   return codret;
2053 }
2054 //=============================================================================
2055 //=============================================================================
2056 // Transfert des coordonnées en suivi de frontière CAO
2057 //=============================================================================
2058 CORBA::Long HOMARD_Gen_i::ComputeCAObis(SMESHHOMARD::HOMARD_Iteration_var myIteration)
2059 {
2060   MESSAGE ("ComputeCAObis");
2061
2062   // A. Prealable
2063   int codret = 0;
2064
2065   // A.1. Controle de la possibilite d'agir
2066   // A.1.1. Etat de l'iteration
2067   int etat = myIteration->GetState();
2068   MESSAGE ("etat = " << etat);
2069   // A.1.2. L'iteration doit Ãªtre calculee
2070   if (etat == 1) {
2071     SALOME::ExceptionStruct es;
2072     es.type = SALOME::BAD_PARAM;
2073     es.text = "This iteration is not computed.";
2074     throw SALOME::SALOME_Exception(es);
2075     return 1;
2076   }
2077   // A.2. Numero de l'iteration
2078   //     siterp1 : numero de l'iteration a traiter
2079   int NumeIter = myIteration->GetNumber();
2080   std::string siterp1;
2081   std::stringstream saux1;
2082   saux1 << NumeIter;
2083   siterp1 = saux1.str();
2084   if (NumeIter < 10) { siterp1 = "0" + siterp1; }
2085   MESSAGE ("siterp1 = "<<siterp1);
2086
2087   // A.3. Le cas
2088   ASSERT(!CORBA::is_nil(myCase));
2089
2090   // A.4. Le sous-répertoire de l'iteration a traiter
2091   char* DirCompute = myIteration->GetDirName();
2092   MESSAGE(". DirCompute = " << DirCompute);
2093
2094   // C. Le fichier des messages
2095   std::string LogFile = DirCompute;
2096   LogFile += "/Liste." + siterp1 + ".maj_coords.log";
2097   MESSAGE (". LogFile = " << LogFile);
2098   myIteration->SetFileInfo(LogFile.c_str());
2099
2100   // D. On passe dans le répertoire de l'iteration a calculer
2101   MESSAGE (". On passe dans DirCompute = " << DirCompute);
2102   CHDIR(DirCompute);
2103
2104   // E. Les données de l'exécution HOMARD
2105   // E.1. L'objet du texte du fichier de configuration
2106   SMESHHOMARDImpl::HomardDriver* myDriver = new SMESHHOMARDImpl::HomardDriver("", siterp1);
2107   myDriver->TexteInit(DirCompute, LogFile, "English");
2108
2109   // E.2. Le maillage associe a l'iteration
2110   const char* NomMesh = myIteration->GetMeshName();
2111   MESSAGE (". NomMesh = " << NomMesh);
2112   const char* MeshFile = myIteration->GetMeshFile();
2113   MESSAGE (". MeshFile = " << MeshFile);
2114
2115   // E.3. Les données du traitement HOMARD
2116   myDriver->TexteMajCoords(NumeIter);
2117   int iaux = 0;
2118   myDriver->TexteMaillageHOMARD(DirCompute, siterp1, iaux);
2119   myDriver->TexteMaillage(NomMesh, MeshFile, 0);
2120   //
2121   // E.4. Ecriture du texte dans le fichier
2122   MESSAGE (". Ecriture du texte dans le fichier de configuration; codret = "<<codret);
2123   if (codret == 0) myDriver->CreeFichier();
2124
2125   // F. Execution
2126   //
2127   int codretexec = 1789;
2128   if (codret == 0) {
2129     codretexec = myDriver->ExecuteHomard();
2130     MESSAGE ("Erreur en executant HOMARD : " << codretexec);
2131   }
2132
2133   // G. Gestion des resultats
2134   if (codret == 0) {
2135     // G.1. Le fichier des messages, dans tous les cas
2136     std::string Commentaire = "logmaj_coords";
2137     // G.2 Message d'erreur
2138     if (codretexec != 0) {
2139       std::string text = "\n\nSee the file " + LogFile + "\n";
2140       INFOS (text);
2141       SALOME::ExceptionStruct es;
2142       es.type = SALOME::BAD_PARAM;
2143       es.text = CORBA::string_dup(text.c_str());
2144       throw SALOME::SALOME_Exception(es);
2145
2146       // On force le succes pour pouvoir consulter le fichier log
2147       codretexec = 0;
2148     }
2149   }
2150
2151   // H. Menage et retour dans le répertoire du cas
2152   if (codret == 0) { delete myDriver; }
2153
2154   return codret;
2155 }
2156 //=============================================================================
2157 // Creation d'un nom de sous-répertoire pour l'iteration au sein d'un répertoire parent
2158 //  nomrep : nom du répertoire parent
2159 //  num : le nom du sous-répertoire est sous la forme 'In', n est >= num
2160 //=============================================================================
2161 char* HOMARD_Gen_i::CreateDirNameIter(const char* nomrep, CORBA::Long num)
2162 {
2163   MESSAGE ("CreateDirNameIter : nomrep ="<< nomrep << ", num = "<<num);
2164   // On verifie que le répertoire parent existe
2165   int codret = CHDIR(nomrep);
2166   if (codret != 0) {
2167     SALOME::ExceptionStruct es;
2168     es.type = SALOME::BAD_PARAM;
2169     es.text = "The directory of the case does not exist.";
2170     throw SALOME::SALOME_Exception(es);
2171   }
2172   std::string nomDirActuel = getenv("PWD");
2173   std::string DirName;
2174   // On boucle sur tous les noms possibles jusqu'a trouver un nom correspondant a un répertoire inconnu
2175   bool a_chercher = true;
2176   while (a_chercher) {
2177     // On passe dans le répertoire parent
2178
2179     CHDIR(nomrep);
2180     // On recherche un nom sous la forme Iabc, avec abc representant le numero
2181     int jaux;
2182     if      (num <    100) { jaux = 2; }
2183     else if (num <   1000) { jaux = 3; }
2184     else if (num <  10000) { jaux = 4; }
2185     else if (num < 100000) { jaux = 5; }
2186     else                     { jaux = 9; }
2187     std::ostringstream iaux;
2188     iaux << std::setw(jaux) << std::setfill('0') << num;
2189     std::ostringstream DirNameA;
2190     DirNameA << "I" << iaux.str();
2191     // Si on ne pas peut entrer dans le répertoire, on doit verifier
2192     // que c'est bien un probleme d'absence
2193     if (CHDIR(DirNameA.str().c_str()) != 0)
2194     {
2195       bool existe = false;
2196 #ifndef WIN32
2197       DIR *dp;
2198       struct dirent *dirp;
2199       dp  = opendir(nomrep);
2200       while ((dirp = readdir(dp)) != NULL)
2201       {
2202         std::string file_name(dirp->d_name);
2203 #else
2204       HANDLE hFind = INVALID_HANDLE_VALUE;
2205       WIN32_FIND_DATA ffd;
2206       hFind = FindFirstFile(nomrep, &ffd);
2207       if (INVALID_HANDLE_VALUE != hFind) {
2208         while (FindNextFile(hFind, &ffd) != 0) {
2209          if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; //skip directories
2210          std::string file_name(ffd.cFileName);
2211 #endif
2212         if (file_name == DirNameA.str()) { existe = true; }
2213       }
2214 #ifndef WIN32
2215       closedir(dp);
2216 #else
2217       FindClose(hFind);
2218 #endif
2219       if (!existe)
2220       {
2221         DirName = DirNameA.str();
2222         a_chercher = false;
2223         break;
2224       }
2225     }
2226     num += 1;
2227   }
2228
2229   MESSAGE ("==> DirName = " << DirName);
2230   MESSAGE (". On retourne dans nomDirActuel = " << nomDirActuel);
2231   CHDIR(nomDirActuel.c_str());
2232   return CORBA::string_dup(DirName.c_str());
2233 }
2234 //=============================================================================
2235 // Calcul d'une iteration : gestion du répertoire de calcul
2236 //=============================================================================
2237 char* HOMARD_Gen_i::ComputeDirManagement(SMESHHOMARD::HOMARD_Cas_var myCase,
2238                                          SMESHHOMARD::HOMARD_Iteration_var myIteration)
2239 {
2240   MESSAGE ("ComputeDirManagement : répertoires pour le calcul");
2241
2242   //Si le sous-répertoire existe :
2243   //  CleanOption =  0 : on sort en erreur si le répertoire n'est pas vide
2244   //  CleanOption =  1 : on fait le menage du répertoire
2245   //  CleanOption = -1 : on ne fait rien
2246   int CleanOption = 0;
2247
2248   // B.2. Le répertoire du cas
2249   const char* nomDirCase = myCase->GetDirName();
2250   MESSAGE (". nomDirCase = " << nomDirCase);
2251
2252   // B.3. Le sous-répertoire de l'iteration a calculer, puis le répertoire complet a creer
2253   // B.3.1. Le nom du sous-répertoire
2254   const char* nomDirIt = myIteration->GetDirNameLoc();
2255
2256   // B.3.2. Le nom complet du sous-répertoire
2257   std::stringstream DirCompute;
2258   DirCompute << nomDirCase << "/" << nomDirIt;
2259   MESSAGE (". DirCompute = " << DirCompute.str());
2260
2261   // B.3.3. Si le sous-répertoire n'existe pas, on le cree
2262   if (CHDIR(DirCompute.str().c_str()) != 0)
2263   {
2264 #ifndef WIN32
2265     if (mkdir(DirCompute.str().c_str(), S_IRWXU|S_IRGRP|S_IXGRP) != 0)
2266 #else
2267     if (_mkdir(DirCompute.str().c_str()) != 0)
2268 #endif
2269     {
2270        // GERALD -- QMESSAGE BOX
2271        std::cerr << "Pb Creation du répertoire DirCompute = " << DirCompute.str() << std::endl;
2272        VERIFICATION("Pb a la creation du répertoire" == 0);
2273     }
2274   }
2275   else
2276   {
2277     //  Le répertoire existe
2278     //  On demande de faire le menage de son contenu :
2279     if (CleanOption == 1) {
2280       MESSAGE (". Menage du répertoire DirCompute = " << DirCompute.str());
2281       std::string commande = "rm -rf " + DirCompute.str()+"/*";
2282       int codret = system(commande.c_str());
2283       if (codret != 0)
2284       {
2285         // GERALD -- QMESSAGE BOX
2286         std::cerr << ". Menage du répertoire de calcul" << DirCompute.str() << std::endl;
2287         VERIFICATION("Pb au menage du répertoire de calcul" == 0);
2288       }
2289     }
2290     //  On n'a pas demande de faire le menage de son contenu : on sort en erreur :
2291     else {
2292       if (CleanOption == 0) {
2293 #ifndef WIN32
2294         DIR *dp;
2295         struct dirent *dirp;
2296         dp  = opendir(DirCompute.str().c_str());
2297         bool result = true;
2298         while ((dirp = readdir(dp)) != NULL && result)
2299         {
2300           std::string file_name(dirp->d_name);
2301           result = file_name.empty() || file_name == "." || file_name == ".."; //if any file - break and return false
2302         }
2303         closedir(dp);
2304 #else
2305        HANDLE hFind = INVALID_HANDLE_VALUE;
2306        WIN32_FIND_DATA ffd;
2307        hFind = FindFirstFile(DirCompute.str().c_str(), &ffd);
2308        bool result = true;
2309        if (INVALID_HANDLE_VALUE != hFind) {
2310          while (FindNextFile(hFind, &ffd) != 0) {
2311           if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; //skip directories
2312           std::string file_name(ffd.cFileName);
2313           result = file_name.empty() || file_name == "." || file_name == ".."; //if any file - break and return false
2314          }
2315        }
2316        FindClose(hFind);
2317 #endif
2318         if (result == false)
2319         {
2320           SALOME::ExceptionStruct es;
2321           es.type = SALOME::BAD_PARAM;
2322           std::string text = "Directory : " + DirCompute.str() + " is not empty";
2323           es.text = CORBA::string_dup(text.c_str());
2324           throw SALOME::SALOME_Exception(es);
2325           VERIFICATION("Directory is not empty" == 0);
2326         }
2327       }
2328     }
2329   }
2330
2331   return CORBA::string_dup(DirCompute.str().c_str());
2332 }
2333 //=============================================================================
2334 // Calcul d'une iteration : gestion du répertoire de calcul de l'iteration parent
2335 //=============================================================================
2336 char* HOMARD_Gen_i::ComputeDirPaManagement(SMESHHOMARD::HOMARD_Cas_var myCase, SMESHHOMARD::HOMARD_Iteration_var myIteration)
2337 {
2338   MESSAGE ("ComputeDirPaManagement : répertoires pour le calcul");
2339   // Le répertoire du cas
2340   const char* nomDirCase = myCase->GetDirName();
2341   MESSAGE (". nomDirCase = " << nomDirCase);
2342
2343   // Le sous-répertoire de l'iteration precedente
2344
2345   SMESHHOMARD::HOMARD_Iteration_var myIterationParent = myIteration0;
2346   const char* nomDirItPa = myIterationParent->GetDirNameLoc();
2347   std::stringstream DirComputePa;
2348   DirComputePa << nomDirCase << "/" << nomDirItPa;
2349   MESSAGE(". nomDirItPa = " << nomDirItPa);
2350   MESSAGE(". DirComputePa = " << DirComputePa.str());
2351
2352   return CORBA::string_dup(DirComputePa.str().c_str());
2353 }
2354
2355 //=============================================================================
2356 // Calcul d'une iteration : ecriture des frontieres dans le fichier de configuration
2357 // On ecrit dans l'ordre :
2358 //    1. la definition des frontieres
2359 //    2. les liens avec les groupes
2360 //    3. un entier resumant le type de comportement pour les frontieres
2361 //=============================================================================
2362 int HOMARD_Gen_i::DriverTexteBoundary(SMESHHOMARD::HOMARD_Cas_var myCase, SMESHHOMARDImpl::HomardDriver* myDriver)
2363 {
2364   MESSAGE ("... DriverTexteBoundary");
2365   // 1. Recuperation des frontieres
2366   std::list<std::string>  ListeBoundaryTraitees;
2367   SMESHHOMARD::ListBoundaryGroupType* ListBoundaryGroupType = myCase->GetBoundaryGroup();
2368   int numberOfitems = ListBoundaryGroupType->length();
2369   MESSAGE ("... number of string for Boundary+Group = " << numberOfitems);
2370   int BoundaryOption = 1;
2371   // 2. Parcours des frontieres pour ecrire leur description
2372   int NumBoundaryAnalytical = 0;
2373   for (int NumBoundary = 0; NumBoundary< numberOfitems; NumBoundary=NumBoundary+2)
2374   {
2375     std::string BoundaryName = std::string((*ListBoundaryGroupType)[NumBoundary]);
2376     MESSAGE ("... BoundaryName = " << BoundaryName);
2377     // 2.1. La frontiere a-t-elle deja ete ecrite ?
2378     //      Cela arrive quand elle est liee a plusieurs groupes. Il ne faut l'ecrire que la premiere fois
2379     int A_faire = 1;
2380     std::list<std::string>::const_iterator it = ListeBoundaryTraitees.begin();
2381     while (it != ListeBoundaryTraitees.end())
2382     {
2383       MESSAGE ("..... BoundaryNameTraitee = " << *it);
2384       if (BoundaryName == *it) { A_faire = 0; }
2385       it++;
2386     }
2387     // 2.2. Ecriture de la frontiere
2388     if (A_faire == 1)
2389     {
2390       // 2.2.1. Caracteristiques de la frontiere
2391       SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
2392       ASSERT(!CORBA::is_nil(myBoundary));
2393       int BoundaryType = myBoundary->GetType();
2394       MESSAGE ("... BoundaryType = " << BoundaryType);
2395       // 2.2.2. Ecriture selon le type
2396       // 2.2.2.1. Cas d une frontiere CAO
2397       if (BoundaryType == -1)
2398       {
2399 //         const char* CAOFile = myBoundary->GetDataFile();
2400 //         MESSAGE (". CAOFile = " << CAOFile);
2401         if (BoundaryOption % 5 != 0) { BoundaryOption = BoundaryOption*5; }
2402       }
2403       // 2.2.2.2. Cas d une frontiere discrete
2404       else if (BoundaryType == 0)
2405       {
2406         const char* MeshName = myBoundary->GetMeshName();
2407         MESSAGE (". MeshName = " << MeshName);
2408         const char* MeshFile = myBoundary->GetDataFile();
2409         MESSAGE (". MeshFile = " << MeshFile);
2410         myDriver->TexteBoundaryDi(MeshName, MeshFile);
2411         if (BoundaryOption % 2 != 0) { BoundaryOption = BoundaryOption*2; }
2412       }
2413       // 2.2.2.3. Cas d une frontiere analytique
2414       else
2415       {
2416         NumBoundaryAnalytical++;
2417         SMESHHOMARD::double_array* coor = myBoundary->GetCoords();
2418         if (BoundaryType == 1) // Cas d un cylindre
2419         {
2420           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], 0.);
2421           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2422         }
2423         else if (BoundaryType == 2) // Cas d une sphere
2424         {
2425           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], 0., 0., 0., 0.);
2426           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2427         }
2428         else if (BoundaryType == 3) // Cas d un cone defini par un axe et un angle
2429         {
2430           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], 0.);
2431           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2432         }
2433         else if (BoundaryType == 4) // Cas d un cone defini par les 2 rayons
2434         {
2435           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], (*coor)[7]);
2436           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2437         }
2438         else if (BoundaryType == 5) // Cas d un tore
2439         {
2440           myDriver->TexteBoundaryAn(BoundaryName, NumBoundaryAnalytical, BoundaryType, (*coor)[0], (*coor)[1], (*coor)[2], (*coor)[3], (*coor)[4], (*coor)[5], (*coor)[6], (*coor)[7]);
2441           if (BoundaryOption % 3 != 0) { BoundaryOption = BoundaryOption*3; }
2442         }
2443       }
2444       // 2.2.3. Memorisation du traitement
2445       ListeBoundaryTraitees.push_back(BoundaryName);
2446     }
2447   }
2448   // 3. Parcours des frontieres pour ecrire les liens avec les groupes
2449   NumBoundaryAnalytical = 0;
2450   for (int NumBoundary = 0; NumBoundary< numberOfitems; NumBoundary=NumBoundary+2)
2451   {
2452     std::string BoundaryName = std::string((*ListBoundaryGroupType)[NumBoundary]);
2453     MESSAGE ("... BoundaryName = " << BoundaryName);
2454     SMESHHOMARD::HOMARD_Boundary_var myBoundary = _mesBoundarys[BoundaryName];
2455     ASSERT(!CORBA::is_nil(myBoundary));
2456     int BoundaryType = myBoundary->GetType();
2457     MESSAGE ("... BoundaryType = " << BoundaryType);
2458     // 3.1. Recuperation du nom du groupe
2459     std::string GroupName = std::string((*ListBoundaryGroupType)[NumBoundary+1]);
2460     MESSAGE ("... GroupName = " << GroupName);
2461     // 3.2. Cas d une frontiere CAO
2462     if (BoundaryType == -1)
2463     {
2464       if (GroupName.size() > 0) { myDriver->TexteBoundaryCAOGr (GroupName); }
2465     }
2466     // 3.3. Cas d une frontiere discrete
2467     else if (BoundaryType == 0)
2468     {
2469       if (GroupName.size() > 0) { myDriver->TexteBoundaryDiGr (GroupName); }
2470     }
2471     // 3.4. Cas d une frontiere analytique
2472     else
2473     {
2474       NumBoundaryAnalytical++;
2475       myDriver->TexteBoundaryAnGr (BoundaryName, NumBoundaryAnalytical, GroupName);
2476     }
2477   }
2478   // 4. Ecriture de l'option finale
2479   myDriver->TexteBoundaryOption(BoundaryOption);
2480 //
2481   return BoundaryOption;
2482 }
2483 //===========================================================================
2484 //===========================================================================
2485
2486 //===========================================================================
2487 // Publications
2488 // Option = 0 : fichier issu d'une importation
2489 // Option = 1 : fichier issu d'une execution HOMARD
2490 //===========================================================================
2491 void HOMARD_Gen_i::PublishResultInSmesh(const char* NomFich, CORBA::Long Option)
2492 {
2493   // Prevent dump of CreateMeshesFromMED
2494   SMESH::TPythonDump pDump; // do not delete this line of code
2495
2496   MESSAGE("PublishResultInSmesh " << NomFich << ", avec Option = " << Option);
2497   if (CORBA::is_nil(SMESH_Gen_i::GetSMESHGen()->getStudyServant())) {
2498     SALOME::ExceptionStruct es;
2499     es.type = SALOME::BAD_PARAM;
2500     es.text = "Invalid study context";
2501     throw SALOME::SALOME_Exception(es);
2502   }
2503
2504   // Le module SMESH est-il actif ?
2505   SALOMEDS::SObject_var aSmeshSO =
2506     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindComponent("SMESH");
2507   //
2508   if (!CORBA::is_nil(aSmeshSO)) {
2509     // On verifie que le fichier n est pas deja publie
2510     SALOMEDS::ChildIterator_var aIter =
2511       SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewChildIterator(aSmeshSO);
2512     for (; aIter->More(); aIter->Next()) {
2513       SALOMEDS::SObject_var aSO = aIter->Value();
2514       SALOMEDS::GenericAttribute_var aGAttr;
2515       if (aSO->FindAttribute(aGAttr, "AttributeExternalFileDef")) {
2516         SALOMEDS::AttributeExternalFileDef_var anAttr =
2517           SALOMEDS::AttributeExternalFileDef::_narrow(aGAttr);
2518         CORBA::String_var value = anAttr->Value();
2519         if (strcmp((const char*)value, NomFich) == 0) {
2520           MESSAGE ("PublishResultInSmesh : le fichier " << NomFich << " est deja publie.");
2521           // Pour un fichier importe, on ne republie pas
2522           if (Option == 0) { return; }
2523           // Pour un fichier calcule, on commence par faire la depublication
2524           else {
2525             MESSAGE("PublishResultInSmesh : depublication");
2526             if (aSO->FindAttribute(aGAttr, "AttributeName")) {
2527               SALOMEDS::AttributeName_var anAttr2 = SALOMEDS::AttributeName::_narrow(aGAttr);
2528               CORBA::String_var value2 = anAttr2->Value();
2529               std::string MeshName = string(value2);
2530               MESSAGE("PublishResultInSmesh : depublication de " << MeshName);
2531               DeleteResultInSmesh(NomFich, MeshName);
2532             }
2533           }
2534         }
2535       }
2536     }
2537   }
2538
2539   // On enregistre le fichier
2540   MESSAGE("Enregistrement du fichier");
2541   //
2542   //SMESH::SMESH_Gen_var aSmeshEngine = this->retrieveSMESHInst();
2543   SMESH_Gen_i* aSmeshEngine = SMESH_Gen_i::GetSMESHGen();
2544   //
2545   //ASSERT(!CORBA::is_nil(aSmeshEngine));
2546   aSmeshEngine->UpdateStudy();
2547   SMESH::DriverMED_ReadStatus theStatus;
2548
2549   // On met a jour les attributs AttributeExternalFileDef et AttributePixMap
2550   SMESH::mesh_array* mesMaillages = aSmeshEngine->CreateMeshesFromMED(NomFich, theStatus);
2551   for (int i = 0; i < (int)mesMaillages->length(); i++) {
2552     MESSAGE(". Mise a jour des attributs du maillage");
2553     SMESH::SMESH_Mesh_var monMaillage = (*mesMaillages)[i];
2554     SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow
2555       (SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectIOR
2556        (SMESH_Gen_i::GetORB()->object_to_string(monMaillage)));
2557     SALOMEDS::StudyBuilder_var aStudyBuilder =
2558       SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewBuilder();
2559     SALOMEDS::GenericAttribute_var aGAttr =
2560       aStudyBuilder->FindOrCreateAttribute(aSO, "AttributeExternalFileDef");
2561     SALOMEDS::AttributeExternalFileDef_var anAttr =
2562       SALOMEDS::AttributeExternalFileDef::_narrow(aGAttr);
2563     anAttr->SetValue(NomFich);
2564     SALOMEDS::GenericAttribute_var aPixMap =
2565       aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePixMap");
2566     SALOMEDS::AttributePixMap_var anAttr2 = SALOMEDS::AttributePixMap::_narrow(aPixMap);
2567     const char* icone;
2568     if (Option == 0) { icone = "mesh_tree_importedmesh.png"; }
2569     else               { icone = "mesh_tree_mesh.png"; }
2570     anAttr2->SetPixMap(icone);
2571   }
2572 }
2573
2574 //=============================================================================
2575 void HOMARD_Gen_i::DeleteResultInSmesh(std::string NomFich, std::string MeshName)
2576 {
2577   MESSAGE ("DeleteResultInSmesh pour le maillage " << MeshName << " dans le fichier " << NomFich);
2578   if (CORBA::is_nil(SMESH_Gen_i::GetSMESHGen()->getStudyServant())) {
2579     SALOME::ExceptionStruct es;
2580     es.type = SALOME::BAD_PARAM;
2581     es.text = "Invalid study context";
2582     throw SALOME::SALOME_Exception(es);
2583   }
2584
2585   // Le module SMESH est-il actif ?
2586   SALOMEDS::SObject_var aSmeshSO =
2587     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindComponent("SMESH");
2588   //
2589   if (CORBA::is_nil(aSmeshSO)) return;
2590   // On verifie que le fichier est deja publie
2591   SALOMEDS::StudyBuilder_var myBuilder =
2592     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewBuilder();
2593   SALOMEDS::ChildIterator_var aIter =
2594     SMESH_Gen_i::GetSMESHGen()->getStudyServant()->NewChildIterator(aSmeshSO);
2595   for (; aIter->More(); aIter->Next()) {
2596     SALOMEDS::SObject_var  aSO = aIter->Value();
2597     SALOMEDS::GenericAttribute_var aGAttr;
2598     if (aSO->FindAttribute(aGAttr, "AttributeExternalFileDef")) {
2599       SALOMEDS::AttributeExternalFileDef_var anAttr =
2600         SALOMEDS::AttributeExternalFileDef::_narrow(aGAttr);
2601       CORBA::String_var value = anAttr->Value();
2602       if (strcmp((const char*)value, NomFich.c_str()) == 0) {
2603         if (aSO->FindAttribute(aGAttr, "AttributeName")) {
2604           SALOMEDS::AttributeName_var anAttr2 = SALOMEDS::AttributeName::_narrow(aGAttr);
2605           CORBA::String_var value2 = anAttr2->Value();
2606           if (strcmp((const char*)value2, MeshName.c_str()) == 0) {
2607             myBuilder->RemoveObjectWithChildren(aSO);
2608           }
2609         }
2610       }
2611     }
2612   }
2613 }
2614
2615 void HOMARD_Gen_i::PythonDump()
2616 {
2617   MESSAGE ("Begin PythonDump");
2618   SMESH::TPythonDump pd;
2619
2620   // SMESH_Homard
2621   pd << "import SMESHHOMARD\n";
2622   pd << "smeshhomard = " << SMESH_Gen_i::GetSMESHGen() << ".CreateHOMARD_ADAPT()\n";
2623
2624   // Boundaries
2625   if (_mesBoundarys.size() > 0) MESSAGE(". Creation of the boundaries");
2626   std::map<std::string, SMESHHOMARD::HOMARD_Boundary_var>::const_iterator it_boundary;
2627   for (it_boundary  = _mesBoundarys.begin();
2628        it_boundary != _mesBoundarys.end(); ++it_boundary) {
2629     SMESHHOMARD::HOMARD_Boundary_var maBoundary = (*it_boundary).second;
2630     pd << maBoundary->GetDumpPython();
2631   }
2632
2633   // Case
2634   ASSERT(!myCase->_is_nil());
2635   MESSAGE (". Creation of the case");
2636
2637   if (_CaseOnMedFile) {
2638     pd << "Case_1 = smeshhomard.CreateCase(\"" << myIteration0->GetMeshName();
2639     pd << "\", \"" << myIteration0->GetMeshFile();
2640     pd << "\", \"" << myCase->GetDirName() << "\")\n";
2641   }
2642   else {
2643     pd << "Case_1 = smeshhomard.CreateCaseOnMesh(\"" << myIteration0->GetMeshName();
2644     pd << "\", " << _SmeshMesh;
2645     pd << ", \"" << myCase->GetDirName() << "\")\n";
2646   }
2647
2648   pd << myCase->GetDumpPython();
2649
2650   // Preferences
2651   pd << "smeshhomard.SetKeepMedOUT(" << _KeepMedOUT << ")\n";
2652   pd << "smeshhomard.SetPublishMeshOUT(" << _PublishMeshOUT << ")\n";
2653   pd << "smeshhomard.SetMeshNameOUT(\"" << _MeshNameOUT << "\")\n";
2654   pd << "smeshhomard.SetMeshFileOUT(\"" << _MeshFileOUT << "\")\n";
2655
2656   pd << "smeshhomard.SetKeepWorkingFiles(" << _KeepWorkingFiles << ")\n";
2657   pd << "smeshhomard.SetLogInFile(" << _LogInFile << ")\n";
2658   if (_LogInFile) pd << "smeshhomard.SetLogFile(\"" << _LogFile << "\")\n";
2659   pd << "smeshhomard.SetRemoveLogOnSuccess(" << _RemoveLogOnSuccess << ")\n";
2660   pd << "smeshhomard.SetVerboseLevel(" << _VerboseLevel << ")\n";
2661
2662   // Compute
2663   pd << "smeshhomard.Compute()\n";
2664   MESSAGE ("End PythonDump");
2665 }
2666
2667 //===============================================================================
2668 // Preferences
2669 //===============================================================================
2670 void HOMARD_Gen_i::SetKeepMedOUT(bool theKeepMedOUT)
2671 {
2672   _KeepMedOUT = theKeepMedOUT;
2673 }
2674 void HOMARD_Gen_i::SetPublishMeshOUT(bool thePublishMeshOUT)
2675 {
2676   _PublishMeshOUT = thePublishMeshOUT;
2677 }
2678 void HOMARD_Gen_i::SetKeepWorkingFiles(bool theKeepWorkingFiles)
2679 {
2680   _KeepWorkingFiles = theKeepWorkingFiles;
2681 }
2682 void HOMARD_Gen_i::SetLogInFile(bool theLogInFile)
2683 {
2684   _LogInFile = theLogInFile;
2685 }
2686 void HOMARD_Gen_i::SetRemoveLogOnSuccess(bool theRemoveLogOnSuccess)
2687 {
2688   _RemoveLogOnSuccess = theRemoveLogOnSuccess;
2689 }
2690 void HOMARD_Gen_i::SetVerboseLevel(CORBA::Long theVerboseLevel)
2691 {
2692   _VerboseLevel = theVerboseLevel;
2693 }
2694 void HOMARD_Gen_i::SetMeshNameOUT(const char* theMeshNameOUT)
2695 {
2696   _MeshNameOUT = theMeshNameOUT;
2697 }
2698 void HOMARD_Gen_i::SetMeshFileOUT(const char* theMeshFileOUT)
2699 {
2700   _MeshFileOUT = theMeshFileOUT;
2701 }
2702 void HOMARD_Gen_i::SetLogFile(const char* theLogFile)
2703 {
2704   _LogFile = theLogFile;
2705 }
2706
2707 // =======================================================================
2708 std::set<std::string> GetListeGroupesInMedFile(const char * aFile)
2709 {
2710   std::set<std::string> ListeGroupes;
2711   med_err erreur = 0;
2712   med_idt medIdt;
2713   while (erreur == 0) {
2714     //  Ouverture du fichier
2715     medIdt = MEDfileOpen(aFile,MED_ACC_RDONLY);
2716     if (medIdt < 0) {
2717       erreur = 1;
2718       break;
2719     }
2720     // Caracteristiques du maillage
2721     char meshname[MED_NAME_SIZE+1];
2722     med_int spacedim,meshdim;
2723     med_mesh_type meshtype;
2724     char descriptionription[MED_COMMENT_SIZE+1];
2725     char dtunit[MED_SNAME_SIZE+1];
2726     med_sorting_type sortingtype;
2727     med_int nstep;
2728     med_axis_type axistype;
2729     int naxis = MEDmeshnAxis(medIdt,1);
2730     char *axisname=new char[naxis*MED_SNAME_SIZE+1];
2731     char *axisunit=new char[naxis*MED_SNAME_SIZE+1];
2732     erreur = MEDmeshInfo(medIdt,
2733                             1,
2734                             meshname,
2735                             &spacedim,
2736                             &meshdim,
2737                             &meshtype,
2738                             descriptionription,
2739                             dtunit,
2740                             &sortingtype,
2741                             &nstep,
2742                             &axistype,
2743                             axisname,
2744                             axisunit);
2745     delete[] axisname;
2746     delete[] axisunit;
2747     if (erreur < 0) { break; }
2748     // Nombre de familles
2749     med_int nfam;
2750     nfam = MEDnFamily(medIdt,meshname);
2751     if (nfam < 0) {
2752       erreur = 2;
2753       break;
2754     }
2755     // Lecture des caracteristiques des familles
2756     for (int i=0;i<nfam;i++) {
2757       // Lecture du nombre de groupes
2758       med_int ngro = MEDnFamilyGroup(medIdt,meshname,i+1);
2759       if (ngro < 0) {
2760         erreur = 3;
2761         break;
2762       }
2763       // Lecture de la famille
2764       else if (ngro > 0) {
2765         char familyname[MED_NAME_SIZE+1];
2766         med_int numfam;
2767         char* gro = (char*) malloc(MED_LNAME_SIZE*ngro+1);
2768         erreur = MEDfamilyInfo(medIdt,
2769                                meshname,
2770                                i+1,
2771                                familyname,
2772                                &numfam,
2773                                gro);
2774         if (erreur < 0) {
2775           free(gro);
2776           break;
2777         }
2778         // Lecture des groupes pour une famille de mailles
2779         if (numfam < 0) {
2780           for (int j=0;j<ngro;j++) {
2781             char str2[MED_LNAME_SIZE+1];
2782             strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
2783             str2[MED_LNAME_SIZE] = '\0';
2784             ListeGroupes.insert(std::string(str2));
2785           }
2786         }
2787         free(gro);
2788       }
2789     }
2790     break;
2791   }
2792   // Fermeture du fichier
2793   if (medIdt > 0) MEDfileClose(medIdt);
2794
2795   return ListeGroupes;
2796 }
2797
2798 // =======================================================================
2799 // Le vecteur en retour contiendra les informations suivantes :
2800 // en position 0 et 1 Xmin, Xmax et en position 2 Dx si < 0  2D
2801 // en position 3 et 4 Ymin, Ymax et en position 5 Dy si < 0  2D
2802 // en position 6 et 7 Zmin, Zmax et en position 8 Dz si < 0  2D
2803 //  9 distance max dans le maillage
2804 // =======================================================================
2805 std::vector<double> GetBoundingBoxInMedFile(const char * aFile)
2806 {
2807   std::vector<double> LesExtremes;
2808   med_err erreur = 0;
2809   med_idt medIdt;
2810   while (erreur == 0) {
2811     //  Ouverture du fichier
2812     medIdt = MEDfileOpen(aFile,MED_ACC_RDONLY);
2813     if (medIdt < 0) {
2814       erreur = 1;
2815       break;
2816     }
2817     //Nombre de maillage : on ne peut en lire qu'un seul
2818     med_int numberOfMeshes = MEDnMesh(medIdt);
2819     if (numberOfMeshes != 1) {
2820       erreur = 2;
2821       break;
2822     }
2823     // Caracteristiques du maillage
2824     char meshname[MED_NAME_SIZE+1];
2825     med_int spacedim,meshdim;
2826     med_mesh_type meshtype;
2827     char descriptionription[MED_COMMENT_SIZE+1];
2828     char dtunit[MED_SNAME_SIZE+1];
2829     med_sorting_type sortingtype;
2830     med_int nstep;
2831     med_axis_type axistype;
2832     int naxis = MEDmeshnAxis(medIdt,1);
2833     char *axisname=new char[naxis*MED_SNAME_SIZE+1];
2834     char *axisunit=new char[naxis*MED_SNAME_SIZE+1];
2835     erreur = MEDmeshInfo(medIdt,
2836                             1,
2837                             meshname,
2838                             &spacedim,
2839                             &meshdim,
2840                             &meshtype,
2841                             descriptionription,
2842                             dtunit,
2843                             &sortingtype,
2844                             &nstep,
2845                             &axistype,
2846                             axisname,
2847                             axisunit);
2848     delete[] axisname;
2849     delete[] axisunit;
2850     if (erreur < 0) { break; }
2851
2852     // Nombre de noeuds
2853     med_bool chgt,trsf;
2854     med_int nnoe  = MEDmeshnEntity(medIdt,
2855                               meshname,
2856                               MED_NO_DT,
2857                               MED_NO_IT,
2858                               MED_NODE,
2859                               MED_NO_GEOTYPE,
2860                               MED_COORDINATE,
2861                               MED_NO_CMODE,
2862                               &chgt,
2863                               &trsf);
2864     if (nnoe < 0) {
2865       erreur =  4;
2866       break;
2867     }
2868
2869     // Les coordonnees
2870     med_float* coo = (med_float*) malloc(sizeof(med_float)*nnoe*spacedim);
2871
2872     erreur = MEDmeshNodeCoordinateRd(medIdt,
2873                                       meshname,
2874                                       MED_NO_DT,
2875                                       MED_NO_IT,
2876                                       MED_NO_INTERLACE,
2877                                       coo);
2878     if (erreur < 0) {
2879       free(coo);
2880       break;
2881     }
2882
2883     // Calcul des extremes
2884     med_float xmin,xmax,ymin,ymax,zmin,zmax;
2885
2886     xmin = coo[0];
2887     xmax = coo[0];
2888     for (int i = 1; i < nnoe; i++) {
2889       xmin = std::min(xmin, coo[i]);
2890       xmax = std::max(xmax, coo[i]);
2891     }
2892     //
2893     if (spacedim > 1) {
2894       ymin = coo[nnoe];
2895       ymax = coo[nnoe];
2896       for (int i = nnoe + 1; i < 2*nnoe; i++) {
2897         ymin = std::min(ymin,coo[i]);
2898         ymax = std::max(ymax,coo[i]);
2899       }
2900     }
2901     else {
2902       ymin = 0;
2903       ymax = 0;
2904       zmin = 0;
2905       zmax = 0;
2906     }
2907     //
2908     if (spacedim > 2) {
2909       zmin = coo[2*nnoe];
2910       zmax = coo[2*nnoe];
2911       for (int i = 2*nnoe + 1; i < 3*nnoe; i++) {
2912         zmin = std::min(zmin,coo[i]);
2913         zmax = std::max(zmax,coo[i]);
2914       }
2915     }
2916     else {
2917       zmin = 0;
2918       zmax = 0;
2919     }
2920
2921     MESSAGE("_______________________________________");
2922     MESSAGE("xmin : " << xmin << " xmax : " << xmax);
2923     MESSAGE("ymin : " << ymin << " ymax : " << ymax);
2924     MESSAGE("zmin : " << zmin << " zmax : " << zmax);
2925     MESSAGE("_______________________________________");
2926     double epsilon = 1.e-6;
2927     LesExtremes.push_back(xmin);
2928     LesExtremes.push_back(xmax);
2929     LesExtremes.push_back(0);
2930     LesExtremes.push_back(ymin);
2931     LesExtremes.push_back(ymax);
2932     LesExtremes.push_back(0);
2933     LesExtremes.push_back(zmin);
2934     LesExtremes.push_back(zmax);
2935     LesExtremes.push_back(0);
2936
2937     double max1 = std::max (LesExtremes[1] - LesExtremes[0], LesExtremes[4] - LesExtremes[3]);
2938     double max2 = std::max (max1 , LesExtremes[7] - LesExtremes[6]);
2939     LesExtremes.push_back(max2);
2940
2941     // LesExtremes[0] = Xmini du maillage
2942     // LesExtremes[1] = Xmaxi du maillage
2943     // LesExtremes[2] = increment de progression en X
2944     // LesExtremes[3,4,5] : idem pour Y
2945     // LesExtremes[6,7,8] : idem pour Z
2946     // LesExtremes[9] = ecart maximal entre coordonnees
2947     // On fait un traitement pour dans le cas d'une coordonnee constante
2948     // inhiber ce cas en mettant un increment negatif
2949     //
2950     double diff = LesExtremes[1] - LesExtremes[0];
2951     if (fabs(diff) > epsilon*max2) { LesExtremes[2] = diff/100.; }
2952     else                           { LesExtremes[2] = -1.; }
2953
2954     diff = LesExtremes[4] - LesExtremes[3];
2955     if (fabs(diff) > epsilon*max2) { LesExtremes[5]=diff/100.; }
2956     else                           { LesExtremes[5] = -1.; }
2957
2958     diff = LesExtremes[7] - LesExtremes[6];
2959     if (fabs(diff) > epsilon*max2) { LesExtremes[8]=diff/100.; }
2960     else                           { LesExtremes[8] = -1.;  }
2961
2962     MESSAGE ("_______________________________________");
2963     MESSAGE ("xmin : " << LesExtremes[0] << " xmax : " << LesExtremes[1] << " xincr : " << LesExtremes[2]);
2964     MESSAGE ("ymin : " << LesExtremes[3] << " ymax : " << LesExtremes[4] << " yincr : " << LesExtremes[5]);
2965     MESSAGE ("zmin : " << LesExtremes[6] << " zmax : " << LesExtremes[7] << " zincr : " << LesExtremes[8]);
2966     MESSAGE ("dmax : " << LesExtremes[9]);
2967     MESSAGE ("_______________________________________");
2968
2969     free(coo);
2970     break;
2971   }
2972   // Fermeture du fichier
2973   if (medIdt > 0) MEDfileClose(medIdt);
2974
2975   return  LesExtremes;
2976 }
2977
2978 }; // namespace SMESHHOMARD_I