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