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