Salome HOME
2806e40eb2664005d7a65075f84abdf7b26db25b
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_Gen_i.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 #include <TopExp.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopoDS.hxx>
32 #include <TopoDS_Iterator.hxx>
33 #include <TopoDS_Compound.hxx>
34 #include <TopoDS_CompSolid.hxx>
35 #include <TopoDS_Solid.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Face.hxx>
38 #include <TopoDS_Wire.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Vertex.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopTools_MapOfShape.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
44 #include <gp_Pnt.hxx>
45 #include <BRep_Tool.hxx>
46 #include <TCollection_AsciiString.hxx>
47
48 #include "Utils_CorbaException.hxx"
49
50 #include "utilities.h"
51 #include <fstream>
52 #include <stdio.h>
53 #include <dlfcn.h>
54
55 #include <HDFOI.hxx>
56
57 #include "SMESH_Gen_i.hxx"
58 #include "SMESH_Mesh_i.hxx"
59 #include "SMESH_Hypothesis_i.hxx"
60 #include "SMESH_Algo_i.hxx"
61 #include "SMESH_Group_i.hxx"
62
63 #include "SMESHDS_Document.hxx"
64 #include "SMESHDS_Group.hxx"
65 #include "SMESHDS_GroupOnGeom.hxx"
66 #include "SMESH_Group.hxx"
67
68 #include "SMDS_EdgePosition.hxx"
69 #include "SMDS_FacePosition.hxx"
70
71 #include CORBA_SERVER_HEADER(SMESH_Group)
72 #include CORBA_SERVER_HEADER(SMESH_Filter)
73
74 #include "DriverMED_W_SMESHDS_Mesh.h"
75 #include "DriverMED_R_SMESHDS_Mesh.h"
76
77 #include "SALOMEDS_Tool.hxx"
78 #include "SALOME_NamingService.hxx"
79 #include "SALOME_LifeCycleCORBA.hxx"
80 #include "Utils_SINGLETON.hxx"
81 #include "OpUtil.hxx"
82
83 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
84
85 #include "GEOM_Client.hxx"
86 #include "Utils_ExceptHandlers.hxx"
87
88 #include <map>
89 #include <boost/filesystem/path.hpp>
90
91 using namespace std;
92
93 #define NUM_TMP_FILES 2
94
95 #ifdef _DEBUG_
96 static int MYDEBUG = 1;
97 #else
98 static int MYDEBUG = 0;
99 #endif
100
101 // Static variables definition
102 CORBA::ORB_var          SMESH_Gen_i::myOrb;
103 PortableServer::POA_var SMESH_Gen_i::myPoa;
104 SALOME_NamingService*   SMESH_Gen_i::myNS  = NULL;
105 SALOME_LifeCycleCORBA*  SMESH_Gen_i::myLCC = NULL;
106 SMESH_Gen_i*            SMESH_Gen_i::mySMESHGen = NULL;
107
108 //=============================================================================
109 /*!
110  *  GetServant [ static ]
111  *
112  *  Get servant of the CORBA object
113  */
114 //=============================================================================
115
116 PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theObject )
117 {
118   if( CORBA::is_nil( theObject ) || CORBA::is_nil( GetPOA() ) )
119     return NULL;
120   try {
121     PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject );
122     return aServant;
123   } 
124   catch (...) {
125     INFOS( "GetServant - Unknown exception was caught!!!" ); 
126     return NULL;
127   }
128 }
129
130 //=============================================================================
131 /*!
132  *  SObjectToObject [ static ]
133  *
134  *  Get CORBA object corresponding to the SALOMEDS::SObject
135  */
136 //=============================================================================
137
138 CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject )
139 {
140   SALOMEDS::GenericAttribute_var anAttr;
141   CORBA::Object_var anObj;
142   if ( !theSObject->_is_nil() ) {
143     try {
144       if( theSObject->FindAttribute( anAttr, "AttributeIOR" ) ) {
145         SALOMEDS::AttributeIOR_var anIOR  = SALOMEDS::AttributeIOR::_narrow( anAttr );
146         CORBA::String_var aValue = anIOR->Value();
147         if( strcmp( aValue, "" ) != 0 )
148           anObj = GetORB()->string_to_object( aValue );
149         }
150     }
151     catch( ... ) {
152       INFOS( "SObjectToObject - Unknown exception was caught!!!" );
153     }
154   }
155   return anObj;
156 }
157
158 //=============================================================================
159 /*!
160  *  GetNS [ static ]
161  *
162  *  Get SALOME_NamingService object 
163  */
164 //=============================================================================
165
166 SALOME_NamingService* SMESH_Gen_i::GetNS()
167 {
168   if ( myNS == NULL ) {
169     myNS = SINGLETON_<SALOME_NamingService>::Instance();
170     ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting());
171     myNS->init_orb( GetORB() );
172   }
173   return myNS;
174 }
175
176 //=============================================================================
177 /*!
178  *  GetLCC [ static ]
179  *
180  *  Get SALOME_LifeCycleCORBA object
181  */
182 //=============================================================================     
183 SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
184   if ( myLCC == NULL ) {
185     myLCC = new SALOME_LifeCycleCORBA( GetNS() );
186   }
187   return myLCC;
188 }
189
190
191 //=============================================================================
192 /*!
193  *  GetGeomEngine [ static ]
194  *
195  *  Get GEOM::GEOM_Gen reference
196  */
197 //=============================================================================     
198 GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() {
199   GEOM::GEOM_Gen_var aGeomEngine =
200     GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") );
201   return aGeomEngine._retn();
202 }
203
204 //=============================================================================
205 /*!
206  *  SMESH_Gen_i::SMESH_Gen_i
207  *
208  *  Default constructor: not for use
209  */
210 //=============================================================================
211
212 SMESH_Gen_i::SMESH_Gen_i()
213 {
214   INFOS( "SMESH_Gen_i::SMESH_Gen_i : default constructor" );
215 }
216
217 //=============================================================================
218 /*!
219  *  SMESH_Gen_i::SMESH_Gen_i 
220  *
221  *  Standard constructor, used with Container
222  */
223 //=============================================================================
224
225 SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
226                           PortableServer::POA_ptr   poa,
227                           PortableServer::ObjectId* contId, 
228                           const char*               instanceName, 
229                           const char*               interfaceName )
230      : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
231 {
232   INFOS( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
233
234   myOrb = CORBA::ORB::_duplicate(orb);
235   myPoa = PortableServer::POA::_duplicate(poa);
236   
237   _thisObj = this ;
238   _id = myPoa->activate_object( _thisObj );
239   
240   myShapeReader = NULL;  // shape reader
241   mySMESHGen = this;
242 }
243
244 //=============================================================================
245 /*!
246  *  SMESH_Gen_i::~SMESH_Gen_i
247  *
248  *  Destructor
249  */
250 //=============================================================================
251
252 SMESH_Gen_i::~SMESH_Gen_i()
253 {
254   INFOS( "SMESH_Gen_i::~SMESH_Gen_i" );
255
256   // delete hypothesis creators
257   map<string, GenericHypothesisCreator_i*>::iterator itHyp;
258   for (itHyp = myHypCreatorMap.begin(); itHyp != myHypCreatorMap.end(); itHyp++)
259   {
260     delete (*itHyp).second;
261   }
262   myHypCreatorMap.clear();
263
264   // Clear study contexts data
265   map<int, StudyContext*>::iterator it;
266   for ( it = myStudyContextMap.begin(); it != myStudyContextMap.end(); ++it ) {
267     delete it->second;
268   }
269   myStudyContextMap.clear();
270   // delete shape reader
271   if ( !myShapeReader ) 
272     delete myShapeReader;
273 }
274   
275 //=============================================================================
276 /*!
277  *  SMESH_Gen_i::createHypothesis
278  *
279  *  Create hypothesis of given type
280  */
281 //=============================================================================
282 SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName,
283                                                           const char* theLibName)
284      throw (SALOME::SALOME_Exception)
285 {
286   Unexpect aCatch(SALOME_SalomeException);
287   if(MYDEBUG) MESSAGE( "Create Hypothesis <" << theHypName << "> from " << theLibName);
288
289   // create a new hypothesis object servant
290   SMESH_Hypothesis_i* myHypothesis_i = 0;
291   SMESH::SMESH_Hypothesis_var hypothesis_i;
292
293   try
294   {
295     // check, if creator for this hypothesis type already exists
296     if (myHypCreatorMap.find(string(theHypName)) == myHypCreatorMap.end())
297     {
298       // load plugin library
299       if(MYDEBUG) MESSAGE("Loading server meshers plugin library ...");
300       void* libHandle = dlopen (theLibName, RTLD_LAZY);
301       if (!libHandle)
302       {
303         // report any error, if occured
304         const char* anError = dlerror();
305         throw(SALOME_Exception(anError));
306       }
307
308       // get method, returning hypothesis creator
309       if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
310       typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char* theHypName);
311       GetHypothesisCreator procHandle =
312         (GetHypothesisCreator)dlsym( libHandle, "GetHypothesisCreator" );
313       if (!procHandle)
314       {
315         throw(SALOME_Exception(LOCALIZED("bad hypothesis plugin library")));
316         dlclose(libHandle);
317       }
318
319       // get hypothesis creator
320       if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << theHypName);
321       GenericHypothesisCreator_i* aCreator = procHandle(theHypName);
322       if (!aCreator)
323       {
324         throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin")));
325       }
326
327       // map hypothesis creator to a hypothesis name
328       myHypCreatorMap[string(theHypName)] = aCreator;
329     }
330
331     // create a new hypothesis object, store its ref. in studyContext
332     if(MYDEBUG) MESSAGE("Create Hypothesis " << theHypName);
333     myHypothesis_i =
334       myHypCreatorMap[string(theHypName)]->Create (myPoa, GetCurrentStudyID(), &myGen);
335     // _CS_gbo Explicit activation (no longer made in the constructor).
336     myHypothesis_i->Activate();
337     myHypothesis_i->SetLibName(theLibName); // for persistency assurance
338   }
339   catch (SALOME_Exception& S_ex)
340   {
341     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
342   }
343
344   if (!myHypothesis_i)
345     return hypothesis_i._retn();
346
347   // activate the CORBA servant of hypothesis
348   hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() );
349   int nextId = RegisterObject( hypothesis_i );
350   if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId );
351
352   return hypothesis_i._retn();
353 }
354   
355 //=============================================================================
356 /*!
357  *  SMESH_Gen_i::createMesh
358  *
359  *  Create empty mesh on shape
360  */
361 //=============================================================================
362 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
363      throw ( SALOME::SALOME_Exception )
364 {
365   Unexpect aCatch(SALOME_SalomeException);
366   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::createMesh" );
367
368   // Get or create the GEOM_Client instance
369   try {
370     // create a new mesh object servant, store it in a map in study context
371     SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() );
372     // create a new mesh object
373     meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID() ));
374
375     // activate the CORBA servant of Mesh
376     SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() );
377     int nextId = RegisterObject( mesh );
378     if(MYDEBUG) MESSAGE( "Add mesh to map with id = "<< nextId);
379     return mesh._retn();
380   }
381   catch (SALOME_Exception& S_ex) {
382     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
383   }
384   return SMESH::SMESH_Mesh::_nil();
385 }
386
387 //=============================================================================
388 /*!
389  *  SMESH_Gen_i::GetShapeReader
390  *
391  *  Get shape reader
392  */
393 //=============================================================================
394 GEOM_Client* SMESH_Gen_i::GetShapeReader()
395 {
396   // create shape reader if necessary
397   if ( !myShapeReader ) 
398     myShapeReader = new GEOM_Client(GetContainerRef());
399   ASSERT( myShapeReader );
400   return myShapeReader;
401 }
402
403 //=============================================================================
404 /*!
405  *  SMESH_Gen_i::SetCurrentStudy
406  *
407  *  Set current study
408  */
409 //=============================================================================
410
411 void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy )
412 {
413   //if(MYDEBUG)
414     MESSAGE( "SMESH_Gen_i::SetCurrentStudy" );
415   myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy );
416   // create study context, if it doesn't exist and set current study
417   int studyId = GetCurrentStudyID();
418   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SetCurrentStudy: study Id = " << studyId );
419   if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) {
420     myStudyContextMap[ studyId ] = new StudyContext;      
421   }
422
423   SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); 
424   if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
425     aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() );
426
427   // set current study for geom engine
428   //if ( !CORBA::is_nil( GetGeomEngine() ) )
429   //  GetGeomEngine()->GetCurrentStudy( myCurrentStudy->StudyId() );
430 }
431
432 //=============================================================================
433 /*!
434  *  SMESH_Gen_i::GetCurrentStudy
435  *
436  *  Get current study
437  */
438 //=============================================================================
439
440 SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy()
441 {
442   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetCurrentStudy: study Id = " << GetCurrentStudyID() );
443   return SALOMEDS::Study::_duplicate( myCurrentStudy );
444 }
445
446 //=============================================================================
447 /*!
448  *  SMESH_Gen_i::GetCurrentStudyContext 
449  *
450  *  Get current study context
451  */
452 //=============================================================================
453 StudyContext* SMESH_Gen_i::GetCurrentStudyContext()
454 {
455   if ( !CORBA::is_nil( myCurrentStudy ) &&
456       myStudyContextMap.find( GetCurrentStudyID() ) != myStudyContextMap.end() )
457     return myStudyContextMap[ myCurrentStudy->StudyId() ];
458   else
459     return 0;
460 }
461
462 //=============================================================================
463 /*!
464  *  SMESH_Gen_i::CreateHypothesis 
465  *
466  *  Create hypothesis/algorothm of given type and publish it in the study
467  */
468 //=============================================================================
469
470 SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypName,
471                                                            const char* theLibName )
472      throw ( SALOME::SALOME_Exception )
473 {
474   Unexpect aCatch(SALOME_SalomeException);
475   // Create hypothesis/algorithm
476   SMESH::SMESH_Hypothesis_var hyp = this->createHypothesis( theHypName, theLibName );
477
478   // Publish hypothesis/algorithm in the study
479   if ( CanPublishInStudy( hyp ) ) {
480     SALOMEDS::SObject_var aSO = PublishHypothesis( myCurrentStudy, hyp );
481     if ( !aSO->_is_nil() ) {
482       // Update Python script
483       TCollection_AsciiString aStr (aSO->GetID());
484       aStr += " = smesh.CreateHypothesis(\"";
485       aStr += Standard_CString(theHypName);
486       aStr += "\", \"";
487       aStr += Standard_CString(theLibName);
488       aStr += "\")";
489
490       AddToCurrentPyScript(aStr);
491     }
492   }
493
494   return hyp._retn();
495 }
496
497 //=============================================================================
498 /*!
499  *  SMESH_Gen_i::CreateMesh
500  *
501  *  Create empty mesh on a shape and publish it in the study
502  */
503 //=============================================================================
504
505 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObject )
506      throw ( SALOME::SALOME_Exception )
507 {
508   Unexpect aCatch(SALOME_SalomeException);
509   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
510   // create mesh
511   SMESH::SMESH_Mesh_var mesh = this->createMesh();
512   // set shape
513   SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
514   ASSERT( meshServant );
515   meshServant->SetShape( theShapeObject );
516
517   // publish mesh in the study
518   if ( CanPublishInStudy( mesh ) ) {
519     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
520     aStudyBuilder->NewCommand();  // There is a transaction
521     SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() );
522     aStudyBuilder->CommitCommand();
523     if ( !aSO->_is_nil() ) {
524       // Update Python script
525       TCollection_AsciiString aStr (aSO->GetID());
526       aStr += " = smesh.CreateMesh(";
527       SMESH_Gen_i::AddObject(aStr, theShapeObject) += ")";
528       
529       AddToCurrentPyScript(aStr);
530     }
531   }
532
533   return mesh._retn();
534 }
535
536 //=============================================================================
537 /*!
538  *  SMESH_Gen_i::CreateMeshFromUNV
539  *
540  *  Create mesh and import data from UNV file
541  */
542 //=============================================================================
543
544 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName )
545   throw ( SALOME::SALOME_Exception )
546 {
547   Unexpect aCatch(SALOME_SalomeException);
548   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromUNV" );
549
550   SMESH::SMESH_Mesh_var aMesh = createMesh();
551   string aFileName; // = boost::filesystem::path(theFileName).leaf();
552   // publish mesh in the study
553   if ( CanPublishInStudy( aMesh ) ) {
554     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
555     aStudyBuilder->NewCommand();  // There is a transaction
556     SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() );
557     aStudyBuilder->CommitCommand();
558     if ( !aSO->_is_nil() ) {
559       // Update Python script
560       TCollection_AsciiString aStr (aSO->GetID());
561       aStr += " = smesh.CreateMeshesFromUNV(\"";
562       aStr += Standard_CString(theFileName);
563       aStr += "\")";
564
565       AddToCurrentPyScript(aStr);
566     }
567   }
568
569   SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
570   ASSERT( aServant );
571   aServant->ImportUNVFile( theFileName );
572   return aMesh._retn();
573 }
574
575 //=============================================================================
576 /*!
577  *  SMESH_Gen_i::CreateMeshFromMED
578  *
579  *  Create mesh and import data from MED file
580  */
581 //=============================================================================
582
583 SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
584                                                      SMESH::DriverMED_ReadStatus& theStatus)
585      throw ( SALOME::SALOME_Exception )
586 {
587   Unexpect aCatch(SALOME_SalomeException);
588   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
589
590   // Python Dump
591   TCollection_AsciiString aStr ("([");
592
593   // Retrieve mesh names from the file
594   DriverMED_R_SMESHDS_Mesh myReader;
595   myReader.SetFile( theFileName );
596   myReader.SetMeshId( -1 );
597   Driver_Mesh::Status aStatus;
598   list<string> aNames = myReader.GetMeshNames(aStatus);
599   SMESH::mesh_array_var aResult = new SMESH::mesh_array();
600   theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
601   if (theStatus == SMESH::DRS_OK) {
602     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
603     aStudyBuilder->NewCommand();  // There is a transaction
604     aResult->length( aNames.size() );
605     int i = 0;
606     
607     // Iterate through all meshes and create mesh objects
608     for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ ) {
609       // Python Dump
610       if (i > 0) aStr += ", ";
611
612       // create mesh
613       SMESH::SMESH_Mesh_var mesh = createMesh();
614       
615       // publish mesh in the study
616       SALOMEDS::SObject_var aSO;
617       if ( CanPublishInStudy( mesh ) )
618         aSO = PublishMesh( myCurrentStudy, mesh.in(), (*it).c_str() );
619       if ( !aSO->_is_nil() ) {
620         // Python Dump
621         aStr += aSO->GetID();
622       } else {
623         // Python Dump
624         aStr += "mesh_";
625         aStr += TCollection_AsciiString(i);
626       }
627
628       // Read mesh data (groups are published automatically by ImportMEDFile())
629       SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
630       ASSERT( meshServant );
631       SMESH::DriverMED_ReadStatus status1 =
632         meshServant->ImportMEDFile( theFileName, (*it).c_str() );
633       if (status1 > theStatus)
634         theStatus = status1;
635
636       aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
637     }
638     aStudyBuilder->CommitCommand();
639   }
640
641   // Update Python script
642   aStr += "], status) = smesh.CreateMeshesFromMED(\"";
643   aStr += Standard_CString(theFileName);
644   aStr += "\")";
645
646   AddToCurrentPyScript(aStr);
647
648   return aResult._retn();
649 }
650
651 //=============================================================================
652 /*!
653  *  SMESH_Gen_i::CreateMeshFromSTL
654  *
655  *  Create mesh and import data from STL file
656  */
657 //=============================================================================
658
659 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName )
660   throw ( SALOME::SALOME_Exception )
661 {
662   Unexpect aCatch(SALOME_SalomeException);
663   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromSTL" );
664
665   SMESH::SMESH_Mesh_var aMesh = createMesh();
666   string aFileName; // = boost::filesystem::path(theFileName).leaf();
667   // publish mesh in the study
668   if ( CanPublishInStudy( aMesh ) ) {
669     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
670     aStudyBuilder->NewCommand();  // There is a transaction
671     SALOMEDS::SObject_var aSO = PublishInStudy
672       ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
673     aStudyBuilder->CommitCommand();
674     if ( !aSO->_is_nil() ) {
675     // Update Python script
676       TCollection_AsciiString aStr (aSO->GetID());
677       aStr += " = smesh.CreateMeshesFromSTL(\"";
678       aStr += Standard_CString(theFileName);
679       aStr += "\")";
680
681       AddToCurrentPyScript(aStr);
682     }
683   }
684
685   SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
686   ASSERT( aServant );
687   aServant->ImportSTLFile( theFileName );
688   return aMesh._retn();
689 }
690
691 //=============================================================================
692 /*!
693  *  SMESH_Gen_i::IsReadyToCompute
694  *
695  *  Returns true if mesh contains enough data to be computed
696  */
697 //=============================================================================
698
699 CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
700                                               GEOM::GEOM_Object_ptr theShapeObject )
701   throw ( SALOME::SALOME_Exception )
702 {
703   Unexpect aCatch(SALOME_SalomeException);
704   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" );
705
706   if ( CORBA::is_nil( theShapeObject ) )
707     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
708                                   SALOME::BAD_PARAM );
709
710   if ( CORBA::is_nil( theMesh ) )
711     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
712                                   SALOME::BAD_PARAM );
713
714   try {
715     // get mesh servant
716     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
717     ASSERT( meshServant );
718     if ( meshServant ) {
719       // get local TopoDS_Shape
720       TopoDS_Shape myLocShape = GeomObjectToShape( theShapeObject );
721       // call implementation
722       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
723       return myGen.CheckAlgoState( myLocMesh, myLocShape );
724     }
725   }
726   catch ( SALOME_Exception& S_ex ) {
727     INFOS( "catch exception "<< S_ex.what() );
728   }
729   return false;
730 }
731
732 //================================================================================
733 /*!
734  * \brief Returns errors of hypotheses definintion
735   * \param theMesh - the mesh
736   * \param theSubObject - the main or sub- shape
737   * \retval SMESH::algo_error_array* - sequence of errors
738  */
739 //================================================================================
740
741 SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, 
742                                                     GEOM::GEOM_Object_ptr theSubObject )
743       throw ( SALOME::SALOME_Exception )
744 {
745   Unexpect aCatch(SALOME_SalomeException);
746   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetAlgoState()" );
747
748   if ( CORBA::is_nil( theSubObject ) )
749     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
750
751   if ( CORBA::is_nil( theMesh ) )
752     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
753
754   SMESH::algo_error_array_var error_array = new SMESH::algo_error_array;
755   try {
756     SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
757     ASSERT( meshServant );
758     if ( meshServant ) {
759       TopoDS_Shape myLocShape = GeomObjectToShape( theSubObject );
760       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
761       list< ::SMESH_Gen::TAlgoStateError > error_list;
762       list< ::SMESH_Gen::TAlgoStateError >::iterator error;
763       // call ::SMESH_Gen::GetAlgoState()
764       myGen.GetAlgoState( myLocMesh, myLocShape, error_list );
765       error_array->length( error_list.size() );
766       int i = 0;
767       for ( error = error_list.begin(); error != error_list.end(); ++error )
768       {
769         // error name
770         SMESH::AlgoStateErrorName errName;
771         switch ( error->_name ) {
772         case ::SMESH_Gen::MISSING_ALGO:     errName = SMESH::MISSING_ALGO; break;
773         case ::SMESH_Gen::MISSING_HYPO:     errName = SMESH::MISSING_HYPO; break;
774         case ::SMESH_Gen::NOT_CONFORM_MESH: errName = SMESH::NOT_CONFORM_MESH; break;
775         default:
776           THROW_SALOME_CORBA_EXCEPTION( "bad error name",SALOME::BAD_PARAM );
777         }
778         // algo name
779         CORBA::String_var algoName;
780         if ( error->_algo ) {
781           if ( !myCurrentStudy->_is_nil() ) {
782             // find algo in the study
783             SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow
784               ( myCurrentStudy->FindComponent( ComponentDataType() ) );
785             if ( !father->_is_nil() ) {
786               SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father );
787               for ( ; itBig->More(); itBig->Next() ) {
788                 SALOMEDS::SObject_var gotBranch = itBig->Value();
789                 if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
790                   SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch );
791                   for ( ; algoIt->More(); algoIt->Next() ) {
792                     SALOMEDS::SObject_var algoSO = algoIt->Value();
793                     CORBA::Object_var    algoIOR = SObjectToObject( algoSO );
794                     if ( !CORBA::is_nil( algoIOR )) {
795                       SMESH_Hypothesis_i* myImpl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
796                       if ( myImpl && myImpl->GetImpl() == error->_algo ) {
797                         algoName = algoSO->GetName();
798                         break;
799                       }
800                     }
801                   } // loop on algo SO's
802                   break;
803                 } // if algo tag
804               } // SMESH component iterator
805             }
806           }
807           if ( algoName.in() == 0 )
808             // use algo type name
809             algoName = CORBA::string_dup( error->_algo->GetName() );
810         }
811         // fill AlgoStateError structure
812         SMESH::AlgoStateError & errStruct = error_array[ i++ ];
813         errStruct.name         = errName;
814         errStruct.algoName     = algoName;
815         errStruct.algoDim      = error->_algoDim;
816         errStruct.isGlobalAlgo = error->_isGlobalAlgo;
817       }
818     }
819   }
820   catch ( SALOME_Exception& S_ex ) {
821     INFOS( "catch exception "<< S_ex.what() );
822   }
823   return error_array._retn();
824 }
825
826 //=============================================================================
827 /*!
828  *  SMESH_Gen_i::GetSubShapesId
829  *
830  *  Get sub-shapes unique ID's list
831  */
832 //=============================================================================
833
834 SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject,
835                                             const SMESH::object_array& theListOfSubShapeObject )
836      throw ( SALOME::SALOME_Exception )
837 {
838   Unexpect aCatch(SALOME_SalomeException);
839   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetSubShapesId" );
840
841   SMESH::long_array_var shapesId = new SMESH::long_array;
842   set<int> setId;
843
844   if ( CORBA::is_nil( theMainShapeObject ) )
845     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
846                                   SALOME::BAD_PARAM );
847
848   try
849     {
850       TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject);
851       TopTools_IndexedMapOfShape myIndexToShape;      
852       TopExp::MapShapes(myMainShape,myIndexToShape);
853
854       for ( int i = 0; i < theListOfSubShapeObject.length(); i++ )
855         {
856           GEOM::GEOM_Object_var aShapeObject
857             = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]);
858           if ( CORBA::is_nil( aShapeObject ) )
859             THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \
860                                         SALOME::BAD_PARAM );
861
862           TopoDS_Shape locShape  = GeomObjectToShape(aShapeObject);
863           for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next())
864             {
865               const TopoDS_Face& F = TopoDS::Face(exp.Current());
866               setId.insert(myIndexToShape.FindIndex(F));
867               if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(F));
868             }
869           for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next())
870             {
871               const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
872               setId.insert(myIndexToShape.FindIndex(E));
873               if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(E));
874             }
875           for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next())
876             {
877               const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
878               setId.insert(myIndexToShape.FindIndex(V));
879               if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V));
880             }
881         }
882       shapesId->length(setId.size());
883       set<int>::iterator iind;
884       int i=0;
885       for (iind = setId.begin(); iind != setId.end(); iind++)
886         {
887           if(MYDEBUG) SCRUTE((*iind));
888           shapesId[i] = (*iind);
889           if(MYDEBUG) SCRUTE(shapesId[i]);
890           i++;
891         }
892     }
893   catch (SALOME_Exception& S_ex)
894     {
895       THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
896     }
897
898   return shapesId._retn();
899 }
900
901 //=============================================================================
902 /*!
903  *  SMESH_Gen_i::Compute
904  *
905  *  Compute mesh on a shape
906  */
907 //=============================================================================
908
909 CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
910                                      GEOM::GEOM_Object_ptr theShapeObject )
911      throw ( SALOME::SALOME_Exception )
912 {
913   Unexpect aCatch(SALOME_SalomeException);
914   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" );
915
916   if ( CORBA::is_nil( theShapeObject ) )
917     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
918                                   SALOME::BAD_PARAM );
919
920   if ( CORBA::is_nil( theMesh ) )
921     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
922                                   SALOME::BAD_PARAM );
923
924   // Update Python script
925   TCollection_AsciiString aStr ("isDone = smesh.Compute(");
926   SMESH_Gen_i::AddObject(aStr, theMesh) += ", ";
927   SMESH_Gen_i::AddObject(aStr, theShapeObject) += ")";
928
929   AddToCurrentPyScript(aStr);
930
931   aStr = "if isDone == 0: print \"Mesh ";
932   SMESH_Gen_i::AddObject(aStr, theMesh) += " computation failed\"";
933   AddToCurrentPyScript(aStr);
934
935   try {
936     // get mesh servant
937     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
938     ASSERT( meshServant );
939     if ( meshServant ) {
940       // get local TopoDS_Shape
941       TopoDS_Shape myLocShape = GeomObjectToShape( theShapeObject );
942       // call implementation compute
943       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
944       return myGen.Compute( myLocMesh, myLocShape);
945     }
946   }
947   catch ( SALOME_Exception& S_ex ) {
948     INFOS( "Compute(): catch exception "<< S_ex.what() );
949   }
950   catch ( ... ) {
951     INFOS( "Compute(): unknown exception " );
952   }
953   return false;
954 }
955
956 //=============================================================================
957 /*!
958  *  SMESH_Gen_i::Save
959  *
960  *  Save SMESH module's data
961  */
962 //=============================================================================
963 SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
964                                       const char*              theURL,
965                                       bool                     isMultiFile )
966 {
967   INFOS( "SMESH_Gen_i::Save" );
968
969 //  ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
970   // san -- in case <myCurrentStudy> differs from theComponent's study,
971   // use that of the component
972   if ( myCurrentStudy->_is_nil() || 
973        theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
974     SetCurrentStudy( theComponent->GetStudy() );
975
976   // Store study contents as a set of python commands
977   SavePython(myCurrentStudy);
978
979   StudyContext* myStudyContext = GetCurrentStudyContext();
980   
981   // Declare a byte stream
982   SALOMEDS::TMPFile_var aStreamFile;
983   
984   // Obtain a temporary dir
985   TCollection_AsciiString tmpDir =
986     ( isMultiFile ) ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str();
987
988   // Create a sequence of files processed
989   SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames;
990   aFileSeq->length( NUM_TMP_FILES );
991
992   TCollection_AsciiString aStudyName( "" );
993   if ( isMultiFile ) 
994     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
995
996   // Set names of temporary files
997   TCollection_AsciiString filename =
998     aStudyName + TCollection_AsciiString( "_SMESH.hdf" );        // for SMESH data itself
999   TCollection_AsciiString meshfile =
1000     aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" );   // for mesh data to be stored in MED file
1001   aFileSeq[ 0 ] = CORBA::string_dup( filename.ToCString() );
1002   aFileSeq[ 1 ] = CORBA::string_dup( meshfile.ToCString() );
1003   filename = tmpDir + filename;
1004   meshfile = tmpDir + meshfile;
1005
1006   HDFfile*    aFile;
1007   HDFdataset* aDataset;
1008   HDFgroup*   aTopGroup;
1009   HDFgroup*   aGroup;
1010   HDFgroup*   aSubGroup;
1011   HDFgroup*   aSubSubGroup;
1012   hdf_size    aSize[ 1 ];
1013
1014   // MED writer to be used by storage process
1015   DriverMED_W_SMESHDS_Mesh myWriter;
1016   myWriter.SetFile( meshfile.ToCString() );
1017
1018   // Write data
1019   // ---> create HDF file
1020   aFile = new HDFfile( filename.ToCString() );
1021   aFile->CreateOnDisk();
1022   
1023   // --> iterator for top-level objects
1024   SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
1025   for ( ; itBig->More(); itBig->Next() ) {
1026     SALOMEDS::SObject_var gotBranch = itBig->Value();
1027
1028     // --> hypotheses root branch (only one for the study)
1029     if ( gotBranch->Tag() == GetHypothesisRootTag() ) {
1030       // create hypotheses root HDF group
1031       aTopGroup = new HDFgroup( "Hypotheses", aFile );
1032       aTopGroup->CreateOnDisk();
1033
1034       // iterator for all hypotheses
1035       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
1036       for ( ; it->More(); it->Next() ) {
1037         SALOMEDS::SObject_var mySObject = it->Value();
1038         CORBA::Object_var anObject = SObjectToObject( mySObject );
1039         if ( !CORBA::is_nil( anObject ) ) {
1040           SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
1041           if ( !myHyp->_is_nil() ) {
1042             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
1043             if ( myImpl ) {
1044               string hypname = string( myHyp->GetName() );
1045               string libname = string( myHyp->GetLibName() );
1046               int    id      = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
1047               string hypdata = string( myImpl->SaveTo() );
1048
1049               // for each hypothesis create HDF group basing on its id
1050               char hypGrpName[30];
1051               sprintf( hypGrpName, "Hypothesis %d", id );
1052               aGroup = new HDFgroup( hypGrpName, aTopGroup );
1053               aGroup->CreateOnDisk();
1054               // --> type name of hypothesis
1055               aSize[ 0 ] = hypname.length() + 1;
1056               aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 );
1057               aDataset->CreateOnDisk();
1058               aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) );
1059               aDataset->CloseOnDisk();
1060               // --> server plugin library name of hypothesis
1061               aSize[ 0 ] = libname.length() + 1;
1062               aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 );
1063               aDataset->CreateOnDisk();
1064               aDataset->WriteOnDisk( ( char* )( libname.c_str() ) );
1065               aDataset->CloseOnDisk();
1066               // --> persistent data of hypothesis
1067               aSize[ 0 ] = hypdata.length() + 1;
1068               aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 );
1069               aDataset->CreateOnDisk();
1070               aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) );
1071               aDataset->CloseOnDisk();
1072               // close hypothesis HDF group
1073               aGroup->CloseOnDisk();
1074             }
1075           }
1076         }
1077       }
1078       // close hypotheses root HDF group
1079       aTopGroup->CloseOnDisk();
1080     }
1081     // --> algorithms root branch (only one for the study)
1082     else if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
1083       // create algorithms root HDF group
1084       aTopGroup = new HDFgroup( "Algorithms", aFile );
1085       aTopGroup->CreateOnDisk();
1086
1087       // iterator for all algorithms
1088       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
1089       for ( ; it->More(); it->Next() ) {
1090         SALOMEDS::SObject_var mySObject = it->Value();
1091         CORBA::Object_var anObject = SObjectToObject( mySObject );
1092         if ( !CORBA::is_nil( anObject ) ) {
1093           SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
1094           if ( !myHyp->_is_nil() ) {
1095             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
1096             if ( myImpl ) {
1097               string hypname = string( myHyp->GetName() );
1098               string libname = string( myHyp->GetLibName() );
1099               int    id      = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
1100               string hypdata = string( myImpl->SaveTo() );
1101
1102               // for each algorithm create HDF group basing on its id
1103               char hypGrpName[30];
1104               sprintf( hypGrpName, "Algorithm %d", id );
1105               aGroup = new HDFgroup( hypGrpName, aTopGroup );
1106               aGroup->CreateOnDisk();
1107               // --> type name of algorithm
1108               aSize[0] = hypname.length() + 1;
1109               aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 );
1110               aDataset->CreateOnDisk();
1111               aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) );
1112               aDataset->CloseOnDisk();
1113               // --> server plugin library name of hypothesis
1114               aSize[0] = libname.length() + 1;
1115               aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 );
1116               aDataset->CreateOnDisk();
1117               aDataset->WriteOnDisk( ( char* )( libname.c_str() ) );
1118               aDataset->CloseOnDisk();
1119               // --> persistent data of algorithm
1120               aSize[0] = hypdata.length() + 1;
1121               aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 );
1122               aDataset->CreateOnDisk();
1123               aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) );
1124               aDataset->CloseOnDisk();
1125               // close algorithm HDF group
1126               aGroup->CloseOnDisk();
1127             }
1128           }
1129         }
1130       }
1131       // close algorithms root HDF group
1132       aTopGroup->CloseOnDisk();
1133     }
1134     // --> mesh objects roots branches
1135     else if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) {
1136       CORBA::Object_var anObject = SObjectToObject( gotBranch );
1137       if ( !CORBA::is_nil( anObject ) ) {
1138         SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
1139         if ( !myMesh->_is_nil() ) {
1140           SMESH_Mesh_i* myImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myMesh ).in() );
1141           if ( myImpl ) {
1142             int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
1143             ::SMESH_Mesh& myLocMesh = myImpl->GetImpl();
1144             SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
1145
1146             // for each mesh open the HDF group basing on its id
1147             char meshGrpName[ 30 ];
1148             sprintf( meshGrpName, "Mesh %d", id );
1149             aTopGroup = new HDFgroup( meshGrpName, aFile );
1150             aTopGroup->CreateOnDisk();
1151
1152             // --> put dataset to hdf file which is a flag that mesh has data
1153             string strHasData = "0";
1154             // check if the mesh is not empty
1155             if ( mySMESHDSMesh->NbNodes() > 0 ) {
1156               // write mesh data to med file
1157               myWriter.SetMesh( mySMESHDSMesh );
1158               myWriter.SetMeshId( id );
1159               strHasData = "1";
1160             }
1161             aSize[ 0 ] = strHasData.length() + 1;
1162             aDataset = new HDFdataset( "Has data", aTopGroup, HDF_STRING, aSize, 1 );
1163             aDataset->CreateOnDisk();
1164             aDataset->WriteOnDisk( ( char* )( strHasData.c_str() ) );
1165             aDataset->CloseOnDisk();
1166             
1167             // write reference on a shape if exists
1168             SALOMEDS::SObject_var myRef;
1169             bool shapeRefFound = false;
1170             bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef );
1171             if ( found ) {
1172               SALOMEDS::SObject_var myShape;
1173               bool ok = myRef->ReferencedObject( myShape );
1174               if ( ok ) {
1175                 shapeRefFound = (! CORBA::is_nil( myShape->GetObject() ));
1176                 string myRefOnObject = myShape->GetID();
1177                 if ( shapeRefFound && myRefOnObject.length() > 0 ) {
1178                   aSize[ 0 ] = myRefOnObject.length() + 1;
1179                   aDataset = new HDFdataset( "Ref on shape", aTopGroup, HDF_STRING, aSize, 1 );
1180                   aDataset->CreateOnDisk();
1181                   aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
1182                   aDataset->CloseOnDisk();
1183                 }
1184               }
1185             }
1186
1187             // write applied hypotheses if exist
1188             SALOMEDS::SObject_var myHypBranch;
1189             found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch );
1190             if ( found && !shapeRefFound ) { // remove applied hyps
1191               myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch );
1192             }
1193             if ( found && shapeRefFound ) {
1194               aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
1195               aGroup->CreateOnDisk();
1196
1197               SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myHypBranch );
1198               int hypNb = 0;
1199               for ( ; it->More(); it->Next() ) {
1200                 SALOMEDS::SObject_var mySObject = it->Value();
1201                 SALOMEDS::SObject_var myRefOnHyp;
1202                 bool ok = mySObject->ReferencedObject( myRefOnHyp );
1203                 if ( ok ) {
1204                   // san - it is impossible to recover applied hypotheses
1205                   //       using their entries within Load() method,
1206                   // for there are no AttributeIORs in the study when Load() is working. 
1207                   // Hence, it is better to store persistent IDs of hypotheses as references to them
1208
1209                   //string myRefOnObject = myRefOnHyp->GetID();
1210                   CORBA::Object_var anObject = SObjectToObject( myRefOnHyp );
1211                   int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
1212                   //if ( myRefOnObject.length() > 0 ) {
1213                   //aSize[ 0 ] = myRefOnObject.length() + 1;
1214                   char hypName[ 30 ], hypId[ 30 ];
1215                   sprintf( hypName, "Hyp %d", ++hypNb );
1216                   sprintf( hypId, "%d", id );
1217                   aSize[ 0 ] = strlen( hypId ) + 1;
1218                   aDataset = new HDFdataset( hypName, aGroup, HDF_STRING, aSize, 1 );
1219                   aDataset->CreateOnDisk();
1220                   //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
1221                   aDataset->WriteOnDisk( hypId );
1222                   aDataset->CloseOnDisk();
1223                   //}
1224                 }
1225               }
1226               aGroup->CloseOnDisk();
1227             }
1228
1229             // write applied algorithms if exist
1230             SALOMEDS::SObject_var myAlgoBranch;
1231             found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), myAlgoBranch );
1232             if ( found && !shapeRefFound ) { // remove applied algos
1233               myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myAlgoBranch );
1234             }
1235             if ( found && shapeRefFound ) {
1236               aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
1237               aGroup->CreateOnDisk();
1238
1239               SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myAlgoBranch );
1240               int algoNb = 0;
1241               for ( ; it->More(); it->Next() ) {
1242                 SALOMEDS::SObject_var mySObject = it->Value();
1243                 SALOMEDS::SObject_var myRefOnAlgo;
1244                 bool ok = mySObject->ReferencedObject( myRefOnAlgo );
1245                 if ( ok ) {
1246                   // san - it is impossible to recover applied algorithms
1247                   //       using their entries within Load() method,
1248                   // for there are no AttributeIORs in the study when Load() is working. 
1249                   // Hence, it is better to store persistent IDs of algorithms as references to them
1250
1251                   //string myRefOnObject = myRefOnAlgo->GetID();
1252                   CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo );
1253                   int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
1254                   //if ( myRefOnObject.length() > 0 ) {
1255                   //aSize[ 0 ] = myRefOnObject.length() + 1;
1256                   char algoName[ 30 ], algoId[ 30 ];
1257                   sprintf( algoName, "Algo %d", ++algoNb );
1258                   sprintf( algoId, "%d", id );
1259                   aSize[ 0 ] = strlen( algoId ) + 1;
1260                   aDataset = new HDFdataset( algoName, aGroup, HDF_STRING, aSize, 1 );
1261                   aDataset->CreateOnDisk();
1262                   //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
1263                   aDataset->WriteOnDisk( algoId );
1264                   aDataset->CloseOnDisk();
1265                   //}
1266                 }
1267               }
1268               aGroup->CloseOnDisk();
1269             }
1270
1271             // --> submesh objects sub-branches
1272
1273             for ( int i = GetSubMeshOnVertexTag(); i <= GetSubMeshOnCompoundTag(); i++ ) {
1274               SALOMEDS::SObject_var mySubmeshBranch;
1275               found = gotBranch->FindSubObject( i, mySubmeshBranch );
1276
1277               if ( found ) // check if there is shape reference in submeshes
1278               {
1279                 bool hasShapeRef = false;
1280                 SALOMEDS::ChildIterator_var itSM =
1281                   myCurrentStudy->NewChildIterator( mySubmeshBranch );
1282                 for ( ; itSM->More(); itSM->Next() ) {
1283                   SALOMEDS::SObject_var mySubRef, myShape, mySObject = itSM->Value();
1284                   if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ))
1285                     mySubRef->ReferencedObject( myShape );
1286                   if ( !CORBA::is_nil( myShape ) && !CORBA::is_nil( myShape->GetObject() ))
1287                     hasShapeRef = true;
1288                   else
1289                   { // remove one submesh
1290                     if ( shapeRefFound )
1291                     { // unassign hypothesis
1292                       SMESH::SMESH_subMesh_var mySubMesh =
1293                         SMESH::SMESH_subMesh::_narrow( SObjectToObject( mySObject ));
1294                       if ( !mySubMesh->_is_nil() ) {
1295                         int shapeID = mySubMesh->GetId();
1296                         TopoDS_Shape S = mySMESHDSMesh->IndexToShape( shapeID );
1297                         const list<const SMESHDS_Hypothesis*>& hypList =
1298                           mySMESHDSMesh->GetHypothesis( S );
1299                         list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
1300                         while ( hyp != hypList.end() ) {
1301                           int hypID = (*hyp++)->GetID(); // goto next hyp here because
1302                           myLocMesh.RemoveHypothesis( S, hypID ); // hypList changes here
1303                         }
1304                       }
1305                     }
1306                     myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( mySObject );
1307                   }
1308                 } // loop on submeshes of a type
1309                 if ( !shapeRefFound || !hasShapeRef ) { // remove the whole submeshes branch
1310                   myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( mySubmeshBranch );
1311                   found = false;
1312                 }
1313               }  // end check if there is shape reference in submeshes
1314               if ( found ) {
1315                 char name_meshgroup[ 30 ];
1316                 if ( i == GetSubMeshOnVertexTag() )
1317                   strcpy( name_meshgroup, "SubMeshes On Vertex" );
1318                 else if ( i == GetSubMeshOnEdgeTag() )
1319                   strcpy( name_meshgroup, "SubMeshes On Edge" );
1320                 else if ( i == GetSubMeshOnWireTag() )
1321                   strcpy( name_meshgroup, "SubMeshes On Wire" );
1322                 else if ( i == GetSubMeshOnFaceTag() )
1323                   strcpy( name_meshgroup, "SubMeshes On Face" );
1324                 else if ( i == GetSubMeshOnShellTag() )
1325                   strcpy( name_meshgroup, "SubMeshes On Shell" );
1326                 else if ( i == GetSubMeshOnSolidTag() )
1327                   strcpy( name_meshgroup, "SubMeshes On Solid" );
1328                 else if ( i == GetSubMeshOnCompoundTag() )
1329                   strcpy( name_meshgroup, "SubMeshes On Compound" );
1330                 
1331                 // for each type of submeshes create container HDF group
1332                 aGroup = new HDFgroup( name_meshgroup, aTopGroup );
1333                 aGroup->CreateOnDisk();
1334             
1335                 // iterator for all submeshes of given type
1336                 SALOMEDS::ChildIterator_var itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch );
1337                 for ( ; itSM->More(); itSM->Next() ) {
1338                   SALOMEDS::SObject_var mySObject = itSM->Value();
1339                   CORBA::Object_var anSubObject = SObjectToObject( mySObject );
1340                   if ( !CORBA::is_nil( anSubObject ))
1341                   {
1342                     SMESH::SMESH_subMesh_var mySubMesh = SMESH::SMESH_subMesh::_narrow( anSubObject ) ;
1343                     int subid = myStudyContext->findId( string( GetORB()->object_to_string( anSubObject ) ) );
1344                       
1345                     // for each mesh open the HDF group basing on its id
1346                     char submeshGrpName[ 30 ];
1347                     sprintf( submeshGrpName, "SubMesh %d", subid );
1348                     aSubGroup = new HDFgroup( submeshGrpName, aGroup );
1349                     aSubGroup->CreateOnDisk();
1350
1351                     // write reference on a shape, already checked if it exists
1352                     SALOMEDS::SObject_var mySubRef, myShape;
1353                     if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ))
1354                       mySubRef->ReferencedObject( myShape );
1355                     string myRefOnObject = myShape->GetID();
1356                     if ( myRefOnObject.length() > 0 ) {
1357                       aSize[ 0 ] = myRefOnObject.length() + 1;
1358                       aDataset = new HDFdataset( "Ref on shape", aSubGroup, HDF_STRING, aSize, 1 );
1359                       aDataset->CreateOnDisk();
1360                       aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
1361                       aDataset->CloseOnDisk();
1362                     }
1363
1364                     // write applied hypotheses if exist
1365                     SALOMEDS::SObject_var mySubHypBranch;
1366                     found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(), mySubHypBranch );
1367                     if ( found ) {
1368                       aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
1369                       aSubSubGroup->CreateOnDisk();
1370
1371                       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubHypBranch );
1372                       int hypNb = 0;
1373                       for ( ; it->More(); it->Next() ) {
1374                         SALOMEDS::SObject_var mySubSObject = it->Value();
1375                         SALOMEDS::SObject_var myRefOnHyp;
1376                         bool ok = mySubSObject->ReferencedObject( myRefOnHyp );
1377                         if ( ok ) {
1378                           //string myRefOnObject = myRefOnHyp->GetID();
1379                           CORBA::Object_var anObject = SObjectToObject( myRefOnHyp );
1380                           int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
1381                           //if ( myRefOnObject.length() > 0 ) {
1382                           //aSize[ 0 ] = myRefOnObject.length() + 1;
1383                           char hypName[ 30 ], hypId[ 30 ];
1384                           sprintf( hypName, "Hyp %d", ++hypNb );
1385                           sprintf( hypId, "%d", id );
1386                           aSize[ 0 ] = strlen( hypId ) + 1;
1387                           aDataset = new HDFdataset( hypName, aSubSubGroup, HDF_STRING, aSize, 1 );
1388                           aDataset->CreateOnDisk();
1389                           //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
1390                           aDataset->WriteOnDisk( hypId );
1391                           aDataset->CloseOnDisk();
1392                           //}
1393                         }
1394                       }
1395                       aSubSubGroup->CloseOnDisk();
1396                     }
1397                     
1398                     // write applied algorithms if exist
1399                     SALOMEDS::SObject_var mySubAlgoBranch;
1400                     found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch );
1401                     if ( found ) {
1402                       aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
1403                       aSubSubGroup->CreateOnDisk();
1404
1405                       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch );
1406                       int algoNb = 0;
1407                       for ( ; it->More(); it->Next() ) {
1408                         SALOMEDS::SObject_var mySubSObject = it->Value();
1409                         SALOMEDS::SObject_var myRefOnAlgo;
1410                         bool ok = mySubSObject->ReferencedObject( myRefOnAlgo );
1411                         if ( ok ) {
1412                           //string myRefOnObject = myRefOnAlgo->GetID();
1413                           CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo );
1414                           int id = myStudyContext->findId( string( GetORB()->object_to_string( anObject ) ) );
1415                           //if ( myRefOnObject.length() > 0 ) {
1416                           //aSize[ 0 ] = myRefOnObject.length() + 1;
1417                           char algoName[ 30 ], algoId[ 30 ];
1418                           sprintf( algoName, "Algo %d", ++algoNb );
1419                           sprintf( algoId, "%d", id );
1420                           aSize[ 0 ] = strlen( algoId ) + 1;
1421                           aDataset = new HDFdataset( algoName, aSubSubGroup, HDF_STRING, aSize, 1 );
1422                           aDataset->CreateOnDisk();
1423                           //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
1424                           aDataset->WriteOnDisk( algoId );
1425                           aDataset->CloseOnDisk();
1426                           //}
1427                         }
1428                       }
1429                       aSubSubGroup->CloseOnDisk();
1430                     }
1431                     // close submesh HDF group
1432                     aSubGroup->CloseOnDisk();
1433                   }
1434                 }
1435                 // close container of submeshes by type HDF group
1436                 aGroup->CloseOnDisk();
1437               }
1438             }
1439             // All sub-meshes will be stored in MED file
1440             if ( shapeRefFound )
1441               myWriter.AddAllSubMeshes();
1442
1443             // groups root sub-branch
1444             SALOMEDS::SObject_var myGroupsBranch;
1445             for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) {
1446               found = gotBranch->FindSubObject( i, myGroupsBranch );
1447               if ( found ) {
1448                 char name_group[ 30 ];
1449                 if ( i == GetNodeGroupsTag() )
1450                   strcpy( name_group, "Groups of Nodes" );
1451                 else if ( i == GetEdgeGroupsTag() )
1452                   strcpy( name_group, "Groups of Edges" );
1453                 else if ( i == GetFaceGroupsTag() )
1454                   strcpy( name_group, "Groups of Faces" );
1455                 else if ( i == GetVolumeGroupsTag() )
1456                   strcpy( name_group, "Groups of Volumes" );
1457
1458                 aGroup = new HDFgroup( name_group, aTopGroup );
1459                 aGroup->CreateOnDisk();
1460
1461                 SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch );
1462                 for ( ; it->More(); it->Next() ) {
1463                   SALOMEDS::SObject_var mySObject = it->Value();
1464                   CORBA::Object_var aSubObject = SObjectToObject( mySObject );
1465                   if ( !CORBA::is_nil( aSubObject ) ) {
1466                     SMESH_GroupBase_i* myGroupImpl =
1467                       dynamic_cast<SMESH_GroupBase_i*>( GetServant( aSubObject ).in() );
1468                     if ( !myGroupImpl )
1469                       continue;
1470
1471                     int anId = myStudyContext->findId( string( GetORB()->object_to_string( aSubObject ) ) );
1472                     
1473                     // For each group, create a dataset named "Group <group_persistent_id>"
1474                     // and store the group's user name into it
1475                     char grpName[ 30 ];
1476                     sprintf( grpName, "Group %d", anId );
1477                     char* aUserName = myGroupImpl->GetName();
1478                     aSize[ 0 ] = strlen( aUserName ) + 1;
1479
1480                     aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 );
1481                     aDataset->CreateOnDisk();
1482                     aDataset->WriteOnDisk( aUserName );
1483                     aDataset->CloseOnDisk();
1484
1485                     // Store the group contents into MED file
1486                     if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) {
1487
1488                       if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = "
1489                               << grpName << " to MED file" );
1490                       SMESHDS_GroupBase* aGrpBaseDS =
1491                         myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS();
1492                       aGrpBaseDS->SetStoreName( grpName );
1493
1494                       // Pass SMESHDS_Group to MED writer 
1495                       SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
1496                       if ( aGrpDS )
1497                         myWriter.AddGroup( aGrpDS );
1498
1499                       // write reference on a shape if exists
1500                       SMESHDS_GroupOnGeom* aGeomGrp =
1501                         dynamic_cast<SMESHDS_GroupOnGeom*>( aGrpBaseDS );
1502                       if ( aGeomGrp ) {
1503                         SALOMEDS::SObject_var mySubRef, myShape;
1504                         if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) &&
1505                             mySubRef->ReferencedObject( myShape ) &&
1506                             !CORBA::is_nil( myShape->GetObject() ))
1507                         {
1508                           string myRefOnObject = myShape->GetID();
1509                           if ( myRefOnObject.length() > 0 ) {
1510                             char aRefName[ 30 ];
1511                             sprintf( aRefName, "Ref on shape %d", anId);
1512                             aSize[ 0 ] = myRefOnObject.length() + 1;
1513                             aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1);
1514                             aDataset->CreateOnDisk();
1515                             aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
1516                             aDataset->CloseOnDisk();
1517                           }
1518                         }
1519                         else // shape ref is invalid:
1520                         {
1521                           // save a group on geometry as ordinary group
1522                           myWriter.AddGroup( aGeomGrp );
1523                         }
1524                       }
1525                     }
1526                   }
1527                 }
1528                 aGroup->CloseOnDisk();
1529               }
1530             } // loop on groups 
1531
1532             if ( strcmp( strHasData.c_str(), "1" ) == 0 )
1533             {
1534               // Flush current mesh information into MED file
1535               myWriter.Perform();
1536
1537               // maybe a shape was deleted in the study
1538               if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() ) {
1539                 TopoDS_Shape nullShape;
1540                 myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data
1541               }
1542
1543               // Store node positions on sub-shapes (SMDS_Position):
1544
1545               if ( !mySMESHDSMesh->SubMeshes().empty() )
1546               {
1547                 aGroup = new HDFgroup( "Node Positions", aTopGroup );
1548                 aGroup->CreateOnDisk();
1549
1550                 // in aGroup, create 5 datasets to contain:
1551                 // "Nodes on Edges" - ID of node on edge
1552                 // "Edge positions" - U parameter on node on edge
1553                 // "Nodes on Faces" - ID of node on face
1554                 // "Face U positions" - U parameter of node on face
1555                 // "Face V positions" - V parameter of node on face
1556
1557                 // Find out nb of nodes on edges and faces
1558                 // Collect corresponing sub-meshes
1559                 int nbEdgeNodes = 0, nbFaceNodes = 0;
1560                 list<SMESHDS_SubMesh*> aEdgeSM, aFaceSM;
1561                 // loop on SMESHDS_SubMesh'es
1562                 const map<int,SMESHDS_SubMesh*>& aSubMeshes = mySMESHDSMesh->SubMeshes();
1563                 map<int,SMESHDS_SubMesh*>::const_iterator itSubM ( aSubMeshes.begin() );
1564                 for ( ; itSubM != aSubMeshes.end() ; itSubM++ )
1565                 {
1566                   SMESHDS_SubMesh* aSubMesh = (*itSubM).second;
1567                   if ( aSubMesh->IsComplexSubmesh() )
1568                     continue; // submesh containing other submeshs
1569                   int nbNodes = aSubMesh->NbNodes();
1570                   if ( nbNodes == 0 ) continue;
1571
1572                   int aShapeID = (*itSubM).first;
1573                   int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType();
1574                   // write only SMDS_FacePosition and SMDS_EdgePosition
1575                   switch ( aShapeType ) {
1576                   case TopAbs_FACE:
1577                     nbFaceNodes += nbNodes;
1578                     aFaceSM.push_back( aSubMesh );
1579                     break;
1580                   case TopAbs_EDGE:
1581                     nbEdgeNodes += nbNodes;
1582                     aEdgeSM.push_back( aSubMesh );
1583                     break;
1584                   default:
1585                     continue;
1586                   }
1587                 }
1588                 // Treat positions on edges or faces
1589                 for ( int onFace = 0; onFace < 2; onFace++ )
1590                 {
1591                   // Create arrays to store in datasets
1592                   int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes );
1593                   if (!nbNodes) continue;
1594                   int* aNodeIDs = new int [ nbNodes ];
1595                   double* aUPos = new double [ nbNodes ];
1596                   double* aVPos = ( onFace ? new double[ nbNodes ] : 0 );
1597
1598                   // Fill arrays
1599                   // loop on sub-meshes
1600                   list<SMESHDS_SubMesh*> * pListSM = ( onFace ? &aFaceSM : &aEdgeSM );
1601                   list<SMESHDS_SubMesh*>::iterator itSM = pListSM->begin();
1602                   for ( ; itSM != pListSM->end(); itSM++ )
1603                   {
1604                     SMESHDS_SubMesh* aSubMesh = (*itSM);
1605                     if ( aSubMesh->IsComplexSubmesh() )
1606                       continue; // submesh containing other submeshs
1607
1608                     SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes();
1609                     // loop on nodes in aSubMesh
1610                     while ( itNode->more() )
1611                     {
1612                       //node ID
1613                       const SMDS_MeshNode* node = itNode->next();
1614                       aNodeIDs [ iNode ] = node->GetID();
1615
1616                       // Position
1617                       const SMDS_PositionPtr pos = node->GetPosition();
1618                       if ( onFace ) { // on FACE
1619                         const SMDS_FacePosition* fPos =
1620                           dynamic_cast<const SMDS_FacePosition*>( pos.get() );
1621                         if ( fPos ) {
1622                           aUPos[ iNode ] = fPos->GetUParameter();
1623                           aVPos[ iNode ] = fPos->GetVParameter();
1624                           iNode++;
1625                         }
1626                         else
1627                           nbNodes--;
1628                       }
1629                       else { // on EDGE
1630                         const SMDS_EdgePosition* ePos =
1631                           dynamic_cast<const SMDS_EdgePosition*>( pos.get() );
1632                         if ( ePos ) {
1633                           aUPos[ iNode ] = ePos->GetUParameter();
1634                           iNode++;
1635                         }
1636                         else
1637                           nbNodes--;
1638                       }
1639                     } // loop on nodes in aSubMesh
1640                   } // loop on sub-meshes
1641
1642                   // Write datasets
1643                   if ( nbNodes )
1644                   {
1645                     aSize[ 0 ] = nbNodes;
1646                     // IDS
1647                     string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges");
1648                     aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
1649                     aDataset->CreateOnDisk();
1650                     aDataset->WriteOnDisk( aNodeIDs );
1651                     aDataset->CloseOnDisk();
1652
1653                     // U Positions
1654                     aDSName = ( onFace ? "Face U positions" : "Edge positions");
1655                     aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1);
1656                     aDataset->CreateOnDisk();
1657                     aDataset->WriteOnDisk( aUPos );
1658                     aDataset->CloseOnDisk();
1659                     // V Positions
1660                     if ( onFace ) {
1661                       aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1);
1662                       aDataset->CreateOnDisk();
1663                       aDataset->WriteOnDisk( aVPos );
1664                       aDataset->CloseOnDisk();
1665                     }
1666                   }
1667                   delete [] aNodeIDs;
1668                   delete [] aUPos;
1669                   if ( aVPos ) delete [] aVPos;
1670
1671                 } // treat positions on edges or faces
1672
1673                 // close "Node Positions" group
1674                 aGroup->CloseOnDisk(); 
1675
1676               } // if ( there are submeshes in SMESHDS_Mesh )
1677             } // if ( hasData )
1678
1679             // close mesh HDF group
1680             aTopGroup->CloseOnDisk();
1681           }
1682         }
1683       }
1684     }
1685   }
1686
1687   // close HDF file
1688   aFile->CloseOnDisk();
1689   delete aFile;
1690
1691   // Convert temporary files to stream
1692   aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile );
1693
1694   // Remove temporary files and directory
1695   if ( !isMultiFile ) 
1696     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
1697
1698   INFOS( "SMESH_Gen_i::Save() completed" );
1699   return aStreamFile._retn();
1700 }
1701
1702 //=============================================================================
1703 /*!
1704  *  SMESH_Gen_i::SaveASCII
1705  *
1706  *  Save SMESH module's data in ASCII format (not implemented yet)
1707  */
1708 //=============================================================================
1709
1710 SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent,
1711                                            const char*              theURL,
1712                                            bool                     isMultiFile ) {
1713   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SaveASCII" );
1714   SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile );
1715   return aStreamFile._retn();
1716 }
1717
1718 //=============================================================================
1719 /*!
1720  *  SMESH_Gen_i::loadGeomData
1721  *
1722  *  Load GEOM module data
1723  */
1724 //=============================================================================
1725
1726 void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot )
1727 {
1728   if ( theCompRoot->_is_nil() )
1729     return;
1730
1731   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theCompRoot->GetStudy() );
1732   if ( aStudy->_is_nil() )
1733     return;
1734
1735   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); 
1736   aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() );
1737 }
1738
1739 //=============================================================================
1740 /*!
1741  *  SMESH_Gen_i::Load
1742  *
1743  *  Load SMESH module's data
1744  */
1745 //=============================================================================
1746
1747 bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
1748                         const SALOMEDS::TMPFile& theStream,
1749                         const char*              theURL,
1750                         bool                     isMultiFile )
1751 {
1752   INFOS( "SMESH_Gen_i::Load" );
1753
1754   if ( myCurrentStudy->_is_nil() || 
1755        theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
1756     SetCurrentStudy( theComponent->GetStudy() );
1757
1758 /*  if( !theComponent->_is_nil() )
1759   {
1760     //SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theComponent->GetStudy() );
1761     if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
1762       loadGeomData( myCurrentStudy->FindComponent( "GEOM" ) );
1763   }*/
1764
1765   StudyContext* myStudyContext = GetCurrentStudyContext();
1766   
1767   // Get temporary files location
1768   TCollection_AsciiString tmpDir =
1769     isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str();
1770
1771   // Convert the stream into sequence of files to process
1772   SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
1773                                                                             tmpDir.ToCString(),
1774                                                                             isMultiFile );
1775   TCollection_AsciiString aStudyName( "" );
1776   if ( isMultiFile ) 
1777     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
1778
1779   // Set names of temporary files
1780   TCollection_AsciiString filename = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH.hdf" );
1781   TCollection_AsciiString meshfile = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" );
1782
1783   int size;
1784   HDFfile*    aFile;
1785   HDFdataset* aDataset;
1786   HDFgroup*   aTopGroup;
1787   HDFgroup*   aGroup;
1788   HDFgroup*   aSubGroup;
1789   HDFgroup*   aSubSubGroup;
1790
1791   // Read data
1792   // ---> open HDF file
1793   aFile = new HDFfile( filename.ToCString() );
1794   try {
1795     aFile->OpenOnDisk( HDF_RDONLY );
1796   }
1797   catch ( HDFexception ) {
1798     INFOS( "Load(): " << filename << " not found!" );
1799     return false;
1800   }
1801
1802   DriverMED_R_SMESHDS_Mesh myReader;
1803   myReader.SetFile( meshfile.ToCString() );
1804
1805   // get total number of top-level groups
1806   int aNbGroups = aFile->nInternalObjects(); 
1807   if ( aNbGroups > 0 ) {
1808     // --> in first turn we should read&create hypotheses
1809     if ( aFile->ExistInternalObject( "Hypotheses" ) ) {
1810       // open hypotheses root HDF group
1811       aTopGroup = new HDFgroup( "Hypotheses", aFile ); 
1812       aTopGroup->OpenOnDisk();
1813
1814       // get number of hypotheses
1815       int aNbObjects = aTopGroup->nInternalObjects(); 
1816       for ( int j = 0; j < aNbObjects; j++ ) {
1817         // try to identify hypothesis
1818         char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
1819         aTopGroup->InternalObjectIndentify( j, hypGrpName );
1820
1821         if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) {
1822           // open hypothesis group
1823           aGroup = new HDFgroup( hypGrpName, aTopGroup ); 
1824           aGroup->OpenOnDisk();
1825
1826           // --> get hypothesis id
1827           int    id = atoi( string( hypGrpName ).substr( 10 ).c_str() );
1828           string hypname;
1829           string libname;
1830           string hypdata;
1831
1832           // get number of datasets
1833           int aNbSubObjects = aGroup->nInternalObjects();
1834           for ( int k = 0; k < aNbSubObjects; k++ ) {
1835             // identify dataset
1836             char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ];
1837             aGroup->InternalObjectIndentify( k, name_of_subgroup );
1838             // --> get hypothesis name
1839             if ( strcmp( name_of_subgroup, "Name"  ) == 0 ) {
1840               aDataset = new HDFdataset( name_of_subgroup, aGroup );
1841               aDataset->OpenOnDisk();
1842               size = aDataset->GetSize();
1843               char* hypname_str = new char[ size ];
1844               aDataset->ReadFromDisk( hypname_str );
1845               hypname = string( hypname_str );
1846               delete [] hypname_str;
1847               aDataset->CloseOnDisk();
1848             }
1849             // --> get hypothesis plugin library name
1850             if ( strcmp( name_of_subgroup, "LibName"  ) == 0 ) {
1851               aDataset = new HDFdataset( name_of_subgroup, aGroup );
1852               aDataset->OpenOnDisk();
1853               size = aDataset->GetSize();
1854               char* libname_str = new char[ size ];
1855               aDataset->ReadFromDisk( libname_str );
1856               if(MYDEBUG) SCRUTE( libname_str );
1857               libname = string( libname_str );
1858               delete [] libname_str;
1859               aDataset->CloseOnDisk();
1860             }
1861             // --> get hypothesis data
1862             if ( strcmp( name_of_subgroup, "Data"  ) == 0 ) {
1863               aDataset = new HDFdataset( name_of_subgroup, aGroup );
1864               aDataset->OpenOnDisk();
1865               size = aDataset->GetSize();
1866               char* hypdata_str = new char[ size ];
1867               aDataset->ReadFromDisk( hypdata_str );
1868               hypdata = string( hypdata_str );
1869               delete [] hypdata_str;
1870               aDataset->CloseOnDisk();
1871             }
1872           }
1873           // close hypothesis HDF group
1874           aGroup->CloseOnDisk();
1875
1876           // --> restore hypothesis from data
1877           if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty
1878             if(MYDEBUG) MESSAGE("VSR - load hypothesis : id = " << id <<
1879                     ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str());
1880             SMESH::SMESH_Hypothesis_var myHyp;
1881             
1882             try { // protect persistence mechanism against exceptions
1883               myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
1884             }
1885             catch (...) {
1886               INFOS( "Exception during hypothesis creation" );
1887             }
1888
1889             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
1890             if ( myImpl ) {
1891               myImpl->LoadFrom( hypdata.c_str() );
1892               string iorString = GetORB()->object_to_string( myHyp );
1893               int newId = myStudyContext->findId( iorString );
1894               myStudyContext->mapOldToNew( id, newId );
1895             }
1896             else
1897               if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
1898           }
1899         }
1900       }
1901       // close hypotheses root HDF group
1902       aTopGroup->CloseOnDisk();
1903     }
1904
1905     // --> then we should read&create algorithms
1906     if ( aFile->ExistInternalObject( "Algorithms" ) ) {
1907       // open algorithms root HDF group
1908       aTopGroup = new HDFgroup( "Algorithms", aFile ); 
1909       aTopGroup->OpenOnDisk();
1910
1911       // get number of algorithms
1912       int aNbObjects = aTopGroup->nInternalObjects(); 
1913       for ( int j = 0; j < aNbObjects; j++ ) {
1914         // try to identify algorithm
1915         char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
1916         aTopGroup->InternalObjectIndentify( j, hypGrpName );
1917
1918         if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) {
1919           // open algorithm group
1920           aGroup = new HDFgroup( hypGrpName, aTopGroup ); 
1921           aGroup->OpenOnDisk();
1922
1923           // --> get algorithm id
1924           int    id = atoi( string( hypGrpName ).substr( 9 ).c_str() );
1925           string hypname;
1926           string libname;
1927           string hypdata;
1928
1929           // get number of datasets
1930           int aNbSubObjects = aGroup->nInternalObjects();
1931           for ( int k = 0; k < aNbSubObjects; k++ ) {
1932             // identify dataset
1933             char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ];
1934             aGroup->InternalObjectIndentify( k, name_of_subgroup );
1935             // --> get algorithm name
1936             if ( strcmp( name_of_subgroup, "Name"  ) == 0 ) {
1937               aDataset = new HDFdataset( name_of_subgroup, aGroup );
1938               aDataset->OpenOnDisk();
1939               size = aDataset->GetSize();
1940               char* hypname_str = new char[ size ];
1941               aDataset->ReadFromDisk( hypname_str );
1942               hypname = string( hypname_str );
1943               delete [] hypname_str;
1944               aDataset->CloseOnDisk();
1945             }
1946             // --> get algorithm plugin library name
1947             if ( strcmp( name_of_subgroup, "LibName"  ) == 0 ) {
1948               aDataset = new HDFdataset( name_of_subgroup, aGroup );
1949               aDataset->OpenOnDisk();
1950               size = aDataset->GetSize();
1951               char* libname_str = new char[ size ];
1952               aDataset->ReadFromDisk( libname_str );
1953               if(MYDEBUG) SCRUTE( libname_str );
1954               libname = string( libname_str );
1955               delete [] libname_str;
1956               aDataset->CloseOnDisk();
1957             }
1958             // --> get algorithm data
1959             if ( strcmp( name_of_subgroup, "Data"  ) == 0 ) {
1960               aDataset = new HDFdataset( name_of_subgroup, aGroup );
1961               aDataset->OpenOnDisk();
1962               size = aDataset->GetSize();
1963               char* hypdata_str = new char[ size ];
1964               aDataset->ReadFromDisk( hypdata_str );
1965               if(MYDEBUG) SCRUTE( hypdata_str );
1966               hypdata = string( hypdata_str );
1967               delete [] hypdata_str;
1968               aDataset->CloseOnDisk();
1969             }
1970           }
1971           // close algorithm HDF group
1972           aGroup->CloseOnDisk();
1973           
1974           // --> restore algorithm from data
1975           if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty
1976             if(MYDEBUG) MESSAGE("VSR - load algo : id = " << id <<
1977                     ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str());
1978             SMESH::SMESH_Hypothesis_var myHyp;
1979                     
1980             try { // protect persistence mechanism against exceptions
1981               myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
1982             }
1983             catch (...) {
1984               INFOS( "Exception during hypothesis creation" );
1985             }
1986             
1987             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
1988             if ( myImpl ) {
1989               myImpl->LoadFrom( hypdata.c_str() );
1990               string iorString = GetORB()->object_to_string( myHyp );
1991               int newId = myStudyContext->findId( iorString );
1992               myStudyContext->mapOldToNew( id, newId );
1993             }
1994             else
1995               if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
1996           }
1997         }
1998       }
1999       // close algorithms root HDF group
2000       aTopGroup->CloseOnDisk();
2001     }
2002
2003     // --> the rest groups should be meshes
2004     for ( int i = 0; i < aNbGroups; i++ ) {
2005       // identify next group
2006       char meshName[ HDF_NAME_MAX_LEN+1 ];
2007       aFile->InternalObjectIndentify( i, meshName );
2008
2009       if ( string( meshName ).substr( 0, 4 ) == string( "Mesh" ) ) {
2010         // --> get mesh id
2011         int id = atoi( string( meshName ).substr( 4 ).c_str() );
2012         if ( id <= 0 )
2013           continue;
2014
2015         bool hasData = false;
2016
2017         // open mesh HDF group
2018         aTopGroup = new HDFgroup( meshName, aFile ); 
2019         aTopGroup->OpenOnDisk();
2020
2021         // get number of child HDF objects
2022         int aNbObjects = aTopGroup->nInternalObjects(); 
2023         if ( aNbObjects > 0 ) {
2024           // create mesh
2025           if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id );
2026           SMESH::SMESH_Mesh_var myNewMesh = this->createMesh();
2027           SMESH_Mesh_i* myNewMeshImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myNewMesh ).in() );
2028           if ( !myNewMeshImpl )
2029             continue;
2030           string iorString = GetORB()->object_to_string( myNewMesh );
2031           int newId = myStudyContext->findId( iorString );
2032           myStudyContext->mapOldToNew( id, newId );
2033           
2034           ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl();
2035           SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
2036
2037           // try to find mesh data dataset
2038           if ( aTopGroup->ExistInternalObject( "Has data" ) ) {
2039             // load mesh "has data" flag
2040             aDataset = new HDFdataset( "Has data", aTopGroup );
2041             aDataset->OpenOnDisk();
2042             size = aDataset->GetSize();
2043             char* strHasData = new char[ size ];
2044             aDataset->ReadFromDisk( strHasData );
2045             aDataset->CloseOnDisk();
2046             if ( strcmp( strHasData, "1") == 0 ) {
2047               // read mesh data from MED file
2048               myReader.SetMesh( mySMESHDSMesh );
2049               myReader.SetMeshId( id );
2050               myReader.Perform();
2051               hasData = true;
2052             }
2053           }
2054
2055           // try to read and set reference to shape
2056           GEOM::GEOM_Object_var aShapeObject;
2057           if ( aTopGroup->ExistInternalObject( "Ref on shape" ) ) {
2058             // load mesh "Ref on shape" - it's an entry to SObject
2059             aDataset = new HDFdataset( "Ref on shape", aTopGroup );
2060             aDataset->OpenOnDisk();
2061             size = aDataset->GetSize();
2062             char* refFromFile = new char[ size ];
2063             aDataset->ReadFromDisk( refFromFile );
2064             aDataset->CloseOnDisk();
2065             if ( strlen( refFromFile ) > 0 ) {
2066               SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile );
2067
2068               // Make sure GEOM data are loaded first
2069               //loadGeomData( shapeSO->GetFatherComponent() );
2070
2071               CORBA::Object_var shapeObject = SObjectToObject( shapeSO );
2072               if ( !CORBA::is_nil( shapeObject ) ) {
2073                 aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject );
2074                 if ( !aShapeObject->_is_nil() )
2075                   myNewMeshImpl->SetShape( aShapeObject );
2076               }
2077             }
2078           }
2079
2080           // try to get applied algorithms
2081           if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) {
2082             aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
2083             aGroup->OpenOnDisk();
2084             // get number of applied algorithms
2085             int aNbSubObjects = aGroup->nInternalObjects(); 
2086             if(MYDEBUG) MESSAGE( "VSR - number of applied algos " << aNbSubObjects );
2087             for ( int j = 0; j < aNbSubObjects; j++ ) {
2088               char name_dataset[ HDF_NAME_MAX_LEN+1 ];
2089               aGroup->InternalObjectIndentify( j, name_dataset );
2090               // check if it is an algorithm
2091               if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) {
2092                 aDataset = new HDFdataset( name_dataset, aGroup );
2093                 aDataset->OpenOnDisk();
2094                 size = aDataset->GetSize();
2095                 char* refFromFile = new char[ size ];
2096                 aDataset->ReadFromDisk( refFromFile );
2097                 aDataset->CloseOnDisk();
2098
2099                 // san - it is impossible to recover applied algorithms using their entries within Load() method
2100                 
2101                 //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
2102                 //CORBA::Object_var hypObject = SObjectToObject( hypSO );
2103                 int id = atoi( refFromFile );
2104                 string anIOR = myStudyContext->getIORbyOldId( id );
2105                 if ( !anIOR.empty() ) {
2106                   CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
2107                   if ( !CORBA::is_nil( hypObject ) ) {
2108                     SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
2109                     if ( !anHyp->_is_nil() && !aShapeObject->_is_nil() )
2110                       myNewMeshImpl->addHypothesis( aShapeObject, anHyp );
2111                   }
2112                 }
2113               }
2114             }
2115             aGroup->CloseOnDisk();
2116           }
2117
2118           // try to get applied hypotheses
2119           if ( aTopGroup->ExistInternalObject( "Applied Hypotheses" ) ) {
2120             aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
2121             aGroup->OpenOnDisk();
2122             // get number of applied hypotheses
2123             int aNbSubObjects = aGroup->nInternalObjects(); 
2124             for ( int j = 0; j < aNbSubObjects; j++ ) {
2125               char name_dataset[ HDF_NAME_MAX_LEN+1 ];
2126               aGroup->InternalObjectIndentify( j, name_dataset );
2127               // check if it is a hypothesis
2128               if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) {
2129                 aDataset = new HDFdataset( name_dataset, aGroup );
2130                 aDataset->OpenOnDisk();
2131                 size = aDataset->GetSize();
2132                 char* refFromFile = new char[ size ];
2133                 aDataset->ReadFromDisk( refFromFile );
2134                 aDataset->CloseOnDisk();
2135
2136                 // san - it is impossible to recover applied hypotheses using their entries within Load() method
2137                 
2138                 //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
2139                 //CORBA::Object_var hypObject = SObjectToObject( hypSO );
2140                 int id = atoi( refFromFile );
2141                 string anIOR = myStudyContext->getIORbyOldId( id );
2142                 if ( !anIOR.empty() ) {
2143                   CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
2144                   if ( !CORBA::is_nil( hypObject ) ) {
2145                     SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
2146                     if ( !anHyp->_is_nil() && !aShapeObject->_is_nil() )
2147                       myNewMeshImpl->addHypothesis( aShapeObject, anHyp );
2148                   }
2149                 }
2150               }
2151             }
2152             aGroup->CloseOnDisk();
2153           }
2154
2155           // --> try to find submeshes containers for each type of submesh
2156           for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) {
2157             char name_meshgroup[ 30 ];
2158             if ( j == GetSubMeshOnVertexTag() )
2159               strcpy( name_meshgroup, "SubMeshes On Vertex" );
2160             else if ( j == GetSubMeshOnEdgeTag() )
2161               strcpy( name_meshgroup, "SubMeshes On Edge" );
2162             else if ( j == GetSubMeshOnWireTag() )
2163               strcpy( name_meshgroup, "SubMeshes On Wire" );
2164             else if ( j == GetSubMeshOnFaceTag() )
2165               strcpy( name_meshgroup, "SubMeshes On Face" );
2166             else if ( j == GetSubMeshOnShellTag() )
2167               strcpy( name_meshgroup, "SubMeshes On Shell" );
2168             else if ( j == GetSubMeshOnSolidTag() )
2169               strcpy( name_meshgroup, "SubMeshes On Solid" );
2170             else if ( j == GetSubMeshOnCompoundTag() )
2171               strcpy( name_meshgroup, "SubMeshes On Compound" );
2172             
2173             // try to get submeshes container HDF group
2174             if ( aTopGroup->ExistInternalObject( name_meshgroup ) ) {
2175               // open submeshes containers HDF group
2176               aGroup = new HDFgroup( name_meshgroup, aTopGroup );
2177               aGroup->OpenOnDisk();
2178               
2179               // get number of submeshes
2180               int aNbSubMeshes = aGroup->nInternalObjects(); 
2181               for ( int k = 0; k < aNbSubMeshes; k++ ) {
2182                 // identify submesh
2183                 char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ];
2184                 aGroup->InternalObjectIndentify( k, name_submeshgroup );
2185                 if ( string( name_submeshgroup ).substr( 0, 7 ) == string( "SubMesh" )  ) {
2186                   // --> get submesh id
2187                   int subid = atoi( string( name_submeshgroup ).substr( 7 ).c_str() );
2188                   if ( subid <= 0 )
2189                     continue;
2190                   // open submesh HDF group
2191                   aSubGroup = new HDFgroup( name_submeshgroup, aGroup );
2192                   aSubGroup->OpenOnDisk();
2193                   
2194                   // try to read and set reference to subshape
2195                   GEOM::GEOM_Object_var aSubShapeObject;
2196                   SMESH::SMESH_subMesh_var aSubMesh;
2197
2198                   if ( aSubGroup->ExistInternalObject( "Ref on shape" ) ) {
2199                     // load submesh "Ref on shape" - it's an entry to SObject
2200                     aDataset = new HDFdataset( "Ref on shape", aSubGroup );
2201                     aDataset->OpenOnDisk();
2202                     size = aDataset->GetSize();
2203                     char* refFromFile = new char[ size ];
2204                     aDataset->ReadFromDisk( refFromFile );
2205                     aDataset->CloseOnDisk();
2206                     if ( strlen( refFromFile ) > 0 ) {
2207                       SALOMEDS::SObject_var subShapeSO = myCurrentStudy->FindObjectID( refFromFile );
2208                       CORBA::Object_var subShapeObject = SObjectToObject( subShapeSO );
2209                       if ( !CORBA::is_nil( subShapeObject ) ) {
2210                         aSubShapeObject = GEOM::GEOM_Object::_narrow( subShapeObject );
2211                         if ( !aSubShapeObject->_is_nil() )
2212                           aSubMesh = SMESH::SMESH_subMesh::_duplicate
2213                             ( myNewMeshImpl->createSubMesh( aSubShapeObject ) );
2214                         if ( aSubMesh->_is_nil() )
2215                           continue;
2216                         string iorSubString = GetORB()->object_to_string( aSubMesh );
2217                         int newSubId = myStudyContext->findId( iorSubString );
2218                         myStudyContext->mapOldToNew( subid, newSubId );
2219                       }
2220                     }
2221                   }
2222                   
2223                   if ( aSubMesh->_is_nil() )
2224                     continue;
2225
2226                   // VSR: Get submesh data from MED convertor
2227 //                int anInternalSubmeshId = aSubMesh->GetId(); // this is not a persistent ID, it's an internal one computed from sub-shape
2228 //                if (myNewMeshImpl->_mapSubMesh.find(anInternalSubmeshId) != myNewMeshImpl->_mapSubMesh.end()) {
2229 //                  if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): loading from MED file submesh with ID = " <<
2230 //                            subid << " for subshape # " << anInternalSubmeshId);
2231 //                  SMESHDS_SubMesh* aSubMeshDS =
2232 //                      myNewMeshImpl->_mapSubMesh[anInternalSubmeshId]->CreateSubMeshDS();
2233 //                  if ( !aSubMeshDS ) {
2234 //                    if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): FAILED to create a submesh for subshape # " <<
2235 //                              anInternalSubmeshId << " in current mesh!");
2236 //                  }
2237 //                  else
2238 //                    myReader.GetSubMesh( aSubMeshDS, subid );
2239 //                }
2240                     
2241                   // try to get applied algorithms
2242                   if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) {
2243                     // open "applied algorithms" HDF group
2244                     aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
2245                     aSubSubGroup->OpenOnDisk();
2246                     // get number of applied algorithms
2247                     int aNbSubObjects = aSubSubGroup->nInternalObjects(); 
2248                     for ( int l = 0; l < aNbSubObjects; l++ ) {
2249                       char name_dataset[ HDF_NAME_MAX_LEN+1 ];
2250                       aSubSubGroup->InternalObjectIndentify( l, name_dataset );
2251                       // check if it is an algorithm
2252                       if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) {
2253                         aDataset = new HDFdataset( name_dataset, aSubSubGroup );
2254                         aDataset->OpenOnDisk();
2255                         size = aDataset->GetSize();
2256                         char* refFromFile = new char[ size ];
2257                         aDataset->ReadFromDisk( refFromFile );
2258                         aDataset->CloseOnDisk();
2259
2260                         //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
2261                         //CORBA::Object_var hypObject = SObjectToObject( hypSO );
2262                         int id = atoi( refFromFile );
2263                         string anIOR = myStudyContext->getIORbyOldId( id );
2264                         if ( !anIOR.empty() ) {
2265                           CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
2266                           if ( !CORBA::is_nil( hypObject ) ) {
2267                             SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
2268                             if ( !anHyp->_is_nil() && !aShapeObject->_is_nil() )
2269                               myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp );
2270                           }
2271                         }
2272                       }
2273                     }
2274                     // close "applied algorithms" HDF group
2275                     aSubSubGroup->CloseOnDisk();
2276                   }
2277                   
2278                   // try to get applied hypotheses
2279                   if ( aSubGroup->ExistInternalObject( "Applied Hypotheses" ) ) {
2280                     // open "applied hypotheses" HDF group
2281                     aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
2282                     aSubSubGroup->OpenOnDisk();
2283                     // get number of applied hypotheses
2284                     int aNbSubObjects = aSubSubGroup->nInternalObjects(); 
2285                     for ( int l = 0; l < aNbSubObjects; l++ ) {
2286                       char name_dataset[ HDF_NAME_MAX_LEN+1 ];
2287                       aSubSubGroup->InternalObjectIndentify( l, name_dataset );
2288                       // check if it is a hypothesis
2289                       if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) {
2290                         aDataset = new HDFdataset( name_dataset, aSubSubGroup );
2291                         aDataset->OpenOnDisk();
2292                         size = aDataset->GetSize();
2293                         char* refFromFile = new char[ size ];
2294                         aDataset->ReadFromDisk( refFromFile );
2295                         aDataset->CloseOnDisk();
2296                         
2297                         //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
2298                         //CORBA::Object_var hypObject = SObjectToObject( hypSO );
2299                         int id = atoi( refFromFile );
2300                         string anIOR = myStudyContext->getIORbyOldId( id );
2301                         if ( !anIOR.empty() ) {
2302                           CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
2303                           if ( !CORBA::is_nil( hypObject ) ) {
2304                             SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
2305                             if ( !anHyp->_is_nil() && !aShapeObject->_is_nil() )
2306                               myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp );
2307                           }
2308                         }
2309                       }
2310                     }
2311                     // close "applied hypotheses" HDF group
2312                     aSubSubGroup->CloseOnDisk();
2313                   }
2314
2315                   // close submesh HDF group
2316                   aSubGroup->CloseOnDisk();
2317                 }
2318               }
2319               // close submeshes containers HDF group
2320               aGroup->CloseOnDisk();
2321             }
2322           }
2323
2324           if(hasData) {
2325             // Read sub-meshes from MED
2326             if(MYDEBUG) MESSAGE("Create all sub-meshes");
2327             myReader.CreateAllSubMeshes();
2328
2329
2330             // Read node positions on sub-shapes (SMDS_Position)
2331
2332             if ( aTopGroup->ExistInternalObject( "Node Positions" ))
2333             {
2334               // There are 5 datasets to read:
2335               // "Nodes on Edges" - ID of node on edge
2336               // "Edge positions" - U parameter on node on edge
2337               // "Nodes on Faces" - ID of node on face
2338               // "Face U positions" - U parameter of node on face
2339               // "Face V positions" - V parameter of node on face
2340               char* aEid_DSName = "Nodes on Edges";
2341               char* aEu_DSName  = "Edge positions";
2342               char* aFu_DSName  = "Face U positions";
2343               //char* aFid_DSName = "Nodes on Faces";
2344               //char* aFv_DSName  = "Face V positions";
2345
2346               // data to retrieve
2347               int nbEids = 0, nbFids = 0;
2348               int *aEids = 0, *aFids  = 0;
2349               double *aEpos = 0, *aFupos = 0, *aFvpos = 0;
2350
2351               // open a group
2352               aGroup = new HDFgroup( "Node Positions", aTopGroup ); 
2353               aGroup->OpenOnDisk();
2354
2355               // loop on 5 data sets
2356               int aNbObjects = aGroup->nInternalObjects();
2357               for ( int i = 0; i < aNbObjects; i++ )
2358               {
2359                 // identify dataset
2360                 char aDSName[ HDF_NAME_MAX_LEN+1 ];
2361                 aGroup->InternalObjectIndentify( i, aDSName );
2362                 // read data
2363                 aDataset = new HDFdataset( aDSName, aGroup );
2364                 aDataset->OpenOnDisk();
2365                 if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions
2366                 {
2367                   double* pos = new double [ aDataset->GetSize() ];
2368                   aDataset->ReadFromDisk( pos );
2369                   // which one?
2370                   if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 )
2371                     aEpos = pos;
2372                   else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 )
2373                     aFupos = pos;
2374                   else
2375                     aFvpos = pos;
2376                 }
2377                 else // NODE IDS
2378                 {
2379                   int aSize = aDataset->GetSize();
2380
2381                   // for reading files, created from 18.07.2005 till 10.10.2005
2382                   if (aDataset->GetType() == HDF_STRING)
2383                     aSize /= sizeof(int);
2384
2385                   int* ids = new int [aSize];
2386                   aDataset->ReadFromDisk( ids );
2387                   // on face or nodes?
2388                   if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) {
2389                     aEids = ids;
2390                     nbEids = aSize;
2391                   }
2392                   else {
2393                     aFids = ids;
2394                     nbFids = aSize;
2395                   }
2396                 }
2397               } // loop on 5 datasets
2398
2399               // Set node positions on edges or faces
2400               for ( int onFace = 0; onFace < 2; onFace++ )
2401               {
2402                 int nbNodes = ( onFace ? nbFids : nbEids );
2403                 if ( nbNodes == 0 ) continue;
2404                 int* aNodeIDs = ( onFace ? aFids : aEids );
2405                 double* aUPos = ( onFace ? aFupos : aEpos );
2406                 double* aVPos = ( onFace ? aFvpos : 0 );
2407                 // loop on node IDs
2408                 for ( int iNode = 0; iNode < nbNodes; iNode++ )
2409                 {
2410                   const SMDS_MeshNode* node = mySMESHDSMesh->FindNode( aNodeIDs[ iNode ]);
2411                   ASSERT( node );
2412                   SMDS_PositionPtr aPos = node->GetPosition();
2413                   ASSERT( aPos )
2414                   if ( onFace ) {
2415                     ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );
2416                     SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
2417                       ( static_cast<const SMDS_FacePosition*>( aPos.get() ));
2418                     fPos->SetUParameter( aUPos[ iNode ]);
2419                     fPos->SetVParameter( aVPos[ iNode ]);
2420                   }
2421                   else {
2422                     ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );
2423                     SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
2424                       ( static_cast<const SMDS_EdgePosition*>( aPos.get() ));
2425                     fPos->SetUParameter( aUPos[ iNode ]);
2426                   }
2427                 }
2428               }
2429               if ( aEids ) delete [] aEids;
2430               if ( aFids ) delete [] aFids;
2431               if ( aEpos ) delete [] aEpos;
2432               if ( aFupos ) delete [] aFupos;
2433               if ( aFvpos ) delete [] aFvpos;
2434               
2435               aGroup->CloseOnDisk();
2436
2437             } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) )
2438           } // if ( hasData )
2439
2440           // Recompute State (as computed sub-meshes are restored from MED)
2441           if ( !aShapeObject->_is_nil() ) {
2442             MESSAGE("Compute State Engine ...");
2443             TopoDS_Shape myLocShape = GeomObjectToShape( aShapeObject );
2444             myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine
2445               (SMESH_subMesh::SUBMESH_RESTORED);
2446             MESSAGE("Compute State Engine finished");
2447           }
2448
2449           // try to get groups
2450           for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) {
2451             char name_group[ 30 ];
2452             if ( ii == GetNodeGroupsTag() )
2453               strcpy( name_group, "Groups of Nodes" );
2454             else if ( ii == GetEdgeGroupsTag() )
2455               strcpy( name_group, "Groups of Edges" );
2456             else if ( ii == GetFaceGroupsTag() )
2457               strcpy( name_group, "Groups of Faces" );
2458             else if ( ii == GetVolumeGroupsTag() )
2459               strcpy( name_group, "Groups of Volumes" );
2460
2461             if ( aTopGroup->ExistInternalObject( name_group ) ) {
2462               aGroup = new HDFgroup( name_group, aTopGroup );
2463               aGroup->OpenOnDisk();
2464               // get number of groups
2465               int aNbSubObjects = aGroup->nInternalObjects(); 
2466               for ( int j = 0; j < aNbSubObjects; j++ ) {
2467                 char name_dataset[ HDF_NAME_MAX_LEN+1 ];
2468                 aGroup->InternalObjectIndentify( j, name_dataset );
2469                 // check if it is an group
2470                 if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) {
2471                   // --> get group id
2472                   int subid = atoi( string( name_dataset ).substr( 5 ).c_str() );
2473                   if ( subid <= 0 )
2474                     continue;
2475                   aDataset = new HDFdataset( name_dataset, aGroup );
2476                   aDataset->OpenOnDisk();
2477
2478                   // Retrieve actual group name
2479                   size = aDataset->GetSize();
2480                   char* nameFromFile = new char[ size ];
2481                   aDataset->ReadFromDisk( nameFromFile );
2482                   aDataset->CloseOnDisk();
2483
2484                   // Try to find a shape reference
2485                   TopoDS_Shape aShape;
2486                   char aRefName[ 30 ];
2487                   sprintf( aRefName, "Ref on shape %d", subid);
2488                   if ( aGroup->ExistInternalObject( aRefName ) ) {
2489                     // load mesh "Ref on shape" - it's an entry to SObject
2490                     aDataset = new HDFdataset( aRefName, aGroup );
2491                     aDataset->OpenOnDisk();
2492                     size = aDataset->GetSize();
2493                     char* refFromFile = new char[ size ];
2494                     aDataset->ReadFromDisk( refFromFile );
2495                     aDataset->CloseOnDisk();
2496                     if ( strlen( refFromFile ) > 0 ) {
2497                       SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile );
2498                       CORBA::Object_var shapeObject = SObjectToObject( shapeSO );
2499                       if ( !CORBA::is_nil( shapeObject ) ) {
2500                         aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject );
2501                         if ( !aShapeObject->_is_nil() )
2502                           aShape = GeomObjectToShape( aShapeObject );
2503                       }
2504                     }
2505                   }
2506                   // Create group servant
2507                   SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1);
2508                   SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate
2509                     ( myNewMeshImpl->createGroup( type, nameFromFile, aShape ) );
2510                   // Obtain a SMESHDS_Group object 
2511                   if ( aNewGroup->_is_nil() )
2512                     continue;
2513
2514                   string iorSubString = GetORB()->object_to_string( aNewGroup );
2515                   int newSubId = myStudyContext->findId( iorSubString );
2516                   myStudyContext->mapOldToNew( subid, newSubId );
2517
2518                   SMESH_GroupBase_i* aGroupImpl =
2519                     dynamic_cast<SMESH_GroupBase_i*>( GetServant( aNewGroup ).in() );
2520                   if ( !aGroupImpl )
2521                     continue;
2522
2523                   SMESH_Group* aLocalGroup  = myLocMesh.GetGroup( aGroupImpl->GetLocalID() );
2524                   if ( !aLocalGroup )
2525                     continue;
2526
2527                   SMESHDS_GroupBase* aGroupBaseDS = aLocalGroup->GetGroupDS();
2528                   aGroupBaseDS->SetStoreName( name_dataset );
2529
2530                   // Fill group with contents from MED file
2531                   SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( aGroupBaseDS );
2532                   if ( aGrp )
2533                     myReader.GetGroup( aGrp );
2534                 }
2535               }
2536               aGroup->CloseOnDisk();
2537             }
2538           }
2539         }
2540         // close mesh group
2541         aTopGroup->CloseOnDisk();       
2542       }
2543     }
2544   }
2545   // close HDF file
2546   aFile->CloseOnDisk();
2547   delete aFile;
2548
2549   // Remove temporary files created from the stream
2550   if ( !isMultiFile ) 
2551     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
2552
2553   INFOS( "SMESH_Gen_i::Load completed" );
2554   return true;
2555 }
2556
2557 //=============================================================================
2558 /*!
2559  *  SMESH_Gen_i::LoadASCII
2560  *
2561  *  Load SMESH module's data in ASCII format (not implemented yet)
2562  */
2563 //=============================================================================
2564
2565 bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent,
2566                              const SALOMEDS::TMPFile& theStream,
2567                              const char*              theURL,
2568                              bool                     isMultiFile ) {
2569   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LoadASCII" );
2570   return Load( theComponent, theStream, theURL, isMultiFile );
2571 }
2572
2573 //=============================================================================
2574 /*!
2575  *  SMESH_Gen_i::Close
2576  *
2577  *  Clears study-connected data when it is closed
2578  */
2579 //=============================================================================
2580
2581 void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
2582 {
2583   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" );
2584
2585   // Clear study contexts data
2586   int studyId = GetCurrentStudyID();
2587   if ( myStudyContextMap.find( studyId ) != myStudyContextMap.end() ) {
2588     delete myStudyContextMap[ studyId ];
2589     myStudyContextMap.erase( studyId );
2590   }
2591   return;
2592 }
2593
2594 //=============================================================================
2595 /*!
2596  *  SMESH_Gen_i::ComponentDataType
2597  * 
2598  *  Get component data type
2599  */
2600 //=============================================================================
2601
2602 char* SMESH_Gen_i::ComponentDataType()
2603 {
2604   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::ComponentDataType" );
2605   return CORBA::string_dup( "SMESH" );
2606 }
2607
2608     
2609 //=============================================================================
2610 /*!
2611  *  SMESH_Gen_i::IORToLocalPersistentID
2612  *  
2613  *  Transform data from transient form to persistent
2614  */
2615 //=============================================================================
2616
2617 char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/,
2618                                            const char*           IORString,
2619                                            CORBA::Boolean        /*isMultiFile*/,
2620                                            CORBA::Boolean        /*isASCII*/ )
2621 {
2622   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" );
2623   StudyContext* myStudyContext = GetCurrentStudyContext();
2624   
2625   if ( myStudyContext && strcmp( IORString, "" ) != 0 ) {
2626     int anId = myStudyContext->findId( IORString );
2627     if ( anId ) {
2628       if(MYDEBUG) MESSAGE( "VSR " << anId )
2629       char strId[ 20 ];
2630       sprintf( strId, "%d", anId );
2631       return  CORBA::string_dup( strId );
2632     }
2633   }
2634   return CORBA::string_dup( "" );
2635 }
2636
2637 //=============================================================================
2638 /*!
2639  *  SMESH_Gen_i::LocalPersistentIDToIOR
2640  *
2641  *  Transform data from persistent form to transient
2642  */
2643 //=============================================================================
2644
2645 char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/,
2646                                            const char*           aLocalPersistentID,
2647                                            CORBA::Boolean        /*isMultiFile*/,
2648                                            CORBA::Boolean        /*isASCII*/ )
2649 {
2650   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID );
2651   StudyContext* myStudyContext = GetCurrentStudyContext();
2652
2653   if ( myStudyContext && strcmp( aLocalPersistentID, "" ) != 0 ) {
2654     int anId = atoi( aLocalPersistentID );
2655     return CORBA::string_dup( myStudyContext->getIORbyOldId( anId ).c_str() );
2656   }
2657   return CORBA::string_dup( "" );
2658 }
2659
2660 //=======================================================================
2661 //function : RegisterObject
2662 //purpose  : 
2663 //=======================================================================
2664
2665 int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject)
2666 {
2667   StudyContext* myStudyContext = GetCurrentStudyContext();
2668   if ( myStudyContext && !CORBA::is_nil( theObject )) {
2669     string iorString = GetORB()->object_to_string( theObject );
2670     return myStudyContext->addObject( iorString );
2671   }
2672   return 0;
2673 }
2674       
2675 //=============================================================================
2676 /*! 
2677  *  SMESHEngine_factory
2678  *
2679  *  C factory, accessible with dlsym, after dlopen  
2680  */
2681 //=============================================================================
2682
2683 extern "C"
2684 {
2685   PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr            orb,
2686                                                  PortableServer::POA_ptr   poa, 
2687                                                  PortableServer::ObjectId* contId,
2688                                                  const char*               instanceName, 
2689                                                  const char*               interfaceName )
2690   {
2691     if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" );
2692     if(MYDEBUG) SCRUTE(interfaceName);
2693     SMESH_Gen_i* aSMESHGen = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName);
2694     return aSMESHGen->getId() ;
2695   }
2696 }