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