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