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