Salome HOME
PR: synchro V6_main tag mergeto_V7_main_11Feb13
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOp.cxx
index 1739b419c7dcab07e1efe08b281f8210985cec5f..9d9aa1c0ccc2c9516e4e7ab4b0551bc3062ebffb 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"
 #include <GEOM_SelectionFilter.h>
 #include <GEOMBase.h>
 #include <GeometryGUI.h>
+#include <GEOM_wrap.hxx>
 
 // 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>
 
 // SALOME KERNEL includes
 #include <SALOMEDS_SComponent.hxx>
 #include <SALOMEDS_SObject.hxx>
+#include <SALOMEDS_Study.hxx>
+#include <SALOMEDS_wrap.hxx>
 
 // Qt includes
 #include <QStringList>
 #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 +150,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 +248,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 );
+    }
+  }
 }
 
 //================================================================================
@@ -264,20 +300,19 @@ SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const
     return new GEOM_SelectionFilter( (SalomeApp_Study*)study(), true );
   }
   else if ( theId == SMESHGUI_MeshDlg::Obj && !myToCreate )
-    return new SMESH_TypeFilter( MESHorSUBMESH );
+    return new SMESH_TypeFilter( SMESH::MESHorSUBMESH );
   else if ( theId == SMESHGUI_MeshDlg::Mesh )
-    return new SMESH_TypeFilter( MESH );
+    return new SMESH_TypeFilter( SMESH::MESH );
   else
     return 0;
 }
 
 //================================================================================
 /*!
- * \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
@@ -304,8 +339,7 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
     if (geomGen->_is_nil() || !aStudy) return false;
 
-    GEOM::GEOM_IGroupOperations_var op =
-        geomGen->GetIGroupOperations(aStudy->StudyId());
+    GEOM::GEOM_IGroupOperations_wrap op = geomGen->GetIGroupOperations(aStudy->StudyId());
     if (op->_is_nil()) return false;
 
     // check all selected shapes
@@ -320,18 +354,18 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const
       if (aSubGeomVar->_is_nil()) return false;
 
       // skl for NPAL14695 - implementation of searching of mainObj
-      GEOM::GEOM_Object_var mainObj = op->GetMainShape(aSubGeomVar);
-      //if (mainObj->_is_nil() ||
-      //    string(mainObj->GetEntry()) != string(mainGeom->GetEntry())) return false;
+      GEOM::GEOM_Object_var mainObj = op->GetMainShape(aSubGeomVar); /* _var not _wrap as
+                                                                        mainObj already exists! */
       while(1) {
         if (mainObj->_is_nil())
           return false;
-        if (std::string(mainObj->GetEntry()) == std::string(mainGeom->GetEntry()))
+        CORBA::String_var entry1 = mainObj->GetEntry();
+        CORBA::String_var entry2 = mainGeom->GetEntry();
+        if (std::string( entry1.in() ) == entry2.in() )
           return true;
         mainObj = op->GetMainShape(mainObj);
       }
     }
-    //return true;
   }
 
   return false;
@@ -340,11 +374,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 +423,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 +533,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 +586,7 @@ void SMESHGUI_MeshOp::selectionDone()
         onAlgoSelected(-1, i);
       }
       myDlg->setMaxHypoDim( shapeDim );
-
+      myDlg->setHypoSets( SMESH::GetHypothesesSets( shapeDim ));
 
       if (!myToCreate) // edition: read hypotheses
       {
@@ -578,7 +614,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 +650,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 +782,6 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const
   * \retval bool - check result
  */
 //================================================================================
-
 static bool isCompatible(const HypothesisData* theAlgoData,
                          const HypothesisData* theHypData,
                          const int             theHypType)
@@ -857,7 +898,9 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim,
           SMESH::SMESH_Hypothesis_var aHypVar = SMESH::SMESH_Hypothesis::_narrow( aVar );
           if ( !aHypVar->_is_nil() )
           {
-            HypothesisData* aData = SMESH::GetHypothesisData( aHypVar->GetName() );
+            CORBA::String_var hypType = aHypVar->GetName();
+            HypothesisData* aData = SMESH::GetHypothesisData( hypType.in() );
+            if ( !aData) continue;
             if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) &&
                  ( isCompatible ( theAlgoData, aData, theHypType )) &&
                  ( isAux == aData->IsAux ))
@@ -876,14 +919,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 +1011,6 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
   * \retval int - dimention
  */
 //================================================================================
-
 static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
 {
   int aDim = -1;
@@ -1027,10 +1068,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 +1101,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 +1128,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 +1168,7 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
           }
         }
       }
-      
+
       aCreator->setShapeEntry( aGeomEntry );
       if ( aMeshEntry != "" )
         aCreator->setMainShapeEntry( aMeshEntry );
@@ -1122,8 +1176,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 +1249,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 +1265,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 +1338,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 +1355,6 @@ HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
   * \param theIndex - algorithm index
  */
 //================================================================================
-
 void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
                                       const int theDim )
 {
@@ -1532,12 +1597,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 +1631,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 +1653,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 +1668,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 = "";
 
@@ -1638,7 +1713,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
     GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
     if (!geomGen->_is_nil() && aStudy) {
-      GEOM::GEOM_IGroupOperations_var op =
+      GEOM::GEOM_IGroupOperations_wrap op =
         geomGen->GetIGroupOperations(aStudy->StudyId());
       if (!op->_is_nil()) {
         // check and add all selected GEOM objects: they must be
@@ -1663,18 +1738,19 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
           aSeq[iSubSh] = aSubGeomVar;
         }
         // create a group
-        GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(mainGeom, aGroupType);
+        GEOM::GEOM_Object_wrap aGroupVar = op->CreateGroup(mainGeom, aGroupType);
         op->UnionList(aGroupVar, aSeq);
 
         if (op->IsDone()) {
-          aGeomVar = aGroupVar;
+          aGeomVar = aGroupVar.in();
 
           // publish the GEOM group in study
           QString aNewGeomGroupName ("Auto_group_for_");
           aNewGeomGroupName += aName;
-          SALOMEDS::SObject_var aNewGroupSO =
-            geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, 
-                                aNewGeomGroupName.toLatin1().data(), mainGeom);
+          SALOMEDS::Study_var aStudyVar = _CAST(Study, aStudy)->GetStudy();
+          SALOMEDS::SObject_wrap aNewGroupSO =
+            geomGen->AddInStudy( aStudyVar, aGeomVar,
+                                 aNewGeomGroupName.toLatin1().data(), mainGeom);
         }
       }
     }
@@ -1689,8 +1765,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 +1792,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 +1921,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" );
@@ -1881,10 +1969,9 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
 
 //================================================================================
 /*!
- * \brief Reads parameters of edited mesh and assigns them to the dialog
+ * \brief Reads parameters of an edited mesh and assigns them to the dialog
  *
- * Reads parameters of edited mesh and assigns them to the dialog (called when
- * mesh is edited only)
+ * Called when mesh is edited only.
  */
 //================================================================================
 void SMESHGUI_MeshOp::readMesh()
@@ -1921,8 +2008,8 @@ void SMESHGUI_MeshOp::readMesh()
 
   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
   QStringList anExisting;
-  const int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
-  for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
+  const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
+  for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
   {
     // get algorithm
     existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] );
@@ -1946,7 +2033,7 @@ void SMESHGUI_MeshOp::readMesh()
 
   // get hypotheses
   bool hypWithoutAlgo = false;
-  for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
+  for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
   {
     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
     {
@@ -2157,14 +2244,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 +2261,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 +2295,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 +2318,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 +2328,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() ) {