Salome HOME
Copyright update 2022
[modules/smesh.git] / src / SMESH / SMESH_Mesh.cxx
index 893a28aba659e6f8fbfb93475a251acddc4c0b97..c819ce0977fd9f9dbd2d84577bd5bc146479e314 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -80,8 +80,6 @@
 #include <pthread.h>
 #endif
 
-using namespace std;
-
 // maximum stored group name length in MED file
 #define MAX_MED_GROUP_NAME_LENGTH 80
 
@@ -105,8 +103,7 @@ class SMESH_Mesh::SubMeshHolder : public SMESHDS_TSubMeshHolder< SMESH_subMesh >
  */
 //=============================================================================
 
-SMESH_Mesh::SMESH_Mesh(int               theLocalId, 
-                       int               theStudyId, 
+SMESH_Mesh::SMESH_Mesh(int               theLocalId,
                        SMESH_Gen*        theGen,
                        bool              theIsEmbeddedMode,
                        SMESHDS_Document* theDocument):
@@ -114,17 +111,34 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
   _id            = theLocalId;
-  _studyId       = theStudyId;
   _gen           = theGen;
-  _myDocument    = theDocument;
-  _myMeshDS      = theDocument->NewMesh(theIsEmbeddedMode,theLocalId);
+  _document    = theDocument;
+  _meshDS      = theDocument->NewMesh(theIsEmbeddedMode,theLocalId);
   _isShapeToMesh = false;
   _isAutoColor   = false;
   _isModified    = false;
   _shapeDiagonal = 0.0;
   _callUp        = NULL;
-  _myMeshDS->ShapeToMesh( PseudoShape() );
+  _meshDS->ShapeToMesh( PseudoShape() );
   _subMeshHolder = new SubMeshHolder;
+
+  // assure unique persistent ID
+  if ( _document->NbMeshes() > 1 )
+  {
+    std::set< int > ids;
+    for ( _document->InitMeshesIterator(); _document->MoreMesh(); )
+    {
+      SMESHDS_Mesh * meshDS =_document->NextMesh();
+      if ( meshDS != _meshDS )
+        ids.insert( meshDS->GetPersistentId() );
+    }
+
+    if ( ids.count( _meshDS->GetPersistentId() ))
+    {
+      int uniqueID = *ids.rbegin() + 1;
+      _meshDS->SetPersistentId( uniqueID );
+    }
+  }
 }
 
 //================================================================================
@@ -135,12 +149,11 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
 
 SMESH_Mesh::SMESH_Mesh():
   _id(-1),
-  _studyId(-1),
   _groupId( 0 ),
   _nbSubShapes( 0 ),
   _isShapeToMesh( false ),
-  _myDocument( 0 ),
-  _myMeshDS( 0 ),
+  _document( 0 ),
+  _meshDS( 0 ),
   _gen( 0 ),
   _isAutoColor( false ),
   _isModified( false ),
@@ -181,10 +194,18 @@ SMESH_Mesh::~SMESH_Mesh()
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::~SMESH_Mesh");
 
-  // avoid usual removal of elements while processing RemoveHypothesis( algo ) event
-  SMESHDS_SubMeshIteratorPtr smIt = _myMeshDS->SubMeshes();
-  while ( smIt->more() )
-    const_cast<SMESHDS_SubMesh*>( smIt->next() )->Clear();
+  if ( _document ) // avoid destructing _meshDS from ~SMESH_Gen()
+    _document->RemoveMesh( _id );
+  _document = 0;
+
+  // remove self from studyContext
+  if ( _gen )
+  {
+    StudyContextStruct * studyContext = _gen->GetStudyContext();
+    studyContext->mapMesh.erase( _id );
+  }
+
+  _meshDS->ClearMesh();
 
   // issue 0020340: EDF 1022 SMESH : Crash with FindNodeClosestTo in a second new study
   //   Notify event listeners at least that something happens
@@ -192,7 +213,7 @@ SMESH_Mesh::~SMESH_Mesh()
     sm->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED );
 
   // delete groups
-  map < int, SMESH_Group * >::iterator itg;
+  std::map < int, SMESH_Group * >::iterator itg;
   for (itg = _mapGroup.begin(); itg != _mapGroup.end(); itg++) {
     SMESH_Group *aGroup = (*itg).second;
     delete aGroup;
@@ -205,23 +226,13 @@ SMESH_Mesh::~SMESH_Mesh()
   if ( _callUp) delete _callUp;
   _callUp = 0;
 
-  // remove self from studyContext
-  if ( _gen )
-  {
-    StudyContextStruct * studyContext = _gen->GetStudyContext( _studyId );
-    studyContext->mapMesh.erase( _id );
-  }
-  if ( _myDocument )
-    _myDocument->RemoveMesh( _id );
-  _myDocument = 0;
-
-  if ( _myMeshDS ) {
-    // delete _myMeshDS, in a thread in order not to block closing a study with large meshes
+  if ( _meshDS ) {
+    // delete _meshDS, in a thread in order not to block closing a study with large meshes
 #ifndef WIN32
-    boost::thread aThread(boost::bind( & deleteMeshDS, _myMeshDS ));
+    boost::thread aThread(boost::bind( & deleteMeshDS, _meshDS ));
 #else
     pthread_t thread;
-    int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_myMeshDS);
+    int result=pthread_create(&thread, NULL, deleteMeshDS, (void*)_meshDS);
 #endif
   }
 }
@@ -234,7 +245,7 @@ SMESH_Mesh::~SMESH_Mesh()
 
 bool SMESH_Mesh::MeshExists( int meshId ) const
 {
-  return _myDocument ? bool( _myDocument->GetMesh( meshId )) : false;
+  return _document ? bool( _document->GetMesh( meshId )) : false;
 }
 
 //================================================================================
@@ -248,7 +259,7 @@ SMESH_Mesh* SMESH_Mesh::FindMesh( int meshId ) const
   if ( _id == meshId )
     return (SMESH_Mesh*) this;
 
-  if ( StudyContextStruct *aStudyContext = _gen->GetStudyContext( _studyId ))
+  if ( StudyContextStruct *aStudyContext = _gen->GetStudyContext())
   {
     std::map < int, SMESH_Mesh * >::iterator i_m = aStudyContext->mapMesh.find( meshId );
     if ( i_m != aStudyContext->mapMesh.end() )
@@ -269,20 +280,20 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 
   if ( !aShape.IsNull() && _isShapeToMesh ) {
     if ( aShape.ShapeType() != TopAbs_COMPOUND && // group contents is allowed to change
-         _myMeshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND )
+         _meshDS->ShapeToMesh().ShapeType() != TopAbs_COMPOUND )
       throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
   }
   // clear current data
-  if ( !_myMeshDS->ShapeToMesh().IsNull() )
+  if ( !_meshDS->ShapeToMesh().IsNull() )
   {
     // removal of a shape to mesh, delete objects referring to sub-shapes:
     // - sub-meshes
     _subMeshHolder->DeleteAll();
     //  - groups on geometry
-    map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
+    std::map <int, SMESH_Group *>::iterator i_gr = _mapGroup.begin();
     while ( i_gr != _mapGroup.end() ) {
       if ( dynamic_cast<SMESHDS_GroupOnGeom*>( i_gr->second->GetGroupDS() )) {
-        _myMeshDS->RemoveGroup( i_gr->second->GetGroupDS() );
+        _meshDS->RemoveGroup( i_gr->second->GetGroupDS() );
         delete i_gr->second;
         _mapGroup.erase( i_gr++ );
       }
@@ -293,7 +304,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 
     // clear SMESHDS
     TopoDS_Shape aNullShape;
-    _myMeshDS->ShapeToMesh( aNullShape );
+    _meshDS->ShapeToMesh( aNullShape );
 
     _shapeDiagonal = 0.0;
   }
@@ -301,9 +312,9 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
   // set a new geometry
   if ( !aShape.IsNull() )
   {
-    _myMeshDS->ShapeToMesh(aShape);
+    _meshDS->ShapeToMesh(aShape);
     _isShapeToMesh = true;
-    _nbSubShapes = _myMeshDS->MaxShapeIndex();
+    _nbSubShapes = _meshDS->MaxShapeIndex();
 
     // fill map of ancestors
     fillAncestorsMap(aShape);
@@ -312,7 +323,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
   {
     _isShapeToMesh = false;
     _shapeDiagonal = 0.0;
-    _myMeshDS->ShapeToMesh( PseudoShape() );
+    _meshDS->ShapeToMesh( PseudoShape() );
   }
   _isModified = false;
 }
@@ -325,7 +336,7 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 
 TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
 {
-  return _myMeshDS->ShapeToMesh();
+  return _meshDS->ShapeToMesh();
 }
 
 //=======================================================================
@@ -364,6 +375,7 @@ double SMESH_Mesh::GetShapeDiagonalSize(const TopoDS_Shape & aShape)
     bool isPrecise = false;
     if ( nbFaces < maxNbFaces )
       try {
+        OCC_CATCH_SIGNALS;
         GEOMUtils::PreciseBoundingBox( aShape, Box );
         isPrecise = true;
       }
@@ -417,7 +429,7 @@ void SMESH_Mesh::Clear()
   if ( HasShapeToMesh() ) // remove all nodes and elements
   {
     // clear mesh data
-    _myMeshDS->ClearMesh();
+    _meshDS->ClearMesh();
 
     // update compute state of submeshes
     if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
@@ -450,7 +462,7 @@ void SMESH_Mesh::Clear()
 
 void SMESH_Mesh::ClearSubMesh(const int theShapeId)
 {
-  // clear sub-meshes; get ready to re-compute as a side-effect 
+  // clear sub-meshes; get ready to re-compute as a side-effect
   if ( SMESH_subMesh *sm = GetSubMeshContaining( theShapeId ) )
   {
     SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
@@ -458,7 +470,7 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId)
     while ( smIt->more() )
     {
       sm = smIt->next();
-      TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();      
+      TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
       if ( shapeType == TopAbs_VERTEX || shapeType < TopAbs_SOLID )
         // all other shapes depends on vertices so they are already cleaned
         sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
@@ -470,7 +482,7 @@ void SMESH_Mesh::ClearSubMesh(const int theShapeId)
 
 //=======================================================================
 //function : UNVToMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMESH_Mesh::UNVToMesh(const char* theFileName)
@@ -480,37 +492,24 @@ int SMESH_Mesh::UNVToMesh(const char* theFileName)
   _isShapeToMesh = false;
 
   DriverUNV_R_SMDS_Mesh myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(-1);
   myReader.Perform();
 
-  if ( SMDS_MeshGroup* aGroup = (SMDS_MeshGroup*) myReader.GetGroup() )
+  TGroupNamesMap& aGroupNames = myReader.GetGroupNamesMap();
+  TGroupNamesMap::iterator gr2names;
+  int anId = 1 + ( _mapGroup.empty() ? 0 : _mapGroup.rbegin()->first );
+  for ( gr2names = aGroupNames.begin(); gr2names != aGroupNames.end(); ++gr2names )
   {
-    TGroupNamesMap aGroupNames = myReader.GetGroupNamesMap();
-    aGroup->InitSubGroupsIterator();
-    while (aGroup->MoreSubGroups())
-    {
-      SMDS_MeshGroup* aSubGroup = (SMDS_MeshGroup*) aGroup->NextSubGroup();
-      string aName = aGroupNames[aSubGroup];
-      int aId;
-      if ( SMESH_Group* aSMESHGroup = AddGroup( aSubGroup->GetType(), aName.c_str(), aId ))
-      {
-        SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aSMESHGroup->GetGroupDS() );
-        if ( aGroupDS ) {
-          aGroupDS->SetStoreName(aName.c_str());
-          aSubGroup->InitIterator();
-          const SMDS_MeshElement* aElement = 0;
-          while ( aSubGroup->More() )
-            if (( aElement = aSubGroup->Next() ))
-              aGroupDS->SMDSGroup().Add( aElement );
-
-          if (aElement)
-            aGroupDS->SetType( aElement->GetType() );
-        }
-      }
-    }
+    SMDS_MeshGroup*   aGroup = gr2names->first;
+    const std::string& aName = gr2names->second;
+    SMESHDS_Group* aGroupDS = new SMESHDS_Group( anId++, _meshDS, aGroup->GetType() );
+    aGroupDS->SMDSGroup() = std::move( *aGroup );
+    aGroupDS->SetStoreName( aName.c_str() );
+    AddGroup( aGroupDS );
   }
+
   return 1;
 }
 
@@ -526,23 +525,22 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
   _isShapeToMesh = false;
 
   DriverMED_R_SMESHDS_Mesh myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetMeshId(-1);
   myReader.SetFile(theFileName);
   myReader.SetMeshName(theMeshName);
   Driver_Mesh::Status status = myReader.Perform();
 #ifdef _DEBUG_
   SMESH_ComputeErrorPtr er = myReader.GetError();
-  if ( er && !er->IsOK() ) cout << er->myComment << endl;
+  if ( er && !er->IsOK() ) std::cout << er->myComment << std::endl;
 #endif
 
   // Reading groups (sub-meshes are out of scope of MED import functionality)
-  list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
-  int anId;
-  list<TNameAndType>::iterator name_type = aGroupNames.begin();
+  std::list<TNameAndType> aGroupNames = myReader.GetGroupNamesAndTypes();
+  std::list<TNameAndType>::iterator name_type = aGroupNames.begin();
   for ( ; name_type != aGroupNames.end(); name_type++ )
   {
-    SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str(), anId );
+    SMESH_Group* aGroup = AddGroup( name_type->second, name_type->first.c_str() );
     if ( aGroup ) {
       SMESHDS_Group* aGroupDS = dynamic_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
       if ( aGroupDS ) {
@@ -551,12 +549,16 @@ int SMESH_Mesh::MEDToMesh(const char* theFileName, const char* theMeshName)
       }
     }
   }
+
+  _meshDS->Modified();
+  _meshDS->CompactMesh();
+
   return (int) status;
 }
 
 //=======================================================================
 //function : STLToMesh
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 std::string SMESH_Mesh::STLToMesh(const char* theFileName)
@@ -566,7 +568,7 @@ std::string SMESH_Mesh::STLToMesh(const char* theFileName)
   _isShapeToMesh = false;
 
   DriverSTL_R_SMDS_Mesh myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(-1);
   myReader.Perform();
@@ -590,7 +592,7 @@ int SMESH_Mesh::CGNSToMesh(const char*  theFileName,
 #ifdef WITH_CGNS
 
   DriverCGNS_Read myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMeshId(theMeshIndex);
   res = myReader.Perform();
@@ -613,7 +615,7 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName,
                                             bool        theMakeRequiredGroups)
 {
   DriverGMF_Read myReader;
-  myReader.SetMesh(_myMeshDS);
+  myReader.SetMesh(_meshDS);
   myReader.SetFile(theFileName);
   myReader.SetMakeRequiredGroups( theMakeRequiredGroups );
   myReader.Perform();
@@ -634,9 +636,8 @@ SMESH_ComputeErrorPtr SMESH_Mesh::GMFToMesh(const char* theFileName,
 SMESH_Hypothesis::Hypothesis_Status
 SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
                           int                  anHypId,
-                          std::string*         anError  ) throw(SALOME_Exception)
+                          std::string*         anError  )
 {
-  Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::AddHypothesis");
 
   if ( anError )
@@ -658,10 +659,10 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
     // NOTE: this is not a correct way to check a name of hypothesis,
     // there should be an attribute of hypothesis saying that it can/can't
     // be global/local
-    string hypName = anHyp->GetName();
+    std::string hypName = anHyp->GetName();
     if ( hypName == "NotConformAllowed" )
     {
-      if(MYDEBUG) MESSAGE( "Hypotesis <NotConformAllowed> can be only global" );
+      if(MYDEBUG) MESSAGE( "Hypothesis <NotConformAllowed> can be only global" );
       return SMESH_Hypothesis::HYP_INCOMPATIBLE;
     }
   }
@@ -697,14 +698,14 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
       }
     }
 
-    // check concurent hypotheses on ancestors
-    if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
+    // check concurrent hypotheses on ancestors
+    if (ret < SMESH_Hypothesis::HYP_CONCURRENT && !isGlobalHyp )
     {
       SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
       while ( smIt->more() ) {
         SMESH_subMesh* sm = smIt->next();
-        if ( sm->IsApplicableHypotesis( anHyp )) {
-          ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
+        if ( sm->IsApplicableHypothesis( anHyp )) {
+          ret2 = sm->CheckConcurrentHypothesis( anHyp->GetType() );
           if (ret2 > ret) {
             ret = ret2;
             break;
@@ -729,12 +730,11 @@ SMESH_Mesh::AddHypothesis(const TopoDS_Shape & aSubShape,
 
 SMESH_Hypothesis::Hypothesis_Status
 SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
-                             int                    anHypId) throw( SALOME_Exception )
+                             int                    anHypId)
 {
-  Unexpect aCatch(SalomeException);
   if(MYDEBUG) MESSAGE("SMESH_Mesh::RemoveHypothesis");
 
-  StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
+  StudyContextStruct *sc = _gen->GetStudyContext();
   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
     throw SALOME_Exception(LOCALIZED("hypothesis does not exist"));
 
@@ -751,10 +751,10 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
 
   // there may appear concurrent hyps that were covered by the removed hyp
-  if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
-      subMesh->IsApplicableHypotesis( anHyp ) &&
-      subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
-    ret = SMESH_Hypothesis::HYP_CONCURENT;
+  if (ret < SMESH_Hypothesis::HYP_CONCURRENT &&
+      subMesh->IsApplicableHypothesis( anHyp ) &&
+      subMesh->CheckConcurrentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
+    ret = SMESH_Hypothesis::HYP_CONCURRENT;
 
   // sub-shapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
@@ -767,14 +767,14 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
     if (ret2 > ret) // more severe
       ret = ret2;
 
-    // check concurent hypotheses on ancestors
-    if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
+    // check concurrent hypotheses on ancestors
+    if (ret < SMESH_Hypothesis::HYP_CONCURRENT && !IsMainShape( aSubShape ) )
     {
       SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
       while ( smIt->more() ) {
         SMESH_subMesh* sm = smIt->next();
-        if ( sm->IsApplicableHypotesis( anHyp )) {
-          ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
+        if ( sm->IsApplicableHypothesis( anHyp )) {
+          ret2 = sm->CheckConcurrentHypothesis( anHyp->GetType() );
           if (ret2 > ret) {
             ret = ret2;
             break;
@@ -798,11 +798,10 @@ SMESH_Mesh::RemoveHypothesis(const TopoDS_Shape & aSubShape,
  */
 //=============================================================================
 
-const list<const SMESHDS_Hypothesis*>&
+const std::list<const SMESHDS_Hypothesis*>&
 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
-  throw(SALOME_Exception)
 {
-  return _myMeshDS->GetHypothesis(aSubShape);
+  return _meshDS->GetHypothesis(aSubShape);
 }
 
 //=======================================================================
@@ -845,8 +844,8 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh *   aSubM
 
   {
     const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
-    const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
-    list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
+    const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(aSubShape);
+    std::list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
     for ( ; hyp != hypList.end(); hyp++ ) {
       const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
       if ( aFilter.IsOk( h, aSubShape)) {
@@ -862,12 +861,12 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh *   aSubM
       const_cast< std::vector< SMESH_subMesh * > & > ( aSubMesh->GetAncestors() );
     SortByMeshOrder( ancestors );
 
-    vector<SMESH_subMesh*>::const_iterator smIt = ancestors.begin(); 
+    std::vector<SMESH_subMesh*>::const_iterator smIt = ancestors.begin(); 
     for ( ; smIt != ancestors.end(); smIt++ )
     {
       const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
-      const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
-      list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
+      const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(curSh);
+      std::list<const SMESHDS_Hypothesis*>::const_iterator hyp = hypList.begin();
       for ( ; hyp != hypList.end(); hyp++ ) {
         const SMESH_Hypothesis * h = cSMESH_Hyp( *hyp );
         if (aFilter.IsOk( h, curSh )) {
@@ -891,11 +890,11 @@ const SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const SMESH_subMesh *   aSubM
  */
 //================================================================================
 
-int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
-                              const SMESH_HypoFilter&             aFilter,
-                              list <const SMESHDS_Hypothesis * >& aHypList,
-                              const bool                          andAncestors,
-                              list< TopoDS_Shape > *              assignedTo/*=0*/) const
+int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                     aSubShape,
+                              const SMESH_HypoFilter&                  aFilter,
+                              std::list <const SMESHDS_Hypothesis * >& aHypList,
+                              const bool                               andAncestors,
+                              std::list< TopoDS_Shape > *              assignedTo/*=0*/) const
 {
   return GetHypotheses( const_cast< SMESH_Mesh* >(this)->GetSubMesh( aSubShape ),
                         aFilter, aHypList, andAncestors, assignedTo );
@@ -912,22 +911,22 @@ int SMESH_Mesh::GetHypotheses(const TopoDS_Shape &                aSubShape,
  */
 //================================================================================
 
-int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *               aSubMesh,
-                              const SMESH_HypoFilter&             aFilter,
-                              list <const SMESHDS_Hypothesis * >& aHypList,
-                              const bool                          andAncestors,
-                              list< TopoDS_Shape > *              assignedTo/*=0*/) const
+int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *                    aSubMesh,
+                              const SMESH_HypoFilter&                  aFilter,
+                              std::list <const SMESHDS_Hypothesis * >& aHypList,
+                              const bool                               andAncestors,
+                              std::list< TopoDS_Shape > *              assignedTo/*=0*/) const
 {
   if ( !aSubMesh ) return 0;
 
-  set<string> hypTypes; // to exclude same type hypos from the result list
+  std::set< std::string > hypTypes; // to exclude same type hypos from the result list
   int nbHyps = 0;
 
   // only one main hypothesis is allowed
   bool mainHypFound = false;
 
   // fill in hypTypes
-  list<const SMESHDS_Hypothesis*>::const_iterator hyp;
+  std::list<const SMESHDS_Hypothesis*>::const_iterator hyp;
   for ( hyp = aHypList.begin(); hyp != aHypList.end(); hyp++ ) {
     if ( hypTypes.insert( (*hyp)->GetName() ).second )
       nbHyps++;
@@ -938,7 +937,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *               aSubMesh,
   // get hypos from aSubShape
   {
     const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
-    const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(aSubShape);
+    const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(aSubShape);
     for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
     {
       const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
@@ -963,11 +962,11 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *               aSubMesh,
       const_cast< std::vector< SMESH_subMesh * > & > ( aSubMesh->GetAncestors() );
     SortByMeshOrder( ancestors );
 
-    vector<SMESH_subMesh*>::const_iterator smIt = ancestors.begin();
+    std::vector<SMESH_subMesh*>::const_iterator smIt = ancestors.begin();
     for ( ; smIt != ancestors.end(); smIt++ )
     {
       const TopoDS_Shape& curSh = (*smIt)->GetSubShape();
-      const list<const SMESHDS_Hypothesis*>& hypList = _myMeshDS->GetHypothesis(curSh);
+      const std::list<const SMESHDS_Hypothesis*>& hypList = _meshDS->GetHypothesis(curSh);
       for ( hyp = hypList.begin(); hyp != hypList.end(); hyp++ )
       {
         const SMESH_Hypothesis* h = cSMESH_Hyp( *hyp );
@@ -995,7 +994,7 @@ int SMESH_Mesh::GetHypotheses(const SMESH_subMesh *               aSubMesh,
 
 SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
 {
-  StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
+  StudyContextStruct *sc = _gen->GetStudyContext();
   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
     return NULL;
 
@@ -1009,10 +1008,9 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
  */
 //=============================================================================
 
-const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
+const std::list<SMESHDS_Command*> & SMESH_Mesh::GetLog()
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetScript()->GetCommands();
+  return _meshDS->GetScript()->GetCommands();
 }
 
 //=============================================================================
@@ -1020,10 +1018,9 @@ const list<SMESHDS_Command*> & SMESH_Mesh::GetLog() throw(SALOME_Exception)
  * 
  */
 //=============================================================================
-void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
+void SMESH_Mesh::ClearLog()
 {
-  Unexpect aCatch(SalomeException);
-  _myMeshDS->GetScript()->Clear();
+  _meshDS->GetScript()->Clear();
 }
 
 //=============================================================================
@@ -1033,9 +1030,8 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
 //=============================================================================
 
 SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
-  throw(SALOME_Exception)
 {
-  int index = _myMeshDS->ShapeToIndex(aSubShape);
+  int index = _meshDS->ShapeToIndex(aSubShape);
   if ( !index && aSubShape.IsNull() )
     return 0;
 
@@ -1045,10 +1041,10 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
     TopoDS_Iterator it( aSubShape );
     if ( it.More() )
     {
-      index = _myMeshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
+      index = _meshDS->AddCompoundSubmesh( aSubShape, it.Value().ShapeType() );
       // fill map of Ancestors
       while ( _nbSubShapes < index )
-        fillAncestorsMap( _myMeshDS->IndexToShape( ++_nbSubShapes ));
+        fillAncestorsMap( _meshDS->IndexToShape( ++_nbSubShapes ));
     }
   }
   // if ( !index )
@@ -1057,7 +1053,7 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
   SMESH_subMesh* aSubMesh = _subMeshHolder->Get( index );
   if ( !aSubMesh )
   {
-    aSubMesh = new SMESH_subMesh(index, this, _myMeshDS, aSubShape);
+    aSubMesh = new SMESH_subMesh(index, this, _meshDS, aSubShape);
     _subMeshHolder->Add( index, aSubMesh );
 
     // include non-computable sub-meshes in SMESH_subMesh::_ancestors of sub-submeshes
@@ -1086,9 +1082,8 @@ SMESH_subMesh * SMESH_Mesh::GetSubMesh(const TopoDS_Shape & aSubShape)
 //=============================================================================
 
 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape) const
-  throw(SALOME_Exception)
 {
-  int index = _myMeshDS->ShapeToIndex(aSubShape);
+  int index = _meshDS->ShapeToIndex(aSubShape);
   return GetSubMeshContaining( index );
 }
 
@@ -1100,10 +1095,8 @@ SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const TopoDS_Shape & aSubShape)
 //=============================================================================
 
 SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID) const
-throw(SALOME_Exception)
 {
   SMESH_subMesh *aSubMesh = _subMeshHolder->Get( aShapeID );
-
   return aSubMesh;
 }
 
@@ -1113,11 +1106,10 @@ throw(SALOME_Exception)
  */
 //================================================================================
 
-list<SMESH_subMesh*>
+std::list<SMESH_subMesh*>
 SMESH_Mesh::GetGroupSubMeshesContaining(const TopoDS_Shape & aSubShape) const
-  throw(SALOME_Exception)
 {
-  list<SMESH_subMesh*> found;
+  std::list<SMESH_subMesh*> found;
 
   SMESH_subMesh * subMesh = GetSubMeshContaining(aSubShape);
   if ( !subMesh )
@@ -1169,7 +1161,7 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
   SMESH_Hypothesis* hyp = static_cast<SMESH_Hypothesis*>(anHyp);
 
   // check if anHyp can be used to mesh aSubMesh
-  if ( !aSubMesh || !aSubMesh->IsApplicableHypotesis( hyp ))
+  if ( !aSubMesh || !aSubMesh->IsApplicableHypothesis( hyp ))
     return false;
 
   SMESH_Algo *algo = aSubMesh->GetAlgo();
@@ -1181,10 +1173,10 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
   // algorithm parameter
   if (algo)
   {
-    // look trough hypotheses used by algo
+    // look through hypotheses used by algo
     const SMESH_HypoFilter* hypoKind;
     if (( hypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() ))) {
-      list <const SMESHDS_Hypothesis * > usedHyps;
+      std::list <const SMESHDS_Hypothesis * > usedHyps;
       if ( GetHypotheses( aSubMesh, *hypoKind, usedHyps, true ))
         return ( find( usedHyps.begin(), usedHyps.end(), anHyp ) != usedHyps.end() );
     }
@@ -1200,18 +1192,21 @@ bool SMESH_Mesh::IsUsedHypothesis(SMESHDS_Hypothesis * anHyp,
 
 void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
 {
-  Unexpect aCatch(SalomeException);
 
   if ( !GetMeshDS()->IsUsedHypothesis( hyp ))
     return;
 
-  if (_callUp)
-    _callUp->HypothesisModified();
+  smIdType nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() );
+  if ( hyp && _callUp && !_callUp->IsLoaded() ) // for not loaded mesh (#16648)
+  {
+    _callUp->HypothesisModified( hyp->GetID(), /*updateIcons=*/true );
+    nbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() ); // after loading mesh
+  }
 
   SMESH_Algo *algo;
   const SMESH_HypoFilter* compatibleHypoKind;
-  list <const SMESHDS_Hypothesis * > usedHyps;
-  vector< SMESH_subMesh* > smToNotify;
+  std::list <const SMESHDS_Hypothesis * > usedHyps;
+  std::vector< SMESH_subMesh* > smToNotify;
   bool allMeshedEdgesNotified = true;
 
   SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
@@ -1232,7 +1227,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
     {
       const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape();
 
-      if (( aSubMesh->IsApplicableHypotesis( hyp )) &&
+      if (( aSubMesh->IsApplicableHypothesis( hyp )) &&
           ( algo = aSubMesh->GetAlgo() )            &&
           ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) &&
           ( compatibleHypoKind->IsOk( hyp, aSubShape )))
@@ -1274,6 +1269,10 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
   }
   HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty
   GetMeshDS()->Modified();
+
+  smIdType newNbEntities = ( _meshDS->NbNodes() + _meshDS->NbElements() );
+  if ( hyp && _callUp )
+    _callUp->HypothesisModified( hyp->GetID(), newNbEntities != nbEntities );
 }
 
 //=============================================================================
@@ -1281,15 +1280,13 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h
  *  Auto color functionality
  */
 //=============================================================================
-void SMESH_Mesh::SetAutoColor(bool theAutoColor) throw(SALOME_Exception)
+void SMESH_Mesh::SetAutoColor(bool theAutoColor)
 {
-  Unexpect aCatch(SalomeException);
   _isAutoColor = theAutoColor;
 }
 
-bool SMESH_Mesh::GetAutoColor() throw(SALOME_Exception)
+bool SMESH_Mesh::GetAutoColor()
 {
-  Unexpect aCatch(SalomeException);
   return _isAutoColor;
 }
 
@@ -1348,6 +1345,41 @@ bool SMESH_Mesh::HasModificationsToDiscard() const
   return false;
 }
 
+//=============================================================================
+/*!
+ * \brief Return true if all sub-meshes are computed OK - to update an icon
+ */
+//=============================================================================
+
+bool SMESH_Mesh::IsComputedOK()
+{
+  if ( NbNodes() == 0 )
+    return false;
+
+  // if ( !HasShapeToMesh() )
+  //   return true;
+
+  if ( SMESH_subMesh* mainSM = GetSubMeshContaining( 1 ))
+  {
+    SMESH_subMeshIteratorPtr smIt = mainSM->getDependsOnIterator(/*includeSelf=*/true);
+    while ( smIt->more() )
+    {
+      const SMESH_subMesh* sm = smIt->next();
+      if ( !sm->IsAlwaysComputed() )
+        switch ( sm->GetComputeState() )
+        {
+        case SMESH_subMesh::NOT_READY:
+        case SMESH_subMesh::COMPUTE_OK:
+          continue; // ok
+        case SMESH_subMesh::FAILED_TO_COMPUTE:
+        case SMESH_subMesh::READY_TO_COMPUTE:
+          return false;
+        }
+    }
+  }
+  return true;
+}
+
 //================================================================================
 /*!
  * \brief Check if any groups of the same type have equal names
@@ -1357,12 +1389,12 @@ bool SMESH_Mesh::HasModificationsToDiscard() const
 bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
 {
   // Corrected for Mantis issue 0020028
-  map< SMDSAbs_ElementType, set<string> > aGroupNames;
-  for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
+  std::map< SMDSAbs_ElementType, std::set< std::string > > aGroupNames;
+  for ( std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
   {
     SMESH_Group*       aGroup = it->second;
     SMDSAbs_ElementType aType = aGroup->GetGroupDS()->GetType();
-    string         aGroupName = aGroup->GetName();
+    std::string    aGroupName = aGroup->GetName();
     aGroupName.resize( MAX_MED_GROUP_NAME_LENGTH );
     if ( !aGroupNames[aType].insert(aGroupName).second )
       return true;
@@ -1373,135 +1405,140 @@ bool SMESH_Mesh::HasDuplicatedGroupNamesMED()
 
 //================================================================================
 /*!
- * \brief Export the mesh to a med file
- *  \param [in] file - name of the MED file
- *  \param [in] theMeshName - name of this mesh
- *  \param [in] theAutoGroups - boolean parameter for creating/not creating
- *              the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
- *              the typical use is auto_groups=false.
- *  \param [in] theVersion - defines the version of format of MED file, that will be created
- *  \param [in] meshPart - mesh data to export
- *  \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either
-     *         - 1D if all mesh nodes lie on OX coordinate axis, or
-     *         - 2D if all mesh nodes lie on XOY coordinate plane, or
-     *         - 3D in the rest cases.
-     *         If \a theAutoDimension is \c false, the space dimension is always 3.
- *  \param [in] theAddODOnVertices - to create 0D elements on all vertices
- *  \param [in] theAllElemsToGroup - to make every element to belong to any group (PAL23413)
- *  \return int - mesh index in the file
+ * \brief Export the mesh to a writer
  */
 //================================================================================
 
-void SMESH_Mesh::ExportMED(const char *        file, 
-                           const char*         theMeshName, 
-                           bool                theAutoGroups,
-                           int                 theVersion,
-                           const SMESHDS_Mesh* meshPart,
-                           bool                theAutoDimension,
-                           bool                theAddODOnVertices,
-                           bool                theAllElemsToGroup)
-  throw(SALOME_Exception)
+void SMESH_Mesh::exportMEDCommmon(DriverMED_W_SMESHDS_Mesh& theWriter,
+                                  const char*               theMeshName,
+                                  bool                      theAutoGroups,
+                                  const SMESHDS_Mesh*       theMeshPart,
+                                  bool                      theAutoDimension,
+                                  bool                      theAddODOnVertices,
+                                  double                    theZTolerance,
+                                  bool                      theSaveNumbers)
 {
+  Driver_Mesh::Status status = Driver_Mesh::DRS_OK;
+
   SMESH_TRY;
 
-  DriverMED_W_SMESHDS_Mesh myWriter;
-  myWriter.SetFile         ( file, MED::EVersion(theVersion) );
-  myWriter.SetMesh         ( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS   );
-  myWriter.SetAutoDimension( theAutoDimension );
-  myWriter.AddODOnVertices ( theAddODOnVertices );
-  if ( !theMeshName ) 
-    myWriter.SetMeshId     ( _id         );
+  theWriter.SetMesh         ( theMeshPart ? (SMESHDS_Mesh*) theMeshPart : _meshDS   );
+  theWriter.SetAutoDimension( theAutoDimension );
+  theWriter.AddODOnVertices ( theAddODOnVertices );
+  theWriter.SetZTolerance   ( theZTolerance );
+  theWriter.SetSaveNumbers  ( theSaveNumbers );
+  if ( !theMeshName )
+    theWriter.SetMeshId     ( _id         );
   else {
-    myWriter.SetMeshId     ( -1          );
-    myWriter.SetMeshName   ( theMeshName );
+    theWriter.SetMeshId     ( -1          );
+    theWriter.SetMeshName   ( theMeshName );
   }
 
   if ( theAutoGroups ) {
-    myWriter.AddGroupOfNodes();
-    myWriter.AddGroupOfEdges();
-    myWriter.AddGroupOfFaces();
-    myWriter.AddGroupOfVolumes();
-    myWriter.AddGroupOf0DElems();
-    myWriter.AddGroupOfBalls();
+    theWriter.AddGroupOfNodes();
+    theWriter.AddGroupOfEdges();
+    theWriter.AddGroupOfFaces();
+    theWriter.AddGroupOfVolumes();
+    theWriter.AddGroupOf0DElems();
+    theWriter.AddGroupOfBalls();
   }
-  if ( theAllElemsToGroup )
-    myWriter.AddAllToGroup();
 
   // Pass groups to writer. Provide unique group names.
   //set<string> aGroupNames; // Corrected for Mantis issue 0020028
-  if ( !meshPart )
+  if ( !theMeshPart )
   {
-    map< SMDSAbs_ElementType, set<string> > aGroupNames;
+    std::map< SMDSAbs_ElementType, std::set<std::string> > aGroupNames;
     char aString [256];
     int maxNbIter = 10000; // to guarantee cycle finish
-    for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
+    for ( std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin();
+          it != _mapGroup.end();
+          it++ ) {
       SMESH_Group*       aGroup   = it->second;
       SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
       if ( aGroupDS ) {
         SMDSAbs_ElementType aType = aGroupDS->GetType();
-        string aGroupName0 = aGroup->GetName();
+        std::string aGroupName0 = aGroup->GetName();
         aGroupName0.resize(MAX_MED_GROUP_NAME_LENGTH);
-        string aGroupName = aGroupName0;
+        std::string aGroupName = aGroupName0;
         for (int i = 1; !aGroupNames[aType].insert(aGroupName).second && i < maxNbIter; i++) {
           sprintf(&aString[0], "GR_%d_%s", i, aGroupName0.c_str());
           aGroupName = aString;
           aGroupName.resize(MAX_MED_GROUP_NAME_LENGTH);
         }
         aGroupDS->SetStoreName( aGroupName.c_str() );
-        myWriter.AddGroup( aGroupDS );
+        theWriter.AddGroup( aGroupDS );
       }
     }
   }
   // Perform export
-  myWriter.Perform();
+  status = theWriter.Perform();
 
   SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("MED");
 }
 
 //================================================================================
 /*!
- * \brief Export the mesh to a SAUV file
+ * Same as SMESH_Mesh::ExportMED except for \a file and \a theVersion
  */
 //================================================================================
 
-void SMESH_Mesh::ExportSAUV(const char *file, 
-                            const char* theMeshName, 
-                            bool theAutoGroups)
-  throw(SALOME_Exception)
+MEDCoupling::MCAuto<MEDCoupling::DataArrayByte>
+SMESH_Mesh::ExportMEDCoupling(const char*         theMeshName,
+                              bool                theAutoGroups,
+                              const SMESHDS_Mesh* theMeshPart,
+                              bool                theAutoDimension,
+                              bool                theAddODOnVertices,
+                              double              theZTolerance,
+                              bool                theSaveNumbers)
 {
-  std::string medfilename(file);
-  medfilename += ".med";
-  std::string cmd;
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
-  cmd += "\"";
-  system(cmd.c_str());
-  ExportMED(medfilename.c_str(), theMeshName, theAutoGroups, /*theVersion=*/1,
-            /*meshPart=*/NULL, /*theAutoDimension=*/false, /*theAddODOnVertices=*/false,
-            /*theAllElemsToGroup=*/true ); // theAllElemsToGroup is for PAL0023413
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import convert ; convert(r'" + medfilename + "', 'MED', 'GIBI', 1, r'" + file + "')";
-  cmd += "\"";
-  system(cmd.c_str());
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
-  cmd += "\"";
-  system(cmd.c_str());
+  DriverMED_W_SMESHDS_Mesh_Mem writer;
+  this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension,
+                          theAddODOnVertices, theZTolerance, theSaveNumbers);
+  return writer.getData();
+}
+
+//================================================================================
+/*!
+ * \brief Export the mesh to a med file
+ *  \param [in] theFile - name of the MED file
+ *  \param [in] theMeshName - name of this mesh
+ *  \param [in] theAutoGroups - boolean parameter for creating/not creating
+ *              the groups Group_On_All_Nodes, Group_On_All_Faces, ... ;
+ *              the typical use is auto_groups=false.
+ *  \param [in] theVersion - define the minor (xy, where version is x.y.z) of MED file format.
+ *              If theVersion is equal to -1, the minor version is not changed (default).
+ *  \param [in] theMeshPart - mesh data to export
+ *  \param [in] theAutoDimension - if \c true, a space dimension of a MED mesh can be either
+ *              - 1D if all mesh nodes lie on OX coordinate axis, or
+ *              - 2D if all mesh nodes lie on XOY coordinate plane, or
+ *              - 3D in the rest cases.
+ *              If \a theAutoDimension is \c false, the space dimension is always 3.
+ *  \param [in] theAddODOnVertices - to create 0D elements on all vertices
+ *  \param [in] theZTolerance - tolerance in Z direction. If Z coordinate of a node is close to zero
+ *              within a given tolerance, the coordinate is set to zero.
+ *              If \a ZTolerance is negative, the node coordinates are kept as is.
+ *  \param [in] theSaveNumbers : enable saving numbers of nodes and cells.
+ *  \return int - mesh index in the file
+ */
+//================================================================================
+
+void SMESH_Mesh::ExportMED(const char *        theFile,
+                           const char*         theMeshName,
+                           bool                theAutoGroups,
+                           int                 theVersion,
+                           const SMESHDS_Mesh* theMeshPart,
+                           bool                theAutoDimension,
+                           bool                theAddODOnVertices,
+                           double              theZTolerance,
+                           bool                theSaveNumbers)
+{
+  MESSAGE("MED_VERSION:"<< theVersion);
+  DriverMED_W_SMESHDS_Mesh writer;
+  writer.SetFile( theFile, theVersion );
+  this->exportMEDCommmon( writer, theMeshName, theAutoGroups, theMeshPart, theAutoDimension, theAddODOnVertices, theZTolerance, theSaveNumbers );
 }
 
 //================================================================================
@@ -1511,14 +1548,23 @@ void SMESH_Mesh::ExportSAUV(const char *file,
 //================================================================================
 
 void SMESH_Mesh::ExportDAT(const char *        file,
-                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+                           const SMESHDS_Mesh* meshPart,
+                           const bool          renumber)
 {
-  Unexpect aCatch(SalomeException);
-  DriverDAT_W_SMDS_Mesh myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
-  myWriter.SetMeshId(_id);
-  myWriter.Perform();
+  Driver_Mesh::Status status;
+  SMESH_TRY;
+
+  DriverDAT_W_SMDS_Mesh writer;
+  writer.SetFile( file );
+  writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS );
+  writer.SetMeshId(_id);
+  writer.SetRenumber( renumber );
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("DAT");
 }
 
 //================================================================================
@@ -1528,28 +1574,38 @@ void SMESH_Mesh::ExportDAT(const char *        file,
 //================================================================================
 
 void SMESH_Mesh::ExportUNV(const char *        file,
-                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+                           const SMESHDS_Mesh* meshPart,
+                           const bool          renumber)
 {
-  Unexpect aCatch(SalomeException);
-  DriverUNV_W_SMDS_Mesh myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS );
-  myWriter.SetMeshId(_id);
-  //  myWriter.SetGroups(_mapGroup);
+  Driver_Mesh::Status status;
+
+  SMESH_TRY;
+  DriverUNV_W_SMDS_Mesh writer;
+  writer.SetFile( file );
+  writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS );
+  writer.SetMeshId(_id);
+  writer.SetRenumber( renumber );
 
+  // pass group names to SMESHDS
   if ( !meshPart )
   {
-    for ( map<int, SMESH_Group*>::iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ ) {
+    std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin();
+    for ( ; it != _mapGroup.end(); it++ ) {
       SMESH_Group*       aGroup   = it->second;
       SMESHDS_GroupBase* aGroupDS = aGroup->GetGroupDS();
       if ( aGroupDS ) {
-        string aGroupName = aGroup->GetName();
+        std::string aGroupName = aGroup->GetName();
         aGroupDS->SetStoreName( aGroupName.c_str() );
-        myWriter.AddGroup( aGroupDS );
+        writer.AddGroup( aGroupDS );
       }
     }
   }
-  myWriter.Perform();
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("UNV");
 }
 
 //================================================================================
@@ -1561,16 +1617,23 @@ void SMESH_Mesh::ExportUNV(const char *        file,
 void SMESH_Mesh::ExportSTL(const char *        file,
                            const bool          isascii,
                            const char *        name,
-                           const SMESHDS_Mesh* meshPart) throw(SALOME_Exception)
+                           const SMESHDS_Mesh* meshPart)
 {
-  Unexpect aCatch(SalomeException);
-  DriverSTL_W_SMDS_Mesh myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetIsAscii( isascii );
-  myWriter.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _myMeshDS);
-  myWriter.SetMeshId(_id);
-  if ( name ) myWriter.SetName( name );
-  myWriter.Perform();
+  Driver_Mesh::Status status;
+  SMESH_TRY;
+
+  DriverSTL_W_SMDS_Mesh writer;
+  writer.SetFile( file );
+  writer.SetIsAscii( isascii );
+  writer.SetMesh( meshPart ? (SMESHDS_Mesh*) meshPart : _meshDS);
+  writer.SetMeshId(_id);
+  if ( name ) writer.SetName( name );
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("STL");
 }
 
 //================================================================================
@@ -1581,18 +1644,46 @@ void SMESH_Mesh::ExportSTL(const char *        file,
 
 void SMESH_Mesh::ExportCGNS(const char *        file,
                             const SMESHDS_Mesh* meshDS,
-                            const char *        meshName)
+                            const char *        meshName,
+                            const bool          groupElemsByType)
 {
+
   int res = Driver_Mesh::DRS_FAIL;
+  SMESH_TRY;
+
+  // pass group names to SMESHDS
+  std::map<int, SMESH_Group*>::iterator it = _mapGroup.begin();
+  for ( ; it != _mapGroup.end(); it++ ) {
+    SMESH_Group*       group   = it->second;
+    SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+    if ( groupDS ) {
+      std::string groupName = group->GetName();
+      groupDS->SetStoreName( groupName.c_str() );
+    }
+  }
 #ifdef WITH_CGNS
-  DriverCGNS_Write myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
-  myWriter.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
+
+  DriverCGNS_Write writer;
+  writer.SetFile( file );
+  writer.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
+  writer.SetMeshName( SMESH_Comment("Mesh_") << meshDS->GetPersistentId());
   if ( meshName && meshName[0] )
-    myWriter.SetMeshName( meshName );
-  res = myWriter.Perform();
+    writer.SetMeshName( meshName );
+  writer.SetElementsByType( groupElemsByType );
+  res = writer.Perform();
+  if ( res != Driver_Mesh::DRS_OK )
+  {
+    SMESH_ComputeErrorPtr err = writer.GetError();
+    if ( err && !err->IsOK() && !err->myComment.empty() )
+      throw SALOME_Exception(("Export failed: " + err->myComment ).c_str() );
+  }
+
 #endif
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( res == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("CGNS");
+
   if ( res != Driver_Mesh::DRS_OK )
     throw SALOME_Exception("Export failed");
 }
@@ -1607,12 +1698,20 @@ void SMESH_Mesh::ExportGMF(const char *        file,
                            const SMESHDS_Mesh* meshDS,
                            bool                withRequiredGroups)
 {
-  DriverGMF_Write myWriter;
-  myWriter.SetFile( file );
-  myWriter.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
-  myWriter.SetExportRequiredGroups( withRequiredGroups );
+  Driver_Mesh::Status status;
+  SMESH_TRY;
+
+  DriverGMF_Write writer;
+  writer.SetFile( file );
+  writer.SetMesh( const_cast<SMESHDS_Mesh*>( meshDS ));
+  writer.SetExportRequiredGroups( withRequiredGroups );
 
-  myWriter.Perform();
+  status = writer.Perform();
+
+  SMESH_CATCH( SMESH::throwSalomeEx );
+
+  if ( status == Driver_Mesh::DRS_TOO_LARGE_MESH )
+    throw TooLargeForExport("GMF");
 }
 
 //================================================================================
@@ -1650,7 +1749,7 @@ double SMESH_Mesh::GetComputeProgress() const
       }
       catch (...) {
 #ifdef _DEBUG_
-        cerr << "Exception in " << algo->GetName() << "::GetProgress()" << endl;
+        std::cerr << "Exception in " << algo->GetName() << "::GetProgress()" << std::endl;
 #endif
       }
       if ( 0. < rate && rate < 1.001 )
@@ -1695,10 +1794,9 @@ double SMESH_Mesh::GetComputeProgress() const
  */
 //================================================================================
 
-int SMESH_Mesh::NbNodes() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbNodes() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->NbNodes();
+  return _meshDS->NbNodes();
 }
 
 //================================================================================
@@ -1707,10 +1805,9 @@ int SMESH_Mesh::NbNodes() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::Nb0DElements() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().Nb0DElements();
+  return _meshDS->GetMeshInfo().Nb0DElements();
 }
 
 //================================================================================
@@ -1719,10 +1816,9 @@ int SMESH_Mesh::Nb0DElements() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbEdges(order);
+  return _meshDS->GetMeshInfo().NbEdges(order);
 }
 
 //================================================================================
@@ -1731,10 +1827,9 @@ int SMESH_Mesh::NbEdges(SMDSAbs_ElementOrder order) const throw(SALOME_Exception
  */
 //================================================================================
 
-int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbFaces(order);
+  return _meshDS->GetMeshInfo().NbFaces(order);
 }
 
 //================================================================================
@@ -1743,10 +1838,9 @@ int SMESH_Mesh::NbFaces(SMDSAbs_ElementOrder order) const throw(SALOME_Exception
  */
 //================================================================================
 
-int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbTriangles(order);
+  return _meshDS->GetMeshInfo().NbTriangles(order);
 }
 
 //================================================================================
@@ -1755,10 +1849,9 @@ int SMESH_Mesh::NbTriangles(SMDSAbs_ElementOrder order) const throw(SALOME_Excep
  */
 //================================================================================
 
-int SMESH_Mesh::NbBiQuadTriangles() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbBiQuadTriangles() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbBiQuadTriangles();
+  return _meshDS->GetMeshInfo().NbBiQuadTriangles();
 }
 
 //================================================================================
@@ -1767,10 +1860,9 @@ int SMESH_Mesh::NbBiQuadTriangles() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbQuadrangles(order);
+  return _meshDS->GetMeshInfo().NbQuadrangles(order);
 }
 
 //================================================================================
@@ -1779,10 +1871,9 @@ int SMESH_Mesh::NbQuadrangles(SMDSAbs_ElementOrder order) const throw(SALOME_Exc
  */
 //================================================================================
 
-int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbBiQuadQuadrangles() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbBiQuadQuadrangles();
+  return _meshDS->GetMeshInfo().NbBiQuadQuadrangles();
 }
 
 //================================================================================
@@ -1791,10 +1882,9 @@ int SMESH_Mesh::NbBiQuadQuadrangles() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPolygons(order);
+  return _meshDS->GetMeshInfo().NbPolygons(order);
 }
 
 //================================================================================
@@ -1803,10 +1893,9 @@ int SMESH_Mesh::NbPolygons(SMDSAbs_ElementOrder order) const throw(SALOME_Except
  */
 //================================================================================
 
-int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbVolumes(order);
+  return _meshDS->GetMeshInfo().NbVolumes(order);
 }
 
 //================================================================================
@@ -1815,10 +1904,9 @@ int SMESH_Mesh::NbVolumes(SMDSAbs_ElementOrder order) const throw(SALOME_Excepti
  */
 //================================================================================
 
-int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbTetras(order);
+  return _meshDS->GetMeshInfo().NbTetras(order);
 }
 
 //================================================================================
@@ -1827,10 +1915,9 @@ int SMESH_Mesh::NbTetras(SMDSAbs_ElementOrder order) const throw(SALOME_Exceptio
  */
 //================================================================================
 
-int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbHexas(order);
+  return _meshDS->GetMeshInfo().NbHexas(order);
 }
 
 //================================================================================
@@ -1839,10 +1926,9 @@ int SMESH_Mesh::NbHexas(SMDSAbs_ElementOrder order) const throw(SALOME_Exception
  */
 //================================================================================
 
-int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbTriQuadraticHexas() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbTriQuadHexas();
+  return _meshDS->GetMeshInfo().NbTriQuadHexas();
 }
 
 //================================================================================
@@ -1851,10 +1937,9 @@ int SMESH_Mesh::NbTriQuadraticHexas() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPyramids(order);
+  return _meshDS->GetMeshInfo().NbPyramids(order);
 }
 
 //================================================================================
@@ -1863,22 +1948,31 @@ int SMESH_Mesh::NbPyramids(SMDSAbs_ElementOrder order) const throw(SALOME_Except
  */
 //================================================================================
 
-int SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPrisms(SMDSAbs_ElementOrder order) const
+{
+  return _meshDS->GetMeshInfo().NbPrisms(order);
+}
+
+smIdType SMESH_Mesh::NbQuadPrisms() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPrisms(order);
+  return _meshDS->GetMeshInfo().NbQuadPrisms();
 }
 
+smIdType SMESH_Mesh::NbBiQuadPrisms() const
+{
+  return _meshDS->GetMeshInfo().NbBiQuadPrisms();
+}
+
+
 //================================================================================
 /*!
  * \brief  Return number of hexagonal prisms in the mesh
  */
 //================================================================================
 
-int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbHexagonalPrisms() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbHexPrisms();
+  return _meshDS->GetMeshInfo().NbHexPrisms();
 }
 
 //================================================================================
@@ -1887,10 +1981,9 @@ int SMESH_Mesh::NbHexagonalPrisms() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbPolyhedrons() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbPolyhedrons();
+  return _meshDS->GetMeshInfo().NbPolyhedrons();
 }
 
 //================================================================================
@@ -1899,10 +1992,9 @@ int SMESH_Mesh::NbPolyhedrons() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbBalls() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbBalls() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->GetMeshInfo().NbBalls();
+  return _meshDS->GetMeshInfo().NbBalls();
 }
 
 //================================================================================
@@ -1911,10 +2003,9 @@ int SMESH_Mesh::NbBalls() const throw(SALOME_Exception)
  */
 //================================================================================
 
-int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception)
+smIdType SMESH_Mesh::NbSubMesh() const
 {
-  Unexpect aCatch(SalomeException);
-  return _myMeshDS->NbSubMesh();
+  return _meshDS->NbSubMesh();
 }
 
 //================================================================================
@@ -1926,7 +2017,7 @@ int SMESH_Mesh::NbSubMesh() const throw(SALOME_Exception)
 
 int SMESH_Mesh::NbMeshes() const // nb meshes in the Study
 {
-  return _myDocument->NbMeshes();
+  return _document->NbMeshes();
 }
 
 //=======================================================================
@@ -1939,7 +2030,7 @@ bool SMESH_Mesh::IsNotConformAllowed() const
   if(MYDEBUG) MESSAGE("SMESH_Mesh::IsNotConformAllowed");
 
   static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "NotConformAllowed" ));
-  return GetHypothesis( _myMeshDS->ShapeToMesh(), filter, false );
+  return GetHypothesis( _meshDS->ShapeToMesh(), filter, false );
 }
 
 //=======================================================================
@@ -1949,7 +2040,17 @@ bool SMESH_Mesh::IsNotConformAllowed() const
 
 bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
 {
-  return theShape.IsSame(_myMeshDS->ShapeToMesh() );
+  return theShape.IsSame(_meshDS->ShapeToMesh() );
+}
+
+//=======================================================================
+//function : GetShapeByEntry
+//purpose  : return TopoDS_Shape by its study entry
+//=======================================================================
+
+TopoDS_Shape SMESH_Mesh::GetShapeByEntry(const std::string& entry) const
+{
+  return _callUp ? _callUp->GetShapeByEntry( entry ) : TopoDS_Shape();
 }
 
 //=============================================================================
@@ -1960,16 +2061,17 @@ bool SMESH_Mesh::IsMainShape(const TopoDS_Shape& theShape) const
 
 SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
                                    const char*               theName,
-                                   int&                      theId,
+                                   const int                 theId,
                                    const TopoDS_Shape&       theShape,
                                    const SMESH_PredicatePtr& thePredicate)
 {
-  if (_mapGroup.count(_groupId))
+  if ( _mapGroup.count( theId ))
     return NULL;
-  theId = _groupId;
-  SMESH_Group* aGroup = new SMESH_Group (theId, this, theType, theName, theShape, thePredicate);
+  int id = ( theId < 0 ) ? _groupId : theId;
+  SMESH_Group* aGroup = new SMESH_Group ( id, this, theType, theName, theShape, thePredicate );
   GetMeshDS()->AddGroup( aGroup->GetGroupDS() );
-  _mapGroup[_groupId++] = aGroup;
+  _mapGroup[ id ] = aGroup;
+  _groupId = 1 + _mapGroup.rbegin()->first;
   return aGroup;
 }
 
@@ -1979,12 +2081,12 @@ SMESH_Group* SMESH_Mesh::AddGroup (const SMDSAbs_ElementType theType,
  */
 //================================================================================
 
-SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exception)
+SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS)
 {
-  if ( !groupDS ) 
+  if ( !groupDS )
     throw SALOME_Exception(LOCALIZED ("SMESH_Mesh::AddGroup(): NULL SMESHDS_GroupBase"));
 
-  map <int, SMESH_Group*>::iterator i_g = _mapGroup.find( groupDS->GetID() );
+  std::map <int, SMESH_Group*>::iterator i_g = _mapGroup.find( groupDS->GetID() );
   if ( i_g != _mapGroup.end() && i_g->second )
   {
     if ( i_g->second->GetGroupDS() == groupDS )
@@ -2006,15 +2108,15 @@ SMESH_Group* SMESH_Mesh::AddGroup (SMESHDS_GroupBase* groupDS) throw(SALOME_Exce
 /*!
  * \brief Creates SMESH_Groups for not wrapped SMESHDS_Groups
  *  \retval bool - true if new SMESH_Groups have been created
- * 
+ *
  */
 //================================================================================
 
 bool SMESH_Mesh::SynchronizeGroups()
 {
-  const size_t                       nbGroups = _mapGroup.size();
-  const set<SMESHDS_GroupBase*>&       groups = _myMeshDS->GetGroups();
-  set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
+  const size_t                            nbGroups = _mapGroup.size();
+  const std::set<SMESHDS_GroupBase*>&       groups = _meshDS->GetGroups();
+  std::set<SMESHDS_GroupBase*>::const_iterator gIt = groups.begin();
   for ( ; gIt != groups.end(); ++gIt )
   {
     SMESHDS_GroupBase* groupDS = (SMESHDS_GroupBase*) *gIt;
@@ -2023,7 +2125,7 @@ bool SMESH_Mesh::SynchronizeGroups()
       _mapGroup[_groupId] = new SMESH_Group( groupDS );
   }
   if ( !_mapGroup.empty() )
-    _groupId = _mapGroup.rbegin()->first + 1;
+    _groupId = 1 + _mapGroup.rbegin()->first;
 
   return nbGroups < _mapGroup.size();
 }
@@ -2036,7 +2138,7 @@ bool SMESH_Mesh::SynchronizeGroups()
 
 SMESH_Mesh::GroupIteratorPtr SMESH_Mesh::GetGroups() const
 {
-  typedef map <int, SMESH_Group *> TMap;
+  typedef std::map <int, SMESH_Group *> TMap;
   return GroupIteratorPtr( new SMDS_mapIterator<TMap>( _mapGroup ));
 }
 
@@ -2046,11 +2148,12 @@ SMESH_Mesh::GroupIteratorPtr SMESH_Mesh::GetGroups() const
  */
 //=============================================================================
 
-SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
+SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID) const
 {
-  if (_mapGroup.find(theGroupID) == _mapGroup.end())
+  std::map <int, SMESH_Group*>::const_iterator id_grp = _mapGroup.find( theGroupID );
+  if ( id_grp == _mapGroup.end() )
     return NULL;
-  return _mapGroup[theGroupID];
+  return id_grp->second;
 }
 
 
@@ -2060,10 +2163,11 @@ SMESH_Group* SMESH_Mesh::GetGroup (const int theGroupID)
  */
 //=============================================================================
 
-list<int> SMESH_Mesh::GetGroupIds() const
+std::list<int> SMESH_Mesh::GetGroupIds() const
 {
-  list<int> anIds;
-  for ( map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin(); it != _mapGroup.end(); it++ )
+  std::list<int> anIds;
+  std::map<int, SMESH_Group*>::const_iterator it = _mapGroup.begin();
+  for ( ; it != _mapGroup.end(); it++ )
     anIds.push_back( it->first );
   
   return anIds;
@@ -2132,19 +2236,19 @@ ostream& SMESH_Mesh::Dump(ostream& save)
   save << ++clause << ") Total number of polyhedrons:\t" << NbPolyhedrons() << endl << endl;
   for ( int isQuadratic = 0; isQuadratic < 2; ++isQuadratic )
   {
-    string orderStr = isQuadratic ? "quadratic" : "linear";
+    std::string orderStr = isQuadratic ? "quadratic" : "linear";
     SMDSAbs_ElementOrder order  = isQuadratic ? ORDER_QUADRATIC : ORDER_LINEAR;
 
     save << ++clause << ") Total number of " << orderStr << " edges:\t" << NbEdges(order) << endl;
     save << ++clause << ") Total number of " << orderStr << " faces:\t" << NbFaces(order) << endl;
     if ( NbFaces(order) > 0 ) {
-      int nb3 = NbTriangles(order);
-      int nb4 = NbQuadrangles(order);
+      smIdType nb3 = NbTriangles(order);
+      smIdType nb4 = NbQuadrangles(order);
       save << clause << ".1) Number of " << orderStr << " triangles:  \t" << nb3 << endl;
       save << clause << ".2) Number of " << orderStr << " quadrangles:\t" << nb4 << endl;
       if ( nb3 + nb4 !=  NbFaces(order) ) {
-        map<int,int> myFaceMap;
-        SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
+        std::map<int,int> myFaceMap;
+        SMDS_FaceIteratorPtr itFaces=_meshDS->facesIterator();
         while( itFaces->more( ) ) {
           int nbNodes = itFaces->next()->NbNodes();
           if ( myFaceMap.find( nbNodes ) == myFaceMap.end() )
@@ -2152,24 +2256,24 @@ ostream& SMESH_Mesh::Dump(ostream& save)
           myFaceMap[ nbNodes ] = myFaceMap[ nbNodes ] + 1;
         }
         save << clause << ".3) Faces in detail: " << endl;
-        map <int,int>::iterator itF;
+        std::map <int,int>::iterator itF;
         for (itF = myFaceMap.begin(); itF != myFaceMap.end(); itF++)
-          save << "--> nb nodes: " << itF->first << " - nb elemens:\t" << itF->second << endl;
+          save << "--> nb nodes: " << itF->first << " - nb elements:\t" << itF->second << endl;
       }
     }
     save << ++clause << ") Total number of " << orderStr << " volumes:\t" << NbVolumes(order) << endl;
     if ( NbVolumes(order) > 0 ) {
-      int nb8 = NbHexas(order);
-      int nb4 = NbTetras(order);
-      int nb5 = NbPyramids(order);
-      int nb6 = NbPrisms(order);
+      smIdType nb8 = NbHexas(order);
+      smIdType nb4 = NbTetras(order);
+      smIdType nb5 = NbPyramids(order);
+      smIdType nb6 = NbPrisms(order);
       save << clause << ".1) Number of " << orderStr << " hexahedrons: \t" << nb8 << endl;
       save << clause << ".2) Number of " << orderStr << " tetrahedrons:\t" << nb4 << endl;
       save << clause << ".3) Number of " << orderStr << " prisms:      \t" << nb6 << endl;
       save << clause << ".4) Number of " << orderStr << " pyramids:    \t" << nb5 << endl;
       if ( nb8 + nb4 + nb5 + nb6 != NbVolumes(order) ) {
-        map<int,int> myVolumesMap;
-        SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
+        std::map<int,int> myVolumesMap;
+        SMDS_VolumeIteratorPtr itVolumes=_meshDS->volumesIterator();
         while( itVolumes->more( ) ) {
           int nbNodes = itVolumes->next()->NbNodes();
           if ( myVolumesMap.find( nbNodes ) == myVolumesMap.end() )
@@ -2177,9 +2281,9 @@ ostream& SMESH_Mesh::Dump(ostream& save)
           myVolumesMap[ nbNodes ] = myVolumesMap[ nbNodes ] + 1;
         }
         save << clause << ".5) Volumes in detail: " << endl;
-        map <int,int>::iterator itV;
+        std::map <int,int>::iterator itV;
         for (itV = myVolumesMap.begin(); itV != myVolumesMap.end(); itV++)
-          save << "--> nb nodes: " << itV->first << " - nb elemens:\t" << itV->second << endl;
+          save << "--> nb nodes: " << itV->first << " - nb elements:\t" << itV->second << endl;
       }
     }
     save << endl;
@@ -2193,9 +2297,9 @@ ostream& SMESH_Mesh::Dump(ostream& save)
 //purpose  : Returns type of mesh element with certain id
 //=======================================================================
 
-SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem )
+SMDSAbs_ElementType SMESH_Mesh::GetElementType( const smIdType id, const bool iselem )
 {
-  return _myMeshDS->GetElementType( id, iselem );
+  return _meshDS->GetElementType( id, iselem );
 }
 
 //=============================================================================
@@ -2207,7 +2311,7 @@ SMDSAbs_ElementType SMESH_Mesh::GetElementType( const int id, const bool iselem
 SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
 {
   SMESH_Group* aGroup = 0;
-  map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID );
+  std::map < int, SMESH_Group * >::iterator itg = _mapGroup.find( theGroupID );
   if ( itg == _mapGroup.end() )
     return aGroup;
 
@@ -2246,7 +2350,7 @@ SMESH_Group* SMESH_Mesh::ConvertToStandalone ( int theGroupID )
 
 void SMESH_Mesh::ClearMeshOrder()
 {
-  _mySubMeshOrder.clear();
+  _subMeshOrder.clear();
 }
 
 //=============================================================================
@@ -2257,7 +2361,7 @@ void SMESH_Mesh::ClearMeshOrder()
 
 void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder )
 {
-  _mySubMeshOrder = theOrder;
+  _subMeshOrder = theOrder;
 }
 
 //=============================================================================
@@ -2268,7 +2372,7 @@ void SMESH_Mesh::SetMeshOrder(const TListOfListOfInt& theOrder )
 
 const TListOfListOfInt& SMESH_Mesh::GetMeshOrder() const
 {
-  return _mySubMeshOrder;
+  return _subMeshOrder;
 }
 
 //=============================================================================
@@ -2329,19 +2433,20 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape)
 
 bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) const
 {
-  if ( !_mySubMeshOrder.size() || theListToSort.size() < 2)
+  if ( _subMeshOrder.empty() || theListToSort.size() < 2 )
     return true;
-  
-  bool res = false;
-  vector<SMESH_subMesh*> onlyOrderedList, smVec;
 
-  // collect all ordered submeshes in one list as pointers
+
+  // collect all ordered sub-meshes in smVec as pointers
   // and get their positions within theListToSort
-  typedef vector<SMESH_subMesh*>::iterator TPosInList;
-  map< int, TPosInList > sortedPos;
+
+  std::vector<SMESH_subMesh*> smVec;
+  typedef std::vector<SMESH_subMesh*>::iterator TPosInList;
+  std::map< size_t, size_t > sortedPos; // index in theListToSort to order
   TPosInList smBeg = theListToSort.begin(), smEnd = theListToSort.end();
-  TListOfListOfInt::const_iterator      listIdsIt = _mySubMeshOrder.begin();
-  for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
+  TListOfListOfInt::const_iterator      listIdsIt = _subMeshOrder.begin();
+  bool needSort = false;
+  for( ; listIdsIt != _subMeshOrder.end(); listIdsIt++)
   {
     const TListOfInt& listOfId = *listIdsIt;
     // convert sm ids to sm's
@@ -2354,6 +2459,7 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
         smVec.push_back( sm );
         if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->IsComplexSubmesh() )
         {
+          smVec.reserve( smVec.size() + sm->GetSubMeshDS()->NbSubMeshes() );
           SMESHDS_SubMeshIteratorPtr smdsIt = sm->GetSubMeshDS()->GetSubMeshIterator();
           while ( smdsIt->more() )
           {
@@ -2367,26 +2473,46 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
     // find smVec items in theListToSort
     for ( size_t i = 0; i < smVec.size(); ++i )
     {
-      TPosInList smPos = find( smBeg, smEnd, smVec[i] );
-      if ( smPos != smEnd ) {
-        onlyOrderedList.push_back( smVec[i] );
-        sortedPos[ distance( smBeg, smPos )] = smPos;
+      TPosInList smPos = find( smBeg, smEnd, smVec[i] ); // position in theListToSort
+      if ( smPos != smEnd )
+      {
+        size_t posInList = std::distance( smBeg, smPos );
+        size_t     order = sortedPos.size();
+        sortedPos.insert( std::make_pair( posInList, order ));
+        if ( posInList != order )
+          needSort = true;
       }
     }
   }
-  if (onlyOrderedList.size() < 2)
-    return res;
-  res = true;
+  if ( ! needSort )
+    return false;
 
-  vector<SMESH_subMesh*>::iterator onlyBIt = onlyOrderedList.begin();
-  vector<SMESH_subMesh*>::iterator onlyEIt = onlyOrderedList.end();
+  // set sm of sortedPos from theListToSort to front of orderedSM
+  // and the rest of theListToSort to orderedSM end
 
-  // iterate on ordered sub-meshes and insert them in detected positions
-  map< int, TPosInList >::iterator i_pos = sortedPos.begin();
-  for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos )
-    *(i_pos->second) = *onlyBIt;
+  std::vector<SMESH_subMesh*> orderedSM;
+  orderedSM.reserve( theListToSort.size() );
+  orderedSM.resize( sortedPos.size() );
 
-  return res;
+  size_t iPrev = 0;
+  sortedPos.insert( std::make_pair( theListToSort.size(), sortedPos.size() ));
+  for ( const auto & pos_order : sortedPos )
+  {
+    const size_t& posInList = pos_order.first;
+    const size_t&     order = pos_order.second;
+    if ( order < sortedPos.size() - 1 )
+      orderedSM[ order ] = theListToSort[ posInList ];
+
+    if ( iPrev < posInList )
+      orderedSM.insert( orderedSM.end(),
+                        theListToSort.begin() + iPrev,
+                        theListToSort.begin() + posInList );
+    iPrev = posInList + 1;
+  }
+
+  theListToSort.swap( orderedSM );
+
+  return true;
 }
 
 //================================================================================
@@ -2398,8 +2524,8 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector<SMESH_subMesh*>& theListToSort) con
 bool SMESH_Mesh::IsOrderOK( const SMESH_subMesh* smBefore,
                             const SMESH_subMesh* smAfter ) const
 {
-  TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin();
-  for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++)
+  TListOfListOfInt::const_iterator listIdsIt = _subMeshOrder.begin();
+  for( ; listIdsIt != _subMeshOrder.end(); listIdsIt++)
   {
     const TListOfInt& listOfId = *listIdsIt;
     int iB = -1, iA = -1, i = 0;