Salome HOME
23586: [EDF] HYDRO: Copy mesh to new geometry
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MeshOp.cxx
index b6c53436919659381b67d54b348281e1d3c4cec3..c5350a76d8b41afb3ac60a48ebafb36761b3c074 100644 (file)
@@ -92,6 +92,7 @@ SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh )
   myShapeByMeshOp( 0 ),
   myToCreate( theToCreate ),
   myIsMesh( theIsMesh ),
+  myIsInvalidSubMesh( false ),
   myHypoSet( 0 )
 {
   if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists
@@ -152,7 +153,7 @@ bool SMESHGUI_MeshOp::onApply()
     QStringList anEntryList;
     if ( myToCreate && myIsMesh )
       aResult = createMesh( aMess, anEntryList );
-    if ( myToCreate && !myIsMesh )
+    if (( myToCreate && !myIsMesh ) || myIsInvalidSubMesh )
       aResult = createSubMesh( aMess, anEntryList );
     else if ( !myToCreate )
       aResult = editMeshOrSubMesh( aMess );
@@ -200,6 +201,8 @@ bool SMESHGUI_MeshOp::onApply()
 //================================================================================
 void SMESHGUI_MeshOp::startOperation()
 {
+  myIgnoreAlgoSelection = false;
+
   if (!myDlg)
   {
     myDlg = new SMESHGUI_MeshDlg( myToCreate, myIsMesh );
@@ -216,11 +219,11 @@ void SMESHGUI_MeshOp::startOperation()
     connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool )));
     connect( myDlg, SIGNAL( selectMeshType( const int, const int ) ), SLOT( onAlgoSetByMeshType( const int, const int)));
     if ( myToCreate ) {
-      if ( myIsMesh ) myHelpFileName = "constructing_meshes_page.html";
-      else            myHelpFileName = "constructing_submeshes_page.html";
+      if ( myIsMesh ) myHelpFileName = "constructing_meshes.html";
+      else            myHelpFileName = "constructing_submeshes.html";
     }
     else {
-      myHelpFileName = "editing_meshes_page.html";
+      myHelpFileName = "editing_meshes.html";
     }
   }
   SMESHGUI_SelectionOp::startOperation();
@@ -260,7 +263,6 @@ void SMESHGUI_MeshOp::startOperation()
   myDlg->setGeomPopupEnabled(false);
   selectionDone();
 
-  myIgnoreAlgoSelection = false;
   myHasConcurrentSubBefore = false;
 
   myObjectToSelect.clear();
@@ -270,7 +272,7 @@ void SMESHGUI_MeshOp::startOperation()
 /*!
  * \brief Selects a recently created mesh or sub-mesh if necessary
  *
- * Virtual method redefined from base class called when operation is commited
+ * Virtual method redefined from base class called when operation is committed
  * selects a recently created mesh or sub-mesh if necessary. Allows to perform
  * selection when the custom selection filters are removed.
  */
@@ -519,6 +521,7 @@ void SMESHGUI_MeshOp::selectionDone()
   try
   {
     myIsOnGeometry = true;
+    myIsInvalidSubMesh = false;
 
     //Check geometry for mesh
     QString anObjEntry = myDlg->selectedObject(SMESHGUI_MeshDlg::Obj);
@@ -637,13 +640,24 @@ void SMESHGUI_MeshOp::selectionDone()
         {
           SMESH::SMESH_subMesh_var submeshVar =
             SMESH::SMESH_subMesh::_narrow( _CAST( SObject,pObj )->GetObject() );
+          myIsMesh = submeshVar->_is_nil();
+          myIsInvalidSubMesh = ( !myIsMesh && submeshVar->GetId() < 1 );
+          myDlg->setTitile( myToCreate, myIsMesh );
           myDlg->setObjectShown( SMESHGUI_MeshDlg::Mesh, !submeshVar->_is_nil() );
           myDlg->setObjectShown( SMESHGUI_MeshDlg::Geom, true );
           myDlg->objectWg( SMESHGUI_MeshDlg::Mesh, SMESHGUI_MeshDlg::Btn )->hide();
-          myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
+          if ( myIsInvalidSubMesh )
+          {
+            // it is necessary to select a new geometry
+            myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->show();
+            myDlg->activateObject( SMESHGUI_MeshDlg::Geom );
+          }
+          else
+          {
+            myDlg->objectWg( SMESHGUI_MeshDlg::Geom, SMESHGUI_MeshDlg::Btn )->hide();
+          }
           myDlg->updateGeometry();
           myDlg->adjustSize();
-          myIsMesh = submeshVar->_is_nil();
           readMesh();
         }
         else
@@ -707,15 +721,14 @@ void SMESHGUI_MeshOp::selectionDone()
       }
     }
     else { // no geometry defined
-      myDlg->enableTab( SMESH::DIM_3D );
-      QStringList hypList;
-      availableHyps( SMESH::DIM_3D, Algo, hypList,
-                     myAvailableHypData[SMESH::DIM_3D][Algo]);
 
-      SMESHGUI_MeshTab* aTab = myDlg->tab( SMESH::DIM_3D );
-      aTab->setAvailableHyps( Algo, hypList );
-      for (int i = SMESH::DIM_0D;i < SMESH::DIM_3D; ++i) {
-        myDlg->disableTab(i);
+      QStringList hypList;
+      for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
+      {
+        availableHyps( dim, Algo, hypList, myAvailableHypData[dim][Algo]);
+        myDlg->tab( dim )->setAvailableHyps( Algo, hypList );
+        if ( hypList.empty() ) myDlg->disableTab( dim );
+        else                   myDlg->enableTab( dim );
       }
       myMaxShapeDim = -1;
       //Hide labels and fields (Mesh and Geometry)
@@ -941,7 +954,6 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
   bool isAux  = ( theHypType >= AddHyp );
   QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry, !myIsMesh );
 
-  QStringList::const_iterator anIter;
   GEOM::GEOM_Object_var aGeomVar;
   QString aCurrentGeomToSelect;
   if ( !theMeshType.isEmpty() ) {
@@ -953,23 +965,50 @@ void SMESHGUI_MeshOp::availableHyps( const int       theDim,
      myHypMapIsApplicable.clear();
   }
 
+  std::multimap< double, HypothesisData* > sortedHyps;
+  QStringList::const_iterator anIter;
   for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter )
   {
     HypothesisData* aData = SMESH::GetHypothesisData( *anIter );
     if ( ( isCompatible ( thePrevAlgoData, aData, theHypType ) &&
            isCompatible ( theNextAlgoData, aData, theHypType ) ) ||
-           ( theMeshType == "ANY" && aData->InputTypes.isEmpty())) {
-      if ( !theMeshType.isEmpty() && theDim >= SMESH::DIM_2D &&
+           ( theMeshType == "ANY" && aData->InputTypes.isEmpty()))
+    {
+      if ( ( !theMeshType.isEmpty() )  &&
+           ( theDim >= SMESH::DIM_2D ) &&
            ( ( theMeshType != "ANY" && !isCompatibleToMeshType( aData, theMeshType )) ||
-           !isCompatibleToGeometry( aData, aCurrentGeomToSelect, aGeomVar )))
+             !isCompatibleToGeometry( aData, aCurrentGeomToSelect, aGeomVar )))
         continue;
+
+      int  groupID = aData->GroupID;
+      int priority = aData->Priority;
+      if ( groupID  < 0 || groupID > 9    ) groupID  = 9;
+      if ( priority < 0 || priority > 999 ) priority = 999;
+
+      sortedHyps.insert( std::make_pair( groupID + priority * 1e-3, aData ));
+    }
+  }
+
+  if ( !sortedHyps.empty() )
+  {
+    HypothesisData* aPrevGroup = SMESH::GetGroupTitle( sortedHyps.rbegin()->second, isAlgo );
+    std::multimap< double, HypothesisData* >::iterator key_hyp = sortedHyps.begin();
+    for ( ; key_hyp != sortedHyps.end(); ++key_hyp )
+    {
+      HypothesisData*  aData = key_hyp->second;
+      HypothesisData* aGroup = SMESH::GetGroupTitle( aData, isAlgo );
+      if ( aPrevGroup != aGroup )
+      {
+        theDataList.append( aGroup );
+        theHyps.append( aGroup->Label );
+        aPrevGroup = aGroup;
+      }
       theDataList.append( aData );
       theHyps.append( aData->Label );
     }
   }
 
-  if ( !theMeshType.isEmpty() && !aCurrentGeomToSelect.isEmpty() &&
-       myLastGeomToSelect != aCurrentGeomToSelect )
+  if ( !theMeshType.isEmpty() && !aCurrentGeomToSelect.isEmpty() )
     myLastGeomToSelect = aCurrentGeomToSelect;
 }
 
@@ -1164,12 +1203,9 @@ void SMESHGUI_MeshOp::initHypCreator( SMESHGUI_GenericHypothesisCreator* theCrea
   // Set shapes, of mesh and sub-mesh if any
 
   // get Entry of the Geom object
-  QString aGeomEntry = "";
-  QString aMeshEntry = "";
-  QString anObjEntry = "";
-  aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
-  aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
-  anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj );
+  QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom );
+  QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
+  QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); 
 
   if ( myToCreate && myIsMesh )
     aMeshEntry = aGeomEntry;
@@ -1214,14 +1250,16 @@ void SMESHGUI_MeshOp::initHypCreator( SMESHGUI_GenericHypothesisCreator* theCrea
   theCreator->setShapeEntry( aGeomEntry );
   if ( aMeshEntry != "" )
     theCreator->setMainShapeEntry( aMeshEntry );
+
+  theCreator->setNoGeomMesh( !myIsOnGeometry && myIsMesh && !myToCreate );
 }
 
 //================================================================================
 /*!
- * \Brief Returns tab dimention
+ * \Brief Returns tab dimension
   * \param tab - the tab in the dlg
   * \param dlg - my dialogue
-  * \retval int - dimention
+  * \retval int - dimension
  */
 //================================================================================
 static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
@@ -1340,7 +1378,8 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim,
       aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) );
       dialog = true;
     }
-    else {
+    else
+    {
      SMESH::SMESH_Hypothesis_var aHyp =
        SMESH::CreateHypothesis(theTypeName, aHypName, false);
      aHyp.out();
@@ -1477,7 +1516,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
   if ( myIgnoreAlgoSelection )
     return;
 
-  int aDim = theDim < 0 ? getTabDim( sender(), myDlg ): theDim;
+  int curDim = getTabDim( sender(), myDlg );
+  int aDim = theDim < 0 ? curDim : theDim;
   if (aDim == -1)
     return;
 
@@ -1559,7 +1599,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
       myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable );
       noCompatible = anAvailable.isEmpty();
       algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
-      if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D) {
+      if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim == curDim ) {
         // select the sole compatible algo
         algoIndex = 0;
       }
@@ -1654,7 +1694,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
         hypIndex = this->find( curHyp, myExistingHyps[ dim ][ type ]);
       else
         hypIndex = -1;
-      if ( !isSubmesh && myToCreate && hypIndex < 0 && anExisting.count() == 1 ) {
+      if ( !isSubmesh && myToCreate && hypIndex < 0 && anExisting.count() == 1 && dim == curDim )
+      {
         // none is yet selected => select the sole existing if it is not optional
         CORBA::String_var hypTypeName = myExistingHyps[ dim ][ type ].first().first->GetName();
         bool isOptional = true;
@@ -1850,9 +1891,9 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess, QStringList& theEntryList )
 //================================================================================
 /*!
  * \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
+ * \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
  */
@@ -1866,10 +1907,15 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList
     return false;
 
   // get mesh object
-  QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh );
-  _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() );
   SMESH::SMESH_Mesh_var aMeshVar =
-    SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() );
+    SMESH::EntryToInterface<SMESH::SMESH_Mesh>( myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ));
+  if ( aMeshVar->_is_nil() && myIsInvalidSubMesh )
+  {
+    SMESH::SMESH_subMesh_var aSMVar =
+      SMESH::EntryToInterface<SMESH::SMESH_subMesh>( myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ));
+    if ( !aSMVar->_is_nil() )
+      aMeshVar = aSMVar->GetMesh();
+  }
   if (aMeshVar->_is_nil())
     return false;
 
@@ -1946,8 +1992,14 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess, QStringList& theEntryList
 
   SUIT_OverrideCursor aWaitCursor;
 
+  QString aNameOrID = aName;
+  if ( myIsInvalidSubMesh )
+    // pass a sub-mesh entry to mesh->GetSubMesh() to replace the invalid sub-mesh
+    // by a valid one in an existing SO
+    aNameOrID = myDlg->selectedObject(SMESHGUI_MeshDlg::Obj);
+
   // create sub-mesh
-  SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.toLatin1().data() );
+  SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aNameOrID.toLatin1().data() );
   _PTR(SObject) aSubMeshSO = SMESH::FindSObject( aSubMeshVar.in() );
   if ( aSubMeshSO ) {
     SMESH::SetName( aSubMeshSO, aName.toLatin1().data() );
@@ -2156,7 +2208,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
       {
         // Call hypothesis creation server method (without GUI)
         SMESH::SMESH_Hypothesis_var aHyp =
-          SMESH::CreateHypothesis(aHypName, aHypName, true);
+          SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
         aHyp.out();
       }
       else
@@ -2169,9 +2221,10 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
           aCreator->create( true, aHypName, myDlg, 0, QString::null );
         else {
           SMESH::SMESH_Hypothesis_var aHyp =
-            SMESH::CreateHypothesis(aHypName, aHypName, true);
+            SMESH::CreateHypothesis(aHypName, aHypData->Label, true);
           aHyp.out();
         }
+        delete aCreator;
       }
       QStringList tmpList;
       _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
@@ -2223,15 +2276,18 @@ void SMESHGUI_MeshOp::readMesh()
       myHasConcurrentSubBefore = checkSubMeshConcurrency( aMeshVar, aSubMeshVar );
     }
 
-    // Get name of geometry object
-    CORBA::String_var name = SMESH::GetGeomName( pObj );
-    if ( name.in() )
-      myDlg->setObjectText( SMESHGUI_MeshDlg::Geom, name.in() );
+    if ( !myIsInvalidSubMesh )
+    {
+      // Get name of geometry object
+      CORBA::String_var name = SMESH::GetGeomName( pObj );
+      if ( name.in() )
+        myDlg->setObjectText( SMESHGUI_MeshDlg::Geom, name.in() );
+    }
   }
 
   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
   QStringList anExisting;
-  const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
+  const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_2D;
   bool algoFound = false;
   for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim )
   {
@@ -2355,7 +2411,7 @@ int SMESHGUI_MeshOp::find( const SMESH::SMESH_Hypothesis_var& theHyp,
 /*!
  * \brief Edits mesh or sub-mesh
   * \param theMess - Output parameter intended for returning error message
-  * \retval bool  - TRUE if mesh is edited succesfully, FALSE otherwise
+  * \retval bool  - TRUE if mesh is edited successfully, FALSE otherwise
  *
  * Assigns new name hypotheses and algoriths to the mesh or sub-mesh
  */
@@ -2378,7 +2434,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
   // Set new name
   QString aName = myDlg->objectText( SMESHGUI_MeshDlg::Obj );
   SMESH::SetName( pObj, aName );
-  int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D;
+  int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_2D;
 
   // First, remove old algos in order to avoid messages on algorithm hiding
   for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
@@ -2525,7 +2581,7 @@ bool SMESHGUI_MeshOp::checkSubMeshConcurrency(SMESH::SMESH_Mesh_ptr    mesh,
  *
  * 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
+ * returns false if theOtherOp operation is not intended for deleting objects or mesh
  * elements.
  */
 //================================================================================
@@ -2714,8 +2770,9 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
     }
     if ( !myIsOnGeometry )
       for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {
-        if ( i < SMESH::DIM_3D ) myDlg->disableTab( i );
-        else                     myDlg->enableTab( i );
+        bool disable = myAvailableHypData[i][Algo].isEmpty();
+        if ( disable ) myDlg->disableTab( i );
+        else           myDlg->enableTab( i );
       }
     else
       for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) {