Salome HOME
PR: synchro V6_main tag mergeto_V7_main_11Feb13
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOp.cxx
index 1e314d04557ddd4df5d07da3fab159c9d6e9889d..9d9aa1c0ccc2c9516e4e7ab4b0551bc3062ebffb 100644 (file)
@@ -1,25 +1,24 @@
-//  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
 //
-//  SMESH SMESHGUI : GUI for SMESH component
 //  File   : SMESHGUI_MeshOp.cxx
 //  Author : Sergey LITONIN, Open CASCADE S.A.S.
 
 #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>
@@ -146,16 +150,20 @@ 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 )
@@ -240,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 );
+    }
+  }
 }
 
 //================================================================================
@@ -270,16 +300,16 @@ 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
  */
 //================================================================================
@@ -309,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
@@ -325,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;
@@ -510,13 +539,13 @@ void SMESHGUI_MeshOp::selectionDone()
           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
-              TopoDS_Shape aShape;
-             bool isClosed = GEOMBase::GetShape(aGeomVar, aShape) && /*aShape.Closed()*/BRep_Tool::IsClosed(aShape);
-              shapeDim = qMax(isClosed ? 3 : 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 = qMax(1, shapeDim); break;
@@ -524,16 +553,21 @@ void SMESHGUI_MeshOp::selectionDone()
           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 = qMax(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 = qMax(2, shapeDim);
                 else if ( exp.Init( aShape, TopAbs_EDGE ), exp.More() )
@@ -543,6 +577,8 @@ void SMESHGUI_MeshOp::selectionDone()
               }
             }
           }
+          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
       {
@@ -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,
@@ -856,7 +898,8 @@ 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 )) &&
@@ -876,7 +919,7 @@ 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.
@@ -1062,7 +1105,7 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
       SMESH::CreateHypothesis(theTypeName, aHypName, false);
 #ifdef WITHGENERICOBJ
     if (!CORBA::is_nil(aHyp))
-      aHyp->Destroy();
+      aHyp->UnRegister();
 #endif
   } else {
     // Get hypotheses creator client (GUI)
@@ -1138,7 +1181,7 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
        SMESH::CreateHypothesis(theTypeName, aHypName, false);
 #ifdef WITHGENERICOBJ
      if (!CORBA::is_nil(aHyp))
-       aHyp->Destroy();
+       aHyp->UnRegister();
 #endif
     }
   }
@@ -1554,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 = "";
 
@@ -1587,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;
@@ -1612,7 +1658,7 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
     // It is safe to decrement its refcount
     // so that it will be destroyed when the entry in study will be removed
     if (aMeshSO)
-      aMeshVar->Destroy();
+      aMeshVar->UnRegister();
 #endif
   }
   return true;
@@ -1622,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 = "";
 
@@ -1666,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
@@ -1691,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);
         }
       }
     }
@@ -1717,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++ )
   {
@@ -1742,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();
@@ -1875,14 +1925,13 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
           SMESH::CreateHypothesis(aHypName, aHypName, true);
 #ifdef WITHGENERICOBJ
         if (!CORBA::is_nil(aHyp))
-          aHyp->Destroy();
+          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
@@ -1893,7 +1942,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
             SMESH::CreateHypothesis(aHypName, aHypName, true);
 #ifdef WITHGENERICOBJ
           if (!CORBA::is_nil(aHyp))
-            aHyp->Destroy();
+            aHyp->UnRegister();
 #endif
         }
       }
@@ -1920,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()
@@ -1960,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 ] );
@@ -1985,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++ )
     {