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