From a47909aa5e6f7db339b96f8e2ada73ca1da8d79c Mon Sep 17 00:00:00 2001 From: eap Date: Fri, 13 Jan 2006 09:56:16 +0000 Subject: [PATCH] PAL10953. When a submesh is being created, provide possibility to select geometry by mesh element --- src/SMESHGUI/SMESHGUI_MeshDlg.cxx | 38 +++++ src/SMESHGUI/SMESHGUI_MeshDlg.h | 5 + src/SMESHGUI/SMESHGUI_MeshOp.cxx | 251 ++++++++++++++++++++++++++++-- src/SMESHGUI/SMESHGUI_MeshOp.h | 11 +- src/SMESHGUI/SMESH_msg_en.po | 27 +++- 5 files changed, 314 insertions(+), 18 deletions(-) diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx index 6d9e88e58..a9dbbcaa1 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx @@ -371,6 +371,7 @@ SMESHGUI_MeshDlg::SMESHGUI_MeshDlg( const bool theToCreate, const bool theIsMesh createObject( tr( "MESH" ), aGrp, Mesh ); // geometry createObject( tr( "GEOMETRY" ), aGrp, Geom ); + myGeomPopup = 0; // Create tab widget @@ -520,3 +521,40 @@ void SMESHGUI_MeshDlg::onHypoSetButton() { myHypoSetPopup->exec( QCursor::pos() ); } + +//================================================================================ +/*! + * \brief Enable showing of the popup when Geometry selection btn is clicked + * \param enable - true to enable + */ +//================================================================================ + +enum { DIRECT_GEOM_INDEX = 0, GEOM_BY_MESH_INDEX }; + +void SMESHGUI_MeshDlg::setGeomPopupEnabled( const bool enable ) +{ + if ( QButton* selBtn = dynamic_cast( objectWg( Geom, Btn ))) + { + disconnect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) )); + if ( enable ) { + if ( ! myGeomPopup ) { + myGeomPopup = new QPopupMenu(); + myGeomPopup->insertItem( tr("DIRECT_GEOM_SELECTION"), DIRECT_GEOM_INDEX ); + myGeomPopup->insertItem( tr("GEOM_BY_MESH_ELEM_SELECTION"), GEOM_BY_MESH_INDEX ); + connect( myGeomPopup, SIGNAL( activated( int ) ), SLOT( onGeomPopup( int ) ) ); + } + connect( selBtn, SIGNAL( toggled(bool) ), this, SLOT( onGeomSelectionButton(bool) )); + } + } +} + +void SMESHGUI_MeshDlg::onGeomSelectionButton(bool isBtnOn) +{ + if ( myGeomPopup && isBtnOn ) + myGeomPopup->exec( QCursor::pos() ); +} + +void SMESHGUI_MeshDlg::onGeomPopup( int index ) +{ + emit geomSelectionByMesh( index == GEOM_BY_MESH_INDEX ); +} diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.h b/src/SMESHGUI/SMESHGUI_MeshDlg.h index f83b77c48..f12773bd1 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.h @@ -71,21 +71,26 @@ public: void setCurrentTab( const int ); void setMaxHypoDim( const int ); void setHypoSets( const QStringList& ); + void setGeomPopupEnabled( const bool ); signals: void hypoSet( const QString& ); + void geomSelectionByMesh( bool ); private slots: void onHypoSetPopup( int ); void onHypoSetButton(); + void onGeomPopup( int ); + void onGeomSelectionButton( bool ); private: QMap< int, SMESHGUI_MeshTab* > myTabs; QTabWidget* myTabWg; QPopupMenu* myHypoSetPopup; + QPopupMenu* myGeomPopup; }; /*! diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 38d8f6742..7e590a8b6 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -31,6 +31,7 @@ #include "SMESHGUI_MeshOp.h" #include "SMESHGUI_MeshDlg.h" +#include "SMESHGUI_ShapeByMeshDlg.h" #include "SMESH_TypeFilter.hxx" #include "SMESHGUI.h" @@ -38,11 +39,14 @@ #include "SMESHGUI_Hypotheses.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_GEOMGenUtils.h" +#include "SMESHGUI_VTKUtils.h" #include "SMESH_TypeFilter.hxx" #include "SMESH_NumberFilter.hxx" #include "GEOM_SelectionFilter.h" +#include "GEOMBase.h" +#include "GeometryGUI.h" #include "SalomeApp_Tools.h" #include "SALOMEDSClient_Study.hxx" @@ -51,14 +55,13 @@ #include "SALOMEDS_SComponent.hxx" #include "SALOMEDS_SObject.hxx" - #include "LightApp_SelectionMgr.h" #include "LightApp_UpdateFlags.h" #include "SUIT_MessageBox.h" #include "SUIT_Desktop.h" #include "SUIT_OverrideCursor.h" - -#include "GEOMBase.h" +#include "SALOME_InteractiveObject.hxx" +#include "SALOME_ListIO.hxx" #include "utilities.h" @@ -68,6 +71,17 @@ #include #include +enum { GLOBAL_ALGO_TAG =3, + GLOBAL_HYPO_TAG =2, + LOCAL_ALGO_TAG =2, + LOCAL_HYPO_TAG =1, + SUBMESH_ON_EDGE_TAG =5, + SUBMESH_ON_WIRE_TAG =6, + SUBMESH_ON_FACE_TAG =7, + SUBMESH_ON_SHELL_TAG =8, + SUBMESH_ON_SOLID_TAG =9, + SUBMESH_ON_COMPOUND_TAG=10 }; + //================================================================================ /*! * \brief Constructor @@ -81,8 +95,11 @@ SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh ) : SMESHGUI_SelectionOp(), myToCreate( theToCreate ), myIsMesh( theIsMesh ), - myDlg( 0 ) + myDlg( 0 ), + myShapeByMeshDlg( 0 ) { + if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists + GeometryGUI::InitGeomGen(); } //================================================================================ @@ -92,7 +109,7 @@ SMESHGUI_MeshOp::SMESHGUI_MeshOp( const bool theToCreate, const bool theIsMesh ) //================================================================================ SMESHGUI_MeshOp::~SMESHGUI_MeshOp() { - if( myDlg ) + if ( myDlg ) delete myDlg; } @@ -190,6 +207,7 @@ void SMESHGUI_MeshOp::startOperation() this, SLOT( onEditHyp( const int, const int) ) ); } connect( myDlg, SIGNAL( hypoSet( const QString& )), SLOT( onHypoSet( const QString& ))); + connect( myDlg, SIGNAL( geomSelectionByMesh( bool )), SLOT( onGeomSelectionByMesh( bool ))); } SMESHGUI_SelectionOp::startOperation(); @@ -253,6 +271,88 @@ SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const return 0; } +//================================================================================ +/*! + * \brief check if selected shape is a subshape of the shape to mesh + * \retval bool - check result + */ +//================================================================================ + +bool SMESHGUI_MeshOp::isSubshapeOk() const +{ + if ( !myToCreate || myIsMesh ) // not submesh creation + return false; + + QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); + QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() ); + _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() ); + if ( pMesh && pGeom ) { + SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface( pMesh ); + if ( !mesh->_is_nil() ) { + GEOM::GEOM_Object_var mainGeom, subGeom; + mainGeom = mesh->GetShapeToMesh(); + subGeom = SMESH::SObjectToInterface( pGeom ); + if ( !mainGeom->_is_nil() && !subGeom->_is_nil() ) { + TopoDS_Shape mainShape, subShape; + if ( GEOMBase::GetShape( mainGeom, mainShape ) && + GEOMBase::GetShape( subGeom, subShape ) ) + // 1 is index of mainShape itself + return GEOMBase::GetIndex( subShape, mainShape, 0 ) > 1; + } + } + } + return false; +} + +//================================================================================ +/*! + * \brief find an existing submesh by the selected shape + * \retval _PTR(SObject) - the found submesh SObject + */ +//================================================================================ + +_PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const +{ + QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); + QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() ); + _PTR(SObject) pGeom = studyDS()->FindObjectID( aGeomEntry.latin1() ); + if ( pMesh && pGeom ) { + GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface( pGeom ); + if ( !geom->_is_nil() ) { + int tag = -1; + switch ( geom->GetShapeType() ) { + case GEOM::EDGE: tag = SUBMESH_ON_EDGE_TAG ; break; + case GEOM::WIRE: tag = SUBMESH_ON_WIRE_TAG ; break; + case GEOM::FACE: tag = SUBMESH_ON_FACE_TAG ; break; + case GEOM::SHELL: tag = SUBMESH_ON_SHELL_TAG ; break; + case GEOM::SOLID: tag = SUBMESH_ON_SOLID_TAG ; break; + case GEOM::COMPOUND: tag = SUBMESH_ON_COMPOUND_TAG; break; + default:; + } + _PTR(SObject) aSubmeshRoot; + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + if ( pMesh->FindSubObject( tag, aSubmeshRoot ) ) + { + _PTR(ChildIterator) smIter = aStudy->NewChildIterator( aSubmeshRoot ); + for (; smIter->More(); smIter->Next() ) + { + _PTR(SObject) aSmObj = smIter->Value(); + _PTR(ChildIterator) anIter1 = aStudy->NewChildIterator(aSmObj); + for (; anIter1->More(); anIter1->Next()) { + _PTR(SObject) pGeom2 = anIter1->Value(); + if ( pGeom2->ReferencedObject( pGeom2 ) && + pGeom2->GetID() == pGeom->GetID() ) + return aSmObj; + } + } + } + } + } + return _PTR(SObject)(); +} + //================================================================================ /*! * \brief Updates dialog's look and feel @@ -264,9 +364,9 @@ void SMESHGUI_MeshOp::selectionDone() { SMESHGUI_SelectionOp::selectionDone(); - if ( !myToCreate ) + try { - try + if ( !myToCreate ) // edition { QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.latin1() ); @@ -282,15 +382,44 @@ void SMESHGUI_MeshOp::selectionDone() } else myDlg->reset(); + } - catch ( const SALOME::SALOME_Exception& S_ex ) - { - SalomeApp_Tools::QtCatchCorbaException( S_ex ); - } - catch ( ... ) + else if ( !myIsMesh ) // submesh creation { + // if a submesh on the selected shape already exist, pass to submesh edition mode + if ( _PTR(SObject) pSubmesh = getSubmeshByGeom() ) { + SMESH::SMESH_subMesh_var sm = + SMESH::SObjectToInterface( pSubmesh ); + bool editSubmesh = ( !sm->_is_nil() && + SUIT_MessageBox::question2( myDlg, tr( "SMESH_WARNING" ), + tr( "EDIT_SUBMESH_QUESTION"), + tr( "SMESH_BUT_YES" ), + tr( "SMESH_BUT_NO" ), 1, 0, 0 )); + if ( editSubmesh ) + { + selectionMgr()->clearFilters(); + selectObject( pSubmesh ); + SMESHGUI::GetSMESHGUI()->switchToOperation(704); + } + else + { + selectObject( _PTR(SObject)() ); + myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" ); + } + } + // enable/disable popup for choice of geom selection way + myDlg->setGeomPopupEnabled( !myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ).isEmpty() ); + } } + catch ( const SALOME::SALOME_Exception& S_ex ) + { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + } + catch ( ... ) + { + } + // Enable tabs according to shape dimension @@ -402,6 +531,11 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const theMess = tr( "MESH_IS_NULL" ); return false; } + if ( !isSubshapeOk() ) + { + theMess = tr( "INVALID_SUBSHAPE" ); + return false; + } } } return true; @@ -468,9 +602,9 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, bool isMesh = !_CAST( SComponent, theFather ); int aPart = -1; if ( isMesh ) - aPart = theHypType == Algo ? 3 : 2; + aPart = theHypType == Algo ? GLOBAL_ALGO_TAG : GLOBAL_HYPO_TAG; else - aPart = theHypType == Algo ? 2 : 1; + aPart = theHypType == Algo ? LOCAL_ALGO_TAG : LOCAL_HYPO_TAG; if ( theFather->FindSubObject( aPart, aHypRoot ) ) { @@ -1288,3 +1422,92 @@ bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const { return SMESHGUI_Operation::isValid( theOp ) && !theOp->inherits( "SMESHGUI_MeshOp" ); } + +//================================================================================ +/*! + * \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 + */ +//================================================================================ + +void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh ) +{ + if ( theByMesh ) { + if ( !myShapeByMeshDlg ) { + myShapeByMeshDlg = new SMESHGUI_ShapeByMeshDlg( SMESHGUI::GetSMESHGUI(), "ShapeByMeshDlg"); + connect(myShapeByMeshDlg, SIGNAL(PublishShape()), SLOT(onPublishShapeByMeshDlg())); + connect(myShapeByMeshDlg, SIGNAL(Close()), SLOT(onCloseShapeByMeshDlg())); + } + // set mesh object to dlg + QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); + if ( _PTR(SObject) pMesh = studyDS()->FindObjectID( aMeshEntry.latin1() )) { + SMESH::SMESH_Mesh_var aMeshVar = + SMESH::SMESH_Mesh::_narrow( _CAST( SObject,pMesh )->GetObject() ); + if ( !aMeshVar->_is_nil() ) { + myDlg->hide(); + myShapeByMeshDlg->Init(); + myShapeByMeshDlg->SetMesh( aMeshVar ); + myShapeByMeshDlg->show(); + } + } + } +} + +//================================================================================ +/*! + * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg + */ +//================================================================================ + +void SMESHGUI_MeshOp::onPublishShapeByMeshDlg() +{ + onCloseShapeByMeshDlg(); + + if ( myShapeByMeshDlg ) { + // Select a found geometry object + GEOM::GEOM_Object_var aGeomVar = myShapeByMeshDlg->GetShape(); + if ( !aGeomVar->_is_nil() ) + { + QString ID = aGeomVar->GetStudyEntry(); + if ( _PTR(SObject) aGeomSO = studyDS()->FindObjectID( ID )) { + selectObject( aGeomSO ); + selectionDone(); + } + } + } +} + +//================================================================================ +/*! + * \brief SLOT. Is called Close Ok is pressed in SMESHGUI_ShapeByMeshDlg + */ +//================================================================================ + +void SMESHGUI_MeshOp::onCloseShapeByMeshDlg() +{ + if ( myDlg ) { + myDlg->show(); + myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" ); + myDlg->activateObject( SMESHGUI_MeshDlg::Geom ); + } +} + +//================================================================================ +/*! + * \brief Selects a SObject + * \param theSObj - the SObject to select + */ +//================================================================================ + +void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const +{ + if ( LightApp_SelectionMgr* sm = selectionMgr() ) { + SALOME_ListIO anIOList; + if ( theSObj ) { + Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject + ( theSObj->GetID().c_str(), "SMESH", theSObj->GetName().c_str() ); + anIOList.Append( anIO ); + } + sm->setSelectedObjects( anIOList, false ); + } +} diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.h b/src/SMESHGUI/SMESHGUI_MeshOp.h index 7c14d1f87..677731a3b 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.h +++ b/src/SMESHGUI/SMESHGUI_MeshOp.h @@ -40,9 +40,7 @@ #include CORBA_SERVER_HEADER(SMESH_Mesh) class SMESHGUI_MeshDlg; -class SMESH_TypeFilter; -class SMESH_NumberFilter; - +class SMESHGUI_ShapeByMeshDlg; /*! * \brief Operation for mech creation or editing @@ -72,6 +70,9 @@ protected slots: void onCreateHyp( const int theHypType, const int theIndex ); void onEditHyp( const int theHypType, const int theIndex ); void onHypoSet( const QString& theSetName ); + void onGeomSelectionByMesh( bool ); + void onPublishShapeByMeshDlg(); + void onCloseShapeByMeshDlg(); private: bool isValid( QString& ) const; @@ -99,12 +100,16 @@ private: const QValueList& ) const; SMESH::SMESH_Hypothesis_var getInitParamsHypothesis( const QString& aHypType, const QString& aServerLib ) const; + bool isSubshapeOk() const; + _PTR(SObject) getSubmeshByGeom() const; + void selectObject( _PTR(SObject) ) const; private: typedef QMap< int, QValueList > IdToHypListMap; typedef QMap< int, IdToHypListMap > DimToHypMap; SMESHGUI_MeshDlg* myDlg; + SMESHGUI_ShapeByMeshDlg* myShapeByMeshDlg; bool myToCreate; bool myIsMesh; diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index 073353aca..ba1f4f80a 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -2893,6 +2893,26 @@ msgstr "Assign a set of hypotheses" #----------------------------------------------------------- +msgid "SMESHGUI_ShapeByMeshDlg::CAPTION" +msgstr "Find geometry by mesh element" + +msgid "SMESH_ELEMENT_TYPE" +msgstr "Element Type" + +msgid "ELEMENT_ID" +msgstr "Element ID" + +msgid "GEOMETRY_NAME" +msgstr "Geometry name" + +msgid "DIRECT_GEOM_SELECTION" +msgstr "Direct geometry selection" + +msgid "GEOM_BY_MESH_ELEM_SELECTION" +msgstr "Find geometry by mesh element selection" + +#----------------------------------------------------------- + msgid "SMESHGUI_MeshTab::ALGORITHM" msgstr "Algorithm" @@ -2931,9 +2951,14 @@ msgstr "Geometry object is not defined\nPlease specify it and try again" msgid "SMESHGUI_MeshOp::THERE_IS_NO_OBJECT_FOR_EDITING" msgstr "There is no object for editing. Please\nselect mesh or sub-mesh and try again" +msgid "SMESHGUI_MeshOp::EDIT_SUBMESH_QUESTION" +msgstr "A submesh on the selected geometry already exists.\n Do you want to edit this submesh?" + msgid "SMESHGUI_MeshOp::MESH_IS_NULL" msgstr "Mesh is null" +msgid "SMESHGUI_MeshOp::INVALID_SUBSHAPE" +msgstr "Geometry object is not a subshape of the shape to mesh" + msgid "SMESHGUI_MeshOp::MESH_IS_NOT_DEFINED" msgstr "Mesh is not defined\nPlease specify it and try again" - -- 2.30.2