Salome HOME
IPAL54678: TC-9.5.0: Sub-mesh priority: not all sub-meshes are displayed in the dialog
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index 1e020c81066282000f6d4a5e371e927e3da3db37..f638d0391b8722e5ca7be3470c7fdd2a7d138a2b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  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
 
 #include "SMESH_version.h"
 
-#include "SMESH_ControlsDef.hxx"
 #include "SMESH_Actor.h"
 #include "SMESH_ActorUtils.h"
 #include "SMESH_Client.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_ControlsDef.hxx"
 #include "SMESH_ScalarBarActor.h"
-#include <SMESH_Comment.hxx>
 #include "SMESH_TypeFilter.hxx"
 
 // SALOME GUI includes
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_ResourceMgr.h>
 #include <SUIT_Session.h>
+#include <SVTK_Renderer.h>
 #include <SVTK_ViewManager.h>
 #include <SVTK_ViewModel.h>
 #include <SVTK_ViewWindow.h>
 #include <SALOMEDS_Study.hxx>
 #include <SALOMEDS_SObject.hxx>
 #include "utilities.h"
+#include <SALOME_LifeCycleCORBA.hxx>
 
 // OCCT includes
 #include <Standard_ErrorHandler.hxx>
@@ -1381,6 +1383,108 @@ namespace
     }
   }
 
+  // Break link with Shaper model
+  void breakShaperLink()
+  {
+    LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if (aSel) {
+      aSel->selectedObjects(selected);
+      if (selected.Extent()) {
+        Handle(SALOME_InteractiveObject) anIObject = selected.First();
+        _PTR(Study) aStudy = SMESH::getStudy();
+        std::string aEntry = anIObject->getEntry();
+        _PTR(SObject) aSObj = aStudy->FindObjectID(aEntry);
+        if (aSObj) {
+          std::string aName = aSObj->GetName();
+          QMessageBox::StandardButton aRes = SUIT_MessageBox::warning(SMESHGUI::desktop(),
+            QObject::tr("SMESH_WRN_WARNING"),
+            QObject::tr("MSG_BREAK_SHAPER_LINK").arg(aName.c_str()),
+            SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No);
+          if (aRes == SUIT_MessageBox::Yes) {
+            SUIT_DataOwnerPtrList aList;
+            aSel->selected(aList, "ObjectBrowser", true);
+            SUIT_DataOwner* aOwn = aList.first();
+            LightApp_DataOwner* sowner = dynamic_cast<LightApp_DataOwner*>(aOwn);
+            QString aREntry = sowner->entry();
+
+            static GEOM::GEOM_Gen_var geomGen;
+            if (CORBA::is_nil(geomGen)) {
+              SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
+                (SUIT_Session::session()->activeApplication());
+              if (app) {
+                SALOME_LifeCycleCORBA* ls = new SALOME_LifeCycleCORBA(app->namingService());
+                Engines::EngineComponent_var comp =
+                  ls->FindOrLoad_Component("FactoryServer", "SHAPERSTUDY");
+                geomGen = GEOM::GEOM_Gen::_narrow(comp);
+              }
+            }
+            if (!CORBA::is_nil(geomGen))
+            {
+              geomGen->BreakLink(aREntry.toStdString().c_str());
+              SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+
+              // remove actors whose objects are removed by BreakLink()
+              QList<SUIT_ViewWindow*> wndList = SMESHGUI::desktop()->windows();
+              SUIT_ViewWindow* wnd;
+              foreach(wnd, wndList)
+                SMESH::UpdateActorsAfterUpdateStudy(wnd);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return true if a mesh icon == ICON_SMESH_TREE_GEOM_MODIF
+   * which means that the mesh can't be modified. It should be either re-computed
+   * or breakShaperLink()'ed. Warn the user about it.
+   */
+  //================================================================================
+
+  bool warnOnGeomModif()
+  {
+    SALOME_ListIO selected;
+    if ( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() )
+      aSel->selectedObjects(selected,"",/*convertReferences=*/false);
+
+    SALOME_ListIteratorOfListIO It( selected );
+    for ( ; It.More(); It.Next() )
+    {
+      Handle(SALOME_InteractiveObject) io = It.Value();
+      if ( !io->hasEntry() ) continue;
+      _PTR(SObject) so = SMESH::getStudy()->FindObjectID( io->getEntry() );
+      SMESH::SMESH_Mesh_var mesh;
+      while ( mesh->_is_nil() && so && so->GetID() != "0:" )
+      {
+        CORBA::Object_var obj = SMESH::SObjectToObject( so );
+        SMESH::SMESH_IDSource_var isrc = SMESH::SMESH_IDSource::_narrow( obj );
+        if ( isrc->_is_nil() )
+          so = so->GetFather();
+        else
+          mesh = isrc->GetMesh();
+      }
+      if ( mesh->_is_nil() ) continue;
+      so = SMESH::FindSObject( mesh );
+      if ( !so ) continue;
+      _PTR(GenericAttribute) attr;
+      so->FindAttribute( attr, "AttributePixMap" );
+      _PTR(AttributePixMap) pixmap = attr;
+      if ( !pixmap ) continue;
+
+      if ( pixmap->GetPixMap() == "ICON_SMESH_TREE_GEOM_MODIF" )
+      {
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 QObject::tr("SMESH_WRN_WARNING"),
+                                 QObject::tr("MSG_WARN_ON_GEOM_MODIF"));
+        return true;
+      }
+    }
+    return false;
+  }
+
   void SetDisplayMode(int theCommandID, VTK::MarkerMap& theMarkerMap)
   {
     SALOME_ListIO selected;
@@ -1749,7 +1853,7 @@ namespace
                 int anEntitiesCount = anActor->GetNumberControlEntities();
                 if (anEntitiesCount >= 0)
                   functorName = functorName + ": " + QString::number(anEntitiesCount);
-                anActor->GetScalarBarActor()->SetTitle( functorName.toLatin1().constData() );
+                anActor->GetScalarBarActor()->SetTitle( functorName.toUtf8().constData() );
                 SMESH::RepaintCurrentView();
 #ifndef DISABLE_PLOT2DVIEWER
                 if ( anActor->GetPlot2Histogram() ) {
@@ -1919,8 +2023,8 @@ void SMESHGUI::OnEditDelete()
 
   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
 
-  // Put the whole hierarchy of sub-objects of the selected SO's into a list and
-  // then treat them all starting from the deepest objects (at list back)
+  // Put one level of sub-objects of the selected SO's into a list
+  // in order to get objects inside folders like "Assigned Algorithms"
   std::list< _PTR(SObject) > listSO;
   SALOME_ListIteratorOfListIO It(selected);
   for( ; It.More(); It.Next()) // loop on selected IO's
@@ -1941,43 +2045,47 @@ void SMESHGUI::OnEditDelete()
         aSO = aRefSObject; // Delete main Object instead of reference
 
       listSO.push_back( aSO );
-      std::list< _PTR(SObject) >::iterator itSO = --listSO.end();
-      for ( ; itSO != listSO.end(); ++itSO ) {
-        _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
-        for (it->InitEx(false); it->More(); it->Next())
-          listSO.push_back( it->Value() );
-      }
+
+      _PTR(ChildIterator) it = aStudy->NewChildIterator( aSO );
+      for (it->InitEx(false); it->More(); it->Next())
+        listSO.push_back( it->Value() );
     }
   }
   // Check if none of objects to delete is referred from outside
   std::list< _PTR(SObject) >::reverse_iterator ritSO;
+  std::vector< _PTR(SObject) > subSO;
   for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
   {
     _PTR(SObject) SO = *ritSO;
     if ( !SO ) continue;
-    std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO  );
-    for (size_t i = 0; i < aReferences.size(); i++) {
-      _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent();
-      std::string type = aComponent->ComponentDataType();
-      if ( type != "SMESH" )
-      {
-        SUIT_MessageBox::warning( anApp->desktop(),
-                                  QObject::tr("WRN_WARNING"),
-                                  QObject::tr("DEP_OBJECT") );
-        return; // outside SMESH, there is an object depending on a SMESH object
+
+    int nbChildren = SO->GetLastChildTag();
+    subSO.clear();
+    subSO.reserve( 1 + nbChildren );
+    subSO.push_back( SO );
+    if ( nbChildren > 0 )
+    {
+      _PTR(ChildIterator) it = aStudy->NewChildIterator( SO );
+      for ( it->InitEx( true ); it->More(); it->Next() )
+        subSO.push_back( it->Value() );
+    }
+    for ( size_t i = 0; i < subSO.size(); ++i )
+    {
+      std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( subSO[i] );
+      for ( size_t j = 0; j < aReferences.size(); j++ ) {
+        _PTR(SComponent) aComponent = aReferences[j]->GetFatherComponent();
+        std::string type = aComponent->ComponentDataType();
+        if ( type != "SMESH" )
+        {
+          SUIT_MessageBox::warning( anApp->desktop(),
+                                    QObject::tr("WRN_WARNING"),
+                                    QObject::tr("DEP_OBJECT") );
+          return; // outside SMESH, there is an object depending on a SMESH object
+        }
       }
     }
   }
 
-  // Call mesh->Clear() to prevent loading mesh from file caused by hypotheses removal
-  for( It.Initialize( selected ); It.More(); It.Next()) // loop on selected IO's
-  {
-    Handle(SALOME_InteractiveObject) IObject = It.Value();
-    SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface< SMESH::SMESH_Mesh >( IObject );
-    if ( !mesh->_is_nil() )
-      mesh->Clear();
-  }
-
   // Treat SO's in the list starting from the back
   aStudyBuilder->NewCommand();  // There is a transaction
   for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
@@ -1987,7 +2095,7 @@ void SMESHGUI::OnEditDelete()
     std::string anEntry = SO->GetID();
 
     /** Erase graphical object and remove all its data **/
-    if(SO->FindAttribute(anAttr, "AttributeIOR")) {
+    if ( SO->FindAttribute( anAttr, "AttributeIOR" )) {
       SMESH::RemoveVisualObjectWithActors( anEntry.c_str(), true);
     }
     /** Remove an object from data structures **/
@@ -2727,6 +2835,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       else
         aSel->setSelectedObjects( to_process );
 
+      if ( vtkwnd && vtkwnd->GetRenderer() && !isStudyLocked() &&
+           ( theCommandID==SMESHOp::OpShow || theCommandID==SMESHOp::OpShowOnly ) )
+        vtkwnd->GetRenderer()->AdjustActors();
+
       break;
     }
 
@@ -2745,18 +2857,37 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
-  case SMESHOp::OpCreateMesh:
-  case SMESHOp::OpCreateSubMesh:
   case SMESHOp::OpEditMeshOrSubMesh:
   case SMESHOp::OpEditMesh:
   case SMESHOp::OpEditSubMesh:
+  case SMESHOp::OpMeshOrder:
+  case SMESHOp::OpCreateSubMesh:
+    if ( warnOnGeomModif() )
+      break; // action forbiden as geometry modified
+
+  case SMESHOp::OpCreateMesh:
   case SMESHOp::OpCompute:
   case SMESHOp::OpComputeSubMesh:
   case SMESHOp::OpPreCompute:
   case SMESHOp::OpEvaluate:
-  case SMESHOp::OpMeshOrder:
+  case SMESHOp::OpShowErrors:
     startOperation( theCommandID );
     break;
+  case SMESHOp::OpRecompute:
+    {
+      if ( isStudyLocked() )
+        break;
+      SALOME_ListIO selected;
+      if ( LightApp_SelectionMgr *sel = selectionMgr() )
+        sel->selectedObjects( selected );
+      if ( selected.Extent() == 1 ) {
+        SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( selected.First() );
+        if ( !aMesh->_is_nil() )
+          aMesh->Clear();
+        startOperation( SMESHOp::OpCompute );
+      }
+    }
+    break;
   case SMESHOp::OpCopyMesh:
     {
       if (isStudyLocked()) break;
@@ -2783,6 +2914,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       if ( isStudyLocked() )
         break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
 
       /*Standard_Boolean aRes;
       SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IObject);
@@ -2813,6 +2946,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       if ( isStudyLocked() )
         break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
 
       EmitSignalDeactivateDialog();
       SMESHGUI_MultiEditDlg* aDlg = NULL;
@@ -2831,6 +2966,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpSmoothing:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_SmoothingDlg( this ) )->show();
@@ -2843,6 +2980,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpExtrusion:
     {
       if (isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if (vtkwnd) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_ExtrusionDlg ( this ) )->show();
@@ -2854,6 +2993,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpExtrusionAlongAPath:
     {
       if (isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if (vtkwnd) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_ExtrusionAlongPathDlg( this ) )->show();
@@ -2865,6 +3006,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpRevolution:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_RevolutionDlg( this ) )->show();
@@ -2878,6 +3021,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if ( isStudyLocked() )
         break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd )
       {
         EmitSignalDeactivateDialog();
@@ -2894,6 +3039,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpReorientFaces:
   case SMESHOp::OpCreateGeometryGroup:
     {
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       startOperation( theCommandID );
       break;
     }
@@ -2906,6 +3053,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
 
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       EmitSignalDeactivateDialog();
       SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil();
 
@@ -2933,6 +3082,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
 
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       EmitSignalDeactivateDialog();
 
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
@@ -3010,6 +3161,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
 
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       EmitSignalDeactivateDialog();
 
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
@@ -3107,6 +3260,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
       if ( isStudyLocked() )
         break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
 
       EmitSignalDeactivateDialog();
 
@@ -3127,6 +3282,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if ( isStudyLocked() )
         break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
 
       EmitSignalDeactivateDialog();
       SMESHGUI_GroupOpDlg* aDlg = new SMESHGUI_DimGroupDlg( this );
@@ -3139,6 +3296,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       if ( isStudyLocked() )
         break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
 
       EmitSignalDeactivateDialog();
       SMESHGUI_FaceGroupsSeparatedByEdgesDlg* aDlg = new SMESHGUI_FaceGroupsSeparatedByEdgesDlg( this );
@@ -3198,6 +3357,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpEditHypothesis:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
 
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
       SALOME_ListIO selected;
@@ -3243,6 +3404,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpUnassign:                      // REMOVE HYPOTHESIS / ALGORITHMS
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       SUIT_OverrideCursor wc;
 
       LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
@@ -3274,6 +3437,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpHexagonalPrism:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         SMDSAbs_EntityType type = SMDSEntity_Edge;
@@ -3300,6 +3465,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpPolyhedron:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_CreatePolyhedralVolumeDlg( this ) )->show();
@@ -3323,6 +3490,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpTriQuadraticHexahedron:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         SMDSAbs_EntityType type = SMDSEntity_Last;
@@ -3354,6 +3523,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpRemoveNodes:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_RemoveNodesDlg( this ) )->show();
@@ -3367,6 +3538,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpRemoveElements:                                    // REMOVES ELEMENTS
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_RemoveElementsDlg( this ) )->show();
@@ -3381,6 +3554,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpClearMesh: {
 
     if(isStudyLocked()) break;
+    if ( warnOnGeomModif() )
+      break; // action forbiden as geometry modified
 
     SALOME_ListIO selected;
     if( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() )
@@ -3420,6 +3595,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpRemoveOrphanNodes:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       SALOME_ListIO selected;
       if( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() )
         aSel->selectedObjects( selected );
@@ -3459,6 +3636,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpRenumberingNodes:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_RenumberingDlg( this, 0 ) )->show();
@@ -3473,6 +3652,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpRenumberingElements:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_RenumberingDlg( this, 1 ) )->show();
@@ -3487,6 +3668,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpTranslation:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_TranslationDlg( this ) )->show();
@@ -3500,6 +3683,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpRotation:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_RotationDlg( this ) )->show();
@@ -3513,6 +3698,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpSymmetry:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if(vtkwnd) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_SymmetryDlg( this ) )->show();
@@ -3526,6 +3713,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpScale:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_ScaleDlg( this ) )->show();
@@ -3540,6 +3729,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpOffset:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_OffsetDlg( this ) )->show();
@@ -3554,6 +3745,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpSewing:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if(vtkwnd) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_SewingDlg( this ) )->show();
@@ -3567,6 +3760,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpMergeNodes:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if(vtkwnd) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_MergeDlg( this, 0 ) )->show();
@@ -3580,6 +3775,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpMergeElements:
     {
       if (isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if (vtkwnd) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_MergeDlg( this, 1 ) )->show();
@@ -3591,12 +3788,16 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
 
   case SMESHOp::OpMoveNode: // MAKE MESH PASS THROUGH POINT
+    if ( warnOnGeomModif() )
+      break; // action forbiden as geometry modified
     startOperation( SMESHOp::OpMoveNode );
     break;
 
   case SMESHOp::OpDuplicateNodes:
     {
       if(isStudyLocked()) break;
+      if ( warnOnGeomModif() )
+        break; // action forbiden as geometry modified
       if ( vtkwnd ) {
         EmitSignalDeactivateDialog();
         ( new SMESHGUI_DuplicateNodesDlg( this ) )->show();
@@ -3609,6 +3810,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     }
 
   case SMESHOp::OpElem0DOnElemNodes: // 0D_ON_ALL_NODES
+    if ( warnOnGeomModif() )
+      break; // action forbiden as geometry modified
     startOperation( SMESHOp::OpElem0DOnElemNodes );
     break;
 
@@ -3742,6 +3945,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpSortChild:
     ::sortChildren();
     break;
+  case SMESHOp::OpBreakLink:
+    ::breakShaperLink();
+    break;
 
   }
 
@@ -3808,7 +4014,7 @@ void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QStr
   if ( !icon_id.isEmpty() )
     pix = resMgr->loadPixmap( "SMESH", tr( icon_id.toLatin1().data() ) );
   else
-    pix = resMgr->loadPixmap( "SMESH", tr( QString( "ICO_%1" ).arg( po_id ).toLatin1().data() ), false );
+    pix = resMgr->loadPixmap( "SMESH", tr( QString( "ICON_%1" ).arg( po_id ).toLatin1().data() ), false );
   if ( !pix.isNull() )
     icon = QIcon( pix );
 
@@ -3915,7 +4121,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( SMESHOp::OpCopyMesh,             "COPY_MESH",               "ICON_COPY_MESH" );
   createSMESHAction( SMESHOp::OpCompute,              "COMPUTE",                 "ICON_COMPUTE" );
   createSMESHAction( SMESHOp::OpComputeSubMesh,       "COMPUTE_SUBMESH",         "ICON_COMPUTE" );
+  createSMESHAction( SMESHOp::OpRecompute,            "RE_COMPUTE",              "ICON_COMPUTE" );
   createSMESHAction( SMESHOp::OpPreCompute,           "PRECOMPUTE",              "ICON_PRECOMPUTE" );
+  createSMESHAction( SMESHOp::OpShowErrors,           "SHOW_ERRORS",             "ICON_SHOW_ERRORS" );
   createSMESHAction( SMESHOp::OpEvaluate,             "EVALUATE",                "ICON_EVALUATE" );
   createSMESHAction( SMESHOp::OpMeshOrder,            "MESH_ORDER",              "ICON_MESH_ORDER");
   createSMESHAction( SMESHOp::OpCreateGroup,          "CREATE_GROUP",            "ICON_CREATE_GROUP" );
@@ -4075,6 +4283,8 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createSMESHAction( SMESHOp::OpSortChild, "SORT_CHILD_ITEMS" );
 
+  createSMESHAction( SMESHOp::OpBreakLink, "BREAK_SHAPER_LINK" );
+
   QList<int> aCtrlActions;
   aCtrlActions << SMESHOp::OpFreeNode << SMESHOp::OpEqualNode
                << SMESHOp::OpNodeConnectivityNb                                         // node controls
@@ -4467,20 +4677,22 @@ void SMESHGUI::initialize( CAM_Application* app )
     hasVolumes("({'Volume'} in elemTypes)"),
     hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) ");
 
-  createPopupItem( SMESHOp::OpFileInformation,   OB, mesh, "&& selcount=1 && isImported" );
-  createPopupItem( SMESHOp::OpCreateSubMesh,     OB, mesh, "&& hasGeomReference");
   createPopupItem( SMESHOp::OpEditMesh,          OB, mesh, "&& selcount=1" );
+  createPopupItem( SMESHOp::OpCreateSubMesh,     OB, mesh, "&& hasGeomReference");
+  createPopupItem( SMESHOp::OpMeshOrder,         OB, mesh, "&& selcount=1 && hasAlgo && hasGeomReference" );
   createPopupItem( SMESHOp::OpEditSubMesh,       OB, subMesh, "&& selcount=1 && hasGeomReference" );
   createPopupItem( SMESHOp::OpEditGroup,         OB, group );
   createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
 
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( SMESHOp::OpCompute,           OB, mesh, "&& selcount=1 && isComputable" );
-  createPopupItem( SMESHOp::OpComputeSubMesh,    OB, subMesh, "&& selcount=1 && isComputable" );
-  createPopupItem( SMESHOp::OpPreCompute,        OB, mesh, "&& selcount=1 && isPreComputable" );
-  createPopupItem( SMESHOp::OpEvaluate,          OB, mesh, "&& selcount=1 && isComputable" );
-  createPopupItem( SMESHOp::OpMeshOrder,         OB, mesh, "&& selcount=1 && isComputable && hasGeomReference" );
-  createPopupItem( SMESHOp::OpUpdate,            OB, mesh_part );
+  createPopupItem( SMESHOp::OpCompute,           OB, mesh, "&& selcount=1 && hasAlgo && isComputable" );
+  createPopupItem( SMESHOp::OpRecompute,         OB, mesh, "&& selcount=1 && hasAlgo && " + isNotEmpty );
+  createPopupItem( SMESHOp::OpShowErrors,        OB, mesh, "&& selcount=1 && hasErrors" );
+  createPopupItem( SMESHOp::OpComputeSubMesh,    OB, subMesh, "&& selcount=1 && hasAlgo && isComputable" );
+  createPopupItem( SMESHOp::OpPreCompute,        OB, mesh, "&& selcount=1 && hasAlgo && isPreComputable" );
+  createPopupItem( SMESHOp::OpEvaluate,          OB, mesh, "&& selcount=1 && hasAlgo && isComputable" );
+  popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( SMESHOp::OpFileInformation,   OB, mesh, "&& selcount=1 && isImported" );
   createPopupItem( SMESHOp::OpMeshInformation,   OB, mesh_part );
   createPopupItem( SMESHOp::OpFindElementByPoint,OB, mesh_group, "&& selcount=1" );
   createPopupItem( SMESHOp::OpOverallMeshQuality,OB, mesh_part );
@@ -4494,8 +4706,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh_submesh );
   createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh_group, "&& selcount=1 && dim>=2");
-  popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( SMESHOp::OpClearMesh,              OB, mesh );
+  //popupMgr()->insert( separator(), -1, 0 );
+
   //popupMgr()->insert( separator(), -1, 0 );
 
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
@@ -4503,6 +4715,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   QString only_one_2D        = only_one_non_empty + " && dim>1";
 
   int anId = popupMgr()->insert( tr( "MEN_EXPORT" ), -1, -1 );        // EXPORT submenu
+  popupMgr()->findMenu( anId )->menuAction()->setIcon( resourceMgr()->loadPixmap( "SMESH", tr( "ICON_EXPORT" )));
   createPopupItem( SMESHOp::OpPopupExportMED,  OB, mesh_group, multiple_non_empty, anId );
   createPopupItem( SMESHOp::OpPopupExportUNV,  OB, mesh_group, only_one_non_empty, anId );
   createPopupItem( SMESHOp::OpPopupExportSTL,  OB, mesh_group, only_one_2D, anId );
@@ -4512,8 +4725,6 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( SMESHOp::OpPopupExportSAUV, OB, mesh_group, only_one_non_empty, anId );
   createPopupItem( SMESHOp::OpPopupExportGMF,  OB, mesh_group, only_one_non_empty, anId );
   createPopupItem( SMESHOp::OpPopupExportDAT,  OB, mesh_group, only_one_non_empty, anId );
-  createPopupItem( SMESHOp::OpDelete,          OB, mesh_part + " " + hyp_alg );
-  createPopupItem( SMESHOp::OpDeleteGroup,     OB, group );
 
   anId = popupMgr()->insert( tr( "MEN_IMPORT" ), -1, -1 );        // IMPORT submenu
   createPopupItem( SMESHOp::OpPopupImportMED,  OB, smesh, "", anId );
@@ -4527,18 +4738,22 @@ void SMESHGUI::initialize( CAM_Application* app )
   createPopupItem( SMESHOp::OpPopupImportDAT,  OB, smesh, "", anId );
   popupMgr()->insert( separator(), -1, 0 );
 
+  createPopupItem( SMESHOp::OpClearMesh,         OB, mesh );
+  createPopupItem( SMESHOp::OpDelete,            OB, mesh_part + " " + hyp_alg );
+  createPopupItem( SMESHOp::OpDeleteGroup,       OB, group );
+
   // popup for viewer
   createPopupItem( SMESHOp::OpEditGroup,            View, group );
   createPopupItem( SMESHOp::OpAddElemGroupPopup,    View, elems, "&& guiState = 800" );
   createPopupItem( SMESHOp::OpRemoveElemGroupPopup, View, elems, "&& guiState = 800" );
 
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( SMESHOp::OpUpdate,             View, mesh_part );
   createPopupItem( SMESHOp::OpMeshInformation,    View, mesh_part );
   createPopupItem( SMESHOp::OpOverallMeshQuality, View, mesh_part );
   createPopupItem( SMESHOp::OpFindElementByPoint, View, mesh );
   popupMgr()->insert( separator(), -1, 0 );
 
+  createPopupItem( SMESHOp::OpUpdate,           OB + " " + View, mesh_part );
   createPopupItem( SMESHOp::OpAutoColor,        OB + " " + View, mesh, "&& (not isAutoColor)" );
   createPopupItem( SMESHOp::OpDisableAutoColor, OB + " " + View, mesh, "&& isAutoColor" );
   popupMgr()->insert( separator(), -1, 0 );
@@ -4848,6 +5063,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( SMESHOp::OpSortChild ), "$component={'SMESH'} and client='ObjectBrowser' and isContainer and nbChildren>1", QtxPopupMgr::VisibleRule );
   popupMgr()->insert( separator(), -1, -1 );
 
+  popupMgr()->insert( action( SMESHOp::OpBreakLink), -1, -1 );
+  popupMgr()->setRule( action( SMESHOp::OpBreakLink), "$component={'SHAPERSTUDY'} and client='ObjectBrowser' and canBreakLink", QtxPopupMgr::VisibleRule );
+
   connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
            this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
 
@@ -4873,8 +5091,9 @@ bool SMESHGUI::isSelectionCompatible()
   SALOME_ListIteratorOfListIO It( selected );
   for ( ; isCompatible && It.More(); It.Next())
     isCompatible =
-      ( strcmp("GEOM", It.Value()->getComponentDataType()) == 0 ) ||
-      ( strcmp("SMESH", It.Value()->getComponentDataType()) == 0 );
+      ( strcmp("GEOM",        It.Value()->getComponentDataType()) == 0 ) ||
+      ( strcmp("SHAPERSTUDY", It.Value()->getComponentDataType()) == 0 ) ||
+      ( strcmp("SMESH",       It.Value()->getComponentDataType()) == 0 );
 
   return isCompatible;
 }
@@ -4883,7 +5102,7 @@ bool SMESHGUI::isSelectionCompatible()
 bool SMESHGUI::reusableOperation( const int id )
 {
   // compute, evaluate and precompute are not reusable operations
-  return ( id == SMESHOp::OpCompute || id == SMESHOp::OpPreCompute || id == SMESHOp::OpEvaluate ) ? false : SalomeApp_Module::reusableOperation( id );
+  return ( id == SMESHOp::OpCompute || id == SMESHOp::OpPreCompute || id == SMESHOp::OpEvaluate || id == SMESHOp::OpRecompute ) ? false : SalomeApp_Module::reusableOperation( id );
 }
 
 bool SMESHGUI::activateModule( SUIT_Study* study )
@@ -4921,7 +5140,14 @@ bool SMESHGUI::activateModule( SUIT_Study* study )
     QList<SUIT_ViewWindow*> wndList = aDesk->windows();
     SUIT_ViewWindow* wnd;
     foreach ( wnd, wndList )
+    {
       connectView( wnd );
+
+      // remove actors whose objects are removed in GetSMESHGen()->UpdateStudy()
+      SMESH::UpdateActorsAfterUpdateStudy(wnd);
+
+      wnd->update();
+    }
   }
 
   Py_XDECREF(pluginsmanager);
@@ -4987,9 +5213,9 @@ void SMESHGUI::contextMenuPopup( const QString& client, QMenu* menu, QString& ti
     _PTR(Study) study = appStudy->studyDS();
     _PTR(SObject) obj = study->FindObjectID( io->getEntry() );
     if ( obj ) {
-      QString aName = QString( SMESH::fromUtf8(obj->GetName()) );
-      while ( aName.at( aName.length() - 1 ) == ' ' ) // Remove extraspaces in Name of Popup
-          aName.remove( (aName.length() - 1), 1 );
+      QString aName = SMESH::fromUtf8( obj->GetName());
+      while ( !aName.isEmpty() && aName.at( aName.length() - 1 ) == ' ' ) // Remove extraspaces in Name of Popup
+        aName.remove(( aName.length() - 1 ), 1 );
       title = aName;
     }
   }
@@ -5202,6 +5428,7 @@ void SMESHGUI::createPreferences()
                              "SMESH", "nb_segments_per_edge" );
   setPreferenceProperty( nbSeg, "min", 1 );
   setPreferenceProperty( nbSeg, "max", 10000000 );
+  addPreference( tr( "PREF_USE_MESHGEMS_HYPOSET" ), segGroup, LightApp_Preferences::Bool, "SMESH", "use-meshgems-hypo-sets" );
 
   int loadGroup = addPreference( tr( "SMESH_PREF_MESH_LOADING" ), genTab );
   addPreference( tr( "PREF_FORGET_MESH_AT_HYP_MODIF" ), loadGroup, LightApp_Preferences::Bool,
@@ -5627,55 +5854,55 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
   // to do : create operation here
   switch( id )
   {
-    case SMESHOp::OpSplitBiQuadratic:
-      op = new SMESHGUI_SplitBiQuadOp();
+  case SMESHOp::OpSplitBiQuadratic:
+    op = new SMESHGUI_SplitBiQuadOp();
     break;
-    case SMESHOp::OpConvertMeshToQuadratic:
-      op = new SMESHGUI_ConvToQuadOp();
+  case SMESHOp::OpConvertMeshToQuadratic:
+    op = new SMESHGUI_ConvToQuadOp();
     break;
-    case SMESHOp::OpCreateBoundaryElements: // create 2D mesh as boundary on 3D
-      op = new SMESHGUI_Make2DFrom3DOp();
+  case SMESHOp::OpCreateBoundaryElements: // create 2D mesh as boundary on 3D
+    op = new SMESHGUI_Make2DFrom3DOp();
     break;
-    case SMESHOp::OpReorientFaces:
-      op = new SMESHGUI_ReorientFacesOp();
-      break;
-    case SMESHOp::OpCreateMesh:
-      op = new SMESHGUI_MeshOp( true, true );
+  case SMESHOp::OpReorientFaces:
+    op = new SMESHGUI_ReorientFacesOp();
+    break;
+  case SMESHOp::OpCreateMesh:
+    op = new SMESHGUI_MeshOp( true, true );
+    break;
+  case SMESHOp::OpCreateSubMesh:
+    op = new SMESHGUI_MeshOp( true, false );
+    break;
+  case SMESHOp::OpEditMeshOrSubMesh:
+  case SMESHOp::OpEditMesh:
+  case SMESHOp::OpEditSubMesh:
+    op = new SMESHGUI_MeshOp( false );
     break;
-    case SMESHOp::OpCreateSubMesh:
-      op = new SMESHGUI_MeshOp( true, false );
+  case SMESHOp::OpCompute:
+  case SMESHOp::OpComputeSubMesh:
+    op = new SMESHGUI_ComputeOp();
+    break;
+  case SMESHOp::OpPreCompute:
+    op = new SMESHGUI_PrecomputeOp();
     break;
-    case SMESHOp::OpEditMeshOrSubMesh:
-    case SMESHOp::OpEditMesh:
-    case SMESHOp::OpEditSubMesh:
-      op = new SMESHGUI_MeshOp( false );
+  case SMESHOp::OpEvaluate:
+    op = new SMESHGUI_EvaluateOp();
+    break;
+  case SMESHOp::OpMeshOrder:
+    op = new SMESHGUI_MeshOrderOp();
     break;
-    case SMESHOp::OpCompute:
-    case SMESHOp::OpComputeSubMesh:
-      op = new SMESHGUI_ComputeOp();
+  case SMESHOp::OpCreateGeometryGroup:
+    op = new SMESHGUI_GroupOnShapeOp();
     break;
-    case SMESHOp::OpPreCompute:
-      op = new SMESHGUI_PrecomputeOp();
+  case SMESHOp::OpFindElementByPoint:
+    op = new SMESHGUI_FindElemByPointOp();
     break;
-    case SMESHOp::OpEvaluate:
-      op = new SMESHGUI_EvaluateOp();
+  case SMESHOp::OpMoveNode: // Make mesh pass through point
+    op = new SMESHGUI_MakeNodeAtPointOp();
     break;
-    case SMESHOp::OpMeshOrder:
-      op = new SMESHGUI_MeshOrderOp();
+  case SMESHOp::OpElem0DOnElemNodes: // Create 0D elements on all nodes
+    op = new SMESHGUI_Add0DElemsOnAllNodesOp();
     break;
-    case SMESHOp::OpCreateGeometryGroup:
-      op = new SMESHGUI_GroupOnShapeOp();
-      break;
-    case SMESHOp::OpFindElementByPoint:
-      op = new SMESHGUI_FindElemByPointOp();
-      break;
-    case SMESHOp::OpMoveNode: // Make mesh pass through point
-      op = new SMESHGUI_MakeNodeAtPointOp();
-      break;
-    case SMESHOp::OpElem0DOnElemNodes: // Create 0D elements on all nodes
-      op = new SMESHGUI_Add0DElemsOnAllNodesOp();
-      break;
-    default:
+  default:
     break;
   }
 
@@ -6129,8 +6356,6 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
 
   // componentName is used for encoding of entries when storing them in IParameters
   std::string componentName = myComponentSMESH->ComponentDataType();
-  //_PTR(SComponent) aSComponent = studyDS->FindComponent("GEOM");
-  //if (!aSComponent) return;
 
   // IParameters
   _PTR(AttributeParameter) ap = studyDS->GetModuleParameters("Interface Applicative",