Version: 6.3.1

src/SMESH_I/SMESH_Gen_i.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File   : SMESH_Gen_i.cxx
00023 //  Author : Paul RASCLE, EDF
00024 //  Module : SMESH
00025 
00026 #include <TopExp.hxx>
00027 #include <TopExp_Explorer.hxx>
00028 #include <TopoDS.hxx>
00029 #include <TopoDS_Iterator.hxx>
00030 #include <TopoDS_Compound.hxx>
00031 #include <TopoDS_CompSolid.hxx>
00032 #include <TopoDS_Solid.hxx>
00033 #include <TopoDS_Shell.hxx>
00034 #include <TopoDS_Face.hxx>
00035 #include <TopoDS_Wire.hxx>
00036 #include <TopoDS_Edge.hxx>
00037 #include <TopoDS_Vertex.hxx>
00038 #include <TopoDS_Shape.hxx>
00039 #include <TopTools_MapOfShape.hxx>
00040 #include <TopTools_IndexedMapOfShape.hxx>
00041 #include <TopTools_ListOfShape.hxx>
00042 #include <TopTools_ListIteratorOfListOfShape.hxx>
00043 #include <gp_Pnt.hxx>
00044 #include <BRep_Tool.hxx>
00045 #include <TCollection_AsciiString.hxx>
00046 #include <OSD.hxx>
00047 
00048 #include "Utils_CorbaException.hxx"
00049 
00050 #include "utilities.h"
00051 #include <fstream>
00052 #include <stdio.h>
00053 
00054 #ifdef WNT
00055  #include <windows.h>
00056  #include <process.h>
00057 #else
00058  #include <dlfcn.h>
00059 #endif
00060 
00061 #ifdef WNT
00062  #define LibHandle HMODULE
00063  #define LoadLib( name ) LoadLibrary( name )
00064  #define GetProc GetProcAddress
00065  #define UnLoadLib( handle ) FreeLibrary( handle );
00066 #else
00067  #define LibHandle void*
00068  #define LoadLib( name ) dlopen( name, RTLD_LAZY )
00069  #define GetProc dlsym
00070  #define UnLoadLib( handle ) dlclose( handle );
00071 #endif
00072 
00073 #include <HDFOI.hxx>
00074 
00075 #include "SMESH_Gen_i.hxx"
00076 #include "SMESH_Mesh_i.hxx"
00077 #include "SMESH_Hypothesis_i.hxx"
00078 #include "SMESH_Algo_i.hxx"
00079 #include "SMESH_Group_i.hxx"
00080 #include "SMESH_PythonDump.hxx"
00081 
00082 #include "SMESHDS_Document.hxx"
00083 #include "SMESHDS_Group.hxx"
00084 #include "SMESHDS_GroupOnGeom.hxx"
00085 #include "SMESH_Mesh.hxx"
00086 #include "SMESH_Hypothesis.hxx"
00087 #include "SMESH_Group.hxx"
00088 #include "SMESH_MeshEditor.hxx"
00089 
00090 #include "SMDS_EdgePosition.hxx"
00091 #include "SMDS_FacePosition.hxx"
00092 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
00093 #include "SMDS_SetIterator.hxx"
00094 #include "SMDS_SpacePosition.hxx"
00095 #include "SMDS_VertexPosition.hxx"
00096 
00097 #include CORBA_SERVER_HEADER(SMESH_Group)
00098 #include CORBA_SERVER_HEADER(SMESH_Filter)
00099 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
00100 
00101 #include "DriverMED_W_SMESHDS_Mesh.h"
00102 #include "DriverMED_R_SMESHDS_Mesh.h"
00103 
00104 #include "SALOMEDS_Tool.hxx"
00105 #include "SALOME_NamingService.hxx"
00106 #include "SALOME_LifeCycleCORBA.hxx"
00107 #include "Utils_SINGLETON.hxx"
00108 #include "OpUtil.hxx"
00109 
00110 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
00111 #include CORBA_CLIENT_HEADER(SALOME_Session)
00112 
00113 #include "GEOM_Client.hxx"
00114 #include "Utils_ExceptHandlers.hxx"
00115 #include "memoire.h"
00116 #include "Basics_Utils.hxx"
00117 
00118 #include <map>
00119 
00120 using namespace std;
00121 using SMESH::TPythonDump;
00122 
00123 #define NUM_TMP_FILES 2
00124 
00125 #ifdef _DEBUG_
00126 static int MYDEBUG = 0;
00127 #else
00128 static int MYDEBUG = 0;
00129 #endif
00130 
00131 // Static variables definition
00132 GEOM::GEOM_Gen_var      SMESH_Gen_i::myGeomGen = GEOM::GEOM_Gen::_nil();
00133 CORBA::ORB_var          SMESH_Gen_i::myOrb;
00134 PortableServer::POA_var SMESH_Gen_i::myPoa;
00135 SALOME_NamingService*   SMESH_Gen_i::myNS  = NULL;
00136 SALOME_LifeCycleCORBA*  SMESH_Gen_i::myLCC = NULL;
00137 SMESH_Gen_i*            SMESH_Gen_i::mySMESHGen = NULL;
00138 
00139 
00140 const int nbElemPerDiagonal = 10;
00141 
00142 //=============================================================================
00148 //=============================================================================
00149 
00150 PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theObject )
00151 {
00152   if( CORBA::is_nil( theObject ) || CORBA::is_nil( GetPOA() ) )
00153     return NULL;
00154   try {
00155     PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject );
00156     return aServant;
00157   }
00158   catch (...) {
00159     INFOS( "GetServant - Unknown exception was caught!!!" );
00160     return NULL;
00161   }
00162 }
00163 
00164 //=============================================================================
00170 //=============================================================================
00171 
00172 CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject )
00173 {
00174   SALOMEDS::GenericAttribute_var anAttr;
00175   CORBA::Object_var anObj;
00176   if ( !theSObject->_is_nil() ) {
00177     try {
00178       if( theSObject->FindAttribute( anAttr, "AttributeIOR" ) ) {
00179         SALOMEDS::AttributeIOR_var anIOR  = SALOMEDS::AttributeIOR::_narrow( anAttr );
00180         CORBA::String_var aValue = anIOR->Value();
00181         if( strcmp( aValue, "" ) != 0 )
00182           anObj = GetORB()->string_to_object( aValue );
00183         }
00184     }
00185     catch( ... ) {
00186       INFOS( "SObjectToObject - Unknown exception was caught!!!" );
00187     }
00188   }
00189   return anObj;
00190 }
00191 
00192 //=============================================================================
00198 //=============================================================================
00199 
00200 SALOME_NamingService* SMESH_Gen_i::GetNS()
00201 {
00202   if ( myNS == NULL ) {
00203     myNS = SINGLETON_<SALOME_NamingService>::Instance();
00204     ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting());
00205     myNS->init_orb( GetORB() );
00206   }
00207   return myNS;
00208 }
00209 
00210 //=============================================================================
00216 //=============================================================================
00217 SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
00218   if ( myLCC == NULL ) {
00219     myLCC = new SALOME_LifeCycleCORBA( GetNS() );
00220   }
00221   return myLCC;
00222 }
00223 
00224 
00225 //=============================================================================
00231 //=============================================================================
00232 GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() {
00233   //CCRT GEOM::GEOM_Gen_var aGeomEngine =
00234   //CCRT   GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") );
00235   //CCRT return aGeomEngine._retn();
00236   if(CORBA::is_nil(myGeomGen))
00237   {
00238     Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM");
00239     myGeomGen=GEOM::GEOM_Gen::_narrow(temp);
00240   }
00241   return myGeomGen;
00242 }
00243 
00244 //=============================================================================
00250 //=============================================================================
00251 
00252 SMESH_Gen_i::SMESH_Gen_i()
00253 {
00254   INFOS( "SMESH_Gen_i::SMESH_Gen_i : default constructor" );
00255 }
00256 
00257 //=============================================================================
00263 //=============================================================================
00264 
00265 SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
00266                           PortableServer::POA_ptr   poa,
00267                           PortableServer::ObjectId* contId,
00268                           const char*               instanceName,
00269                           const char*               interfaceName )
00270      : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
00271 {
00272   MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
00273 
00274   myOrb = CORBA::ORB::_duplicate(orb);
00275   myPoa = PortableServer::POA::_duplicate(poa);
00276 
00277   _thisObj = this ;
00278   _id = myPoa->activate_object( _thisObj );
00279 
00280   myIsEmbeddedMode = false;
00281   myShapeReader = NULL;  // shape reader
00282   mySMESHGen = this;
00283 
00284   // set it in standalone mode only
00285   //OSD::SetSignal( true );
00286 
00287   // 0020605: EDF 1190 SMESH: Display performance. 80 seconds for 52000 cells.
00288   // find out mode (embedded or standalone) here else
00289   // meshes created before calling SMESH_Client::GetSMESHGen(), which calls
00290   // SMESH_Gen_i::SetEmbeddedMode(), have wrong IsEmbeddedMode flag
00291   if ( SALOME_NamingService* ns = GetNS() )
00292   {
00293     CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" );
00294     SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
00295     if ( !session->_is_nil() )
00296     {
00297       CORBA::String_var s_host = session->getHostname();
00298       CORBA::Long        s_pid = session->getPID();
00299       string my_host = Kernel_Utils::GetHostname();
00300 #ifdef WNT
00301       long    my_pid = (long)_getpid();
00302 #else
00303       long    my_pid = (long) getpid();
00304 #endif
00305       SetEmbeddedMode( s_pid == my_pid && my_host == s_host.in() );
00306     }
00307   }
00308 }
00309 
00310 //=============================================================================
00316 //=============================================================================
00317 
00318 SMESH_Gen_i::~SMESH_Gen_i()
00319 {
00320   MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" );
00321 
00322   // delete hypothesis creators
00323   map<string, GenericHypothesisCreator_i*>::iterator itHyp;
00324   for (itHyp = myHypCreatorMap.begin(); itHyp != myHypCreatorMap.end(); itHyp++)
00325   {
00326     delete (*itHyp).second;
00327   }
00328   myHypCreatorMap.clear();
00329 
00330   // Clear study contexts data
00331   map<int, StudyContext*>::iterator it;
00332   for ( it = myStudyContextMap.begin(); it != myStudyContextMap.end(); ++it ) {
00333     delete it->second;
00334   }
00335   myStudyContextMap.clear();
00336   // delete shape reader
00337   if ( !myShapeReader )
00338     delete myShapeReader;
00339 }
00340 
00341 //=============================================================================
00347 //=============================================================================
00348 SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName,
00349                                                           const char* theLibName)
00350      throw (SALOME::SALOME_Exception)
00351 {
00352   /* It's Need to tranlate lib name for WIN32 or X platform */
00353   char* aPlatformLibName = 0;
00354   if ( theLibName && theLibName[0] != '\0'  )
00355   {
00356     int libNameLen = strlen(theLibName);
00357     //check for old format "libXXXXXXX.so"
00358     if (libNameLen > 7 &&
00359         !strncmp( theLibName, "lib", 3 ) &&
00360         !strcmp( theLibName+libNameLen-3, ".so" ))
00361     {
00362       //the old format
00363 #ifdef WNT
00364       aPlatformLibName = new char[libNameLen - 1];
00365       aPlatformLibName[0] = '\0';
00366       aPlatformLibName = strncat( aPlatformLibName, theLibName+3, libNameLen-6  );
00367       aPlatformLibName = strcat( aPlatformLibName, ".dll" );
00368       aPlatformLibName[libNameLen - 2] = '\0';
00369 #else
00370       aPlatformLibName = new char[ libNameLen + 1];
00371       aPlatformLibName[0] = '\0';
00372       aPlatformLibName = strcat( aPlatformLibName, theLibName );
00373       aPlatformLibName[libNameLen] = '\0';
00374 #endif
00375     }
00376     else
00377     {
00378       //try to use new format
00379 #ifdef WNT
00380       aPlatformLibName = new char[ libNameLen + 5 ];
00381       aPlatformLibName[0] = '\0';
00382       aPlatformLibName = strcat( aPlatformLibName, theLibName );
00383       aPlatformLibName = strcat( aPlatformLibName, ".dll" );
00384 #else
00385       aPlatformLibName = new char[ libNameLen + 7 ];
00386       aPlatformLibName[0] = '\0';
00387       aPlatformLibName = strcat( aPlatformLibName, "lib" );
00388       aPlatformLibName = strcat( aPlatformLibName, theLibName );
00389       aPlatformLibName = strcat( aPlatformLibName, ".so" );
00390 #endif
00391     }
00392   }
00393 
00394 
00395   Unexpect aCatch(SALOME_SalomeException);
00396   if(MYDEBUG) MESSAGE( "Create Hypothesis <" << theHypName << "> from " << aPlatformLibName/*theLibName*/);
00397 
00398   // create a new hypothesis object servant
00399   SMESH_Hypothesis_i* myHypothesis_i = 0;
00400   SMESH::SMESH_Hypothesis_var hypothesis_i;
00401 
00402   try
00403   {
00404     // check, if creator for this hypothesis type already exists
00405     if (myHypCreatorMap.find(string(theHypName)) == myHypCreatorMap.end())
00406     {
00407       // load plugin library
00408       if(MYDEBUG) MESSAGE("Loading server meshers plugin library ...");
00409       LibHandle libHandle = LoadLib( aPlatformLibName/*theLibName*/ );
00410       if (!libHandle)
00411       {
00412         // report any error, if occured
00413 #ifndef WNT
00414         const char* anError = dlerror();
00415         throw(SALOME_Exception(anError));
00416 #else
00417         throw(SALOME_Exception(LOCALIZED( "Can't load server meshers plugin library" )));
00418 #endif
00419       }
00420 
00421       // get method, returning hypothesis creator
00422       if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
00423       typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char* theHypName);
00424       GetHypothesisCreator procHandle =
00425         (GetHypothesisCreator)GetProc( libHandle, "GetHypothesisCreator" );
00426       if (!procHandle)
00427       {
00428         throw(SALOME_Exception(LOCALIZED("bad hypothesis plugin library")));
00429         UnLoadLib(libHandle);
00430       }
00431 
00432       // get hypothesis creator
00433       if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << theHypName);
00434       GenericHypothesisCreator_i* aCreator = procHandle(theHypName);
00435       if (!aCreator)
00436       {
00437         throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin")));
00438       }
00439 
00440       // map hypothesis creator to a hypothesis name
00441       myHypCreatorMap[string(theHypName)] = aCreator;
00442     }
00443 
00444     // create a new hypothesis object, store its ref. in studyContext
00445     if(MYDEBUG) MESSAGE("Create Hypothesis " << theHypName);
00446     myHypothesis_i =
00447       myHypCreatorMap[string(theHypName)]->Create(myPoa, GetCurrentStudyID(), &myGen);
00448     myHypothesis_i->SetLibName(aPlatformLibName/*theLibName*/); // for persistency assurance
00449   }
00450   catch (SALOME_Exception& S_ex)
00451   {
00452     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00453   }
00454 
00455   if ( aPlatformLibName )
00456     delete[] aPlatformLibName;
00457 
00458   if (!myHypothesis_i)
00459     return hypothesis_i._retn();
00460 
00461   // activate the CORBA servant of hypothesis
00462   hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() );
00463   int nextId = RegisterObject( hypothesis_i );
00464   if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId );
00465 
00466   return hypothesis_i._retn();
00467 }
00468 
00469 //=============================================================================
00475 //=============================================================================
00476 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
00477      throw ( SALOME::SALOME_Exception )
00478 {
00479   Unexpect aCatch(SALOME_SalomeException);
00480   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::createMesh" );
00481 
00482   // Get or create the GEOM_Client instance
00483   try {
00484     // create a new mesh object servant, store it in a map in study context
00485     SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() );
00486     // create a new mesh object
00487     MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
00488     meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode ));
00489 
00490     // activate the CORBA servant of Mesh
00491     SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() );
00492     int nextId = RegisterObject( mesh );
00493     if(MYDEBUG) MESSAGE( "Add mesh to map with id = "<< nextId);
00494     return mesh._retn();
00495   }
00496   catch (SALOME_Exception& S_ex) {
00497     THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
00498   }
00499   return SMESH::SMESH_Mesh::_nil();
00500 }
00501 
00502 //=============================================================================
00508 //=============================================================================
00509 GEOM_Client* SMESH_Gen_i::GetShapeReader()
00510 {
00511   // create shape reader if necessary
00512   if ( !myShapeReader )
00513     myShapeReader = new GEOM_Client(GetContainerRef());
00514   ASSERT( myShapeReader );
00515   return myShapeReader;
00516 }
00517 
00518 //=============================================================================
00524 //=============================================================================
00525 //GEOM::GEOM_Gen_ptr SMESH_Gen_i::SetGeomEngine( const char* containerLoc )
00526 void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo )
00527 {
00528   //Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component(containerLoc,"GEOM");
00529   //myGeomGen=GEOM::GEOM_Gen::_narrow(temp);
00530   myGeomGen=GEOM::GEOM_Gen::_duplicate(geomcompo);
00531   //return myGeomGen;
00532 }
00533 
00534 //=============================================================================
00540 //=============================================================================
00541 
00542 void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode )
00543 {
00544   myIsEmbeddedMode = theMode;
00545   MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
00546 
00547   if ( !myIsEmbeddedMode ) {
00548     //PAL10867: disable signals catching with "noexcepthandler" option
00549     char* envNoCatchSignals = getenv("NOT_INTERCEPT_SIGNALS");
00550     if (!envNoCatchSignals || !atoi(envNoCatchSignals))
00551     {
00552       bool raiseFPE;
00553 #ifdef _DEBUG_
00554       raiseFPE = true;
00555       char* envDisableFPE = getenv("DISABLE_FPE");
00556       if (envDisableFPE && atoi(envDisableFPE))
00557         raiseFPE = false;
00558 #else
00559       raiseFPE = false;
00560 #endif
00561       OSD::SetSignal( raiseFPE );
00562     }
00563     // else OSD::SetSignal() is called in GUI
00564   }
00565 }
00566 
00567 //=============================================================================
00573 //=============================================================================
00574 
00575 CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode()
00576 {
00577   return myIsEmbeddedMode;
00578 }
00579 
00580 //=============================================================================
00586 //=============================================================================
00587 
00588 void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy )
00589 {
00590   int curStudyId = GetCurrentStudyID();
00591   myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy );
00592   // create study context, if it doesn't exist and set current study
00593   int studyId = GetCurrentStudyID();
00594   if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) {
00595     myStudyContextMap[ studyId ] = new StudyContext;
00596   }
00597 
00598   // myCurrentStudy may be nil
00599   if ( !CORBA::is_nil( myCurrentStudy ) ) {
00600     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
00601     if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
00602       aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() );
00603 
00604     // NPAL16168, issue 0020210
00605     // Let meshes update their data depending on GEOM groups that could change
00606     if ( curStudyId != studyId )
00607     {
00608       //SALOMEDS::SComponent_var me =  PublishComponent( myCurrentStudy );
00609       SALOMEDS::SComponent_var me = SALOMEDS::SComponent::_narrow
00610         ( myCurrentStudy->FindComponent( ComponentDataType() ) );
00611       if ( !me->_is_nil() ) {
00612         SALOMEDS::ChildIterator_var anIter = myCurrentStudy->NewChildIterator( me );
00613         for ( ; anIter->More(); anIter->Next() ) {
00614           SALOMEDS::SObject_var so = anIter->Value();
00615           CORBA::Object_var    ior = SObjectToObject( so );
00616           if ( SMESH_Mesh_i*  mesh = SMESH::DownCast<SMESH_Mesh_i*>( ior ))
00617             mesh->CheckGeomGroupModif();
00618         }
00619       }
00620     }
00621   }
00622 }
00623 
00624 //=============================================================================
00630 //=============================================================================
00631 
00632 SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy()
00633 {
00634   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetCurrentStudy: study Id = " << GetCurrentStudyID() );
00635   return SALOMEDS::Study::_duplicate( myCurrentStudy );
00636 }
00637 
00638 //=============================================================================
00644 //=============================================================================
00645 StudyContext* SMESH_Gen_i::GetCurrentStudyContext()
00646 {
00647   if ( !CORBA::is_nil( myCurrentStudy ) &&
00648       myStudyContextMap.find( GetCurrentStudyID() ) != myStudyContextMap.end() )
00649     return myStudyContextMap[ myCurrentStudy->StudyId() ];
00650   else
00651     return 0;
00652 }
00653 
00654 //=============================================================================
00660 //=============================================================================
00661 
00662 SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypName,
00663                                                            const char* theLibName )
00664      throw ( SALOME::SALOME_Exception )
00665 {
00666   Unexpect aCatch(SALOME_SalomeException);
00667   // Create hypothesis/algorithm
00668   SMESH::SMESH_Hypothesis_var hyp = this->createHypothesis( theHypName, theLibName );
00669 
00670   // Publish hypothesis/algorithm in the study
00671   if ( CanPublishInStudy( hyp ) ) {
00672     SALOMEDS::SObject_var aSO = PublishHypothesis( myCurrentStudy, hyp );
00673     if ( !aSO->_is_nil() ) {
00674       // Update Python script
00675       TPythonDump() << aSO << " = " << this << ".CreateHypothesis('"
00676                     << theHypName << "', '" << theLibName << "')";
00677     }
00678   }
00679 
00680   return hyp._retn();
00681 }
00682 
00683 //================================================================================
00695 //================================================================================
00696 
00697 SMESH::SMESH_Hypothesis_ptr
00698 SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
00699                                            const char*           theLibName,
00700                                            SMESH::SMESH_Mesh_ptr theMesh,
00701                                            GEOM::GEOM_Object_ptr theGeom,
00702                                            CORBA::Boolean        byMesh)
00703   throw ( SALOME::SALOME_Exception )
00704 {
00705   Unexpect aCatch(SALOME_SalomeException);
00706   if ( byMesh && CORBA::is_nil( theMesh ) )
00707     return SMESH::SMESH_Hypothesis::_nil();
00708   if ( byMesh && CORBA::is_nil( theGeom ) )
00709     return SMESH::SMESH_Hypothesis::_nil();
00710 
00711   // -----------------------------------------------
00712   // find hypothesis used to mesh theGeom
00713   // -----------------------------------------------
00714 
00715   // get mesh and shape
00716   SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
00717   TopoDS_Shape shape = GeomObjectToShape( theGeom );
00718   if ( byMesh && ( !meshServant || meshServant->NbNodes()==0 || shape.IsNull() ))
00719     return SMESH::SMESH_Hypothesis::_nil();
00720   ::SMESH_Mesh* mesh = meshServant ? &meshServant->GetImpl() : (::SMESH_Mesh*)0;
00721 
00722   // create a temporary hypothesis to know its dimention
00723   SMESH::SMESH_Hypothesis_var tmpHyp = this->createHypothesis( theHypType, theLibName );
00724   SMESH_Hypothesis_i* hypServant = SMESH::DownCast<SMESH_Hypothesis_i*>( tmpHyp );
00725   if ( !hypServant )
00726     return SMESH::SMESH_Hypothesis::_nil();
00727   ::SMESH_Hypothesis* hyp = hypServant->GetImpl();
00728 
00729   if ( byMesh ) {
00730     // look for a hypothesis of theHypType used to mesh the shape
00731     if ( myGen.GetShapeDim( shape ) == hyp->GetDim() )
00732     {
00733       // check local shape
00734       SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( theGeom );
00735       int nbLocalHyps = aHypList->length();
00736       for ( int i = 0; i < nbLocalHyps; i++ )
00737         if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND local!
00738           return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] );
00739       // check super shapes
00740       TopTools_ListIteratorOfListOfShape itShape( mesh->GetAncestors( shape ));
00741       while ( nbLocalHyps == 0 && itShape.More() ) {
00742         GEOM::GEOM_Object_ptr geomObj = ShapeToGeomObject( itShape.Value() );
00743         if ( ! CORBA::is_nil( geomObj )) {
00744           SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( geomObj );
00745           nbLocalHyps = aHypList->length();
00746           for ( int i = 0; i < nbLocalHyps; i++ )
00747             if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND global!
00748               return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] );
00749         }
00750         itShape.Next();
00751       }
00752     }
00753 
00754     // let the temporary hypothesis find out some how parameter values by mesh
00755     if ( hyp->SetParametersByMesh( mesh, shape ))
00756       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
00757   }
00758   else {
00759     double diagonal = 0;
00760     if ( mesh )
00761       diagonal = mesh->GetShapeDiagonalSize();
00762     else
00763       diagonal = ::SMESH_Mesh::GetShapeDiagonalSize( shape );
00764     ::SMESH_Hypothesis::TDefaults dflts;
00765     dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation();
00766     dflts._nbSegments = myGen.GetDefaultNbSegments();
00767     // let the temporary hypothesis initialize it's values
00768     if ( hyp->SetParametersByDefaults( dflts, mesh ))
00769       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
00770   }
00771 
00772   return SMESH::SMESH_Hypothesis::_nil();
00773 }
00774 
00775 //=============================================================================
00780 //=============================================================================
00781 
00782 void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long theNbSegments )
00783   throw ( SALOME::SALOME_Exception )
00784 {
00785   if ( theNbSegments > 0 )
00786     myGen.SetBoundaryBoxSegmentation( int( theNbSegments ));
00787   else
00788     THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM );
00789 }
00790 //=============================================================================
00794 //=============================================================================
00795 void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments)
00796   throw ( SALOME::SALOME_Exception )
00797 {
00798   if ( theNbSegments > 0 )
00799     myGen.SetDefaultNbSegments( int(theNbSegments) );
00800   else
00801     THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM );
00802 }
00803 
00804 //=============================================================================
00810 //=============================================================================
00811 
00812 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObject )
00813      throw ( SALOME::SALOME_Exception )
00814 {
00815   Unexpect aCatch(SALOME_SalomeException);
00816   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
00817   // create mesh
00818   SMESH::SMESH_Mesh_var mesh = this->createMesh();
00819   // set shape
00820   SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
00821   ASSERT( meshServant );
00822   meshServant->SetShape( theShapeObject );
00823 
00824   // publish mesh in the study
00825   if ( CanPublishInStudy( mesh ) ) {
00826     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
00827     aStudyBuilder->NewCommand();  // There is a transaction
00828     SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() );
00829     aStudyBuilder->CommitCommand();
00830     if ( !aSO->_is_nil() ) {
00831       // Update Python script
00832       TPythonDump() << aSO << " = " << this << ".CreateMesh(" << theShapeObject << ")";
00833     }
00834   }
00835 
00836   return mesh._retn();
00837 }
00838 
00839 //=============================================================================
00845 //=============================================================================
00846 
00847 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh()
00848      throw ( SALOME::SALOME_Exception )
00849 {
00850   Unexpect aCatch(SALOME_SalomeException);
00851   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
00852   // create mesh
00853   SMESH::SMESH_Mesh_var mesh = this->createMesh();
00854 
00855   // publish mesh in the study
00856   if ( CanPublishInStudy( mesh ) ) {
00857     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
00858     aStudyBuilder->NewCommand();  // There is a transaction
00859     SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() );
00860     aStudyBuilder->CommitCommand();
00861     if ( !aSO->_is_nil() ) {
00862       // Update Python script
00863       TPythonDump() << aSO << " = " << this << ".CreateEmptyMesh()";
00864     }
00865   }
00866 
00867   return mesh._retn();
00868 }
00869 
00870 //=============================================================================
00876 //=============================================================================
00877 
00878 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName )
00879   throw ( SALOME::SALOME_Exception )
00880 {
00881   Unexpect aCatch(SALOME_SalomeException);
00882   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromUNV" );
00883 
00884   SMESH::SMESH_Mesh_var aMesh = createMesh();
00885   string aFileName;
00886   // publish mesh in the study
00887   if ( CanPublishInStudy( aMesh ) ) {
00888     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
00889     aStudyBuilder->NewCommand();  // There is a transaction
00890     SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() );
00891     aStudyBuilder->CommitCommand();
00892     if ( !aSO->_is_nil() ) {
00893       // Update Python script
00894       TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV(r'" << theFileName << "')";
00895     }
00896   }
00897 
00898   SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
00899   ASSERT( aServant );
00900   aServant->ImportUNVFile( theFileName );
00901 
00902   // Dump creation of groups
00903   SMESH::ListOfGroups_var groups = aServant->GetGroups();
00904 
00905   aServant->GetImpl().GetMeshDS()->Modified();
00906   return aMesh._retn();
00907 }
00908 
00909 //=============================================================================
00915 //=============================================================================
00916 
00917 SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
00918                                                      SMESH::DriverMED_ReadStatus& theStatus)
00919      throw ( SALOME::SALOME_Exception )
00920 {
00921   Unexpect aCatch(SALOME_SalomeException);
00922   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
00923 
00924   // Retrieve mesh names from the file
00925   DriverMED_R_SMESHDS_Mesh myReader;
00926   myReader.SetFile( theFileName );
00927   myReader.SetMeshId( -1 );
00928   Driver_Mesh::Status aStatus;
00929   list<string> aNames = myReader.GetMeshNames(aStatus);
00930   SMESH::mesh_array_var aResult = new SMESH::mesh_array();
00931   theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
00932 
00933   { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
00934 
00935   // Python Dump
00936   TPythonDump aPythonDump;
00937   aPythonDump << "([";
00938 
00939   if (theStatus == SMESH::DRS_OK) {
00940     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
00941     aStudyBuilder->NewCommand();  // There is a transaction
00942     aResult->length( aNames.size() );
00943     int i = 0;
00944 
00945     // Iterate through all meshes and create mesh objects
00946     for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ ) {
00947       // Python Dump
00948       if (i > 0) aPythonDump << ", ";
00949 
00950       // create mesh
00951       SMESH::SMESH_Mesh_var mesh = createMesh();
00952 
00953       // publish mesh in the study
00954       SALOMEDS::SObject_var aSO;
00955       if ( CanPublishInStudy( mesh ) )
00956         aSO = PublishMesh( myCurrentStudy, mesh.in(), (*it).c_str() );
00957       if ( !aSO->_is_nil() ) {
00958         // Python Dump
00959         aPythonDump << aSO;
00960       } else {
00961         // Python Dump
00962         aPythonDump << "mesh_" << i;
00963       }
00964 
00965       // Read mesh data (groups are published automatically by ImportMEDFile())
00966       SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
00967       ASSERT( meshServant );
00968       SMESH::DriverMED_ReadStatus status1 =
00969         meshServant->ImportMEDFile( theFileName, (*it).c_str() );
00970       if (status1 > theStatus)
00971         theStatus = status1;
00972 
00973       aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
00974       meshServant->GetImpl().GetMeshDS()->Modified();
00975     }
00976     aStudyBuilder->CommitCommand();
00977   }
00978 
00979   // Update Python script
00980   aPythonDump << "], status) = " << this << ".CreateMeshesFromMED(r'" << theFileName << "')";
00981   }
00982   // Dump creation of groups
00983   for ( int i = 0; i < aResult->length(); ++i )
00984     SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
00985 
00986   return aResult._retn();
00987 }
00988 
00989 //=============================================================================
00995 //=============================================================================
00996 
00997 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName )
00998   throw ( SALOME::SALOME_Exception )
00999 {
01000   Unexpect aCatch(SALOME_SalomeException);
01001   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromSTL" );
01002 
01003   SMESH::SMESH_Mesh_var aMesh = createMesh();
01004   string aFileName;
01005   // publish mesh in the study
01006   if ( CanPublishInStudy( aMesh ) ) {
01007     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
01008     aStudyBuilder->NewCommand();  // There is a transaction
01009     SALOMEDS::SObject_var aSO = PublishInStudy
01010       ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
01011     aStudyBuilder->CommitCommand();
01012     if ( !aSO->_is_nil() ) {
01013       // Update Python script
01014       TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')";
01015     }
01016   }
01017 
01018   SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
01019   ASSERT( aServant );
01020   aServant->ImportSTLFile( theFileName );
01021   aServant->GetImpl().GetMeshDS()->Modified();
01022   return aMesh._retn();
01023 }
01024 
01025 //=============================================================================
01031 //=============================================================================
01032 
01033 CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
01034                                               GEOM::GEOM_Object_ptr theShapeObject )
01035   throw ( SALOME::SALOME_Exception )
01036 {
01037   Unexpect aCatch(SALOME_SalomeException);
01038   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" );
01039 
01040   if ( CORBA::is_nil( theShapeObject ) )
01041     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
01042                                   SALOME::BAD_PARAM );
01043 
01044   if ( CORBA::is_nil( theMesh ) )
01045     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
01046                                   SALOME::BAD_PARAM );
01047 
01048   try {
01049     // get mesh servant
01050     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
01051     ASSERT( meshServant );
01052     if ( meshServant ) {
01053       // get local TopoDS_Shape
01054       TopoDS_Shape myLocShape = GeomObjectToShape( theShapeObject );
01055       // call implementation
01056       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
01057       return myGen.CheckAlgoState( myLocMesh, myLocShape );
01058     }
01059   }
01060   catch ( SALOME_Exception& S_ex ) {
01061     INFOS( "catch exception "<< S_ex.what() );
01062   }
01063   return false;
01064 }
01065 
01066 //================================================================================
01070 //================================================================================
01071 
01072 SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
01073 {
01074   if ( algo ) {
01075     if ( !myCurrentStudy->_is_nil() ) {
01076       // find algo in the study
01077       SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow
01078         ( myCurrentStudy->FindComponent( ComponentDataType() ) );
01079       if ( !father->_is_nil() ) {
01080         SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father );
01081         for ( ; itBig->More(); itBig->Next() ) {
01082           SALOMEDS::SObject_var gotBranch = itBig->Value();
01083           if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
01084             SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch );
01085             for ( ; algoIt->More(); algoIt->Next() ) {
01086               SALOMEDS::SObject_var algoSO = algoIt->Value();
01087               CORBA::Object_var     algoIOR = SObjectToObject( algoSO );
01088               if ( !CORBA::is_nil( algoIOR )) {
01089                 SMESH_Hypothesis_i* impl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
01090                 if ( impl && impl->GetImpl() == algo )
01091                   return algoSO._retn();
01092               }
01093             } // loop on algo SO's
01094             break;
01095           } // if algo tag
01096         } // SMESH component iterator
01097       }
01098     }
01099   }
01100   return SALOMEDS::SObject::_nil();
01101 }
01102 
01103 //================================================================================
01107 //================================================================================
01108 
01109 SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh,
01110                                                            GEOM::GEOM_Object_ptr theSubObject )
01111   throw ( SALOME::SALOME_Exception )
01112 {
01113   Unexpect aCatch(SALOME_SalomeException);
01114   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetComputeErrors()" );
01115 
01116   if ( CORBA::is_nil( theSubObject ) && theMesh->HasShapeToMesh())
01117     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
01118 
01119   if ( CORBA::is_nil( theMesh ) )
01120     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
01121 
01122   SMESH::compute_error_array_var error_array = new SMESH::compute_error_array;
01123   try {
01124     if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
01125     {
01126       TopoDS_Shape shape;
01127       if(theMesh->HasShapeToMesh())
01128         shape = GeomObjectToShape( theSubObject );
01129       else
01130         shape = SMESH_Mesh::PseudoShape();
01131 
01132       ::SMESH_Mesh& mesh = meshServant->GetImpl();
01133 
01134       error_array->length( mesh.GetMeshDS()->MaxShapeIndex() );
01135       int nbErr = 0;
01136 
01137       SMESH_subMesh *sm = mesh.GetSubMesh(shape);
01138       const bool includeSelf = true, complexShapeFirst = true;
01139       SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(includeSelf,
01140                                                                complexShapeFirst);
01141       while ( smIt->more() )
01142       {
01143         sm = smIt->next();
01144         if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
01145           break;
01146         SMESH_ComputeErrorPtr error = sm->GetComputeError();
01147         if ( error && !error->IsOK() && error->myAlgo )
01148         {
01149           SMESH::ComputeError & errStruct = error_array[ nbErr++ ];
01150           errStruct.code       = -( error->myName < 0 ? error->myName + 1: error->myName ); // -1 -> 0
01151           errStruct.comment    = error->myComment.c_str();
01152           errStruct.subShapeID = sm->GetId();
01153           SALOMEDS::SObject_var algoSO = GetAlgoSO( error->myAlgo );
01154           if ( !algoSO->_is_nil() )
01155             errStruct.algoName = algoSO->GetName();
01156           else
01157             errStruct.algoName = error->myAlgo->GetName();
01158           errStruct.hasBadMesh = !error->myBadElements.empty();
01159         }
01160       }
01161       error_array->length( nbErr );
01162     }
01163   }
01164   catch ( SALOME_Exception& S_ex ) {
01165     INFOS( "catch exception "<< S_ex.what() );
01166   }
01167 
01168   return error_array._retn();
01169 }
01170 
01171 //
01172 //================================================================================
01176 //================================================================================
01177 
01178 SMESH::MeshPreviewStruct*
01179 SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
01180                                   CORBA::Short          theSubShapeID )
01181   throw ( SALOME::SALOME_Exception )
01182 {
01183   Unexpect aCatch(SALOME_SalomeException);
01184   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetBadInputElements()" );
01185 
01186   if ( CORBA::is_nil( theMesh ) )
01187     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
01188 
01189   SMESH::MeshPreviewStruct_var result = new SMESH::MeshPreviewStruct;
01190   try {
01191     // mesh servant
01192     if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
01193     {
01194       // mesh implementation
01195       ::SMESH_Mesh& mesh = meshServant->GetImpl();
01196       // submesh by subshape id
01197       if ( SMESH_subMesh * sm = mesh.GetSubMeshContaining( theSubShapeID ))
01198       {
01199         // compute error
01200         SMESH_ComputeErrorPtr error = sm->GetComputeError();
01201         if ( error && !error->myBadElements.empty())
01202         {
01203           typedef map<const SMDS_MeshElement*, int > TNode2LocalIDMap;
01204           typedef TNode2LocalIDMap::iterator         TNodeLocalID;
01205 
01206           // get nodes of elements and count elements
01207           TNode2LocalIDMap mapNode2LocalID;
01208           list< TNodeLocalID > connectivity;
01209           int i, nbElements = 0, nbConnNodes = 0;
01210 
01211           list<const SMDS_MeshElement*>::iterator elemIt  = error->myBadElements.begin();
01212           list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
01213           for ( ; elemIt != elemEnd; ++elemIt, ++nbElements )
01214           {
01215             SMDS_ElemIteratorPtr nIt = (*elemIt)->nodesIterator();
01216             while ( nIt->more() )
01217               connectivity.push_back
01218                 ( mapNode2LocalID.insert( make_pair( nIt->next(), ++nbConnNodes)).first );
01219           }
01220           // fill node coords and assign local ids to the nodes
01221           int nbNodes = mapNode2LocalID.size();
01222           result->nodesXYZ.length( nbNodes );
01223           TNodeLocalID node2ID = mapNode2LocalID.begin();
01224           for ( i = 0; i < nbNodes; ++i, ++node2ID ) {
01225             node2ID->second = i;
01226             const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first;
01227             result->nodesXYZ[i].x = node->X();
01228             result->nodesXYZ[i].y = node->Y();
01229             result->nodesXYZ[i].z = node->Z();
01230           }
01231           // fill connectivity
01232           result->elementConnectivities.length( nbConnNodes );
01233           list< TNodeLocalID >::iterator connIt = connectivity.begin();
01234           for ( i = 0; i < nbConnNodes; ++i, ++connIt ) {
01235             result->elementConnectivities[i] = (*connIt)->second;
01236           }
01237           // fill element types
01238           result->elementTypes.length( nbElements );
01239           for ( i = 0, elemIt = error->myBadElements.begin(); i <nbElements; ++i, ++elemIt )
01240           {
01241             const SMDS_MeshElement* elem = *elemIt;
01242             result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) elem->GetType();
01243             result->elementTypes[i].isPoly           = elem->IsPoly();
01244             result->elementTypes[i].nbNodesInElement = elem->NbNodes();
01245           }
01246         }
01247       }
01248     }
01249   }
01250   catch ( SALOME_Exception& S_ex ) {
01251     INFOS( "catch exception "<< S_ex.what() );
01252   }
01253 
01254   return result._retn();
01255 }
01256 
01257 //================================================================================
01264 //================================================================================
01265 
01266 SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh,
01267                                                     GEOM::GEOM_Object_ptr theSubObject )
01268       throw ( SALOME::SALOME_Exception )
01269 {
01270   Unexpect aCatch(SALOME_SalomeException);
01271   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetAlgoState()" );
01272 
01273   if ( CORBA::is_nil( theSubObject ) && theMesh->HasShapeToMesh())
01274     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
01275 
01276   if ( CORBA::is_nil( theMesh ) )
01277     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
01278 
01279   SMESH::algo_error_array_var error_array = new SMESH::algo_error_array;
01280   try {
01281     SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
01282     ASSERT( meshServant );
01283     if ( meshServant ) {
01284       TopoDS_Shape myLocShape;
01285       if(theMesh->HasShapeToMesh())
01286         myLocShape = GeomObjectToShape( theSubObject );
01287       else
01288         myLocShape = SMESH_Mesh::PseudoShape();
01289 
01290       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
01291       list< ::SMESH_Gen::TAlgoStateError > error_list;
01292       list< ::SMESH_Gen::TAlgoStateError >::iterator error;
01293       // call ::SMESH_Gen::GetAlgoState()
01294       myGen.GetAlgoState( myLocMesh, myLocShape, error_list );
01295       error_array->length( error_list.size() );
01296       int i = 0;
01297       for ( error = error_list.begin(); error != error_list.end(); ++error )
01298       {
01299         // fill AlgoStateError structure
01300         SMESH::AlgoStateError & errStruct = error_array[ i++ ];
01301         errStruct.state        = SMESH_Mesh_i::ConvertHypothesisStatus( error->_name );
01302         errStruct.algoDim      = error->_algoDim;
01303         errStruct.isGlobalAlgo = error->_isGlobalAlgo;
01304         errStruct.algoName     = "";
01305         SALOMEDS::SObject_var algoSO = GetAlgoSO( error->_algo );
01306         if ( !algoSO->_is_nil() )
01307           errStruct.algoName   = algoSO->GetName();
01308       }
01309     }
01310   }
01311   catch ( SALOME_Exception& S_ex ) {
01312     INFOS( "catch exception "<< S_ex.what() );
01313   }
01314   return error_array._retn();
01315 }
01316 
01317 //=============================================================================
01323 //=============================================================================
01324 
01325 SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainShapeObject,
01326                                             const SMESH::object_array& theListOfSubShapeObject )
01327      throw ( SALOME::SALOME_Exception )
01328 {
01329   Unexpect aCatch(SALOME_SalomeException);
01330   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetSubShapesId" );
01331 
01332   SMESH::long_array_var shapesId = new SMESH::long_array;
01333   set<int> setId;
01334 
01335   if ( CORBA::is_nil( theMainShapeObject ) )
01336     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
01337                                   SALOME::BAD_PARAM );
01338 
01339   try
01340     {
01341       TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject);
01342       TopTools_IndexedMapOfShape myIndexToShape;
01343       TopExp::MapShapes(myMainShape,myIndexToShape);
01344 
01345       for ( int i = 0; i < theListOfSubShapeObject.length(); i++ )
01346         {
01347           GEOM::GEOM_Object_var aShapeObject
01348             = GEOM::GEOM_Object::_narrow(theListOfSubShapeObject[i]);
01349           if ( CORBA::is_nil( aShapeObject ) )
01350             THROW_SALOME_CORBA_EXCEPTION ("bad shape object reference", \
01351                                         SALOME::BAD_PARAM );
01352 
01353           TopoDS_Shape locShape  = GeomObjectToShape(aShapeObject);
01354           for (TopExp_Explorer exp(locShape,TopAbs_FACE); exp.More(); exp.Next())
01355             {
01356               const TopoDS_Face& F = TopoDS::Face(exp.Current());
01357               setId.insert(myIndexToShape.FindIndex(F));
01358               if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(F));
01359             }
01360           for (TopExp_Explorer exp(locShape,TopAbs_EDGE); exp.More(); exp.Next())
01361             {
01362               const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
01363               setId.insert(myIndexToShape.FindIndex(E));
01364               if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(E));
01365             }
01366           for (TopExp_Explorer exp(locShape,TopAbs_VERTEX); exp.More(); exp.Next())
01367             {
01368               const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current());
01369               setId.insert(myIndexToShape.FindIndex(V));
01370               if(MYDEBUG) SCRUTE(myIndexToShape.FindIndex(V));
01371             }
01372         }
01373       shapesId->length(setId.size());
01374       set<int>::iterator iind;
01375       int i=0;
01376       for (iind = setId.begin(); iind != setId.end(); iind++)
01377         {
01378           if(MYDEBUG) SCRUTE((*iind));
01379           shapesId[i] = (*iind);
01380           if(MYDEBUG) SCRUTE(shapesId[i]);
01381           i++;
01382         }
01383     }
01384   catch (SALOME_Exception& S_ex)
01385     {
01386       THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
01387     }
01388 
01389   return shapesId._retn();
01390 }
01391 
01392 //=============================================================================
01398 //=============================================================================
01399 
01400 CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
01401                                      GEOM::GEOM_Object_ptr theShapeObject )
01402      throw ( SALOME::SALOME_Exception )
01403 {
01404   MEMOSTAT;
01405   Unexpect aCatch(SALOME_SalomeException);
01406   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" );
01407 
01408   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
01409     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
01410                                   SALOME::BAD_PARAM );
01411 
01412   if ( CORBA::is_nil( theMesh ) )
01413     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
01414                                   SALOME::BAD_PARAM );
01415 
01416   // Update Python script
01417   TPythonDump() << "isDone = " << this << ".Compute( "
01418                 << theMesh << ", " << theShapeObject << ")";
01419 
01420   try {
01421     // get mesh servant
01422     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
01423     ASSERT( meshServant );
01424     if ( meshServant ) {
01425       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
01426       meshServant->CheckGeomGroupModif();
01427       // get local TopoDS_Shape
01428       TopoDS_Shape myLocShape;
01429       if(theMesh->HasShapeToMesh())
01430         myLocShape = GeomObjectToShape( theShapeObject );
01431       else
01432         myLocShape = SMESH_Mesh::PseudoShape();
01433       // call implementation compute
01434       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
01435 #ifdef WITH_SMESH_CANCEL_COMPUTE
01436       myGen.PrepareCompute( myLocMesh, myLocShape);
01437 #endif
01438       bool ok = myGen.Compute( myLocMesh, myLocShape);
01439       meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
01440       myLocMesh.GetMeshDS()->Modified();
01441       return ok;
01442     }
01443   }
01444   catch ( std::bad_alloc ) {
01445     INFOS( "Compute(): lack of memory" );
01446   }
01447   catch ( SALOME_Exception& S_ex ) {
01448     INFOS( "Compute(): catch exception "<< S_ex.what() );
01449   }
01450   catch ( ... ) {
01451     INFOS( "Compute(): unknown exception " );
01452   }
01453   return false;
01454 }
01455 
01456 //=============================================================================
01462 //=============================================================================
01463 
01464 void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh,
01465                                  GEOM::GEOM_Object_ptr theShapeObject )
01466 {
01467 #ifdef WITH_SMESH_CANCEL_COMPUTE
01468   SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
01469   ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
01470   TopoDS_Shape myLocShape;
01471   if(theMesh->HasShapeToMesh())
01472     myLocShape = GeomObjectToShape( theShapeObject );
01473   else
01474     myLocShape = SMESH_Mesh::PseudoShape();
01475   myGen.CancelCompute( myLocMesh, myLocShape);
01476 #endif
01477 }
01478 
01479 //=============================================================================
01485 //=============================================================================
01486 
01487 SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh,
01488                                                    GEOM::GEOM_Object_ptr theShapeObject,
01489                                                    SMESH::Dimension      theDimension,
01490                                                    SMESH::long_array&    theShapesId)
01491      throw ( SALOME::SALOME_Exception )
01492 {
01493   Unexpect aCatch(SALOME_SalomeException);
01494   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" );
01495 
01496   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
01497     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
01498                                   SALOME::BAD_PARAM );
01499 
01500   if ( CORBA::is_nil( theMesh ) )
01501     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
01502                                   SALOME::BAD_PARAM );
01503 
01504   SMESH::MeshPreviewStruct_var result = new SMESH::MeshPreviewStruct;
01505   try {
01506     // get mesh servant
01507     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
01508     ASSERT( meshServant );
01509     if ( meshServant ) {
01510       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
01511       meshServant->CheckGeomGroupModif();
01512       // get local TopoDS_Shape
01513       TopoDS_Shape myLocShape;
01514       if(theMesh->HasShapeToMesh())
01515         myLocShape = GeomObjectToShape( theShapeObject );
01516       else
01517         return result._retn();;
01518 
01519       // call implementation compute
01520       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
01521       TSetOfInt shapeIds;
01522       ::MeshDimension aDim = (MeshDimension)theDimension;
01523       if ( myGen.Compute( myLocMesh, myLocShape, false, aDim, &shapeIds ) )
01524       {
01525         int nbShapeId = shapeIds.size();
01526         theShapesId.length( nbShapeId );
01527         // iterates on shapes and collect mesh entities into mesh preview
01528         TSetOfInt::const_iterator idIt = shapeIds.begin();
01529         TSetOfInt::const_iterator idEnd = shapeIds.end();
01530         std::map< int, int > mapOfShIdNb;
01531         std::set< SMESH_TLink > setOfEdge;
01532         std::list< SMDSAbs_ElementType > listOfElemType;
01533         typedef map<const SMDS_MeshElement*, int > TNode2LocalIDMap;
01534         typedef TNode2LocalIDMap::iterator         TNodeLocalID;
01535         TNode2LocalIDMap mapNode2LocalID;
01536         list< TNodeLocalID > connectivity;
01537         int i, nbConnNodes = 0;
01538         std::set< const SMESH_subMesh* > setOfVSubMesh;
01539         // iterates on shapes
01540         for ( ; idIt != idEnd; idIt++ )
01541         {
01542           if ( mapOfShIdNb.find( *idIt ) != mapOfShIdNb.end() )
01543             continue;
01544           SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt);
01545           if ( !sm || !sm->IsMeshComputed() )
01546             continue;
01547 
01548           const TopoDS_Shape& aSh = sm->GetSubShape();
01549           const int shDim = myGen.GetShapeDim( aSh );
01550           if ( shDim < 1 || shDim > theDimension )
01551             continue;
01552 
01553           mapOfShIdNb[ *idIt ] = 0;
01554           theShapesId[ mapOfShIdNb.size() - 1 ] = *idIt;
01555 
01556           SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
01557           if ( !smDS ) continue;
01558 
01559           if ( theDimension == SMESH::DIM_2D )
01560           {
01561             SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
01562             while ( faceIt->more() )
01563             {
01564               const SMDS_MeshElement* face = faceIt->next();
01565               int aNbNode = face->NbNodes();
01566               if ( aNbNode > 4 )
01567                 aNbNode /= 2; // do not take into account additional middle nodes
01568 
01569               SMDS_MeshNode* node1 = (SMDS_MeshNode*)face->GetNode( 0 );
01570               for ( int nIndx = 0; nIndx < aNbNode; nIndx++ )
01571               {
01572                 SMDS_MeshNode* node2 = (SMDS_MeshNode*)face->GetNode( nIndx+1 < aNbNode ? nIndx+1 : 0 );
01573                 if ( setOfEdge.insert( SMESH_TLink ( node1, node2 ) ).second )
01574                 {
01575                   listOfElemType.push_back( SMDSAbs_Edge );
01576                   connectivity.push_back
01577                     ( mapNode2LocalID.insert( make_pair( node1, ++nbConnNodes)).first );
01578                   connectivity.push_back
01579                     ( mapNode2LocalID.insert( make_pair( node2, ++nbConnNodes)).first );
01580                 }
01581                 node1 = node2;
01582               }
01583             }
01584           }
01585           else if ( theDimension == SMESH::DIM_1D )
01586           {
01587             SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
01588             while ( nodeIt->more() )
01589             {
01590               listOfElemType.push_back( SMDSAbs_Node );
01591               connectivity.push_back
01592                 ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
01593             }
01594             // add corner nodes by first vertex from edge
01595             SMESH_subMeshIteratorPtr edgeSmIt =
01596               sm->getDependsOnIterator(/*includeSelf*/false,
01597                                        /*complexShapeFirst*/false);
01598             while ( edgeSmIt->more() )
01599             {
01600               SMESH_subMesh* vertexSM = edgeSmIt->next();
01601               // check that vertex is not already treated
01602               if ( !setOfVSubMesh.insert( vertexSM ).second )
01603                 continue;
01604               if ( vertexSM->GetSubShape().ShapeType() != TopAbs_VERTEX )
01605                 continue;
01606 
01607               const SMESHDS_SubMesh* vertexSmDS = vertexSM->GetSubMeshDS();
01608               SMDS_NodeIteratorPtr nodeIt = vertexSmDS->GetNodes();
01609               while ( nodeIt->more() )
01610               {
01611                 listOfElemType.push_back( SMDSAbs_Node );
01612                 connectivity.push_back
01613                   ( mapNode2LocalID.insert( make_pair( nodeIt->next(), ++nbConnNodes)).first );
01614               }
01615             }
01616           }
01617         }
01618 
01619         // fill node coords and assign local ids to the nodes
01620         int nbNodes = mapNode2LocalID.size();
01621         result->nodesXYZ.length( nbNodes );
01622         TNodeLocalID node2ID = mapNode2LocalID.begin();
01623         for ( i = 0; i < nbNodes; ++i, ++node2ID ) {
01624           node2ID->second = i;
01625           const SMDS_MeshNode* node = (const SMDS_MeshNode*) node2ID->first;
01626           result->nodesXYZ[i].x = node->X();
01627           result->nodesXYZ[i].y = node->Y();
01628           result->nodesXYZ[i].z = node->Z();
01629         }
01630         // fill connectivity
01631         result->elementConnectivities.length( nbConnNodes );
01632         list< TNodeLocalID >::iterator connIt = connectivity.begin();
01633         for ( i = 0; i < nbConnNodes; ++i, ++connIt ) {
01634           result->elementConnectivities[i] = (*connIt)->second;
01635         }
01636 
01637         // fill element types
01638         result->elementTypes.length( listOfElemType.size() );
01639         std::list< SMDSAbs_ElementType >::const_iterator typeIt = listOfElemType.begin();
01640         std::list< SMDSAbs_ElementType >::const_iterator typeEnd = listOfElemType.end();
01641         for ( i = 0; typeIt != typeEnd; ++i, ++typeIt )
01642         {
01643           SMDSAbs_ElementType elemType = *typeIt;
01644           result->elementTypes[i].SMDS_ElementType = (SMESH::ElementType)elemType;
01645           result->elementTypes[i].isPoly           = false;
01646           result->elementTypes[i].nbNodesInElement = elemType == SMDSAbs_Edge ? 2 : 1;
01647         }
01648 
01649         // correct number of shapes
01650         theShapesId.length( mapOfShIdNb.size() );
01651       }
01652     }
01653   }
01654   catch ( std::bad_alloc ) {
01655     INFOS( "Precompute(): lack of memory" );
01656   }
01657   catch ( SALOME_Exception& S_ex ) {
01658     INFOS( "Precompute(): catch exception "<< S_ex.what() );
01659   }
01660   catch ( ... ) {
01661     INFOS( "Precompute(): unknown exception " );
01662   }
01663   return result._retn();
01664 }
01665 
01666 
01667 //=============================================================================
01673 //=============================================================================
01674 
01675 SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
01676                                          GEOM::GEOM_Object_ptr theShapeObject)
01677 //                                     SMESH::long_array& theNbElems)
01678      throw ( SALOME::SALOME_Exception )
01679 {
01680   Unexpect aCatch(SALOME_SalomeException);
01681   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" );
01682 
01683   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
01684     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
01685                                   SALOME::BAD_PARAM );
01686 
01687   if ( CORBA::is_nil( theMesh ) )
01688     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
01689                                   SALOME::BAD_PARAM );
01690 
01691   SMESH::long_array_var nbels = new SMESH::long_array;
01692   nbels->length(SMESH::Entity_Last);
01693   int i = SMESH::Entity_Node;
01694   for (; i < SMESH::Entity_Last; i++)
01695     nbels[i] = 0;
01696 
01697   // Update Python script
01698   TPythonDump() << "theNbElems = " << this << ".Evaluate( "
01699                 << theMesh << ", " << theShapeObject << ")";
01700 
01701   try {
01702     // get mesh servant
01703     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
01704     ASSERT( meshServant );
01705     if ( meshServant ) {
01706       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
01707       meshServant->CheckGeomGroupModif();
01708       // get local TopoDS_Shape
01709       TopoDS_Shape myLocShape;
01710       if(theMesh->HasShapeToMesh())
01711         myLocShape = GeomObjectToShape( theShapeObject );
01712       else
01713         myLocShape = SMESH_Mesh::PseudoShape();
01714       // call implementation compute
01715       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
01716       MapShapeNbElems aResMap;
01717       /*CORBA::Boolean ret =*/ myGen.Evaluate( myLocMesh, myLocShape, aResMap);
01718       MapShapeNbElemsItr anIt = aResMap.begin();
01719       for(; anIt!=aResMap.end(); anIt++) {
01720         const vector<int>& aVec = (*anIt).second;
01721         for(i = SMESH::Entity_Node; i < aVec.size(); i++) {
01722           int nbElem = aVec[i];
01723           if ( nbElem < 0 ) // algo failed, check that it has reported a message
01724           {
01725             SMESH_subMesh* sm = anIt->first;
01726             SMESH_ComputeErrorPtr& error = sm->GetComputeError();
01727             const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape());
01728             if ( (algo && !error.get()) || error->IsOK() )
01729               error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
01730           }
01731           else
01732           {
01733             nbels[i] += aVec[i];
01734           }
01735         }
01736       }
01737       return nbels._retn();
01738     }
01739   }
01740   catch ( std::bad_alloc ) {
01741     INFOS( "Evaluate(): lack of memory" );
01742   }
01743   catch ( SALOME_Exception& S_ex ) {
01744     INFOS( "Evaluate(): catch exception "<< S_ex.what() );
01745   }
01746   catch ( ... ) {
01747     INFOS( "Evaluate(): unknown exception " );
01748   }
01749 
01750   return nbels._retn();
01751 }
01752 
01753 //================================================================================
01761 //================================================================================
01762 
01763 GEOM::GEOM_Object_ptr
01764 SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
01765                                        CORBA::Long            theElementID,
01766                                        const char*            theGeomName)
01767   throw ( SALOME::SALOME_Exception )
01768 {
01769   Unexpect aCatch(SALOME_SalomeException);
01770 
01771   GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID);
01772   if ( !geom->_is_nil() ) {
01773     GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
01774     GEOM::GEOM_Gen_ptr    geomGen   = GetGeomEngine();
01775 
01776     // try to find the corresponding SObject
01777     SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
01778     if ( SObj->_is_nil() ) // submesh can be not found even if published
01779     {
01780       // try to find published submesh
01781       GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
01782       if ( !geom->IsMainShape() && list->length() == 1 ) {
01783         SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
01784         SALOMEDS::ChildIterator_var it;
01785         if ( !mainSO->_is_nil() )
01786           it = myCurrentStudy->NewChildIterator( mainSO );
01787         if ( !it->_is_nil() ) {
01788           for ( it->InitEx(true); SObj->_is_nil() && it->More(); it->Next() ) {
01789             GEOM::GEOM_Object_var subGeom =
01790               GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
01791             if ( !subGeom->_is_nil() ) {
01792               GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
01793               if ( subList->length() == 1 && list[0] == subList[0] ) {
01794                 SObj = it->Value();
01795                 geom = subGeom;
01796               }
01797             }
01798           }
01799         }
01800       }
01801     }
01802     if ( SObj->_is_nil() ) // publish a new subshape
01803       SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape );
01804 
01805     // return only published geometry
01806     if ( !SObj->_is_nil() )
01807       return geom._retn();
01808   }
01809   return GEOM::GEOM_Object::_nil();
01810 }
01811 
01812 //================================================================================
01819 //================================================================================
01820 
01821 GEOM::GEOM_Object_ptr
01822 SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
01823                                         CORBA::Long            theElementID)
01824   throw ( SALOME::SALOME_Exception )
01825 {
01826   Unexpect aCatch(SALOME_SalomeException);
01827   if ( CORBA::is_nil( theMesh ) )
01828     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM );
01829 
01830   GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
01831   GEOM::GEOM_Gen_ptr    geomGen   = GetGeomEngine();
01832 
01833   // get a core mesh DS
01834   SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
01835   if ( meshServant && !geomGen->_is_nil() && !mainShape->_is_nil() )
01836   {
01837     ::SMESH_Mesh & mesh = meshServant->GetImpl();
01838     SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
01839     // find the element in mesh
01840     if ( const SMDS_MeshElement * elem = meshDS->FindElement( theElementID ) ) {
01841       // find a shape id by the element
01842       if ( int shapeID = ::SMESH_MeshEditor( &mesh ).FindShape( elem )) {
01843         // get a geom object by the shape id
01844         GEOM::GEOM_Object_var geom = ShapeToGeomObject( meshDS->IndexToShape( shapeID ));
01845         if ( geom->_is_nil() ) {
01846           // try to find a published sub-shape
01847           SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
01848           SALOMEDS::ChildIterator_var it;
01849           if ( !mainSO->_is_nil() )
01850             it = myCurrentStudy->NewChildIterator( mainSO );
01851           if ( !it->_is_nil() ) {
01852             for ( it->InitEx(true); it->More(); it->Next() ) {
01853               GEOM::GEOM_Object_var subGeom =
01854                 GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
01855               if ( !subGeom->_is_nil() ) {
01856                 GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
01857                 if ( subList->length() == 1 && shapeID == subList[0] ) {
01858                   geom = subGeom;
01859                   break;
01860                 }
01861               }
01862             }
01863           }
01864         }
01865         if ( geom->_is_nil() ) {
01866           // explode
01867           GEOM::GEOM_IShapesOperations_var op =
01868             geomGen->GetIShapesOperations( GetCurrentStudyID() );
01869           if ( !op->_is_nil() )
01870             geom = op->GetSubShape( mainShape, shapeID );
01871         }
01872         if ( !geom->_is_nil() ) {
01873           GeomObjectToShape( geom ); // let geom client remember the found shape
01874           return geom._retn();
01875         }
01876       }
01877     }
01878   }
01879   return GEOM::GEOM_Object::_nil();
01880 }
01881 
01882 //================================================================================
01888 //================================================================================
01889 
01890 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray,
01891                                                CORBA::Boolean           theUniteIdenticalGroups,
01892                                                CORBA::Boolean           theMergeNodesAndElements,
01893                                                CORBA::Double            theMergeTolerance)
01894   throw ( SALOME::SALOME_Exception )
01895 {
01896   return ConcatenateCommon(theMeshesArray,
01897                            theUniteIdenticalGroups,
01898                            theMergeNodesAndElements,
01899                            theMergeTolerance,
01900                            false);
01901 }
01902 
01903 //================================================================================
01910 //================================================================================
01911 
01912 SMESH::SMESH_Mesh_ptr
01913 SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
01914                                    CORBA::Boolean           theUniteIdenticalGroups,
01915                                    CORBA::Boolean           theMergeNodesAndElements,
01916                                    CORBA::Double            theMergeTolerance)
01917   throw ( SALOME::SALOME_Exception )
01918 {
01919   return ConcatenateCommon(theMeshesArray,
01920                            theUniteIdenticalGroups,
01921                            theMergeNodesAndElements,
01922                            theMergeTolerance,
01923                            true);
01924 }
01925 
01926 //================================================================================
01932 //================================================================================
01933 
01934 SMESH::SMESH_Mesh_ptr
01935 SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
01936                                CORBA::Boolean           theUniteIdenticalGroups,
01937                                CORBA::Boolean           theMergeNodesAndElements,
01938                                CORBA::Double            theMergeTolerance,
01939                                CORBA::Boolean           theCommonGroups)
01940   throw ( SALOME::SALOME_Exception )
01941 {
01942   typedef map<int, int> TIDsMap;
01943   typedef list<SMESH::SMESH_Group_var> TListOfNewGroups;
01944   typedef map< pair<string, SMESH::ElementType>, TListOfNewGroups > TGroupsMap;
01945   typedef std::set<SMESHDS_GroupBase*> TGroups;
01946 
01947   TPythonDump* pPythonDump = new TPythonDump;
01948   TPythonDump& aPythonDump = *pPythonDump; // prevent dump of called methods
01949 
01950   // create mesh
01951   SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
01952 
01953   SMESHDS_Mesh* aNewMeshDS = 0;
01954   if ( !aNewMesh->_is_nil() ) {
01955     SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
01956     if ( aNewImpl ) {
01957       ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
01958       aNewMeshDS = aLocMesh.GetMeshDS();
01959 
01960       TGroupsMap aGroupsMap;
01961       TListOfNewGroups aListOfNewGroups;
01962       SMESH_MeshEditor aNewEditor = ::SMESH_MeshEditor(&aLocMesh);
01963       SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
01964 
01965       // loop on meshes
01966       for ( int i = 0; i < theMeshesArray.length(); i++) {
01967         SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i];
01968         if ( !anInitMesh->_is_nil() ) {
01969           SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
01970           if ( anInitImpl ) {
01971             ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
01972             SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
01973 
01974             TIDsMap nodesMap;
01975             TIDsMap elemsMap;
01976 
01977             // loop on elements of mesh
01978             SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator();
01979             const SMDS_MeshElement* anElem = 0;
01980             const SMDS_MeshElement* aNewElem = 0;
01981             int anElemNbNodes = 0;
01982 
01983             int anNbNodes   = 0;
01984             int anNbEdges   = 0;
01985             int anNbFaces   = 0;
01986             int anNbVolumes = 0;
01987 
01988             SMESH::long_array_var anIDsNodes   = new SMESH::long_array();
01989             SMESH::long_array_var anIDsEdges   = new SMESH::long_array();
01990             SMESH::long_array_var anIDsFaces   = new SMESH::long_array();
01991             SMESH::long_array_var anIDsVolumes = new SMESH::long_array();
01992 
01993             if( theCommonGroups ) {
01994               anIDsNodes->length(   anInitMeshDS->NbNodes()   );
01995               anIDsEdges->length(   anInitMeshDS->NbEdges()   );
01996               anIDsFaces->length(   anInitMeshDS->NbFaces()   );
01997               anIDsVolumes->length( anInitMeshDS->NbVolumes() );
01998             }
01999 
02000             for ( int j = 0; itElems->more(); j++) {
02001               anElem = itElems->next();
02002               SMDSAbs_ElementType anElemType = anElem->GetType();
02003               anElemNbNodes = anElem->NbNodes();
02004               std::vector<const SMDS_MeshNode*> aNodesArray (anElemNbNodes);
02005 
02006               // loop on nodes of element
02007               const SMDS_MeshNode* aNode = 0;
02008               const SMDS_MeshNode* aNewNode = 0;
02009               SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
02010 
02011               for ( int k = 0; itNodes->more(); k++) {
02012                 aNode = static_cast<const SMDS_MeshNode*>(itNodes->next());
02013                 if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) {
02014                   aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
02015                   nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
02016                   if( theCommonGroups )
02017                     anIDsNodes[anNbNodes++] = aNewNode->GetID();
02018                 }
02019                 else
02020                   aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second );
02021                 aNodesArray[k] = aNewNode;
02022               }//nodes loop
02023 
02024               // creates a corresponding element on existent nodes in new mesh
02025               if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
02026                 {
02027                   const SMDS_VtkVolume* aVolume =
02028                     dynamic_cast<const SMDS_VtkVolume*> (anElem);
02029                   if ( aVolume ) {
02030                     aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
02031                                                                aVolume->GetQuantities());
02032                     elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
02033                     if( theCommonGroups )
02034                       anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
02035                   }
02036                 }
02037               else {
02038 
02039                 aNewElem = aNewEditor.AddElement(aNodesArray,
02040                                                  anElemType,
02041                                                  anElem->IsPoly());
02042                 elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
02043                 if( theCommonGroups ) {
02044                   if( anElemType == SMDSAbs_Edge )
02045                     anIDsEdges[anNbEdges++] = aNewElem->GetID();
02046                   else if( anElemType == SMDSAbs_Face )
02047                     anIDsFaces[anNbFaces++] = aNewElem->GetID();
02048                   else if( anElemType == SMDSAbs_Volume )
02049                     anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
02050                 }
02051               }
02052             }//elems loop
02053 
02054             // copy orphan nodes
02055             SMDS_NodeIteratorPtr  itNodes = anInitMeshDS->nodesIterator();
02056             while ( itNodes->more() )
02057             {
02058               const SMDS_MeshNode* aNode = itNodes->next();
02059               if ( aNode->NbInverseElements() == 0 )
02060               {
02061                 const SMDS_MeshNode* aNewNode =
02062                   aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
02063                 nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
02064                 if( theCommonGroups )
02065                   anIDsNodes[anNbNodes++] = aNewNode->GetID();
02066               }
02067             }
02068 
02069 
02070             aListOfGroups = anInitImpl->GetGroups();
02071             SMESH::SMESH_GroupBase_ptr aGroup;
02072 
02073             // loop on groups of mesh
02074             SMESH::long_array_var anInitIDs = new SMESH::long_array();
02075             SMESH::long_array_var anNewIDs = new SMESH::long_array();
02076             SMESH::SMESH_Group_var aNewGroup;
02077 
02078             SMESH::ElementType aGroupType;
02079             CORBA::String_var aGroupName;
02080             if ( theCommonGroups ) {
02081               for(aGroupType=SMESH::NODE;aGroupType<=SMESH::VOLUME;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
02082                 string str = "Gr";
02083                 SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
02084                 if(aMeshSObj)
02085                   str += aMeshSObj->GetName();
02086                 str += "_";
02087 
02088                 int anLen = 0;
02089 
02090                 switch(aGroupType) {
02091                 case SMESH::NODE:
02092                   str += "Nodes";
02093                   anIDsNodes->length(anNbNodes);
02094                   anLen = anNbNodes;
02095                   break;
02096                 case SMESH::EDGE:
02097                   str += "Edges";
02098                   anIDsEdges->length(anNbEdges);
02099                   anLen = anNbEdges;
02100                   break;
02101                 case SMESH::FACE:
02102                   str += "Faces";
02103                   anIDsFaces->length(anNbFaces);
02104                   anLen = anNbFaces;
02105                   break;
02106                 case SMESH::VOLUME:
02107                   str += "Volumes";
02108                   anIDsVolumes->length(anNbVolumes);
02109                   anLen = anNbVolumes;
02110                   break;
02111                 default:
02112                   break;
02113                 }
02114 
02115                 if(anLen) {
02116                   aGroupName = str.c_str();
02117 
02118                   // add a new group in the mesh
02119                   aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
02120 
02121                   switch(aGroupType) {
02122                   case SMESH::NODE:
02123                     aNewGroup->Add( anIDsNodes );
02124                     break;
02125                   case SMESH::EDGE:
02126                     aNewGroup->Add( anIDsEdges );
02127                     break;
02128                   case SMESH::FACE:
02129                     aNewGroup->Add( anIDsFaces );
02130                     break;
02131                   case SMESH::VOLUME:
02132                     aNewGroup->Add( anIDsVolumes );
02133                     break;
02134                   default:
02135                     break;
02136                   }
02137 
02138                   aListOfNewGroups.clear();
02139                   aListOfNewGroups.push_back(aNewGroup);
02140                   aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
02141                 }
02142               }
02143             }
02144 
02145             // check that current group name and type don't have identical ones in union mesh
02146             for (int i = 0; i < aListOfGroups->length(); i++) {
02147               aGroup = aListOfGroups[i];
02148               aListOfNewGroups.clear();
02149               aGroupType = aGroup->GetType();
02150               aGroupName = aGroup->GetName();
02151 
02152               TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType));
02153 
02154               // convert a list of IDs
02155               anInitIDs = aGroup->GetListOfID();
02156               anNewIDs->length(anInitIDs->length());
02157               if ( aGroupType == SMESH::NODE )
02158                 for (int j = 0; j < anInitIDs->length(); j++) {
02159                   anNewIDs[j] = nodesMap.find(anInitIDs[j])->second;
02160                 }
02161               else
02162                 for (int j = 0; j < anInitIDs->length(); j++) {
02163                   anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
02164                 }
02165 
02166               // check that current group name and type don't have identical ones in union mesh
02167               if ( anIter == aGroupsMap.end() ) {
02168                 // add a new group in the mesh
02169                 aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
02170                 // add elements into new group
02171                 aNewGroup->Add( anNewIDs );
02172 
02173                 aListOfNewGroups.push_back(aNewGroup);
02174                 aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
02175               }
02176 
02177               else if ( theUniteIdenticalGroups ) {
02178                 // unite identical groups
02179                 TListOfNewGroups& aNewGroups = anIter->second;
02180                 aNewGroups.front()->Add( anNewIDs );
02181               }
02182 
02183               else {
02184                 // rename identical groups
02185                 aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
02186                 aNewGroup->Add( anNewIDs );
02187 
02188                 TListOfNewGroups& aNewGroups = anIter->second;
02189                 string aNewGroupName;
02190                 if (aNewGroups.size() == 1) {
02191                   aNewGroupName = string(aGroupName) + "_1";
02192                   aNewGroups.front()->SetName(aNewGroupName.c_str());
02193                 }
02194                 char aGroupNum[128];
02195                 sprintf(aGroupNum, "%u", aNewGroups.size()+1);
02196                 aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
02197                 aNewGroup->SetName(aNewGroupName.c_str());
02198                 aNewGroups.push_back(aNewGroup);
02199               }
02200             }//groups loop
02201           }
02202         }
02203       }//meshes loop
02204 
02205       if (theMergeNodesAndElements) {
02206         // merge nodes
02207         TIDSortedNodeSet aMeshNodes; // no input nodes
02208         SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
02209         aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
02210         aNewEditor.MergeNodes( aGroupsOfNodes );
02211         // merge elements
02212         aNewEditor.MergeEqualElements();
02213       }
02214     }
02215   }
02216 
02217   // Update Python script
02218   aPythonDump << aNewMesh << " = " << this;
02219   if( !theCommonGroups )
02220     aPythonDump << ".Concatenate(";
02221   else
02222     aPythonDump << ".ConcatenateWithGroups(";
02223   aPythonDump << "[";
02224   for ( int i = 0; i < theMeshesArray.length(); i++) {
02225     if (i > 0) aPythonDump << ", ";
02226     aPythonDump << theMeshesArray[i];
02227   }
02228   aPythonDump << "], ";
02229   aPythonDump << theUniteIdenticalGroups << ", "
02230               << theMergeNodesAndElements << ", "
02231               << theMergeTolerance << ")";
02232 
02233   delete pPythonDump; // enable python dump from GetGroups()
02234 
02235   // 0020577: EDF 1164 SMESH: Bad dump of concatenate with create common groups
02236   if ( !aNewMesh->_is_nil() )
02237   {
02238     SMESH::ListOfGroups_var groups = aNewMesh->GetGroups();
02239   }
02240 
02241   // IPAL21468 Change icon of compound because it need not be computed.
02242   SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh );
02243   if( !aMeshSObj->_is_nil() ) {
02244     SALOMEDS::GenericAttribute_var anAttr;
02245     SALOMEDS::StudyBuilder_var aBuilder = myCurrentStudy->NewBuilder();
02246     anAttr = aBuilder->FindOrCreateAttribute( aMeshSObj,"AttributePixMap" );
02247     SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
02248     aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
02249   }
02250   if (aNewMeshDS)
02251     aNewMeshDS->Modified();
02252   return aNewMesh._retn();
02253 }
02254 
02255 //================================================================================
02264 //================================================================================
02265 
02266 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
02267                                             const char*               meshName,
02268                                             CORBA::Boolean            toCopyGroups,
02269                                             CORBA::Boolean            toKeepIDs)
02270 {
02271   Unexpect aCatch(SALOME_SalomeException);
02272 
02273   TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
02274 
02275   // 1. Get source mesh
02276 
02277   if ( CORBA::is_nil( meshPart ))
02278     THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM );
02279 
02280   SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh();
02281   SMESH_Mesh_i*       srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( srcMesh );
02282   if ( !srcMesh_i )
02283     THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM );
02284 
02285   SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS();
02286 
02287   // 2. Make a new mesh
02288 
02289   SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil());
02290   SMESH_Mesh_i*       newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
02291   if ( !newMesh_i )
02292     THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR );
02293   SALOMEDS::SObject_var meshSO = ObjectToSObject(myCurrentStudy, newMesh );
02294   if ( !meshSO->_is_nil() )
02295   {
02296     SetName( meshSO, meshName, "Mesh" );
02297     SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
02298   }
02299   SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
02300   ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
02301 
02302   // 3. Get elements to copy
02303 
02304   SMDS_ElemIteratorPtr srcElemIt;
02305   TIDSortedElemSet srcElems;
02306   SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes();
02307   if ( SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
02308   {
02309     srcElemIt = srcMeshDS->elementsIterator();
02310   }
02311   else
02312   {
02313     SMESH::long_array_var ids = meshPart->GetIDs();
02314     if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
02315     {
02316       for (int i=0; i < ids->length(); i++)
02317         if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] ))
02318           srcElems.insert( elem );
02319     }
02320     else
02321     {
02322       for (int i=0; i < ids->length(); i++)
02323         if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] ))
02324           srcElems.insert( elem );
02325     }
02326     if ( srcElems.empty() )
02327       return newMesh._retn();
02328 
02329     typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter;
02330     srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() ));
02331   }
02332 
02333   // 4. Copy elements
02334 
02335   typedef map<SMDS_pElement, SMDS_pElement, TIDCompare> TE2EMap;
02336   TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ];
02337   TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ];
02338   int iN;
02339   const SMDS_MeshNode *nSrc, *nTgt;
02340   vector< const SMDS_MeshNode* > nodes;
02341   while ( srcElemIt->more() )
02342   {
02343     const SMDS_MeshElement * elem = srcElemIt->next();
02344     nodes.resize( elem->NbNodes());
02345     SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
02346     if ( toKeepIDs ) {
02347       for ( iN = 0; nIt->more(); ++iN )
02348       {
02349         nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
02350         nTgt = newMeshDS->FindNode( nSrc->GetID());
02351         if ( !nTgt )
02352           nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
02353         nodes[ iN ] = nTgt;
02354       }
02355     }
02356     else {
02357       for ( iN = 0; nIt->more(); ++iN )
02358       {
02359         nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
02360         TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first;
02361         if ( !n2n->second )
02362           n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
02363         nodes[ iN ] = (const SMDS_MeshNode*) n2n->second;
02364       }
02365     }
02366     if ( elem->GetType() != SMDSAbs_Node )
02367     {
02368       int ID = toKeepIDs ? elem->GetID() : 0;
02369       const SMDS_MeshElement * newElem = editor.AddElement( nodes,
02370                                                             elem->GetType(),
02371                                                             elem->IsPoly(),
02372                                                             ID);
02373       if ( toCopyGroups && !toKeepIDs )
02374         e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
02375     }
02376   }
02377 
02378   // 5. Copy groups
02379 
02380   int nbNewGroups = 0;
02381   if ( toCopyGroups )
02382   {
02383     SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups();
02384     while ( gIt->more() )
02385     {
02386       SMESH_Group* group = gIt->next();
02387       const SMESHDS_GroupBase* groupDS = group->GetGroupDS();
02388 
02389       // Check group type. We copy nodal groups containing nodes of copied element
02390       SMDSAbs_ElementType groupType = groupDS->GetType();
02391       if ( groupType != SMDSAbs_Node &&
02392            newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 )
02393         continue; // group type differs from types of meshPart
02394 
02395       // Find copied elements in the group
02396       vector< const SMDS_MeshElement* > groupElems;
02397       SMDS_ElemIteratorPtr eIt = groupDS->GetElements();
02398       if ( toKeepIDs )
02399       {
02400         const SMDS_MeshElement* foundElem;
02401         if ( groupType == SMDSAbs_Node )
02402         {
02403           while ( eIt->more() )
02404             if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() )))
02405               groupElems.push_back( foundElem );
02406         }
02407         else
02408         {
02409           while ( eIt->more() )
02410             if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() )))
02411               groupElems.push_back( foundElem );
02412         }
02413       }
02414       else
02415       {
02416         TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ];
02417         if ( e2eMap.empty() ) continue;
02418         int minID = e2eMap.begin()->first->GetID();
02419         int maxID = e2eMap.rbegin()->first->GetID();
02420         TE2EMap::iterator e2e;
02421         while ( eIt->more() && groupElems.size() < e2eMap.size())
02422         {
02423           const SMDS_MeshElement* e = eIt->next();
02424           if ( e->GetID() < minID || e->GetID() > maxID ) continue;
02425           if ((e2e = e2eMap.find( e )) != e2eMap.end())
02426             groupElems.push_back( e2e->second );
02427         }
02428       }
02429       // Make a new group
02430       if ( !groupElems.empty() )
02431       {
02432         SMESH::SMESH_Group_var newGroupObj =
02433           newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() );
02434         if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast<SMESH_GroupBase_i*>( newGroupObj))
02435         {
02436           SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS();
02437           SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup();
02438           for ( unsigned i = 0; i < groupElems.size(); ++i )
02439             smdsGroup.Add( groupElems[i] );
02440 
02441           nbNewGroups++;
02442         }
02443       }
02444     }
02445   }
02446 
02447   newMeshDS->Modified();
02448 
02449   *pyDump << newMesh << " = " << this
02450           << ".CopyMesh( " << meshPart << ", "
02451           << "'" << meshName << "', "
02452           << toCopyGroups << ", "
02453           << toKeepIDs << ")";
02454 
02455   delete pyDump; pyDump = 0; // allow dump in GetGroups()
02456 
02457   if ( nbNewGroups > 0 ) // dump created groups
02458     SMESH::ListOfGroups_var groups = newMesh->GetGroups();
02459 
02460   return newMesh._retn();
02461 }
02462 
02463 //================================================================================
02469 //================================================================================
02470 CORBA::Boolean SMESH_Gen_i::GetMEDVersion(const char* theFileName,
02471                                           SMESH::MED_VERSION& theVersion)
02472 {
02473   theVersion = SMESH::MED_V2_1;
02474   MED::EVersion aVersion = MED::GetVersionId( theFileName );
02475   switch( aVersion ) {
02476     case MED::eV2_1     : theVersion = SMESH::MED_V2_1; return true;
02477     case MED::eV2_2     : theVersion = SMESH::MED_V2_2; return true;
02478     case MED::eVUnknown : return false;
02479   }
02480   return false;
02481 }
02482 
02483 //================================================================================
02489 //================================================================================
02490 SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName)
02491 {
02492   SMESH::string_array_var aResult = new SMESH::string_array();
02493   MED::PWrapper aMed = MED::CrWrapper( theFileName );
02494   MED::TErr anErr;
02495   MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr );
02496   if( anErr >= 0 ) {
02497     aResult->length( aNbMeshes );
02498     for( MED::TInt i = 0; i < aNbMeshes; i++ ) {
02499       MED::PMeshInfo aMeshInfo = aMed->GetPMeshInfo( i+1 );
02500       aResult[i] = CORBA::string_dup( aMeshInfo->GetName().c_str() );
02501     }
02502   }
02503   return aResult._retn();
02504 }
02505 
02506 //=============================================================================
02512 //=============================================================================
02513 SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
02514                                       const char*              theURL,
02515                                       bool                     isMultiFile )
02516 {
02517   INFOS( "SMESH_Gen_i::Save" );
02518 
02519   //  ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
02520   // san -- in case <myCurrentStudy> differs from theComponent's study,
02521   // use that of the component
02522   if ( myCurrentStudy->_is_nil() ||
02523     theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
02524     SetCurrentStudy( theComponent->GetStudy() );
02525 
02526   // Store study contents as a set of python commands
02527   SavePython(myCurrentStudy);
02528 
02529   StudyContext* myStudyContext = GetCurrentStudyContext();
02530 
02531   // Declare a byte stream
02532   SALOMEDS::TMPFile_var aStreamFile;
02533 
02534   // Obtain a temporary dir
02535   TCollection_AsciiString tmpDir =
02536     ( isMultiFile ) ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str();
02537 
02538   // Create a sequence of files processed
02539   SALOMEDS::ListOfFileNames_var aFileSeq = new SALOMEDS::ListOfFileNames;
02540   aFileSeq->length( NUM_TMP_FILES );
02541 
02542   TCollection_AsciiString aStudyName( "" );
02543   if ( isMultiFile )
02544     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
02545 
02546   // Set names of temporary files
02547   TCollection_AsciiString filename =
02548     aStudyName + TCollection_AsciiString( "_SMESH.hdf" );        // for SMESH data itself
02549   TCollection_AsciiString meshfile =
02550     aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" );   // for mesh data to be stored in MED file
02551   aFileSeq[ 0 ] = CORBA::string_dup( filename.ToCString() );
02552   aFileSeq[ 1 ] = CORBA::string_dup( meshfile.ToCString() );
02553   filename = tmpDir + filename;
02554   meshfile = tmpDir + meshfile;
02555 
02556   HDFfile*    aFile;
02557   HDFdataset* aDataset;
02558   HDFgroup*   aTopGroup;
02559   HDFgroup*   aGroup;
02560   HDFgroup*   aSubGroup;
02561   HDFgroup*   aSubSubGroup;
02562   hdf_size    aSize[ 1 ];
02563 
02564 
02565   //Remove the files if they exist: BugID: 11225
02566 #ifndef WNT /* unix functionality */
02567   TCollection_AsciiString cmd("rm -f \"");
02568 #else /* windows */
02569   TCollection_AsciiString cmd("del /F \"");
02570 #endif
02571 
02572   cmd+=filename;
02573   cmd+="\" \"";
02574   cmd+=meshfile;
02575   cmd+="\"";
02576   system(cmd.ToCString());
02577 
02578   // MED writer to be used by storage process
02579   DriverMED_W_SMESHDS_Mesh myWriter;
02580   myWriter.SetFile( meshfile.ToCString() );
02581 
02582   // IMP issue 20918
02583   // SetStoreName() to groups before storing hypotheses to let them refer to
02584   // groups using "store name", which is "Group <group_persistent_id>"
02585   {
02586     SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
02587     for ( ; itBig->More(); itBig->Next() ) {
02588       SALOMEDS::SObject_var gotBranch = itBig->Value();
02589       if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) {
02590         CORBA::Object_var anObject = SObjectToObject( gotBranch );
02591         if ( !CORBA::is_nil( anObject ) ) {
02592           SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
02593           if ( !myMesh->_is_nil() ) {
02594             SMESH::ListOfGroups_var groups = myMesh->GetGroups();
02595             for ( int i = 0; i < groups->length(); ++i )
02596             {
02597               SMESH_GroupBase_i* grImpl = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i]);
02598               if ( grImpl )
02599               {
02600                 CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() );
02601                 int anId = myStudyContext->findId( string( objStr.in() ) );
02602                 char grpName[ 30 ];
02603                 sprintf( grpName, "Group %d", anId );
02604                 SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS();
02605                 aGrpBaseDS->SetStoreName( grpName );
02606               }
02607             }
02608           }
02609         }
02610       }
02611     }
02612   }
02613 
02614   // Write data
02615   // ---> create HDF file
02616   aFile = new HDFfile( (char*) filename.ToCString() );
02617   aFile->CreateOnDisk();
02618 
02619   // --> iterator for top-level objects
02620   SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
02621   for ( ; itBig->More(); itBig->Next() ) {
02622     SALOMEDS::SObject_var gotBranch = itBig->Value();
02623 
02624     // --> hypotheses root branch (only one for the study)
02625     if ( gotBranch->Tag() == GetHypothesisRootTag() ) {
02626       // create hypotheses root HDF group
02627       aTopGroup = new HDFgroup( "Hypotheses", aFile );
02628       aTopGroup->CreateOnDisk();
02629 
02630       // iterator for all hypotheses
02631       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
02632       for ( ; it->More(); it->Next() ) {
02633         SALOMEDS::SObject_var mySObject = it->Value();
02634         CORBA::Object_var anObject = SObjectToObject( mySObject );
02635         if ( !CORBA::is_nil( anObject ) ) {
02636           SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
02637           if ( !myHyp->_is_nil() ) {
02638             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
02639             if ( myImpl ) {
02640               string hypname = string( myHyp->GetName() );
02641               string libname = string( myHyp->GetLibName() );
02642               // BUG SWP13062
02643               // Needs for save crossplatform libname, i.e. parth of name ( ".dll" for
02644               // WNT and ".so" for X-system) must be deleted
02645               int libname_len = libname.length();
02646 #ifdef WNT
02647               if( libname_len > 4 )
02648                 libname.resize( libname_len - 4 );
02649 #else
02650               // PAL17753 (Regresion: missing hypothesis in restored study)
02651               // "lib" also should be removed from the beginning
02652               //if( libname_len > 3 )
02653                 //libname.resize( libname_len - 3 );
02654               if( libname_len > 6 )
02655                 libname = libname.substr( 3, libname_len - 3 - 3 );
02656 #endif
02657               CORBA::String_var objStr = GetORB()->object_to_string( anObject );
02658               int    id      = myStudyContext->findId( string( objStr.in() ) );
02659               string hypdata = string( myImpl->SaveTo() );
02660 
02661               // for each hypothesis create HDF group basing on its id
02662               char hypGrpName[30];
02663               sprintf( hypGrpName, "Hypothesis %d", id );
02664               aGroup = new HDFgroup( hypGrpName, aTopGroup );
02665               aGroup->CreateOnDisk();
02666               // --> type name of hypothesis
02667               aSize[ 0 ] = hypname.length() + 1;
02668               aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 );
02669               aDataset->CreateOnDisk();
02670               aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) );
02671               aDataset->CloseOnDisk();
02672               // --> server plugin library name of hypothesis
02673               aSize[ 0 ] = libname.length() + 1;
02674               aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 );
02675               aDataset->CreateOnDisk();
02676               aDataset->WriteOnDisk( ( char* )( libname.c_str() ) );
02677               aDataset->CloseOnDisk();
02678               // --> persistent data of hypothesis
02679               aSize[ 0 ] = hypdata.length() + 1;
02680               aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 );
02681               aDataset->CreateOnDisk();
02682               aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) );
02683               aDataset->CloseOnDisk();
02684               // close hypothesis HDF group
02685               aGroup->CloseOnDisk();
02686             }
02687           }
02688         }
02689       }
02690       // close hypotheses root HDF group
02691       aTopGroup->CloseOnDisk();
02692     }
02693     // --> algorithms root branch (only one for the study)
02694     else if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
02695       // create algorithms root HDF group
02696       aTopGroup = new HDFgroup( "Algorithms", aFile );
02697       aTopGroup->CreateOnDisk();
02698 
02699       // iterator for all algorithms
02700       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
02701       for ( ; it->More(); it->Next() ) {
02702         SALOMEDS::SObject_var mySObject = it->Value();
02703         CORBA::Object_var anObject = SObjectToObject( mySObject );
02704         if ( !CORBA::is_nil( anObject ) ) {
02705           SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
02706           if ( !myHyp->_is_nil() ) {
02707             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
02708             if ( myImpl ) {
02709               string hypname = string( myHyp->GetName() );
02710               string libname = string( myHyp->GetLibName() );
02711               // BUG SWP13062
02712               // Needs for save crossplatform libname, i.e. parth of name ( ".dll" for
02713               // WNT and ".so" for X-system) must be deleted
02714               int libname_len = libname.length();
02715 #ifdef WNT
02716               if( libname_len > 4 )
02717                 libname.resize( libname_len - 4 );
02718 #else
02719               // PAL17753 (Regresion: missing hypothesis in restored study)
02720               // "lib" also should be removed from the beginning
02721               //if( libname_len > 3 )
02722                 //libname.resize( libname_len - 3 );
02723               if( libname_len > 6 )
02724                 libname = libname.substr( 3, libname_len - 3 - 3 );
02725 #endif
02726               CORBA::String_var objStr = GetORB()->object_to_string( anObject );
02727               int    id      = myStudyContext->findId( string( objStr.in() ) );
02728               string hypdata = string( myImpl->SaveTo() );
02729 
02730               // for each algorithm create HDF group basing on its id
02731               char hypGrpName[30];
02732               sprintf( hypGrpName, "Algorithm %d", id );
02733               aGroup = new HDFgroup( hypGrpName, aTopGroup );
02734               aGroup->CreateOnDisk();
02735               // --> type name of algorithm
02736               aSize[0] = hypname.length() + 1;
02737               aDataset = new HDFdataset( "Name", aGroup, HDF_STRING, aSize, 1 );
02738               aDataset->CreateOnDisk();
02739               aDataset->WriteOnDisk( ( char* )( hypname.c_str() ) );
02740               aDataset->CloseOnDisk();
02741               // --> server plugin library name of hypothesis
02742               aSize[0] = libname.length() + 1;
02743               aDataset = new HDFdataset( "LibName", aGroup, HDF_STRING, aSize, 1 );
02744               aDataset->CreateOnDisk();
02745               aDataset->WriteOnDisk( ( char* )( libname.c_str() ) );
02746               aDataset->CloseOnDisk();
02747               // --> persistent data of algorithm
02748               aSize[0] = hypdata.length() + 1;
02749               aDataset = new HDFdataset( "Data", aGroup, HDF_STRING, aSize, 1 );
02750               aDataset->CreateOnDisk();
02751               aDataset->WriteOnDisk( ( char* )( hypdata.c_str() ) );
02752               aDataset->CloseOnDisk();
02753               // close algorithm HDF group
02754               aGroup->CloseOnDisk();
02755             }
02756           }
02757         }
02758       }
02759       // close algorithms root HDF group
02760       aTopGroup->CloseOnDisk();
02761     }
02762     // --> mesh objects roots branches
02763     else if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) {
02764       CORBA::Object_var anObject = SObjectToObject( gotBranch );
02765       if ( !CORBA::is_nil( anObject ) ) {
02766         SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
02767         if ( !myMesh->_is_nil() ) {
02768           SMESH_Mesh_i* myImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myMesh ).in() );
02769           if ( myImpl ) {
02770             CORBA::String_var objStr = GetORB()->object_to_string( anObject );
02771             int id = myStudyContext->findId( string( objStr.in() ) );
02772             ::SMESH_Mesh& myLocMesh = myImpl->GetImpl();
02773             SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
02774             bool hasShape = myLocMesh.HasShapeToMesh();
02775 
02776             // for each mesh open the HDF group basing on its id
02777             char meshGrpName[ 30 ];
02778             sprintf( meshGrpName, "Mesh %d", id );
02779             aTopGroup = new HDFgroup( meshGrpName, aFile );
02780             aTopGroup->CreateOnDisk();
02781 
02782             // --> put dataset to hdf file which is a flag that mesh has data
02783             string strHasData = "0";
02784             // check if the mesh is not empty
02785             if ( mySMESHDSMesh->NbNodes() > 0 ) {
02786               // write mesh data to med file
02787               myWriter.SetMesh( mySMESHDSMesh );
02788               myWriter.SetMeshId( id );
02789               strHasData = "1";
02790             }
02791             aSize[ 0 ] = strHasData.length() + 1;
02792             aDataset = new HDFdataset( "Has data", aTopGroup, HDF_STRING, aSize, 1 );
02793             aDataset->CreateOnDisk();
02794             aDataset->WriteOnDisk( ( char* )( strHasData.c_str() ) );
02795             aDataset->CloseOnDisk();
02796 
02797             // ouv : NPAL12872
02798             // for each mesh open the HDF group basing on its auto color parameter
02799             char meshAutoColorName[ 30 ];
02800             sprintf( meshAutoColorName, "AutoColorMesh %d", id );
02801             int anAutoColor[1];
02802             anAutoColor[0] = myImpl->GetAutoColor();
02803             aSize[ 0 ] = 1;
02804             aDataset = new HDFdataset( meshAutoColorName, aTopGroup, HDF_INT32, aSize, 1 );
02805             aDataset->CreateOnDisk();
02806             aDataset->WriteOnDisk( anAutoColor );
02807             aDataset->CloseOnDisk();
02808 
02809             // issue 0020693. Store _isModified flag
02810             int isModified = myLocMesh.GetIsModified();
02811             aSize[ 0 ] = 1;
02812             aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 );
02813             aDataset->CreateOnDisk();
02814             aDataset->WriteOnDisk( &isModified );
02815             aDataset->CloseOnDisk();
02816 
02817             // issue 20918. Store Persistent Id of SMESHDS_Mesh
02818             int meshPersistentId = mySMESHDSMesh->GetPersistentId();
02819             aSize[ 0 ] = 1;
02820             aDataset = new HDFdataset( "meshPersistentId", aTopGroup, HDF_INT32, aSize, 1 );
02821             aDataset->CreateOnDisk();
02822             aDataset->WriteOnDisk( &meshPersistentId );
02823             aDataset->CloseOnDisk();
02824 
02825             // write reference on a shape if exists
02826             SALOMEDS::SObject_var myRef;
02827             bool shapeRefFound = false;
02828             bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef );
02829             if ( found ) {
02830               SALOMEDS::SObject_var myShape;
02831               bool ok = myRef->ReferencedObject( myShape );
02832               if ( ok ) {
02833                 shapeRefFound = (! CORBA::is_nil( myShape->GetObject() ));
02834                 string myRefOnObject = myShape->GetID();
02835                 if ( shapeRefFound && myRefOnObject.length() > 0 ) {
02836                   aSize[ 0 ] = myRefOnObject.length() + 1;
02837                   aDataset = new HDFdataset( "Ref on shape", aTopGroup, HDF_STRING, aSize, 1 );
02838                   aDataset->CreateOnDisk();
02839                   aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
02840                   aDataset->CloseOnDisk();
02841                 }
02842               }
02843             }
02844 
02845             // write applied hypotheses if exist
02846             SALOMEDS::SObject_var myHypBranch;
02847             found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch );
02848             if ( found && !shapeRefFound && hasShape) { // remove applied hyps
02849               myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch );
02850             }
02851             if ( found && (shapeRefFound || !hasShape) ) {
02852               aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
02853               aGroup->CreateOnDisk();
02854 
02855               SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myHypBranch );
02856               int hypNb = 0;
02857               for ( ; it->More(); it->Next() ) {
02858                 SALOMEDS::SObject_var mySObject = it->Value();
02859                 SALOMEDS::SObject_var myRefOnHyp;
02860                 bool ok = mySObject->ReferencedObject( myRefOnHyp );
02861                 if ( ok ) {
02862                   // san - it is impossible to recover applied hypotheses
02863                   //       using their entries within Load() method,
02864                   // for there are no AttributeIORs in the study when Load() is working.
02865                   // Hence, it is better to store persistent IDs of hypotheses as references to them
02866 
02867                   //string myRefOnObject = myRefOnHyp->GetID();
02868                   CORBA::Object_var anObject = SObjectToObject( myRefOnHyp );
02869                   CORBA::String_var objStr = GetORB()->object_to_string( anObject );
02870                   int id = myStudyContext->findId( string( objStr.in() ) );
02871                   //if ( myRefOnObject.length() > 0 ) {
02872                   //aSize[ 0 ] = myRefOnObject.length() + 1;
02873                   char hypName[ 30 ], hypId[ 30 ];
02874                   sprintf( hypName, "Hyp %d", ++hypNb );
02875                   sprintf( hypId, "%d", id );
02876                   aSize[ 0 ] = strlen( hypId ) + 1;
02877                   aDataset = new HDFdataset( hypName, aGroup, HDF_STRING, aSize, 1 );
02878                   aDataset->CreateOnDisk();
02879                   //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
02880                   aDataset->WriteOnDisk( hypId );
02881                   aDataset->CloseOnDisk();
02882                   //}
02883                 }
02884               }
02885               aGroup->CloseOnDisk();
02886             }
02887 
02888             // write applied algorithms if exist
02889             SALOMEDS::SObject_var myAlgoBranch;
02890             found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), myAlgoBranch );
02891             if ( found && !shapeRefFound && hasShape) { // remove applied algos
02892               myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myAlgoBranch );
02893             }
02894             if ( found && (shapeRefFound || !hasShape)) {
02895               aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
02896               aGroup->CreateOnDisk();
02897 
02898               SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myAlgoBranch );
02899               int algoNb = 0;
02900               for ( ; it->More(); it->Next() ) {
02901                 SALOMEDS::SObject_var mySObject = it->Value();
02902                 SALOMEDS::SObject_var myRefOnAlgo;
02903                 bool ok = mySObject->ReferencedObject( myRefOnAlgo );
02904                 if ( ok ) {
02905                   // san - it is impossible to recover applied algorithms
02906                   //       using their entries within Load() method,
02907                   // for there are no AttributeIORs in the study when Load() is working.
02908                   // Hence, it is better to store persistent IDs of algorithms as references to them
02909 
02910                   //string myRefOnObject = myRefOnAlgo->GetID();
02911                   CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo );
02912                   CORBA::String_var objStr = GetORB()->object_to_string( anObject );
02913                   int id = myStudyContext->findId( string( objStr.in() ) );
02914                   //if ( myRefOnObject.length() > 0 ) {
02915                   //aSize[ 0 ] = myRefOnObject.length() + 1;
02916                   char algoName[ 30 ], algoId[ 30 ];
02917                   sprintf( algoName, "Algo %d", ++algoNb );
02918                   sprintf( algoId, "%d", id );
02919                   aSize[ 0 ] = strlen( algoId ) + 1;
02920                   aDataset = new HDFdataset( algoName, aGroup, HDF_STRING, aSize, 1 );
02921                   aDataset->CreateOnDisk();
02922                   //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
02923                   aDataset->WriteOnDisk( algoId );
02924                   aDataset->CloseOnDisk();
02925                   //}
02926                 }
02927               }
02928               aGroup->CloseOnDisk();
02929             }
02930 
02931             // --> submesh objects sub-branches
02932 
02933             for ( int i = GetSubMeshOnVertexTag(); i <= GetSubMeshOnCompoundTag(); i++ ) {
02934               SALOMEDS::SObject_var mySubmeshBranch;
02935               found = gotBranch->FindSubObject( i, mySubmeshBranch );
02936 
02937               if ( found ) // check if there is shape reference in submeshes
02938               {
02939                 bool hasShapeRef = false;
02940                 SALOMEDS::ChildIterator_var itSM =
02941                   myCurrentStudy->NewChildIterator( mySubmeshBranch );
02942                 for ( ; itSM->More(); itSM->Next() ) {
02943                   SALOMEDS::SObject_var mySubRef, myShape, mySObject = itSM->Value();
02944                   if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ))
02945                     mySubRef->ReferencedObject( myShape );
02946                   if ( !CORBA::is_nil( myShape ) && !CORBA::is_nil( myShape->GetObject() ))
02947                     hasShapeRef = true;
02948                   else
02949                   { // remove one submesh
02950                     if ( shapeRefFound )
02951                     { // unassign hypothesis
02952                       SMESH::SMESH_subMesh_var mySubMesh =
02953                         SMESH::SMESH_subMesh::_narrow( SObjectToObject( mySObject ));
02954                       if ( !mySubMesh->_is_nil() ) {
02955                         int shapeID = mySubMesh->GetId();
02956                         TopoDS_Shape S = mySMESHDSMesh->IndexToShape( shapeID );
02957                         const list<const SMESHDS_Hypothesis*>& hypList =
02958                           mySMESHDSMesh->GetHypothesis( S );
02959                         list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
02960                         while ( hyp != hypList.end() ) {
02961                           int hypID = (*hyp++)->GetID(); // goto next hyp here because
02962                           myLocMesh.RemoveHypothesis( S, hypID ); // hypList changes here
02963                         }
02964                       }
02965                     }
02966                     myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( mySObject );
02967                   }
02968                 } // loop on submeshes of a type
02969                 if ( !shapeRefFound || !hasShapeRef ) { // remove the whole submeshes branch
02970                   myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( mySubmeshBranch );
02971                   found = false;
02972                 }
02973               }  // end check if there is shape reference in submeshes
02974               if ( found ) {
02975                 char name_meshgroup[ 30 ];
02976                 if ( i == GetSubMeshOnVertexTag() )
02977                   strcpy( name_meshgroup, "SubMeshes On Vertex" );
02978                 else if ( i == GetSubMeshOnEdgeTag() )
02979                   strcpy( name_meshgroup, "SubMeshes On Edge" );
02980                 else if ( i == GetSubMeshOnWireTag() )
02981                   strcpy( name_meshgroup, "SubMeshes On Wire" );
02982                 else if ( i == GetSubMeshOnFaceTag() )
02983                   strcpy( name_meshgroup, "SubMeshes On Face" );
02984                 else if ( i == GetSubMeshOnShellTag() )
02985                   strcpy( name_meshgroup, "SubMeshes On Shell" );
02986                 else if ( i == GetSubMeshOnSolidTag() )
02987                   strcpy( name_meshgroup, "SubMeshes On Solid" );
02988                 else if ( i == GetSubMeshOnCompoundTag() )
02989                   strcpy( name_meshgroup, "SubMeshes On Compound" );
02990 
02991                 // for each type of submeshes create container HDF group
02992                 aGroup = new HDFgroup( name_meshgroup, aTopGroup );
02993                 aGroup->CreateOnDisk();
02994 
02995                 // iterator for all submeshes of given type
02996                 SALOMEDS::ChildIterator_var itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch );
02997                 for ( ; itSM->More(); itSM->Next() ) {
02998                   SALOMEDS::SObject_var mySObject = itSM->Value();
02999                   CORBA::Object_var anSubObject = SObjectToObject( mySObject );
03000                   if ( !CORBA::is_nil( anSubObject ))
03001                   {
03002                     SMESH::SMESH_subMesh_var mySubMesh = SMESH::SMESH_subMesh::_narrow( anSubObject ) ;
03003                     CORBA::String_var objStr = GetORB()->object_to_string( anSubObject );
03004                     int subid = myStudyContext->findId( string( objStr.in() ) );
03005 
03006                     // for each mesh open the HDF group basing on its id
03007                     char submeshGrpName[ 30 ];
03008                     sprintf( submeshGrpName, "SubMesh %d", subid );
03009                     aSubGroup = new HDFgroup( submeshGrpName, aGroup );
03010                     aSubGroup->CreateOnDisk();
03011 
03012                     // write reference on a shape, already checked if it exists
03013                     SALOMEDS::SObject_var mySubRef, myShape;
03014                     if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ))
03015                       mySubRef->ReferencedObject( myShape );
03016                     string myRefOnObject = myShape->GetID();
03017                     if ( myRefOnObject.length() > 0 ) {
03018                       aSize[ 0 ] = myRefOnObject.length() + 1;
03019                       aDataset = new HDFdataset( "Ref on shape", aSubGroup, HDF_STRING, aSize, 1 );
03020                       aDataset->CreateOnDisk();
03021                       aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
03022                       aDataset->CloseOnDisk();
03023                     }
03024 
03025                     // write applied hypotheses if exist
03026                     SALOMEDS::SObject_var mySubHypBranch;
03027                     found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(), mySubHypBranch );
03028                     if ( found ) {
03029                       aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
03030                       aSubSubGroup->CreateOnDisk();
03031 
03032                       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubHypBranch );
03033                       int hypNb = 0;
03034                       for ( ; it->More(); it->Next() ) {
03035                         SALOMEDS::SObject_var mySubSObject = it->Value();
03036                         SALOMEDS::SObject_var myRefOnHyp;
03037                         bool ok = mySubSObject->ReferencedObject( myRefOnHyp );
03038                         if ( ok ) {
03039                           //string myRefOnObject = myRefOnHyp->GetID();
03040                           CORBA::Object_var anObject = SObjectToObject( myRefOnHyp );
03041                           CORBA::String_var objStr = GetORB()->object_to_string( anObject );
03042                           int id = myStudyContext->findId( string( objStr.in() ) );
03043                           //if ( myRefOnObject.length() > 0 ) {
03044                           //aSize[ 0 ] = myRefOnObject.length() + 1;
03045                           char hypName[ 30 ], hypId[ 30 ];
03046                           sprintf( hypName, "Hyp %d", ++hypNb );
03047                           sprintf( hypId, "%d", id );
03048                           aSize[ 0 ] = strlen( hypId ) + 1;
03049                           aDataset = new HDFdataset( hypName, aSubSubGroup, HDF_STRING, aSize, 1 );
03050                           aDataset->CreateOnDisk();
03051                           //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
03052                           aDataset->WriteOnDisk( hypId );
03053                           aDataset->CloseOnDisk();
03054                           //}
03055                         }
03056                       }
03057                       aSubSubGroup->CloseOnDisk();
03058                     }
03059 
03060                     // write applied algorithms if exist
03061                     SALOMEDS::SObject_var mySubAlgoBranch;
03062                     found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch );
03063                     if ( found ) {
03064                       aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
03065                       aSubSubGroup->CreateOnDisk();
03066 
03067                       SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch );
03068                       int algoNb = 0;
03069                       for ( ; it->More(); it->Next() ) {
03070                         SALOMEDS::SObject_var mySubSObject = it->Value();
03071                         SALOMEDS::SObject_var myRefOnAlgo;
03072                         bool ok = mySubSObject->ReferencedObject( myRefOnAlgo );
03073                         if ( ok ) {
03074                           //string myRefOnObject = myRefOnAlgo->GetID();
03075                           CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo );
03076                           CORBA::String_var objStr = GetORB()->object_to_string( anObject );
03077                           int id = myStudyContext->findId( string( objStr.in() ) );
03078                           //if ( myRefOnObject.length() > 0 ) {
03079                           //aSize[ 0 ] = myRefOnObject.length() + 1;
03080                           char algoName[ 30 ], algoId[ 30 ];
03081                           sprintf( algoName, "Algo %d", ++algoNb );
03082                           sprintf( algoId, "%d", id );
03083                           aSize[ 0 ] = strlen( algoId ) + 1;
03084                           aDataset = new HDFdataset( algoName, aSubSubGroup, HDF_STRING, aSize, 1 );
03085                           aDataset->CreateOnDisk();
03086                           //aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
03087                           aDataset->WriteOnDisk( algoId );
03088                           aDataset->CloseOnDisk();
03089                           //}
03090                         }
03091                       }
03092                       aSubSubGroup->CloseOnDisk();
03093                     }
03094                     // close submesh HDF group
03095                     aSubGroup->CloseOnDisk();
03096                   }
03097                 }
03098                 // close container of submeshes by type HDF group
03099                 aGroup->CloseOnDisk();
03100               }
03101             }
03102             // All sub-meshes will be stored in MED file
03103             // .. will NOT (PAL 12992)
03104             //if ( shapeRefFound )
03105             //myWriter.AddAllSubMeshes();
03106 
03107             // store submesh order if any
03108             const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder();
03109             if ( theOrderIds.size() ) {
03110               char order_list[ 30 ];
03111               strcpy( order_list, "Mesh Order" );
03112               // count number of submesh ids
03113               int nbIDs = 0;
03114               TListOfListOfInt::const_iterator idIt = theOrderIds.begin();
03115               for ( ; idIt != theOrderIds.end(); idIt++ )
03116                 nbIDs += (*idIt).size();
03117               // number of values = number of IDs +
03118               //                    number of lists (for separators) - 1
03119               int* smIDs = new int [ nbIDs + theOrderIds.size() - 1 ];
03120               idIt = theOrderIds.begin();
03121               for ( int i = 0; idIt != theOrderIds.end(); idIt++ ) {
03122                 const TListOfInt& idList = *idIt;
03123                 if (idIt != theOrderIds.begin()) // not first list
03124                   smIDs[ i++ ] = -1/* *idList.size()*/; // separator between lists
03125                 // dump submesh ids from current list
03126                 TListOfInt::const_iterator id_smId = idList.begin();
03127                 for( ; id_smId != idList.end(); id_smId++ )
03128                   smIDs[ i++ ] = *id_smId;
03129               }
03130               // write HDF group
03131               aSize[ 0 ] = nbIDs + theOrderIds.size() - 1;
03132 
03133               aDataset = new HDFdataset( order_list, aTopGroup, HDF_INT32, aSize, 1 );
03134               aDataset->CreateOnDisk();
03135               aDataset->WriteOnDisk( smIDs );
03136               aDataset->CloseOnDisk();
03137               //
03138               delete[] smIDs;
03139             }
03140 
03141             // groups root sub-branch
03142             SALOMEDS::SObject_var myGroupsBranch;
03143             for ( int i = GetNodeGroupsTag(); i <= Get0DElementsGroupsTag(); i++ ) {
03144               found = gotBranch->FindSubObject( i, myGroupsBranch );
03145               if ( found ) {
03146                 char name_group[ 30 ];
03147                 if ( i == GetNodeGroupsTag() )
03148                   strcpy( name_group, "Groups of Nodes" );
03149                 else if ( i == GetEdgeGroupsTag() )
03150                   strcpy( name_group, "Groups of Edges" );
03151                 else if ( i == GetFaceGroupsTag() )
03152                   strcpy( name_group, "Groups of Faces" );
03153                 else if ( i == GetVolumeGroupsTag() )
03154                   strcpy( name_group, "Groups of Volumes" );
03155                 else if ( i == Get0DElementsGroupsTag() )
03156                   strcpy( name_group, "Groups of 0D Elements" );
03157 
03158                 aGroup = new HDFgroup( name_group, aTopGroup );
03159                 aGroup->CreateOnDisk();
03160 
03161                 SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch );
03162                 for ( ; it->More(); it->Next() ) {
03163                   SALOMEDS::SObject_var mySObject = it->Value();
03164                   CORBA::Object_var aSubObject = SObjectToObject( mySObject );
03165                   if ( !CORBA::is_nil( aSubObject ) ) {
03166                     SMESH_GroupBase_i* myGroupImpl =
03167                       dynamic_cast<SMESH_GroupBase_i*>( GetServant( aSubObject ).in() );
03168                     if ( !myGroupImpl )
03169                       continue;
03170                     SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS();
03171                     if ( !aGrpBaseDS )
03172                       continue;
03173 
03174                     CORBA::String_var objStr = GetORB()->object_to_string( aSubObject );
03175                     int anId = myStudyContext->findId( string( objStr.in() ) );
03176 
03177                     // For each group, create a dataset named "Group <group_persistent_id>"
03178                     // and store the group's user name into it
03179                     const char* grpName = aGrpBaseDS->GetStoreName();
03180                     char* aUserName = myGroupImpl->GetName();
03181                     aSize[ 0 ] = strlen( aUserName ) + 1;
03182 
03183                     aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 );
03184                     aDataset->CreateOnDisk();
03185                     aDataset->WriteOnDisk( aUserName );
03186                     aDataset->CloseOnDisk();
03187 
03188                     // ouv : NPAL12872
03189                     // For each group, create a dataset named "Group <group_persistent_id> Color"
03190                     // and store the group's color into it
03191                     char grpColorName[ 30 ];
03192                     sprintf( grpColorName, "ColorGroup %d", anId );
03193                     SALOMEDS::Color aColor = myGroupImpl->GetColor();
03194                     double anRGB[3];
03195                     anRGB[ 0 ] = aColor.R;
03196                     anRGB[ 1 ] = aColor.G;
03197                     anRGB[ 2 ] = aColor.B;
03198                     aSize[ 0 ] = 3;
03199                     aDataset = new HDFdataset( grpColorName, aGroup, HDF_FLOAT64, aSize, 1 );
03200                     aDataset->CreateOnDisk();
03201                     aDataset->WriteOnDisk( anRGB );
03202                     aDataset->CloseOnDisk();
03203 
03204                     // Pass SMESHDS_Group to MED writer
03205                     SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
03206                     if ( aGrpDS )
03207                       myWriter.AddGroup( aGrpDS );
03208 
03209                     // write reference on a shape if exists
03210                     SMESHDS_GroupOnGeom* aGeomGrp =
03211                       dynamic_cast<SMESHDS_GroupOnGeom*>( aGrpBaseDS );
03212                     if ( aGeomGrp ) {
03213                       SALOMEDS::SObject_var mySubRef, myShape;
03214                       if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) &&
03215                           mySubRef->ReferencedObject( myShape ) &&
03216                           !CORBA::is_nil( myShape->GetObject() ))
03217                       {
03218                         string myRefOnObject = myShape->GetID();
03219                         if ( myRefOnObject.length() > 0 ) {
03220                           char aRefName[ 30 ];
03221                           sprintf( aRefName, "Ref on shape %d", anId);
03222                           aSize[ 0 ] = myRefOnObject.length() + 1;
03223                           aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1);
03224                           aDataset->CreateOnDisk();
03225                           aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) );
03226                           aDataset->CloseOnDisk();
03227                         }
03228                       }
03229                       else // shape ref is invalid:
03230                       {
03231                         // save a group on geometry as ordinary group
03232                         myWriter.AddGroup( aGeomGrp );
03233                       }
03234                     }
03235                   }
03236                 }
03237                 aGroup->CloseOnDisk();
03238               }
03239             } // loop on groups
03240 
03241             if ( strcmp( strHasData.c_str(), "1" ) == 0 )
03242             {
03243               // Flush current mesh information into MED file
03244               myWriter.Perform();
03245 
03246               // maybe a shape was deleted in the study
03247               if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) {
03248                 TopoDS_Shape nullShape;
03249                 myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data
03250               }
03251 
03252               if ( !mySMESHDSMesh->SubMeshes().empty() )
03253               {
03254                 // Store submeshes
03255                 // ----------------
03256                 aGroup = new HDFgroup( "Submeshes", aTopGroup );
03257                 aGroup->CreateOnDisk();
03258 
03259                 // each element belongs to one or none submesh,
03260                 // so for each node/element, we store a submesh ID
03261 
03262                 // Make maps of submesh IDs of elements sorted by element IDs
03263                 typedef int TElemID;
03264                 typedef int TSubMID;
03265                 map< TElemID, TSubMID > eId2smId, nId2smId;
03266                 map< TElemID, TSubMID >::iterator hint; // insertion to map is done before hint
03267                 const map<int,SMESHDS_SubMesh*>& aSubMeshes = mySMESHDSMesh->SubMeshes();
03268                 map<int,SMESHDS_SubMesh*>::const_iterator itSubM ( aSubMeshes.begin() );
03269                 SMDS_NodeIteratorPtr itNode;
03270                 SMDS_ElemIteratorPtr itElem;
03271                 for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
03272                 {
03273                   TSubMID          aSubMeID = itSubM->first;
03274                   SMESHDS_SubMesh* aSubMesh = itSubM->second;
03275                   if ( aSubMesh->IsComplexSubmesh() )
03276                     continue; // submesh containing other submeshs
03277                   // nodes
03278                   hint = nId2smId.begin(); // optimize insertion basing on increasing order of elem Ids in submesh
03279                   for ( itNode = aSubMesh->GetNodes(); itNode->more(); ++hint)
03280                     hint = nId2smId.insert( hint, make_pair( itNode->next()->GetID(), aSubMeID ));
03281                   // elements
03282                   hint = eId2smId.begin();
03283                   for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint)
03284                     hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID ));
03285                 }
03286 
03287                 // Care of elements that are not on submeshes
03288                 if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) {
03289                   for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); )
03290                     /*  --- stl_map.h says : */
03291                     /*  A %map relies on unique keys and thus a %pair is only inserted if its */
03292                     /*  first element (the key) is not already present in the %map.           */
03293                     nId2smId.insert( make_pair( itNode->next()->GetID(), 0 ));
03294                 }
03295                 int nbElems = mySMESHDSMesh->NbEdges() + mySMESHDSMesh->NbFaces() + mySMESHDSMesh->NbVolumes();
03296                 if ( nbElems != eId2smId.size() ) {
03297                   for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); )
03298                     eId2smId.insert( make_pair( itElem->next()->GetID(), 0 ));
03299                 }
03300 
03301                 // Store submesh IDs
03302                 for ( int isNode = 0; isNode < 2; ++isNode )
03303                 {
03304                   map< TElemID, TSubMID >& id2smId = isNode ? nId2smId : eId2smId;
03305                   if ( id2smId.empty() ) continue;
03306                   map< TElemID, TSubMID >::const_iterator id_smId = id2smId.begin();
03307                   // make and fill array of submesh IDs
03308                   int* smIDs = new int [ id2smId.size() ];
03309                   for ( int i = 0; id_smId != id2smId.end(); ++id_smId, ++i )
03310                     smIDs[ i ] = id_smId->second;
03311                   // write HDF group
03312                   aSize[ 0 ] = id2smId.size();
03313                   string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
03314                   aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
03315                   aDataset->CreateOnDisk();
03316                   aDataset->WriteOnDisk( smIDs );
03317                   aDataset->CloseOnDisk();
03318                   //
03319                   delete[] smIDs;
03320                 }
03321 
03322                 // Store node positions on sub-shapes (SMDS_Position):
03323                 // ----------------------------------------------------
03324 
03325                 aGroup = new HDFgroup( "Node Positions", aTopGroup );
03326                 aGroup->CreateOnDisk();
03327 
03328                 // in aGroup, create 5 datasets to contain:
03329                 // "Nodes on Edges" - ID of node on edge
03330                 // "Edge positions" - U parameter on node on edge
03331                 // "Nodes on Faces" - ID of node on face
03332                 // "Face U positions" - U parameter of node on face
03333                 // "Face V positions" - V parameter of node on face
03334 
03335                 // Find out nb of nodes on edges and faces
03336                 // Collect corresponing sub-meshes
03337                 int nbEdgeNodes = 0, nbFaceNodes = 0;
03338                 list<SMESHDS_SubMesh*> aEdgeSM, aFaceSM;
03339                 // loop on SMESHDS_SubMesh'es
03340                 for ( itSubM = aSubMeshes.begin(); itSubM != aSubMeshes.end() ; itSubM++ )
03341                 {
03342                   SMESHDS_SubMesh* aSubMesh = (*itSubM).second;
03343                   if ( aSubMesh->IsComplexSubmesh() )
03344                     continue; // submesh containing other submeshs
03345                   int nbNodes = aSubMesh->NbNodes();
03346                   if ( nbNodes == 0 ) continue;
03347 
03348                   int aShapeID = (*itSubM).first;
03349                   if ( aShapeID < 1 || aShapeID > mySMESHDSMesh->MaxShapeIndex() )
03350                     continue;
03351                   int aShapeType = mySMESHDSMesh->IndexToShape( aShapeID ).ShapeType();
03352                   // write only SMDS_FacePosition and SMDS_EdgePosition
03353                   switch ( aShapeType ) {
03354                   case TopAbs_FACE:
03355                     nbFaceNodes += nbNodes;
03356                     aFaceSM.push_back( aSubMesh );
03357                     break;
03358                   case TopAbs_EDGE:
03359                     nbEdgeNodes += nbNodes;
03360                     aEdgeSM.push_back( aSubMesh );
03361                     break;
03362                   default:
03363                     continue;
03364                   }
03365                 }
03366                 // Treat positions on edges or faces
03367                 for ( int onFace = 0; onFace < 2; onFace++ )
03368                 {
03369                   // Create arrays to store in datasets
03370                   int iNode = 0, nbNodes = ( onFace ? nbFaceNodes : nbEdgeNodes );
03371                   if (!nbNodes) continue;
03372                   int* aNodeIDs = new int [ nbNodes ];
03373                   double* aUPos = new double [ nbNodes ];
03374                   double* aVPos = ( onFace ? new double[ nbNodes ] : 0 );
03375 
03376                   // Fill arrays
03377                   // loop on sub-meshes
03378                   list<SMESHDS_SubMesh*> * pListSM = ( onFace ? &aFaceSM : &aEdgeSM );
03379                   list<SMESHDS_SubMesh*>::iterator itSM = pListSM->begin();
03380                   for ( ; itSM != pListSM->end(); itSM++ )
03381                   {
03382                     SMESHDS_SubMesh* aSubMesh = (*itSM);
03383 
03384                     SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes();
03385                     // loop on nodes in aSubMesh
03386                     while ( itNode->more() )
03387                     {
03388                       //node ID
03389                       const SMDS_MeshNode* node = itNode->next();
03390                       aNodeIDs [ iNode ] = node->GetID();
03391 
03392                       // Position
03393                       const SMDS_PositionPtr pos = node->GetPosition();
03394                       if ( onFace ) { // on FACE
03395                         const SMDS_FacePosition* fPos =
03396                           dynamic_cast<const SMDS_FacePosition*>( pos );
03397                         if ( fPos ) {
03398                           aUPos[ iNode ] = fPos->GetUParameter();
03399                           aVPos[ iNode ] = fPos->GetVParameter();
03400                           iNode++;
03401                         }
03402                         else
03403                           nbNodes--;
03404                       }
03405                       else { // on EDGE
03406                         const SMDS_EdgePosition* ePos =
03407                           dynamic_cast<const SMDS_EdgePosition*>( pos );
03408                         if ( ePos ) {
03409                           aUPos[ iNode ] = ePos->GetUParameter();
03410                           iNode++;
03411                         }
03412                         else
03413                           nbNodes--;
03414                       }
03415                     } // loop on nodes in aSubMesh
03416                   } // loop on sub-meshes
03417 
03418                   // Write datasets
03419                   if ( nbNodes )
03420                   {
03421                     aSize[ 0 ] = nbNodes;
03422                     // IDS
03423                     string aDSName( onFace ? "Nodes on Faces" : "Nodes on Edges");
03424                     aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_INT32, aSize, 1 );
03425                     aDataset->CreateOnDisk();
03426                     aDataset->WriteOnDisk( aNodeIDs );
03427                     aDataset->CloseOnDisk();
03428 
03429                     // U Positions
03430                     aDSName = ( onFace ? "Face U positions" : "Edge positions");
03431                     aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1);
03432                     aDataset->CreateOnDisk();
03433                     aDataset->WriteOnDisk( aUPos );
03434                     aDataset->CloseOnDisk();
03435                     // V Positions
03436                     if ( onFace ) {
03437                       aDataset = new HDFdataset( "Face V positions", aGroup, HDF_FLOAT64, aSize, 1);
03438                       aDataset->CreateOnDisk();
03439                       aDataset->WriteOnDisk( aVPos );
03440                       aDataset->CloseOnDisk();
03441                     }
03442                   }
03443                   delete [] aNodeIDs;
03444                   delete [] aUPos;
03445                   if ( aVPos ) delete [] aVPos;
03446 
03447                 } // treat positions on edges or faces
03448 
03449                 // close "Node Positions" group
03450                 aGroup->CloseOnDisk();
03451 
03452               } // if ( there are submeshes in SMESHDS_Mesh )
03453             } // if ( hasData )
03454 
03455             // close mesh HDF group
03456             aTopGroup->CloseOnDisk();
03457           }
03458         }
03459       }
03460     }
03461   }
03462 
03463   // close HDF file
03464   aFile->CloseOnDisk();
03465   delete aFile;
03466 
03467   // Convert temporary files to stream
03468   aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile );
03469 
03470   // Remove temporary files and directory
03471   if ( !isMultiFile )
03472     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
03473 
03474   INFOS( "SMESH_Gen_i::Save() completed" );
03475   return aStreamFile._retn();
03476 }
03477 
03478 //=============================================================================
03484 //=============================================================================
03485 
03486 SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent,
03487                                            const char*              theURL,
03488                                            bool                     isMultiFile ) {
03489   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::SaveASCII" );
03490   SALOMEDS::TMPFile_var aStreamFile = Save( theComponent, theURL, isMultiFile );
03491   return aStreamFile._retn();
03492 
03493   //after usual saving needs to encipher binary to text string
03494   //Any binary symbol will be represent as "|xx" () hexadecimal format number
03495   int size = aStreamFile.in().length();
03496   _CORBA_Octet* buffer = new _CORBA_Octet[size*3+1];
03497   for ( int i = 0; i < size; i++ )
03498     sprintf( (char*)&(buffer[i*3]), "|%02x", aStreamFile[i] );
03499 
03500   buffer[size * 3] = '\0';
03501 
03502   SALOMEDS::TMPFile_var anAsciiStreamFile = new SALOMEDS::TMPFile(size*3, size*3, buffer, 1);
03503 
03504   return anAsciiStreamFile._retn();
03505 }
03506 
03507 //=============================================================================
03513 //=============================================================================
03514 
03515 void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot )
03516 {
03517   if ( theCompRoot->_is_nil() )
03518     return;
03519 
03520   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theCompRoot->GetStudy() );
03521   if ( aStudy->_is_nil() )
03522     return;
03523 
03524   SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
03525   aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() );
03526 }
03527 //=============================================================================
03531 //=============================================================================
03532 
03533 class PositionCreator {
03534 public:
03535   SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) {
03536     return (this->*myFuncTable[ type ])();
03537   }
03538   PositionCreator() {
03539     myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition );
03540     myFuncTable[ TopAbs_SOLID  ] = & PositionCreator::volumePosition;
03541     myFuncTable[ TopAbs_FACE   ] = & PositionCreator::facePosition;
03542     myFuncTable[ TopAbs_EDGE   ] = & PositionCreator::edgePosition;
03543     myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition;
03544   }
03545 private:
03546   SMDS_PositionPtr edgePosition()    const { return SMDS_PositionPtr( new SMDS_EdgePosition  ); }
03547   SMDS_PositionPtr facePosition()    const { return SMDS_PositionPtr( new SMDS_FacePosition  ); }
03548   SMDS_PositionPtr volumePosition()  const { return SMDS_PositionPtr( new SMDS_SpacePosition ); }
03549   SMDS_PositionPtr vertexPosition()  const { return SMDS_PositionPtr( new SMDS_VertexPosition); }
03550   SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition();  }
03551   typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const;
03552   vector<FmakePos> myFuncTable;
03553 };
03554 
03555 //=============================================================================
03561 //=============================================================================
03562 
03563 bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
03564                         const SALOMEDS::TMPFile& theStream,
03565                         const char*              theURL,
03566                         bool                     isMultiFile )
03567 {
03568   INFOS( "SMESH_Gen_i::Load" );
03569 
03570   if ( myCurrentStudy->_is_nil() ||
03571        theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
03572     SetCurrentStudy( theComponent->GetStudy() );
03573 
03574   /*  if( !theComponent->_is_nil() )
03575       {
03576       //SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow( theComponent->GetStudy() );
03577       if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
03578       loadGeomData( myCurrentStudy->FindComponent( "GEOM" ) );
03579       }*/
03580 
03581   StudyContext* myStudyContext = GetCurrentStudyContext();
03582 
03583   // Get temporary files location
03584   TCollection_AsciiString tmpDir =
03585     isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str();
03586 
03587     INFOS( "THE URL++++++++++++++" )
03588     INFOS( theURL );
03589     INFOS( "THE TMP PATH+++++++++" );
03590     INFOS( tmpDir );
03591 
03592   // Convert the stream into sequence of files to process
03593   SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
03594                                                                             tmpDir.ToCString(),
03595                                                                             isMultiFile );
03596   TCollection_AsciiString aStudyName( "" );
03597   if ( isMultiFile )
03598     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
03599 
03600   // Set names of temporary files
03601   TCollection_AsciiString filename = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH.hdf" );
03602   TCollection_AsciiString meshfile = tmpDir + aStudyName + TCollection_AsciiString( "_SMESH_Mesh.med" );
03603 
03604   int size;
03605   HDFfile*    aFile;
03606   HDFdataset* aDataset;
03607   HDFgroup*   aTopGroup;
03608   HDFgroup*   aGroup;
03609   HDFgroup*   aSubGroup;
03610   HDFgroup*   aSubSubGroup;
03611 
03612   // Read data
03613   // ---> open HDF file
03614   aFile = new HDFfile( (char*) filename.ToCString() );
03615   try {
03616     aFile->OpenOnDisk( HDF_RDONLY );
03617   }
03618   catch ( HDFexception ) {
03619     INFOS( "Load(): " << filename << " not found!" );
03620     return false;
03621   }
03622 
03623   DriverMED_R_SMESHDS_Mesh myReader;
03624   myReader.SetFile( meshfile.ToCString() );
03625 
03626   // For PAL13473 ("Repetitive mesh") implementation.
03627   // New dependencies between SMESH objects are established:
03628   // now hypotheses can refer to meshes, shapes and other hypotheses.
03629   // To keep data consistent, the following order of data restoration
03630   // imposed:
03631   // 1. Create hypotheses
03632   // 2. Create all meshes
03633   // 3. Load hypotheses' data
03634   // 4. All the rest
03635 
03636   list< pair< SMESH_Hypothesis_i*, string > >    hypDataList;
03637   list< pair< SMESH_Mesh_i*,       HDFgroup* > > meshGroupList;
03638 
03639   // get total number of top-level groups
03640   int aNbGroups = aFile->nInternalObjects();
03641   if ( aNbGroups > 0 ) {
03642     // --> in first turn we should read&create hypotheses
03643     if ( aFile->ExistInternalObject( "Hypotheses" ) ) {
03644       // open hypotheses root HDF group
03645       aTopGroup = new HDFgroup( "Hypotheses", aFile );
03646       aTopGroup->OpenOnDisk();
03647 
03648       // get number of hypotheses
03649       int aNbObjects = aTopGroup->nInternalObjects();
03650       for ( int j = 0; j < aNbObjects; j++ ) {
03651         // try to identify hypothesis
03652         char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
03653         aTopGroup->InternalObjectIndentify( j, hypGrpName );
03654 
03655         if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) {
03656           // open hypothesis group
03657           aGroup = new HDFgroup( hypGrpName, aTopGroup );
03658           aGroup->OpenOnDisk();
03659 
03660           // --> get hypothesis id
03661           int    id = atoi( string( hypGrpName ).substr( 10 ).c_str() );
03662           string hypname;
03663           string libname;
03664           string hypdata;
03665 
03666           // get number of datasets
03667           int aNbSubObjects = aGroup->nInternalObjects();
03668           for ( int k = 0; k < aNbSubObjects; k++ ) {
03669             // identify dataset
03670             char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ];
03671             aGroup->InternalObjectIndentify( k, name_of_subgroup );
03672             // --> get hypothesis name
03673             if ( strcmp( name_of_subgroup, "Name"  ) == 0 ) {
03674               aDataset = new HDFdataset( name_of_subgroup, aGroup );
03675               aDataset->OpenOnDisk();
03676               size = aDataset->GetSize();
03677               char* hypname_str = new char[ size ];
03678               aDataset->ReadFromDisk( hypname_str );
03679               hypname = string( hypname_str );
03680               delete [] hypname_str;
03681               aDataset->CloseOnDisk();
03682             }
03683             // --> get hypothesis plugin library name
03684             if ( strcmp( name_of_subgroup, "LibName"  ) == 0 ) {
03685               aDataset = new HDFdataset( name_of_subgroup, aGroup );
03686               aDataset->OpenOnDisk();
03687               size = aDataset->GetSize();
03688               char* libname_str = new char[ size ];
03689               aDataset->ReadFromDisk( libname_str );
03690               if(MYDEBUG) SCRUTE( libname_str );
03691               libname = string( libname_str );
03692               delete [] libname_str;
03693               aDataset->CloseOnDisk();
03694             }
03695             // --> get hypothesis data
03696             if ( strcmp( name_of_subgroup, "Data"  ) == 0 ) {
03697               aDataset = new HDFdataset( name_of_subgroup, aGroup );
03698               aDataset->OpenOnDisk();
03699               size = aDataset->GetSize();
03700               char* hypdata_str = new char[ size ];
03701               aDataset->ReadFromDisk( hypdata_str );
03702               hypdata = string( hypdata_str );
03703               delete [] hypdata_str;
03704               aDataset->CloseOnDisk();
03705             }
03706           }
03707           // close hypothesis HDF group
03708           aGroup->CloseOnDisk();
03709 
03710           // --> restore hypothesis from data
03711           if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty
03712             if(MYDEBUG) MESSAGE("VSR - load hypothesis : id = " << id <<
03713                                 ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str());
03714             SMESH::SMESH_Hypothesis_var myHyp;
03715 
03716             try { // protect persistence mechanism against exceptions
03717               myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
03718             }
03719             catch (...) {
03720               INFOS( "Exception during hypothesis creation" );
03721             }
03722 
03723             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
03724             if ( myImpl ) {
03725               // myImpl->LoadFrom( hypdata.c_str() );
03726               hypDataList.push_back( make_pair( myImpl, hypdata ));
03727               string iorString = GetORB()->object_to_string( myHyp );
03728               int newId = myStudyContext->findId( iorString );
03729               myStudyContext->mapOldToNew( id, newId );
03730             }
03731             else
03732               if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
03733           }
03734         }
03735       }
03736       // close hypotheses root HDF group
03737       aTopGroup->CloseOnDisk();
03738       aTopGroup = 0;
03739     }
03740 
03741     // --> then we should read&create algorithms
03742     if ( aFile->ExistInternalObject( "Algorithms" ) ) {
03743       // open algorithms root HDF group
03744       aTopGroup = new HDFgroup( "Algorithms", aFile );
03745       aTopGroup->OpenOnDisk();
03746 
03747       // get number of algorithms
03748       int aNbObjects = aTopGroup->nInternalObjects();
03749       for ( int j = 0; j < aNbObjects; j++ ) {
03750         // try to identify algorithm
03751         char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
03752         aTopGroup->InternalObjectIndentify( j, hypGrpName );
03753 
03754         if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) {
03755           // open algorithm group
03756           aGroup = new HDFgroup( hypGrpName, aTopGroup );
03757           aGroup->OpenOnDisk();
03758 
03759           // --> get algorithm id
03760           int    id = atoi( string( hypGrpName ).substr( 9 ).c_str() );
03761           string hypname;
03762           string libname;
03763           string hypdata;
03764 
03765           // get number of datasets
03766           int aNbSubObjects = aGroup->nInternalObjects();
03767           for ( int k = 0; k < aNbSubObjects; k++ ) {
03768             // identify dataset
03769             char name_of_subgroup[ HDF_NAME_MAX_LEN+1 ];
03770             aGroup->InternalObjectIndentify( k, name_of_subgroup );
03771             // --> get algorithm name
03772             if ( strcmp( name_of_subgroup, "Name"  ) == 0 ) {
03773               aDataset = new HDFdataset( name_of_subgroup, aGroup );
03774               aDataset->OpenOnDisk();
03775               size = aDataset->GetSize();
03776               char* hypname_str = new char[ size ];
03777               aDataset->ReadFromDisk( hypname_str );
03778               hypname = string( hypname_str );
03779               delete [] hypname_str;
03780               aDataset->CloseOnDisk();
03781             }
03782             // --> get algorithm plugin library name
03783             if ( strcmp( name_of_subgroup, "LibName"  ) == 0 ) {
03784               aDataset = new HDFdataset( name_of_subgroup, aGroup );
03785               aDataset->OpenOnDisk();
03786               size = aDataset->GetSize();
03787               char* libname_str = new char[ size ];
03788               aDataset->ReadFromDisk( libname_str );
03789               if(MYDEBUG) SCRUTE( libname_str );
03790               libname = string( libname_str );
03791               delete [] libname_str;
03792               aDataset->CloseOnDisk();
03793             }
03794             // --> get algorithm data
03795             if ( strcmp( name_of_subgroup, "Data"  ) == 0 ) {
03796               aDataset = new HDFdataset( name_of_subgroup, aGroup );
03797               aDataset->OpenOnDisk();
03798               size = aDataset->GetSize();
03799               char* hypdata_str = new char[ size ];
03800               aDataset->ReadFromDisk( hypdata_str );
03801               if(MYDEBUG) SCRUTE( hypdata_str );
03802               hypdata = string( hypdata_str );
03803               delete [] hypdata_str;
03804               aDataset->CloseOnDisk();
03805             }
03806           }
03807           // close algorithm HDF group
03808           aGroup->CloseOnDisk();
03809 
03810           // --> restore algorithm from data
03811           if ( id > 0 && !hypname.empty()/* && !hypdata.empty()*/ ) { // VSR : persistent data can be empty
03812             if(MYDEBUG) MESSAGE("VSR - load algo : id = " << id <<
03813                                 ", name = " << hypname.c_str() << ", persistent string = " << hypdata.c_str());
03814             SMESH::SMESH_Hypothesis_var myHyp;
03815 
03816             try { // protect persistence mechanism against exceptions
03817               myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
03818             }
03819             catch (...) {
03820               INFOS( "Exception during hypothesis creation" );
03821             }
03822 
03823             SMESH_Hypothesis_i* myImpl = dynamic_cast<SMESH_Hypothesis_i*>( GetServant( myHyp ).in() );
03824             if ( myImpl ) {
03825               //myImpl->LoadFrom( hypdata.c_str() );
03826               hypDataList.push_back( make_pair( myImpl, hypdata ));
03827               string iorString = GetORB()->object_to_string( myHyp );
03828               int newId = myStudyContext->findId( iorString );
03829               myStudyContext->mapOldToNew( id, newId );
03830             }
03831             else
03832               if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen::Load - can't get servant" );
03833           }
03834         }
03835       }
03836       // close algorithms root HDF group
03837       aTopGroup->CloseOnDisk();
03838       aTopGroup = 0;
03839     }
03840 
03841     // --> the rest groups should be meshes
03842     for ( int i = 0; i < aNbGroups; i++ ) {
03843       // identify next group
03844       char meshName[ HDF_NAME_MAX_LEN+1 ];
03845       aFile->InternalObjectIndentify( i, meshName );
03846 
03847       if ( string( meshName ).substr( 0, 4 ) == string( "Mesh" ) ) {
03848         // --> get mesh id
03849         int id = atoi( string( meshName ).substr( 4 ).c_str() );
03850         if ( id <= 0 )
03851           continue;
03852 
03853         // open mesh HDF group
03854         aTopGroup = new HDFgroup( meshName, aFile );
03855         aTopGroup->OpenOnDisk();
03856 
03857         // get number of child HDF objects
03858         int aNbObjects = aTopGroup->nInternalObjects();
03859         if ( aNbObjects > 0 ) {
03860           // create mesh
03861           if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id );
03862           SMESH::SMESH_Mesh_var myNewMesh = this->createMesh();
03863           SMESH_Mesh_i* myNewMeshImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( myNewMesh ).in() );
03864           if ( !myNewMeshImpl )
03865             continue;
03866           meshGroupList.push_back( make_pair( myNewMeshImpl, aTopGroup ));
03867 
03868           string iorString = GetORB()->object_to_string( myNewMesh );
03869           int newId = myStudyContext->findId( iorString );
03870           myStudyContext->mapOldToNew( id, newId );
03871 
03872           // ouv : NPAL12872
03873           // try to read and set auto color flag
03874           char aMeshAutoColorName[ 30 ];
03875           sprintf( aMeshAutoColorName, "AutoColorMesh %d", id);
03876           if( aTopGroup->ExistInternalObject( aMeshAutoColorName ) )
03877           {
03878             aDataset = new HDFdataset( aMeshAutoColorName, aTopGroup );
03879             aDataset->OpenOnDisk();
03880             size = aDataset->GetSize();
03881             int* anAutoColor = new int[ size ];
03882             aDataset->ReadFromDisk( anAutoColor );
03883             aDataset->CloseOnDisk();
03884             myNewMeshImpl->GetImpl().SetAutoColor( (bool)anAutoColor[0] );
03885           }
03886 
03887           // try to read and set reference to shape
03888           GEOM::GEOM_Object_var aShapeObject;
03889           if ( aTopGroup->ExistInternalObject( "Ref on shape" ) ) {
03890             // load mesh "Ref on shape" - it's an entry to SObject
03891             aDataset = new HDFdataset( "Ref on shape", aTopGroup );
03892             aDataset->OpenOnDisk();
03893             size = aDataset->GetSize();
03894             char* refFromFile = new char[ size ];
03895             aDataset->ReadFromDisk( refFromFile );
03896             aDataset->CloseOnDisk();
03897             if ( strlen( refFromFile ) > 0 ) {
03898               SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile );
03899 
03900               // Make sure GEOM data are loaded first
03901               //loadGeomData( shapeSO->GetFatherComponent() );
03902 
03903               CORBA::Object_var shapeObject = SObjectToObject( shapeSO );
03904               if ( !CORBA::is_nil( shapeObject ) ) {
03905                 aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject );
03906                 if ( !aShapeObject->_is_nil() )
03907                   myNewMeshImpl->SetShape( aShapeObject );
03908               }
03909             }
03910           }
03911 
03912           // issue 0020693. Restore _isModified flag
03913           if( aTopGroup->ExistInternalObject( "_isModified" ) )
03914           {
03915             aDataset = new HDFdataset( "_isModified", aTopGroup );
03916             aDataset->OpenOnDisk();
03917             size = aDataset->GetSize();
03918             int* isModified = new int[ size ];
03919             aDataset->ReadFromDisk( isModified );
03920             aDataset->CloseOnDisk();
03921             myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified));
03922           }
03923 
03924           // issue 20918. Restore Persistent Id of SMESHDS_Mesh
03925           if( aTopGroup->ExistInternalObject( "meshPersistentId" ) )
03926           {
03927             aDataset = new HDFdataset( "meshPersistentId", aTopGroup );
03928             aDataset->OpenOnDisk();
03929             size = aDataset->GetSize();
03930             int* meshPersistentId = new int[ size ];
03931             aDataset->ReadFromDisk( meshPersistentId );
03932             aDataset->CloseOnDisk();
03933             myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId );
03934           }
03935         }
03936       }
03937     }
03938 
03939     // As all object that can be referred by hypothesis are created,
03940     // we can restore hypothesis data
03941 
03942     list< pair< SMESH_Hypothesis_i*, string > >::iterator hyp_data;
03943     for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data )
03944     {
03945       SMESH_Hypothesis_i* hyp  = hyp_data->first;
03946       string &            data = hyp_data->second;
03947       hyp->LoadFrom( data.c_str() );
03948     }
03949 
03950     // Restore the rest mesh data
03951 
03952     list< pair< SMESH_Mesh_i*, HDFgroup* > >::iterator meshi_group;
03953     for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group )
03954     {
03955       aTopGroup                   = meshi_group->second;
03956       SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
03957       ::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
03958       SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
03959 
03960       GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh();
03961       bool hasData = false;
03962 
03963       // get mesh old id
03964       string iorString = GetORB()->object_to_string( myNewMeshImpl->_this() );
03965       int newId = myStudyContext->findId( iorString );
03966       int id = myStudyContext->getOldId( newId );
03967 
03968       // try to find mesh data dataset
03969       if ( aTopGroup->ExistInternalObject( "Has data" ) ) {
03970         // load mesh "has data" flag
03971         aDataset = new HDFdataset( "Has data", aTopGroup );
03972         aDataset->OpenOnDisk();
03973         size = aDataset->GetSize();
03974         char* strHasData = new char[ size ];
03975         aDataset->ReadFromDisk( strHasData );
03976         aDataset->CloseOnDisk();
03977         if ( strcmp( strHasData, "1") == 0 ) {
03978           // read mesh data from MED file
03979           myReader.SetMesh( mySMESHDSMesh );
03980           myReader.SetMeshId( id );
03981           myReader.Perform();
03982           hasData = true;
03983         }
03984       }
03985 
03986       // Try to get applied ALGORITHMS (mesh is not cleared by algo addition because
03987       // nodes and elements are not yet put into sub-meshes)
03988       if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) {
03989         aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
03990         aGroup->OpenOnDisk();
03991         // get number of applied algorithms
03992         int aNbSubObjects = aGroup->nInternalObjects();
03993         if(MYDEBUG) MESSAGE( "VSR - number of applied algos " << aNbSubObjects );
03994         for ( int j = 0; j < aNbSubObjects; j++ ) {
03995           char name_dataset[ HDF_NAME_MAX_LEN+1 ];
03996           aGroup->InternalObjectIndentify( j, name_dataset );
03997           // check if it is an algorithm
03998           if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) {
03999             aDataset = new HDFdataset( name_dataset, aGroup );
04000             aDataset->OpenOnDisk();
04001             size = aDataset->GetSize();
04002             char* refFromFile = new char[ size ];
04003             aDataset->ReadFromDisk( refFromFile );
04004             aDataset->CloseOnDisk();
04005 
04006             // san - it is impossible to recover applied algorithms using their entries within Load() method
04007 
04008             //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
04009             //CORBA::Object_var hypObject = SObjectToObject( hypSO );
04010             int id = atoi( refFromFile );
04011             string anIOR = myStudyContext->getIORbyOldId( id );
04012             if ( !anIOR.empty() ) {
04013               CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
04014               if ( !CORBA::is_nil( hypObject ) ) {
04015                 SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
04016                 if ( !anHyp->_is_nil() && (!aShapeObject->_is_nil()
04017                                            || !myNewMeshImpl->HasShapeToMesh()) )
04018                   myNewMeshImpl->addHypothesis( aShapeObject, anHyp );
04019               }
04020             }
04021           }
04022         }
04023         aGroup->CloseOnDisk();
04024       }
04025 
04026       // try to get applied hypotheses
04027       if ( aTopGroup->ExistInternalObject( "Applied Hypotheses" ) ) {
04028         aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
04029         aGroup->OpenOnDisk();
04030         // get number of applied hypotheses
04031         int aNbSubObjects = aGroup->nInternalObjects();
04032         for ( int j = 0; j < aNbSubObjects; j++ ) {
04033           char name_dataset[ HDF_NAME_MAX_LEN+1 ];
04034           aGroup->InternalObjectIndentify( j, name_dataset );
04035           // check if it is a hypothesis
04036           if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) {
04037             aDataset = new HDFdataset( name_dataset, aGroup );
04038             aDataset->OpenOnDisk();
04039             size = aDataset->GetSize();
04040             char* refFromFile = new char[ size ];
04041             aDataset->ReadFromDisk( refFromFile );
04042             aDataset->CloseOnDisk();
04043 
04044             // san - it is impossible to recover applied hypotheses using their entries within Load() method
04045 
04046             //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
04047             //CORBA::Object_var hypObject = SObjectToObject( hypSO );
04048             int id = atoi( refFromFile );
04049             string anIOR = myStudyContext->getIORbyOldId( id );
04050             if ( !anIOR.empty() ) {
04051               CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
04052               if ( !CORBA::is_nil( hypObject ) ) {
04053                 SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
04054                 if ( !anHyp->_is_nil() && (!aShapeObject->_is_nil()
04055                                            || !myNewMeshImpl->HasShapeToMesh()) )
04056                   myNewMeshImpl->addHypothesis( aShapeObject, anHyp );
04057               }
04058             }
04059           }
04060         }
04061         aGroup->CloseOnDisk();
04062       }
04063 
04064       // --> try to find submeshes containers for each type of submesh
04065       for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) {
04066         char name_meshgroup[ 30 ];
04067         if ( j == GetSubMeshOnVertexTag() )
04068           strcpy( name_meshgroup, "SubMeshes On Vertex" );
04069         else if ( j == GetSubMeshOnEdgeTag() )
04070           strcpy( name_meshgroup, "SubMeshes On Edge" );
04071         else if ( j == GetSubMeshOnWireTag() )
04072           strcpy( name_meshgroup, "SubMeshes On Wire" );
04073         else if ( j == GetSubMeshOnFaceTag() )
04074           strcpy( name_meshgroup, "SubMeshes On Face" );
04075         else if ( j == GetSubMeshOnShellTag() )
04076           strcpy( name_meshgroup, "SubMeshes On Shell" );
04077         else if ( j == GetSubMeshOnSolidTag() )
04078           strcpy( name_meshgroup, "SubMeshes On Solid" );
04079         else if ( j == GetSubMeshOnCompoundTag() )
04080           strcpy( name_meshgroup, "SubMeshes On Compound" );
04081 
04082         // try to get submeshes container HDF group
04083         if ( aTopGroup->ExistInternalObject( name_meshgroup ) ) {
04084           // open submeshes containers HDF group
04085           aGroup = new HDFgroup( name_meshgroup, aTopGroup );
04086           aGroup->OpenOnDisk();
04087 
04088           // get number of submeshes
04089           int aNbSubMeshes = aGroup->nInternalObjects();
04090           for ( int k = 0; k < aNbSubMeshes; k++ ) {
04091             // identify submesh
04092             char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ];
04093             aGroup->InternalObjectIndentify( k, name_submeshgroup );
04094             if ( string( name_submeshgroup ).substr( 0, 7 ) == string( "SubMesh" )  ) {
04095               // --> get submesh id
04096               int subid = atoi( string( name_submeshgroup ).substr( 7 ).c_str() );
04097               if ( subid <= 0 )
04098                 continue;
04099               // open submesh HDF group
04100               aSubGroup = new HDFgroup( name_submeshgroup, aGroup );
04101               aSubGroup->OpenOnDisk();
04102 
04103               // try to read and set reference to subshape
04104               GEOM::GEOM_Object_var aSubShapeObject;
04105               SMESH::SMESH_subMesh_var aSubMesh;
04106 
04107               if ( aSubGroup->ExistInternalObject( "Ref on shape" ) ) {
04108                 // load submesh "Ref on shape" - it's an entry to SObject
04109                 aDataset = new HDFdataset( "Ref on shape", aSubGroup );
04110                 aDataset->OpenOnDisk();
04111                 size = aDataset->GetSize();
04112                 char* refFromFile = new char[ size ];
04113                 aDataset->ReadFromDisk( refFromFile );
04114                 aDataset->CloseOnDisk();
04115                 if ( strlen( refFromFile ) > 0 ) {
04116                   SALOMEDS::SObject_var subShapeSO = myCurrentStudy->FindObjectID( refFromFile );
04117                   CORBA::Object_var subShapeObject = SObjectToObject( subShapeSO );
04118                   if ( !CORBA::is_nil( subShapeObject ) ) {
04119                     aSubShapeObject = GEOM::GEOM_Object::_narrow( subShapeObject );
04120                     if ( !aSubShapeObject->_is_nil() )
04121                       aSubMesh = SMESH::SMESH_subMesh::_duplicate
04122                         ( myNewMeshImpl->createSubMesh( aSubShapeObject ) );
04123                     if ( aSubMesh->_is_nil() )
04124                       continue;
04125                     string iorSubString = GetORB()->object_to_string( aSubMesh );
04126                     int newSubId = myStudyContext->findId( iorSubString );
04127                     myStudyContext->mapOldToNew( subid, newSubId );
04128                   }
04129                 }
04130               }
04131 
04132               if ( aSubMesh->_is_nil() )
04133                 continue;
04134 
04135               // try to get applied algorithms
04136               if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) {
04137                 // open "applied algorithms" HDF group
04138                 aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
04139                 aSubSubGroup->OpenOnDisk();
04140                 // get number of applied algorithms
04141                 int aNbSubObjects = aSubSubGroup->nInternalObjects();
04142                 for ( int l = 0; l < aNbSubObjects; l++ ) {
04143                   char name_dataset[ HDF_NAME_MAX_LEN+1 ];
04144                   aSubSubGroup->InternalObjectIndentify( l, name_dataset );
04145                   // check if it is an algorithm
04146                   if ( string( name_dataset ).substr( 0, 4 ) == string( "Algo" ) ) {
04147                     aDataset = new HDFdataset( name_dataset, aSubSubGroup );
04148                     aDataset->OpenOnDisk();
04149                     size = aDataset->GetSize();
04150                     char* refFromFile = new char[ size ];
04151                     aDataset->ReadFromDisk( refFromFile );
04152                     aDataset->CloseOnDisk();
04153 
04154                     int id = atoi( refFromFile );
04155                     string anIOR = myStudyContext->getIORbyOldId( id );
04156                     if ( !anIOR.empty() ) {
04157                       CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
04158                       if ( !CORBA::is_nil( hypObject ) ) {
04159                         SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
04160                         if ( !anHyp->_is_nil() && !aShapeObject->_is_nil() )
04161                           myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp );
04162                       }
04163                     }
04164                   }
04165                 }
04166                 // close "applied algorithms" HDF group
04167                 aSubSubGroup->CloseOnDisk();
04168               }
04169 
04170               // try to get applied hypotheses
04171               if ( aSubGroup->ExistInternalObject( "Applied Hypotheses" ) ) {
04172                 // open "applied hypotheses" HDF group
04173                 aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
04174                 aSubSubGroup->OpenOnDisk();
04175                 // get number of applied hypotheses
04176                 int aNbSubObjects = aSubSubGroup->nInternalObjects();
04177                 for ( int l = 0; l < aNbSubObjects; l++ ) {
04178                   char name_dataset[ HDF_NAME_MAX_LEN+1 ];
04179                   aSubSubGroup->InternalObjectIndentify( l, name_dataset );
04180                   // check if it is a hypothesis
04181                   if ( string( name_dataset ).substr( 0, 3 ) == string( "Hyp" ) ) {
04182                     aDataset = new HDFdataset( name_dataset, aSubSubGroup );
04183                     aDataset->OpenOnDisk();
04184                     size = aDataset->GetSize();
04185                     char* refFromFile = new char[ size ];
04186                     aDataset->ReadFromDisk( refFromFile );
04187                     aDataset->CloseOnDisk();
04188 
04189                     int id = atoi( refFromFile );
04190                     string anIOR = myStudyContext->getIORbyOldId( id );
04191                     if ( !anIOR.empty() ) {
04192                       CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
04193                       if ( !CORBA::is_nil( hypObject ) ) {
04194                         SMESH::SMESH_Hypothesis_var anHyp = SMESH::SMESH_Hypothesis::_narrow( hypObject );
04195                         if ( !anHyp->_is_nil() && !aShapeObject->_is_nil() )
04196                           myNewMeshImpl->addHypothesis( aSubShapeObject, anHyp );
04197                       }
04198                     }
04199                   }
04200                 }
04201                 // close "applied hypotheses" HDF group
04202                 aSubSubGroup->CloseOnDisk();
04203               }
04204 
04205               // close submesh HDF group
04206               aSubGroup->CloseOnDisk();
04207             }
04208           }
04209           // close submeshes containers HDF group
04210           aGroup->CloseOnDisk();
04211         }
04212       }
04213 
04214       if(hasData) {
04215 
04216         // Read sub-meshes
04217         // ----------------
04218         if(MYDEBUG) MESSAGE("Create all sub-meshes");
04219         bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" ));
04220         if ( submeshesInFamilies ) // from MED
04221         {
04222           // old way working before fix of PAL 12992
04223           myReader.CreateAllSubMeshes();
04224         }
04225         else
04226         {
04227           // open a group
04228           aGroup = new HDFgroup( "Submeshes", aTopGroup );
04229           aGroup->OpenOnDisk();
04230 
04231           int maxID = Max( mySMESHDSMesh->MaxSubMeshIndex(), mySMESHDSMesh->MaxShapeIndex() );
04232           vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 );
04233           vector< TopAbs_ShapeEnum  > smType   ( maxID + 1, TopAbs_SHAPE );
04234 
04235           PositionCreator aPositionCreator;
04236 
04237           SMDS_NodeIteratorPtr nIt = mySMESHDSMesh->nodesIterator();
04238           SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator();
04239           for ( int isNode = 0; isNode < 2; ++isNode )
04240           {
04241             string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
04242             if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
04243             {
04244               aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
04245               aDataset->OpenOnDisk();
04246               // read submesh IDs for all elements sorted by ID
04247               int nbElems = aDataset->GetSize();
04248               int* smIDs = new int [ nbElems ];
04249               aDataset->ReadFromDisk( smIDs );
04250               aDataset->CloseOnDisk();
04251 
04252               // get elements sorted by ID
04253               TIDSortedElemSet elemSet;
04254               if ( isNode )
04255                 while ( nIt->more() ) elemSet.insert( nIt->next() );
04256               else
04257                 while ( eIt->more() ) elemSet.insert( eIt->next() );
04258               //ASSERT( elemSet.size() == nbElems ); -- issue 20182
04259               // -- Most probably a bad study was saved when there were
04260               // not fixed bugs in SMDS_MeshInfo
04261               if ( elemSet.size() < nbElems ) {
04262 #ifdef _DEBUG_
04263                 cout << "SMESH_Gen_i::Load(), warning: Node position data is invalid" << endl;
04264 #endif
04265                 nbElems = elemSet.size();
04266               }
04267               // add elements to submeshes
04268               TIDSortedElemSet::iterator iE = elemSet.begin();
04269               for ( int i = 0; i < nbElems; ++i, ++iE )
04270               {
04271                 int smID = smIDs[ i ];
04272                 if ( smID == 0 ) continue;
04273                 const SMDS_MeshElement* elem = *iE;
04274                 if( smID > maxID ) {
04275                   // corresponding subshape no longer exists: maybe geom group has been edited
04276                   if ( myNewMeshImpl->HasShapeToMesh() )
04277                     mySMESHDSMesh->RemoveElement( elem );
04278                   continue;
04279                 }
04280                 // get or create submesh
04281                 SMESHDS_SubMesh* & sm = subMeshes[ smID ];
04282                 if ( ! sm ) {
04283                   sm = mySMESHDSMesh->NewSubMesh( smID );
04284                   smType[ smID ] = mySMESHDSMesh->IndexToShape( smID ).ShapeType();
04285                 }
04286                 // add
04287                 if ( isNode ) {
04288                   SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
04289                   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
04290                   node->SetPosition( pos );
04291                   sm->AddNode( node );
04292                 } else {
04293                   sm->AddElement( elem );
04294                 }
04295               }
04296               delete [] smIDs;
04297             }
04298           }
04299         } // end reading submeshes
04300 
04301         // Read node positions on sub-shapes (SMDS_Position)
04302 
04303         if ( aTopGroup->ExistInternalObject( "Node Positions" ))
04304         {
04305           // There are 5 datasets to read:
04306           // "Nodes on Edges" - ID of node on edge
04307           // "Edge positions" - U parameter on node on edge
04308           // "Nodes on Faces" - ID of node on face
04309           // "Face U positions" - U parameter of node on face
04310           // "Face V positions" - V parameter of node on face
04311           const char* aEid_DSName = "Nodes on Edges";
04312           const char* aEu_DSName  = "Edge positions";
04313           const char* aFu_DSName  = "Face U positions";
04314           //char* aFid_DSName = "Nodes on Faces";
04315           //char* aFv_DSName  = "Face V positions";
04316 
04317           // data to retrieve
04318           int nbEids = 0, nbFids = 0;
04319           int *aEids = 0, *aFids  = 0;
04320           double *aEpos = 0, *aFupos = 0, *aFvpos = 0;
04321 
04322           // open a group
04323           aGroup = new HDFgroup( "Node Positions", aTopGroup );
04324           aGroup->OpenOnDisk();
04325 
04326           // loop on 5 data sets
04327           int aNbObjects = aGroup->nInternalObjects();
04328           for ( int i = 0; i < aNbObjects; i++ )
04329           {
04330             // identify dataset
04331             char aDSName[ HDF_NAME_MAX_LEN+1 ];
04332             aGroup->InternalObjectIndentify( i, aDSName );
04333             // read data
04334             aDataset = new HDFdataset( aDSName, aGroup );
04335             aDataset->OpenOnDisk();
04336             if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions
04337             {
04338               double* pos = new double [ aDataset->GetSize() ];
04339               aDataset->ReadFromDisk( pos );
04340               // which one?
04341               if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 )
04342                 aEpos = pos;
04343               else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 )
04344                 aFupos = pos;
04345               else
04346                 aFvpos = pos;
04347             }
04348             else // NODE IDS
04349             {
04350               int aSize = aDataset->GetSize();
04351 
04352               // for reading files, created from 18.07.2005 till 10.10.2005
04353               if (aDataset->GetType() == HDF_STRING)
04354                 aSize /= sizeof(int);
04355 
04356               int* ids = new int [aSize];
04357               aDataset->ReadFromDisk( ids );
04358               // on face or nodes?
04359               if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) {
04360                 aEids = ids;
04361                 nbEids = aSize;
04362               }
04363               else {
04364                 aFids = ids;
04365                 nbFids = aSize;
04366               }
04367             }
04368             aDataset->CloseOnDisk();
04369           } // loop on 5 datasets
04370 
04371           // Set node positions on edges or faces
04372           for ( int onFace = 0; onFace < 2; onFace++ )
04373           {
04374             int nbNodes = ( onFace ? nbFids : nbEids );
04375             if ( nbNodes == 0 ) continue;
04376             int* aNodeIDs = ( onFace ? aFids : aEids );
04377             double* aUPos = ( onFace ? aFupos : aEpos );
04378             double* aVPos = ( onFace ? aFvpos : 0 );
04379             // loop on node IDs
04380             for ( int iNode = 0; iNode < nbNodes; iNode++ )
04381             {
04382               const SMDS_MeshNode* node = mySMESHDSMesh->FindNode( aNodeIDs[ iNode ]);
04383               if ( !node ) continue; // maybe removed while Loading() if geometry changed
04384               SMDS_PositionPtr aPos = node->GetPosition();
04385               ASSERT( aPos );
04386               if ( onFace ) {
04387                 // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );-- issue 20182
04388                 // -- Most probably a bad study was saved when there were
04389                 // not fixed bugs in SMDS_MeshInfo
04390                 if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
04391                   SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
04392                     ( static_cast<const SMDS_FacePosition*>( aPos ));
04393                   fPos->SetUParameter( aUPos[ iNode ]);
04394                   fPos->SetVParameter( aVPos[ iNode ]);
04395                 }
04396               }
04397               else {
04398                 // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182
04399                 if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) {
04400                   SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
04401                     ( static_cast<const SMDS_EdgePosition*>( aPos ));
04402                   fPos->SetUParameter( aUPos[ iNode ]);
04403                 }
04404               }
04405             }
04406           }
04407           if ( aEids ) delete [] aEids;
04408           if ( aFids ) delete [] aFids;
04409           if ( aEpos ) delete [] aEpos;
04410           if ( aFupos ) delete [] aFupos;
04411           if ( aFvpos ) delete [] aFvpos;
04412 
04413           aGroup->CloseOnDisk();
04414 
04415         } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) )
04416       } // if ( hasData )
04417 
04418       // try to get groups
04419       for ( int ii = GetNodeGroupsTag(); ii <= Get0DElementsGroupsTag(); ii++ ) {
04420         char name_group[ 30 ];
04421         if ( ii == GetNodeGroupsTag() )
04422           strcpy( name_group, "Groups of Nodes" );
04423         else if ( ii == GetEdgeGroupsTag() )
04424           strcpy( name_group, "Groups of Edges" );
04425         else if ( ii == GetFaceGroupsTag() )
04426           strcpy( name_group, "Groups of Faces" );
04427         else if ( ii == GetVolumeGroupsTag() )
04428           strcpy( name_group, "Groups of Volumes" );
04429         else if ( ii == Get0DElementsGroupsTag() )
04430           strcpy( name_group, "Groups of 0D Elements" );
04431 
04432         if ( aTopGroup->ExistInternalObject( name_group ) ) {
04433           aGroup = new HDFgroup( name_group, aTopGroup );
04434           aGroup->OpenOnDisk();
04435           // get number of groups
04436           int aNbSubObjects = aGroup->nInternalObjects();
04437           for ( int j = 0; j < aNbSubObjects; j++ ) {
04438             char name_dataset[ HDF_NAME_MAX_LEN+1 ];
04439             aGroup->InternalObjectIndentify( j, name_dataset );
04440             // check if it is an group
04441             if ( string( name_dataset ).substr( 0, 5 ) == string( "Group" ) ) {
04442               // --> get group id
04443               int subid = atoi( string( name_dataset ).substr( 5 ).c_str() );
04444               if ( subid <= 0 )
04445                 continue;
04446               aDataset = new HDFdataset( name_dataset, aGroup );
04447               aDataset->OpenOnDisk();
04448 
04449               // Retrieve actual group name
04450               size = aDataset->GetSize();
04451               char* nameFromFile = new char[ size ];
04452               aDataset->ReadFromDisk( nameFromFile );
04453               aDataset->CloseOnDisk();
04454 
04455               // Try to find a shape reference
04456               TopoDS_Shape aShape;
04457               char aRefName[ 30 ];
04458               sprintf( aRefName, "Ref on shape %d", subid);
04459               if ( aGroup->ExistInternalObject( aRefName ) ) {
04460                 // load mesh "Ref on shape" - it's an entry to SObject
04461                 aDataset = new HDFdataset( aRefName, aGroup );
04462                 aDataset->OpenOnDisk();
04463                 size = aDataset->GetSize();
04464                 char* refFromFile = new char[ size ];
04465                 aDataset->ReadFromDisk( refFromFile );
04466                 aDataset->CloseOnDisk();
04467                 if ( strlen( refFromFile ) > 0 ) {
04468                   SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile );
04469                   CORBA::Object_var shapeObject = SObjectToObject( shapeSO );
04470                   if ( !CORBA::is_nil( shapeObject ) ) {
04471                     aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject );
04472                     if ( !aShapeObject->_is_nil() )
04473                       aShape = GeomObjectToShape( aShapeObject );
04474                   }
04475                 }
04476               }
04477               // Create group servant
04478               SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1);
04479               SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate
04480                 ( myNewMeshImpl->createGroup( type, nameFromFile, aShape ) );
04481               // Obtain a SMESHDS_Group object
04482               if ( aNewGroup->_is_nil() )
04483                 continue;
04484 
04485               string iorSubString = GetORB()->object_to_string( aNewGroup );
04486               int newSubId = myStudyContext->findId( iorSubString );
04487               myStudyContext->mapOldToNew( subid, newSubId );
04488 
04489               SMESH_GroupBase_i* aGroupImpl =
04490                 dynamic_cast<SMESH_GroupBase_i*>( GetServant( aNewGroup ).in() );
04491               if ( !aGroupImpl )
04492                 continue;
04493 
04494               SMESH_Group* aLocalGroup  = myLocMesh.GetGroup( aGroupImpl->GetLocalID() );
04495               if ( !aLocalGroup )
04496                 continue;
04497 
04498               SMESHDS_GroupBase* aGroupBaseDS = aLocalGroup->GetGroupDS();
04499               aGroupBaseDS->SetStoreName( name_dataset );
04500 
04501               // ouv : NPAL12872
04502               // Read color of the group
04503               char aGroupColorName[ 30 ];
04504               sprintf( aGroupColorName, "ColorGroup %d", subid);
04505               if ( aGroup->ExistInternalObject( aGroupColorName ) )
04506               {
04507                 aDataset = new HDFdataset( aGroupColorName, aGroup );
04508                 aDataset->OpenOnDisk();
04509                 size = aDataset->GetSize();
04510                 double* anRGB = new double[ size ];
04511                 aDataset->ReadFromDisk( anRGB );
04512                 aDataset->CloseOnDisk();
04513                 Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB );
04514                 aGroupBaseDS->SetColor( aColor );
04515               }
04516 
04517               // Fill group with contents from MED file
04518               SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( aGroupBaseDS );
04519               if ( aGrp )
04520                 myReader.GetGroup( aGrp );
04521             }
04522           }
04523           aGroup->CloseOnDisk();
04524         }
04525       }
04526 
04527       // read submeh order if any
04528       if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) {
04529         aDataset = new HDFdataset( "Mesh Order", aTopGroup );
04530         aDataset->OpenOnDisk();
04531         size = aDataset->GetSize();
04532         int* smIDs = new int[ size ];
04533         aDataset->ReadFromDisk( smIDs );
04534         aDataset->CloseOnDisk();
04535         TListOfListOfInt anOrderIds;
04536         anOrderIds.push_back( TListOfInt() );
04537         for ( int i = 0; i < size; i++ )
04538           if ( smIDs[ i ] < 0 ) // is separator
04539             anOrderIds.push_back( TListOfInt() );
04540           else
04541             anOrderIds.back().push_back(smIDs[ i ]);
04542 
04543         myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
04544       }
04545     } // loop on meshes
04546 
04547     // notify algos on completed restoration
04548     for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group )
04549     {
04550       SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
04551       ::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
04552 
04553       TopoDS_Shape myLocShape;
04554       if(myLocMesh.HasShapeToMesh())
04555         myLocShape = myLocMesh.GetShapeToMesh();
04556       else
04557         myLocShape = SMESH_Mesh::PseudoShape();
04558 
04559       myLocMesh.GetSubMesh(myLocShape)->
04560         ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED);
04561     }
04562 
04563     for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data )
04564     {
04565       SMESH_Hypothesis_i* hyp  = hyp_data->first;
04566       hyp->UpdateAsMeshesRestored(); // for hyps needing full mesh data restored (issue 20918)
04567     }
04568 
04569     // close mesh group
04570     if(aTopGroup)
04571       aTopGroup->CloseOnDisk();
04572   }
04573   // close HDF file
04574   aFile->CloseOnDisk();
04575   delete aFile;
04576 
04577   // Remove temporary files created from the stream
04578   if ( !isMultiFile )
04579     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
04580 
04581   INFOS( "SMESH_Gen_i::Load completed" );
04582   return true;
04583 }
04584 
04585 //=============================================================================
04591 //=============================================================================
04592 
04593 bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent,
04594                              const SALOMEDS::TMPFile& theStream,
04595                              const char*              theURL,
04596                              bool                     isMultiFile ) {
04597   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LoadASCII" );
04598   return Load( theComponent, theStream, theURL, isMultiFile );
04599 
04600   //before call main ::Load method it's need for decipher text format to
04601   //binary ( "|xx" => x' )
04602   int size = theStream.length();
04603   if ( int((size / 3 )*3) != size ) //error size of buffer
04604     return false;
04605 
04606   int real_size = int(size / 3);
04607 
04608   _CORBA_Octet* buffer = new _CORBA_Octet[real_size];
04609   char tmp[3];
04610   tmp[2]='\0';
04611   int c = -1;
04612   for ( int i = 0; i < real_size; i++ )
04613   {
04614     memcpy( &(tmp[0]), &(theStream[i*3+1]), 2 );
04615     sscanf( tmp, "%x", &c );
04616     sprintf( (char*)&(buffer[i]), "%c", (char)c );
04617   }
04618 
04619   SALOMEDS::TMPFile_var aRealStreamFile = new SALOMEDS::TMPFile(real_size, real_size, buffer, 1);
04620 
04621   return Load( theComponent, *(aRealStreamFile._retn()), theURL, isMultiFile );
04622 }
04623 
04624 //=============================================================================
04630 //=============================================================================
04631 
04632 void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
04633 {
04634   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" );
04635 
04636   // set correct current study
04637   if (theComponent->GetStudy()->StudyId() != GetCurrentStudyID())
04638     SetCurrentStudy(theComponent->GetStudy());
04639 
04640   // Clear study contexts data
04641   int studyId = GetCurrentStudyID();
04642   if ( myStudyContextMap.find( studyId ) != myStudyContextMap.end() ) {
04643     delete myStudyContextMap[ studyId ];
04644     myStudyContextMap.erase( studyId );
04645   }
04646 
04647   // delete SMESH_Mesh's
04648 //   See bug IPAL19437.
04649 //
04650 //   StudyContextStruct* context = myGen.GetStudyContext( studyId );
04651 //   map< int, SMESH_Mesh* >::iterator i_mesh = context->mapMesh.begin();
04652 //   for ( ; i_mesh != context->mapMesh.end(); ++i_mesh ) {
04653 //     printf( "--------------------------- SMESH_Gen_i::Close, delete aGroup = %p \n", i_mesh->second );
04654 //     delete i_mesh->second;
04655 //   }
04656 
04657 
04658   // delete SMESHDS_Mesh's
04659   // it's too long on big meshes
04660 //   if ( context->myDocument ) {
04661 //     delete context->myDocument;
04662 //     context->myDocument = 0;
04663 //   }
04664 
04665   myCurrentStudy = SALOMEDS::Study::_nil();
04666   return;
04667 }
04668 
04669 //=============================================================================
04675 //=============================================================================
04676 
04677 char* SMESH_Gen_i::ComponentDataType()
04678 {
04679   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::ComponentDataType" );
04680   return CORBA::string_dup( "SMESH" );
04681 }
04682 
04683 
04684 //=============================================================================
04690 //=============================================================================
04691 
04692 char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/,
04693                                            const char*           IORString,
04694                                            CORBA::Boolean        /*isMultiFile*/,
04695                                            CORBA::Boolean        /*isASCII*/ )
04696 {
04697   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" );
04698   StudyContext* myStudyContext = GetCurrentStudyContext();
04699 
04700   if ( myStudyContext && strcmp( IORString, "" ) != 0 ) {
04701     int anId = myStudyContext->findId( IORString );
04702     if ( anId ) {
04703       if(MYDEBUG) MESSAGE( "VSR " << anId )
04704       char strId[ 20 ];
04705       sprintf( strId, "%d", anId );
04706       return  CORBA::string_dup( strId );
04707     }
04708   }
04709   return CORBA::string_dup( "" );
04710 }
04711 
04712 //=============================================================================
04718 //=============================================================================
04719 
04720 char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/,
04721                                            const char*           aLocalPersistentID,
04722                                            CORBA::Boolean        /*isMultiFile*/,
04723                                            CORBA::Boolean        /*isASCII*/ )
04724 {
04725   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::LocalPersistentIDToIOR(): id = " << aLocalPersistentID );
04726   StudyContext* myStudyContext = GetCurrentStudyContext();
04727 
04728   if ( myStudyContext && strcmp( aLocalPersistentID, "" ) != 0 ) {
04729     int anId = atoi( aLocalPersistentID );
04730     return CORBA::string_dup( myStudyContext->getIORbyOldId( anId ).c_str() );
04731   }
04732   return CORBA::string_dup( "" );
04733 }
04734 
04735 //=======================================================================
04736 //function : RegisterObject
04737 //purpose  :
04738 //=======================================================================
04739 
04740 int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject)
04741 {
04742   StudyContext* myStudyContext = GetCurrentStudyContext();
04743   if ( myStudyContext && !CORBA::is_nil( theObject )) {
04744     CORBA::String_var iorString = GetORB()->object_to_string( theObject );
04745     return myStudyContext->addObject( string( iorString.in() ) );
04746   }
04747   return 0;
04748 }
04749 
04750 //================================================================================
04756 //================================================================================
04757 
04758 CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject)
04759 {
04760   StudyContext* myStudyContext = GetCurrentStudyContext();
04761   if ( myStudyContext && !CORBA::is_nil( theObject )) {
04762     string iorString = GetORB()->object_to_string( theObject );
04763     return myStudyContext->findId( iorString );
04764   }
04765   return 0;
04766 }
04767 
04768 //=============================================================================
04774 //=============================================================================
04775 void SMESH_Gen_i::SetName(const char* theIOR,
04776                           const char* theName)
04777 {
04778   if ( theIOR && strcmp( theIOR, "" ) ) {
04779     CORBA::Object_var anObject = GetORB()->string_to_object( theIOR );
04780     SALOMEDS::SObject_var aSO = ObjectToSObject( myCurrentStudy, anObject );
04781     if ( !aSO->_is_nil() ) {
04782       SetName( aSO, theName );
04783     }
04784   }
04785 }
04786 
04787 int SMESH_Gen_i::GetCurrentStudyID()
04788 {
04789   return myCurrentStudy->_is_nil() || myCurrentStudy->_non_existent() ? -1 : myCurrentStudy->StudyId();
04790 }
04791 
04792 //=============================================================================
04798 //=============================================================================
04799 
04800 extern "C"
04801 { SMESH_I_EXPORT
04802   PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr            orb,
04803                                                  PortableServer::POA_ptr   poa,
04804                                                  PortableServer::ObjectId* contId,
04805                                                  const char*               instanceName,
04806                                                  const char*               interfaceName )
04807   {
04808     if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" );
04809     if(MYDEBUG) SCRUTE(interfaceName);
04810     SMESH_Gen_i* aSMESHGen = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName);
04811     return aSMESHGen->getId() ;
04812   }
04813 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS