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