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