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