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