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