Salome HOME
#19765 EDF 21730 - long time to load med file file with huge amount of groups
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index 2b0e5d30c910e99bcd4a627c8799efd28a36f7e4..701de05a84ed019316a6715d8302079d3b49ff0f 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
@@ -157,7 +157,7 @@ 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;
@@ -258,14 +258,15 @@ SALOME_NamingService* SMESH_Gen_i::GetNS()
  *  Get SALOME_LifeCycleCORBA object
  */
 //=============================================================================
-SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
+
+SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC()
+{
   if ( myLCC == NULL ) {
     myLCC = new SALOME_LifeCycleCORBA( GetNS() );
   }
   return myLCC;
 }
 
-
 //=============================================================================
 /*!
  *  GetGeomEngine [ static ]
@@ -273,18 +274,33 @@ 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);
-  }
+
+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;
+  if ( !CORBA::is_nil( go ))
+    gen = go->GetGen();
+  return gen;
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::SMESH_Gen_i
@@ -386,6 +402,7 @@ SMESH_Gen_i::~SMESH_Gen_i()
   if ( myShapeReader )
     delete myShapeReader;
 }
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::getHypothesisCreator
@@ -393,6 +410,7 @@ SMESH_Gen_i::~SMESH_Gen_i()
  *  Get hypothesis creator
  */
 //=============================================================================
+
 GenericHypothesisCreator_i* SMESH_Gen_i::getHypothesisCreator(const char* theHypName,
                                                               const char* theLibName,
                                                               std::string& thePlatformLibName)
@@ -511,6 +529,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)
 {
@@ -544,6 +563,7 @@ 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 )
 {
@@ -578,6 +598,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
  *  Get shape reader
  */
 //=============================================================================
+
 GEOM_Client* SMESH_Gen_i::GetShapeReader()
 {
   // create shape reader if necessary
@@ -594,13 +615,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 );
 }
 
 //=============================================================================
@@ -655,6 +673,7 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode()
  *  Set enable publishing in the study
  */
 //=============================================================================
+
 void SMESH_Gen_i::SetEnablePublish( CORBA::Boolean theIsEnablePublish )
 {
   myIsEnablePublish = theIsEnablePublish;
@@ -687,11 +706,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();
@@ -708,6 +734,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
@@ -715,6 +798,7 @@ void SMESH_Gen_i::UpdateStudy()
  *  Get study context
  */
 //=============================================================================
+
 StudyContext* SMESH_Gen_i::GetStudyContext()
 {
   return myStudyContext;
@@ -749,6 +833,43 @@ 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)
+  throw ( SALOME::SALOME_Exception )
+{
+  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() << hyp << " = " << this << ".CreateHypothesisByAverageLength( '"
+                << theHypType << "', '"
+                << theLibName << "', "
+                << theAverageLength << ", "
+                << theQuadDominated << " )";
+
+  return hyp._retn();
+}
+
 //================================================================================
 /*!
  * \brief Return a hypothesis holding parameter values corresponding either to the mesh
@@ -764,7 +885,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam
 //================================================================================
 
 SMESH::SMESH_Hypothesis_ptr
-SMESH_Gen_i::GetHypothesisParameterValues (const char*                 theHypType,
+SMESH_Gen_i::GetHypothesisParameterValuesconst char*                 theHypType,
                                            const char*                 theLibName,
                                            SMESH::SMESH_Mesh_ptr       theMesh,
                                            GEOM::GEOM_Object_ptr       theGeom,
@@ -844,6 +965,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*                 theHypTyp
       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 );
@@ -952,7 +1074,7 @@ 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
  */
 //=============================================================================
@@ -965,11 +1087,13 @@ void SMESH_Gen_i::SetBoundaryBoxSegmentation( CORBA::Long 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 )
 {
@@ -981,8 +1105,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)
@@ -1044,8 +1168,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)
@@ -1138,7 +1262,7 @@ 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
    */
   //================================================================================
 
@@ -1289,14 +1413,21 @@ 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;
 }
 
@@ -1308,7 +1439,7 @@ 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 )
 {
@@ -1328,7 +1459,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
@@ -1389,7 +1523,7 @@ 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 )
 {
@@ -1517,7 +1651,7 @@ 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
  */
 //=============================================================================
 
@@ -1531,11 +1665,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() );
@@ -1563,7 +1695,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();
@@ -1790,9 +1922,9 @@ 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
  */
 //================================================================================
 
@@ -1957,7 +2089,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
@@ -2055,7 +2190,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();
@@ -2222,12 +2357,10 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
   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);
@@ -2313,7 +2446,7 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
   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() );
@@ -2344,7 +2477,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
@@ -2377,7 +2510,7 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  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 );
@@ -2400,7 +2533,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() ) {
@@ -3060,7 +3193,7 @@ namespace // utils for CopyMeshWithGeom()
       std::string  newMainEntry = newEntry.in();
 
       SALOMEDS::Study_var            study = myGen_i->getStudyServant();
-      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine();
+      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine( mainShapeNew );
       GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
       mySubshapes                          = op->GetExistingSubObjects( mainShapeNew,
                                                                         /*groupsOnly=*/false );
@@ -3115,7 +3248,7 @@ namespace // utils for CopyMeshWithGeom()
         return GEOM::GEOM_Object::_duplicate( oldShape ); // shape independent of the old shape
 
       GEOM::GEOM_Object_var mainShapeNew = myNewMesh_i->GetShapeToMesh();
-      GEOM::GEOM_Gen_var         geomGen = myGen_i->GetGeomEngine();
+      GEOM::GEOM_Gen_var         geomGen = myGen_i->GetGeomEngine( mainShapeNew );
 
       // try to find by entry or name
       if ( myToPublish )
@@ -3337,7 +3470,7 @@ namespace // utils for CopyMeshWithGeom()
 
         GEOM::GEOM_Object_var   mainShapeNew = myNewMesh_i->GetShapeToMesh();
         GEOM::GEOM_Object_var   mainShapeOld = mySrcMesh_i->GetShapeToMesh();
-        GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine();
+        GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine( mainShapeNew );
         GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
         try
         {
@@ -3359,7 +3492,7 @@ namespace // utils for CopyMeshWithGeom()
       GEOM::GEOM_Object_var newShape;
 
       GEOM::GEOM_Object_var   mainShapeNew = myNewMesh_i->GetShapeToMesh();
-      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine();
+      GEOM::GEOM_Gen_var           geomGen = myGen_i->GetGeomEngine( mainShapeNew );
       GEOM::GEOM_IShapesOperations_wrap op = geomGen->GetIShapesOperations();
       try
       {
@@ -3976,6 +4109,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 );
@@ -3989,6 +4123,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 );
@@ -4001,6 +4136,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 );
@@ -4014,13 +4150,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++ ) {
@@ -4038,6 +4173,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 )
@@ -4180,8 +4316,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
@@ -4250,8 +4384,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
@@ -4354,6 +4486,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;
@@ -4647,10 +4787,6 @@ 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();
@@ -5029,23 +5165,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
@@ -5059,17 +5178,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                         const char*              theURL,
                         bool                     isMultiFile )
 {
-  // localizing
+  UpdateStudy(); // load geom data
   Kernel_Utils::Localizer loc;
 
-  //if (!myStudyContext)
-    UpdateStudy();
   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 =
@@ -5109,9 +5221,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
 
   TPythonDump pd; // prevent dump during loading
 
-  // DriverMED_R_SMESHDS_Mesh myReader;
-  // myReader.SetFile( meshfile.ToCString() );
-
   // For PAL13473 ("Repetitive mesh") implementation.
   // New dependencies between SMESH objects are established:
   // now hypotheses can refer to meshes, shapes and other hypotheses.
@@ -5391,11 +5500,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() )
@@ -5406,7 +5511,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();
@@ -5418,6 +5523,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" ))
           {
@@ -5451,8 +5566,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;
@@ -5497,8 +5610,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 );
@@ -5534,8 +5645,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 );
@@ -6118,6 +6227,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)
 {
@@ -6145,6 +6255,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 )
@@ -6220,10 +6331,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,
@@ -6250,6 +6363,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,
@@ -6257,12 +6376,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);
 
@@ -6275,6 +6396,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,
@@ -6284,7 +6411,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();
@@ -6306,10 +6434,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();
@@ -6327,12 +6462,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();
@@ -6353,7 +6492,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);
@@ -6407,7 +6546,6 @@ std::vector<long> SMESH_Gen_i::_GetInside( SMESH::SMESH_IDSource_ptr meshPart,
   return res;
 }
 
-
 //=============================================================================
 /*!
  *  SMESHEngine_factory