Salome HOME
Merge from V6_5_BR 05/06/2012
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOp.cxx
index 1739b419c7dcab07e1efe08b281f8210985cec5f..9ad1a47fc5ae4d4a5ae928f3d6d315ce80107e92 100644 (file)
@@ -1,30 +1,28 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  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
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  File   : SMESHGUI_MeshOp.cxx
+//  Author : Sergey LITONIN, Open CASCADE S.A.S.
 
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI_MeshOp.cxx
-// Author : Sergey LITONIN, Open CASCADE S.A.S.
 // SMESH includes
-//
 #include "SMESHGUI_MeshOp.h"
 
 #include "SMESHGUI.h"
 // SALOME GUI includes
 #include <SalomeApp_Tools.h>
 #include <SalomeApp_Application.h>
+#include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 #include <LightApp_UpdateFlags.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_OverrideCursor.h>
+#include <SUIT_Session.h>
 #include <SALOME_InteractiveObject.hxx>
 #include <SALOME_ListIO.hxx>
 
 #include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SMESH_Gen)
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //================================================================================
 /*!
  * \brief Constructor
@@ -143,14 +147,21 @@ bool SMESHGUI_MeshOp::onApply()
   aMess = "";
   try
   {
+    QStringList anEntryList;
     if ( myToCreate && myIsMesh )
-      aResult = createMesh( aMess );
+      aResult = createMesh( aMess, anEntryList );
     if ( myToCreate && !myIsMesh )
-      aResult = createSubMesh( aMess );
+      aResult = createSubMesh( aMess, anEntryList );
     else if ( !myToCreate )
       aResult = editMeshOrSubMesh( aMess );
     if ( aResult )
+    {
+      SMESHGUI::Modified();
       update( UF_ObjBrowser | UF_Model );
+      if( LightApp_Application* anApp =
+          dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+        myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() );
+    }
   }
   catch ( const SALOME::SALOME_Exception& S_ex )
   {
@@ -234,14 +245,36 @@ void SMESHGUI_MeshOp::startOperation()
   else
     myDlg->activateObject( SMESHGUI_MeshDlg::Obj );
 
-  myDlg->setHypoSets( SMESH::GetHypothesesSets() );
-
   myDlg->setCurrentTab( SMESH::DIM_3D );
   myDlg->show();
-
+  myDlg->setGeomPopupEnabled(false);
   selectionDone();
 
   myIgnoreAlgoSelection = false;
+
+  myObjectToSelect.clear();
+}
+
+//=================================================================================
+/*!
+ * \brief Selects a recently created mesh or sub-mesh if necessary
+ *
+ * Virtual method redefined from base class called when operation is commited
+ * selects a recently created mesh or sub-mesh if necessary. Allows to perform
+ * selection when the custom selection filters are removed.
+ */
+//=================================================================================
+void SMESHGUI_MeshOp::commitOperation()
+{
+  SMESHGUI_SelectionOp::commitOperation();
+
+  if ( !myObjectToSelect.isEmpty() ) {
+    if ( LightApp_SelectionMgr* aSelectionMgr = selectionMgr() ) {
+      SUIT_DataOwnerPtrList aList;
+      aList.append( new LightApp_DataOwner( myObjectToSelect ) );
+      aSelectionMgr->setSelected( aList );
+    }
+  }
 }
 
 //================================================================================
@@ -273,11 +306,10 @@ SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const
 
 //================================================================================
 /*!
- * \brief check if selected shape is a subshape of the shape to mesh
+ * \brief check if selected shape is a sub-shape of the shape to mesh
   * \retval bool - check result
  */
 //================================================================================
-
 bool SMESHGUI_MeshOp::isSubshapeOk() const
 {
   if ( !myToCreate || myIsMesh ) // not submesh creation
@@ -340,11 +372,10 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const
 //================================================================================
 /*!
  * \brief Return name of the algorithm that does not support submeshes and makes
- * submesh creation useless 
+ * submesh creation useless
  *  \retval char* - string is to be deleted!!!
  */
 //================================================================================
-
 char* SMESHGUI_MeshOp::isSubmeshIgnored() const
 {
   if ( myToCreate && !myIsMesh ) {
@@ -390,7 +421,6 @@ char* SMESHGUI_MeshOp::isSubmeshIgnored() const
  * \retval _PTR(SObject) - the found submesh SObject
  */
 //================================================================================
-
 _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const
 {
   QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
@@ -501,48 +531,52 @@ void SMESHGUI_MeshOp::selectionDone()
       }
 
       if (aSeq->length() > 0) {
-        shapeDim = 0;
+        shapeDim = -1;
         for (int iss = 0; iss < aSeq->length() && shapeDim < 3; iss++) {
           GEOM::GEOM_Object_var aGeomVar = aSeq[iss];
           switch ( aGeomVar->GetShapeType() ) {
           case GEOM::SOLID:  shapeDim = 3; break;
           case GEOM::SHELL:
-            {
-              //shapeDim = 3; // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
-              shapeDim = (shapeDim < 2) ? 2 : shapeDim;
-              TopoDS_Shape aShape;
-              if (GEOMBase::GetShape(aGeomVar, aShape)) {
-                if (/*aShape.Closed()*/BRep_Tool::IsClosed(aShape))
-                  shapeDim = 3;
-              }
-            }
-            break;
-          case GEOM::FACE:   shapeDim = (shapeDim < 2) ? 2 : shapeDim; break;
+            // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
+            // {
+            //   TopoDS_Shape aShape;
+            //   bool isClosed = GEOMBase::GetShape(aGeomVar, aShape) && /*aShape.Closed()*/BRep_Tool::IsClosed(aShape);
+            //   shapeDim = qMax(isClosed ? 3 : 2, shapeDim);
+            // }
+            // break;
+          case GEOM::FACE:   shapeDim = qMax(2, shapeDim); break;
           case GEOM::WIRE:
-          case GEOM::EDGE:   shapeDim = (shapeDim < 1) ? 1 : shapeDim; break;
-          case GEOM::VERTEX: break;
+          case GEOM::EDGE:   shapeDim = qMax(1, shapeDim); break;
+          case GEOM::VERTEX: shapeDim = qMax(0, shapeDim); break;
           default:
             {
               TopoDS_Shape aShape;
-              if (GEOMBase::GetShape(aGeomVar, aShape)) {
-                TopExp_Explorer exp (aShape, TopAbs_SHELL);
+              if (GEOMBase::GetShape(aGeomVar, aShape))
+              {
+                TopExp_Explorer exp (aShape, TopAbs_SOLID);
                 if (exp.More()) {
-                  //shapeDim = 3; // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
-                  shapeDim = (shapeDim < 2) ? 2 : shapeDim;
-                  for (; exp.More() && shapeDim == 2; exp.Next()) {
-                    if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current()))
-                      shapeDim = 3;
-                  }
+                  shapeDim = 3;
                 }
+                // Bug 0016155: EDF PAL 447: If the shape is a Shell, disable 3D tab
+                // else if ( exp.Init( aShape, TopAbs_SHELL ), exp.More() )
+                // {
+                //   shapeDim = 2;
+                //   for (; exp.More() && shapeDim == 2; exp.Next()) {
+                //     if (/*exp.Current().Closed()*/BRep_Tool::IsClosed(exp.Current()))
+                //       shapeDim = 3;
+                //   }
+                // }
                 else if ( exp.Init( aShape, TopAbs_FACE ), exp.More() )
-                  shapeDim = (shapeDim < 2) ? 2 : shapeDim;
+                  shapeDim = qMax(2, shapeDim);
                 else if ( exp.Init( aShape, TopAbs_EDGE ), exp.More() )
-                  shapeDim = (shapeDim < 1) ? 1 : shapeDim;
-                else
-                  ;//shapeDim = 0;
+                  shapeDim = qMax(1, shapeDim);
+                else if ( exp.Init( aShape, TopAbs_VERTEX ), exp.More() )
+                  shapeDim = qMax(0, shapeDim);
               }
             }
           }
+          if ( shapeDim == 3 )
+            break;
         }
       }
       for (int i = SMESH::DIM_3D; i > shapeDim; i--) {
@@ -550,7 +584,7 @@ void SMESHGUI_MeshOp::selectionDone()
         onAlgoSelected(-1, i);
       }
       myDlg->setMaxHypoDim( shapeDim );
-
+      myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim ));
 
       if (!myToCreate) // edition: read hypotheses
       {
@@ -578,7 +612,7 @@ void SMESHGUI_MeshOp::selectionDone()
           bool editSubmesh = ( !sm->_is_nil() &&
                                SUIT_MessageBox::question( myDlg, tr( "SMESH_WARNING" ),
                                                           tr( "EDIT_SUBMESH_QUESTION"),
-                                                          SUIT_MessageBox::Yes | 
+                                                          SUIT_MessageBox::Yes |
                                                           SUIT_MessageBox::No,
                                                           SUIT_MessageBox::No )
                                == SUIT_MessageBox::Yes );
@@ -614,13 +648,19 @@ void SMESHGUI_MeshOp::selectionDone()
         QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
         if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() )) {
           SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( pMesh );
-          if ( !mesh->_is_nil() )
+          if ( !mesh->_is_nil() ) {
+            //rnv: issue 21056: EDF 1608 SMESH: Dialog Box "Create Sub Mesh": focus should automatically switch to geometry
+            QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+            _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.toLatin1().data() );
+            if ( !pGeom || GEOM::GEOM_Object::_narrow( _CAST( SObject,pGeom )->GetObject() )->_is_nil() )
+              myDlg->activateObject(SMESHGUI_MeshDlg::Geom);
             enable = ( shapeDim > 1 ) && ( mesh->NbEdges() > 0 );
+          }
         }
         myDlg->setGeomPopupEnabled( enable );
       }
     }
-    else {
+    else { // no geometry defined
       myDlg->enableTab( SMESH::DIM_3D );
       QStringList hypList;
       availableHyps( SMESH::DIM_3D, Algo, hypList,
@@ -740,7 +780,6 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
   * \retval bool - check result
  */
 //================================================================================
-
 static bool isCompatible(const HypothesisData* theAlgoData,
                          const HypothesisData* theHypData,
                          const int             theHypType)
@@ -858,6 +897,7 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
           if ( !aHypVar->_is_nil() )
           {
             HypothesisData* aData = SMESH::GetHypothesisData( aHypVar->GetName() );
+            if ( !aData) continue;
             if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
                  ( isCompatible ( theAlgoData, aData, theHypType )) &&
                  ( isAux == aData->IsAux ))
@@ -876,14 +916,13 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
 //================================================================================
 /*!
  * \brief If create or edit a submesh, return a hypothesis holding parameters used
- *        to mesh a subshape
+ *        to mesh a sub-shape
   * \param aHypType - The hypothesis type name
   * \param aServerLib - Server library name
   * \param hypData - The structure holding the hypothesis type etc.
   * \retval SMESH::SMESH_Hypothesis_var - the hypothesis holding parameter values
  */
 //================================================================================
-
 SMESH::SMESH_Hypothesis_var
 SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
                                           const QString& aServerLib ) const
@@ -969,7 +1008,6 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
   * \retval int - dimention
  */
 //================================================================================
-
 static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
 {
   int aDim = -1;
@@ -1027,10 +1065,9 @@ namespace
  *  \param theTypeName - specifies hypothesis to be created
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::createHypothesis(const int theDim,
-                                        const int theType,
-                                        const QString& theTypeName)
+                                       const int theType,
+                                       const QString& theTypeName)
 {
   HypothesisData* aData = SMESH::GetHypothesisData(theTypeName);
   if (!aData)
@@ -1061,7 +1098,12 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
   QString aClientLibName = aData->ClientLibName;
   if (aClientLibName == "") {
     // Call hypothesis creation server method (without GUI)
-    SMESH::CreateHypothesis(theTypeName, aHypName, false);
+    SMESH::SMESH_Hypothesis_var aHyp =
+      SMESH::CreateHypothesis(theTypeName, aHypName, false);
+#ifdef WITHGENERICOBJ
+    if (!CORBA::is_nil(aHyp))
+      aHyp->UnRegister();
+#endif
   } else {
     // Get hypotheses creator client (GUI)
     // BUG 0020378
@@ -1083,21 +1125,30 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
       aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
       aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
       anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
-      
-      if ( aMeshEntry != "" ) { // Get Geom object from Mesh
+
+      if ( myToCreate && myIsMesh )
+        aMeshEntry = aGeomEntry;
+
+      if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
         _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
         GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
         aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry();
       }
-      
-      if ( aMeshEntry == "" && aGeomEntry == "" ) {
+
+      if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
         _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
-        GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
+        bool isMesh;
+        GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
         if ( !aGeomVar->_is_nil() )
+        {
           aGeomEntry = aGeomVar->GetStudyEntry();
+          if ( isMesh )
+            aMeshEntry = aGeomEntry;
+        }
       }
 
-      if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) { // take geometry from submesh
+      if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
+        // take geometry from submesh being created
         _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
         if ( pObj ) {
           // if current object is sub-mesh
@@ -1114,7 +1165,7 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
           }
         }
       }
-      
+
       aCreator->setShapeEntry( aGeomEntry );
       if ( aMeshEntry != "" )
         aCreator->setMainShapeEntry( aMeshEntry );
@@ -1122,8 +1173,14 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
       aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) );
       dialog = true;
     }
-    else
-      SMESH::CreateHypothesis(theTypeName, aHypName, false);
+    else {
+     SMESH::SMESH_Hypothesis_var aHyp =
+       SMESH::CreateHypothesis(theTypeName, aHypName, false);
+#ifdef WITHGENERICOBJ
+     if (!CORBA::is_nil(aHyp))
+       aHyp->UnRegister();
+#endif
+    }
   }
 
   if( !dialog )
@@ -1189,8 +1246,6 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
   if ( aHyp->_is_nil() )
     return;
 
-  // BUG 0020378
-  //SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHyp->GetName());
   SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHyp->GetName());
   if ( aCreator )
   {
@@ -1207,20 +1262,29 @@ void SMESHGUI_MeshOp::onEditHyp( const int theHypType, const int theIndex )
     aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
     anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
 
-    if ( aMeshEntry != "" ) { // Get Geom object from Mesh
+    if ( myToCreate && myIsMesh )
+      aMeshEntry = aGeomEntry;
+
+    if ( aMeshEntry != aGeomEntry ) { // Get Geom object from Mesh of a sub-mesh being edited
       _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
       GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
       aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry();
     }
 
-    if ( aMeshEntry == "" && aGeomEntry == "" ) {
+    if ( aMeshEntry == "" && aGeomEntry == "" ) { // get geom of an object being edited
       _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
-      GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj );
+      bool isMesh;
+      GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj, &isMesh );
       if ( !aGeomVar->_is_nil() )
+      {
         aGeomEntry = aGeomVar->GetStudyEntry();
+        if ( isMesh )
+          aMeshEntry = aGeomEntry;
+      }
     }
 
-    if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) { // take geometry from submesh
+    if ( anObjEntry != "" && aGeomEntry != "" && aMeshEntry == "" ) {
+      // take geometry from submesh being created
       _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() );
       if ( pObj ) {
         // if current object is sub-mesh
@@ -1271,7 +1335,6 @@ void SMESHGUI_MeshOp::onHypoEdited( int result )
   * \retval HypothesisData* - result data, may be 0
  */
 //================================================================================
-
 HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
                                           const int theHypType,
                                           const int theIndex)
@@ -1289,7 +1352,6 @@ HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
   * \param theIndex - algorithm index
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
                                       const int theDim )
 {
@@ -1532,12 +1594,13 @@ void SMESHGUI_MeshOp::processSet()
 /*!
  * \brief Creates mesh
   * \param theMess - Output parameter intended for returning error message
+  * \param theEntryList - List of entries of published objects
   * \retval bool  - TRUE if mesh is created, FALSE otherwise
  *
  * Creates mesh
  */
 //================================================================================
-bool SMESHGUI_MeshOp::createMesh( QString& theMess )
+bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
 {
   theMess = "";
 
@@ -1565,8 +1628,10 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
     if ( aMeshVar->_is_nil() )
       return false;
     _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshVar.in() );
-    if ( aMeshSO )
+    if ( aMeshSO ) {
       SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ) );
+      theEntryList.append( aMeshSO->GetID().c_str() );
+    }
 
     for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) {
       if ( !isAccessibleDim( aDim )) continue;
@@ -1585,7 +1650,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
       if ( !anAlgoVar->_is_nil() )
         SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar );
     }
-
+#ifdef WITHGENERICOBJ
+    // obj has been published in study. Its refcount has been incremented.
+    // It is safe to decrement its refcount
+    // so that it will be destroyed when the entry in study will be removed
+    if (aMeshSO)
+      aMeshVar->UnRegister();
+#endif
   }
   return true;
 }
@@ -1594,12 +1665,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
 /*!
  * \brief Creates sub-mesh
   * \param theMess - Output parameter intended for returning error message
+  * \param theEntryList - List of entries of published objects
   * \retval bool  - TRUE if sub-mesh is created, FALSE otherwise
  *
  * Creates sub-mesh
  */
 //================================================================================
-bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
+bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList )
 {
   theMess = "";
 
@@ -1673,7 +1745,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
           QString aNewGeomGroupName ("Auto_group_for_");
           aNewGeomGroupName += aName;
           SALOMEDS::SObject_var aNewGroupSO =
-            geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, 
+            geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar,
                                 aNewGeomGroupName.toLatin1().data(), mainGeom);
         }
       }
@@ -1689,8 +1761,10 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
   // create sub-mesh
   SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.toLatin1().data() );
   _PTR(SObject) aSubMeshSO = SMESH::FindSObject( aSubMeshVar.in() );
-  if ( aSubMeshSO )
+  if ( aSubMeshSO ) {
     SMESH::SetName( aSubMeshSO, aName.toLatin1().data() );
+    theEntryList.append( aSubMeshSO->GetID().c_str() );
+  }
 
   for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
   {
@@ -1714,7 +1788,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
     }
   }
 
-  // deselect geometry: next submesh should be created on other subshape
+  // deselect geometry: next submesh should be created on other sub-shape
   myDlg->clearSelection( SMESHGUI_MeshDlg::Geom );
   selectObject( _PTR(SObject)() );
   selectionDone();
@@ -1843,20 +1917,30 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
       if (aClientLibName == "")
       {
         // Call hypothesis creation server method (without GUI)
-        SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
+        SMESH::SMESH_Hypothesis_var aHyp =
+          SMESH::CreateHypothesis(aHypName, aHypName, true);
+#ifdef WITHGENERICOBJ
+        if (!CORBA::is_nil(aHyp))
+          aHyp->UnRegister();
+#endif
       }
       else
       {
         // Get hypotheses creator client (GUI)
         // BUG 0020378
-        //SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypName);
         SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(aHypName);
 
         // Create algorithm
         if (aCreator)
           aCreator->create(true, aHypName, myDlg, 0, QString::null );
-        else
-          SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
+        else {
+          SMESH::SMESH_Hypothesis_var aHyp =
+            SMESH::CreateHypothesis(aHypName, aHypName, true);
+#ifdef WITHGENERICOBJ
+          if (!CORBA::is_nil(aHyp))
+            aHyp->UnRegister();
+#endif
+        }
       }
       QStringList tmpList;
       _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
@@ -2157,14 +2241,14 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
 //================================================================================
 /*!
  * \brief Verifies whether given operator is valid for this one
 * \param theOtherOp - other operation
 * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
-*
-* method redefined from base class verifies whether given operator is valid for
-* this one (i.e. can be started "above" this operator). In current implementation method
-* retuns false if theOtherOp operation is not intended for deleting objects or mesh
-* elements.
-*/
+ * \param theOtherOp - other operation
+ * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise
+ *
+ * method redefined from base class verifies whether given operator is valid for
+ * this one (i.e. can be started "above" this operator). In current implementation method
+ * retuns false if theOtherOp operation is not intended for deleting objects or mesh
+ * elements.
+ */
 //================================================================================
 bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
 {
@@ -2174,10 +2258,9 @@ bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const
 //================================================================================
 /*!
  * \brief SLOT. Is called when the user selects a way of geometry selection
 * \param theByMesh - true if the user wants to find geometry by mesh element
+ * \param theByMesh - true if the user wants to find geometry by mesh element
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh )
 {
   if ( theByMesh ) {
@@ -2209,7 +2292,6 @@ void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh )
  * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op)
 {
   if ( myShapeByMeshOp == op ) {
@@ -2233,7 +2315,6 @@ void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op)
  * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op)
 {
   if ( myShapeByMeshOp == op && myDlg ) {
@@ -2244,10 +2325,9 @@ void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op)
 //================================================================================
 /*!
  * \brief Selects a SObject
 * \param theSObj - the SObject to select
+ * \param theSObj - the SObject to select
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const
 {
   if ( LightApp_SelectionMgr* sm = selectionMgr() ) {