Salome HOME
Fix Compilation issue
[modules/multipr.git] / src / MULTIPR / MULTIPR_i.cxx
1 // Project MULTIPR, IOLS WP1.2.1 - EDF/CS
2 // Partitioning/decimation module for the SALOME v3.2 platform
3
4 /**
5  * \file    MULTIPR_i.cxx
6  *
7  * \brief   see MULTIPR_i.hxx
8  *
9  * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
10  *
11  * \date    01/2007
12  */
13
14
15 //*****************************************************************************
16 // Includes section
17 //*****************************************************************************
18
19 using namespace std;
20
21 #include "MULTIPR_i.hxx"
22 #include "utilities.h"
23
24 #include <string>
25 #include <sstream>
26
27 #include "MULTIPR_API.hxx"
28 #include "MULTIPR_Exceptions.hxx"
29 #include "MULTIPR_Utils.hxx"
30
31 #include <SALOMEDS_Tool.hxx>
32
33 #include CORBA_CLIENT_HEADER(SALOMEDS)
34 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
35
36 #ifdef _DEBUG_
37 static int MYDEBUG = 1;
38 #else
39 static int MYDEBUG = 0;
40 #endif
41
42 // Dump Python utilities
43 namespace MULTIPR
44 {
45   class TPythonDump
46   {
47     std::ostringstream myStream;
48     static size_t myCounter;
49     //MULTIPR_ORB::MULTIPR_Gen_ptr myEngine;
50     MULTIPR_Gen_i* myEngine;
51
52   public:
53     //TPythonDump (MULTIPR_ORB::MULTIPR_Gen_ptr theEngine);
54     TPythonDump (MULTIPR_Gen_i* theEngine);
55     virtual ~TPythonDump();
56
57     TPythonDump& operator<< (long int theArg);
58     TPythonDump& operator<< (int theArg);
59     TPythonDump& operator<< (double theArg);
60     TPythonDump& operator<< (float theArg);
61     TPythonDump& operator<< (const void* theArg);
62     TPythonDump& operator<< (const char* theArg);
63
64     TPythonDump& operator<< (SALOMEDS::SObject_ptr theArg);
65     TPythonDump& operator<< (CORBA::Object_ptr theArg);
66
67     TPythonDump& operator<< (MULTIPR_ORB::MULTIPR_Gen_ptr theArg);
68     TPythonDump& operator<< (MULTIPR_ORB::MULTIPR_Obj_ptr theArg);
69
70     TPythonDump& operator<< (MULTIPR_Gen_i* theArg);
71     TPythonDump& operator<< (MULTIPR_Obj_i* theArg);
72
73     static char* MULTIPRGenName() { return "mpr_gen"; }
74     static char* MULTIPRObjName() { return "mpr_obj"; }
75   };
76
77   size_t TPythonDump::myCounter = 0;
78
79   //TPythonDump::TPythonDump (MULTIPR_ORB::MULTIPR_Gen_ptr theEngine)
80   TPythonDump::TPythonDump (MULTIPR_Gen_i* theEngine)
81   {
82     ++myCounter;
83     //myEngine = MULTIPR_ORB::MULTIPR_Gen::_duplicate(theEngine);
84     myEngine = theEngine;
85   }
86
87   TPythonDump::~TPythonDump()
88   {
89     if (--myCounter == 0)
90     {
91       SALOMEDS::Study_ptr aStudy = myEngine->GetCurrentStudy();
92       int aStudyID = -1;
93       if (!aStudy->_is_nil()) aStudyID = aStudy->StudyId();
94
95       std::string aString = myStream.str();
96       myEngine->AddToPythonScript(aStudyID, aString);
97       //if(MYDEBUG) MESSAGE(" *DP* " << aString.c_str());
98     }
99   }
100
101   TPythonDump& TPythonDump::operator<< (long int theArg)
102   {
103     myStream << theArg;
104     return *this;
105   }
106
107   TPythonDump& TPythonDump::operator<< (int theArg)
108   {
109     myStream << theArg;
110     return *this;
111   }
112
113   TPythonDump& TPythonDump::operator<< (double theArg)
114   {
115     myStream << theArg;
116     return *this;
117   }
118
119   TPythonDump& TPythonDump::operator<< (float theArg)
120   {
121     myStream << theArg;
122     return *this;
123   }
124
125   TPythonDump& TPythonDump::operator<< (const void* theArg)
126   {
127     myStream << theArg;
128     return *this;
129   }
130
131   TPythonDump& TPythonDump::operator<< (const char* theArg)
132   {
133     if (theArg)
134       myStream << theArg;
135     return *this;
136   }
137
138   TPythonDump& TPythonDump::operator<< (SALOMEDS::SObject_ptr aSObject)
139   {
140     if (aSObject->_is_nil())
141       myStream << "None";
142     else
143       myStream << "theStudy.FindObjectID(\"" << aSObject->GetID() << "\")";
144     return *this;
145   }
146
147   TPythonDump& TPythonDump::operator<< (CORBA::Object_ptr theArg)
148   {
149     if (CORBA::is_nil(theArg))
150       myStream << "None";
151     else
152       myStream << theArg;
153     return *this;
154   }
155
156   TPythonDump& TPythonDump::operator<< (MULTIPR_ORB::MULTIPR_Gen_ptr theArg)
157   {
158     myStream << MULTIPRGenName();
159     return *this;
160   }
161
162   TPythonDump& TPythonDump::operator<< (MULTIPR_ORB::MULTIPR_Obj_ptr theArg)
163   {
164     myStream << MULTIPRObjName();
165     return *this;
166   }
167
168   TPythonDump& TPythonDump::operator<< (MULTIPR_Gen_i* theArg)
169   {
170     myStream << MULTIPRGenName();
171     return *this;
172   }
173
174   TPythonDump& TPythonDump::operator<< (MULTIPR_Obj_i* theArg)
175   {
176     myStream << MULTIPRObjName();
177     return *this;
178   }
179 }
180
181 //*****************************************************************************
182 // Class MULTIPR_Gen_i implementation
183 //*****************************************************************************
184
185 MULTIPR_Gen_i::MULTIPR_Gen_i(
186     CORBA::ORB_ptr orb,
187     PortableServer::POA_ptr poa,
188     PortableServer::ObjectId* contId,
189     const char* instanceName,
190     const char* interfaceName) :
191     Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
192 {
193     MESSAGE("activate object");
194     _thisObj = this ;
195     _id = _poa->activate_object(_thisObj);
196 }
197
198
199 MULTIPR_Gen_i::~MULTIPR_Gen_i()
200 {
201 }
202
203
204 //-----------------------------------------------------------------------------
205 // High level API
206 //-----------------------------------------------------------------------------
207
208 char* MULTIPR_Gen_i::getVersion()
209     throw (SALOME::SALOME_Exception)
210 {
211     return CORBA::string_dup(multipr::getVersion());
212 }
213
214
215 void MULTIPR_Gen_i::partitionneDomaine(
216     const char* medFilename,
217     const char* meshName)
218     throw (SALOME::SALOME_Exception)
219 {
220     try
221     {
222         multipr::partitionneDomaine(medFilename, meshName);
223     }
224     catch (multipr::RuntimeException& e)
225     {
226         e.dump(cout);
227         THROW_SALOME_CORBA_EXCEPTION("partitionneDomaine() failed", SALOME::INTERNAL_ERROR);
228     }
229 }
230
231
232 void MULTIPR_Gen_i::partitionneGroupe(
233     const char* medFilename,
234     const char* partName,
235     CORBA::Long nbParts,
236     CORBA::Long partitionner)
237     throw (SALOME::SALOME_Exception)
238 {
239     try
240     {
241         multipr::partitionneGroupe(
242             medFilename,
243             partName,
244             nbParts,
245             partitionner);
246     }
247     catch (multipr::RuntimeException& e)
248     {
249         e.dump(cout);
250         THROW_SALOME_CORBA_EXCEPTION("partitionneGroupe() failed", SALOME::INTERNAL_ERROR);
251     }
252 }
253
254
255 void MULTIPR_Gen_i::decimePartition(
256     const char*   medFilename,
257     const char*   partName,
258     const char*   fieldName,
259     CORBA::Long   fieldIt,
260     const char*   filterName,
261     const char*   filterParams)
262     throw (SALOME::SALOME_Exception)
263 {
264
265     /*
266     // debug
267     cout << "File  : " << medFilename << endl;
268     cout << "Part  : " << partName    << endl;
269     cout << "Field : " << fieldName   << endl;
270     cout << "It    : " << fieldIt     << endl;
271     cout << "Filter: " << filterName  << endl;
272     cout << "Med   : " << tmed        << endl;
273     cout << "Low   : " << tlow        << endl;
274     cout << "Rad   : " << radius      << endl;
275     cout << "Box   : " << boxing      << endl;
276     cout << endl;
277     */
278
279     try
280     {
281         multipr::decimePartition(
282             medFilename,
283             partName,
284             fieldName,
285             fieldIt,
286             filterName,
287             filterParams);
288     }
289     catch (multipr::RuntimeException& e)
290     {
291         e.dump(cout);
292         THROW_SALOME_CORBA_EXCEPTION("decimePartition() failed", SALOME::INTERNAL_ERROR);
293     }
294 }
295
296
297 //-----------------------------------------------------------------------------
298 // Low level API
299 //-----------------------------------------------------------------------------
300
301 MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_Gen_i::getObject(const char* medFilename)
302     throw (SALOME::SALOME_Exception)
303 {
304     MULTIPR_Obj_i* obj = new MULTIPR_Obj_i(_poa, medFilename);
305     obj->setEngine(this);
306
307     // Dump Python
308     MULTIPR::TPythonDump(this) << obj << " = " << this << ".getObject(\"" << medFilename << "\")";
309
310     return obj->POA_MULTIPR_ORB::MULTIPR_Obj::_this();
311 }
312
313
314 void MULTIPR_Gen_i::ObjModified (MULTIPR_ORB::MULTIPR_Obj_ptr theObj)
315 {
316   // Mark current study as modified, if theObj is published in it
317   if (!CORBA::is_nil(myCurrentStudy) && !CORBA::is_nil(theObj))
318   {
319     SALOMEDS::SObject_var aSO = myCurrentStudy->FindObjectIOR(_orb->object_to_string(theObj));
320     // if published
321     if (!CORBA::is_nil(aSO))
322       myCurrentStudy->Modified();
323   }
324 }
325
326
327 MULTIPR_Obj_i::MULTIPR_Obj_i(PortableServer::POA_ptr thePOA,
328                               const char* medFilename,
329                               bool isPersistence,
330                               bool isMultifile)
331     throw (SALOME::SALOME_Exception)
332     : SALOME::GenericObj_i(thePOA),
333       mBoxing(100),
334       _engine(NULL),
335       mIsTmp(isPersistence && !isMultifile)
336 {
337     mObj    = new multipr::Obj();
338
339     try
340     {
341         cout << "Load " << medFilename << endl;
342         if (isPersistence)
343           mObj->restorePersistent(medFilename);
344         else
345           mObj->create(medFilename);
346         cout << endl;
347     }
348     catch (multipr::RuntimeException& e)
349     {
350         delete mObj;
351         mObj = NULL;
352         e.dump(cout);
353         THROW_SALOME_CORBA_EXCEPTION("Unable to create object", SALOME::INTERNAL_ERROR);
354     }
355 }
356
357
358 MULTIPR_Obj_i::~MULTIPR_Obj_i()
359 {
360     if (mObj != NULL)
361     {
362         if (mIsTmp)
363         {
364             // Remove temporary files, created during study loading, together with directory
365             std::string strFile = mObj->getMEDFilename();
366             std::string strPath = multipr::getPath(strFile.c_str());
367 #ifdef WNT
368             //std::string cmd_rm ("del /F \"");
369 #else
370             std::string cmd_rm ("rm -rf \"");
371 #endif
372             cmd_rm += strPath + "\"";
373             system(cmd_rm.c_str());
374         }
375
376         if(MYDEBUG) MESSAGE("MULTIPR_Obj_i: Destructor: remove mObj");
377         delete mObj;
378         mObj = NULL;
379     }
380 }
381
382 void MULTIPR_Obj_i::reset()
383         throw (SALOME::SALOME_Exception)
384 {
385     mObj->reset();
386 }
387
388 CORBA::Boolean MULTIPR_Obj_i::isValidSequentialMEDFile()
389         throw (SALOME::SALOME_Exception)
390 {
391     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
392
393     return mObj->isValidSequentialMEDFile();
394 }
395
396
397 CORBA::Boolean MULTIPR_Obj_i::isValidDistributedMEDFile()
398     throw (SALOME::SALOME_Exception)
399 {
400     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
401
402     return mObj->isValidDistributedMEDFile();
403 }
404
405
406 char* MULTIPR_Obj_i::getFilename()
407         throw (SALOME::SALOME_Exception)
408 {
409     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
410
411     return CORBA::string_dup(mObj->getMEDFilename().c_str());
412 }
413
414
415 char* MULTIPR_Obj_i::getSeqFilename()
416         throw (SALOME::SALOME_Exception)
417 {
418     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
419
420     return CORBA::string_dup(mObj->getSequentialMEDFilename().c_str());
421 }
422
423
424 void MULTIPR_Obj_i::setMesh(const char* meshName)
425         throw (SALOME::SALOME_Exception)
426 {
427     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
428
429     try
430     {
431         mObj->setMesh(meshName);
432
433         // Dump Python
434         MULTIPR::TPythonDump(_engine) << this << ".setMesh(\"" << meshName << "\")";
435
436         if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::setMesh - OK");
437     }
438     catch (multipr::RuntimeException& e)
439     {
440         e.dump(cout);
441         THROW_SALOME_CORBA_EXCEPTION("Unable to set mesh", SALOME::INTERNAL_ERROR);
442     }
443
444   // Mark current study as modified, if theObj is published in it
445   _engine->ObjModified(_this());
446 }
447
448 std::string MULTIPR_Obj_i::getMeshName() const
449         throw (SALOME::SALOME_Exception)
450 {
451   if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
452
453   return mObj->getMeshName();
454 }
455
456
457 void MULTIPR_Obj_i::setBoxing(CORBA::Long pBoxing)
458     throw (SALOME::SALOME_Exception)
459 {
460     if (mBoxing < 0) THROW_SALOME_CORBA_EXCEPTION("Invalid boxing parameter; should be >= 1", SALOME::INTERNAL_ERROR);
461     if (mBoxing > 200) THROW_SALOME_CORBA_EXCEPTION("Invalid boxing parameter; should be <= 200", SALOME::INTERNAL_ERROR);
462
463     mBoxing = pBoxing;
464
465     // Dump Python
466     MULTIPR::TPythonDump(_engine) << this << ".setBoxing(" << pBoxing << ")";
467
468   // Mark current study as modified, if theObj is published in it
469   _engine->ObjModified(_this());
470 }
471
472
473 MULTIPR_ORB::string_array* MULTIPR_Obj_i::getMeshes()
474     throw (SALOME::SALOME_Exception)
475 {
476     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
477
478     MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
479
480     try
481     {
482         std::vector<std::string> listMeshes = mObj->getMeshes();
483         mySeq->length(listMeshes.size());
484
485         for (size_t i = 0 ; i < listMeshes.size() ; i++)
486         {
487             mySeq[i] = CORBA::string_dup(listMeshes[i].c_str());
488         }
489     }
490     catch (multipr::RuntimeException& e)
491     {
492         e.dump(cout);
493         THROW_SALOME_CORBA_EXCEPTION("Unable to get meshes", SALOME::INTERNAL_ERROR);
494     }
495
496     return mySeq._retn();
497 }
498
499
500 MULTIPR_ORB::string_array* MULTIPR_Obj_i::getFields(const char* pPartList)
501     throw (SALOME::SALOME_Exception)
502 {
503     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
504
505     MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
506
507     try
508     {
509         std::vector<std::string> listFields = mObj->getFields(pPartList);
510         mySeq->length(listFields.size());
511
512         for (size_t i = 0 ; i < listFields.size() ; i++)
513         {
514             mySeq[i] = CORBA::string_dup(listFields[i].c_str());
515         }
516     }
517     catch (multipr::RuntimeException& e)
518     {
519         e.dump(cout);
520         THROW_SALOME_CORBA_EXCEPTION("Unable to get fields", SALOME::INTERNAL_ERROR);
521     }
522
523     return mySeq._retn();
524 }
525
526
527 CORBA::Long MULTIPR_Obj_i::getTimeStamps(const char* pPartList, const char* fieldName)
528     throw (SALOME::SALOME_Exception)
529 {
530     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
531
532     try
533     {
534         return mObj->getTimeStamps(pPartList, fieldName);
535     }
536     catch (multipr::RuntimeException& e)
537     {
538         e.dump(cout);
539         THROW_SALOME_CORBA_EXCEPTION("Unable to get time stamps", SALOME::INTERNAL_ERROR);
540     }
541 }
542
543 void MULTIPR_Obj_i::getFieldMinMax(const char* pPartName, const char* pFieldName,
544                                    CORBA::Float& pMin, CORBA::Float& pMax)
545     throw (SALOME::SALOME_Exception)
546 {
547     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
548     try
549     {
550         mObj->getFieldMinMax(pPartName, pFieldName, pMin, pMax);
551     }
552     catch (multipr::RuntimeException& e)
553     {
554         e.dump(cout);
555         THROW_SALOME_CORBA_EXCEPTION("Unable to get parts", SALOME::INTERNAL_ERROR);
556     }
557 }
558
559 MULTIPR_ORB::string_array* MULTIPR_Obj_i::getParts()
560     throw (SALOME::SALOME_Exception)
561 {
562     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
563
564     MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
565
566     try
567     {
568         std::vector<std::string> listParts = mObj->getParts();
569         mySeq->length(listParts.size());
570
571         for (size_t i = 0 ; i < listParts.size() ; i++)
572         {
573             mySeq[i] = CORBA::string_dup(listParts[i].c_str());
574         }
575     }
576     catch (multipr::RuntimeException& e)
577     {
578         e.dump(cout);
579         THROW_SALOME_CORBA_EXCEPTION("Unable to get parts", SALOME::INTERNAL_ERROR);
580     }
581
582     return mySeq._retn();
583 }
584
585
586 char* MULTIPR_Obj_i::getPartInfo(const char* pPartName)
587     throw (SALOME::SALOME_Exception)
588 {
589     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
590
591     return CORBA::string_dup(mObj->getPartInfo(pPartName).c_str());
592 }
593
594
595 MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneDomaine()
596     throw (SALOME::SALOME_Exception)
597 {
598     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
599
600     MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
601
602     try
603     {
604         std::vector<std::string> listParts = mObj->partitionneDomaine();
605         mySeq->length(listParts.size());
606
607         for (size_t i = 0 ; i < listParts.size() ; i++)
608         {
609             mySeq[i] = CORBA::string_dup(listParts[i].c_str());
610         }
611
612         // Dump Python
613         MULTIPR::TPythonDump(_engine) << "parts = " << this << ".partitionneDomaine()";
614     }
615     catch (multipr::RuntimeException& e)
616     {
617         e.dump(cout);
618         THROW_SALOME_CORBA_EXCEPTION("Unable to partition mesh", SALOME::INTERNAL_ERROR);
619     }
620
621   // Mark current study as modified, if theObj is published in it
622   _engine->ObjModified(_this());
623
624   return mySeq._retn();
625 }
626
627
628 MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneGroupe(
629         const char* pPartName,
630         CORBA::Long pNbParts,
631         CORBA::Long pPartitionner)
632         throw (SALOME::SALOME_Exception)
633 {
634     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
635
636     MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
637
638     try
639     {
640         std::vector<std::string> listParts = mObj->partitionneGroupe(
641             pPartName,
642             pNbParts,
643             pPartitionner);
644
645         mySeq->length(listParts.size());
646
647         for (size_t i = 0 ; i < listParts.size() ; i++)
648         {
649             mySeq[i] = CORBA::string_dup(listParts[i].c_str());
650         }
651
652         // Dump Python
653         MULTIPR::TPythonDump(_engine) << "new_parts = " << this << ".partitionneGroupe(\""
654         << pPartName << "\", " << pNbParts << ", " << pPartitionner << ")";
655     }
656     catch (std::exception& exc)
657     {
658         THROW_SALOME_CORBA_EXCEPTION(exc.what(), SALOME::INTERNAL_ERROR);
659     }
660     catch (multipr::RuntimeException& exc)
661     {
662         std::ostringstream aStream;
663         exc.dump(aStream);
664         aStream<<ends;
665         THROW_SALOME_CORBA_EXCEPTION(aStream.str().c_str(), SALOME::INTERNAL_ERROR);
666     }
667
668   // Mark current study as modified, if theObj is published in it
669   _engine->ObjModified(_this());
670
671   return mySeq._retn();
672 }
673
674
675 MULTIPR_ORB::string_array* MULTIPR_Obj_i::decimePartition(
676         const char*   pPartName,
677         const char*   pFieldName,
678         CORBA::Long   pFieldIt,
679         const char*   pFilterName,
680         const char*   pFilterParams)
681         throw (SALOME::SALOME_Exception)
682 {
683   if (mObj == NULL)
684   {
685     THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
686   }
687     MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
688
689     try
690     {
691         std::vector<std::string> listParts = mObj->decimePartition(
692             pPartName,
693             pFieldName,
694             pFieldIt,
695             pFilterName,
696             pFilterParams);
697         mySeq->length(listParts.size());
698         for (size_t i = 0 ; i < listParts.size() ; i++)
699         {
700             mySeq[i] = CORBA::string_dup(listParts[i].c_str());
701         }
702
703         // Dump Python
704         MULTIPR::TPythonDump(_engine) << "parts = " << this << ".decimePartition(\""
705                                       << pPartName << "\", \"" << pFieldName << "\", "
706                                       << pFieldIt << ", \"" << pFilterName << "\", \""
707                                       << pFilterParams << "\")";
708     }
709     catch (multipr::RuntimeException& e)
710     {
711         e.dump(cout);
712         THROW_SALOME_CORBA_EXCEPTION("Unable to decimate", SALOME::INTERNAL_ERROR);
713     }
714
715   // Mark current study as modified, if theObj is published in it
716   _engine->ObjModified(_this());
717
718   return mySeq._retn();
719 }
720
721 /*
722 MULTIPR_ORB::string_array* MULTIPR_Obj_i::decimatePart(
723         const char*   pPartName,
724         const char*   pFieldName,
725         CORBA::Long   pFieldIt,
726         const char*   pFilterName,
727         const char*   pFilterParams)
728         throw (SALOME::SALOME_Exception)
729 {
730   if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
731
732   MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
733
734   try
735   {
736     std::list<std::string> emptyParts;
737     mObj->decimePartition(pPartName,
738                           pFieldName,
739                           pFieldIt,
740                           pFilterName,
741                           pFilterParams,
742                           emptyParts);
743
744     mySeq->length(emptyParts.size());
745     std::list<std::string>::const_iterator it = emptyParts.begin(), end = emptyParts.end();
746     for (size_t i = 0; it != end; it++, i++)
747     {
748       mySeq[i] = CORBA::string_dup((*it).c_str());
749     }
750
751     // Dump Python
752     MULTIPR::TPythonDump(_engine) << "empty_parts = " << this << ".decimatePart(\""
753                                   << pPartName << "\", \"" << pFieldName << "\", "
754                                   << pFieldIt << ", \"" << pFilterName << "\", \""
755                                   << pFilterParams << "\")";
756   }
757   catch (multipr::RuntimeException& e)
758   {
759     e.dump(cout);
760     THROW_SALOME_CORBA_EXCEPTION("Unable to decimate", SALOME::INTERNAL_ERROR);
761   }
762
763   // Mark current study as modified, if theObj is published in it
764   _engine->ObjModified(_this());
765
766   return mySeq._retn();
767 }
768 */
769
770 char* MULTIPR_Obj_i::evalDecimationParams(
771     const char* pPartName,
772     const char* pFieldName,
773     CORBA::Long pFieldIt,
774     const char* pFilterName,
775     const char* pFilterParams)
776     throw (SALOME::SALOME_Exception)
777 {
778     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
779
780     try
781     {
782         string res = mObj->evalDecimationParams(
783             pPartName,
784             pFieldName,
785             pFieldIt,
786             pFilterName,
787             pFilterParams);
788
789         // Dump Python
790         MULTIPR::TPythonDump(_engine) << "dec_params = " << this << ".evalDecimationParams(\""
791                                       << pPartName << "\", \"" << pFieldName << "\", " << pFieldIt
792                                       << ", \"" << pFilterName << "\", \"" << pFilterParams
793                                       << "\") # " << res.c_str();
794         return CORBA::string_dup(res.c_str());
795     }
796     catch (multipr::RuntimeException& e)
797     {
798         e.dump(cout);
799         THROW_SALOME_CORBA_EXCEPTION("Unable to evaluate decimation parameters", SALOME::INTERNAL_ERROR);
800     }
801 }
802
803
804 void MULTIPR_Obj_i::removeParts(const char* pPrefixPartName)
805     throw (SALOME::SALOME_Exception)
806 {
807     if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
808
809     mObj->removeParts(pPrefixPartName);
810
811     // Dump Python
812     MULTIPR::TPythonDump(_engine) << this << ".removeParts(\"" << pPrefixPartName << "\")";
813
814   // Mark current study as modified, if theObj is published in it
815   _engine->ObjModified(_this());
816 }
817
818 char* MULTIPR_Obj_i::getMEDInfo(const char* pPartName)
819   throw (SALOME::SALOME_Exception)
820 {
821   if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
822   char res[128];
823
824   mObj->getMEDInfo(res, const_cast<char*>(pPartName));
825   return CORBA::string_dup(res);
826 }
827
828 void MULTIPR_Obj_i::save(const char* pPath)
829     throw (SALOME::SALOME_Exception)
830 {
831   if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
832
833   try
834   {
835     std::string strFile = mObj->getMEDFilename();
836
837     // Do Save
838     mObj->save(pPath);
839
840     // Remove temporary files, if needed
841     if (mIsTmp)
842     {
843       mIsTmp = false;
844
845       // Remove temporary files, created during study loading, together with directory
846       std::string strPath = multipr::getPath(strFile.c_str());
847 #ifdef WNT
848       //std::string cmd_rm ("del /F \"");
849 #else
850       std::string cmd_rm ("rm -rf \"");
851 #endif
852       cmd_rm += strPath + "\"";
853       system(cmd_rm.c_str());
854     }
855   }
856   catch (multipr::RuntimeException& e)
857   {
858     e.dump(cout);
859     THROW_SALOME_CORBA_EXCEPTION("Unable to save MED file", SALOME::INTERNAL_ERROR);
860   }
861
862   // Dump Python
863   MULTIPR::TPythonDump(_engine) << this << ".save(\"" << pPath << "\")";
864 }
865
866 CORBA::Long MULTIPR_Obj_i::getSaveProgress()
867 {
868   return mObj->getProgress();
869 }
870
871 void MULTIPR_Obj_i::resetSaveProgress()
872 {
873   mObj->resetProgress();
874 }
875
876 //-----------------------------------------------------------------------------
877 // savePersistent and setEngine (for Persistence & Dump Python)
878 //-----------------------------------------------------------------------------
879
880 void MULTIPR_Obj_i::savePersistent (const char* pPath)
881     throw (SALOME::SALOME_Exception)
882 {
883   if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
884
885   try
886   {
887     mObj->savePersistent(pPath);
888   }
889   catch (multipr::RuntimeException& e)
890   {
891     e.dump(cout);
892     THROW_SALOME_CORBA_EXCEPTION("Unable to save MED file", SALOME::INTERNAL_ERROR);
893   }
894 }
895
896 void MULTIPR_Obj_i::setEngine (MULTIPR_Gen_i* theEngine)
897 {
898   _engine = theEngine;
899 }
900
901
902 //-----------------------------------------------------------------------------
903 // Set/Get current study (for Persistence & Dump Python)
904 //-----------------------------------------------------------------------------
905
906 /*! Set current study
907  */
908 void MULTIPR_Gen_i::SetCurrentStudy (SALOMEDS::Study_ptr theStudy)
909 {
910   //if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::SetCurrentStudy");
911
912   // theStudy or myCurrentStudy may be nil
913   if (!CORBA::is_nil(theStudy))
914   {
915     if (CORBA::is_nil(myCurrentStudy))
916     {
917       // move python trace of unknown study to the real study
918       int studyId = theStudy->StudyId();
919       if (myPythonScripts.find(-1) != myPythonScripts.end())
920       {
921         myPythonScripts[studyId].insert(myPythonScripts[studyId].begin(), // at
922                                         myPythonScripts[-1].begin(), // from
923                                         myPythonScripts[-1].end());  // to
924         myPythonScripts[-1].clear();
925       }
926     }
927   }
928
929   myCurrentStudy = SALOMEDS::Study::_duplicate(theStudy);
930 }
931
932 /*! Get current study
933  */
934 SALOMEDS::Study_ptr MULTIPR_Gen_i::GetCurrentStudy()
935 {
936   //if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::GetCurrentStudy: study Id = " << GetCurrentStudyID());
937   return SALOMEDS::Study::_duplicate(myCurrentStudy);
938 }
939
940 //-----------------------------------------------------------------------------
941 // SALOMEDS::Driver methods (Persistence & Dump Python)
942 //-----------------------------------------------------------------------------
943
944 /*! Get component data type
945  */
946 char* MULTIPR_Gen_i::ComponentDataType()
947 {
948   if(MYDEBUG) MESSAGE( "MULTIPR_Gen_i::ComponentDataType" );
949   return CORBA::string_dup( "MULTIPR" );
950 }
951
952 /*! Clears study-connected data when it is closed
953  */
954 void MULTIPR_Gen_i::Close (SALOMEDS::SComponent_ptr theComponent)
955 {
956   if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::Close");
957 }
958
959 /*! Save MULTIPR module's data
960  */
961 SALOMEDS::TMPFile* MULTIPR_Gen_i::Save (SALOMEDS::SComponent_ptr theComponent,
962                                         const char*              theURL,
963                                         bool                     isMultiFile)
964 {
965   INFOS( "MULTIPR_Gen_i::Save" );
966
967   if (myCurrentStudy->_is_nil() ||
968       theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId())
969     SetCurrentStudy(theComponent->GetStudy());
970
971   // Store study contents as a set of python commands
972   SavePython(myCurrentStudy);
973
974   // Study name (for tmp directory and tmp files naming)
975   std::string aStudyName;
976   if (isMultiFile)
977     aStudyName = SALOMEDS_Tool::GetNameFromPath(myCurrentStudy->URL());
978
979   // Declare a byte stream
980   SALOMEDS::TMPFile_var aStreamFile;
981
982   SALOMEDS::ChildIterator_ptr obj_it (myCurrentStudy->NewChildIterator(theComponent));
983
984   // TODO: iterate on all objects under theComponent
985   if (!obj_it->More())
986     return aStreamFile._retn();
987
988   SALOMEDS::SObject_ptr aSObj = obj_it->Value();
989   CORBA::Object_var anObj = aSObj->GetObject();
990   MULTIPR_ORB::MULTIPR_Obj_ptr obj = MULTIPR_ORB::MULTIPR_Obj::_narrow(anObj);
991   if (CORBA::is_nil(obj))
992     return aStreamFile._retn();
993
994   // Obtain a temporary directory
995   std::string tmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir();
996
997   // Directory for MED data to be stored in a distributed MED file
998   std::string subDir  = aStudyName + "_MULTIPR_MED";
999   std::string meshDir = tmpDir + subDir;
1000
1001   // Create a new dir <meshDir> to save the sequential/distributed file in.
1002   // Remove all the files in <meshDir> if they exist.
1003 #ifdef WNT
1004   std::string dirSeparator = "\\";
1005   //std::string cmd_mk ("mkdir /F \"");
1006   //std::string cmd_rm ("del /F \"");
1007 #else
1008   std::string dirSeparator = "/";
1009   std::string cmd_mk ("mkdir \"");
1010   std::string cmd_rm ("rm -rf \"");
1011 #endif
1012   cmd_mk += meshDir + "\"";
1013   cmd_rm += meshDir + dirSeparator + "\"*";
1014   system(cmd_mk.c_str());
1015   system(cmd_rm.c_str());
1016
1017   // Create a sequence of files processed
1018   SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames;
1019
1020   if (obj->isValidSequentialMEDFile())
1021   {
1022     std::string aFile = obj->getFilename();
1023     std::string aFileName = multipr::getFilenameWithoutPath(aFile.c_str());
1024
1025     // Copy initial sequential MED file to <meshDir>
1026 #ifdef WNT
1027     std::string dirSeparator = "\\";
1028     //std::string cmd_cp ("copy \"");
1029 #else
1030     std::string dirSeparator = "/";
1031     std::string cmd_cp ("cp \"");
1032 #endif
1033     cmd_cp += aFile + "\" \"" + meshDir + dirSeparator + "\"";
1034     system(cmd_cp.c_str());
1035
1036     // Set names of temporary files
1037     std::string aFileNameRel = subDir + dirSeparator + aFileName;
1038     aFileSeq->length(1);
1039     aFileSeq[0] = CORBA::string_dup(aFileNameRel.c_str()); // sequential MED file
1040   }
1041   else if (obj->isValidDistributedMEDFile())
1042   {
1043     // Save distributed MED file to the <meshDir>
1044     PortableServer::Servant aServant = _poa->reference_to_servant(obj);
1045     MULTIPR_Obj_i* objServant = dynamic_cast<MULTIPR_Obj_i*>(aServant);
1046     if (!objServant)
1047     {
1048       // TODO: exception
1049       return aStreamFile._retn();
1050     }
1051     objServant->savePersistent(meshDir.c_str());
1052
1053     // ASCII master file name
1054     std::string aMaitreFile = obj->getFilename();
1055     std::string aMaitreFileName = multipr::getFilenameWithoutPath(aMaitreFile.c_str());
1056     // just after partitionneDomaine() the state is MULTIPR_OBJ_STATE_DIS_MEM,
1057     // and getFilename() returns name of sequential file
1058     // (because distributed file is not created on disk yet). So, build the name:
1059     if (aMaitreFile == obj->getSeqFilename())
1060     {
1061       std::string strExtension (".med");
1062       std::string strNamePrefix =
1063         multipr::removeExtension(aMaitreFileName.c_str(), strExtension.c_str());
1064       aMaitreFileName = strNamePrefix + "_grains_maitre" + strExtension;
1065     }
1066     //std::string aMaitreFileName = SALOMEDS_Tool::GetNameFromPath(aMaitreFile);
1067     std::string aMaitreFileNameRel = subDir + dirSeparator + aMaitreFileName;
1068
1069     // Set names of temporary files
1070     MULTIPR_ORB::string_array* listParts = obj->getParts();
1071     unsigned int nbParts = listParts->length();
1072     aFileSeq->length(nbParts + 1);
1073
1074     char   lMeshName[256];
1075     int    lId;
1076     char   lPartName[256];
1077     char   lPath[256];
1078     char   lMEDFileName[256];
1079
1080     for (unsigned int i = 0; i < nbParts; i++) // each part MED files
1081     {
1082       const char* strPartName = (*listParts)[i];
1083       char* strPartInfo = obj->getPartInfo(strPartName);
1084
1085       // parse infos
1086       int ret = sscanf(strPartInfo, "%s %d %s %s %s",
1087                        lMeshName, &lId, lPartName, lPath, lMEDFileName);
1088
1089       if (ret != 5)
1090       {
1091         // TODO: exception
1092         return aStreamFile._retn();
1093       }
1094
1095       std::string aPartFileName = multipr::getFilenameWithoutPath(lMEDFileName);
1096       std::string aPartFileNameRel = subDir + dirSeparator + aPartFileName;
1097
1098       aFileSeq[i] = CORBA::string_dup(aPartFileNameRel.c_str()); // part MED file
1099     }
1100     aFileSeq[nbParts] = CORBA::string_dup(aMaitreFileNameRel.c_str()); // ASCII master file
1101   }
1102   else
1103   {
1104     // TODO: exception
1105     return aStreamFile._retn();
1106   }
1107
1108   // Convert temporary files to stream
1109   aStreamFile = SALOMEDS_Tool::PutFilesToStream(tmpDir, aFileSeq.in(), isMultiFile);
1110
1111   // Remove temporary files and directory
1112   if (!isMultiFile)
1113   {
1114     //SALOMEDS_Tool::RemoveTemporaryFiles(tmpDir, aFileSeq.in(), true);
1115     // remove with shell command, because SALOMEDS_Tool::RemoveTemporaryFiles does not remove sub-folders
1116 #ifdef WNT
1117     //std::string cmd_rm ("del /F \"");
1118 #else
1119     std::string cmd_rm ("rm -rf \"");
1120 #endif
1121     cmd_rm += tmpDir + "\"";
1122     system(cmd_rm.c_str());
1123   }
1124
1125   INFOS("MULTIPR_Gen_i::Save() completed");
1126   return aStreamFile._retn();
1127 }
1128
1129 /*! Save MULTIPR module's data in ASCII format
1130  */
1131 SALOMEDS::TMPFile* MULTIPR_Gen_i::SaveASCII (SALOMEDS::SComponent_ptr theComponent,
1132                                              const char*              theURL,
1133                                              bool                     isMultiFile)
1134 {
1135   if(MYDEBUG) MESSAGE( "MULTIPR_Gen_i::SaveASCII" );
1136   SALOMEDS::TMPFile_var aStreamFile = Save(theComponent, theURL, isMultiFile);
1137   return aStreamFile._retn();
1138 }
1139
1140 /*! Load MULTIPR module's data
1141  */
1142 bool MULTIPR_Gen_i::Load (SALOMEDS::SComponent_ptr theComponent,
1143                           const SALOMEDS::TMPFile& theStream,
1144                           const char*              theURL,
1145                           bool                     isMultiFile)
1146 {
1147   INFOS("MULTIPR_Gen_i::Load");
1148
1149   if (myCurrentStudy->_is_nil() ||
1150       theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId())
1151     SetCurrentStudy(theComponent->GetStudy());
1152
1153   // Get temporary files location
1154   std::string tmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir();
1155
1156   INFOS("THE URL++++++++++++++");
1157   INFOS(theURL);
1158   INFOS("THE TMP PATH+++++++++");
1159   INFOS(tmpDir.c_str());
1160
1161   // For LocalPersistentIDToIOR():
1162   myTmpDir = tmpDir;
1163
1164   // Create a new dir <meshDir> to restore the distributed/sequential
1165   // MED file in. It is needed only if not multifile, because in
1166   // multifile study all required files are already on disk.
1167   if (!isMultiFile)
1168   {
1169     std::string subDir  = "_MULTIPR_MED";
1170     std::string meshDir = tmpDir + subDir;
1171 #ifdef WNT
1172     //std::string cmd_mk ("mkdir /F \"");
1173 #else
1174     std::string cmd_mk ("mkdir \"");
1175 #endif
1176     cmd_mk += meshDir + "\"";
1177     system(cmd_mk.c_str());
1178   }
1179
1180   // Convert the stream into sequence of files to process
1181   SALOMEDS::ListOfFileNames_var aFileSeq =
1182     SALOMEDS_Tool::PutStreamToFiles(theStream, tmpDir.c_str(), isMultiFile);
1183
1184   //TCollection_AsciiString aStudyName;
1185   //if (isMultiFile)
1186   //  aStudyName = ((char*)SALOMEDS_Tool::GetNameFromPath(myCurrentStudy->URL()).c_str());
1187
1188   // Set names of "temporary" files
1189   //TCollection_AsciiString filename = tmpDir + aStudyName + TCollection_AsciiString( "_MULTIPR.hdf" );
1190   //TCollection_AsciiString meshfile = tmpDir + aStudyName + TCollection_AsciiString( "_MULTIPR_Mesh.med" );
1191
1192   // Remove temporary files created from the stream
1193   //if (!isMultiFile)
1194   //  SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
1195
1196   INFOS("MULTIPR_Gen_i::Load completed");
1197   return true;
1198 }
1199
1200 /*! Load MULTIPR module's data in ASCII format
1201  */
1202 bool MULTIPR_Gen_i::LoadASCII (SALOMEDS::SComponent_ptr theComponent,
1203                                const SALOMEDS::TMPFile& theStream,
1204                                const char*              theURL,
1205                                bool                     isMultiFile)
1206 {
1207   if(MYDEBUG) MESSAGE( "MULTIPR_Gen_i::LoadASCII" );
1208   return Load(theComponent, theStream, theURL, isMultiFile);
1209 }
1210
1211 /*! Transform data from transient form to persistent
1212  */
1213 char* MULTIPR_Gen_i::IORToLocalPersistentID (SALOMEDS::SObject_ptr /*theSObject*/,
1214                                              const char*           IORString,
1215                                              CORBA::Boolean        isMultiFile,
1216                                              CORBA::Boolean        /*isASCII*/ )
1217 {
1218   if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::IORToLocalPersistentID");
1219
1220   MULTIPR_ORB::MULTIPR_Obj_ptr obj =
1221     MULTIPR_ORB::MULTIPR_Obj::_narrow(_orb->string_to_object(IORString));
1222
1223   if (!CORBA::is_nil(obj))
1224   {
1225     std::string aStudyName;
1226     if (isMultiFile)
1227       aStudyName = SALOMEDS_Tool::GetNameFromPath(myCurrentStudy->URL());
1228
1229     std::string subDir  = aStudyName + "_MULTIPR_MED";
1230
1231     std::string aFile = obj->getFilename();
1232     std::string aFileName = multipr::getFilenameWithoutPath(aFile.c_str());
1233
1234     // Get servant (to call methods, not present in IDL interface
1235     PortableServer::Servant aServant = _poa->reference_to_servant(obj);
1236     MULTIPR_Obj_i* objServant = dynamic_cast<MULTIPR_Obj_i*>(aServant);
1237     if (!objServant)
1238     {
1239       // TODO: exception
1240       return CORBA::string_dup("");
1241     }
1242
1243     std::string strSeparator ("|");
1244     if (obj->isValidSequentialMEDFile())
1245     {
1246       // Save Boxing
1247       char strBoxing[32];
1248       sprintf(strBoxing, "%d", objServant->getBoxing());
1249       aFileName += strSeparator + strBoxing;
1250
1251       // Save Mesh Name
1252       std::string aMeshName = objServant->getMeshName();
1253       if (!aMeshName.empty())
1254       {
1255         aFileName += strSeparator + aMeshName;
1256       }
1257     }
1258     else if (obj->isValidDistributedMEDFile())
1259     {
1260       // just after partitionneDomaine() the state is MULTIPR_OBJ_STATE_DIS_MEM,
1261       // and getFilename() returns name of sequential file
1262       // (because distributed file is not created on disk yet). So, build the name:
1263       if (aFile == obj->getSeqFilename())
1264       {
1265         std::string strExtension (".med");
1266         std::string strNamePrefix =
1267           multipr::removeExtension(aFileName.c_str(), strExtension.c_str());
1268         aFileName = strNamePrefix + "_grains_maitre" + strExtension;
1269       }
1270
1271       // Save Boxing
1272       char strBoxing[32];
1273       sprintf(strBoxing, "%d", objServant->getBoxing());
1274       aFileName += strSeparator + strBoxing;
1275     }
1276     else
1277     {
1278       // TODO: exception
1279       return CORBA::string_dup("");
1280     }
1281
1282     // PersistentID will be a relative path to MED file (relatively tmp dir)
1283     // plus additianal parameters, separated by '|' (see above)
1284 #ifdef WNT
1285     std::string dirSeparator = "\\";
1286 #else
1287     std::string dirSeparator = "/";
1288 #endif
1289     aFileName = subDir + dirSeparator + aFileName;
1290
1291     if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::IORToLocalPersistentID: id = " << aFileName.c_str());
1292
1293     return CORBA::string_dup(aFileName.c_str());
1294   }
1295   return CORBA::string_dup("");
1296 }
1297
1298 /*! Transform data from persistent form to transient
1299  */
1300 char* MULTIPR_Gen_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr /*theSObject*/,
1301                                              const char*           aLocalPersistentID,
1302                                              CORBA::Boolean        isMultiFile,
1303                                              CORBA::Boolean        /*isASCII*/)
1304 {
1305   if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID);
1306
1307   if (strlen(aLocalPersistentID) > 0)
1308   {
1309     // Extract relative path
1310     std::string strLocalPersistentID (aLocalPersistentID);
1311     int nb = strLocalPersistentID.find("|");
1312     if (nb < 1) nb = strLocalPersistentID.size();
1313     if (nb < 1)
1314     {
1315       // TODO: exception
1316       return CORBA::string_dup("");
1317     }
1318     std::string strRelativePath = strLocalPersistentID.substr(0, nb);
1319     strLocalPersistentID.erase(0, nb); // erase <strRelativePath>
1320     if (strLocalPersistentID.size() > 0) strLocalPersistentID.erase(0, 1); // erase "|"
1321
1322     // the only kind of available objects is a MULTIPR_ORB::MULTIPR_Obj,
1323     // representing a sequential or a distributed MED file.
1324     std::string medFilename = myTmpDir + strRelativePath; // myTmpDir already contains dir separator
1325
1326     // create MULTIPR_Obj from file
1327     //MULTIPR_ORB::MULTIPR_Obj_ptr obj = getObject(medFilename.c_str());
1328     MULTIPR_Obj_i* obj_i = new MULTIPR_Obj_i (_poa,
1329                                               medFilename.c_str(),
1330                                               /*isPersistence = */true,
1331                                               isMultiFile);
1332     obj_i->setEngine(this);
1333     MULTIPR_ORB::MULTIPR_Obj_ptr obj = obj_i->POA_MULTIPR_ORB::MULTIPR_Obj::_this();
1334
1335     // Set boxing and mesh name, if provided
1336     nb = strLocalPersistentID.find("|");
1337     if (nb < 1) nb = strLocalPersistentID.size();
1338     if (nb > 0)
1339     {
1340       std::string strBoxing = strLocalPersistentID.substr(0, nb);
1341       strLocalPersistentID.erase(0, nb); // erase <strBoxing>
1342       if (strLocalPersistentID.size() > 0) strLocalPersistentID.erase(0, 1); // erase "|"
1343       int aBoxing = atoi(strBoxing.c_str());
1344       obj->setBoxing(aBoxing);
1345     }
1346
1347     if (obj->isValidSequentialMEDFile())
1348     {
1349       nb = strLocalPersistentID.size();
1350       if (nb > 0)
1351       {
1352         std::string strMeshName = strLocalPersistentID.substr(0, nb);
1353         obj->setMesh(strMeshName.c_str());
1354         // we do not cut <strLocalPersistentID> here,
1355         // because we do not expect to find in it anything
1356       }
1357     }
1358
1359     // get IOR string
1360     CORBA::String_var anIORString = _orb->object_to_string(obj);
1361     return CORBA::string_dup(anIORString);
1362   }
1363   return CORBA::string_dup("");
1364 }
1365
1366 /*! Transform data from persistent form to transient
1367  */
1368 Engines::TMPFile* MULTIPR_Gen_i::DumpPython (CORBA::Object_ptr theStudy,
1369                                              CORBA::Boolean isPublished,
1370                                              CORBA::Boolean& isValidScript)
1371 {
1372   isValidScript = false;
1373
1374   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
1375   if (CORBA::is_nil(aStudy))
1376     return new Engines::TMPFile(0);
1377
1378   /*
1379   SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType());
1380   if (CORBA::is_nil(aSO))
1381     return new Engines::TMPFile(0);
1382
1383   // Map study entries to object names
1384   Resource_DataMapOfAsciiStringAsciiString aMap;
1385   Resource_DataMapOfAsciiStringAsciiString aMapNames;
1386
1387   SALOMEDS::ChildIterator_var Itr = aStudy->NewChildIterator(aSO);
1388   for (Itr->InitEx(true); Itr->More(); Itr->Next()) {
1389     SALOMEDS::SObject_var aValue = Itr->Value();
1390     CORBA::String_var anID = aValue->GetID();
1391     CORBA::String_var aName = aValue->GetName();
1392     TCollection_AsciiString aGUIName ( (char*) aName.in() );
1393     TCollection_AsciiString anEnrty ( (char*) anID.in() );
1394     if (aGUIName.Length() > 0) {
1395       aMapNames.Bind( anEnrty, aGUIName );
1396       aMap.Bind( anEnrty, aGUIName );
1397     }
1398   }
1399   //*/
1400
1401   // Get trace of restored study
1402   SALOMEDS::SObject_var aSO = aStudy->FindComponent(ComponentDataType());
1403   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
1404   SALOMEDS::GenericAttribute_var anAttr =
1405     aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
1406
1407   char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
1408   std::string aSavedTrace (oldValue);
1409
1410   // Add trace of API methods calls and replace study entries by names
1411   std::string aScript =
1412     "### This file is generated by SALOME automatically "
1413     "by dump python functionality of MULTIPR component\n\n";
1414   aScript += DumpPython_impl(aStudy->StudyId(), isPublished, isValidScript, aSavedTrace);
1415
1416   int aLen = aScript.length();
1417   unsigned char* aBuffer = new unsigned char[aLen+1];
1418   strcpy((char*)aBuffer, aScript.c_str());
1419
1420   CORBA::Octet* anOctetBuf = (CORBA::Octet*)aBuffer;
1421   Engines::TMPFile_var aStreamFile = new Engines::TMPFile (aLen+1, aLen+1, anOctetBuf, 1);
1422
1423   //bool hasNotPublishedObjects = aScript.Location( NotPublishedObjectName(), 1, aLen);
1424   //isValidScript = isValidScript && !hasNotPublishedObjects;
1425
1426   return aStreamFile._retn();
1427 }
1428
1429 /*! DumpPython_impl
1430  */
1431 std::string MULTIPR_Gen_i::DumpPython_impl (int theStudyID,
1432                                             bool isPublished,
1433                                             bool& aValidScript,
1434                                             std::string theSavedTrace)
1435 {
1436   std::string helper;
1437   std::string aGen = MULTIPR::TPythonDump::MULTIPRGenName();
1438
1439   // set initial part of a script
1440   std::string aScript ("import salome\n");
1441   aScript += "import MULTIPR_ORB\n\n";
1442   aScript += "def RebuildData(theStudy):\n";
1443
1444   aScript += helper + "\tmpr_comp = salome.lcc.FindOrLoadComponent(\"FactoryServer\", \"" +
1445              ComponentDataType() + "\")\n";
1446   aScript += helper + "\t" + aGen + " = mpr_comp._narrow(MULTIPR_ORB.MULTIPR_Gen)\n";
1447
1448   //if ( isPublished )
1449   //  aScript += helper + "\t" + aGen + ".SetCurrentStudy(theStudy)";
1450   //else
1451   //  aScript += helper + "\t" + aGen + ".SetCurrentStudy(None)";
1452   aScript += helper + "\t" + aGen + ".SetCurrentStudy(theStudy)\n";
1453
1454   // Dump trace of restored study
1455   if (theSavedTrace.length() > 0)
1456   {
1457     aScript += helper + "\n" + theSavedTrace;
1458   }
1459
1460   // Dump trace of API methods calls
1461   std::string aNewLines = GetNewPythonLines(theStudyID);
1462   if (aNewLines.length() > 0)
1463   {
1464     aScript += helper + "\n" + aNewLines;
1465   }
1466
1467   // add final part of a script
1468   //aScript += helper + "\n\tisGUIMode = " + isPublished;
1469   //aScript += "\n\tif isGUIMode and salome.sg.hasDesktop():";
1470   //aScript += "\n\t\tsalome.sg.updateObjBrowser(0)";
1471   aScript += "\n\n\tpass\n";
1472
1473   aValidScript = true;
1474
1475   return aScript;
1476 }
1477
1478 /*! GetNewPythonLines
1479  */
1480 std::string MULTIPR_Gen_i::GetNewPythonLines (int theStudyID)
1481 {
1482   std::string aScript;
1483
1484   // Dump trace of API methods calls
1485   if (myPythonScripts.find(theStudyID) != myPythonScripts.end())
1486   {
1487     std::vector <std::string> aPythonScript = myPythonScripts[theStudyID];
1488     int istr, aLen = aPythonScript.size();
1489     for (istr = 0; istr < aLen; istr++)
1490     {
1491       aScript += "\n\t";
1492       aScript += aPythonScript[istr];
1493     }
1494     aScript += "\n";
1495   }
1496
1497   return aScript;
1498 }
1499
1500 /*! CleanPythonTrace
1501  */
1502 void MULTIPR_Gen_i::CleanPythonTrace (int theStudyID)
1503 {
1504   // Clean trace of API methods calls
1505   if (myPythonScripts.find(theStudyID) != myPythonScripts.end())
1506   {
1507     myPythonScripts[theStudyID].clear();
1508   }
1509 }
1510
1511 /*! AddToPythonScript
1512  */
1513 void MULTIPR_Gen_i::AddToPythonScript (int theStudyID, std::string theString)
1514 {
1515   //if (myPythonScripts.find(theStudyID) == myPythonScripts.end())
1516   //{
1517   //  myPythonScripts[theStudyID] = std::vector<std::string>;
1518   //}
1519   myPythonScripts[theStudyID].push_back(theString);
1520 }
1521
1522 /*! SavePython
1523  */
1524 void MULTIPR_Gen_i::SavePython (SALOMEDS::Study_ptr theStudy)
1525 {
1526   // Dump trace of API methods calls
1527   std::string aScript = GetNewPythonLines(theStudy->StudyId());
1528
1529   // Check contents of PythonObject attribute
1530   SALOMEDS::SObject_var aSO = theStudy->FindComponent(ComponentDataType());
1531   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1532   SALOMEDS::GenericAttribute_var anAttr =
1533     aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePythonObject");
1534
1535   char* oldValue = SALOMEDS::AttributePythonObject::_narrow(anAttr)->GetObject();
1536   std::string oldScript (oldValue);
1537
1538   if (oldScript.length() > 0) {
1539     oldScript += "\n";
1540     oldScript += aScript;
1541   }
1542   else {
1543     oldScript = aScript;
1544   }
1545
1546   // Store in PythonObject attribute
1547   SALOMEDS::AttributePythonObject::_narrow(anAttr)->SetObject(oldScript.c_str(), 1);
1548
1549   // Clean trace of API methods calls
1550   CleanPythonTrace(theStudy->StudyId());
1551 }
1552
1553
1554 /*! Returns true if object can be published in the study
1555  */
1556 bool MULTIPR_Gen_i::CanPublishInStudy (CORBA::Object_ptr theIOR)
1557 {
1558   //if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::CanPublishInStudy - " << !CORBA::is_nil(myCurrentStudy));
1559   if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::CanPublishInStudy");
1560
1561   //if (CORBA::is_nil(myCurrentStudy))
1562   //  return false;
1563
1564   MULTIPR_ORB::MULTIPR_Obj_var anObj = MULTIPR_ORB::MULTIPR_Obj::_narrow(theIOR);
1565   if (!anObj->_is_nil())
1566     return true;
1567
1568   if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::CanPublishInStudy - CANNOT");
1569   return false;
1570 }
1571
1572 /*! Publish object in the study
1573  */
1574 SALOMEDS::SObject_ptr MULTIPR_Gen_i::PublishInStudy (SALOMEDS::Study_ptr   theStudy,
1575                                                      SALOMEDS::SObject_ptr theSObject,
1576                                                      CORBA::Object_ptr     theIOR,
1577                                                      const char*           theName)
1578      throw (SALOME::SALOME_Exception)
1579 {
1580   //Unexpect aCatch(SALOME_SalomeException);
1581
1582   if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::PublishInStudy");
1583
1584   //if (myCurrentStudy->_is_nil() || theStudy->StudyId() != myCurrentStudy->StudyId())
1585   if (myCurrentStudy->_is_nil())
1586     SetCurrentStudy(theStudy);
1587
1588   SALOMEDS::SObject_var aSO;
1589   if (CORBA::is_nil(theStudy) || CORBA::is_nil(theIOR))
1590     return aSO._retn();
1591
1592   // Publishing a MULTIPR_Object
1593   MULTIPR_ORB::MULTIPR_Obj_var anObj = MULTIPR_ORB::MULTIPR_Obj::_narrow(theIOR);
1594   if (!anObj->_is_nil())
1595   {
1596     aSO = theStudy->FindObjectIOR(_orb->object_to_string(anObj));
1597     if (aSO->_is_nil())
1598     {
1599       SALOMEDS::GenericAttribute_var anAttr;
1600       SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
1601
1602       SALOMEDS::SComponent_var aFather = theStudy->FindComponent(ComponentDataType());
1603       if (aFather->_is_nil())
1604       {
1605         aFather = aStudyBuilder->NewComponent(ComponentDataType());
1606         anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
1607         SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
1608         aName->SetValue("MULTI-PR");
1609         //anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
1610         //SALOMEDS::AttributePixMap::_narrow(anAttr)->SetPixMap("ICON_OBJBROWSER_MULTIPR");
1611         //aStudyBuilder->DefineComponentInstance(aFather, MULTIPR_ORB::MULTIPR_Gen::_this());
1612         aStudyBuilder->DefineComponentInstance(aFather, MULTIPR_Gen::_this());
1613       }
1614       if (aFather->_is_nil()) return aSO._retn();
1615
1616       if (CORBA::is_nil(theSObject))
1617       {
1618         aSO = aStudyBuilder->NewObject(aFather);
1619       }
1620       else
1621       {
1622         if (!theSObject->ReferencedObject(aSO))
1623           aSO = SALOMEDS::SObject::_duplicate(theSObject);
1624       }
1625
1626       anAttr = aStudyBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
1627       SALOMEDS::AttributeIOR_var anIORAttr = SALOMEDS::AttributeIOR::_narrow(anAttr);
1628       CORBA::String_var anIOR = _orb->object_to_string(anObj);
1629       anIORAttr->SetValue(anIOR);
1630
1631       //anAttr = aStudyBuilder->FindOrCreateAttribute(aSO, "AttributePixMap");
1632       //SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
1633       //aPixmap->SetPixMap("ICON_OBJBROWSER_GROUP_PNT");
1634
1635       anAttr = aStudyBuilder->FindOrCreateAttribute(aSO, "AttributeName");
1636       SALOMEDS::AttributeName_var aNameAttrib = SALOMEDS::AttributeName::_narrow(anAttr);
1637       if (strlen(theName) == 0)
1638         aNameAttrib->SetValue(anObj->getFilename());
1639       else
1640         aNameAttrib->SetValue(theName);
1641
1642       // Dump Python
1643       MULTIPR::TPythonDump(this) << "sobj = " << this << ".PublishInStudy(theStudy, "
1644                                  << theSObject << ", " << anObj << ", \"" << theName
1645                                  << "\") # " << aSO->GetID();
1646     }
1647   }
1648
1649   if(MYDEBUG) MESSAGE("MULTIPR_Gen_i::PublishInStudy - END");
1650
1651   return aSO._retn();
1652 }
1653
1654 /*
1655 SALOMEDS::SComponent_ptr _Gen_i::PublishComponent(SALOMEDS::Study_ptr theStudy)
1656 {
1657   if ( CORBA::is_nil( theStudy ))
1658     return SALOMEDS::SComponent::_nil();
1659   if(MYDEBUG) MESSAGE("PublishComponent");
1660
1661   SALOMEDS::SComponent_var father =
1662     SALOMEDS::SComponent::_narrow( theStudy->FindComponent( ComponentDataType() ) );
1663   if ( !CORBA::is_nil( father ) )
1664     return father._retn();
1665
1666   SALOME_ModuleCatalog::ModuleCatalog_var aCat =
1667     SALOME_ModuleCatalog::ModuleCatalog::_narrow( GetNS()->Resolve("/Kernel/ModulCatalog") );
1668   if ( CORBA::is_nil( aCat ) )
1669     return father._retn();
1670
1671   SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( ComponentDataType() );
1672   if ( CORBA::is_nil( aComp ) )
1673     return father._retn();
1674
1675   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder();
1676   SALOMEDS::GenericAttribute_var anAttr;
1677   SALOMEDS::AttributePixMap_var  aPixmap;
1678
1679   father  = aStudyBuilder->NewComponent( ComponentDataType() );
1680   aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() );
1681   anAttr  = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" );
1682   aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
1683   aPixmap ->SetPixMap( "ICON_OBJBROWSER_SMESH" );
1684   SetName( father, aComp->componentusername(), "MESH" );
1685   if(MYDEBUG) MESSAGE("PublishComponent--END");
1686
1687   return father._retn();
1688 }
1689 //*/
1690
1691
1692 /*!
1693  *  MULTIPREngine_factory
1694  *
1695  *  C factory, accessible with dlsym, after dlopen
1696  */
1697 extern "C"
1698 {
1699     PortableServer::ObjectId* MULTIPREngine_factory(
1700         CORBA::ORB_ptr orb,
1701         PortableServer::POA_ptr poa,
1702         PortableServer::ObjectId * contId,
1703         const char* instanceName,
1704         const char* interfaceName)
1705     {
1706         MESSAGE("PortableServer::ObjectId* MULTIPREngine_factory()");
1707         SCRUTE(interfaceName);
1708         MULTIPR_Gen_i* myMULTIPR = new MULTIPR_Gen_i(orb, poa, contId, instanceName, interfaceName);
1709         return myMULTIPR->getId();
1710     }
1711 }