Back to index

salome-smesh  6.5.0
SMESH_PreMeshInfo.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  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_PreMeshInfo.cxx
00023 // Created   : Fri Feb 10 17:36:39 2012
00024 // Author    : Edward AGAPOV (eap)
00025 //
00026 
00027 #include "SMESH_PreMeshInfo.hxx"
00028 
00029 #include "DriverMED_R_SMESHDS_Mesh.h"
00030 #include "SMDS_EdgePosition.hxx"
00031 #include "SMDS_FacePosition.hxx"
00032 #include "SMDS_SpacePosition.hxx"
00033 #include "SMDS_VertexPosition.hxx"
00034 #include "SMESHDS_Group.hxx"
00035 #include "SMESHDS_GroupOnFilter.hxx"
00036 #include "SMESH_Gen_i.hxx"
00037 #include "SMESH_Group_i.hxx"
00038 #include "SMESH_Mesh_i.hxx"
00039 #include "SMESH_subMesh_i.hxx"
00040 
00041 #include <HDFarray.hxx>
00042 #include <HDFdataset.hxx>
00043 #include <HDFfile.hxx>
00044 #include <HDFgroup.hxx>
00045 #include <MED_Factory.hxx>
00046 #include <SALOMEDS_Tool.hxx>
00047 
00048 #include <Standard_ErrorHandler.hxx>
00049 #include <Standard_Failure.hxx>
00050 #include <TopoDS_Iterator.hxx>
00051 #include <TopoDS_Shape.hxx>
00052 
00053 #include CORBA_SERVER_HEADER(SALOME_Session)
00054 
00055 #define MYDEBUGOUT(msg) //std::cout << msg << std::endl;
00056 
00057 //================================================================================
00058 #define PreMeshInfo_TRY \
00059   try { OCC_CATCH_SIGNALS
00060 //================================================================================
00061 #define PreMeshInfo_CATCH }                                             \
00062   catch (Standard_Failure& ex) {                                        \
00063     onExceptionCaught(SMESH_Comment("OCC Exception caught: \t")<<ex.GetMessageString()); \
00064   }                                                                     \
00065   catch ( const std::exception& ex) {                                   \
00066     onExceptionCaught(SMESH_Comment("Exception caught: \t")<<ex.what()); \
00067   }                                                                     \
00068   catch (...) {                                                         \
00069     onExceptionCaught("Unknown Exception caught");                      \
00070   }
00071 //================================================================================
00072 
00073 namespace
00074 {
00075   enum {  GroupOnFilter_OutOfDate = -1 };
00076 
00077   // a map to count not yet loaded meshes 
00078   static map< int, int > theStudyIDToMeshCounter;
00079 
00080   //================================================================================
00084   //================================================================================
00085 
00086   void meshInfoLoaded( SMESH_Mesh_i* mesh )
00087   {
00088     map< int, int >::iterator id2counter =
00089       theStudyIDToMeshCounter.insert( make_pair( (int) mesh->GetStudyId(), 0 )).first;
00090     id2counter->second++;
00091   }
00092   //================================================================================
00096   //================================================================================
00097 
00098   void filesNoMoreNeeded(SMESH_Mesh_i* mesh,
00099                          std::string   medFile,
00100                          std::string   hdfFile)
00101   {
00102     if ( --theStudyIDToMeshCounter[ (int) mesh->GetStudyId() ] == 0 )
00103     {
00104       string tmpDir = SALOMEDS_Tool::GetDirFromPath( hdfFile );
00105 
00106       SALOMEDS::ListOfFileNames_var aFiles = new SALOMEDS::ListOfFileNames;
00107       aFiles->length(2);
00108       medFile = SALOMEDS_Tool::GetNameFromPath( medFile ) + ".med";
00109       hdfFile = SALOMEDS_Tool::GetNameFromPath( hdfFile ) + ".hdf";
00110       aFiles[0] = medFile.c_str();
00111       aFiles[1] = hdfFile.c_str();
00112 
00113       SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.c_str(), aFiles.in(), true );
00114     }
00115   }
00116 
00117   //================================================================================
00121   //================================================================================
00122 
00123   void onExceptionCaught(const string& msg)
00124   {
00125     INFOS( msg );
00126     MYDEBUGOUT( msg );
00127   }
00128 
00129   //=============================================================================
00133   //=============================================================================
00134 
00135   class SignalToGUI
00136   {
00137     string              _messagePrefix;
00138     SALOME::Session_var _session;
00139   public:
00140     SignalToGUI( SMESH_Mesh_i* mesh )
00141     {
00142       SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
00143       SALOMEDS::Study_var study = gen->GetCurrentStudy();
00144       if ( !study->_is_nil() && study->StudyId() == mesh->GetStudyId() )
00145       {
00146         SALOMEDS::SObject_var meshSO = gen->ObjectToSObject(study, mesh->_this() );
00147         CORBA::Object_var obj = gen->GetNS()->Resolve( "/Kernel/Session" );
00148         _session = SALOME::Session::_narrow( obj );
00149         if ( !meshSO->_is_nil() && !_session->_is_nil() )
00150         {
00151           CORBA::String_var meshEntry = meshSO->GetID();
00152           _messagePrefix = "SMESH/mesh_loading/";
00153           _messagePrefix += meshEntry.in();
00154 
00155           string msgToGUI = _messagePrefix + "/";
00156           msgToGUI += SMESH_Comment( mesh->NbNodes() );
00157           msgToGUI += "/";
00158           msgToGUI += SMESH_Comment( mesh->NbElements() );
00159 
00160           _session->emitMessageOneWay( msgToGUI.c_str());
00161         }
00162       }
00163     }
00164     void sendStop()
00165     {
00166       if ( !_messagePrefix.empty() )
00167       {
00168         string msgToGUI = _messagePrefix + "/stop";
00169         _session->emitMessageOneWay( msgToGUI.c_str());
00170         _messagePrefix.clear();
00171       }
00172     }
00173     ~SignalToGUI() { sendStop(); }
00174   };
00175 
00176   //=============================================================================
00180   //=============================================================================
00181 
00182   class PositionCreator {
00183   public:
00184     SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) {
00185       return (this->*myFuncTable[ type ])();
00186     }
00187     PositionCreator() {
00188       myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition );
00189       myFuncTable[ TopAbs_SOLID  ] = & PositionCreator::volumePosition;
00190       myFuncTable[ TopAbs_FACE   ] = & PositionCreator::facePosition;
00191       myFuncTable[ TopAbs_EDGE   ] = & PositionCreator::edgePosition;
00192       myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition;
00193     }
00194   private:
00195     SMDS_PositionPtr edgePosition()    const { return SMDS_PositionPtr( new SMDS_EdgePosition  ); }
00196     SMDS_PositionPtr facePosition()    const { return SMDS_PositionPtr( new SMDS_FacePosition  ); }
00197     SMDS_PositionPtr volumePosition()  const { return SMDS_PositionPtr( new SMDS_SpacePosition ); }
00198     SMDS_PositionPtr vertexPosition()  const { return SMDS_PositionPtr( new SMDS_VertexPosition); }
00199     SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition();  }
00200     typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const;
00201     vector<FmakePos> myFuncTable;
00202   };
00203 
00204   //================================================================================
00208   //================================================================================
00209 
00210   vector<int> getSimpleSubMeshIds( SMESHDS_Mesh* meshDS, int shapeId )
00211   {
00212     vector<int> ids;
00213 
00214     list<TopoDS_Shape> shapeQueue( 1, meshDS->IndexToShape( shapeId ));
00215     list<TopoDS_Shape>::iterator shape = shapeQueue.begin();
00216     for ( ; shape != shapeQueue.end(); ++shape )
00217     {
00218       if ( shape->IsNull() ) continue;
00219       if ( shape->ShapeType() == TopAbs_COMPOUND ||
00220            shape->ShapeType() == TopAbs_COMPSOLID )
00221       {
00222         for ( TopoDS_Iterator it( *shape ); it.More(); it.Next() )
00223           shapeQueue.push_back( it.Value() );
00224       }
00225       else
00226       {
00227         ids.push_back( meshDS->ShapeToIndex( *shape ));
00228       }
00229     }
00230     return ids;
00231   }
00232 
00233   //================================================================================
00237   //================================================================================
00238 
00239   typedef map< MED::EGeometrieElement, SMDSAbs_EntityType > Tmed2smeshElemTypeMap;
00240   const Tmed2smeshElemTypeMap& med2smeshElemTypeMap()
00241   {
00242     static map< MED::EGeometrieElement, SMDSAbs_EntityType> med2smeshTypes;
00243     if ( med2smeshTypes.empty() )
00244     {
00245       med2smeshTypes[ MED::ePOINT1   ] = SMDSEntity_0D                ;
00246       med2smeshTypes[ MED::eSEG2     ] = SMDSEntity_Edge              ;
00247       med2smeshTypes[ MED::eSEG3     ] = SMDSEntity_Quad_Edge         ;
00248       med2smeshTypes[ MED::eTRIA3    ] = SMDSEntity_Triangle          ;
00249       med2smeshTypes[ MED::eTRIA6    ] = SMDSEntity_Quad_Triangle     ;
00250       med2smeshTypes[ MED::eQUAD4    ] = SMDSEntity_Quadrangle        ;
00251       med2smeshTypes[ MED::eQUAD8    ] = SMDSEntity_Quad_Quadrangle   ;
00252       med2smeshTypes[ MED::eQUAD9    ] = SMDSEntity_BiQuad_Quadrangle ;
00253       med2smeshTypes[ MED::eTETRA4   ] = SMDSEntity_Tetra             ;
00254       med2smeshTypes[ MED::ePYRA5    ] = SMDSEntity_Pyramid           ;
00255       med2smeshTypes[ MED::ePENTA6   ] = SMDSEntity_Penta             ;
00256       med2smeshTypes[ MED::eHEXA8    ] = SMDSEntity_Hexa              ;
00257       med2smeshTypes[ MED::eOCTA12   ] = SMDSEntity_Hexagonal_Prism   ;
00258       med2smeshTypes[ MED::eTETRA10  ] = SMDSEntity_Quad_Tetra        ;
00259       med2smeshTypes[ MED::ePYRA13   ] = SMDSEntity_Quad_Pyramid      ;
00260       med2smeshTypes[ MED::ePENTA15  ] = SMDSEntity_Quad_Penta        ;
00261       med2smeshTypes[ MED::eHEXA20   ] = SMDSEntity_Quad_Hexa         ;
00262       med2smeshTypes[ MED::eHEXA27   ] = SMDSEntity_TriQuad_Hexa      ;
00263       med2smeshTypes[ MED::ePOLYGONE ] = SMDSEntity_Polygon           ;
00264       med2smeshTypes[ MED::ePOLYEDRE ] = SMDSEntity_Polyhedra         ;
00265       med2smeshTypes[ MED::eNONE     ] = SMDSEntity_Node              ;
00266     }
00267     return med2smeshTypes;
00268   }
00269 
00270   //================================================================================
00275   //================================================================================
00276 
00277   const vector<MED::EGeometrieElement>& mesh2medElemType()
00278   {
00279     static vector<MED::EGeometrieElement> mesh2medElemTypes;
00280     if ( mesh2medElemTypes.empty() )
00281     {
00282       mesh2medElemTypes.resize( SMDSEntity_Last + 1 );
00283       Tmed2smeshElemTypeMap::const_iterator me2sme    = med2smeshElemTypeMap().begin();
00284       Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end();
00285       for ( ; me2sme != me2smeEnd; ++me2sme )
00286         mesh2medElemTypes[ me2sme->second ] = me2sme->first;
00287     }
00288     return mesh2medElemTypes;
00289   }
00290 
00291   //================================================================================
00295   //================================================================================
00296 
00297   void meshInfo2hdf( SMESH::long_array_var meshInfo,
00298                      const std::string&    name,
00299                      HDFgroup*             hdfGroup)
00300   {
00301     // we use med identification of element (MED::EGeometrieElement>) types
00302     // but not enum SMDSAbs_EntityType because values of SMDSAbs_EntityType may
00303     // change at insertion of new items in the middle.
00304     const vector<MED::EGeometrieElement>& medTypes = mesh2medElemType();
00305 
00306     vector<int> data;
00307 
00308     for ( size_t i = 0; i < meshInfo->length(); ++i )
00309       if ( meshInfo[i] > 0 )
00310       {
00311         data.push_back( medTypes[ i ] );
00312         data.push_back( meshInfo[ i ] );
00313       }
00314 
00315     if ( !data.empty() )
00316     {
00317       hdf_size datasetSize[] = { data.size() };
00318       HDFarray* anArray = new HDFarray(0, HDF_INT32, 1, datasetSize);
00319       anArray->CreateOnDisk();
00320       datasetSize[0] = 1;
00321       HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup, HDF_ARRAY, datasetSize, 1 );
00322       dataset->SetArrayId(anArray->GetId());
00323       dataset->CreateOnDisk();
00324       dataset->WriteOnDisk( & data[0]  );
00325       dataset->CloseOnDisk();
00326       anArray->CloseOnDisk();
00327     }
00328   }
00329 }
00330 
00331 //================================================================================
00335 //================================================================================
00336 
00337 void SMESH_PreMeshInfo::hdf2meshInfo( const std::string& name,
00338                                       HDFgroup*          hdfGroup)
00339 {
00340   if ( hdfGroup->ExistInternalObject( name.c_str()) )
00341   {
00342     HDFdataset* dataset = new HDFdataset( name.c_str(), hdfGroup );
00343     dataset->OpenOnDisk();
00344 
00345     // // hdf_size datasetSize[ 1 ];
00346     // // HDFarray *array = new HDFarray(dataset);
00347     // // array->GetDim( datasetSize );
00348     // int size = dataset->GetSize();
00349 
00350     vector<int> info( SMDSEntity_Last * 2, 0 );
00351     dataset->ReadFromDisk( &info[0] );
00352     dataset->CloseOnDisk();
00353 
00354     const Tmed2smeshElemTypeMap& med2smesh = med2smeshElemTypeMap();
00355     Tmed2smeshElemTypeMap::const_iterator me2sme, me2smeEnd = med2smesh.end();
00356     for ( size_t i = 0; i < info.size(); )
00357     {
00358       int medType = info[i++];
00359       int nbElems = info[i++];
00360       if ( !nbElems ) break;
00361       me2sme = med2smesh.find( (MED::EGeometrieElement) medType );
00362       if ( me2sme != me2smeEnd )
00363         setNb( me2sme->second, nbElems );
00364     }
00365   }
00366   _isInfoOk = true;
00367 
00368   if ( NbNodes() == GroupOnFilter_OutOfDate ) // case of !SMESHDS_GroupOnFilter::IsUpToDate()
00369   {
00370     _isInfoOk = false;
00371     setNb( SMDSEntity_Node, 0 );
00372   }
00373 }
00374 
00375 //================================================================================
00379 //================================================================================
00380 
00381 SMESH_PreMeshInfo::SMESH_PreMeshInfo(SMESH_Mesh_i*      mesh,
00382                                      const int          meshID,
00383                                      const std::string& medFile,
00384                                      const std::string& hdfFile)
00385   : _medFileName( medFile ),
00386     _hdfFileName( hdfFile ),
00387     _toRemoveFiles( false ),
00388     _meshID( meshID ),
00389     _mesh( mesh ),
00390     _isInfoOk( false ),
00391     _elemCounter( 0 )
00392 {
00393 }
00394 
00395 //================================================================================
00399 //================================================================================
00400 
00401 SMESH_PreMeshInfo::~SMESH_PreMeshInfo()
00402 {
00403   if ( _toRemoveFiles ) // it can be true only for SMESH_PreMeshInfo of the mesh
00404     filesNoMoreNeeded( _mesh, _medFileName, _hdfFileName );
00405 
00406   _toRemoveFiles = false;
00407 }
00408 
00409 //================================================================================
00413 //================================================================================
00414 
00415 void SMESH_PreMeshInfo::LoadFromFile( SMESH_Mesh_i*      mesh,
00416                                       const int          meshID,
00417                                       const std::string& medFile,
00418                                       const std::string& hdfFile,
00419                                       const bool         toRemoveFiles)
00420 {
00421   PreMeshInfo_TRY;
00422 
00423   SMESH_PreMeshInfo* meshPreInfo = new SMESH_PreMeshInfo( mesh,meshID,medFile,hdfFile );
00424   mesh->changePreMeshInfo() = meshPreInfo;
00425 
00426   meshPreInfo->_toRemoveFiles = toRemoveFiles;
00427   if ( toRemoveFiles )
00428     meshInfoLoaded( mesh );
00429 
00430   if ( meshPreInfo->readPreInfoFromHDF() )
00431     // all SMESH_PreMeshInfo's are stored in HDF file (written after
00432     // implementing SMESH_PreMeshInfo)
00433     return;
00434 
00435   // try to read SMESH_PreMeshInfo from med file (as study is older than SMESH_PreMeshInfo)
00436   if ( meshPreInfo->readMeshInfo() )
00437   {
00438     meshPreInfo->readGroupInfo();
00439     meshPreInfo->readSubMeshInfo();
00440   }
00441   else
00442   {
00443     meshPreInfo->FullLoadFromFile();
00444   }
00445   PreMeshInfo_CATCH;
00446 }
00447 
00448 //================================================================================
00455 //================================================================================
00456 
00457 bool SMESH_PreMeshInfo::readPreInfoFromHDF()
00458 {
00459   HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() );
00460   aFile->OpenOnDisk( HDF_RDONLY );
00461 
00462   SMESH_Comment hdfGroupName("SMESH_PreMeshInfo"); hdfGroupName << _meshID;
00463   const bool infoAvailable = aFile->ExistInternalObject( hdfGroupName );
00464   if ( infoAvailable )
00465   {
00466 
00467     HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, aFile );
00468     infoHdfGroup->OpenOnDisk();
00469 
00470     _mesh->changePreMeshInfo()->hdf2meshInfo( "Mesh", infoHdfGroup );
00471 
00472     // read SMESH_PreMeshInfo of groups
00473     map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin();
00474     for ( ; i2group != _mesh->_mapGroups.end(); ++i2group )
00475     {
00476       if ( SMESH_GroupBase_i* group_i =
00477            SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
00478       {
00479         group_i->changePreMeshInfo() = newInstance();
00480         if ( SMESHDS_GroupBase* group = group_i->GetGroupDS() )
00481         {
00482           const string name = group->GetStoreName();
00483           group_i->changePreMeshInfo()->hdf2meshInfo( name, infoHdfGroup );
00484         }
00485       }
00486     }
00487 
00488     // read SMESH_PreMeshInfo of sub-meshes
00489     map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
00490     for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
00491     {
00492       if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
00493       {
00494         sm->changePreMeshInfo() = newInstance();
00495         sm->changePreMeshInfo()->hdf2meshInfo( SMESH_Comment( sm->GetId()), infoHdfGroup );
00496       }
00497     }
00498   }
00499 
00500   aFile->CloseOnDisk();
00501   delete aFile;
00502 
00503   return infoAvailable;
00504 }
00505 
00506 //================================================================================
00510 //================================================================================
00511 
00512 bool SMESH_PreMeshInfo::readMeshInfo()
00513 {
00514   _isInfoOk = true;
00515 
00516   MED::PWrapper aMed = MED::CrWrapper(_medFileName,true);
00517   // if ( aMed->GetVersion() != MED::eV2_2 )
00518   //   return false;
00519 
00520   MED::PMeshInfo medMeshInfo = aMed->CrMeshInfo(3,3,SMESH_Comment( _meshID ));
00521 
00522   // read nb nodes
00523   int nbNodes = std::max( 0, aMed->GetNbNodes( medMeshInfo ));
00524   if ( nbNodes > 0 )
00525   {
00526     setNb( SMDSEntity_Node, nbNodes);
00527 
00528     // read nb of elements
00529     Tmed2smeshElemTypeMap::const_iterator me2sme    = med2smeshElemTypeMap().begin();
00530     Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end();
00531     for ( ; me2sme != me2smeEnd; ++me2sme )
00532     {
00533       int nbElems = aMed->GetNbCells( medMeshInfo, MED::eMAILLE, me2sme->first );
00534       if ( nbElems > 0 )
00535         setNb( me2sme->second, nbElems );
00536     }
00537   }
00538   return true;
00539 }
00540 
00541 //================================================================================
00545 //================================================================================
00546 
00547 void SMESH_PreMeshInfo::readGroupInfo()
00548 {
00549   if ( _mesh->_mapGroups.empty() ) return;
00550 
00551   // make SMESH_PreMeshInfo of groups
00552   map< string, SMESH_PreMeshInfo* > name2GroupInfo;
00553   map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin();
00554   for ( ; i2group != _mesh->_mapGroups.end(); ++i2group )
00555   {
00556     if ( SMESH_GroupBase_i* group_i =
00557          SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
00558     {
00559       SMESH_PreMeshInfo* info = newInstance();
00560       group_i->changePreMeshInfo() = info;
00561       if ( SMESHDS_Group* group = dynamic_cast< SMESHDS_Group* >( group_i->GetGroupDS() ))
00562       {
00563         string name = group->GetStoreName();
00564         name2GroupInfo.insert( make_pair( name, info ));
00565         info->_isInfoOk = true;
00566       }
00567     }
00568   }
00569 
00570   map< int, vector< SMESH_PreMeshInfo* > > famId2grInfo;
00571 
00572   MED::PWrapper aMed = MED::CrWrapper(_medFileName,false);
00573   MED::PMeshInfo medMeshInfo = aMed->CrMeshInfo(3,3,SMESH_Comment( _meshID ));
00574 
00575   // read families to fill in famId2grInfo
00576   int nbFams = aMed->GetNbFamilies( medMeshInfo );
00577   if ( nbFams <= 1 ) return; // zero family is always present
00578   for ( int iF = 0; iF <= nbFams; ++iF )
00579   {
00580     int nbGroups = aMed->GetNbFamGroup( iF, medMeshInfo );
00581     if ( nbGroups < 1 ) continue;
00582     MED::PFamilyInfo medFamInfo = aMed->CrFamilyInfo( medMeshInfo, nbGroups, nbGroups );
00583     aMed->GetFamilyInfo( iF, medFamInfo ); // read groups of a family
00584     vector< SMESH_PreMeshInfo* >& grInfoVec = famId2grInfo[ medFamInfo->GetId() ];
00585     for ( int iG = 0; iG < nbGroups; ++iG )
00586     {
00587       const string grName = medFamInfo->GetGroupName( iG );
00588       map< string, SMESH_PreMeshInfo* >::iterator n2i = name2GroupInfo.find( grName );
00589       if ( n2i != name2GroupInfo.end() )
00590         grInfoVec.push_back( n2i->second );
00591     }
00592   }
00593 
00594   // read family numbers of elements
00595   Tmed2smeshElemTypeMap::const_iterator me2sme    = med2smeshElemTypeMap().begin();
00596   Tmed2smeshElemTypeMap::const_iterator me2smeEnd = med2smeshElemTypeMap().end();
00597   MED::PElemInfo medElemInfo = aMed->CrElemInfo( medMeshInfo, 0 );
00598   MED::TIntVector& famNums = medElemInfo->myFamNum;
00599   for ( ; me2sme != me2smeEnd; ++me2sme ) // loop on elem types
00600   {
00601     famNums.resize( NbEntities( me2sme->second ));
00602     if ( famNums.empty() ) continue;
00603     aMed->GetFamilies( medElemInfo, famNums.size(), MED::eMAILLE, me2sme->first );
00604     // distribute elements of a type among groups
00605     map< int, vector< SMESH_PreMeshInfo* > >::iterator f2infos = famId2grInfo.begin();
00606     for ( size_t i = 0; i < famNums.size(); ++i )
00607     {
00608       if ( famNums[i] != f2infos->first )
00609       {
00610         f2infos = famId2grInfo.find( famNums[i] );
00611         if ( f2infos == famId2grInfo.end() )
00612           f2infos = famId2grInfo.insert
00613             ( make_pair( famNums[i], vector< SMESH_PreMeshInfo*>())).first;
00614       }
00615       vector< SMESH_PreMeshInfo* >& infoVec = f2infos->second ;
00616       for ( size_t j = 0; j < infoVec.size(); ++j )
00617         infoVec[j]->_elemCounter++;
00618     }
00619     // pass _elemCounter to a real elem type
00620     map< string, SMESH_PreMeshInfo* >::iterator n2i = name2GroupInfo.begin();
00621     for ( ; n2i != name2GroupInfo.end(); ++n2i )
00622     {
00623       SMESH_PreMeshInfo* info = n2i->second;
00624       info->setNb( me2sme->second, info->_elemCounter );
00625       info->_elemCounter = 0;
00626     }
00627   }
00628 }
00629 
00630 //================================================================================
00634 //================================================================================
00635 
00636 void SMESH_PreMeshInfo::readSubMeshInfo()
00637 {
00638   if ( _mesh->_mapSubMeshIor.empty() ) return;
00639 
00640   // create SMESH_PreMeshInfo of sub-meshes
00641   map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
00642   for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
00643   {
00644     if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
00645     {
00646       sm->changePreMeshInfo() = newInstance();
00647       sm->changePreMeshInfo()->_isInfoOk = true;
00648     }
00649   }
00650 
00651   // try to read 
00652   HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() );
00653   aFile->OpenOnDisk( HDF_RDONLY );
00654 
00655   char meshGrpName[ 30 ];
00656   sprintf( meshGrpName, "Mesh %d", _meshID );
00657   if ( aFile->ExistInternalObject( meshGrpName ) )
00658   {
00659     HDFgroup* aTopGroup = new HDFgroup( meshGrpName, aFile );
00660     aTopGroup->OpenOnDisk();
00661     if ( aTopGroup->ExistInternalObject( "Submeshes" ))
00662     {
00663       HDFgroup* aGroup = new HDFgroup( "Submeshes", aTopGroup );
00664       aGroup->OpenOnDisk();
00665 
00666       SMESHDS_Mesh* meshDS = _mesh->GetImpl().GetMeshDS();
00667       int maxSmId = Max( meshDS->MaxSubMeshIndex(), meshDS->MaxShapeIndex() );
00668 
00669       for ( int isNode = 0; isNode < 2; ++isNode )
00670       {
00671         string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
00672         if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
00673         {
00674           // read sub-mesh id of all nodes or elems
00675           HDFdataset* aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
00676           aDataset->OpenOnDisk();
00677           int nbElems = aDataset->GetSize();
00678           int* smIDs = new int [ nbElems ];
00679           aDataset->ReadFromDisk( smIDs );
00680           aDataset->CloseOnDisk();
00681           // count nb elems in each sub-mesh
00682           vector<int> nbBySubmeshId( maxSmId + 1, 0 );
00683           for ( int i = 0; i < nbElems; ++i )
00684           {
00685             const int smID = smIDs[ i ];
00686             if ( smID < (int) nbBySubmeshId.size() )
00687               nbBySubmeshId[ smID ]++;
00688           }
00689           delete [] smIDs;
00690 
00691           // store nb elems in SMESH_PreMeshInfo of sub-meshes
00692           map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
00693           for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
00694           {
00695             if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
00696             {
00697               SMESH_PreMeshInfo* & info = sm->changePreMeshInfo();
00698 
00699               vector<int> smIds = getSimpleSubMeshIds( meshDS, id2sm->first );
00700               for ( size_t i = 0; i < smIds.size(); ++i )
00701                 info->_elemCounter += nbBySubmeshId[ smIds[i] ];
00702 
00703               SMDSAbs_EntityType elemType;
00704               if ( isNode )
00705               {
00706                 elemType = SMDSEntity_Node;
00707               }
00708               else
00709               {
00710                 bool koElemType = false;
00711                 const TopoDS_Shape& shape = meshDS->IndexToShape( smIds[0] );
00712                 elemType = getElemType( shape.ShapeType(), info->_elemCounter, koElemType );
00713                 info->_isInfoOk = !koElemType;
00714               }
00715               info->setNb( elemType, info->_elemCounter );
00716             }
00717           }
00718         } // if ( aGroup->ExistInternalObject( aDSName ))
00719       } // for ( int isNode = 0; isNode < 2; ++isNode )
00720 
00721       aGroup->CloseOnDisk();
00722     } // if ( aTopGroup->ExistInternalObject( "Submeshes" ))
00723 
00724     aTopGroup->CloseOnDisk();
00725   } // if ( aFile->ExistInternalObject( meshGrpName ) )
00726 
00727   aFile->CloseOnDisk();
00728   delete aFile;
00729 }
00730 
00731 //================================================================================
00735 //================================================================================
00736 
00737 SMDSAbs_EntityType SMESH_PreMeshInfo::getElemType( const TopAbs_ShapeEnum shapeType,
00738                                                    const int              nbElemsInSubMesh,
00739                                                    bool&                  isKoType) const
00740 {
00741   isKoType = false;
00742   int type, typeEnd;
00743   SMESH_PreMeshInfo* meshInfo = _mesh->changePreMeshInfo();
00744 
00745   switch ( shapeType )
00746   {
00747   case TopAbs_SOLID:
00748     type = SMDSEntity_Tetra;
00749     typeEnd = SMDSEntity_Last;
00750     isKoType = ( meshInfo->NbVolumes() != nbElemsInSubMesh );
00751     break;
00752   case TopAbs_FACE:
00753   case TopAbs_SHELL:  
00754     type = SMDSEntity_Triangle;
00755     typeEnd = SMDSEntity_Tetra;
00756     isKoType = ( meshInfo->NbFaces() != nbElemsInSubMesh );
00757     break;
00758   case TopAbs_WIRE:
00759   case TopAbs_EDGE:   return SMDSEntity_Edge;
00760   case TopAbs_VERTEX: return SMDSEntity_0D;
00761   default:            return SMDSEntity_Last;
00762   }
00763 
00764   if ( !isKoType )
00765   {
00766     for ( int t = type; t < typeEnd; ++t )
00767       if ( nbElemsInSubMesh == meshInfo->NbEntities( SMDSAbs_EntityType( t )))
00768         return SMDSAbs_EntityType( t );
00769   }
00770   isKoType = true;
00771   return SMDSAbs_EntityType( type );
00772 }
00773 
00774 //================================================================================
00778 //================================================================================
00779 
00780 void SMESH_PreMeshInfo::SaveToFile( SMESH_Mesh_i* mesh,
00781                                     const int     meshID,
00782                                     HDFfile*      hdfFile)
00783 {
00784   // create a HDF group for SMESH_PreMeshInfo of this mesh
00785   SMESH_Comment hdfGroupName("SMESH_PreMeshInfo"); hdfGroupName << meshID;
00786   HDFgroup* infoHdfGroup = new HDFgroup( hdfGroupName, hdfFile );
00787   infoHdfGroup->CreateOnDisk();
00788 
00789   PreMeshInfo_TRY;
00790 
00791   // info of mesh
00792   meshInfo2hdf( mesh->GetMeshInfo(), "Mesh", infoHdfGroup );
00793   
00794   // info of groups
00795   SMESH_PreMeshInfo incompleteInfo( 0,0,"","");
00796   incompleteInfo.setNb( SMDSEntity_Node, GroupOnFilter_OutOfDate );
00797   SMESHDS_Mesh* meshDS = mesh->GetImpl().GetMeshDS();
00798 
00799   map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = mesh->_mapGroups.begin();
00800   for ( ; i2group != mesh->_mapGroups.end(); ++i2group )
00801   {
00802     if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
00803     {
00804       SMESHDS_GroupBase * group = group_i->GetGroupDS();
00805       if ( SMESHDS_GroupOnFilter* gof = dynamic_cast<SMESHDS_GroupOnFilter*>(group))
00806       {
00807         // prevent too long storage time due to applying filter to many elements
00808         if ( !gof->IsUpToDate() && meshDS->GetMeshInfo().NbElements( gof->GetType() ) > 1e5 )
00809         {
00810           meshInfo2hdf( incompleteInfo.GetMeshInfo(),
00811                         group->GetStoreName(),
00812                         infoHdfGroup);
00813           continue;
00814         }
00815       }
00816       meshInfo2hdf( group_i->GetMeshInfo(), group->GetStoreName(), infoHdfGroup);
00817     }
00818   }
00819 
00820   // info of sub-meshes
00821   map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = mesh->_mapSubMeshIor.begin();
00822   for ( ; id2sm != mesh->_mapSubMeshIor.end(); ++id2sm )
00823   {
00824     if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
00825     {
00826       meshInfo2hdf( sm->GetMeshInfo(),
00827                     SMESH_Comment( sm->GetId() ),
00828                     infoHdfGroup);
00829     }
00830   }
00831 
00832   PreMeshInfo_CATCH;
00833 
00834   infoHdfGroup->CloseOnDisk();
00835 }
00836 
00837 //================================================================================
00841 //================================================================================
00842 
00843 void SMESH_PreMeshInfo::FullLoadFromFile() const
00844 {
00845   SignalToGUI signalOnLoading( _mesh );
00846 
00847   SMESH_PreMeshInfo* meshInfo = _mesh->changePreMeshInfo();
00848   _mesh->changePreMeshInfo() = NULL; // to allow GUI accessing to real info
00849 
00850   ::SMESH_Mesh& mesh = _mesh->GetImpl();
00851   SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
00852 
00853   PreMeshInfo_TRY;
00854 
00855   MYDEBUGOUT( "BEG FullLoadFromFile() " << _meshID );
00856 
00857   // load mesh
00858   DriverMED_R_SMESHDS_Mesh myReader;
00859   myReader.SetFile( _medFileName.c_str() );
00860   myReader.SetMesh( meshDS );
00861   myReader.SetMeshId( _meshID );
00862   myReader.Perform();
00863 
00864   // load groups
00865   const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
00866   set<SMESHDS_GroupBase*>::const_iterator groupIt = groups.begin();
00867   for ( ; groupIt != groups.end(); ++groupIt )
00868     if ( SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( *groupIt ))
00869       myReader.GetGroup( aGrp );
00870 
00871   // load sub-meshes
00872   readSubMeshes( &myReader );
00873 
00874   PreMeshInfo_CATCH;
00875 
00876   _mesh->changePreMeshInfo() = meshInfo;
00877 
00878   ForgetAllData();
00879 
00880   signalOnLoading.sendStop();
00881 
00882   meshDS->Modified();
00883 
00884   // load dependent meshes referring/referred via hypotheses
00885   mesh.GetSubMesh( mesh.GetShapeToMesh() )->
00886     ComputeStateEngine (SMESH_subMesh::SUBMESH_LOADED);
00887 
00888   MYDEBUGOUT( "END FullLoadFromFile()" );
00889 }
00890 
00891 //================================================================================
00895 //================================================================================
00896 
00897 void SMESH_PreMeshInfo::readSubMeshes(DriverMED_R_SMESHDS_Mesh* reader) const
00898 {
00899   HDFfile* aFile = new HDFfile( (char*) _hdfFileName.c_str() );
00900   aFile->OpenOnDisk( HDF_RDONLY );
00901 
00902   char meshGrpName[ 30 ];
00903   sprintf( meshGrpName, "Mesh %d", _meshID );
00904   if ( aFile->ExistInternalObject( meshGrpName ) )
00905   {
00906     HDFgroup* aTopGroup = new HDFgroup( meshGrpName, aFile );
00907     aTopGroup->OpenOnDisk();
00908 
00909     SMESHDS_Mesh* meshDS = _mesh->GetImpl().GetMeshDS();
00910 
00911     bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" ));
00912     if ( submeshesInFamilies ) // from MED
00913     {
00914       // old way working before fix of PAL 12992
00915       reader->CreateAllSubMeshes();
00916     }
00917     else
00918     {
00919       // open a group
00920       HDFgroup* aGroup = new HDFgroup( "Submeshes", aTopGroup );
00921       aGroup->OpenOnDisk();
00922 
00923       int maxID = Max( meshDS->MaxSubMeshIndex(), meshDS->MaxShapeIndex() );
00924       vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 );
00925       vector< TopAbs_ShapeEnum  > smType   ( maxID + 1, TopAbs_SHAPE );
00926 
00927       PositionCreator aPositionCreator;
00928 
00929       SMDS_NodeIteratorPtr nIt = meshDS->nodesIterator();
00930       SMDS_ElemIteratorPtr eIt = meshDS->elementsIterator();
00931       for ( int isNode = 0; isNode < 2; ++isNode )
00932       {
00933         string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
00934         if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
00935         {
00936           HDFdataset* aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
00937           aDataset->OpenOnDisk();
00938           // read submesh IDs for all elements sorted by ID
00939           int nbElems = aDataset->GetSize();
00940           int* smIDs = new int [ nbElems ];
00941           aDataset->ReadFromDisk( smIDs );
00942           aDataset->CloseOnDisk();
00943 
00944           // get elements sorted by ID
00945           TIDSortedElemSet elemSet;
00946           if ( isNode )
00947             while ( nIt->more() ) elemSet.insert( elemSet.end(), nIt->next() );
00948           else
00949             while ( eIt->more() ) elemSet.insert( elemSet.end(), eIt->next() );
00950           //ASSERT( elemSet.size() == nbElems ); -- issue 20182
00951           // -- Most probably a bad study was saved when there were
00952           // not fixed bugs in SMDS_MeshInfo
00953           if ( elemSet.size() < nbElems ) {
00954 #ifdef _DEBUG_
00955             cout << "SMESH_Gen_i::Load(), warning: Node position data is invalid" << endl;
00956 #endif
00957             nbElems = elemSet.size();
00958           }
00959           // add elements to submeshes
00960           TIDSortedElemSet::iterator iE = elemSet.begin();
00961           for ( int i = 0; i < nbElems; ++i, ++iE )
00962           {
00963             int smID = smIDs[ i ];
00964             if ( smID == 0 ) continue;
00965             const SMDS_MeshElement* elem = *iE;
00966             if ( smID > maxID ) {
00967               // corresponding subshape no longer exists: maybe geom group has been edited
00968               if ( _mesh->GetImpl().HasShapeToMesh() )
00969                 meshDS->RemoveElement( elem );
00970               continue;
00971             }
00972             // get or create submesh
00973             SMESHDS_SubMesh* & sm = subMeshes[ smID ];
00974             if ( ! sm ) {
00975               sm = meshDS->NewSubMesh( smID );
00976               smType[ smID ] = meshDS->IndexToShape( smID ).ShapeType();
00977             }
00978             // add
00979             if ( isNode ) {
00980               SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
00981               SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
00982               node->SetPosition( pos );
00983               sm->AddNode( node );
00984             } else {
00985               sm->AddElement( elem );
00986             }
00987           }
00988           delete [] smIDs;
00989         }
00990       }
00991     } // end reading submeshes
00992 
00993     // Read node positions on sub-shapes (SMDS_Position)
00994 
00995     if ( aTopGroup->ExistInternalObject( "Node Positions" ))
00996     {
00997       // There are 5 datasets to read:
00998       // "Nodes on Edges" - ID of node on edge
00999       // "Edge positions" - U parameter on node on edge
01000       // "Nodes on Faces" - ID of node on face
01001       // "Face U positions" - U parameter of node on face
01002       // "Face V positions" - V parameter of node on face
01003       const char* aEid_DSName = "Nodes on Edges";
01004       const char* aEu_DSName  = "Edge positions";
01005       const char* aFu_DSName  = "Face U positions";
01006       //char* aFid_DSName = "Nodes on Faces";
01007       //char* aFv_DSName  = "Face V positions";
01008 
01009       // data to retrieve
01010       int nbEids = 0, nbFids = 0;
01011       int *aEids = 0, *aFids  = 0;
01012       double *aEpos = 0, *aFupos = 0, *aFvpos = 0;
01013 
01014       // open a group
01015       HDFgroup* aGroup = new HDFgroup( "Node Positions", aTopGroup );
01016       aGroup->OpenOnDisk();
01017 
01018       // loop on 5 data sets
01019       int aNbObjects = aGroup->nInternalObjects();
01020       for ( int i = 0; i < aNbObjects; i++ )
01021       {
01022         // identify dataset
01023         char aDSName[ HDF_NAME_MAX_LEN+1 ];
01024         aGroup->InternalObjectIndentify( i, aDSName );
01025         // read data
01026         HDFdataset* aDataset = new HDFdataset( aDSName, aGroup );
01027         aDataset->OpenOnDisk();
01028         if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions
01029         {
01030           double* pos = new double [ aDataset->GetSize() ];
01031           aDataset->ReadFromDisk( pos );
01032           // which one?
01033           if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 )
01034             aEpos = pos;
01035           else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 )
01036             aFupos = pos;
01037           else
01038             aFvpos = pos;
01039         }
01040         else // NODE IDS
01041         {
01042           int aSize = aDataset->GetSize();
01043 
01044           // for reading files, created from 18.07.2005 till 10.10.2005
01045           if (aDataset->GetType() == HDF_STRING)
01046             aSize /= sizeof(int);
01047 
01048           int* ids = new int [aSize];
01049           aDataset->ReadFromDisk( ids );
01050           // on face or nodes?
01051           if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) {
01052             aEids = ids;
01053             nbEids = aSize;
01054           }
01055           else {
01056             aFids = ids;
01057             nbFids = aSize;
01058           }
01059         }
01060         aDataset->CloseOnDisk();
01061       } // loop on 5 datasets
01062 
01063       // Set node positions on edges or faces
01064       for ( int onFace = 0; onFace < 2; onFace++ )
01065       {
01066         int nbNodes = ( onFace ? nbFids : nbEids );
01067         if ( nbNodes == 0 ) continue;
01068         int* aNodeIDs = ( onFace ? aFids : aEids );
01069         double* aUPos = ( onFace ? aFupos : aEpos );
01070         double* aVPos = ( onFace ? aFvpos : 0 );
01071         // loop on node IDs
01072         for ( int iNode = 0; iNode < nbNodes; iNode++ )
01073         {
01074           const SMDS_MeshNode* node = meshDS->FindNode( aNodeIDs[ iNode ]);
01075           if ( !node ) continue; // maybe removed while Loading() if geometry changed
01076           SMDS_PositionPtr aPos = node->GetPosition();
01077           ASSERT( aPos );
01078           if ( onFace ) {
01079             // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );-- issue 20182
01080             // -- Most probably a bad study was saved when there were
01081             // not fixed bugs in SMDS_MeshInfo
01082             if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
01083               SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
01084                 ( static_cast<const SMDS_FacePosition*>( aPos ));
01085               fPos->SetUParameter( aUPos[ iNode ]);
01086               fPos->SetVParameter( aVPos[ iNode ]);
01087             }
01088           }
01089           else {
01090             // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182
01091             if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) {
01092               SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
01093                 ( static_cast<const SMDS_EdgePosition*>( aPos ));
01094               fPos->SetUParameter( aUPos[ iNode ]);
01095             }
01096           }
01097         }
01098       }
01099       if ( aEids ) delete [] aEids;
01100       if ( aFids ) delete [] aFids;
01101       if ( aEpos ) delete [] aEpos;
01102       if ( aFupos ) delete [] aFupos;
01103       if ( aFvpos ) delete [] aFvpos;
01104 
01105       aGroup->CloseOnDisk();
01106 
01107     } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) )
01108 
01109     aTopGroup->CloseOnDisk();
01110   } // if ( aFile->ExistInternalObject( meshGrpName ) )
01111   
01112   aFile->CloseOnDisk();
01113   delete aFile;
01114 }
01115 
01116 //================================================================================
01120 //================================================================================
01121 
01122 void SMESH_PreMeshInfo::ForgetAllData() const
01123 {
01124   PreMeshInfo_TRY;
01125 
01126   if ( _mesh->changePreMeshInfo() != this )
01127     return _mesh->changePreMeshInfo()->ForgetAllData();
01128 
01129   // remove SMESH_PreMeshInfo from groups
01130   map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i2group = _mesh->_mapGroups.begin();
01131   for ( ; i2group != _mesh->_mapGroups.end(); ++i2group )
01132   {
01133     if ( SMESH_GroupBase_i* group_i =
01134          SMESH::DownCast<SMESH_GroupBase_i*>( i2group->second ))
01135     {
01136       SMESH_PreMeshInfo* & info = group_i->changePreMeshInfo();
01137       delete info;
01138       info = NULL;
01139     }
01140   }
01141   // remove SMESH_PreMeshInfo from sub-meshes
01142   map<int, SMESH::SMESH_subMesh_ptr>::iterator id2sm = _mesh->_mapSubMeshIor.begin();
01143   for ( ; id2sm != _mesh->_mapSubMeshIor.end(); ++id2sm )
01144   {
01145     if ( SMESH_subMesh_i* sm = SMESH::DownCast<SMESH_subMesh_i*>( id2sm->second ))
01146     {
01147       SMESH_PreMeshInfo* & info = sm->changePreMeshInfo();
01148       delete info;
01149       info = NULL;
01150     }
01151   }
01152   // remove SMESH_PreMeshInfo from the mesh
01153   _mesh->changePreMeshInfo() = NULL;
01154   delete this;
01155 
01156   PreMeshInfo_CATCH;
01157 
01158 
01159   // Finalize loading
01160 
01161   // PreMeshInfo_TRY;
01162 
01163   // ::SMESH_Mesh& mesh = _mesh->GetImpl();
01164 
01165   // // update hyps needing full mesh data restored (issue 20918)
01166   // // map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id2hyp= _mesh->_mapHypo.begin();
01167   // // for ( ; id2hyp != _mesh->_mapHypo.end(); ++id2hyp )
01168   // //   if ( SMESH_Hypothesis_i* hyp = SMESH::DownCast<SMESH_Hypothesis_i*>( id2hyp->second ))
01169   // //     hyp->UpdateAsMeshesRestored();
01170 
01171 
01172   // PreMeshInfo_CATCH;
01173 }
01174 
01175 //================================================================================
01179 //================================================================================
01180 
01181 void SMESH_PreMeshInfo::ForgetOrLoad() const
01182 {
01183   if ( SMESH_Gen_i::GetSMESHGen()->ToForgetMeshDataOnHypModif() &&
01184        _mesh->HasShapeToMesh())
01185     ForgetAllData();
01186   else
01187     FullLoadFromFile();
01188 }
01189 
01190 //================================================================================
01194 //================================================================================
01195 
01196 SMESH::array_of_ElementType* SMESH_PreMeshInfo::GetTypes() const
01197 {
01198   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
01199 
01200   types->length( 4 );
01201   int nbTypes = 0;
01202   if (NbEdges())
01203     types[nbTypes++] = SMESH::EDGE;
01204   if (NbFaces())
01205     types[nbTypes++] = SMESH::FACE;
01206   if (NbVolumes())
01207     types[nbTypes++] = SMESH::VOLUME;
01208   if (Nb0DElements())
01209     types[nbTypes++] = SMESH::ELEM0D;
01210   types->length( nbTypes );
01211 
01212   return types._retn();
01213 }
01214 
01215 //================================================================================
01219 //================================================================================
01220 
01221 SMESH::long_array* SMESH_PreMeshInfo::GetMeshInfo() const
01222 {
01223   SMESH::long_array_var aRes = new SMESH::long_array();
01224   aRes->length(SMESH::Entity_Last);
01225   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
01226     aRes[i] = 0;
01227 
01228   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
01229     aRes[i] = NbEntities((SMDSAbs_EntityType)i);
01230   return aRes._retn();
01231 }
01232 
01233 //================================================================================
01238 //================================================================================
01239 
01240 bool SMESH_PreMeshInfo::IsMeshInfoCorrect() const
01241 {
01242   return _isInfoOk;
01243 }
01244 
01245 //================================================================================
01250 //================================================================================
01251 
01252 void SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD(SALOMEDS::SComponent_ptr smeshComp)
01253 {
01254   SALOMEDS::Study_var study = smeshComp->GetStudy();
01255   if ( theStudyIDToMeshCounter[ (int) study->StudyId() ] > 0 )
01256   {
01257     SALOMEDS::ChildIterator_var itBig = study->NewChildIterator( smeshComp );
01258     for ( ; itBig->More(); itBig->Next() ) {
01259       SALOMEDS::SObject_var gotBranch = itBig->Value();
01260       CORBA::Object_var anObject = SMESH_Gen_i::SObjectToObject( gotBranch );
01261       if ( SMESH_Mesh_i* mesh = SMESH::DownCast<SMESH_Mesh_i*>( anObject ))
01262       {
01263         if ( mesh->changePreMeshInfo() )
01264         {
01265           mesh->changePreMeshInfo()->ForgetAllData();
01266         }
01267       }
01268     }
01269   }
01270 }