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