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