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