Salome HOME
bos #26523 EDF 24234 - Viscous Layer
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index f01646e74344c93f9c3762746765d622f5f793ae..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 "SMESH_TryCatch.hxx" // to include after OCC headers!
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 
+#include <GEOMImpl_Types.hxx>
 #include <GEOM_Client.hxx>
 
 #include <Basics_Utils.hxx>
 #include <sstream>
 #include <cstdio>
 #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;
@@ -152,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;
@@ -180,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;
   }
 }
@@ -228,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 ]
@@ -236,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() );
@@ -253,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 ]
@@ -268,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;
 }
 
 //=============================================================================
@@ -304,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);
@@ -330,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() );
+      }
     }
   }
 }
@@ -381,6 +400,7 @@ SMESH_Gen_i::~SMESH_Gen_i()
   if ( myShapeReader )
     delete myShapeReader;
 }
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::getHypothesisCreator
@@ -388,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 */
@@ -439,15 +459,27 @@ GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHyp
     {
       // load plugin library
       if(MYDEBUG) MESSAGE("Loading server meshers plugin library ...");
-      LibHandle libHandle = LoadLib( aPlatformLibName.c_str() );
+#ifdef WIN32
+#  ifdef UNICODE
+      const wchar_t* path = Kernel_Utils::decode_s(aPlatformLibName);
+      SMESHUtils::ArrayDeleter<const wchar_t> deleter( path );
+#  else
+      const char* path = aPlatformLibName.c_str();
+#  endif
+#else
+      const char* path = aPlatformLibName.c_str();
+#endif
+      LibHandle libHandle = LoadLib( path );
+
       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
       }
 
@@ -457,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);
       }
 
@@ -466,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;
@@ -491,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)
 {
@@ -512,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();
 }
@@ -524,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" );
@@ -542,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) {
@@ -558,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
@@ -574,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 );
 }
 
 //=============================================================================
@@ -635,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;
@@ -667,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();
@@ -688,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
@@ -695,6 +793,7 @@ void SMESH_Gen_i::UpdateStudy()
  *  Get study context
  */
 //=============================================================================
+
 StudyContext* SMESH_Gen_i::GetStudyContext()
 {
   return myStudyContext;
@@ -704,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
@@ -721,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 << "')";
     }
   }
@@ -729,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
@@ -744,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 ) )
@@ -806,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 );
   }
@@ -924,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) );
@@ -953,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)
@@ -1016,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)
@@ -1049,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" );
@@ -1068,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 << ")";
     }
   }
 
@@ -1084,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" );
@@ -1099,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()";
     }
   }
 
@@ -1110,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 )
@@ -1138,7 +1278,6 @@ namespace
 //=============================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
 
@@ -1154,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 << "')";
     }
   }
 
@@ -1177,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;
@@ -1200,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();
 
-      // 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;
+        // publish mesh in the study
+        SALOMEDS::SObject_wrap aSO;
+        if ( CanPublishInStudy( mesh ) )
+          aSO = PublishMesh( mesh.in(), meshName.c_str() );
+
+        // Python Dump
+        if ( !aSO->_is_nil() ) {
+          aPythonDump << aSO;
+        } else {
+          aPythonDump << "mesh_" << i;
+        }
+
+        // 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();
+        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 )
@@ -1261,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
@@ -1322,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 );
@@ -1344,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 << "')";
     }
   }
 
@@ -1361,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 );
@@ -1383,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)
@@ -1451,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 );
@@ -1472,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 << " )";
     }
@@ -1489,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" );
@@ -1503,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() );
@@ -1535,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();
@@ -1572,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()" );
@@ -1647,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()" );
@@ -1735,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);
 
@@ -1748,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 << "' )";
     }
@@ -1762,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()" );
@@ -1832,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" );
@@ -1906,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);
@@ -1921,15 +1994,18 @@ 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 {
     // get mesh servant
-    SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+    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
@@ -1948,10 +2024,12 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
       meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
       myLocMesh.GetMeshDS()->Modified();
       UpdateIcons( theMesh );
+      if ( ok )
+        HighLightInvalid( theMesh, /*isInvalid=*/false );
       return ok;
     }
   }
-  catch ( std::bad_alloc ) {
+  catch ( std::bad_alloc& ) {
     INFOS( "Compute(): lack of memory" );
   }
   catch ( SALOME_Exception& S_ex ) {
@@ -1974,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);
+  }
 }
 
 //=============================================================================
@@ -1996,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" );
@@ -2023,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();
@@ -2160,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 ) {
@@ -2181,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 {
@@ -2227,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;
@@ -2247,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 ) {
@@ -2272,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() );
@@ -2312,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
@@ -2337,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 );
@@ -2368,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() ) {
@@ -2412,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);
 }
 
 //================================================================================
@@ -2435,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);
 }
 
 //================================================================================
@@ -2458,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();
@@ -2478,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;
 
@@ -2488,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() ||
@@ -2501,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
 
@@ -2515,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() )
@@ -2543,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;
@@ -2595,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();
@@ -2674,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()
 
@@ -2715,7 +2817,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
 {
   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
 
@@ -2758,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++ )
@@ -2881,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())
         {
@@ -2918,7 +3021,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
           << toCopyGroups << ", "
           << toKeepIDs << ")";
 
-  delete pyDump; pyDump = 0; // allow dump in GetGroups()
+  pyDumpDeleter.reset(); // allow dump in GetGroups()
 
   if ( nbNewGroups > 0 ) // dump created groups
     SMESH::ListOfGroups_var groups = newMesh->GetGroups();
@@ -2926,59 +3029,1035 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
   return newMesh._retn();
 }
 
-//================================================================================
-/*!
- * \brief Get version of MED format being used.
- */
-//================================================================================
 
-char* SMESH_Gen_i::GetMEDFileVersion()
+namespace // utils for CopyMeshWithGeom()
 {
-  MED::TInt majeur, mineur, release;
-  majeur =  mineur = release = 0;
-  MED::GetVersionRelease(majeur, mineur, release);
-  std::ostringstream version;
-  version << majeur << "." << mineur << "." << release;
-  return CORBA::string_dup( version.str().c_str() );
-}
+  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::string, int >                     TName2IndexMap;
 
-//================================================================================
-/*!
- *  SMESH_Gen_i::GetMEDVersion
- *
- *  Get MED version of the file by its name
- */
-//================================================================================
-char* SMESH_Gen_i::GetMEDVersion(const char* theFileName)
-{
-  std::string version = MED::GetMEDVersion( theFileName );
-  return CORBA::string_dup( version.c_str() );
-}
+  //================================================================================
+  /*!
+   * \brief Return a new sub-shape corresponding to an old one
+   */
+  //================================================================================
 
-//================================================================================
-/*!
- *  SMESH_Gen_i::CheckCompatibility
- *
- *  Check compatibility of file with MED format being used.
- */
-//================================================================================
-CORBA::Boolean SMESH_Gen_i::CheckCompatibility(const char* theFileName)
-{
-  return MED::CheckCompatibility( theFileName );
-}
+  struct ShapeMapper
+  {
+    SMESH_Mesh_i* mySrcMesh_i;
+    SMESH_Mesh_i* myNewMesh_i;
+    SMESH_Gen_i*  myGen_i;
+    bool          myToPublish;
+    bool          myIsSameGeom;
+
+    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
+    TName2IndexMap             myName2SubshapeIndex; // to find an existing sub-shape by name
+
+    bool                       myGIPMapDone;
+    GEOM::ListOfListOfLong_var myGIPMap; // filled by GetInPlaceMap()
+
+    // not directly relating to shape search
+    TStr2StrSetMap myInvalidMap; // blame shape -> invalid objects
+
+    //================================================================================
+    /*!
+     * \brief Constructor
+     */
+    ShapeMapper( SMESH_Mesh_i* srcMesh_i,
+                 SMESH_Mesh_i* newMesh_i,
+                 SMESH_Gen_i*  smeshGen_i )
+      : mySrcMesh_i( srcMesh_i ),
+        myNewMesh_i( newMesh_i ),
+        myGen_i    ( smeshGen_i ),
+        myToPublish( smeshGen_i->IsEnablePublish() ),
+        myGIPMapDone( false )
+    {
+      // retrieve from the study shape mapping made thanks to
+      // "Set presentation parameters and sub-shapes from arguments" option
+
+      GEOM::GEOM_Object_var mainShapeNew = myNewMesh_i->GetShapeToMesh();
+      GEOM::GEOM_Object_var mainShapeOld = mySrcMesh_i->GetShapeToMesh();
+      SALOMEDS::SObject_wrap oldSO = myGen_i->ObjectToSObject( mainShapeOld );
+      SALOMEDS::SObject_wrap newSO = myGen_i->ObjectToSObject( mainShapeNew );
+      if ( newSO->_is_nil() )
+      {
+        myToPublish = false;
+        return;
+      }
+      if (( myIsSameGeom = mainShapeNew->_is_equivalent( mainShapeOld )))
+        return;
+      CORBA::String_var oldEntry = oldSO->GetID();
+      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( mainShapeNew );
+      GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
+      mySubshapes                          = op->GetExistingSubObjects( mainShapeNew,
+                                                                        /*groupsOnly=*/false );
+      for ( CORBA::ULong i = 0; i < mySubshapes->length(); ++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();
+          if ( so->ReferencedObject( oldSO.inout() ))
+          {
+            oldEntry = oldSO->GetID();
+            newEntry = newSO->GetID();
+            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 ));
+          }
+        }
+      }
+    }
 
-//================================================================================
-/*!
- *  SMESH_Gen_i::GetMeshNames
- *
- *  Get names of meshes defined in file with the specified name
- */
-//================================================================================
-SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName)
-{
-  SMESH::string_array_var aResult = new SMESH::string_array();
-  MED::PWrapper aMed = MED::CrWrapperR( theFileName );
-  MED::TErr anErr;
+    //================================================================================
+    /*!
+     * \brief Find a new sub-shape corresponding to an old one
+     */
+    GEOM::GEOM_Object_ptr FindNew( GEOM::GEOM_Object_ptr oldShape )
+    {
+      if ( myIsSameGeom )
+        return GEOM::GEOM_Object::_duplicate( oldShape );
+
+      GEOM::GEOM_Object_var newShape;
+
+      if ( CORBA::is_nil( oldShape ))
+        return newShape._retn();
+
+      if ( !isChildOfOld( oldShape ))
+        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( mainShapeNew );
+
+      // try to find by entry or name
+      if ( myToPublish )
+      {
+        CORBA::String_var  oldEntry = oldShape->GetStudyEntry();
+        TStr2StrMap::iterator o2nID = myOld2NewEntryMap.find( oldEntry.in() );
+        if ( o2nID != myOld2NewEntryMap.end() )
+        {
+          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() )
+      {
+        // try to construct a new sub-shape using myGIPMap
+        buildGIPMap();
+        std::vector< int >   newIndices;
+        GEOM::ListOfLong_var oldIndices = oldShape->GetSubShapeIndices();
+        for ( CORBA::ULong i = 0; i < oldIndices->length(); ++i )
+        {
+          findNewIDs( oldIndices[i], newIndices );
+        }
+        if ( newIndices.size() < oldIndices->length() ) // issue #17096
+        {
+          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
+            {
+              // 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::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] );
+              }
+            }
+            catch (...)
+            {
+            }
+        }
+      }
+
+      if ( !newShape->_is_nil() && myToPublish )
+      {
+        CORBA::String_var oldEntry, newEntry = newShape->GetStudyEntry();
+        if ( !newEntry.in() || !newEntry.in()[0] )
+        {
+          CORBA::String_var    name = oldShape->GetName();
+          SALOMEDS::SObject_wrap so = geomGen->AddInStudy( newShape, name, mainShapeNew );
+          newEntry = newShape->GetStudyEntry();
+          oldEntry = oldShape->GetStudyEntry();
+          myOld2NewEntryMap.insert( std::make_pair( std::string( oldEntry.in() ),
+                                                    std::string( newEntry.in() )));
+        }
+      }
+
+      return newShape._retn();
+    }
+
+    //================================================================================
+    /*!
+     * \brief Return a study entry of a new shape by study entry of the old one
+     */
+    std::string FindNew( const std::string & oldEntry )
+    {
+      if ( myIsSameGeom )
+        return oldEntry;
+
+      TStr2StrMap::iterator o2nID = myOld2NewEntryMap.find( oldEntry );
+      if ( o2nID != myOld2NewEntryMap.end() )
+        return o2nID->second;
+
+      GEOM::GEOM_Object_var oldShape = getShapeByEntry( oldEntry );
+      if ( oldShape->_is_nil() || !isChildOfOld( oldShape ))
+        return oldEntry;
+
+      GEOM::GEOM_Object_ptr newShape = FindNew( oldShape );
+      if ( newShape->_is_nil() )
+        return std::string();
+
+      CORBA::String_var newEntry = newShape->GetStudyEntry();
+      return newEntry.in();
+    }
+
+    //================================================================================
+    /*!
+     * \brief Return a sub-shape ID of a new shape by a sub-shape ID of the old one.
+     *        Return zero if not found or there are more than one new ID
+     */
+    int FindNew( int oldID )
+    {
+      if ( myIsSameGeom )
+        return oldID;
+
+      buildGIPMap();
+
+      int newID = 0;
+
+      if ( 0 < oldID && oldID < (int)myGIPMap->length() )
+      {
+        if ( myGIPMap[ oldID ].length() == 1 )
+        {
+          newID = myGIPMap[ oldID ][ 0 ];
+        }
+        else if ( myGIPMap[ oldID ].length() > 1 &&
+                  getShapeType( mySrcMesh_i, oldID ) == TopAbs_VERTEX )
+        {
+          // select a meshed VERTEX
+          SMESH_subMesh* newSM;
+          for ( CORBA::ULong i = 0; i < myGIPMap[ oldID ].length() && !newID; ++i )
+            if (( newSM = myNewMesh_i->GetImpl().GetSubMeshContaining( myGIPMap[ oldID ][ i ] )) &&
+                ( !newSM->IsEmpty() ))
+              newID = myGIPMap[ oldID ][ i ];
+        }
+      }
+      return newID;
+    }
+
+    //================================================================================
+    /*!
+     * \brief Return a sub-shape ID of a new shape by an old sub-mesh.
+     *        Return zero if the old shape is not kept as is in the new shape.
+     */
+    int FindNewNotChanged( SMESH_subMesh* oldSM )
+    {
+      if ( myIsSameGeom )
+        return oldSM->GetId();
+
+      int newID = FindNew( oldSM->GetId() );
+      if ( !newID )
+        return 0;
+
+      SMESH_subMesh* newSM = myNewMesh_i->GetImpl().GetSubMeshContaining( newID );
+      if ( !newSM )
+        return 0;
+
+      // consider a sub-shape as not changed if all its sub-shapes are mapped into
+      // one new sub-shape of the same type.
+
+      if ( oldSM->DependsOn().size() !=
+           newSM->DependsOn().size() )
+        return 0;
+
+      SMESH_subMeshIteratorPtr srcSMIt = oldSM->getDependsOnIterator( /*includeSelf=*/true );
+      while ( srcSMIt->more() )
+      {
+        oldSM = srcSMIt->next();
+        int newSubID = FindNew( oldSM->GetId() );
+        if ( getShapeType( myNewMesh_i, newSubID ) !=
+             getShapeType( mySrcMesh_i, oldSM->GetId() ))
+          return 0;
+      }
+      return newID;
+    }
+
+    //================================================================================
+    /*!
+     * \brief Return shape by study entry
+     */
+    GEOM::GEOM_Object_ptr getShapeByEntry( const std::string & entry )
+    {
+      GEOM::GEOM_Object_var shape;
+      SALOMEDS::SObject_wrap so = myGen_i->getStudyServant()->FindObjectID( entry.c_str() );
+      if ( !so->_is_nil() )
+      {
+        CORBA::Object_var obj = so->GetObject();
+        shape = GEOM::GEOM_Object::_narrow( obj );
+      }
+      return shape._retn();
+    }
+
+    //================================================================================
+    /*!
+     * \brief Fill myGIPMap by calling GetInPlaceMap()
+     */
+    void buildGIPMap()
+    {
+      if ( !myGIPMapDone )
+      {
+        myGIPMapDone = true;
+
+        GEOM::GEOM_Object_var   mainShapeNew = myNewMesh_i->GetShapeToMesh();
+        GEOM::GEOM_Object_var   mainShapeOld = mySrcMesh_i->GetShapeToMesh();
+        GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine( mainShapeNew );
+        GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
+        try
+        {
+          myGIPMap = op->GetInPlaceMap( mainShapeNew, mainShapeOld );
+        }
+        catch( ... )
+        {
+          myGIPMap = new GEOM::ListOfListOfLong();
+        }
+      }
+    }
+
+    //================================================================================
+    /*!
+     * \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
+     *        number of found IDs
+     */
+    int findNewIDs( int oldID, std::vector< int >& newIDs  )
+    {
+      size_t prevNbIDs = newIDs.size();
+
+      if ( 0 < oldID && oldID < (int) myGIPMap->length() )
+      {
+        for ( CORBA::ULong i = 0; i < myGIPMap[ oldID ].length(); ++i )
+          newIDs.push_back( myGIPMap[ oldID ][ i ]);
+      }
+      return newIDs.size() - prevNbIDs;
+    }
+
+    //================================================================================
+    /*!
+     * \brief Check if an object relates to the old shape
+     */
+    bool isChildOfOld( GEOM::GEOM_Object_ptr oldShape )
+    {
+      if ( CORBA::is_nil( oldShape ))
+        return false;
+      GEOM::GEOM_Object_var mainShapeOld1 = mySrcMesh_i->GetShapeToMesh();
+      GEOM::GEOM_Object_var mainShapeOld2 = oldShape->GetMainShape();
+      return ( mainShapeOld1->_is_equivalent( mainShapeOld2 ) ||
+               mainShapeOld1->_is_equivalent( oldShape ));
+    }
+
+    //================================================================================
+    /*!
+     * \brief Return shape type by shape ID
+     */
+    TopAbs_ShapeEnum getShapeType( SMESH_Mesh_i* mesh_i, int shapeID )
+    {
+      SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
+      const TopoDS_Shape& shape = meshDS->IndexToShape( shapeID );
+      return shape.IsNull() ? TopAbs_SHAPE : shape.ShapeType();
+    }
+
+    //================================================================================
+    /*!
+     * \brief Store a source sub-shape for which a counterpart not found and
+     *        a smesh object invalid due to that
+     */
+    void AddInvalid( GEOM::GEOM_Object_var  srcShape,
+                     SALOMEDS::SObject_wrap smeshSO )
+    {
+      CORBA::String_var geomEntry = srcShape->GetStudyEntry();
+      if ( geomEntry.in()[0] && !smeshSO->_is_nil() )
+      {
+        CORBA::String_var smeshEntry = smeshSO->GetID();
+        myInvalidMap[ geomEntry.in() ].insert( smeshEntry.in() );
+      }
+    }
+
+    //================================================================================
+    /*!
+     * \brief Store a source sub-shape for which a counterpart not found and
+     *        a smesh object invalid due to that
+     */
+    void AddInvalid( std::string            geomEntry,
+                     SALOMEDS::SObject_wrap smeshSO )
+    {
+      if ( !geomEntry.empty() )
+      {
+        CORBA::String_var smeshEntry = smeshSO->GetID();
+        myInvalidMap[ geomEntry ].insert( smeshEntry.in() );
+      }
+    }
+
+    //================================================================================
+    /*!
+     * \brief Store a source sub-shape for which a counterpart not found and
+     *        a smesh object invalid due to that
+     */
+    void AddInvalid( int                    oldGeomID,
+                     SALOMEDS::SObject_wrap smeshSO )
+    {
+      int shapeType = getShapeType( mySrcMesh_i, oldGeomID );
+      if ( shapeType < 0 || shapeType > TopAbs_SHAPE )
+        return;
+
+      const char* typeName[] = { "COMPOUND","COMPSOLID","SOLID","SHELL",
+                                 "FACE","WIRE","EDGE","VERTEX","SHAPE" };
+
+      SMESH_Comment geomName( typeName[ shapeType ]);
+      geomName << " #" << oldGeomID;
+
+      CORBA::String_var smeshEntry = smeshSO->GetID();
+      myInvalidMap[ geomName ].insert( smeshEntry.in() );
+    }
+
+    //================================================================================
+    /*!
+     * \brief Return entries of a source sub-shape for which a counterpart not found and
+     *        of smesh objects invalid due to that
+     */
+    void GetInvalid( SMESH::string_array_out &               theInvalidEntries,
+                     std::vector< SALOMEDS::SObject_wrap > & theInvalidMeshSObjects)
+    {
+      int nbSO = 0;
+      TStr2StrSetMap::iterator entry2entrySet = myInvalidMap.begin();
+      for ( ; entry2entrySet != myInvalidMap.end(); ++entry2entrySet )
+      {
+        nbSO += 1 + entry2entrySet->second.size();
+      }
+      int iSO = theInvalidMeshSObjects.size(), iEntry = 0;
+      theInvalidEntries->length  ( nbSO );
+      theInvalidMeshSObjects.resize( theInvalidMeshSObjects.size() + nbSO - myInvalidMap.size() );
+
+      entry2entrySet = myInvalidMap.begin();
+      for ( ; entry2entrySet != myInvalidMap.end(); ++entry2entrySet )
+      {
+        theInvalidEntries[ iEntry++ ] = entry2entrySet->first.c_str();
+
+        std::set< std::string > & entrySet = entry2entrySet->second;
+        std::set< std::string >::iterator entry = entrySet.begin();
+        for ( ; entry != entrySet.end(); ++entry )
+        {
+          theInvalidEntries[ iEntry++ ] = entry->c_str();
+
+          SALOMEDS::SObject_wrap so = myGen_i->getStudyServant()->FindObjectID( entry->c_str() );
+          if ( !so->_is_nil() )
+            theInvalidMeshSObjects[ iSO++ ] = so;
+        }
+      }
+    }
+
+  }; // struct ShapeMapper
+
+  //================================================================================
+  /*!
+   * \brief Append an item to a CORBA sequence
+   */
+  template < class CORBA_seq, class ITEM >
+  void append( CORBA_seq& seq, ITEM item )
+  {
+    if ( !CORBA::is_nil( item ))
+    {
+      seq->length( 1 + seq->length() );
+      seq[ seq->length() - 1 ] = item;
+    }
+  }
+} // namespace // utils for CopyMeshWithGeom()
+
+//================================================================================
+/*!
+ * \brief Create a mesh by copying definitions of another mesh to a given geometry
+ *  \param [in] sourceMesh - a mesh to copy
+ *  \param [in] newGeometry - a new geometry
+ *  \param [in] toCopyGroups - to create groups in the new mesh
+ *  \param [in] toReuseHypotheses - if True, existing hypothesis will be used by the new mesh,
+ *         otherwise new hypotheses with the same parameters will be created for the new mesh.
+ *  \param [in] toCopyElements - to copy mesh elements of same sub-shapes of the two geometries
+ *  \param [out] newMesh - return a new mesh
+ *  \param [out] newGroups - return new groups
+ *  \param [out] newSubmeshes - return new sub-meshes
+ *  \param [out] newHypotheses - return new algorithms and hypotheses
+ *  \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
+ *         preceding sub-shape
+ *  \return CORBA::Boolean - is a success
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Gen_i::CopyMeshWithGeom( SMESH::SMESH_Mesh_ptr       theSourceMesh,
+                                              GEOM::GEOM_Object_ptr       theNewGeometry,
+                                              const char*                 theMeshName,
+                                              CORBA::Boolean              theToCopyGroups,
+                                              CORBA::Boolean              theToReuseHypotheses,
+                                              CORBA::Boolean              theToCopyElements,
+                                              SMESH::SMESH_Mesh_out       theNewMesh,
+                                              SMESH::ListOfGroups_out     theNewGroups,
+                                              SMESH::submesh_array_out    theNewSubmeshes,
+                                              SMESH::ListOfHypothesis_out theNewHypotheses,
+                                              SMESH::string_array_out     theInvalidEntries)
+{
+  if ( CORBA::is_nil( theSourceMesh ) ||
+       CORBA::is_nil( theNewGeometry ))
+    THROW_SALOME_CORBA_EXCEPTION( "NULL arguments", SALOME::BAD_PARAM );
+
+  if ( !theSourceMesh->HasShapeToMesh() )
+    THROW_SALOME_CORBA_EXCEPTION( "Source mesh not on geometry", SALOME::BAD_PARAM );
+
+  bool ok = true;
+  SMESH_TRY;
+
+  TPythonDump pyDump(this); // prevent dump from CreateMesh()
+
+  theNewMesh        = CreateMesh( theNewGeometry );
+  theNewGroups      = new SMESH::ListOfGroups();
+  theNewSubmeshes   = new SMESH::submesh_array();
+  theNewHypotheses  = new SMESH::ListOfHypothesis();
+  theInvalidEntries = new SMESH::string_array();
+
+  std::vector< SALOMEDS::SObject_wrap > invalidSObjects;
+
+  GEOM::GEOM_Object_var srcGeom = theSourceMesh->GetShapeToMesh();
+  GEOM::GEOM_Object_var geom, newGeom;
+  SALOMEDS::SObject_wrap so;
+
+  SMESH_Mesh_i* srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theSourceMesh );
+  SMESH_Mesh_i* newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theNewMesh );
+  srcMesh_i->Load();
+
+  ShapeMapper shapeMapper( srcMesh_i, newMesh_i, this );
+
+  // treat hypotheses of mesh and sub-meshes
+  SMESH::submesh_array_var smList = theSourceMesh->GetSubMeshes();
+  for ( CORBA::ULong iSM = 0; iSM <= smList->length(); ++iSM )
+  {
+    bool isSubMesh = ( iSM < smList->length() );
+    if ( isSubMesh )
+    {
+      // create a new sub-mesh
+      SMESH::SMESH_subMesh_var newSM;
+      geom = smList[iSM]->GetSubShape();
+      so   = ObjectToSObject( smList[iSM] );
+      CORBA::String_var name;
+      if ( !so->_is_nil() )
+        name = so->GetName();
+      newGeom = shapeMapper.FindNew( geom );
+      if ( newGeom->_is_nil() )
+      {
+        newSM = createInvalidSubMesh( theNewMesh, geom, name.in() );
+        shapeMapper.AddInvalid( geom, ObjectToSObject( newSM ));
+        ok = false;
+      }
+      else
+      {
+        newSM = theNewMesh->GetSubMesh( newGeom, name.in() );
+      }
+      append( theNewSubmeshes, newSM );
+
+      if ( newGeom->_is_nil() )
+        continue; // don't assign hypotheses
+    }
+    else
+    {
+      newGeom = GEOM::GEOM_Object::_duplicate( theNewGeometry );
+      geom    = srcGeom;
+      so      = ObjectToSObject( theNewMesh );
+      SetName( so, theMeshName, "Mesh" );
+    }
+
+    // assign hypotheses
+    SMESH::ListOfHypothesis_var hypList = theSourceMesh->GetHypothesisList( geom );
+    for ( CORBA::ULong iHyp = 0; iHyp < hypList->length(); ++iHyp )
+    {
+      SMESH::SMESH_Hypothesis_var hyp = hypList[ iHyp ];
+      SMESH_Hypothesis_i*       hyp_i = SMESH::DownCast< SMESH_Hypothesis_i* >( hyp );
+
+      // get geometry hyp depends on
+      std::vector< std::string > entryArray;
+      std::vector< int >         subIDArray;
+      bool dependsOnGeom = hyp_i->getObjectsDependOn( entryArray, subIDArray );
+
+      if ( !theToReuseHypotheses || dependsOnGeom )
+      {
+        // create a new hypothesis
+        CORBA::String_var type = hyp->GetName();
+        CORBA::String_var lib  = hyp->GetLibName();
+        CORBA::String_var data = hyp_i->SaveTo();
+        if ( data.in()[0] )
+        {
+          hyp   = CreateHypothesis( type, lib );
+          hyp_i = SMESH::DownCast< SMESH_Hypothesis_i* >( hyp );
+          hyp_i->LoadFrom( data.in() );
+          append( theNewHypotheses, hyp );
+        }
+      }
+
+      // update geometry hyp depends on
+      if ( dependsOnGeom )
+      {
+        for ( size_t iGeo = 0; iGeo < entryArray.size(); ++iGeo )
+        {
+          if ( !entryArray[ iGeo ].empty() )
+          {
+            std::string newEntry = shapeMapper.FindNew( entryArray[ iGeo ]);
+            if ( newEntry.empty() )
+            {
+              ok = false;
+              shapeMapper.AddInvalid( entryArray[ iGeo ], ObjectToSObject( hyp ));
+              shapeMapper.AddInvalid( entryArray[ iGeo ], so ); // sub-mesh
+            }
+            entryArray[ iGeo ] = newEntry;
+          }
+        }
+        for ( size_t iGeo = 0; iGeo < subIDArray.size(); ++iGeo )
+        {
+          if ( subIDArray[ iGeo ] > 0 )
+          {
+            int newID = shapeMapper.FindNew( subIDArray[ iGeo ]);
+            if ( newID < 1 )
+            {
+              ok = false;
+              shapeMapper.AddInvalid( subIDArray[ iGeo ], ObjectToSObject( hyp ));
+              shapeMapper.AddInvalid( subIDArray[ iGeo ], so ); // sub-mesh
+            }
+            subIDArray[ iGeo ] = newID;
+          }
+        }
+        if ( !hyp_i->setObjectsDependOn( entryArray, subIDArray ))
+          ok = false;
+      }
+
+      CORBA::String_var errorText;
+      theNewMesh->AddHypothesis( newGeom, hyp, errorText.out() );
+      if ( errorText.in()[0] )
+        ok = false;
+
+    } // loop on hypotheses
+  } // loop on sub-meshes and mesh
+
+
+  // copy mesh elements, keeping IDs
+  SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
+  if ( theToCopyElements && theSourceMesh->NbNodes() > 0 )
+  {
+    ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+    ::SMESH_MeshEditor::ElemFeatures elemData;
+
+    SMESH_subMesh*         srcMainSM = srcMesh_i->GetImpl().GetSubMeshContaining( 1 );
+    SMESH_subMeshIteratorPtr srcSMIt = srcMainSM->getDependsOnIterator( /*includeSelf=*/true,
+                                                                        /*vertexLast=*/false);
+    while ( srcSMIt->more() )
+    {
+      SMESH_subMesh* srcSM = srcSMIt->next();
+      if ( srcSM->IsEmpty() )
+        continue; // not yet computed
+      int newID = shapeMapper.FindNewNotChanged( srcSM );
+      if ( newID < 1 )
+        continue;
+
+      SMESHDS_SubMesh* srcSMDS = srcSM->GetSubMeshDS();
+      SMDS_NodeIteratorPtr nIt = srcSMDS->GetNodes();
+      while ( nIt->more() )
+      {
+        SMESH_NodeXYZ node( nIt->next() );
+        const SMDS_MeshNode* newNode = newMeshDS->AddNodeWithID( node.X(), node.Y(), node.Z(),
+                                                                 node->GetID() );
+        const SMDS_PositionPtr pos = node->GetPosition();
+        const double*           uv = pos->GetParameters();
+        switch ( pos->GetTypeOfPosition() )
+        {
+        case SMDS_TOP_3DSPACE: newMeshDS->SetNodeInVolume( newNode, newID );               break;
+        case SMDS_TOP_FACE:    newMeshDS->SetNodeOnFace  ( newNode, newID, uv[0], uv[1] ); break;
+        case SMDS_TOP_EDGE:    newMeshDS->SetNodeOnEdge  ( newNode, newID, uv[0] );        break;
+        case SMDS_TOP_VERTEX:  newMeshDS->SetNodeOnVertex( newNode, newID );               break;
+        default: ;
+        }
+      }
+      SMDS_ElemIteratorPtr eIt = srcSMDS->GetElements();
+      while( eIt->more() )
+      {
+        const SMDS_MeshElement* e = eIt->next();
+        elemData.Init( e, /*basicOnly=*/false );
+        elemData.SetID( e->GetID() );
+        elemData.myNodes.resize( e->NbNodes() );
+        SMDS_NodeIteratorPtr nnIt = e->nodeIterator();
+        size_t iN;
+        for ( iN = 0; nnIt->more(); ++iN )
+        {
+          const SMDS_MeshNode* srcNode = nnIt->next();
+          elemData.myNodes[ iN ] = newMeshDS->FindNode( srcNode->GetID() );
+          if ( !elemData.myNodes[ iN ])
+            break;
+        }
+        if ( iN == elemData.myNodes.size() )
+          if ( const SMDS_MeshElement * newElem = editor.AddElement( elemData.myNodes, elemData ))
+            newMeshDS->SetMeshElementOnShape( newElem, newID );
+      }
+      if ( SMESH_subMesh* newSM = newMesh_i->GetImpl().GetSubMeshContaining( newID ))
+        newSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+    }
+
+    newMeshDS->Modified();
+  }
+
+
+  // treat groups
+
+  TStr2StrMap old2newGroupMap;
+
+  SALOME::GenericObj_wrap< SMESH::FilterManager > filterMgr = CreateFilterManager();
+
+  SMESH::ListOfGroups_var groups = theSourceMesh->GetGroups();
+  CORBA::ULong nbGroups = theToCopyGroups ? groups->length() : 0, nbAddedGroups = 0;
+  for ( CORBA::ULong i = 0; i < nbGroups + nbAddedGroups; ++i )
+  {
+    SMESH::SMESH_Group_var         stdlGroup = SMESH::SMESH_Group::_narrow        ( groups[ i ]);
+    SMESH::SMESH_GroupOnGeom_var   geomGroup = SMESH::SMESH_GroupOnGeom::_narrow  ( groups[ i ]);
+    SMESH::SMESH_GroupOnFilter_var fltrGroup = SMESH::SMESH_GroupOnFilter::_narrow( groups[ i ]);
+
+    CORBA::String_var      name = groups[ i ]->GetName();
+    SMESH::ElementType elemType = groups[ i ]->GetType();
+
+    SMESH::SMESH_GroupBase_var newGroup;
+
+    if ( !stdlGroup->_is_nil() )
+    {
+      if ( newMeshDS->GetMeshInfo().NbElements( SMDSAbs_ElementType( elemType )) > 0 )
+      {
+        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
+          if ( newMeshDS->GetElementType( elemIDs[ iE ], isElem ) != SMDSAbs_All )
+            break;
+        if ( iE < elemIDs->length() )
+        {
+          stdlGroup = theNewMesh->CreateGroup( elemType, name );
+          stdlGroup->Add( elemIDs );
+          newGroup = SMESH::SMESH_GroupBase::_narrow( stdlGroup );
+        }
+      }
+    }
+    else if ( !geomGroup->_is_nil() )
+    {
+      GEOM::GEOM_Object_var    geom = geomGroup->GetShape();
+      GEOM::GEOM_Object_var newGeom = shapeMapper.FindNew( geom );
+      if ( newGeom->_is_nil() )
+      {
+        newGroup = theNewMesh->CreateGroup( elemType, name ); // just to notify the user
+        shapeMapper.AddInvalid( geom, ObjectToSObject( newGroup ));
+        ok = false;
+      }
+      else
+      {
+        newGroup = theNewMesh->CreateGroupFromGEOM( elemType, name, newGeom );
+      }
+    }
+    else if ( !fltrGroup->_is_nil() )
+    {
+      // replace geometry in a filter
+      SMESH::Filter_var filter = fltrGroup->GetFilter();
+      SMESH::Filter::Criteria_var criteria;
+      filter->GetCriteria( criteria.out() );
+
+      bool isMissingGroup = false;
+      std::vector< std::string > badEntries;
+
+      for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
+      {
+        const char* thresholdID = criteria[ iCr ].ThresholdID.in();
+        switch ( criteria[ iCr ].Type )
+        {
+        case SMESH::FT_BelongToMeshGroup:
+        {
+          SALOME::GenericObj_wrap< SMESH::BelongToMeshGroup > btgg = filterMgr->CreateBelongToMeshGroup();
+          btgg->SetGroupID( thresholdID );
+          SMESH::SMESH_GroupBase_ptr refGroup = btgg->GetGroup();
+          SALOMEDS::SObject_wrap   refGroupSO = ObjectToSObject( refGroup );
+          if ( refGroupSO->_is_nil() )
+            break;
+          CORBA::String_var     refID = refGroupSO->GetID();
+          TStr2StrMap::iterator o2nID = old2newGroupMap.find( refID.in() );
+          if ( o2nID == old2newGroupMap.end() )
+          {
+            isMissingGroup = true; // corresponding new group not yet created
+            break;
+          }
+          criteria[ iCr ].ThresholdID = o2nID->second.c_str();
+
+          if ( o2nID->second.empty() ) // new referred group is invalid
+            badEntries.push_back( refID.in() );
+          break;
+        }
+        case SMESH::FT_BelongToGeom:
+        case SMESH::FT_BelongToPlane:
+        case SMESH::FT_BelongToCylinder:
+        case SMESH::FT_BelongToGenSurface:
+        case SMESH::FT_LyingOnGeom:
+        {
+          std::string newID = shapeMapper.FindNew( thresholdID );
+          criteria[ iCr ].ThresholdID = newID.c_str();
+          if ( newID.empty() )
+            badEntries.push_back( thresholdID );
+          break;
+        }
+        case SMESH::FT_ConnectedElements:
+        {
+          if ( thresholdID && thresholdID[0] )
+          {
+            std::string newID = shapeMapper.FindNew( thresholdID );
+            criteria[ iCr ].ThresholdID = newID.c_str();
+            if ( newID.empty() )
+              badEntries.push_back( thresholdID );
+          }
+          break;
+        }
+        default:;
+        }
+      } // loop on criteria
+
+      if ( isMissingGroup && i < nbGroups )
+      {
+        // to treat the group again
+        append( groups, SMESH::SMESH_GroupBase::_duplicate( groups[ i ]));
+        ++nbAddedGroups;
+        continue;
+      }
+      SMESH::Filter_var newFilter = filterMgr->CreateFilter();
+      newFilter->SetCriteria( criteria );
+
+      newGroup = theNewMesh->CreateGroupFromFilter( elemType, name, newFilter );
+      newFilter->UnRegister();
+
+      SALOMEDS::SObject_wrap newSO = ObjectToSObject( newGroup );
+      for ( size_t iEnt = 0; iEnt < badEntries.size(); ++iEnt )
+        shapeMapper.AddInvalid( badEntries[ iEnt ], newSO );
+
+      if ( isMissingGroup ) // all groups treated but a referred groups still not found
+      {
+        invalidSObjects.push_back( ObjectToSObject( newGroup ));
+        ok = false;
+      }
+      if ( !badEntries.empty() )
+        ok = false;
+
+    } // treat a group on filter
+
+    append( theNewGroups, newGroup );
+
+    // fill old2newGroupMap
+    SALOMEDS::SObject_wrap srcSO = ObjectToSObject( groups[i] );
+    SALOMEDS::SObject_wrap newSO = ObjectToSObject( newGroup );
+    if ( !srcSO->_is_nil() )
+    {
+      CORBA::String_var srcID, newID("");
+      srcID = srcSO->GetID();
+      if ( !newSO->_is_nil() )
+        newID = newSO->GetID();
+      old2newGroupMap.insert( std::make_pair( std::string( srcID.in() ),
+                                              std::string( newID.in() )));
+    }
+
+    if ( newGroup->_is_nil() )
+      ok = false;
+
+  } // loop on groups
+
+  newMeshDS->CompactMesh();
+
+  // set mesh name
+  if ( !theMeshName || !theMeshName[0] )
+  {
+    SALOMEDS::SObject_wrap soNew = ObjectToSObject( theNewMesh );
+    SALOMEDS::SObject_wrap soOld = ObjectToSObject( theSourceMesh );
+    CORBA::String_var oldName = soOld->GetName();
+    SetName( soNew, oldName.in(), "Mesh" );
+  }
+  // mark invalid objects
+  shapeMapper.GetInvalid( theInvalidEntries, invalidSObjects );
+
+  for ( size_t i = 0; i < invalidSObjects.size(); ++i )
+    highLightInvalid( invalidSObjects[i].in(), true );
+
+  pyDump << "ok, "
+         << theNewMesh << ", "
+         << theNewGroups << ", "
+         << *theNewSubmeshes.ptr() << ", "
+         << *theNewHypotheses.ptr() << ", "
+         << "invalidEntries = " << this << ".CopyMeshWithGeom( "
+         << theSourceMesh << ", "
+         << theNewGeometry << ", "
+         << "'" << theMeshName << "', "
+         << theToCopyGroups << ", "
+         << theToReuseHypotheses << ", "
+         << theToCopyElements << " )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return ok;
+}
+
+//================================================================================
+/*!
+ * \brief Get version of MED format being used.
+ */
+//================================================================================
+
+char* SMESH_Gen_i::GetMEDFileVersion()
+{
+  MED::TInt majeur, mineur, release;
+  majeur =  mineur = release = 0;
+  MED::GetVersionRelease(majeur, mineur, release);
+  std::ostringstream version;
+  version << majeur << "." << mineur << "." << release;
+  return CORBA::string_dup( version.str().c_str() );
+}
+
+//================================================================================
+/*!
+ *  SMESH_Gen_i::GetMEDVersion
+ *
+ *  Get MED version of the file by its name
+ */
+//================================================================================
+
+char* SMESH_Gen_i::GetMEDVersion(const char* theFileName)
+{
+  std::string version = MED::GetMEDVersion( theFileName );
+  return CORBA::string_dup( version.c_str() );
+}
+
+//================================================================================
+/*!
+ *  SMESH_Gen_i::CheckCompatibility
+ *
+ *  Check compatibility of file with MED format being used, read only.
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Gen_i::CheckCompatibility(const char* theFileName)
+{
+  return MED::CheckCompatibility( theFileName );
+}
+
+//================================================================================
+/*!
+ *  SMESH_Gen_i::CheckWriteCompatibility
+ *
+ *  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 );
+}
+
+//================================================================================
+/*!
+ *  SMESH_Gen_i::GetMeshNames
+ *
+ *  Get names of meshes defined in file with the specified name
+ */
+//================================================================================
+SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* 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 );
   if( anErr >= 0 ) {
     aResult->length( aNbMeshes );
@@ -2997,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();
 
@@ -3054,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
@@ -3073,9 +4160,8 @@ 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();
-            pd << ""; // to avoid optimizing pd out
             for ( CORBA::ULong i = 0; i < groups->length(); ++i )
             {
               SMESH_GroupBase_i* grImpl = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i]);
@@ -3084,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 );
               }
@@ -3134,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
@@ -3204,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
@@ -3270,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;
@@ -3308,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() );
@@ -3329,9 +4419,20 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
               }
             }
 
+            // Store file info
+            std::string info = myImpl->FileInfoToString();
+            if ( !info.empty() )
+            {
+              aSize[ 0 ] = info.size();
+              aDataset = new HDFdataset( "file info", aTopGroup, HDF_STRING, aSize, 1 );
+              aDataset->CreateOnDisk();
+              aDataset->WriteOnDisk( (char*) info.data() );
+              aDataset->CloseOnDisk();
+            }
+
             // 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 );
             }
@@ -3590,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
@@ -3628,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;
@@ -3697,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 =
@@ -3722,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 =
@@ -3745,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 );
@@ -3772,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 );
@@ -3813,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();
@@ -3972,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
@@ -4002,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 =
@@ -4022,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";
@@ -4047,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:
@@ -4246,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" );
             }
@@ -4327,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() )
@@ -4342,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();
@@ -4353,11 +5460,33 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId );
             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" ))
+          {
+            aDataset = new HDFdataset( "file info", aTopGroup );
+            aDataset->OpenOnDisk();
+            size = aDataset->GetSize();
+            std::string info( size, ' ');
+            aDataset->ReadFromDisk( (char*) info.data() );
+            aDataset->CloseOnDisk();
+            myNewMeshImpl->FileInfoFromString( info );
+          }
         }
       }
     } // 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;
@@ -4375,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;
@@ -4384,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" ) ) {
@@ -4396,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;
@@ -4425,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 );
@@ -4462,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 );
@@ -4543,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 );
                   }
                 }
@@ -4666,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();
 
@@ -4725,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 );
 
@@ -4774,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();
@@ -4801,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)
@@ -4860,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:
@@ -4929,12 +6078,14 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" );
 
   // Clear study contexts data
-  delete myStudyContext;
-  myStudyContext = 0;
+  myStudyContext->Clear();
 
   // remove the tmp files meshes are loaded from
   SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD( theComponent );
 
+  // Clean trace of API methods calls
+  CleanPythonTrace();
+
   return;
 }
 
@@ -5024,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;
 }
@@ -5040,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)
 {
@@ -5067,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 )
@@ -5120,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
   {
@@ -5141,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,
@@ -5171,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,
@@ -5178,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);
 
@@ -5196,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,
@@ -5205,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();
@@ -5227,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();
@@ -5248,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();
@@ -5274,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);
@@ -5294,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();
@@ -5303,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();
@@ -5315,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) {
@@ -5327,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() ;
-  }
-}