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