Salome HOME
Modif for salome gui without neither NS nor other servers.
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index 3003a0a5259d5120a52ecb8db178bc02a39d3a0e..e89466cfbdc42868373a38f9e039a2d55e9b2525 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020  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 <cstdlib>
 #include <memory>
 
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/string.hpp>
+
 using namespace std;
 using SMESH::TPythonDump;
 using SMESH::TVar;
@@ -160,9 +164,9 @@ static int MYDEBUG = 0;
 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;
@@ -241,7 +245,7 @@ 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 ) {
     myNS = SINGLETON_<SALOME_NamingService>::Instance();
@@ -275,27 +279,9 @@ SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC()
  */
 //=============================================================================
 
-GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine( bool isShaper )
-{
-  Engines::EngineComponent_ptr temp =
-    GetLCC()->FindOrLoad_Component( isShaper ? "FactoryServer" : "FactoryServer",
-                                    isShaper ? "SHAPERSTUDY" : "GEOM" );
-  myGeomGen = GEOM::GEOM_Gen::_narrow( temp );
-
-  return myGeomGen;
-}
-
-//=============================================================================
-/*!
- *  GetGeomEngine [ static ]
- *
- *  Get GEOM::GEOM_Gen reference
- */
-//=============================================================================
-
 GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine( GEOM::GEOM_Object_ptr go )
 {
-  GEOM::GEOM_Gen_ptr gen;
+  GEOM::GEOM_Gen_ptr gen = GEOM::GEOM_Gen::_nil();
   if ( !CORBA::is_nil( go ))
     gen = go->GetGen();
   return gen;
@@ -325,8 +311,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);
@@ -351,21 +338,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() );
+      }
     }
   }
 }
@@ -402,6 +392,7 @@ SMESH_Gen_i::~SMESH_Gen_i()
   if ( myShapeReader )
     delete myShapeReader;
 }
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::getHypothesisCreator
@@ -409,10 +400,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 */
@@ -527,6 +518,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)
 {
@@ -548,7 +540,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();
 }
@@ -560,8 +552,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" );
@@ -578,7 +570,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) {
@@ -594,6 +586,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
  *  Get shape reader
  */
 //=============================================================================
+
 GEOM_Client* SMESH_Gen_i::GetShapeReader()
 {
   // create shape reader if necessary
@@ -610,13 +603,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 );
 }
 
 //=============================================================================
@@ -671,6 +661,7 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode()
  *  Set enable publishing in the study
  */
 //=============================================================================
+
 void SMESH_Gen_i::SetEnablePublish( CORBA::Boolean theIsEnablePublish )
 {
   myIsEnablePublish = theIsEnablePublish;
@@ -731,6 +722,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
@@ -738,6 +786,7 @@ void SMESH_Gen_i::UpdateStudy()
  *  Get study context
  */
 //=============================================================================
+
 StudyContext* SMESH_Gen_i::GetStudyContext()
 {
   return myStudyContext;
@@ -753,7 +802,6 @@ StudyContext* SMESH_Gen_i::GetStudyContext()
 
 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
@@ -764,7 +812,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 << "')";
     }
   }
@@ -772,6 +820,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
@@ -787,14 +871,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 ) )
@@ -849,17 +934,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 );
   }
@@ -967,26 +1059,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) );
@@ -996,8 +1088,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)
@@ -1059,8 +1151,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)
@@ -1092,7 +1184,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" );
@@ -1111,7 +1202,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 << ")";
     }
   }
 
@@ -1127,7 +1218,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" );
@@ -1142,7 +1232,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()";
     }
   }
 
@@ -1153,11 +1243,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 )
@@ -1181,7 +1271,6 @@ namespace
 //=============================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName )
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
 
@@ -1197,7 +1286,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 << "')";
     }
   }
 
@@ -1244,7 +1333,7 @@ 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;
+  TPythonDump aPythonDump(this);
   aPythonDump << "([";
 
   if (theStatus == SMESH::DRS_OK) {
@@ -1304,14 +1393,20 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileNa
   return aResult._retn();
 }
 
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
+//================================================================================
+/*!
+ * \brief Create meshes by reading a MED file
+ */
+//================================================================================
+
+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);
+  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus,
+                                                        "CreateMeshesFromMED", theFileName);
   return result;
 }
 
@@ -1323,9 +1418,8 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
  */
 //=============================================================================
 
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName,
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char*                  theFileName,
                                                       SMESH::DriverMED_ReadStatus& theStatus)
-     throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
   checkFileReadable( theFileName );
@@ -1343,7 +1437,10 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName,
   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());
+  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(),
+                                                        theStatus,
+                                                        "CreateMeshesFromSAUV",
+                                                        sauvfilename.c_str());
 #ifdef WIN32
   cmd = "%PYTHONBIN% ";
 #else
@@ -1365,7 +1462,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 );
@@ -1387,7 +1483,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 << "')";
     }
   }
 
@@ -1404,9 +1500,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 );
@@ -1426,7 +1521,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)
@@ -1494,7 +1589,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 );
@@ -1515,7 +1609,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 << " )";
     }
@@ -1532,13 +1626,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" );
@@ -1546,11 +1639,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() );
@@ -1578,7 +1669,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();
@@ -1615,7 +1706,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()" );
@@ -1690,7 +1780,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()" );
@@ -1778,7 +1867,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);
 
@@ -1791,7 +1879,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 << "' )";
     }
@@ -1805,15 +1893,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()" );
@@ -1875,7 +1962,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" );
@@ -1949,7 +2035,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);
@@ -1964,7 +2049,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
                                   SALOME::BAD_PARAM );
 
   // Update Python script
-  TPythonDump() << "isDone = " << this << ".Compute( "
+  TPythonDump(this) << "isDone = " << this << ".Compute( "
                 << theMesh << ", " << theShapeObject << ")";
 
   try {
@@ -1972,7 +2057,10 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
     SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
     ASSERT( meshServant );
     if ( meshServant ) {
-      meshServant->Load();
+      if ( isGeomModifIcon( theMesh ))
+        meshServant->Clear();
+      else
+        meshServant->Load();
       // NPAL16168: "geometrical group edition from a submesh don't modify mesh computation"
       meshServant->CheckGeomModif();
       // get local TopoDS_Shape
@@ -1996,7 +2084,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
       return ok;
     }
   }
-  catch ( std::bad_alloc ) {
+  catch ( std::bad_alloc& ) {
     INFOS( "Compute(): lack of memory" );
   }
   catch ( SALOME_Exception& S_ex ) {
@@ -2043,7 +2131,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" );
@@ -2070,7 +2157,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();
@@ -2207,7 +2294,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 ) {
@@ -2231,18 +2318,15 @@ 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 )
 {
   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;
   nbels->length(SMESH::Entity_Last);
@@ -2251,7 +2335,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
     nbels[i] = 0;
 
   // Update Python script
-  TPythonDump() << "theNbElems = " << this << ".Evaluate( "
+  TPythonDump(this) << "theNbElems = " << this << ".Evaluate( "
                 << theMesh << ", " << theShapeObject << ")";
 
   try {
@@ -2294,7 +2378,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 ) {
@@ -2321,14 +2405,13 @@ GEOM::GEOM_Object_ptr
 SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
                                        CORBA::Long            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::GEOM_Gen_var    geomGen   = GetGeomEngine( geom );
 
     // try to find the corresponding SObject
     SALOMEDS::SObject_wrap SObj = ObjectToSObject( geom.in() );
@@ -2359,7 +2442,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
@@ -2385,14 +2468,13 @@ 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 )
 {
   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( mainShape );
+  GEOM::GEOM_Gen_var    geomGen   = GetGeomEngine( mainShape );
 
   // get a core mesh DS
   SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh );
@@ -2415,7 +2497,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() ) {
@@ -2461,7 +2543,6 @@ SMESH_Gen_i::Concatenate(const SMESH::ListOfIDSources& theMeshesArray,
                          CORBA::Boolean                theMergeNodesAndElements,
                          CORBA::Double                 theMergeTolerance,
                          SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
-  throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
                            theUniteIdenticalGroups,
@@ -2486,7 +2567,6 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::ListOfIDSources& theMeshesArray,
                                    CORBA::Boolean                theMergeNodesAndElements,
                                    CORBA::Double                 theMergeTolerance,
                                    SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
-  throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
                            theUniteIdenticalGroups,
@@ -2511,9 +2591,8 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
                                CORBA::Double                 theMergeTolerance,
                                CORBA::Boolean                theCommonGroups,
                                SMESH::SMESH_Mesh_ptr         theMeshToAppendTo)
-  throw ( SALOME::SALOME_Exception )
 {
-  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 if theMeshToAppendTo not provided
@@ -2791,11 +2870,10 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
                                             const char*               meshName,
                                             CORBA::Boolean            toCopyGroups,
                                             CORBA::Boolean            toKeepIDs)
-  throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
 
-  TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
+  TPythonDump* pyDump = new TPythonDump(this); // prevent dump from CreateMesh()
   std::unique_ptr<TPythonDump> pyDumpDeleter( pyDump );
 
   // 1. Get source mesh
@@ -3566,7 +3644,6 @@ CORBA::Boolean SMESH_Gen_i::CopyMeshWithGeom( SMESH::SMESH_Mesh_ptr       theSou
                                               SMESH::submesh_array_out    theNewSubmeshes,
                                               SMESH::ListOfHypothesis_out theNewHypotheses,
                                               SMESH::string_array_out     theInvalidEntries)
-throw ( SALOME::SALOME_Exception )
 {
   if ( CORBA::is_nil( theSourceMesh ) ||
        CORBA::is_nil( theNewGeometry ))
@@ -3578,7 +3655,7 @@ throw ( SALOME::SALOME_Exception )
   bool ok = true;
   SMESH_TRY;
 
-  TPythonDump pyDump; // prevent dump from CreateMesh()
+  TPythonDump pyDump(this); // prevent dump from CreateMesh()
 
   theNewMesh        = CreateMesh( theNewGeometry );
   theNewGroups      = new SMESH::ListOfGroups();
@@ -3991,6 +4068,7 @@ char* SMESH_Gen_i::GetMEDFileVersion()
  *  Get MED version of the file by its name
  */
 //================================================================================
+
 char* SMESH_Gen_i::GetMEDVersion(const char* theFileName)
 {
   std::string version = MED::GetMEDVersion( theFileName );
@@ -4004,6 +4082,7 @@ char* SMESH_Gen_i::GetMEDVersion(const char* theFileName)
  *  Check compatibility of file with MED format being used, read only.
  */
 //================================================================================
+
 CORBA::Boolean SMESH_Gen_i::CheckCompatibility(const char* theFileName)
 {
   return MED::CheckCompatibility( theFileName );
@@ -4016,6 +4095,7 @@ CORBA::Boolean SMESH_Gen_i::CheckCompatibility(const char* theFileName)
  *  Check compatibility of file with MED format being used, for append on write.
  */
 //================================================================================
+
 CORBA::Boolean SMESH_Gen_i::CheckWriteCompatibility(const char* theFileName)
 {
   return MED::CheckCompatibility( theFileName, true );
@@ -4029,13 +4109,12 @@ CORBA::Boolean SMESH_Gen_i::CheckWriteCompatibility(const char* theFileName)
  */
 //================================================================================
 SMESH::string_array* SMESH_Gen_i::GetMeshNames(const char* theFileName)
+
 {
-  //MESSAGE("GetMeshNames " << theFileName);
   SMESH::string_array_var aResult = new SMESH::string_array();
   MED::PWrapper aMed = MED::CrWrapperR( theFileName );
   MED::TErr anErr;
   MED::TInt aNbMeshes = aMed->GetNbMeshes( &anErr );
-  //MESSAGE("---" << aNbMeshes);
   if( anErr >= 0 ) {
     aResult->length( aNbMeshes );
     for( MED::TInt i = 0; i < aNbMeshes; i++ ) {
@@ -4053,6 +4132,7 @@ 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 )
@@ -4135,7 +4215,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
           SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
           if ( !myMesh->_is_nil() ) {
             myMesh->Load(); // load from study file if not yet done
-            TPythonDump pd; // not to dump GetGroups()
+            TPythonDump pd(this); // not to dump GetGroups()
             SMESH::ListOfGroups_var groups = myMesh->GetGroups();
             for ( CORBA::ULong i = 0; i < groups->length(); ++i )
             {
@@ -4195,8 +4275,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
@@ -4265,8 +4343,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
@@ -4369,6 +4445,14 @@ 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;
@@ -4662,14 +4746,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
@@ -4700,6 +4781,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;
@@ -5098,10 +5211,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:
@@ -5393,7 +5503,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();
@@ -5405,6 +5515,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             delete [] meshPersistentId;
           }
 
+          // Restore SMESH_Mesh_i::_mainShapeTick
+          if ( aTopGroup->ExistInternalObject( "shapeTick" ))
+          {
+            aDataset = new HDFdataset( "shapeTick", aTopGroup );
+            aDataset->OpenOnDisk();
+            int* shapeTick = & myNewMeshImpl->MainShapeTick();
+            aDataset->ReadFromDisk( shapeTick );
+            aDataset->CloseOnDisk();
+          }
+
           // Restore file info
           if ( aTopGroup->ExistInternalObject( "file info" ))
           {
@@ -5438,8 +5558,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;
@@ -5484,8 +5602,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 );
@@ -5521,8 +5637,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 );
@@ -5846,7 +5960,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
       }
 
       // 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();
@@ -5864,6 +5978,37 @@ 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::istringstream istream( dataString.data() );
+        boost::archive::text_iarchive archive( istream );
+        std::list< std::list< std::string > > orderEntryLists;
+        try {
+          archive >> orderEntryLists;
+        }
+        catch (...) {}
+
+        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)
@@ -5923,7 +6068,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:
@@ -6105,6 +6249,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)
 {
@@ -6132,6 +6277,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 )
@@ -6185,7 +6331,6 @@ 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)
@@ -6207,10 +6352,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,
@@ -6237,6 +6384,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,
@@ -6244,12 +6397,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);
 
@@ -6262,6 +6417,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,
@@ -6271,7 +6432,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();
@@ -6293,10 +6455,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();
@@ -6314,12 +6483,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();
@@ -6340,7 +6513,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);
@@ -6393,27 +6566,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() ;
-  }
-}