Salome HOME
bos #26523 EDF 24234 - Viscous Layer
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index 86f9daa3b97ffef19a9319b68037433d0bd167f9..9fce23337f80410db0b0cc76714487d90492dd25 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  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
@@ -49,7 +49,6 @@
 #include <TopoDS_Wire.hxx>
 #include <gp_Pnt.hxx>
 
-
 #ifdef WIN32
  #include <windows.h>
  #include <process.h>
 #include "SMESH_PreMeshInfo.hxx"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_ControlsDef.hxx"
+#include <SMESH_BoostTxtArchive.hxx>
 
 // to pass CORBA exception through SMESH_TRY
 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
 #include <cstdlib>
 #include <memory>
 
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/string.hpp>
+
 using namespace std;
 using SMESH::TPythonDump;
 using SMESH::TVar;
@@ -157,12 +161,12 @@ static int MYDEBUG = 0;
 #endif
 
 // Static variables definition
-GEOM::GEOM_Gen_var      SMESH_Gen_i::myGeomGen = GEOM::GEOM_Gen::_nil();
+GEOM::GEOM_Gen_var      SMESH_Gen_i::myGeomGen;
 CORBA::ORB_var          SMESH_Gen_i::myOrb;
 PortableServer::POA_var SMESH_Gen_i::myPoa;
-SALOME_NamingService*   SMESH_Gen_i::myNS  = NULL;
-SALOME_LifeCycleCORBA*  SMESH_Gen_i::myLCC = NULL;
-SMESH_Gen_i*            SMESH_Gen_i::mySMESHGen = NULL;
+SALOME_NamingService_Abstract*   SMESH_Gen_i::myNS  = nullptr;
+SALOME_LifeCycleCORBA*  SMESH_Gen_i::myLCC = nullptr;
+SMESH_Gen_i*            SMESH_Gen_i::mySMESHGen = nullptr;
 
 
 const int nbElemPerDiagonal = 10;
@@ -185,22 +189,22 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb
   }
   catch (PortableServer::POA::ObjectNotActive &ex)
   {
-    INFOS("GetServant: ObjectNotActive");
+    MESSAGE("GetServant: ObjectNotActive");
     return NULL;
   }
   catch (PortableServer::POA::WrongAdapter &ex)
   {
-    INFOS("GetServant: WrongAdapter: OK when several servants used to build several mesh in parallel...");
+    MESSAGE("GetServant: WrongAdapter: OK when several servants used to build several mesh in parallel...");
     return NULL;
   }
   catch (PortableServer::POA::WrongPolicy &ex)
   {
-    INFOS("GetServant: WrongPolicy");
+    MESSAGE("GetServant: WrongPolicy");
     return NULL;
   }
   catch (...)
   {
-    INFOS( "GetServant - Unknown exception was caught!!!" );
+    MESSAGE( "GetServant - Unknown exception was caught!!!" );
     return NULL;
   }
 }
@@ -233,6 +237,14 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject
   return anObj;
 }
 
+// Set Naming Service object
+void SMESH_Gen_i::SetNS(SALOME_NamingService_Abstract *ns)
+{
+  if(myNS)
+    delete myNS;
+  myNS = ns;
+}
+
 //=============================================================================
 /*!
  *  GetNS [ static ]
@@ -241,9 +253,9 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject
  */
 //=============================================================================
 
-SALOME_NamingService* SMESH_Gen_i::GetNS()
+SALOME_NamingService_Abstract* SMESH_Gen_i::GetNS()
 {
-  if ( myNS == NULL ) {
+  if ( !myNS ) {
     myNS = SINGLETON_<SALOME_NamingService>::Instance();
     ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting());
     myNS->init_orb( GetORB() );
@@ -258,14 +270,15 @@ SALOME_NamingService* SMESH_Gen_i::GetNS()
  *  Get SALOME_LifeCycleCORBA object
  */
 //=============================================================================
-SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
+
+SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC()
+{
   if ( myLCC == NULL ) {
     myLCC = new SALOME_LifeCycleCORBA( GetNS() );
   }
   return myLCC;
 }
 
-
 //=============================================================================
 /*!
  *  GetGeomEngine [ static ]
@@ -273,16 +286,13 @@ SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
  *  Get GEOM::GEOM_Gen reference
  */
 //=============================================================================
-GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() {
-  //CCRT GEOM::GEOM_Gen_var aGeomEngine =
-  //CCRT   GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") );
-  //CCRT return aGeomEngine._retn();
-  if(CORBA::is_nil(myGeomGen))
-  {
-    Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM");
-    myGeomGen=GEOM::GEOM_Gen::_narrow(temp);
-  }
-  return myGeomGen;
+
+GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine( GEOM::GEOM_Object_ptr go )
+{
+  GEOM::GEOM_Gen_ptr gen = GEOM::GEOM_Gen::_nil();
+  if ( !CORBA::is_nil( go ))
+    gen = go->GetGen();
+  return gen;
 }
 
 //=============================================================================
@@ -309,8 +319,9 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
                           PortableServer::POA_ptr   poa,
                           PortableServer::ObjectId* contId,
                           const char*               instanceName,
-                          const char*               interfaceName )
-  : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
+                          const char*               interfaceName,
+                          bool                      checkNS)
+  : Engines_Component_i( orb, poa, contId, instanceName, interfaceName, false, checkNS )
 {
 
   myOrb = CORBA::ORB::_duplicate(orb);
@@ -335,21 +346,24 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
   // find out mode (embedded or standalone) here else
   // meshes created before calling SMESH_Client::GetSMESHGen(), which calls
   // SMESH_Gen_i::SetEmbeddedMode(), have wrong IsEmbeddedMode flag
-  if ( SALOME_NamingService* ns = GetNS() )
+  if(checkNS)
   {
-    CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" );
-    SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
-    if ( !session->_is_nil() )
+    if ( SALOME_NamingService_Abstract* ns = GetNS() )
     {
-      CORBA::String_var str_host = session->getHostname();
-      CORBA::Long        s_pid = session->getPID();
-      string my_host = Kernel_Utils::GetHostname();
+      CORBA::Object_var obj = ns->Resolve( "/Kernel/Session" );
+      SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
+      if ( !session->_is_nil() )
+      {
+        CORBA::String_var str_host = session->getHostname();
+        CORBA::Long        s_pid = session->getPID();
+        string my_host = Kernel_Utils::GetHostname();
 #ifdef WIN32
-      long    my_pid = (long)_getpid();
+        long    my_pid = (long)_getpid();
 #else
-      long    my_pid = (long) getpid();
+        long    my_pid = (long) getpid();
 #endif
-      SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() );
+        SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() );
+      }
     }
   }
 }
@@ -386,6 +400,7 @@ SMESH_Gen_i::~SMESH_Gen_i()
   if ( myShapeReader )
     delete myShapeReader;
 }
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::getHypothesisCreator
@@ -393,10 +408,10 @@ SMESH_Gen_i::~SMESH_Gen_i()
  *  Get hypothesis creator
  */
 //=============================================================================
+
 GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHypName,
                                                               const char* theLibName,
                                                               std::string& thePlatformLibName)
-  throw (SALOME::SALOME_Exception)
 {
   std::string aPlatformLibName;
   /* It's Need to translate lib name for WIN32 or X platform */
@@ -445,26 +460,26 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
       // load plugin library
       if(MYDEBUG) MESSAGE("Loading server meshers plugin library ...");
 #ifdef WIN32
-#ifdef UNICODE
+#  ifdef UNICODE
       const wchar_t* path = Kernel_Utils::decode_s(aPlatformLibName);
-#else
+      SMESHUtils::ArrayDeleter<const wchar_t> deleter( path );
+#  else
       const char* path = aPlatformLibName.c_str();
-#endif
+#  endif
 #else
       const char* path = aPlatformLibName.c_str();
 #endif
       LibHandle libHandle = LoadLib( path );
-#if defined(WIN32) && defined(UNICODE)
-      delete path;
-#endif
+
       if (!libHandle)
       {
         // report any error, if occurred
 #ifndef WIN32
         const char* anError = dlerror();
-        throw(SALOME_Exception(anError));
+        throw(SALOME_Exception( anError ));
 #else
-        throw(SALOME_Exception(LOCALIZED( "Can't load server meshers plugin library" )));
+        throw(SALOME_Exception ( SMESH_Comment("Can't load meshers plugin library " )
+                                 << aPlatformLibName));
 #endif
       }
 
@@ -474,7 +489,8 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
         (GetHypothesisCreator)GetProc( libHandle, "GetHypothesisCreator" );
       if (!procHandle)
       {
-        throw(SALOME_Exception(LOCALIZED("bad hypothesis plugin library")));
+        throw(SALOME_Exception(SMESH_Comment("bad hypothesis plugin library")
+                               << aPlatformLibName ));
         UnLoadLib(libHandle);
       }
 
@@ -483,7 +499,8 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
       aCreator = procHandle(theHypName);
       if (!aCreator)
       {
-        throw(SALOME_Exception(LOCALIZED("no such a hypothesis in this plugin")));
+        throw(SALOME_Exception( SMESH_Comment( theHypName ) << " is missing from "
+                                << aPlatformLibName));
       }
       // map hypothesis creator to a hypothesis name
       myHypCreatorMap[string(theHypName)] = aCreator;
@@ -508,6 +525,7 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
  *  Create hypothesis of given type
  */
 //=============================================================================
+
 SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName,
                                                           const char* theLibName)
 {
@@ -529,7 +547,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
     hypothesis_i = myHypothesis_i->_this();
     int nextId = RegisterObject( hypothesis_i );
     if(MYDEBUG) { MESSAGE( "Add hypo to map with id = "<< nextId ); }
-    else        { nextId = 0; } // avoid "unused variable" warning in release mode
+    else        { (void)nextId; } // avoid "unused variable" warning in release mode
   }
   return hypothesis_i._retn();
 }
@@ -541,8 +559,8 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
  *  Create empty mesh on shape
  */
 //=============================================================================
+
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::createMesh" );
@@ -559,7 +577,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
     SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( meshServant->_this() );
     int nextId = RegisterObject( mesh );
     if(MYDEBUG) { MESSAGE( "Add mesh to map with id = "<< nextId); }
-    else        { nextId = 0; } // avoid "unused variable" warning in release mode
+    else        { (void)nextId; } // avoid "unused variable" warning in release mode
     return mesh._retn();
   }
   catch (SALOME_Exception& S_ex) {
@@ -575,6 +593,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
  *  Get shape reader
  */
 //=============================================================================
+
 GEOM_Client* SMESH_Gen_i::GetShapeReader()
 {
   // create shape reader if necessary
@@ -591,13 +610,10 @@ GEOM_Client* SMESH_Gen_i::GetShapeReader()
  *  Set GEOM::GEOM_Gen reference
  */
 //=============================================================================
-//GEOM::GEOM_Gen_ptr SMESH_Gen_i::SetGeomEngine( const char* containerLoc )
+
 void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo )
 {
-  //Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component(containerLoc,"GEOM");
-  //myGeomGen=GEOM::GEOM_Gen::_narrow(temp);
-  myGeomGen=GEOM::GEOM_Gen::_duplicate(geomcompo);
-  //return myGeomGen;
+  myGeomGen = GEOM::GEOM_Gen::_duplicate( geomcompo );
 }
 
 //=============================================================================
@@ -652,6 +668,7 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode()
  *  Set enable publishing in the study
  */
 //=============================================================================
+
 void SMESH_Gen_i::SetEnablePublish( CORBA::Boolean theIsEnablePublish )
 {
   myIsEnablePublish = theIsEnablePublish;
@@ -684,11 +701,18 @@ void SMESH_Gen_i::UpdateStudy()
     myStudyContext = new StudyContext;
 
   SALOMEDS::Study_var aStudy = getStudyServant();
-  if ( !CORBA::is_nil( aStudy ) ) {
+  if ( !CORBA::is_nil( aStudy ) )
+  {
     SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
+
     SALOMEDS::SComponent_wrap GEOM_var = aStudy->FindComponent( "GEOM" );
     if( !GEOM_var->_is_nil() )
-      aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine() );
+      aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine( /*isShaper=*/false ) );
+
+    GEOM_var = aStudy->FindComponent( "SHAPERSTUDY" );
+    if( !GEOM_var->_is_nil() )
+      aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine( /*isShaper=*/true ) );
+
     // NPAL16168, issue 0020210
     // Let meshes update their data depending on GEOM groups that could change
     CORBA::String_var compDataType = ComponentDataType();
@@ -705,6 +729,63 @@ void SMESH_Gen_i::UpdateStudy()
   }
 }
 
+//================================================================================
+/*!
+ * \brief Return true if mesh has ICON_SMESH_TREE_GEOM_MODIF icon
+ */
+//================================================================================
+
+bool SMESH_Gen_i::isGeomModifIcon( SMESH::SMESH_Mesh_ptr mesh )
+{
+  SALOMEDS::SObject_wrap so = ObjectToSObject( mesh );
+  SALOMEDS::GenericAttribute_wrap attr;
+  if ( ! so->_is_nil() && so->FindAttribute( attr.inout(), "AttributePixMap" ))
+  {
+    SALOMEDS::AttributePixMap_wrap pm = attr;
+    CORBA::String_var             ico = pm->GetPixMap();
+    return ( strcmp( ico.in(), "ICON_SMESH_TREE_GEOM_MODIF" ) == 0 );
+  }
+  return false;
+}
+
+//=================================================================================
+// function : hasObjectInfo()
+// purpose  : shows if module provides information for its objects
+//=================================================================================
+
+bool SMESH_Gen_i::hasObjectInfo()
+{
+  return true;
+}
+
+//=================================================================================
+// function : getObjectInfo()
+// purpose  : returns an information for a given object by its entry
+//=================================================================================
+
+char* SMESH_Gen_i::getObjectInfo( const char* entry )
+{
+  // for a mesh with icon == ICON_SMESH_TREE_GEOM_MODIF show a warning;
+  // for the rest, "module 'SMESH', ID=0:1:2:*"
+
+  SMESH_Comment txt;
+
+  SALOMEDS::SObject_wrap  so = getStudyServant()->FindObjectID( entry );
+  CORBA::Object_var      obj = SObjectToObject( so );
+  SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
+  if ( isGeomModifIcon( mesh ))
+  {
+    txt << "The geometry was changed and the mesh needs to be recomputed";
+  }
+
+  if ( txt.empty() )
+  {
+    CORBA::String_var compType = ComponentDataType();
+    txt << "module '" << compType << "', ID=" << entry;
+  }
+  return CORBA::string_dup( txt );
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::GetStudyContext
@@ -712,6 +793,7 @@ void SMESH_Gen_i::UpdateStudy()
  *  Get study context
  */
 //=============================================================================
+
 StudyContext* SMESH_Gen_i::GetStudyContext()
 {
   return myStudyContext;
@@ -721,13 +803,12 @@ StudyContext* SMESH_Gen_i::GetStudyContext()
 /*!
  *  SMESH_Gen_i::CreateHypothesis
  *
- *  Create hypothesis/algorothm of given type and publish it in the study
+ *  Create hypothesis/algorithm of given type and publish it in the study
  */
 //=============================================================================
 
 SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypName,
                                                            const char* theLibName )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   // Create hypothesis/algorithm
@@ -738,7 +819,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam
     SALOMEDS::SObject_wrap aSO = PublishHypothesis( hyp );
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = " << this << ".CreateHypothesis('"
+      TPythonDump(this) << aSO << " = " << this << ".CreateHypothesis('"
                     << theHypName << "', '" << theLibName << "')";
     }
   }
@@ -746,6 +827,42 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam
   return hyp._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Return a hypothesis initialized by given average length.
+ *  \param theHypType - hypothesis type name
+ *  \param theLibName - plugin library name
+ *  \param theAverageLength - average length
+ *  \param theQuadDominated - is quad-dominated flag
+ *  \retval SMESH::SMESH_Hypothesis_ptr - the new hypothesis
+ */
+//================================================================================
+
+SMESH::SMESH_Hypothesis_ptr
+SMESH_Gen_i::CreateHypothesisByAverageLength( const char*    theHypType,
+                                              const char*    theLibName,
+                                              CORBA::Double  theAverageLength,
+                                              CORBA::Boolean theQuadDominated)
+{
+  SMESH::HypInitParams initParams = { ::SMESH_Hypothesis::BY_AVERAGE_LENGTH,
+                                      theAverageLength, theQuadDominated };
+
+  SMESH::SMESH_Hypothesis_var hyp =
+    GetHypothesisParameterValues( theHypType, theLibName,
+                                  SMESH::SMESH_Mesh::_nil(),
+                                  GEOM::GEOM_Object::_nil(),
+                                  initParams );
+  SALOMEDS::SObject_wrap so = PublishHypothesis( hyp );
+
+  TPythonDump(this) << hyp << " = " << this << ".CreateHypothesisByAverageLength( '"
+                << theHypType << "', '"
+                << theLibName << "', "
+                << theAverageLength << ", "
+                << theQuadDominated << " )";
+
+  return hyp._retn();
+}
+
 //================================================================================
 /*!
  * \brief Return a hypothesis holding parameter values corresponding either to the mesh
@@ -761,14 +878,15 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam
 //================================================================================
 
 SMESH::SMESH_Hypothesis_ptr
-SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
-                                           const char*           theLibName,
-                                           SMESH::SMESH_Mesh_ptr theMesh,
-                                           GEOM::GEOM_Object_ptr theGeom,
-                                           CORBA::Boolean        byMesh)
-  throw ( SALOME::SALOME_Exception )
+SMESH_Gen_i::GetHypothesisParameterValues( const char*                 theHypType,
+                                           const char*                 theLibName,
+                                           SMESH::SMESH_Mesh_ptr       theMesh,
+                                           GEOM::GEOM_Object_ptr       theGeom,
+                                           const SMESH::HypInitParams& theParams)
 {
   Unexpect aCatch(SALOME_SalomeException);
+
+  const bool byMesh = ( theParams.way == ::SMESH_Hypothesis::BY_MESH );
   if ( byMesh && CORBA::is_nil( theMesh ) )
     return SMESH::SMESH_Hypothesis::_nil();
   if ( byMesh && CORBA::is_nil( theGeom ) )
@@ -823,17 +941,24 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
     if ( hyp->SetParametersByMesh( mesh, shape ))
       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
   }
-  else {
-    double diagonal = 0;
-    if ( mesh )
-      diagonal = mesh->GetShapeDiagonalSize();
-    else
-      diagonal = ::SMESH_Mesh::GetShapeDiagonalSize( shape );
+  else
+  {
     ::SMESH_Hypothesis::TDefaults dflts;
-    dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation();
-    dflts._nbSegments = myGen.GetDefaultNbSegments();
-    dflts._shape      = &shape;
-    // let the temporary hypothesis initialize it's values
+    dflts._way           = ( ::SMESH_Hypothesis::InitWay) theParams.way;
+    dflts._nbSegments    = myGen.GetDefaultNbSegments();
+    dflts._elemLength    = theParams.averageLength;
+    dflts._quadDominated = theParams.quadDominated;
+    if ( theParams.way == ::SMESH_Hypothesis::BY_GEOM )
+    {
+      if ( mesh )
+        dflts._diagonal  = mesh->GetShapeDiagonalSize();
+      else
+        dflts._diagonal  = ::SMESH_Mesh::GetShapeDiagonalSize( shape );
+      dflts._elemLength  = dflts._diagonal / myGen.GetBoundaryBoxSegmentation();
+      dflts._shape       = &shape;
+    }
+
+    // let the hypothesis initialize it's values
     if ( hyp->SetParametersByDefaults( dflts, mesh ))
       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
   }
@@ -941,26 +1066,26 @@ CORBA::Boolean SMESH_Gen_i::GetSoleSubMeshUsingHyp( SMESH::SMESH_Hypothesis_ptr
 
 //=============================================================================
 /*!
- * Sets number of segments per diagonal of boundary box of geometry by which
+ * Set number of segments per diagonal of boundary box of geometry by which
  * default segment length of appropriate 1D hypotheses is defined
  */
 //=============================================================================
 
 void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long theNbSegments )
-  throw ( SALOME::SALOME_Exception )
 {
   if ( theNbSegments > 0 )
     myGen.SetBoundaryBoxSegmentation( int( theNbSegments ));
   else
     THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM );
 }
+
 //=============================================================================
-  /*!
  * \brief Sets default number of segments per edge
  */
+/*!
* \brief Set default number of segments per edge
+ */
 //=============================================================================
+
 void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments)
-  throw ( SALOME::SALOME_Exception )
 {
   if ( theNbSegments > 0 )
     myGen.SetDefaultNbSegments( int(theNbSegments) );
@@ -970,8 +1095,8 @@ void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments)
 
 //=============================================================================
 /*!
-  Set an option value
-*/
* Set an option value
+ */
 //=============================================================================
 
 void SMESH_Gen_i::SetOption(const char* name, const char* value)
@@ -1033,8 +1158,8 @@ void SMESH_Gen_i::SetOption(const char* name, const char* value)
 
 //=============================================================================
 /*!
-  Return an option value
-*/
 Return an option value
+ */
 //=============================================================================
 
 char* SMESH_Gen_i::GetOption(const char* name)
@@ -1066,7 +1191,6 @@ char* SMESH_Gen_i::GetOption(const char* name)
 //=============================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObject )
-     throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
@@ -1085,7 +1209,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = " << this << ".CreateMesh(" << theShapeObject << ")";
+      TPythonDump(this) << aSO << " = " << this << ".CreateMesh(" << theShapeObject << ")";
     }
   }
 
@@ -1101,7 +1225,6 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj
 //=============================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh()
-     throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMesh" );
@@ -1116,7 +1239,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh()
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = " << this << ".CreateEmptyMesh()";
+      TPythonDump(this) << aSO << " = " << this << ".CreateEmptyMesh()";
     }
   }
 
@@ -1127,11 +1250,11 @@ namespace
 {
   //================================================================================
   /*!
-   * \brief Throws an exception in case if the file can't be read
+   * \brief Throw an exception in case if the file can't be read
    */
   //================================================================================
 
-  void checkFileReadable( const char* theFileName ) throw ( SALOME::SALOME_Exception )
+  void checkFileReadable( const char* theFileName )
   {
     SMESH_File f ( theFileName );
     if ( !f )
@@ -1155,7 +1278,6 @@ namespace
 //=============================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
 
@@ -1171,7 +1293,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')";
+      TPythonDump(this) << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')";
     }
   }
 
@@ -1194,17 +1316,17 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
  */
 //=============================================================================
 
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName,
-                                                           SMESH::DriverMED_ReadStatus& theStatus,
-                                                           const char* theCommandNameForPython,
-                                                           const char* theFileNameForPython)
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char*                  theFileName,
+                                                     SMESH::DriverMED_ReadStatus& theStatus )
 {
+  checkFileReadable( theFileName );
+
 #ifdef WIN32
   char bname[ _MAX_FNAME ];
-  _splitpath( theFileNameForPython, NULL, NULL, bname, NULL );
+  _splitpath( theFileName, NULL, NULL, bname, NULL );
   string aFileName = bname;
 #else
-  string aFileName = basename( const_cast<char *>(theFileNameForPython) );
+  string aFileName = basename( const_cast<char *>( theFileName ));
 #endif
   // Retrieve mesh names from the file
   DriverMED_R_SMESHDS_Mesh myReader;
@@ -1217,59 +1339,57 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa
 
   { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
 
-  // Python Dump
-  TPythonDump aPythonDump;
-  aPythonDump << "([";
+    // Python Dump
+    TPythonDump aPythonDump(this);
+    aPythonDump << "([";
 
-  if (theStatus == SMESH::DRS_OK) {
-    SALOMEDS::StudyBuilder_var aStudyBuilder;
-    aStudyBuilder = getStudyServant()->NewBuilder();
-    aStudyBuilder->NewCommand();  // There is a transaction
+    if (theStatus == SMESH::DRS_OK)
+    {
+      SALOMEDS::StudyBuilder_var aStudyBuilder;
+      aStudyBuilder = getStudyServant()->NewBuilder();
+      aStudyBuilder->NewCommand();  // There is a transaction
 
-    aResult->length( aNames.size() );
-    int i = 0;
+      aResult->length( aNames.size() );
+      int i = 0;
 
-    // Iterate through all meshes and create mesh objects
-    for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ )
-    {
-      // Python Dump
-      if (i > 0) aPythonDump << ", ";
-
-      // create mesh
-      SMESH::SMESH_Mesh_var mesh = createMesh();
-
-      // publish mesh in the study
-      SALOMEDS::SObject_wrap aSO;
-      if ( CanPublishInStudy( mesh ) )
-        // little trick: for MED file theFileName and theFileNameForPython are the same, but they are different for SAUV
-        // - as names of meshes are stored in MED file, we use them for data publishing
-        // - as mesh name is not stored in UNV file, we use file name as name of mesh when publishing data
-        aSO = PublishMesh( mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() );
-
-      // Python Dump
-      if ( !aSO->_is_nil() ) {
-        aPythonDump << aSO;
-      } else {
-        aPythonDump << "mesh_" << i;
-      }
+      // Iterate through all meshes and create mesh objects
+      for ( const std::string & meshName : aNames )
+      {
+        // Python Dump
+        if (i > 0) aPythonDump << ", ";
+
+        // create mesh
+        SMESH::SMESH_Mesh_var mesh = createMesh();
+
+        // publish mesh in the study
+        SALOMEDS::SObject_wrap aSO;
+        if ( CanPublishInStudy( mesh ) )
+          aSO = PublishMesh( mesh.in(), meshName.c_str() );
 
-      // Read mesh data (groups are published automatically by ImportMEDFile())
-      SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
-      ASSERT( meshServant );
-      SMESH::DriverMED_ReadStatus status1 =
-        meshServant->ImportMEDFile( theFileName, (*it).c_str() );
-      if (status1 > theStatus)
-        theStatus = status1;
+        // Python Dump
+        if ( !aSO->_is_nil() ) {
+          aPythonDump << aSO;
+        } else {
+          aPythonDump << "mesh_" << i;
+        }
 
-      aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
-      meshServant->GetImpl().GetMeshDS()->Modified();
+        // Read mesh data (groups are published automatically by ImportMEDFile())
+        SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+        ASSERT( meshServant );
+        SMESH::DriverMED_ReadStatus status1 =
+          meshServant->ImportMEDFile( theFileName, meshName.c_str() );
+        if (status1 > theStatus)
+          theStatus = status1;
+
+        aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
+        meshServant->GetImpl().GetMeshDS()->Modified();
+      }
+      if ( !aStudyBuilder->_is_nil() )
+        aStudyBuilder->CommitCommand();
     }
-    if ( !aStudyBuilder->_is_nil() )
-      aStudyBuilder->CommitCommand();
-  }
 
-  // Update Python script
-  aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')";
+    // Update Python script
+    aPythonDump << "], status) = " << this << ".CreateMeshesFromMED( r'" << theFileName << "' )";
   }
   // Dump creation of groups
   for ( CORBA::ULong  i = 0; i < aResult->length(); ++i )
@@ -1278,58 +1398,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa
   return aResult._retn();
 }
 
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
-                                                     SMESH::DriverMED_ReadStatus& theStatus)
-  throw ( SALOME::SALOME_Exception )
-{
-  Unexpect aCatch(SALOME_SalomeException);
-  checkFileReadable( theFileName );
-
-  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, "CreateMeshesFromMED", theFileName);
-  return result;
-}
-
-//=============================================================================
-/*!
- *  SMESH_Gen_i::CreateMeshFromSAUV
- *
- *  Create mesh and import data from SAUV file
- */
-//=============================================================================
-
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName,
-                                                      SMESH::DriverMED_ReadStatus& theStatus)
-     throw ( SALOME::SALOME_Exception )
-{
-  Unexpect aCatch(SALOME_SalomeException);
-  checkFileReadable( theFileName );
-
-  std::string sauvfilename(theFileName);
-  std::string medfilename(theFileName);
-  medfilename += ".med";
-  std::string cmd;
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python3 ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')";
-  cmd += "\"";
-  system(cmd.c_str());
-  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), theStatus, "CreateMeshesFromSAUV", sauvfilename.c_str());
-#ifdef WIN32
-  cmd = "%PYTHONBIN% ";
-#else
-  cmd = "python3 ";
-#endif
-  cmd += "-c \"";
-  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
-  cmd += "\"";
-  system(cmd.c_str());
-  return result;
-}
-
 //=============================================================================
 /*!
  *  SMESH_Gen_i::CreateMeshFromSTL
@@ -1339,7 +1407,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName,
 //=============================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   checkFileReadable( theFileName );
@@ -1361,7 +1428,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')";
+      TPythonDump(this) << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')";
     }
   }
 
@@ -1378,9 +1445,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
  */
 //================================================================================
 
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName,
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char*                  theFileName,
                                                       SMESH::DriverMED_ReadStatus& theStatus)
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   checkFileReadable( theFileName );
@@ -1400,7 +1466,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName,
   { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
 
     // Python Dump
-    TPythonDump aPythonDump;
+    TPythonDump aPythonDump(this);
     aPythonDump << "([";
 
     if (theStatus == SMESH::DRS_OK)
@@ -1468,7 +1534,6 @@ SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::CreateMeshesFromGMF( const char*             theFileName,
                                   CORBA::Boolean          theMakeRequiredGroups,
                                   SMESH::ComputeError_out theError)
-    throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   checkFileReadable( theFileName );
@@ -1489,7 +1554,7 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char*             theFileName,
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'"
+      TPythonDump(this) << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'"
                     << theFileName << "', "
                     << theMakeRequiredGroups << " )";
     }
@@ -1506,13 +1571,12 @@ SMESH_Gen_i::CreateMeshesFromGMF( const char*             theFileName,
 /*!
  *  SMESH_Gen_i::IsReadyToCompute
  *
- *  Returns true if mesh contains enough data to be computed
+ *  Return true if mesh contains enough data to be computed
  */
 //=============================================================================
 
 CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
                                               GEOM::GEOM_Object_ptr theShapeObject )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" );
@@ -1520,11 +1584,9 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
   if ( CORBA::is_nil( theShapeObject ) )
     THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
-
   if ( CORBA::is_nil( theMesh ) )
     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
                                   SALOME::BAD_PARAM );
-
   try {
     // get mesh servant
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
@@ -1552,7 +1614,7 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
 SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
 {
   if ( algo ) {
-  SALOMEDS::Study_var aStudy = getStudyServant();
+    SALOMEDS::Study_var aStudy = getStudyServant();
     if ( !aStudy->_is_nil() ) {
       // find algo in the study
       CORBA::String_var compDataType  = ComponentDataType();
@@ -1589,7 +1651,6 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
 
 SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh,
                                                            GEOM::GEOM_Object_ptr theSubObject )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetComputeErrors()" );
@@ -1664,7 +1725,6 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr
 SMESH::MeshPreviewStruct*
 SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
                                   CORBA::Short          theSubShapeID )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetBadInputElements()" );
@@ -1752,7 +1812,6 @@ SMESH::ListOfGroups*
 SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
                                            CORBA::Short          theSubShapeID,
                                            const char*           theGroupName )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
 
@@ -1765,7 +1824,7 @@ SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
     if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
     {
       groups = meshServant->MakeGroupsOfBadInputElements( theSubShapeID, theGroupName );
-      TPythonDump() << groups << " = " << this
+      TPythonDump(this) << groups << " = " << this
                     << ".MakeGroupsOfBadInputElements( "
                     << theMesh << ", " << theSubShapeID << ", '" << theGroupName << "' )";
     }
@@ -1779,15 +1838,14 @@ SMESH_Gen_i::MakeGroupsOfBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
 //================================================================================
 /*!
  * \brief Returns errors of hypotheses definition
- * \param theMesh - the mesh
- * \param theSubObject - the main or sub- shape
- * \retval SMESH::algo_error_array* - sequence of errors
+ *  \param theMesh - the mesh
+ *  \param theSubObject - the main or sub- shape
+ *  \retval SMESH::algo_error_array* - sequence of errors
  */
 //================================================================================
 
 SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh,
                                                     GEOM::GEOM_Object_ptr theSubObject )
-      throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetAlgoState()" );
@@ -1849,7 +1907,6 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes
 SMESH::long_array*
 SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr      theMainShapeObject,
                              const SMESH::object_array& theListOfSubShapeObject )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetSubShapesId" );
@@ -1923,7 +1980,6 @@ SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr      theMainShapeObject,
 
 CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
                                      GEOM::GEOM_Object_ptr theShapeObject )
-     throw ( SALOME::SALOME_Exception )
 {
   //MEMOSTAT;
   Unexpect aCatch(SALOME_SalomeException);
@@ -1938,7 +1994,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
                                   SALOME::BAD_PARAM );
 
   // Update Python script
-  TPythonDump() << "isDone = " << this << ".Compute( "
+  TPythonDump(this) << "isDone = " << this << ".Compute( "
                 << theMesh << ", " << theShapeObject << ")";
 
   try {
@@ -1946,7 +2002,10 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
     SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
     ASSERT( meshServant );
     if ( meshServant ) {
-      meshServant->Load();
+      if ( isGeomModifIcon( theMesh ))
+        meshServant->Clear();
+      else
+        meshServant->Load();
       // NPAL16168: "geometrical group edition from a submesh don't modify mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
@@ -1970,7 +2029,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
       return ok;
     }
   }
-  catch ( std::bad_alloc ) {
+  catch ( std::bad_alloc& ) {
     INFOS( "Compute(): lack of memory" );
   }
   catch ( SALOME_Exception& S_ex ) {
@@ -1993,14 +2052,16 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
 void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh,
                                  GEOM::GEOM_Object_ptr theShapeObject )
 {
-  SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
-  ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
-  TopoDS_Shape myLocShape;
-  if(theMesh->HasShapeToMesh())
-    myLocShape = GeomObjectToShape( theShapeObject );
-  else
-    myLocShape = SMESH_Mesh::PseudoShape();
-  myGen.CancelCompute( myLocMesh, myLocShape);
+  if ( SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() ))
+  {
+    ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+    TopoDS_Shape myLocShape;
+    if(theMesh->HasShapeToMesh())
+      myLocShape = GeomObjectToShape( theShapeObject );
+    else
+      myLocShape = SMESH_Mesh::PseudoShape();
+    myGen.CancelCompute( myLocMesh, myLocShape);
+  }
 }
 
 //=============================================================================
@@ -2015,7 +2076,6 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
                                                    GEOM::GEOM_Object_ptr theShapeObject,
                                                    SMESH::Dimension      theDimension,
                                                    SMESH::long_array&    theShapesId)
-     throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" );
@@ -2042,7 +2102,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
       if(theMesh->HasShapeToMesh())
         myLocShape = GeomObjectToShape( theShapeObject );
       else
-        return result._retn();;
+        return result._retn();
 
       // call implementation compute
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
@@ -2179,7 +2239,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
       }
     }
   }
-  catch ( std::bad_alloc ) {
+  catch ( std::bad_alloc& ) {
     INFOS( "Precompute(): lack of memory" );
   }
   catch ( SALOME_Exception& S_ex ) {
@@ -2200,30 +2260,26 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
  */
 //=============================================================================
 
-SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
-                                         GEOM::GEOM_Object_ptr theShapeObject)
-//                                     SMESH::long_array& theNbElems)
-     throw ( SALOME::SALOME_Exception )
+SMESH::smIdType_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
+                                             GEOM::GEOM_Object_ptr theShapeObject)
 {
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" );
 
   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
-                                  SALOME::BAD_PARAM );
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
-    THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",
-                                  SALOME::BAD_PARAM );
+    THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM );
 
-  SMESH::long_array_var nbels = new SMESH::long_array;
+  SMESH::smIdType_array_var nbels = new SMESH::smIdType_array;
   nbels->length(SMESH::Entity_Last);
   int i = SMESH::Entity_Node;
   for (; i < SMESH::Entity_Last; i++)
     nbels[i] = 0;
 
   // Update Python script
-  TPythonDump() << "theNbElems = " << this << ".Evaluate( "
+  TPythonDump(this) << "theNbElems = " << this << ".Evaluate( "
                 << theMesh << ", " << theShapeObject << ")";
 
   try {
@@ -2246,9 +2302,9 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
       /*CORBA::Boolean ret =*/ myGen.Evaluate( myLocMesh, myLocShape, aResMap);
       MapShapeNbElemsItr anIt = aResMap.begin();
       for(; anIt!=aResMap.end(); anIt++) {
-        const vector<int>& aVec = (*anIt).second;
+        const vector<smIdType>& aVec = (*anIt).second;
         for ( i = SMESH::Entity_Node; i < (int)aVec.size(); i++ ) {
-          int nbElem = aVec[i];
+          smIdType nbElem = aVec[i];
           if ( nbElem < 0 ) // algo failed, check that it has reported a message
           {
             SMESH_subMesh*            sm = anIt->first;
@@ -2266,7 +2322,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
       return nbels._retn();
     }
   }
-  catch ( std::bad_alloc ) {
+  catch ( std::bad_alloc& ) {
     INFOS( "Evaluate(): lack of memory" );
   }
   catch ( SALOME_Exception& S_ex ) {
@@ -2291,16 +2347,15 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
 
 GEOM::GEOM_Object_ptr
 SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
-                                       CORBA::Long            theElementID,
+                                       SMESH::smIdType        theElementID,
                                        const char*            theGeomName)
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
 
   GEOM::GEOM_Object_wrap geom = FindGeometryByMeshElement(theMesh, theElementID);
   if ( !geom->_is_nil() ) {
     GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
-    GEOM::GEOM_Gen_ptr    geomGen   = GetGeomEngine();
+    GEOM::GEOM_Gen_var    geomGen   = GetGeomEngine( geom );
 
     // try to find the corresponding SObject
     SALOMEDS::SObject_wrap SObj = ObjectToSObject( geom.in() );
@@ -2331,7 +2386,7 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
         }
       }
     }
-    if ( SObj->_is_nil() ) // publish a new subshape
+    if ( SObj->_is_nil() && !geomGen->_is_nil() ) // publish a new subshape
       SObj = geomGen->AddInStudy( geom, theGeomName, mainShape );
 
     // return only published geometry
@@ -2356,15 +2411,14 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
 
 GEOM::GEOM_Object_ptr
 SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
-                                        CORBA::Long            theElementID)
-  throw ( SALOME::SALOME_Exception )
+                                        SMESH::smIdType            theElementID)
 {
   Unexpect aCatch(SALOME_SalomeException);
   if ( CORBA::is_nil( theMesh ) )
     THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference", SALOME::BAD_PARAM );
 
   GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
-  GEOM::GEOM_Gen_ptr    geomGen   = GetGeomEngine();
+  GEOM::GEOM_Gen_var    geomGen   = GetGeomEngine( mainShape );
 
   // get a core mesh DS
   SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
@@ -2387,7 +2441,7 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
           }
           if ( !it->_is_nil() ) {
             for ( it->InitEx(true); it->More(); it->Next() ) {
-              SALOMEDS::SObject_wrap      so = it->Value();
+              SALOMEDS::SObject_wrap     so = it->Value();
               CORBA::Object_var         obj = SObjectToObject( so );
               GEOM::GEOM_Object_var subGeom = GEOM::GEOM_Object::_narrow( obj );
               if ( !subGeom->_is_nil() ) {
@@ -2431,14 +2485,15 @@ SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::Concatenate(const SMESH::ListOfIDSources& theMeshesArray,
                          CORBA::Boolean                theUniteIdenticalGroups,
                          CORBA::Boolean                theMergeNodesAndElements,
-                         CORBA::Double                 theMergeTolerance)
-  throw ( SALOME::SALOME_Exception )
+                         CORBA::Double                 theMergeTolerance,
+                         SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
 {
   return ConcatenateCommon(theMeshesArray,
                            theUniteIdenticalGroups,
                            theMergeNodesAndElements,
                            theMergeTolerance,
-                           false);
+                           false,
+                           theMeshToAppendTo);
 }
 
 //================================================================================
@@ -2454,14 +2509,15 @@ SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::ConcatenateWithGroups(const SMESH::ListOfIDSources& theMeshesArray,
                                    CORBA::Boolean                theUniteIdenticalGroups,
                                    CORBA::Boolean                theMergeNodesAndElements,
-                                   CORBA::Double                 theMergeTolerance)
-  throw ( SALOME::SALOME_Exception )
+                                   CORBA::Double                 theMergeTolerance,
+                                   SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
 {
   return ConcatenateCommon(theMeshesArray,
                            theUniteIdenticalGroups,
                            theMergeNodesAndElements,
                            theMergeTolerance,
-                           true);
+                           true,
+                           theMeshToAppendTo);
 }
 
 //================================================================================
@@ -2477,16 +2533,21 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
                                CORBA::Boolean                theUniteIdenticalGroups,
                                CORBA::Boolean                theMergeNodesAndElements,
                                CORBA::Double                 theMergeTolerance,
-                               CORBA::Boolean                theCommonGroups)
-  throw ( SALOME::SALOME_Exception )
+                               CORBA::Boolean                theCommonGroups,
+                               SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
 {
-  std::unique_ptr< TPythonDump > pPythonDump( new TPythonDump );
+  std::unique_ptr< TPythonDump > pPythonDump( new TPythonDump(this) );
   TPythonDump& pythonDump = *pPythonDump; // prevent dump of called methods
 
-  // create mesh
-  SMESH::SMESH_Mesh_var newMesh = CreateEmptyMesh();
-  SMESH_Mesh_i*         newImpl = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
+  // create mesh if theMeshToAppendTo not provided
+  SMESH::SMESH_Mesh_var newMesh;
+  if ( CORBA::is_nil( theMeshToAppendTo ))
+    newMesh = CreateEmptyMesh();
+  else
+    newMesh = SMESH::SMESH_Mesh::_duplicate( theMeshToAppendTo );
+  SMESH_Mesh_i* newImpl = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
   if ( !newImpl ) return newMesh._retn();
+  newImpl->Load();
 
   ::SMESH_Mesh&   locMesh = newImpl->GetImpl();
   SMESHDS_Mesh* newMeshDS = locMesh.GetMeshDS();
@@ -2497,6 +2558,22 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
   TGroupsMap       groupsMap;
   TListOfNewGroups listOfNewGroups;
 
+  if ( !CORBA::is_nil( theMeshToAppendTo ))
+  {
+    // fill groupsMap with existing groups
+    SMESH::ListOfGroups_var groups = theMeshToAppendTo->GetGroups();
+    for ( CORBA::ULong i = 0; i < groups->length(); ++i )
+    {
+      SMESH::SMESH_Group_var group = SMESH::SMESH_Group::_narrow( groups[ i ]);
+      if ( !group->_is_nil() )
+      {
+        CORBA::String_var  name = group->GetName();
+        SMESH::ElementType type = group->GetType();
+        groupsMap[ TNameAndType( name.in(), type ) ].push_back( group );
+      }
+    }
+  }
+
   ::SMESH_MeshEditor               newEditor( &locMesh );
   ::SMESH_MeshEditor::ElemFeatures elemType;
 
@@ -2507,9 +2584,11 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
     SMESH::SMESH_Mesh_var initMesh = theMeshesArray[i]->GetMesh();
     SMESH_Mesh_i*         initImpl = SMESH::DownCast<SMESH_Mesh_i*>( initMesh );
     if ( !initImpl ) continue;
+    if ( initMesh->_is_equivalent( theMeshToAppendTo ))
+      continue;
     initImpl->Load();
 
-    // assure that IDs increments by one during iteration
+    // assure that IDs increment by one during iteration
     ::SMESH_Mesh& initLocMesh = initImpl->GetImpl();
     SMESHDS_Mesh*  initMeshDS = initLocMesh.GetMeshDS();
     if ( initMeshDS->MaxNodeID()    > initMeshDS->NbNodes() ||
@@ -2520,7 +2599,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
     }
 
     // remember nb of elements before filling in
-    SMESH::long_array_var prevState =  newMesh->GetNbElementsByType();
+    SMESH::smIdType_array_var prevState =  newMesh->GetNbElementsByType();
 
     // copy nodes
 
@@ -2534,6 +2613,9 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
 
     // copy elements
 
+    SMESH::array_of_ElementType_var srcElemTypes = theMeshesArray[i]->GetTypes();
+    if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
+      continue;
     std::vector< const SMDS_MeshElement* > newElems( initMeshDS->NbElements() + 1, 0 );
     elemIt = initImpl->GetElements( theMeshesArray[i], SMESH::ALL );
     while ( elemIt->more() )
@@ -2562,12 +2644,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
     {
       // type names
       const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" };
-      { // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed:
-        const int nbNames = sizeof(typeNames) / sizeof(const char*);
-        int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 2 : -1 ]; _assert[0]=_assert[1]=0;
-      }
 
-      SMESH::long_array_var curState = newMesh->GetNbElementsByType();
+      // check of typeNames: compilation failure mains that NB_ELEMENT_TYPES changed:
+      static_assert( sizeof(typeNames) / sizeof(const char*) ==SMESH::NB_ELEMENT_TYPES,
+                     "Update names of ElementType's!!!" );
+
+      SMESH::smIdType_array_var curState = newMesh->GetNbElementsByType();
 
       for( groupType = SMESH::NODE;
            groupType < SMESH::NB_ELEMENT_TYPES;
@@ -2614,7 +2696,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
 
       SMESH::SMESH_GroupBase_ptr group;
       CORBA::String_var          groupName;
-      SMESH::long_array_var newIDs = new SMESH::long_array();
+      SMESH::smIdType_array_var newIDs = new SMESH::smIdType_array();
 
       // loop on groups of a source mesh
       SMESH::ListOfGroups_var listOfGroups = initImpl->GetGroups();
@@ -2693,11 +2775,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
 
   // Update Python script
   pythonDump << newMesh << " = " << this
-             << "." << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) << "("
+             << "." << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" ) << "( "
              << theMeshesArray << ", "
              << theUniteIdenticalGroups << ", "
              << theMergeNodesAndElements << ", "
-             << TVar( theMergeTolerance ) << ")";
+             << TVar( theMergeTolerance ) << ", "
+             << theMeshToAppendTo << " )";
 
   pPythonDump.reset(); // enable python dump from GetGroups()
 
@@ -2731,11 +2814,10 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
                                             const char*               meshName,
                                             CORBA::Boolean            toCopyGroups,
                                             CORBA::Boolean            toKeepIDs)
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
 
-  TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
+  TPythonDump* pyDump = new TPythonDump(this); // prevent dump from CreateMesh()
   std::unique_ptr<TPythonDump> pyDumpDeleter( pyDump );
 
   // 1. Get source mesh
@@ -2779,7 +2861,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
   }
   else
   {
-    SMESH::long_array_var ids = meshPart->GetIDs();
+    SMESH::smIdType_array_var ids = meshPart->GetIDs();
     if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
     {
       for ( CORBA::ULong i=0; i < ids->length(); i++ )
@@ -2902,8 +2984,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
       {
         TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ];
         if ( e2eMap.empty() ) continue;
-        int minID = e2eMap.begin()->first->GetID();
-        int maxID = e2eMap.rbegin()->first->GetID();
+        smIdType minID = e2eMap.begin()->first->GetID();
+        smIdType maxID = e2eMap.rbegin()->first->GetID();
         TE2EMap::iterator e2e;
         while ( eIt->more() && groupElems.size() < e2eMap.size())
         {
@@ -2952,7 +3034,8 @@ namespace // utils for CopyMeshWithGeom()
 {
   typedef std::map< std::string, std::string >             TStr2StrMap;
   typedef std::map< std::string, std::set< std::string > > TStr2StrSetMap;
-  //typedef std::map< std::set<int>, int >                   TIdSet2IndexMap;
+  typedef std::map< std::set<int>, int >                   TIdSet2IndexMap;
+  typedef std::map< std::string, int >                     TName2IndexMap;
 
   //================================================================================
   /*!
@@ -2970,8 +3053,9 @@ namespace // utils for CopyMeshWithGeom()
 
     TStr2StrMap   myOld2NewEntryMap; // map of study entries
 
-    //GEOM::ListOfGO_var         mySubshapes; // sub-shapes existing in the new geometry
-    //TIdSet2IndexMap            myIds2SubshapeIndex; // to find an existing sub-shape
+    GEOM::ListOfGO_var         mySubshapes; // sub-shapes existing in the new geometry
+    TIdSet2IndexMap            myIds2SubshapeIndex; // to find an existing sub-shape
+    TName2IndexMap             myName2SubshapeIndex; // to find an existing sub-shape by name
 
     bool                       myGIPMapDone;
     GEOM::ListOfListOfLong_var myGIPMap; // filled by GetInPlaceMap()
@@ -3010,16 +3094,18 @@ namespace // utils for CopyMeshWithGeom()
       CORBA::String_var newEntry = newSO->GetID();
       myOld2NewEntryMap.insert( std::make_pair( std::string( oldEntry.in() ),
                                                 std::string( newEntry.in() )));
+      std::string  newMainEntry = newEntry.in();
 
       SALOMEDS::Study_var            study = myGen_i->getStudyServant();
-      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine();
+      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine( mainShapeNew );
       GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
-      GEOM::ListOfGO_var         subShapes = op->GetExistingSubObjects( mainShapeNew,
+      mySubshapes                          = op->GetExistingSubObjects( mainShapeNew,
                                                                         /*groupsOnly=*/false );
-      for ( CORBA::ULong i = 0; i < subShapes->length(); ++i )
+      for ( CORBA::ULong i = 0; i < mySubshapes->length(); ++i )
       {
-        newSO = myGen_i->ObjectToSObject( subShapes[ i ]);
+        newSO = myGen_i->ObjectToSObject( mySubshapes[ i ]);
         SALOMEDS::ChildIterator_wrap anIter = study->NewChildIterator( newSO );
+        bool refFound = false;
         for ( ; anIter->More(); anIter->Next() )
         {
           SALOMEDS::SObject_wrap so = anIter->Value();
@@ -3027,8 +3113,22 @@ namespace // utils for CopyMeshWithGeom()
           {
             oldEntry = oldSO->GetID();
             newEntry = newSO->GetID();
-            myOld2NewEntryMap.insert( std::make_pair( std::string( oldEntry.in() ),
-                                                      std::string( newEntry.in() )));
+            if (( refFound = ( newMainEntry != oldEntry.in() )))
+              myOld2NewEntryMap.insert( std::make_pair( std::string( oldEntry.in() ),
+                                                        std::string( newEntry.in() )));
+          }
+        }
+        if ( !refFound )
+        {
+          GEOM::GEOM_Object_var father = mySubshapes[ i ]->GetMainShape();
+          if ( father->_is_equivalent( mainShapeNew ))
+          {
+            GEOM::ListOfLong_var ids = mySubshapes[ i ]->GetSubShapeIndices();
+            std::set< int > idSet( &ids[0] , &ids[0] + ids->length() );
+            myIds2SubshapeIndex.insert( std::make_pair( idSet, i ));
+            CORBA::String_var name = newSO->GetName();
+            if ( name.in()[0] )
+              myName2SubshapeIndex.insert( std::make_pair( name.in(), i ));
           }
         }
       }
@@ -3052,9 +3152,9 @@ namespace // utils for CopyMeshWithGeom()
         return GEOM::GEOM_Object::_duplicate( oldShape ); // shape independent of the old shape
 
       GEOM::GEOM_Object_var mainShapeNew = myNewMesh_i->GetShapeToMesh();
-      GEOM::GEOM_Gen_var         geomGen = myGen_i->GetGeomEngine();
+      GEOM::GEOM_Gen_var         geomGen = myGen_i->GetGeomEngine( mainShapeNew );
 
-      // try to find by entry
+      // try to find by entry or name
       if ( myToPublish )
       {
         CORBA::String_var  oldEntry = oldShape->GetStudyEntry();
@@ -3063,6 +3163,22 @@ namespace // utils for CopyMeshWithGeom()
         {
           newShape = getShapeByEntry( o2nID->second );
         }
+        if ( newShape->_is_nil() )
+        {
+          CORBA::String_var name = oldShape->GetName();
+          TName2IndexMap::iterator n2ind = myName2SubshapeIndex.find( name.in() );
+          if ( n2ind != myName2SubshapeIndex.end() )
+          {
+            newShape = GEOM::GEOM_Object::_duplicate( mySubshapes[ n2ind->second ]);
+            GEOM::ListOfLong_var oldIndices = oldShape->GetSubShapeIndices();
+            GEOM::ListOfLong_var newIndices = newShape->GetSubShapeIndices();
+            if ( oldIndices->length() == 0 ||
+                 newIndices->length() == 0 ||
+                 getShapeType( myNewMesh_i, newIndices[0] ) !=
+                 getShapeType( mySrcMesh_i, oldIndices[0] ))
+              newShape = GEOM::GEOM_Object::_nil();
+          }
+        }
       }
 
       if ( newShape->_is_nil() )
@@ -3075,32 +3191,45 @@ namespace // utils for CopyMeshWithGeom()
         {
           findNewIDs( oldIndices[i], newIndices );
         }
-        if ( !newIndices.empty() )
+        if ( newIndices.size() < oldIndices->length() ) // issue #17096
         {
-          try
-          {
-            if ( newIndices.size() > 1 || oldShape->GetType() == GEOM_GROUP )
+          newIndices.clear();
+          newShape = getInPlace( oldShape );
+        }
+        if ( !newIndices.empty() && newShape->_is_nil() )
+        {
+          // search for a sub-shape with same ids
+          std::set< int > idSet( newIndices.begin(), newIndices.end() );
+          TIdSet2IndexMap::iterator ids2ind = myIds2SubshapeIndex.find( idSet );
+          if ( ids2ind != myIds2SubshapeIndex.end() ) {
+            newShape = GEOM::GEOM_Object::_duplicate( mySubshapes[ ids2ind->second ]);
+          }
+          if ( newShape->_is_nil() )
+            try
             {
-              int groupType = getShapeType( myNewMesh_i, newIndices[0] );
+              // create a new shape
+              if ( newIndices.size() > 1 || oldShape->GetType() == GEOM_GROUP )
+              {
+                int groupType = getShapeType( myNewMesh_i, newIndices[0] );
 
-              GEOM::GEOM_IGroupOperations_wrap grOp = geomGen->GetIGroupOperations();
-              newShape = grOp->CreateGroup( mainShapeNew, groupType );
+                GEOM::GEOM_IGroupOperations_wrap grOp = geomGen->GetIGroupOperations();
+                newShape = grOp->CreateGroup( mainShapeNew, groupType );
 
-              GEOM::ListOfLong_var  newIndicesList = new GEOM::ListOfLong();
-              newIndicesList->length( newIndices.size() );
-              for ( size_t i = 0; i < newIndices.size(); ++i )
-                newIndicesList[ i ] = newIndices[ i ];
-              grOp->UnionIDs( newShape, newIndicesList );
+                GEOM::ListOfLong_var  newIndicesList = new GEOM::ListOfLong();
+                newIndicesList->length( newIndices.size() );
+                for ( size_t i = 0; i < newIndices.size(); ++i )
+                  newIndicesList[ i ] = newIndices[ i ];
+                grOp->UnionIDs( newShape, newIndicesList );
+              }
+              else
+              {
+                GEOM::GEOM_IShapesOperations_wrap shOp = geomGen->GetIShapesOperations();
+                newShape = shOp->GetSubShape( mainShapeNew, newIndices[0] );
+              }
             }
-            else
+            catch (...)
             {
-              GEOM::GEOM_IShapesOperations_wrap shOp = geomGen->GetIShapesOperations();
-              newShape = shOp->GetSubShape( mainShapeNew, newIndices[0] );
             }
-          }
-          catch (...)
-          {
-          }
         }
       }
 
@@ -3245,7 +3374,7 @@ namespace // utils for CopyMeshWithGeom()
 
         GEOM::GEOM_Object_var   mainShapeNew = myNewMesh_i->GetShapeToMesh();
         GEOM::GEOM_Object_var   mainShapeOld = mySrcMesh_i->GetShapeToMesh();
-        GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine();
+        GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine( mainShapeNew );
         GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
         try
         {
@@ -3258,6 +3387,27 @@ namespace // utils for CopyMeshWithGeom()
       }
     }
 
+    //================================================================================
+    /*!
+     * \brief Get new sub-shape by calling GetInPlace()
+     */
+    GEOM::GEOM_Object_ptr getInPlace( GEOM::GEOM_Object_ptr oldShape )
+    {
+      GEOM::GEOM_Object_var newShape;
+
+      GEOM::GEOM_Object_var   mainShapeNew = myNewMesh_i->GetShapeToMesh();
+      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine( mainShapeNew );
+      GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
+      try
+      {
+        newShape = op->GetInPlace( mainShapeNew, oldShape );
+      }
+      catch( ... )
+      {
+      }
+      return newShape._retn();
+    }
+
     //================================================================================
     /*!
      * \brief Find a new sub-shape indices by an old one in myGIPMap. Return
@@ -3422,7 +3572,7 @@ namespace // utils for CopyMeshWithGeom()
  *  \param [out] invalidEntries - return study entries of objects whose
  *         counterparts are not found in the newGeometry, followed by entries
  *         of mesh sub-objects that are invalid because they depend on a not found
- *         preceeding sub-shape
+ *         preceding sub-shape
  *  \return CORBA::Boolean - is a success
  */
 //================================================================================
@@ -3438,7 +3588,6 @@ CORBA::Boolean SMESH_Gen_i::CopyMeshWithGeom( SMESH::SMESH_Mesh_ptr       theSou
                                               SMESH::submesh_array_out    theNewSubmeshes,
                                               SMESH::ListOfHypothesis_out theNewHypotheses,
                                               SMESH::string_array_out     theInvalidEntries)
-throw ( SALOME::SALOME_Exception )
 {
   if ( CORBA::is_nil( theSourceMesh ) ||
        CORBA::is_nil( theNewGeometry ))
@@ -3450,7 +3599,7 @@ throw ( SALOME::SALOME_Exception )
   bool ok = true;
   SMESH_TRY;
 
-  TPythonDump pyDump; // prevent dump from CreateMesh()
+  TPythonDump pyDump(this); // prevent dump from CreateMesh()
 
   theNewMesh        = CreateMesh( theNewGeometry );
   theNewGroups      = new SMESH::ListOfGroups();
@@ -3667,7 +3816,7 @@ throw ( SALOME::SALOME_Exception )
     {
       if ( newMeshDS->GetMeshInfo().NbElements( SMDSAbs_ElementType( elemType )) > 0 )
       {
-        SMESH::long_array_var elemIDs = stdlGroup->GetIDs();
+        SMESH::smIdType_array_var elemIDs = stdlGroup->GetIDs();
         const bool isElem = ( elemType != SMESH::NODE );
         CORBA::ULong iE = 0;
         for ( ; iE < elemIDs->length(); ++iE ) // check if any element has been copied
@@ -3863,6 +4012,7 @@ char* SMESH_Gen_i::GetMEDFileVersion()
  *  Get MED version of the file by its name
  */
 //================================================================================
+
 char* SMESH_Gen_i::GetMEDVersion(const char* theFileName)
 {
   std::string version = MED::GetMEDVersion( theFileName );
@@ -3876,6 +4026,7 @@ char* SMESH_Gen_i::GetMEDVersion(const char* theFileName)
  *  Check compatibility of file with MED format being used, read only.
  */
 //================================================================================
+
 CORBA::Boolean SMESH_Gen_i::CheckCompatibility(const char* theFileName)
 {
   return MED::CheckCompatibility( theFileName );
@@ -3888,6 +4039,7 @@ CORBA::Boolean SMESH_Gen_i::CheckCompatibility(const char* theFileName)
  *  Check compatibility of file with MED format being used, for append on write.
  */
 //================================================================================
+
 CORBA::Boolean SMESH_Gen_i::CheckWriteCompatibility(const char* theFileName)
 {
   return MED::CheckCompatibility( theFileName, true );
@@ -3901,13 +4053,12 @@ CORBA::Boolean SMESH_Gen_i::CheckWriteCompatibility(const char* theFileName)
  */
 //================================================================================
 SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName)
+
 {
-  //MESSAGE("GetMeshNames " << theFileName);
   SMESH::string_array_var aResult = new SMESH::string_array();
   MED::PWrapper aMed = MED::CrWrapperR( theFileName );
   MED::TErr anErr;
   MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr );
-  //MESSAGE("---" << aNbMeshes);
   if( anErr >= 0 ) {
     aResult->length( aNbMeshes );
     for( MED::TInt i = 0; i < aNbMeshes; i++ ) {
@@ -3925,10 +4076,14 @@ SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName)
  *  Save SMESH module's data
  */
 //=============================================================================
+
 SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                                       const char*              theURL,
                                       bool                     isMultiFile )
 {
+  // localizing
+  Kernel_Utils::Localizer loc;
+
   if (!myStudyContext)
     UpdateStudy();
 
@@ -3982,11 +4137,15 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   cmd+="\" \"";
   cmd+=meshfile;
   cmd+="\"";
+#ifdef WIN32
+  cmd+=" 2>NUL";
+#endif
   system(cmd.ToCString());
 
   // MED writer to be used by storage process
-  DriverMED_W_SMESHDS_Mesh myWriter;
-  myWriter.SetFile( meshfile.ToCString() );
+  DriverMED_W_SMESHDS_Mesh writer;
+  writer.SetFile( meshfile.ToCString() );
+  //writer.SetSaveNumbers( false ); // bos #24400 -- it leads to change of element IDs
 
   // IMP issue 20918
   // SetStoreName() to groups before storing hypotheses to let them refer to
@@ -4001,7 +4160,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
           SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
           if ( !myMesh->_is_nil() ) {
             myMesh->Load(); // load from study file if not yet done
-            TPythonDump pd; // not to dump GetGroups()
+            TPythonDump pd(this); // not to dump GetGroups()
             SMESH::ListOfGroups_var groups = myMesh->GetGroups();
             for ( CORBA::ULong i = 0; i < groups->length(); ++i )
             {
@@ -4011,7 +4170,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                 CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() );
                 int anId = myStudyContext->findId( string( objStr.in() ) );
                 char grpName[ 30 ];
-                sprintf( grpName, "Group %d", anId );
+                sprintf( grpName, "Group %d %d", anId, grImpl->GetLocalID() );
                 SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS();
                 aGrpBaseDS->SetStoreName( grpName );
               }
@@ -4061,8 +4220,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
 #else
               // PAL17753 (Regression: missing hypothesis in restored study)
               // "lib" also should be removed from the beginning
-              //if( libname_len > 3 )
-              //libname.resize( libname_len - 3 );
               if( libname_len > 6 )
                 libname = libname.substr( 3, libname_len - 3 - 3 );
 #endif
@@ -4131,8 +4288,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
 #else
               // PAL17753 (Regression: missing hypothesis in restored study)
               // "lib" also should be removed from the beginning
-              //if( libname_len > 3 )
-              //libname.resize( libname_len - 3 );
               if( libname_len > 6 )
                 libname = libname.substr( 3, libname_len - 3 - 3 );
 #endif
@@ -4197,8 +4352,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             // check if the mesh is not empty
             if ( mySMESHDSMesh->NbNodes() > 0 ) {
               // write mesh data to med file
-              myWriter.SetMesh( mySMESHDSMesh );
-              myWriter.SetMeshId( id );
+              writer.SetMesh( mySMESHDSMesh );
+              writer.SetMeshId( id );
               strHasData = "1";
             }
             aSize[ 0 ] = strHasData.length() + 1;
@@ -4235,10 +4390,18 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             aDataset->WriteOnDisk( &meshPersistentId );
             aDataset->CloseOnDisk();
 
+            // Store SMESH_Mesh_i::_mainShapeTick
+            int shapeTick = myImpl->MainShapeTick();
+            aSize[ 0 ] = 1;
+            aDataset = new HDFdataset( "shapeTick", aTopGroup, HDF_INT32, aSize, 1 );
+            aDataset->CreateOnDisk();
+            aDataset->WriteOnDisk( &shapeTick );
+            aDataset->CloseOnDisk();
+
             // write reference on a shape if exists
             SALOMEDS::SObject_wrap myRef;
             bool shapeRefFound = false;
-            bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef.inout() );
+            bool found = gotBranch->FindSubObject( (CORBA::Long)GetRefOnShapeTag(), myRef.inout() );
             if ( found ) {
               SALOMEDS::SObject_wrap myShape;
               bool ok = myRef->ReferencedObject( myShape.inout() );
@@ -4269,7 +4432,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
 
             // write applied hypotheses if exist
             SALOMEDS::SObject_wrap myHypBranch;
-            found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch.inout() );
+            found = gotBranch->FindSubObject( (CORBA::Long)GetRefOnAppliedHypothesisTag(), myHypBranch.inout() );
             if ( found && !shapeRefFound && hasShape ) { // remove applied hyps
               aStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch );
             }
@@ -4528,14 +4691,11 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                 aGroup->CloseOnDisk();
               }
             }
-            // All sub-meshes will be stored in MED file
-            // .. will NOT (PAL 12992)
-            //if ( shapeRefFound )
-            //myWriter.AddAllSubMeshes();
 
             // store submesh order if any
             const TListOfListOfInt& theOrderIds = myLocMesh.GetMeshOrder();
-            if ( theOrderIds.size() ) {
+            const bool isNewOrederVersion = true; // old version saves ids, new one, entries
+            if ( !theOrderIds.empty() && !isNewOrederVersion ) { // keep old version for reference
               char order_list[ 30 ];
               strcpy( order_list, "Mesh Order" );
               // count number of submesh ids
@@ -4566,6 +4726,38 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
               //
               delete[] smIDs;
             }
+            if ( !theOrderIds.empty() && isNewOrederVersion )
+            {
+              // convert ids to entries
+              std::list< std::list< std::string > > orderEntryLists;
+              for ( const TListOfInt& idList : theOrderIds )
+              {
+                orderEntryLists.emplace_back();
+                std::list< std::string > & entryList = orderEntryLists.back();
+                for ( const int& id : idList )
+                {
+                  const TopoDS_Shape& shape = mySMESHDSMesh->IndexToShape( id );
+                  GEOM::GEOM_Object_var  go = ShapeToGeomObject( shape );
+                  SALOMEDS::SObject_var  so = ObjectToSObject( go );
+                  if ( !so->_is_nil() )
+                  {
+                    CORBA::String_var entry = so->GetID();
+                    entryList.emplace_back( entry.in() );
+                  }
+                }
+              }
+              // convert orderEntryLists to string
+              std::ostringstream ostream;
+              boost::archive::text_oarchive( ostream ) << orderEntryLists;
+              std::string orderEntryString = ostream.str();
+
+              // write HDF group
+              aSize[ 0 ] = orderEntryString.size() + 1;
+              aDataset = new HDFdataset( "MeshOrder_new", aTopGroup, HDF_STRING, aSize, 1 );
+              aDataset->CreateOnDisk();
+              aDataset->WriteOnDisk((char*) orderEntryString.data() );
+              aDataset->CloseOnDisk();
+            }
 
             // groups root sub-branch
             SALOMEDS::SObject_wrap myGroupsBranch;
@@ -4635,7 +4827,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     // Pass SMESHDS_Group to MED writer
                     SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
                     if ( aGrpDS )
-                      myWriter.AddGroup( aGrpDS );
+                      writer.AddGroup( aGrpDS );
 
                     // write reference on a shape if exists
                     SMESHDS_GroupOnGeom* aGeomGrp =
@@ -4660,7 +4852,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                       else // shape ref is invalid:
                       {
                         // save a group on geometry as ordinary group
-                        myWriter.AddGroup( aGeomGrp );
+                        writer.AddGroup( aGeomGrp );
                       }
                     }
                     else if ( SMESH_GroupOnFilter_i* aFilterGrp_i =
@@ -4683,7 +4875,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             if ( strcmp( strHasData.c_str(), "1" ) == 0 )
             {
               // Flush current mesh information into MED file
-              myWriter.Perform();
+              writer.Perform();
 
               // save info on nb of elements
               SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile );
@@ -4710,7 +4902,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                 {
                   SMDS_ElemIteratorPtr eIt =
                     mySMESHDSMesh->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
-                  int nbElems = isNode ? mySMESHDSMesh->NbNodes() : mySMESHDSMesh->GetMeshInfo().NbElements();
+                  smIdType nbElems = isNode ? mySMESHDSMesh->NbNodes() : mySMESHDSMesh->GetMeshInfo().NbElements();
                   if ( nbElems < 1 )
                     continue;
                   std::vector<int> smIDs; smIDs.reserve( nbElems );
@@ -4751,7 +4943,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   SMESHDS_SubMesh* aSubMesh = const_cast< SMESHDS_SubMesh* >( smIt->next() );
                   if ( aSubMesh->IsComplexSubmesh() )
                     continue; // submesh containing other submeshs
-                  int nbNodes = aSubMesh->NbNodes();
+                  smIdType nbNodes = aSubMesh->NbNodes();
                   if ( nbNodes == 0 ) continue;
 
                   int aShapeID = aSubMesh->GetID();
@@ -4910,23 +5102,6 @@ SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent
   return anAsciiStreamFile._retn();
 }
 
-//=============================================================================
-/*!
- *  SMESH_Gen_i::loadGeomData
- *
- *  Load GEOM module data
- */
-//=============================================================================
-
-void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot )
-{
-  if ( theCompRoot->_is_nil() )
-    return;
-
-  SALOMEDS::StudyBuilder_var aStudyBuilder = getStudyServant()->NewBuilder();
-  aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() );
-}
-
 //=============================================================================
 /*!
  *  SMESH_Gen_i::Load
@@ -4940,14 +5115,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                         const char*              theURL,
                         bool                     isMultiFile )
 {
-  //if (!myStudyContext)
-    UpdateStudy();
+  UpdateStudy(); // load geom data
+  Kernel_Utils::Localizer loc;
+
   SALOMEDS::Study_var aStudy = getStudyServant();
-  /*  if( !theComponent->_is_nil() )
-      {
-      if( !aStudy->FindComponent( "GEOM" )->_is_nil() )
-      loadGeomData( aStudy->FindComponent( "GEOM" ) );
-      }*/
 
   // Get temporary files location
   TCollection_AsciiString tmpDir =
@@ -4960,7 +5131,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   TCollection_AsciiString aStudyName( "" );
   if ( isMultiFile ) {
     CORBA::WString_var url = aStudy->URL();
-    aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( Kernel_Utils::encode(url.in()) ).c_str();
+    SMESHUtils::ArrayDeleter<const char> urlMulibyte( Kernel_Utils::encode( url.in()) );
+    aStudyName = (char*)SALOMEDS_Tool::GetNameFromPath( urlMulibyte.get() ).c_str();
   }
   // Set names of temporary files
   TCollection_AsciiString filename = tmpDir + aStudyName + "_SMESH.hdf";
@@ -4985,10 +5157,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     return false;
   }
 
-  TPythonDump pd; // prevent dump during loading
-
-  // DriverMED_R_SMESHDS_Mesh myReader;
-  // myReader.SetFile( meshfile.ToCString() );
+  TPythonDump pd(this); // prevent dump during loading
 
   // For PAL13473 ("Repetitive mesh") implementation.
   // New dependencies between SMESH objects are established:
@@ -5184,6 +5353,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             try { // protect persistence mechanism against exceptions
               myHyp = this->createHypothesis( hypname.c_str(), libname.c_str() );
             }
+            catch( SALOME::SALOME_Exception& ex )
+            {
+              INFOS( "Exception during hypothesis creation: " << ex.details.text );
+            }
             catch (...) {
               INFOS( "Exception during hypothesis creation" );
             }
@@ -5265,11 +5438,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             aDataset->CloseOnDisk();
             if ( strlen( refFromFile ) > 0 ) {
               SALOMEDS::SObject_wrap shapeSO = aStudy->FindObjectID( refFromFile );
-
-              // Make sure GEOM data are loaded first
-              //loadGeomData( shapeSO->GetFatherComponent() );
-
-              CORBA::Object_var shapeObject = SObjectToObject( shapeSO );
+              CORBA::Object_var  shapeObject = SObjectToObject( shapeSO );
               if ( !CORBA::is_nil( shapeObject ) ) {
                 aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject );
                 if ( !aShapeObject->_is_nil() )
@@ -5280,7 +5449,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           }
 
           // issue 20918. Restore Persistent Id of SMESHDS_Mesh
-          if( aTopGroup->ExistInternalObject( "meshPersistentId" ) )
+          if ( aTopGroup->ExistInternalObject( "meshPersistentId" ) )
           {
             aDataset = new HDFdataset( "meshPersistentId", aTopGroup );
             aDataset->OpenOnDisk();
@@ -5292,6 +5461,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             delete [] meshPersistentId;
           }
 
+          // Restore SMESH_Mesh_i::_mainShapeTick
+          if ( aTopGroup->ExistInternalObject( "shapeTick" ))
+          {
+            aDataset = new HDFdataset( "shapeTick", aTopGroup );
+            aDataset->OpenOnDisk();
+            int* shapeTick = & myNewMeshImpl->MainShapeTick();
+            aDataset->ReadFromDisk( shapeTick );
+            aDataset->CloseOnDisk();
+          }
+
           // Restore file info
           if ( aTopGroup->ExistInternalObject( "file info" ))
           {
@@ -5307,7 +5486,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       }
     } // reading MESHes
 
-    // As all object that can be referred by hypothesis are created,
+    // As all objects that can be referred by hypothesis are created,
     // we can restore hypothesis data
 
     list< pair< SMESH_Hypothesis_i*, string > >::iterator hyp_data;
@@ -5325,8 +5504,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     {
       aTopGroup                   = meshi_group->second;
       SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
-      //::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
-      //SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
 
       GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh();
       bool hasData = false;
@@ -5334,7 +5511,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       // get mesh old id
       CORBA::String_var iorString = GetORB()->object_to_string( myNewMeshImpl->_this() );
       int newId = myStudyContext->findId( iorString.in() );
-      int id = myStudyContext->getOldId( newId );
+      int meshOldId = myStudyContext->getOldId( newId );
 
       // try to find mesh data dataset
       if ( aTopGroup->ExistInternalObject( "Has data" ) ) {
@@ -5346,10 +5523,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aDataset->ReadFromDisk( strHasData );
         aDataset->CloseOnDisk();
         if ( strcmp( strHasData, "1") == 0 ) {
-          // read mesh data from MED file
-          // myReader.SetMesh( mySMESHDSMesh );
-          // myReader.SetMeshId( id );
-          // myReader.Perform();
           hasData = true;
         }
         delete [] strHasData;
@@ -5375,8 +5548,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             aDataset->ReadFromDisk( refFromFile );
             aDataset->CloseOnDisk();
             // san - it is impossible to recover applied algorithms using their entries within Load() method
-            //SALOMEDS::SObject_wrap hypSO = aStudy->FindObjectID( refFromFile );
-            //CORBA::Object_var hypObject = SObjectToObject( hypSO );
             int id = atoi( refFromFile );
             delete [] refFromFile;
             string anIOR = myStudyContext->getIORbyOldId( id );
@@ -5412,8 +5583,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             aDataset->ReadFromDisk( refFromFile );
             aDataset->CloseOnDisk();
             // san - it is impossible to recover applied hypotheses using their entries within Load() method
-            //SALOMEDS::SObject_wrap hypSO = myStudy->FindObjectID( refFromFile );
-            //CORBA::Object_var hypObject = SObjectToObject( hypSO );
             int id = atoi( refFromFile );
             delete [] refFromFile;
             string anIOR = myStudyContext->getIORbyOldId( id );
@@ -5493,7 +5662,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                     if ( aSubMesh->_is_nil() )
                       continue;
                     string iorSubString = GetORB()->object_to_string( aSubMesh );
-                    int newSubId = myStudyContext->findId( iorSubString );
+                    int        newSubId = myStudyContext->findId( iorSubString );
                     myStudyContext->mapOldToNew( subid, newSubId );
                   }
                 }
@@ -5616,9 +5785,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             // check if it is a group
             if ( name_dataset.substr( 0, 5 ) == "Group" ) {
               // --> get group id
-              int subid = atoi( name_dataset.substr( 5 ).c_str() );
+              char * endptr;
+              int subid = strtol( name_dataset.data() + 5, &endptr, 10 );
               if ( subid <= 0 )
                 continue;
+              int groupID = -1; // group local ID (also persistent)
+              if ( *endptr )
+                groupID = atoi( endptr + 1 );
               aDataset = new HDFdataset( name_dataset.c_str(), aGroup );
               aDataset->OpenOnDisk();
 
@@ -5675,13 +5848,14 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               // Create group servant
               SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1);
               SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate
-                ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) );
+                ( myNewMeshImpl->createGroup( type, nameFromFile, groupID, aShape, predicate ) );
               delete [] nameFromFile;
               // Obtain a SMESHDS_Group object
               if ( aNewGroup->_is_nil() )
                 continue;
 
-              string iorSubString = GetORB()->object_to_string( aNewGroup );
+              CORBA::String_var iorSubStringVar = GetORB()->object_to_string( aNewGroup );
+              string iorSubString(iorSubStringVar.in());
               int        newSubId = myStudyContext->findId( iorSubString );
               myStudyContext->mapOldToNew( subid, newSubId );
 
@@ -5724,16 +5898,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       } // reading GROUPs
 
       // instead of reading mesh data, we read only brief information of all
-      // objects: mesh, groups, sub-meshes (issue 0021208 )
+      // objects: mesh, groups, sub-meshes (issue 0021208)
       if ( hasData )
       {
-        SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id,
+        SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, meshOldId,
                                          meshfile.ToCString(), filename.ToCString(),
                                          !isMultiFile );
       }
 
       // read Sub-Mesh ORDER if any
-      if ( aTopGroup->ExistInternalObject( "Mesh Order" )) {
+      if ( aTopGroup->ExistInternalObject( "Mesh Order" )) { // old version keeps ids
         aDataset = new HDFdataset( "Mesh Order", aTopGroup );
         aDataset->OpenOnDisk();
         size = aDataset->GetSize();
@@ -5751,6 +5925,32 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
         delete [] smIDs;
       }
+      if ( aTopGroup->ExistInternalObject( "MeshOrder_new" )) // new version keeps entries
+      {
+        aDataset = new HDFdataset( "MeshOrder_new", aTopGroup );
+        aDataset->OpenOnDisk();
+        size = aDataset->GetSize();
+        std::string dataString; dataString.resize( size );
+        aDataset->ReadFromDisk((char*) dataString.data() );
+        aDataset->CloseOnDisk();
+
+        std::list< std::list< std::string > > orderEntryLists;
+        SMESHUtils::BoostTxtArchive( dataString ) >> orderEntryLists;
+
+        TListOfListOfInt anOrderIds;
+        for ( const std::list< std::string >& entryList : orderEntryLists )
+        {
+          anOrderIds.emplace_back();
+          for ( const std::string & entry : entryList )
+          {
+            GEOM::GEOM_Object_var go = GetGeomObjectByEntry( entry );
+            TopoDS_Shape       shape = GeomObjectToShape( go );
+            if ( SMESH_subMesh*   sm = myNewMeshImpl->GetImpl().GetSubMesh( shape ))
+              anOrderIds.back().emplace_back( sm->GetId() );
+          }
+        }
+        myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
+      }
     } // loop on meshes
 
     // update hyps needing full mesh data restored (issue 20918)
@@ -5810,7 +6010,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       }
     }
   }
-  pd << ""; // prevent optimizing pd out
 
   // creation of tree nodes for all data objects in the study
   // to support tree representation customization and drag-n-drop:
@@ -5976,11 +6175,12 @@ int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject)
  */
 //================================================================================
 
-CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject)
+CORBA::Long  SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject)
 {
   if ( myStudyContext && !CORBA::is_nil( theObject )) {
-    string iorString = GetORB()->object_to_string( theObject );
-    return myStudyContext->findId( iorString );
+    CORBA::String_var iorString = GetORB()->object_to_string( theObject );
+    string iorStringCpp(iorString.in()); 
+    return myStudyContext->findId( iorStringCpp );
   }
   return 0;
 }
@@ -5992,6 +6192,7 @@ CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject)
  *  Set a new object name
  */
 //=============================================================================
+
 void SMESH_Gen_i::SetName(const char* theIOR,
                           const char* theName)
 {
@@ -6019,6 +6220,7 @@ char* SMESH_Gen_i::getVersion()
 // purpose  : Moves objects to the specified position.
 //            Is used in the drag-n-drop functionality.
 //=================================================================================
+
 void SMESH_Gen_i::Move( const SMESH::sobject_list& what,
                         SALOMEDS::SObject_ptr      where,
                         CORBA::Long                row )
@@ -6072,13 +6274,13 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   SMESH_TRY;
 
   std::string aPlatformLibName;
-  typedef GenericHypothesisCreator_i* (*GetHypothesisCreator)(const char*);
   GenericHypothesisCreator_i* aCreator =
     getHypothesisCreator(theAlgoType, theLibName, aPlatformLibName);
   if (aCreator)
   {
     TopoDS_Shape shape = GeomObjectToShape( theGeomObject );
-    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll );
+    const SMESH_Algo::Features& feat = SMESH_Algo::GetFeatures( theAlgoType );
+    return shape.IsNull() || aCreator->IsApplicable( shape, toCheckAll, feat._dim );
   }
   else
   {
@@ -6093,10 +6295,12 @@ CORBA::Boolean SMESH_Gen_i::IsApplicable ( const char*           theAlgoType,
   return true;
 }
 
-//=================================================================================
-// function : GetInsideSphere
-// purpose  : Collect indices of elements, which are located inside the sphere
-//=================================================================================
+//================================================================================
+/*!
+ * \brief Collect indices of elements, which are located inside the sphere
+ */
+//================================================================================
+
 SMESH::long_array* SMESH_Gen_i::GetInsideSphere( SMESH::SMESH_IDSource_ptr meshPart,
                                                  SMESH::ElementType     theElemType,
                                                  CORBA::Double         theX,
@@ -6123,6 +6327,12 @@ SMESH::long_array* SMESH_Gen_i::GetInsideSphere( SMESH::SMESH_IDSource_ptr meshP
   return aResult._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Collect indices of elements, which are located inside the box
+ */
+//================================================================================
+
 SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart,
                                               SMESH::ElementType        theElemType,
                                               CORBA::Double             theX1,
@@ -6130,12 +6340,14 @@ SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart
                                               CORBA::Double             theZ1,
                                               CORBA::Double             theX2,
                                               CORBA::Double             theY2,
-                                              CORBA::Double             theZ2) {
+                                              CORBA::Double             theZ2)
+{
   SMESH::long_array_var aResult = new SMESH::long_array();
   if( meshPart->_is_nil() )
     return aResult._retn();
 
-  TopoDS_Shape aShape = BRepPrimAPI_MakeBox( gp_Pnt( theX1, theY1, theZ1 ), gp_Pnt( theX2, theY2, theZ2 ) ).Shape();
+  TopoDS_Shape aShape = BRepPrimAPI_MakeBox( gp_Pnt( theX1, theY1, theZ1 ),
+                                             gp_Pnt( theX2, theY2, theZ2 ) ).Shape();
 
   std::vector<long> lst =_GetInside(meshPart, theElemType, aShape);
 
@@ -6148,6 +6360,12 @@ SMESH::long_array* SMESH_Gen_i::GetInsideBox( SMESH::SMESH_IDSource_ptr meshPart
   return aResult._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Collect indices of elements, which are located inside the cylinder
+ */
+//================================================================================
+
 SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr meshPart,
                                                    SMESH::ElementType        theElemType,
                                                    CORBA::Double             theX,
@@ -6157,7 +6375,8 @@ SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr mes
                                                    CORBA::Double             theDY,
                                                    CORBA::Double             theDZ,
                                                    CORBA::Double             theH,
-                                                   CORBA::Double             theR ){
+                                                   CORBA::Double             theR )
+{
   SMESH::long_array_var aResult = new SMESH::long_array();
   if( meshPart->_is_nil() )
     return aResult._retn();
@@ -6179,10 +6398,17 @@ SMESH::long_array* SMESH_Gen_i::GetInsideCylinder( SMESH::SMESH_IDSource_ptr mes
   return aResult._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Collect indices of elements, which are located inside the geom object
+ */
+//================================================================================
+
 SMESH::long_array* SMESH_Gen_i::GetInside( SMESH::SMESH_IDSource_ptr meshPart,
                                            SMESH::ElementType        theElemType,
                                            GEOM::GEOM_Object_ptr     theGeom,
-                                           CORBA::Double             theTolerance ) {
+                                           CORBA::Double             theTolerance )
+{
   SMESH::long_array_var aResult = new SMESH::long_array();
   if( meshPart->_is_nil() || theGeom->_is_nil() )
     return aResult._retn();
@@ -6200,12 +6426,16 @@ SMESH::long_array* SMESH_Gen_i::GetInside( SMESH::SMESH_IDSource_ptr meshPart,
   return aResult._retn();
 }
 
-
+//================================================================================
+/*!
+ * \brief Collect indices of elements, which are located inside the TopoDS_Shape
+ */
+//================================================================================
 
 std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
-                                           SMESH::ElementType theElemType,
-                                           TopoDS_Shape& aShape,
-                                           double* theTolerance) {
+                                           SMESH::ElementType        theElemType,
+                                           const TopoDS_Shape&       theShape,
+                                           double*                   theTolerance) {
 
   std::vector<long> res;
   SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
@@ -6226,7 +6456,7 @@ std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
   SMESH::Controls::ElementsOnShape* anElementsOnShape = new SMESH::Controls::ElementsOnShape();
   anElementsOnShape->SetAllNodes( true );
   anElementsOnShape->SetMesh( meshDS );
-  anElementsOnShape->SetShape( aShape, aType );
+  anElementsOnShape->SetShape( theShape, aType );
 
   if(theTolerance)
     anElementsOnShape->SetTolerance(*theTolerance);
@@ -6246,7 +6476,7 @@ std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
   SMESH::SMESH_Group_var gsource = SMESH::SMESH_Group::_narrow(meshPart);
   if ( !gsource->_is_nil() ) {
     if(theElemType == SMESH::NODE) {
-      SMESH::long_array_var nodes = gsource->GetNodeIDs();
+      SMESH::smIdType_array_var nodes = gsource->GetNodeIDs();
       for ( CORBA::ULong i = 0; i < nodes->length(); ++i ) {
         if ( const SMDS_MeshNode* node = meshDS->FindNode( nodes[i] )) {
           long anId = node->GetID();
@@ -6255,7 +6485,7 @@ std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
         }
       }
     } else if (gsource->GetType() == theElemType || theElemType == SMESH::ALL ) {
-      SMESH::long_array_var elems = gsource->GetListOfID();
+      SMESH::smIdType_array_var elems = gsource->GetListOfID();
       for ( CORBA::ULong i = 0; i < elems->length(); ++i ) {
         if ( const SMDS_MeshElement* elem = meshDS->FindElement( elems[i] )) {
           long anId = elem->GetID();
@@ -6267,7 +6497,7 @@ std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
   }
   SMESH::SMESH_subMesh_var smsource = SMESH::SMESH_subMesh::_narrow(meshPart);
   if ( !smsource->_is_nil() ) {
-    SMESH::long_array_var elems = smsource->GetElementsByType( theElemType );
+    SMESH::smIdType_array_var elems = smsource->GetElementsByType( theElemType );
     for ( CORBA::ULong i = 0; i < elems->length(); ++i ) {
       const SMDS_MeshElement* elem = ( theElemType == SMESH::NODE ) ? meshDS->FindNode( elems[i] ) : meshDS->FindElement( elems[i] );
       if (elem) {
@@ -6279,27 +6509,3 @@ std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
   }
   return res;
 }
-
-
-//=============================================================================
-/*!
- *  SMESHEngine_factory
- *
- *  C factory, accessible with dlsym, after dlopen
- */
-//=============================================================================
-
-extern "C"
-{ SMESH_I_EXPORT
-  PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr            orb,
-                                                 PortableServer::POA_ptr   poa,
-                                                 PortableServer::ObjectId* contId,
-                                                 const char*               instanceName,
-                                                 const char*               interfaceName )
-  {
-    if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" );
-    if(MYDEBUG) SCRUTE(interfaceName);
-    SMESH_Gen_i* aSMESHGen = new SMESH_Gen_i(orb, poa, contId, instanceName, interfaceName);
-    return aSMESHGen->getId() ;
-  }
-}