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