Salome HOME
NRI : Update 1.1a and New organisation.
[modules/med.git] / src / MED / Med_Gen_i.cxx
1 using namespace std;
2 //=============================================================================
3 // File      : Med_Gen_i.cxx
4 // Created   : mer fév 20 15:47:57 CET 2002
5 // Author    : Paul RASCLE, EDF
6 // Project   : SALOME
7 // Copyright : EDF 2001
8 // $Header$
9 //=============================================================================
10 using namespace std;
11
12 #include "Med_Gen_i.hxx"
13
14 #include "Mesh_i.hxx"
15 #include "Med_i.hxx"
16 #include "FieldInt_i.hxx"
17 #include "FieldDouble_i.hxx"
18 #include "Support_i.hxx"
19
20
21 #include "MEDMEM_Mesh.hxx"
22 #include "MEDMEM_Field.hxx"
23 #include "MEDMEM_Med.hxx"
24 #include "MEDMEM_MedMedDriver.hxx"
25 #include "MEDMEM_MedMeshDriver.hxx"
26 #include "MEDMEM_MedFieldDriver.hxx"
27 #include "MEDMEM_define.hxx"
28 #include "MEDMEM_DriversDef.hxx"
29
30
31 #include "Utils_SINGLETON.hxx"
32 #include "OpUtil.hxx"
33 #include "Utils_CorbaException.hxx"
34 #include "utilities.h"
35
36 #include <string>
37 #include <deque>
38 #include <map>
39
40 #include <TCollection_AsciiString.hxx>
41 #include <TColStd_SequenceOfAsciiString.hxx>
42 #include "SALOMEDS_Tool.hxx"
43
44 // Initialisation des variables statiques
45  map <string, string> Med_Gen_i::_MedCorbaObj;
46  string Med_Gen_i::_myFileName="";
47  string Med_Gen_i::_saveFileName="";
48
49 //=============================================================================
50 /*!
51  *  default constructor: not for use
52  */
53 //=============================================================================
54
55 Med_Gen_i::Med_Gen_i()
56 {
57   MESSAGE("Med_Gen_i::Med_Gen_i");
58 }
59
60 //=============================================================================
61 /*!
62  *  standard constructor
63  */
64 //=============================================================================
65
66 Med_Gen_i:: Med_Gen_i(CORBA::ORB_ptr orb,
67                                 PortableServer::POA_ptr poa,
68                                 PortableServer::ObjectId * contId, 
69                                 const char *instanceName, 
70                                 const char *interfaceName) :
71   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
72 {
73   MESSAGE("activate object");
74   _thisObj = this ;
75   _id = _poa->activate_object(_thisObj);
76
77   _duringLoad=false;
78   // get an NamingService interface
79   _NS = SINGLETON_<SALOME_NamingService>::Instance() ;
80   ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
81   _NS->init_orb( _orb ) ;
82 }
83 //=============================================================================
84 /*!
85  *  private method : change a study name in SALOMEDS::Study_var
86  */
87 //=============================================================================
88
89 SALOMEDS::Study_var Med_Gen_i::studyName2Study(const char* studyName)
90   throw(SALOME::SALOME_Exception)
91 {
92   string myStudyName(studyName);
93
94   if (myStudyName.size() == 0)
95     THROW_SALOME_CORBA_EXCEPTION("No Study Name given", \
96                                  SALOME::BAD_PARAM);
97
98   // Get StudyManager Reference, current study,
99   
100   CORBA::Object_var obj = _NS->Resolve("/myStudyManager");
101   SALOMEDS::StudyManager_var myStudyManager =
102     SALOMEDS::StudyManager::_narrow(obj);
103   if(CORBA::is_nil(myStudyManager))
104     THROW_SALOME_CORBA_EXCEPTION("No StudyManager Found in NameService", \
105                                  SALOME::BAD_PARAM);
106   
107   SALOMEDS::Study_var myStudy =
108     myStudyManager->GetStudyByName(myStudyName.c_str());
109   if (CORBA::is_nil(myStudy))
110     THROW_SALOME_CORBA_EXCEPTION("Wrong Study Name", \
111                                  SALOME::BAD_PARAM);
112
113   return SALOMEDS::Study::_duplicate(myStudy) ;
114 }
115
116 //=============================================================================
117 /*!
118  *  private method : add Med component in Study (Not MedGen ???)
119  */
120 //=============================================================================
121
122 void Med_Gen_i::addInStudy(SALOMEDS::Study_var myStudy)
123   throw(SALOME::SALOME_Exception)
124 {
125   SALOMEDS::StudyBuilder_var  myBuilder = myStudy->NewBuilder();
126   
127   myBuilder->NewCommand();
128   
129   // Create SComponent labelled 'Med' if it doesn't already exit
130   SALOMEDS::SComponent_var medfather = myStudy->FindComponent("Med");
131   if ( CORBA::is_nil(medfather) )
132     {
133       // mpv: component label must be created in spite of "Locked" study flag state
134       bool aLocked = myStudy->GetProperties()->IsLocked();
135       if (aLocked) myStudy->GetProperties()->SetLocked(false);
136       
137       MESSAGE("Add Component Med");
138       medfather = myBuilder->NewComponent("Med");
139       SALOMEDS::GenericAttribute_var anAttr = myBuilder->FindOrCreateAttribute(medfather, "AttributeName");
140       SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
141       aName->SetValue("Med");
142       //            Utilisation de this  deconseillee par Paul ??
143       //            myBuilder->DefineComponentInstance(medfather,POA_Engines::Med_Gen::_this());
144       CORBA::Object_var myO = _poa->id_to_reference(*_id); // this ior...
145       myBuilder->DefineComponentInstance(medfather,myO);
146       
147       if (aLocked) myStudy->GetProperties()->SetLocked(true);
148     } 
149   
150   myBuilder->CommitCommand();
151    
152 }
153
154 //=============================================================================
155 /*!
156  * Lit tous les objets contenus dans un fichier med et les lit en memoire
157  */
158 //=============================================================================
159 SALOME_MED::MED_ptr Med_Gen_i::readStructFile (const char* fileName,
160                                 const char* studyName)
161   throw(SALOME::SALOME_Exception)
162 {
163         SCRUTE(fileName);
164         SALOMEDS::Study_var myStudy = studyName2Study(studyName) ;
165         if (!_duringLoad) addInStudy(myStudy) ;
166
167         SALOME_MED::MED_ptr myMedIOR ;
168         try 
169         {
170           // we create a new MED_i and add in study
171           MED_i * myMedI = new MED_i();
172           myMedIOR = myMedI->_this() ;
173           if (!_duringLoad) myMedI->addInStudy(myStudy,myMedIOR) ;        
174           // create ::MED object, read all and add in study !
175           myMedI->init(myStudy,MED_DRIVER,fileName) ;
176         }
177         catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
178         catch(...)
179         {
180                 MESSAGE("Erreur a la lecture du fichier");
181                 THROW_SALOME_CORBA_EXCEPTION("Unable to open File "\
182                                                 ,SALOME::BAD_PARAM);
183         }
184         return SALOME_MED::MED::_duplicate(myMedIOR) ;
185 }
186
187 //=============================================================================
188 /*!
189  *  Prepare un Maillage sans le lire en memoire avec stokage dans l'etude
190  *  des champs avec leur type
191  */
192 //=============================================================================
193 void Med_Gen_i::readStructFileWithFieldType (const char* fileName,
194                                              const char* studyName)
195 throw (SALOME::SALOME_Exception)
196 {
197   BEGIN_OF("Med_Gen_i::readStructFileWithFieldType (const char* fileName,const char* studyName)");
198
199         SCRUTE(fileName);
200         SALOMEDS::Study_var myStudy = studyName2Study(studyName) ;
201
202         if (!_duringLoad) addInStudy(myStudy) ;
203
204         try 
205         {
206           // we create a new MED_i and add in study
207           MED_i * myMedI = new MED_i();
208           SALOME_MED::MED_ptr myMedIOR = myMedI->_this() ;
209           if (!_duringLoad) myMedI->addInStudy(myStudy,myMedIOR) ;        
210           // create ::MED object, read all and add in study !
211           myMedI->initWithFieldType(myStudy,MED_DRIVER,fileName) ;
212         }
213         catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
214         catch(...)
215         {
216                 MESSAGE("Erreur a la lecture du fichier");
217                 THROW_SALOME_CORBA_EXCEPTION("Unable to open File "\
218                                                 ,SALOME::BAD_PARAM);
219         }
220
221         END_OF("Med_Gen_i::readStructFileWithFieldType (const char* fileName,const char* studyName)");
222
223
224 }
225
226 //=============================================================================
227 /*!
228  *  Sert un Maillage
229  */
230 //=============================================================================
231 SALOME_MED::MESH_ptr Med_Gen_i::readMeshInFile(const char* fileName,
232                                                const char* studyName,
233                                                const char* meshName)
234 throw (SALOME::SALOME_Exception)
235 {
236         SCRUTE(fileName);
237         SALOMEDS::Study_var myStudy = studyName2Study(studyName) ;
238
239         if (!_duringLoad) addInStudy(myStudy) ;
240
241 // Creation du maillage
242
243         MESH * myMesh= new MESH() ;
244         myMesh->setName(meshName);
245         MED_MESH_RDONLY_DRIVER myMeshDriver(fileName,myMesh);
246         try
247         {
248                 myMeshDriver.setMeshName(meshName);
249                 myMeshDriver.open();
250         }
251         catch (const exception & ex)
252         {
253                 MESSAGE("Exception Interceptee : ");
254                 SCRUTE(ex.what());
255                 THROW_SALOME_CORBA_EXCEPTION("Unable to find this mesh in this file",SALOME::BAD_PARAM);
256         };
257         try
258         {
259                 myMeshDriver.read();
260                 MESSAGE("apres read");
261                 myMeshDriver.close();
262         }
263         catch (const exception & ex)
264         {
265                 MESSAGE("Exception Interceptee : ");
266                 SCRUTE(ex.what());
267                 THROW_SALOME_CORBA_EXCEPTION("Unable to read this mesh in this file",SALOME::BAD_PARAM);
268         };
269
270         MESH_i * meshi = new MESH_i(myMesh);
271         //SALOME_MED::MESH_var mesh = SALOME_MED::MESH::_narrow(meshi->_this());
272         SALOME_MED::MESH_ptr mesh = meshi->_this();
273         try
274         {
275         // add the mesh object in study
276                 if (!_duringLoad) meshi->addInStudy(myStudy,mesh);
277         }
278         catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
279         return SALOME_MED::MESH::_duplicate(mesh);
280 }
281 //=============================================================================
282 /*!
283  *  Sert un Champ
284  */
285 //=============================================================================
286 SALOME_MED::FIELD_ptr Med_Gen_i::readFieldInFile(const char* fileName,
287                                                const char* studyName,
288                                                const char* fieldName,
289                                                CORBA::Long ordre,
290                                                CORBA::Long iter)
291 throw (SALOME::SALOME_Exception)
292 {
293         SCRUTE(fileName);
294         string myStudyName(studyName);
295
296         if (myStudyName.size() == 0)
297                 THROW_SALOME_CORBA_EXCEPTION("No Study Name given", \
298                                  SALOME::BAD_PARAM);
299
300         // Get StudyManager Reference, current study,
301         
302         CORBA::Object_var obj = _NS->Resolve("/myStudyManager");
303         SALOMEDS::StudyManager_var myStudyManager =
304                         SALOMEDS::StudyManager::_narrow(obj);
305         ASSERT(! CORBA::is_nil(myStudyManager));
306         SALOMEDS::Study_var myStudy =
307                 myStudyManager->GetStudyByName(myStudyName.c_str());
308         if (CORBA::is_nil(myStudy))
309         THROW_SALOME_CORBA_EXCEPTION("Wrong Study Name", \
310                                  SALOME::BAD_PARAM);
311
312         SALOMEDS::StudyBuilder_var myBuilder = myStudy->NewBuilder();
313         SALOMEDS::SComponent_var medfather = myStudy->FindComponent("Med");
314         if (CORBA::is_nil(medfather))
315         {
316                 myBuilder->NewCommand();
317                 // mpv: component label must be created in spite of "Locked" study flag state
318                 bool aLocked = myStudy->GetProperties()->IsLocked();
319                 if (aLocked) myStudy->GetProperties()->SetLocked(false);
320
321                 medfather = myBuilder->NewComponent("Med");
322                 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(
323                       myBuilder->FindOrCreateAttribute(medfather, "AttributeName"));
324                 aName->SetValue("Med");
325                 CORBA::Object_var myO = _poa->id_to_reference(*_id); // this ior...
326                 myBuilder->DefineComponentInstance(medfather,myO);
327
328                 if (aLocked) myStudy->GetProperties()->SetLocked(true);
329                 myBuilder->CommitCommand();
330
331         }
332         else
333                         MESSAGE("MED dejà dans l étude");
334
335         MESSAGE("Lecture du fichier ")
336         SCRUTE(fileName);
337
338 // Creation du champ
339
340         FIELD_ * myField= new FIELD_() ;
341         MED * mymed = new MED(MED_DRIVER,fileName) ;
342         try
343         {
344                 deque<string> fieldsNames = mymed->getFieldNames() ;
345                 int numberOfFields = fieldsNames.size();
346                 int i;
347                 for (i=0; i<numberOfFields; i++)
348                 {
349                         if (fieldsNames[i]== fieldName) break;
350                 }
351                 if (i == numberOfFields)
352                 {
353                         THROW_SALOME_CORBA_EXCEPTION("Unable to find this field ",SALOME::BAD_PARAM);
354                 }
355                 MESSAGE("trouve");
356 /*
357                 deque<DT_IT_> myIteration = mymed->getFieldIteration (fieldName);
358                 if (myIteration.size() != 1)
359                 {
360                         MESSAGE("WARNING : My iteration size is ")
361                         SCRUTE(myIteration.size());
362                 }
363 */
364                 myField = mymed->getField(fieldName,iter,ordre);
365         }
366         catch (const exception & ex)
367         {
368                 MESSAGE("Exception Interceptee : ");
369                 SCRUTE(ex.what());
370                 THROW_SALOME_CORBA_EXCEPTION("Unable to find this field in this file",SALOME::BAD_PARAM);
371         };
372                         
373         SUPPORT * fieldSupport;
374         SALOME_MED::SUPPORT_ptr mySupportIOR;
375         try
376         {
377                 fieldSupport=(SUPPORT *)myField->getSupport() ;
378                 ASSERT(fieldSupport != NULL);
379                 MESH * myMesh=(MESH *)fieldSupport->getMesh();
380                 ASSERT(myMesh != NULL);
381                 myMesh->read();
382                 SCRUTE(myMesh->getName());
383                 fieldSupport->update();
384                 SUPPORT_i * mySupportI = new SUPPORT_i(fieldSupport);
385                 mySupportIOR=mySupportI->_this();
386         }
387         catch (const exception & ex)
388         {
389                 MESSAGE("Exception Interceptee : ");
390                 SCRUTE(ex.what());
391                 THROW_SALOME_CORBA_EXCEPTION("Unable to find associated support",SALOME::BAD_PARAM);
392         };
393
394         med_type_champ type = myField->getValueType() ;
395         switch (type) 
396         {
397          case MED_FR::MED_INT32:        
398          {
399                 try 
400                 {
401                         ((FIELD<int>*)myField)->read() ;
402                         FIELDINT_i * myFieldIntI = new FIELDINT_i(mySupportIOR,(FIELD<int>*)myField);
403                         POA_SALOME_MED::FIELD_tie<FIELD_i> * myFieldTie = new POA_SALOME_MED::FIELD_tie<FIELD_i>(myFieldIntI);
404                         SALOME_MED::FIELD_ptr myFieldIOR = myFieldTie->_this() ;
405                         if (!_duringLoad) myFieldIntI->addInStudy(myStudy,myFieldIOR) ;
406                         return SALOME_MED::FIELD::_duplicate(myFieldIOR);
407                 }
408                 catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
409                 catch (const exception & ex)
410                 {
411                         MESSAGE("Exception Interceptee : ");
412                         SCRUTE(ex.what());
413                         THROW_SALOME_CORBA_EXCEPTION("Unable to read int field",SALOME::BAD_PARAM);
414                 };
415                 break;
416          }
417          case MED_FR::MED_REEL64: 
418          {
419                 try 
420                 {
421                         ((FIELD<double>*)myField)->read() ;
422                         FIELDDOUBLE_i * myFieldDoubleI = new FIELDDOUBLE_i(mySupportIOR,(FIELD<double>*)myField);
423                         POA_SALOME_MED::FIELD_tie<FIELD_i> * myFieldTie = new POA_SALOME_MED::FIELD_tie<FIELD_i>(myFieldDoubleI);
424                         SALOME_MED::FIELD_ptr myFieldIOR = myFieldTie->_this() ;
425                         if (!_duringLoad) myFieldDoubleI->addInStudy(myStudy,myFieldIOR) ;
426                         return SALOME_MED::FIELD::_duplicate(myFieldIOR);
427                 }
428                 catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
429                 catch (const exception & ex)
430                 {
431                         MESSAGE("Exception Interceptee : ");
432                         SCRUTE(ex.what());
433                         THROW_SALOME_CORBA_EXCEPTION("Unable to read double field",SALOME::BAD_PARAM);
434                 };
435                 break;
436          }
437         }
438
439         
440 }
441
442
443 //=============================================================================
444 /*!
445  *  Destructor
446  */
447 //=============================================================================
448
449 Med_Gen_i::~Med_Gen_i()
450 {
451   MESSAGE("Med_Gen_i::~Med_Gen_i");
452 }
453
454 //=============================================================================
455 /*!
456  *  CORBA: Save Mesh objects (called when a study is saved)
457  */
458 //=============================================================================
459 SALOMEDS::TMPFile* Med_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent,
460                                    const char* theURL,
461                                    bool isMultiFile) {
462   const char* LOC = "Med_Gen_i::Save";
463   BEGIN_OF(LOC);
464
465   SALOMEDS::TMPFile_var aStreamFile;
466   // Get a temporary directory to store a file
467   TCollection_AsciiString aTmpDir = (isMultiFile)?TCollection_AsciiString((char*)theURL):SALOMEDS_Tool::GetTmpDir();
468   // Create a list to store names of created files
469   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
470   TColStd_SequenceOfAsciiString aFileNames;
471
472   CORBA::String_var aSaveStudyName = strdup(SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL()));
473
474   SALOMEDS::SObject_var aMedMeshFather = theComponent->GetStudy()->FindObject("MEDMESH");
475   if (!CORBA::is_nil(aMedMeshFather)) {
476     SALOMEDS::ChildIterator_var anIter = theComponent->GetStudy()->NewChildIterator(aMedMeshFather);
477     for(; anIter->More(); anIter->Next()) {
478       SALOMEDS::SObject_var aSO = anIter->Value();
479       SALOMEDS::GenericAttribute_var anAttr;
480       if (aSO->FindAttribute(anAttr,"AttributeIOR")) {
481         CORBA::Object_var myIOR = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
482         SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
483         if (! CORBA::is_nil(myMesh)) {
484           TCollection_AsciiString aName(strdup(aSaveStudyName));
485           aName += "_MEDMESH_";
486           aName += myMesh->getName();
487           aName += ".med";
488           MESSAGE("Save mesh with name "<<aName.ToCString());
489           long driverId = myMesh->addDriver(SALOME_MED::MED_DRIVER,(aTmpDir+aName).ToCString(),myMesh->getName());
490           myMesh->write(driverId,"");
491           aFileNames.Append(aName);
492         }
493       }
494     }
495   }
496
497   SALOMEDS::SObject_var aMedFieldFather = theComponent->GetStudy()->FindObject("MEDFIELD");
498   if (!CORBA::is_nil(aMedFieldFather)) {
499     SALOMEDS::ChildIterator_var anIter = theComponent->GetStudy()->NewChildIterator(aMedFieldFather);
500     for(; anIter->More(); anIter->Next()) {
501       SALOMEDS::SObject_var aSO = anIter->Value();
502       SALOMEDS::GenericAttribute_var anAttr;
503       if (aSO->FindAttribute(anAttr,"AttributeIOR")) {
504         CORBA::Object_var myIOR = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
505         SALOME_MED::FIELD_var myField = SALOME_MED::FIELD::_narrow(myIOR);
506         if (! CORBA::is_nil(myField)) {
507           ostringstream a,b;
508           a<< myField->getOrderNumber();
509           b<< myField->getIterationNumber();
510
511           TCollection_AsciiString aName(strdup(aSaveStudyName));
512           aName += "_MEDFIELD_";
513           aName += myField->getName();
514           aName += "_ORDRE_";
515           aName += strdup(a.str().c_str());
516           aName += "_ITER_";
517           aName += strdup(b.str().c_str());
518           aName += ".med";
519           MESSAGE("Save mesh with name "<<aName.ToCString());
520           long driverId = myField->addDriver(SALOME_MED::MED_DRIVER,(aTmpDir+aName).ToCString(),myField->getName());
521           myField->write(driverId,"");
522           aFileNames.Append(aName);
523         }
524       }
525     }
526   }
527
528   int i;
529   aSeq->length(aFileNames.Length());
530   for(i = aFileNames.Length(); i > 0; i--) aSeq[i-1] = CORBA::string_dup(aFileNames.Value(i).ToCString());
531   // Conver a file to the byte stream
532   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.ToCString(), aSeq.in(), isMultiFile);
533   // Remove the created file and tmp directory
534   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.ToCString(), aSeq.in(), true);
535   // Return the created byte stream
536   return aStreamFile._retn();
537   
538   END_OF(LOC);
539 }
540
541 //=============================================================================
542 /*!
543  *  CORBA: Load Mesh objects (called when an existing study is opened)
544  */
545 //=============================================================================
546
547 CORBA::Boolean Med_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,
548                                const SALOMEDS::TMPFile& theStream,
549                                const char* theURL,
550                                bool isMultiFile) {
551   const char* LOC = "Med_Gen_i::Load";
552   BEGIN_OF(LOC);
553
554   // Get a temporary directory for a file
555   TCollection_AsciiString aTmpDir =
556     (isMultiFile)?TCollection_AsciiString((char*)theURL):SALOMEDS_Tool::GetTmpDir();
557   _saveFileName = CORBA::string_dup(aTmpDir.ToCString());
558   SALOMEDS::ListOfFileNames_var aSeq =
559     SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir.ToCString(), isMultiFile);
560   return true;
561
562   END_OF(LOC);
563 }
564
565 //=============================================================================
566 /*!
567  *  CORBA: 
568  */
569 //=============================================================================
570
571 void Med_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent)
572 {
573   MESSAGE("Med_Gen_i::Close");
574   SALOMEDS::SObject_var aMedMeshFather = theComponent->GetStudy()->FindObject("MEDMESH");
575   if (!CORBA::is_nil(aMedMeshFather)) {
576     SALOMEDS::ChildIterator_var anIter = theComponent->GetStudy()->NewChildIterator(aMedMeshFather);
577     for(; anIter->More(); anIter->Next()) {
578       SALOMEDS::SObject_var aSO = anIter->Value();
579       SALOMEDS::GenericAttribute_var anAttr;
580       if (aSO->FindAttribute(anAttr,"AttributeIOR")) {
581         CORBA::Object_var myIOR = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
582         SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
583         // here must call method destroy of myMesh, but it not implented yet
584       }
585     }
586   }
587 }
588
589 //=============================================================================
590 /*!
591  *  CORBA:
592  */
593 //=============================================================================
594
595 char* Med_Gen_i::ComponentDataType()
596 {
597   MESSAGE("Med_Gen_i::ComponentDataType");
598   return strdup("Med") ; /* What is this type ? */
599 }
600     
601 //=============================================================================
602 /*!
603  *  CORBA: give a persistent reference of a transient object (for study save) 
604  */
605 //=============================================================================
606
607 char* Med_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
608                                         const char* IORString,
609                                         CORBA::Boolean isMultiFile)
610 {
611   const char * LOC = "Med_Gen_i::IORToLocalPersistentID" ;
612   BEGIN_OF(LOC) ;
613   SCRUTE(IORString);
614
615   string aSaveStudyName(strdup(SALOMEDS_Tool::GetNameFromPath(theSObject->GetStudy()->URL())));
616   
617
618   if (string(IORString).size()==0) return strdup((aSaveStudyName+"_MED").c_str());
619   // Well, we know where put object (_saveFilename) and we know object (IORString)
620   // cast object :
621   CORBA::Object_var myIOR = _orb->string_to_object(IORString);
622
623   // MED
624   SALOME_MED::MED_var myMed = SALOME_MED::MED::_narrow(myIOR);
625   if (! CORBA::is_nil(myMed)) 
626   {
627         // nothing to save : Support will be saved inside the mesh
628         string str_MedName=aSaveStudyName + "_MED Objet Med + /OBJ_MED/";
629         return strdup(str_MedName.c_str()) ; 
630   }
631  
632   // MESH
633   SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
634   if (! CORBA::is_nil(myMesh)) 
635   {
636     CORBA::String_var aName((aSaveStudyName+"_MEDMESH_"+ myMesh->getName() + ".med").c_str());
637     return strdup(aName._retn()) ;
638   }
639     
640   // SUPPORT
641   SALOME_MED::SUPPORT_var mySupport = SALOME_MED::SUPPORT::_narrow(myIOR);
642   if (! CORBA::is_nil(mySupport)) 
643   {
644         // nothing to save : Support will be saved inside the mesh
645         string str_SupportName;
646         try
647         {
648                 str_SupportName=string("/FAS/")+string(mySupport->getName());
649                 str_SupportName+=string("/ENS_MAA/")+string(mySupport->getMesh()->getName());
650                 SCRUTE(str_SupportName);
651         }
652         catch(...)
653         {
654                 MESSAGE("Unable to save the support");
655                 THROW_SALOME_CORBA_EXCEPTION("Unable to save Field in Med"\
656                                               ,SALOME::INTERNAL_ERROR);
657         }
658     return strdup((aSaveStudyName+"_MED"+str_SupportName).c_str());
659   }
660     
661   SALOME_MED::FIELD_var myField = SALOME_MED::FIELD::_narrow(myIOR);
662   if (! CORBA::is_nil(myField)) 
663   {
664     string str_FieldName;
665     ostringstream a,b;
666     a<< myField->getOrderNumber();
667     b<< myField->getIterationNumber();
668     CORBA::String_var aName((aSaveStudyName+"_MEDFIELD_"+ myField->getName() +
669                              string("_ORDRE_")+a.str()+
670                              string("_ITER_")+b.str() +
671                              ".med").c_str());
672     return strdup(aName._retn());
673   }
674
675   //THROW_SALOME_CORBA_EXCEPTION("Unable to save IOR",SALOME::BAD_PARAM);
676   return strdup((aSaveStudyName+"_MED").c_str());
677
678   END_OF(LOC) ;
679 }
680
681 //=============================================================================
682 /*!
683  *  CORBA: give a transient reference (when loading an object, opening study)
684  */
685 //=============================================================================
686
687 char* Med_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
688                                         const char* aLocalPersistentID,
689                                         CORBA::Boolean isMultiFile)
690      throw(SALOME::SALOME_Exception)
691 {
692   const char * LOC = "Med_Gen_i::LocalPersistentIDToIOR" ;
693   BEGIN_OF(LOC) ;
694
695   TCollection_AsciiString aTmpDir(CORBA::string_dup(_saveFileName.c_str()));
696
697   string aSaveStudyName(strdup(SALOMEDS_Tool::GetNameFromPath(theSObject->GetStudy()->URL())));
698   int aStudyNameLen = strlen(aSaveStudyName.c_str());
699
700   if (strlen(aLocalPersistentID) <= aStudyNameLen) return strdup("");
701   if (strcmp(aLocalPersistentID, "Objet Med + /OBJ_MED/") == 0) return strdup(""); // MED
702
703   if (strncmp(&(aLocalPersistentID[aStudyNameLen]), "_MEDMESH_",13) == 0) {// MESH
704     MESH * myMesh= new MESH() ;
705     int aMeshNameLen = strlen(aLocalPersistentID) - 16 - aStudyNameLen;
706     char* aMeshName = new char[aMeshNameLen];
707     strncpy(aMeshName, &(aLocalPersistentID[aStudyNameLen + 13]), aMeshNameLen-1);
708     aMeshName[aMeshNameLen-1] = 0;
709     myMesh->setName(aMeshName);
710     MED_MESH_RDONLY_DRIVER myMeshDriver((aTmpDir + strdup(aLocalPersistentID)).ToCString(),myMesh);
711     try
712       {
713         myMeshDriver.setMeshName(aMeshName);
714         myMeshDriver.open();
715       }
716     catch (const exception & ex)
717       {
718         MESSAGE("Exception Interceptee : ");
719         SCRUTE(ex.what());
720         THROW_SALOME_CORBA_EXCEPTION("Unable to find this mesh in this file",SALOME::BAD_PARAM);
721       };
722     try
723       {
724         myMeshDriver.read();
725         MESSAGE("apres read");
726         myMeshDriver.close();
727       }
728     catch (const exception & ex)
729       {
730         MESSAGE("Exception Interceptee : ");
731         SCRUTE(ex.what());
732         THROW_SALOME_CORBA_EXCEPTION("Unable to read this mesh in this file",SALOME::BAD_PARAM);
733       }
734     MESH_i * meshi = new MESH_i(myMesh);
735     //SALOME_MED::MESH_var mesh = SALOME_MED::MESH::_narrow(meshi->_this());
736     SALOME_MED::MESH_ptr mesh = meshi->_this();
737     SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
738     aSeq->length(1);
739     aSeq[0]=CORBA::string_dup(aLocalPersistentID);
740     if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.ToCString(), aSeq.in(), true);
741     return(CORBA::string_dup(_orb->object_to_string(mesh)));
742   } else if (strncmp(&(aLocalPersistentID[aStudyNameLen]), "_MEDFIELD_",14) == 0) { // FIELD
743     return(strdup("")); // not implemented yet
744   }
745
746   return strdup("");
747
748   END_OF(LOC) ;
749 }
750
751 //=============================================================================
752 /*!
753  *  returns true, if can publish object
754  */
755 //=============================================================================
756 bool Med_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR) {
757   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(theIOR);
758   return !(aMesh->_is_nil());
759 }
760
761 //=============================================================================
762 /*!
763  *  publish the given object
764  */
765 //=============================================================================
766 SALOMEDS::SObject_ptr Med_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
767                                                 SALOMEDS::SObject_ptr theSObject,
768                                                 CORBA::Object_ptr theObject,
769                                                 const char* theName) throw (SALOME::SALOME_Exception)
770 {
771   SALOMEDS::SObject_var aResultSO;
772
773   if(CORBA::is_nil(theObject)) return aResultSO;
774   if(theStudy->_is_nil()) return aResultSO;
775
776   SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
777   SALOMEDS::GenericAttribute_var anAttr;
778   SALOMEDS::AttributeName_var    aName;
779   SALOMEDS::AttributeIOR_var     anIOR;
780   SALOMEDS::SComponent_var aFather = theStudy->FindComponent("Med");
781
782   if (aFather->_is_nil()) {
783     aFather = aBuilder->NewComponent("Med");
784     if (aFather->_is_nil()) return aResultSO;
785     anAttr = aBuilder->FindOrCreateAttribute(aFather, "AttributeName");
786     aName = SALOMEDS::AttributeName::_narrow(anAttr);
787     aName->SetValue("MED");
788     aBuilder->DefineComponentInstance(aFather, Med_Gen::_this());
789   }
790
791   if (CORBA::is_nil(theSObject)) {
792     SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(theObject);
793     aMesh->addInStudy(theStudy, aMesh);
794     SALOMEDS::SObject_var aResultSO = theStudy->FindObjectIOR(_orb->object_to_string(theObject));
795   } else {
796     if (!theSObject->ReferencedObject(aResultSO)) 
797       THROW_SALOME_CORBA_EXCEPTION("Publish in study MED object error",SALOME::BAD_PARAM);
798   }
799 //    aBuilder->Addreference(theObject, aResultSO);
800   return aResultSO._retn();
801 }
802
803 //=============================================================================
804 /*!
805  *  returns true, if can copy the object
806  */
807 //=============================================================================
808 CORBA::Boolean Med_Gen_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
809   // Try to retrieve known by MED component mesh by given IOR
810   SALOMEDS::GenericAttribute_var anAttr;
811   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
812   CORBA::Object_var anObj = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
813   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(anObj);
814   // If the object is null one it can't be copied: return false
815   if (aMesh->_is_nil()) return false;
816   return true;
817 }
818
819 //=============================================================================
820 /*!
821  *  create copy of the object and put it to the stream
822  */
823 //=============================================================================
824 SALOMEDS::TMPFile* Med_Gen_i::CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID) {
825     // Declare a sequence of the byte to store the copied object
826   SALOMEDS::TMPFile_var aStreamFile;
827
828   // Try to get GEOM_Shape object by given SObject
829   SALOMEDS::GenericAttribute_var anAttr;
830   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return new SALOMEDS::TMPFile(0);
831   CORBA::String_var anIOR = strdup(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
832   CORBA::Object_var anObj = _orb->string_to_object(anIOR);
833   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(anObj);
834   if (aMesh->_is_nil()) return new SALOMEDS::TMPFile(0);
835
836   // Get a temporary directory to store a temporary file
837   CORBA::String_var aTmpDir = SALOMEDS_Tool::GetTmpDir();
838   // Create a list to store names of created files
839   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
840   aSeq->length(1);
841   aSeq[0] = strdup(aMesh->getName());
842   char* aFullName = new char[strlen(aTmpDir)+strlen(aSeq[0])+1];
843   strcpy(aFullName, aTmpDir);
844   strcpy(aFullName+strlen(aTmpDir), aSeq[0]);
845   long driverId = aMesh->addDriver(SALOME_MED::MED_DRIVER,strdup(aFullName) , aMesh->getName());
846   aMesh->write(driverId,"");
847   delete(aFullName);
848   
849   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir, aSeq.in(), false);
850   SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir, aSeq.in(), true);
851   
852   // Assign an ID = 1 the the type SALOME_MED::MESH
853   theObjectID = 1;
854  
855   return aStreamFile._retn();
856 }
857
858 //=============================================================================
859 /*!
860  *  returns true, if can copy the object
861  */
862 //=============================================================================
863 CORBA::Boolean Med_Gen_i::CanPaste(const char* theComponentName, CORBA::Long theObjectID) {
864   // The MED component can paste only objects copied by MED component
865   // and with the object type = 1 (mesh)
866   if (strcmp(theComponentName, ComponentDataType()) != 0 || theObjectID != 1) return false;
867   return true;
868 }
869
870 //=============================================================================
871 /*!
872  *  returns true, if can copy the object
873  */
874 //=============================================================================
875 SALOMEDS::SObject_ptr Med_Gen_i::PasteInto(const SALOMEDS::TMPFile& theStream,
876                                            CORBA::Long theObjectID,
877                                            SALOMEDS::SObject_ptr theObject) {
878   SALOMEDS::SObject_var aResultSO = SALOMEDS::SObject::_duplicate(theObject);
879   if (theStream.length() == 0) return aResultSO._retn();
880   
881   SALOMEDS::Study_var aStudy = theObject->GetStudy();
882
883   CORBA::String_var aTmpDir = strdup(SALOMEDS_Tool::GetTmpDir());
884   SALOMEDS::ListOfFileNames_var aSeq = SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir, false);
885   CORBA::String_var aMeshName = strdup(aSeq[0]);
886   char* aFullName = new char[strlen(aTmpDir)+strlen(aMeshName)+1];
887   strcpy(aFullName, aTmpDir);
888   strcpy(aFullName+strlen(aTmpDir), aMeshName);
889
890   MESH * myMesh= new MESH() ;
891   myMesh->setName((char*)aMeshName);
892   MED_MESH_RDONLY_DRIVER myMeshDriver(aFullName, myMesh);
893   try {
894     myMeshDriver.setMeshName((char*)aMeshName);
895     myMeshDriver.open();
896   } catch (const exception & ex) {
897     MESSAGE("Exception Interceptee : ");
898     SCRUTE(ex.what());
899     delete(aFullName);
900     return aResultSO._retn();
901   };
902   try {
903     myMeshDriver.read();
904     ("apres read");
905     myMeshDriver.close();
906   } catch (const exception & ex) {
907     MESSAGE("Exception Interceptee : ");
908     SCRUTE(ex.what());
909     delete(aFullName);
910     return aResultSO._retn();
911   };
912   // set new mesh name, becouse now there are no possibility to operate meshes with the same names
913 //    srand((unsigned int)time(NULL));
914   int aRND = rand(); //Get a random number to present a name of a copied mesh
915   char aCopiedMeshName[20];
916   sprintf(aCopiedMeshName,"MESH_COPY_%d",aRND);
917   myMesh->setName(aCopiedMeshName);
918   MESH_i * meshi = new MESH_i(myMesh);
919   SALOME_MED::MESH_ptr mesh = meshi->_this();
920   // add the mesh object in study
921   meshi->addInStudy(aStudy,mesh);
922   // get the IOR attribute of just added mesh
923   CORBA::String_var anIORString = _orb->object_to_string(mesh);
924   aResultSO = aStudy->FindObjectIOR(anIORString);
925
926   SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir, aSeq.in(), true);
927   delete(aFullName);
928   return aResultSO._retn();
929 }
930
931
932
933
934
935
936 //=============================================================================
937 /*! 
938  * C factory, accessible with dlsym, after dlopen  
939  */
940 //=============================================================================
941
942 extern "C"
943 {
944   PortableServer::ObjectId * MEDEngine_factory(
945                                CORBA::ORB_ptr orb,
946                                PortableServer::POA_ptr poa, 
947                                PortableServer::ObjectId * contId,
948                                const char *instanceName, 
949                                const char *interfaceName)
950   {
951     MESSAGE("PortableServer::ObjectId * MedEngine_factory()");
952     SCRUTE(interfaceName);
953     Med_Gen_i * myMed_Gen 
954       = new Med_Gen_i(orb, poa, contId, instanceName, interfaceName);
955     return myMed_Gen->getId() ;
956   }
957 }