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