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