Salome HOME
Fix Python dump of ExportPartToMED()
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index d030cbc93b99224c73319515e8f2002945bab70a..8dc1b25b585e3bb0def9dcdef7cef4d507dc6adc 100644 (file)
 #include "DriverMED_W_Field.h"
 #include "DriverMED_W_SMESHDS_Mesh.h"
 #include "MED_Factory.hxx"
+#include "SMDS_LinearEdge.hxx"
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_ElemIterator.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_IteratorOnIterators.hxx"
 #include "SMDS_MeshGroup.hxx"
 #include "SMDS_SetIterator.hxx"
+#include "SMDS_StdIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_Command.hxx"
 #include "SMESHDS_CommandType.hxx"
@@ -156,7 +158,7 @@ SMESH_Mesh_i::~SMESH_Mesh_i()
   }
   _mapHypo.clear();
 
-  // clear cashed shapes if no more meshes remain; (the cash is blame,
+  // clear cached shapes if no more meshes remain; (the cache is blame,
   // together with publishing, of spent time increasing in issue 22874)
   if ( _impl->NbMeshes() == 1 )
     _gen_i->GetShapeReader()->ClearClientBuffer();
@@ -297,6 +299,9 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
   }
 
   TPythonDump() <<  SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
+
+  SMESH::SMESH_Mesh_var mesh = _this();
+  _gen_i->UpdateIcons( mesh );
 }
 
 //================================================================================
@@ -402,8 +407,8 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
   CreateGroupServants();
 
   int major, minor, release;
-  if( !MED::getMEDVersion( theFileName, major, minor, release ) )
-    major = minor = release = -1;
+  major = minor = release = 0;
+  MED::GetMEDVersion(theFileName, major, minor, release);
   _medFileInfo           = new SMESH::MedFileInfo();
   _medFileInfo->fileName = theFileName;
   _medFileInfo->fileSize = 0;
@@ -440,6 +445,13 @@ SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char*  theFileNa
 
   CreateGroupServants();
 
+  _medFileInfo           = new SMESH::MedFileInfo();
+  _medFileInfo->fileName = theFileName;
+  _medFileInfo->major    = 0;
+  _medFileInfo->minor    = 0;
+  _medFileInfo->release  = 0;
+  _medFileInfo->fileSize = SMESH_File( theFileName ).size();
+
   return ConvertDriverMEDReadStatus(status);
 }
 
@@ -449,9 +461,9 @@ SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char*  theFileNa
  */
 //================================================================================
 
-char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
+char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
 {
-  string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
+  string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
                                                           nbDigits);
   return CORBA::string_dup( ver.c_str() );
 }
@@ -474,6 +486,13 @@ int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
 
   CreateGroupServants();
 
+  _medFileInfo           = new SMESH::MedFileInfo();
+  _medFileInfo->fileName = theFileName;
+  _medFileInfo->major    = 0;
+  _medFileInfo->minor    = 0;
+  _medFileInfo->release  = 0;
+  _medFileInfo->fileSize = SMESH_File( theFileName ).size();
+
   SMESH_CATCH( SMESH::throwCorbaException );
 
   return 1;
@@ -498,6 +517,12 @@ int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
     SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
     _gen_i->SetName( meshSO, name.c_str() );
   }
+  _medFileInfo           = new SMESH::MedFileInfo();
+  _medFileInfo->fileName = theFileName;
+  _medFileInfo->major    = 0;
+  _medFileInfo->minor    = 0;
+  _medFileInfo->release  = 0;
+  _medFileInfo->fileSize = SMESH_File( theFileName ).size();
 
   SMESH_CATCH( SMESH::throwCorbaException );
 
@@ -536,6 +561,13 @@ SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
 
   error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
 
+  _medFileInfo           = new SMESH::MedFileInfo();
+  _medFileInfo->fileName = theFileName;
+  _medFileInfo->major    = 0;
+  _medFileInfo->minor    = 0;
+  _medFileInfo->release  = 0;
+  _medFileInfo->fileSize = SMESH_File( theFileName ).size();
+
   SMESH_CATCH( exceptionToComputeError );
 #undef SMESH_CAUGHT
 #define SMESH_CAUGHT
@@ -559,7 +591,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
   switch (theStatus) {
   RETURNCASE( HYP_OK            );
   RETURNCASE( HYP_MISSING       );
-  RETURNCASE( HYP_CONCURENT     );
+  RETURNCASE( HYP_CONCURRENT    );
   RETURNCASE( HYP_BAD_PARAMETER );
   RETURNCASE( HYP_HIDDEN_ALGO   );
   RETURNCASE( HYP_HIDING_ALGO   );
@@ -605,6 +637,7 @@ SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr       aSubShape,
   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
   {
     _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
+    _gen_i->UpdateIcons( mesh );
   }
   if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
 
@@ -690,6 +723,7 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS
   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
   {
     _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
+    _gen_i->UpdateIcons( mesh );
   }
   // Update Python script
   if(_impl->HasShapeToMesh())
@@ -1084,7 +1118,8 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
     return;
 
   vector<int> nodeIds; // to remove nodes becoming free
-  if ( !theGroup->IsEmpty() )
+  bool isNodal = ( theGroup->GetType() == SMESH::NODE );
+  if ( !isNodal && !theGroup->IsEmpty() )
   {
     CORBA::Long elemID = theGroup->GetID( 1 );
     int nbElemNodes = GetElemNbNodes( elemID );
@@ -1092,36 +1127,46 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
       nodeIds.reserve( theGroup->Size() * nbElemNodes );
   }
 
-  // Remove contents
+  // Retrieve contents
   SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
   SMDS_ElemIteratorPtr     elemIt = GetElements( idSrc, theGroup->GetType() );
-  while ( elemIt->more() )
-  {
-    const SMDS_MeshElement* e = elemIt->next();
+  SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
+  std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
+  elems.assign( elemBeg, elemEnd );
+
+  TPythonDump pyDump; // Suppress dump from RemoveGroup()
 
-    SMDS_ElemIteratorPtr nIt = e->nodesIterator();
-    while ( nIt->more() )
-      nodeIds.push_back( nIt->next()->GetID() );
+  // Remove group
+  RemoveGroup( theGroup );
+
+  // Remove contents
+  for ( size_t i = 0; i < elems.size(); ++i )
+  {
+    // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
+    //   continue;
+    if ( !isNodal )
+    {
+      for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
+        nodeIds.push_back( nIt->next()->GetID() );
 
-    _impl->GetMeshDS()->RemoveElement( e );
+      _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
+    }
+    else
+    {
+      _impl->GetMeshDS()->RemoveElement( elems[i] );
+    }
   }
 
   // Remove free nodes
-  if ( theGroup->GetType() != SMESH::NODE )
-    for ( size_t i = 0 ; i < nodeIds.size(); ++i )
-      if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
-        if ( n->NbInverseElements() == 0 )
-          _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
-
-  TPythonDump pyDump; // Suppress dump from RemoveGroup()
+  for ( size_t i = 0 ; i < nodeIds.size(); ++i )
+    if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
+      if ( n->NbInverseElements() == 0 )
+        _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
 
   // Update Python script (theGroup must be alive for this)
   pyDump << SMESH::SMESH_Mesh_var(_this())
          << ".RemoveGroupWithContents( " << theGroup << " )";
 
-  // Remove group
-  RemoveGroup( theGroup );
-
   SMESH_CATCH( SMESH::throwCorbaException );
 }
 
@@ -2085,7 +2130,7 @@ void SMESH_Mesh_i::CheckGeomModif()
 /*!
  * \brief Update objects depending on changed geom groups
  *
- * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
+ * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
  * issue 0020210: Update of a smesh group after modification of the associated geom group
  */
 //=============================================================================
@@ -2525,7 +2570,7 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType
                                                       const SMESH_PredicatePtr& thePredicate )
 {
   std::string newName;
-  if ( !theName || strlen( theName ) == 0 )
+  if ( !theName || !theName[0] )
   {
     std::set< std::string > presentNames;
     std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
@@ -2705,6 +2750,9 @@ void SMESH_Mesh_i::onHypothesisModified()
 {
   if ( _preMeshInfo )
     _preMeshInfo->ForgetOrLoad();
+
+  SMESH::SMESH_Mesh_var mesh = _this();
+  _gen_i->UpdateIcons( mesh );
 }
 
 //=============================================================================
@@ -2973,59 +3021,36 @@ string SMESH_Mesh_i::prepareMeshNameAndGroups(const char*    file,
 
 //================================================================================
 /*!
- * \brief Export to med file
+ * \brief Export to MED file
  */
 //================================================================================
 
-void SMESH_Mesh_i::ExportToMEDX (const char*        file,
-                                 CORBA::Boolean     auto_groups,
-                                 SMESH::MED_VERSION theVersion,
-                                 CORBA::Boolean     overwrite,
-                                 CORBA::Boolean     autoDimension)
+void SMESH_Mesh_i::ExportMED(const char*        file,
+                             CORBA::Boolean     auto_groups,
+                             CORBA::Long        minor,
+                             CORBA::Boolean     overwrite,
+                             CORBA::Boolean     autoDimension)
   throw(SALOME::SALOME_Exception)
 {
+  //MESSAGE("MED minor version: "<< minor);
   SMESH_TRY;
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
   string aMeshName = prepareMeshNameAndGroups(file, overwrite);
-  _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
+  _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor, 0, autoDimension );
 
-  TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
-                << file << "', " << auto_groups << ", "
-                << theVersion << ", " << overwrite << ", "
-                << autoDimension << " )";
+  TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
+                << file << "', "
+                << "auto_groups=" <<auto_groups << ", "
+                << "minor=" << minor <<  ", "
+                << "overwrite=" << overwrite << ", "
+                << "meshPart=None, "
+                << "autoDimension=" << autoDimension << " )";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 }
 
-//================================================================================
-/*!
- * \brief Export a mesh to a med file
- */
-//================================================================================
-
-void SMESH_Mesh_i::ExportToMED (const char*        file,
-                                CORBA::Boolean     auto_groups,
-                                SMESH::MED_VERSION theVersion)
-  throw(SALOME::SALOME_Exception)
-{
-  ExportToMEDX(file,auto_groups,theVersion,true);
-}
-
-//================================================================================
-/*!
- * \brief Export a mesh to a med file
- */
-//================================================================================
-
-void SMESH_Mesh_i::ExportMED (const char* file,
-                              CORBA::Boolean auto_groups)
-  throw(SALOME::SALOME_Exception)
-{
-  ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
-}
-
 //================================================================================
 /*!
  * \brief Export a mesh to a SAUV file
@@ -3131,13 +3156,14 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
                                    const char*               file,
                                    CORBA::Boolean            auto_groups,
-                                   SMESH::MED_VERSION        version,
+                                   CORBA::Long               minor,
                                    CORBA::Boolean            overwrite,
                                    CORBA::Boolean            autoDimension,
                                    const GEOM::ListOfFields& fields,
                                    const char*               geomAssocFields)
   throw (SALOME::SALOME_Exception)
 {
+  //MESSAGE("MED minor version: "<< minor);
   SMESH_TRY;
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
@@ -3184,8 +3210,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
        SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
   {
     aMeshName = prepareMeshNameAndGroups(file, overwrite);
-    _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
-                      version, 0, autoDimension, /*addODOnVertices=*/have0dField);
+    _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
+                      0, autoDimension, /*addODOnVertices=*/have0dField);
     meshDS = _impl->GetMeshDS();
   }
   else
@@ -3202,8 +3228,8 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
     }
 
     SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
-    _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
-                      version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
+    _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
+                      partDS, autoDimension, /*addODOnVertices=*/have0dField);
     meshDS = tmpDSDeleter._obj = partDS;
   }
 
@@ -3228,10 +3254,14 @@ void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
     goList[i] = gbo;
   }
   TPythonDump() << _this() << ".ExportPartToMED( "
-                << meshPart << ", r'" << file << "', "
-                << auto_groups << ", " << version << ", " << overwrite << ", "
-                << autoDimension << ", " << goList
-                << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
+                << meshPart << ", r'"
+                << file << "', "
+                << auto_groups << ", "
+                << minor << ", "
+                << overwrite << ", "
+                << autoDimension << ", "
+                << goList << ", '"
+                << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 }
@@ -3586,7 +3616,8 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
 
 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
                               const char*                 file,
-                              CORBA::Boolean              overwrite)
+                              CORBA::Boolean              overwrite,
+                              CORBA::Boolean              groupElemsByType)
   throw (SALOME::SALOME_Exception)
 {
 #ifdef WITH_CGNS
@@ -3603,8 +3634,12 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
     CORBA::String_var name = so->GetName();
     meshName = name.in();
   }
+  SMESH_TRY;
+
   SMESH_MeshPartDS partDS( meshPart );
-  _impl->ExportCGNS(file, &partDS, meshName.c_str() );
+  _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 
   TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
                 << meshPart<< ", r'" << file << "', " << overwrite << ")";
@@ -4048,14 +4083,14 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId()
     _preMeshInfo->FullLoadFromFile();
 
   SMESH::long_array_var aResult = new SMESH::long_array();
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
 
-  if ( aSMESHDS_Mesh == NULL )
+  if ( aMeshDS == NULL )
     return aResult._retn();
 
   long nbNodes = NbNodes();
   aResult->length( nbNodes );
-  SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
+  SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
   for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
     aResult[i] = anIt->next()->GetID();
 
@@ -4275,12 +4310,12 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
     _preMeshInfo->FullLoadFromFile();
 
   SMESH::double_array_var aResult = new SMESH::double_array();
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL )
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL )
     return aResult._retn();
 
   // find node
-  const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
+  const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
   if(!aNode)
     return aResult._retn();
 
@@ -4306,12 +4341,12 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
     _preMeshInfo->FullLoadFromFile();
 
   SMESH::long_array_var aResult = new SMESH::long_array();
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL )
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL )
     return aResult._retn();
 
   // find node
-  const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
+  const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
   if(!aNode)
     return aResult._retn();
 
@@ -4353,17 +4388,16 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
       case SMDS_TOP_EDGE:
         aNodePosition->shapeType = GEOM::EDGE;
         aNodePosition->params.length(1);
-        aNodePosition->params[0] =
-          static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
+        aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
         break;
-      case SMDS_TOP_FACE:
+      case SMDS_TOP_FACE: {
+        SMDS_FacePositionPtr fPos = pos;
         aNodePosition->shapeType = GEOM::FACE;
         aNodePosition->params.length(2);
-        aNodePosition->params[0] =
-          static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
-        aNodePosition->params[1] =
-          static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
+        aNodePosition->params[0] = fPos->GetUParameter();
+        aNodePosition->params[1] = fPos->GetVParameter();
         break;
+      }
       case SMDS_TOP_VERTEX:
         aNodePosition->shapeType = GEOM::VERTEX;
         break;
@@ -4438,12 +4472,12 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL )
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL )
     return -1;
 
   // try to find node
-  const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
+  const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
   if(aNode) {
     return aNode->getshapeId();
   }
@@ -4465,12 +4499,12 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL )
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL )
     return -1;
 
   // try to find element
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem)
     return -1;
 
@@ -4495,10 +4529,10 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return -1;
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return -1;
   // try to find element
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem) return -1;
   return elem->NbNodes();
 }
@@ -4517,9 +4551,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long in
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return -1;
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return -1;
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem) return -1;
   if( index>=elem->NbNodes() || index<0 ) return -1;
   return elem->GetNode(index)->GetID();
@@ -4537,9 +4571,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
     _preMeshInfo->FullLoadFromFile();
 
   SMESH::long_array_var aResult = new SMESH::long_array();
-  if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
+  if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
   {
-    if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
+    if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
     {
       aResult->length( elem->NbNodes() );
       for ( int i = 0; i < elem->NbNodes(); ++i )
@@ -4561,13 +4595,13 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Lo
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return false;
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return false;
   // try to find node
-  const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
+  const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
   if(!aNode) return false;
   // try to find element
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
   if(!elem) return false;
 
   return elem->IsMediumNode(aNode);
@@ -4587,11 +4621,11 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return false;
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return false;
 
   // try to find node
-  const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
+  const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
   if(!aNode) return false;
 
   SMESH_MesherHelper aHelper( *(_impl) );
@@ -4617,9 +4651,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return -1;
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return -1;
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem) return -1;
   return elem->NbEdges();
 }
@@ -4636,9 +4670,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return -1;
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return -1;
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem) return -1;
   return elem->NbFaces();
 }
@@ -4655,9 +4689,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
     _preMeshInfo->FullLoadFromFile();
 
   SMESH::long_array_var aResult = new SMESH::long_array();
-  if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
+  if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
   {
-    if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
+    if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
     {
       SMDS_VolumeTool vtool( elem );
       if ( faceIndex < vtool.NbFaces() )
@@ -4768,9 +4802,9 @@ CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return false;
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return false;
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem) return false;
   return elem->IsPoly();
 }
@@ -4787,9 +4821,9 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
   if ( _preMeshInfo )
     _preMeshInfo->FullLoadFromFile();
 
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL ) return false;
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL ) return false;
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem) return false;
   return elem->IsQuadratic();
 }
@@ -4806,7 +4840,7 @@ CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
     _preMeshInfo->FullLoadFromFile();
 
   if ( const SMDS_BallElement* ball =
-       dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
+       SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
     return ball->GetDiameter();
 
   return 0;
@@ -4824,11 +4858,11 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
     _preMeshInfo->FullLoadFromFile();
 
   SMESH::double_array_var aResult = new SMESH::double_array();
-  SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-  if ( aSMESHDS_Mesh == NULL )
+  SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
+  if ( aMeshDS == NULL )
     return aResult._retn();
 
-  const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
+  const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
   if(!elem)
     return aResult._retn();
 
@@ -4888,12 +4922,14 @@ SMESH_Mesh_i::MakeGroupsOfBadInputElements( int         theSubShapeID,
   {
     // compute error
     SMESH_ComputeErrorPtr error = sm->GetComputeError();
-    if ( error && !error->myBadElements.empty())
+    if ( error && error->HasBadElems() )
     {
       // sort bad elements by type
       vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
-      list<const SMDS_MeshElement*>::iterator elemIt  = error->myBadElements.begin();
-      list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
+      const list<const SMDS_MeshElement*>& badElems =
+        static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
+      list<const SMDS_MeshElement*>::const_iterator elemIt  = badElems.begin();
+      list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
       for ( ; elemIt != elemEnd; ++elemIt )
       {
         const SMDS_MeshElement* elem = *elemIt;
@@ -5013,6 +5049,17 @@ void SMESH_Mesh_i::CreateGroupServants()
   }
 }
 
+//=============================================================================
+/*!
+ * \brief Return true if all sub-meshes are computed OK - to update an icon
+ */
+//=============================================================================
+
+bool SMESH_Mesh_i::IsComputedOK()
+{
+  return _impl->IsComputedOK();
+}
+
 //=============================================================================
 /*!
  * \brief Return groups cantained in _mapGroups by their IDs
@@ -5053,6 +5100,48 @@ SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
   return res._retn();
 }
 
+//=======================================================================
+//function : FileInfoToString
+//purpose  : Persistence of file info
+//=======================================================================
+
+std::string SMESH_Mesh_i::FileInfoToString()
+{
+  std::string s;
+  if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
+  {
+    s = SMESH_Comment( _medFileInfo->fileSize )
+      << " " << _medFileInfo->major
+      << " " << _medFileInfo->minor
+      << " " << _medFileInfo->release
+      << " " << _medFileInfo->fileName;
+  }
+  return s;
+}
+
+//=======================================================================
+//function : FileInfoFromString
+//purpose  : Persistence of file info
+//=======================================================================
+
+void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
+{
+  std::string size, major, minor, release, fileName;
+  std::istringstream is(info);
+  is >> size >> major >> minor >> release;
+  fileName = info.data() + ( size.size()   + 1 +
+                             major.size()  + 1 +
+                             minor.size()  + 1 +
+                             release.size()+ 1 );
+
+  _medFileInfo           = new SMESH::MedFileInfo();
+  _medFileInfo->fileName = fileName.c_str();
+  _medFileInfo->fileSize = atoi( size.c_str() );
+  _medFileInfo->major    = atoi( major.c_str() );
+  _medFileInfo->minor    = atoi( minor.c_str() );
+  _medFileInfo->release  = atoi( release.c_str() );
+}
+
 //=============================================================================
 /*!
  * \brief Pass names of mesh groups from study to mesh DS
@@ -5251,7 +5340,7 @@ SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
 {
   SALOMEDS::TMPFile_var SeqFile;
   if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
-    SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
+    SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
     if(aGrid) {
       vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
       aWriter->WriteToOutputStringOn();
@@ -5388,7 +5477,7 @@ namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_v
     {
       const SMDS_MeshElement* res = _node;
       _node = 0;
-      while (( _elemIter->more() || _nodeIter->more() ) && !_node )
+      while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
       {
         if ( _nodeIter->more() )
         {
@@ -5526,17 +5615,17 @@ TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
 
 //-----------------------------------------------------------------------------
 /*!
- * \brief Internal structure used to find concurent submeshes
+ * \brief Internal structure used to find concurrent submeshes
  *
- * It represents a pair < submesh, concurent dimension >, where
- * 'concurrent dimension' is dimension of shape where the submesh can concurent
+ * It represents a pair < submesh, concurrent dimension >, where
+ * 'concurrent dimension' is dimension of shape where the submesh can concurrent
  *  with another submesh. In other words, it is dimension of a hypothesis assigned
  *  to submesh.
  */
 class SMESH_DimHyp
 {
  public:
-  //! fileds
+  //! fields
   int _dim;    //!< a dimension the algo can build (concurrent dimension)
   int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
   TopTools_MapOfShape _shapeMap;
@@ -5921,7 +6010,7 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
     
     removeDimHyps(dimHypListArr);
     
-    // now, minimise the number of concurrent groups
+    // now, minimize the number of concurrent groups
     // Here we assume that lists of submeshes can have same submesh
     // in case of multi-dimension algorithms, as result
     //  list with common submesh has to be united into one list
@@ -5990,6 +6079,9 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
   mesh.SetMeshOrder( subMeshOrder );
   res = true;
   
+  SMESH::SMESH_Mesh_var me = _this();
+  _gen_i->UpdateIcons( me );
+
   return res;
 }
 
@@ -6018,7 +6110,7 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt&     theIdsOrder,
       continue;
     if ( theIsDump )
       aPythonDump << "[ ";
-    // convert shape indeces into interfaces
+    // convert shape indices into interfaces
     SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
     aResSubSet->length(aSubOrder.size());
     TListOfInt::const_iterator subIt = aSubOrder.begin();
@@ -6050,6 +6142,24 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt&     theIdsOrder,
   }
 }
 
+namespace // utils used by SMESH_MeshPartDS
+{
+  /*!
+   * \brief Class used to access to protected data of SMDS_MeshInfo
+   */
+  struct TMeshInfo : public SMDS_MeshInfo
+  {
+    void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
+  };
+  /*!
+   * \brief Element holing its ID only
+   */
+  struct TElemID : public SMDS_LinearEdge
+  {
+    TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
+  };
+}
+
 //================================================================================
 //
 // Implementation of SMESH_MeshPartDS
@@ -6060,6 +6170,7 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
   SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
   SMESH_Mesh_i*       mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
 
+  mesh_i->Load();
   _meshDS = mesh_i->GetImpl().GetMeshDS();
 
   SetPersistentId( _meshDS->GetPersistentId() );
@@ -6129,6 +6240,21 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > &
   myInfo = tmpInfo;
 }
 // -------------------------------------------------------------------------------------
+const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
+{
+  if ( _meshDS ) return _meshDS->FindElement( IDelem );
+
+  TElemID elem( IDelem );
+  for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
+    if ( !_elements[ iType ].empty() )
+    {
+      TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
+      if ( it != _elements[ iType ].end() )
+        return *it;
+    }
+  return 0;
+}
+// -------------------------------------------------------------------------------------
 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
 {
   if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
@@ -6140,7 +6266,7 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType
     SMDS_MeshElement::GeomFilter
     > TIter;
 
-  SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
+  SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
 
   return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
                                           _elements[type].end(),
@@ -6158,7 +6284,7 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType
     SMDS_MeshElement::EntityFilter
     > TIter;
 
-  SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
+  SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
 
   return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
                                           _elements[type].end(),
@@ -6185,10 +6311,10 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type
 }
 // -------------------------------------------------------------------------------------
 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType)                       \
-  iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const                 \
+  iterType SMESH_MeshPartDS::methName() const                 \
   {                                                                                 \
     typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
-    return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType                 \
+    return _meshDS ? _meshDS->methName() : iterType                 \
       ( new TIter( _elements[elemType].begin(), _elements[elemType].end() ));       \
   }
 // -------------------------------------------------------------------------------------