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