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