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