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