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