X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_ShapeByMeshDlg.cxx;h=223001a4428fc60ffe893d1fbebefcad4ca02952;hp=ba07781952344b6699b2d74f19b1cb30a9de3d95;hb=e85e13ee2a8e2484050471ff8e4dea298abe481a;hpb=c63ee099ad2b149bd70136839c973e8910137bc5 diff --git a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx index ba0778195..223001a44 100644 --- a/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx @@ -1,30 +1,29 @@ -// SMESH SMESHGUI : GUI for SMESH component +// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 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, or (at your option) any later version. // -// 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 // -// -// -// File : SMESHGUI_ShapeByMeshDlg.cxx -// Author : Edward AGAPOV -// Module : SMESH +// File : SMESHGUI_ShapeByMeshDlg.cxx +// Author : Edward AGAPOV, Open CASCADE S.A.S. +// SMESH includes +// #include "SMESHGUI_ShapeByMeshDlg.h" #include "SMESHGUI.h" @@ -34,41 +33,49 @@ #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" -#include "SMDS_Mesh.hxx" -#include "SMDS_MeshNode.hxx" -#include "SMESH_Actor.h" - -#include "GEOMBase.h" -#include "GeometryGUI.h" - -#include "LightApp_DataOwner.h" -#include "LightApp_SelectionMgr.h" -#include "SALOMEDSClient_SObject.hxx" -#include "SALOME_ListIO.hxx" -#include "SUIT_Desktop.h" -#include "SVTK_Selector.h" -#include "SVTK_ViewWindow.h" -#include "SVTK_ViewModel.h" -#include "SalomeApp_Tools.h" - -// OCCT Includes +#include +#include +#include + +// SALOME GEOM includes +#include +#include +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include +#include +#include +#include + +// SALOME KERNEL includes +#include +#include +#include + +// OCCT includes #include #include #include -// QT Includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SPACING 5 -#define MARGIN 10 +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 enum { EDGE = 0, FACE, VOLUME }; @@ -76,12 +83,15 @@ enum { EDGE = 0, FACE, VOLUME }; * \brief Dialog to publish a sub-shape of the mesh main shape * by selecting mesh elements */ -SMESHGUI_ShapeByMeshDlg::SMESHGUI_ShapeByMeshDlg() - : SMESHGUI_Dialog( 0, false, true, OK | Close ) +SMESHGUI_ShapeByMeshDlg::SMESHGUI_ShapeByMeshDlg(bool isMultipleAllowed) + : SMESHGUI_Dialog( 0, false, true, OK | Close ), + myIsMultipleAllowed( isMultipleAllowed ) { - setCaption(tr("CAPTION")); + setWindowTitle(tr("CAPTION")); - QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame(), MARGIN, SPACING); + QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); + aDlgLay->setMargin(MARGIN); + aDlgLay->setSpacing(SPACING); QFrame* aMainFrame = createMainFrame (mainFrame()); @@ -96,32 +106,41 @@ SMESHGUI_ShapeByMeshDlg::SMESHGUI_ShapeByMeshDlg() //======================================================================= QFrame* SMESHGUI_ShapeByMeshDlg::createMainFrame (QWidget* theParent) { - QFrame* aMainGrp = new QFrame(theParent, "main frame"); - QGridLayout* aLayout = new QGridLayout(aMainGrp, 3, 2); - aLayout->setSpacing(6); - aLayout->setAutoAdd(false); + QFrame* aMainGrp = new QFrame(theParent); + QGridLayout* aLayout = new QGridLayout(aMainGrp); + aLayout->setMargin(0); + aLayout->setSpacing(SPACING); // elem type - myElemTypeGroup = new QButtonGroup(1, Qt::Vertical, aMainGrp, "Group types"); - myElemTypeGroup->setTitle(tr("SMESH_ELEMENT_TYPE")); - myElemTypeGroup->setExclusive(true); - - (new QRadioButton( tr("SMESH_EDGE") , myElemTypeGroup))->setChecked(true); - new QRadioButton( tr("SMESH_FACE") , myElemTypeGroup); - new QRadioButton( tr("SMESH_VOLUME"), myElemTypeGroup); - + myElemTypeBox = new QGroupBox(tr("SMESH_ELEMENT_TYPE"), aMainGrp); + myElemTypeGroup = new QButtonGroup(aMainGrp); + QHBoxLayout* myElemTypeBoxLayout = new QHBoxLayout(myElemTypeBox); + myElemTypeBoxLayout->setMargin(MARGIN); + myElemTypeBoxLayout->setSpacing(SPACING); + + QRadioButton* aEdgeRb = new QRadioButton( tr("SMESH_EDGE"), myElemTypeBox); + QRadioButton* aFaceRb = new QRadioButton( tr("SMESH_FACE"), myElemTypeBox); + QRadioButton* aVolumeRb = new QRadioButton( tr("SMESH_VOLUME"), myElemTypeBox); + + myElemTypeBoxLayout->addWidget(aEdgeRb); + myElemTypeBoxLayout->addWidget(aFaceRb); + myElemTypeBoxLayout->addWidget(aVolumeRb); + myElemTypeGroup->addButton(aEdgeRb, 0); + myElemTypeGroup->addButton(aFaceRb, 1); + myElemTypeGroup->addButton(aVolumeRb, 2); + aEdgeRb->setChecked(true); + // element id - QLabel* anIdLabel = new QLabel( aMainGrp, "element id label"); - anIdLabel->setText( tr("ELEMENT_ID") ); - myElementId = new QLineEdit( aMainGrp, "element id"); - myElementId->setValidator( new SMESHGUI_IdValidator( theParent, "id validator", 1 )); + QLabel* anIdLabel = new QLabel( tr("ELEMENT_ID"), aMainGrp ); + myElementId = new QLineEdit( aMainGrp ); + myElementId->setValidator( new SMESHGUI_IdValidator( theParent, + !myIsMultipleAllowed ? 1 : 0 ) ); // 0 for any number of entities // shape name - QLabel* aNameLabel = new QLabel( aMainGrp, "geom name label"); - aNameLabel->setText( tr("GEOMETRY_NAME") ); - myGeomName = new QLineEdit( aMainGrp, "geom name"); + QLabel* aNameLabel = new QLabel( tr("GEOMETRY_NAME"), aMainGrp ); + myGeomName = new QLineEdit( aMainGrp ); - aLayout->addMultiCellWidget(myElemTypeGroup, 0, 0, 0, 1); + aLayout->addWidget(myElemTypeBox, 0, 0, 1, 2); aLayout->addWidget(anIdLabel, 1, 0); aLayout->addWidget(myElementId, 1, 1); aLayout->addWidget(aNameLabel, 2, 0); @@ -136,26 +155,27 @@ QFrame* SMESHGUI_ShapeByMeshDlg::createMainFrame (QWidget* theParent) //======================================================================= SMESHGUI_ShapeByMeshDlg::~SMESHGUI_ShapeByMeshDlg() { - // no need to delete child widgets, Qt does it all for us +} + +void SMESHGUI_ShapeByMeshDlg:: setMultipleAllowed( bool isAllowed ) +{ + myIsMultipleAllowed = isAllowed; } //================================================================================ /*! * \brief Constructor - * \param theToCreate - if this parameter is true then operation is used for creation, - * for editing otherwise - * - * Initialize operation -*/ + */ //================================================================================ -SMESHGUI_ShapeByMeshOp::SMESHGUI_ShapeByMeshOp() +SMESHGUI_ShapeByMeshOp::SMESHGUI_ShapeByMeshOp(bool isMultipleAllowed): + myIsMultipleAllowed(isMultipleAllowed) { if ( GeometryGUI::GetGeomGen()->_is_nil() )// check that GEOM_Gen exists GeometryGUI::InitGeomGen(); - myDlg = new SMESHGUI_ShapeByMeshDlg; + myDlg = new SMESHGUI_ShapeByMeshDlg(myIsMultipleAllowed); - connect(myDlg->myElemTypeGroup, SIGNAL(clicked(int)), SLOT(onTypeChanged(int))); + connect(myDlg->myElemTypeGroup, SIGNAL(buttonClicked(int)), SLOT(onTypeChanged(int))); connect(myDlg->myElementId, SIGNAL(textChanged(const QString&)), SLOT(onElemIdChanged(const QString&))); } @@ -180,7 +200,7 @@ void SMESHGUI_ShapeByMeshOp::startOperation() //================================================================================ /*! * \brief Destructor -*/ + */ //================================================================================ SMESHGUI_ShapeByMeshOp::~SMESHGUI_ShapeByMeshOp() { @@ -191,17 +211,22 @@ SMESHGUI_ShapeByMeshOp::~SMESHGUI_ShapeByMeshOp() //================================================================================ /*! * \brief Gets dialog of this operation - * \retval LightApp_Dialog* - pointer to dialog of this operation -*/ + * \retval LightApp_Dialog* - pointer to dialog of this operation + */ //================================================================================ LightApp_Dialog* SMESHGUI_ShapeByMeshOp::dlg() const { return myDlg; } +SMESH::SMESH_Mesh_ptr SMESHGUI_ShapeByMeshOp::GetMesh() +{ + return myMesh; +} + //======================================================================= // function : GetShape() -// purpose : Get published sub-shape +// purpose : Return published sub-shape, it must be UnRegister()ed! //======================================================================= GEOM::GEOM_Object_ptr SMESHGUI_ShapeByMeshOp::GetShape() { @@ -219,52 +244,52 @@ void SMESHGUI_ShapeByMeshOp::SetMesh (SMESH::SMESH_Mesh_ptr thePtr) myGeomObj = GEOM::GEOM_Object::_nil(); myHasSolids = false; - vector< bool > hasElement (myDlg->myElemTypeGroup->count(), false); + std::vector< bool > hasElement (myDlg->myElemTypeGroup->buttons().count(), false); if (!myMesh->_is_nil() ) - { -// _PTR(SObject) aSobj = SMESH::FindSObject(myMesh.in()); -// SUIT_DataOwnerPtr anIObj (new LightApp_DataOwner(aSobj->GetID().c_str())); - - vector< int > nbShapes( TopAbs_SHAPE, 0 ); - int shapeDim = 0; // max dim with several shapes - //if ( /*mySelectionMgr*/ selectionMgr()->isOk(anIObj) ) // check that the mesh has a valid shape { - _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in()); - GEOM::GEOM_Object_var mainShape = SMESH::GetGeom(aSO); - if ( !mainShape->_is_nil() ) + // _PTR(SObject) aSobj = SMESH::FindSObject(myMesh.in()); + // SUIT_DataOwnerPtr anIObj (new LightApp_DataOwner(aSobj->GetID().c_str())); + + std::vector< int > nbShapes( TopAbs_SHAPE, 0 ); + int shapeDim = 0; // max dim with several shapes + //if ( /*mySelectionMgr*/ selectionMgr()->isOk(anIObj) ) // check that the mesh has a valid shape { - TopoDS_Shape aShape; - if ( GEOMBase::GetShape(mainShape, aShape)) - { - TopAbs_ShapeEnum types[4] = { TopAbs_EDGE, TopAbs_FACE, TopAbs_SHELL, TopAbs_SOLID }; - for ( int dim = 4; dim > 0; --dim ) { - TopAbs_ShapeEnum type = types[ dim - 1 ]; - TopAbs_ShapeEnum avoid = ( type == TopAbs_SHELL ) ? TopAbs_SOLID : TopAbs_SHAPE; - TopExp_Explorer exp( aShape, type, avoid ); - for ( ; nbShapes[ type ] < 2 && exp.More(); exp.Next() ) - ++nbShapes[ type ]; - if ( nbShapes[ type ] > 1 ) { - shapeDim = dim; - break; - } + _PTR(SObject) aSO = SMESH::FindSObject(myMesh.in()); + GEOM::GEOM_Object_var mainShape = SMESH::GetGeom(aSO); + if ( !mainShape->_is_nil() ) + { + TopoDS_Shape aShape; + if ( GEOMBase::GetShape(mainShape, aShape)) + { + TopAbs_ShapeEnum types[4] = { TopAbs_EDGE, TopAbs_FACE, TopAbs_SHELL, TopAbs_SOLID }; + for ( int dim = 4; dim > 0; --dim ) { + TopAbs_ShapeEnum type = types[ dim - 1 ]; + TopAbs_ShapeEnum avoid = ( type == TopAbs_SHELL ) ? TopAbs_SOLID : TopAbs_SHAPE; + TopExp_Explorer exp( aShape, type, avoid ); + for ( ; nbShapes[ type ] < 2 && exp.More(); exp.Next() ) + ++nbShapes[ type ]; + if ( nbShapes[ type ] > 1 ) { + shapeDim = dim; + break; + } + } + } } - } } + if (shapeDim > 0) + { + if ( nbShapes[ TopAbs_SHELL ] + nbShapes[ TopAbs_SOLID ] > 1 ) + shapeDim = 3; + hasElement[ EDGE ] = shapeDim > 0 && myMesh->NbEdges(); + hasElement[ FACE ] = shapeDim > 1 && myMesh->NbFaces(); + hasElement[ VOLUME ] = shapeDim > 2 && myMesh->NbVolumes(); + } + myHasSolids = nbShapes[ TopAbs_SOLID ]; } - if (shapeDim > 0) - { - if ( nbShapes[ TopAbs_SHELL ] + nbShapes[ TopAbs_SOLID ] > 1 ) - shapeDim = 3; - hasElement[ EDGE ] = shapeDim > 0 && myMesh->NbEdges() ; - hasElement[ FACE ] = shapeDim > 1 && myMesh->NbFaces() ; - hasElement[ VOLUME ] = shapeDim > 2 && myMesh->NbVolumes(); - } - myHasSolids = nbShapes[ TopAbs_SOLID ]; - } - // disable inexistant elem types - for ( int i = 0; i < myDlg->myElemTypeGroup->count(); ++i ) { - if ( QButton* button = myDlg->myElemTypeGroup->find( i ) ) + // disable inexistent elem types + for ( int i = 0; i < myDlg->myElemTypeGroup->buttons().count(); ++i ) { + if ( QAbstractButton* button = myDlg->myElemTypeGroup->button( i ) ) button->setEnabled( hasElement[ i ] ); } myDlg->myElementId->setEnabled( hasElement[ EDGE ] ); @@ -282,9 +307,89 @@ void SMESHGUI_ShapeByMeshOp::commitOperation() { SMESHGUI_SelectionOp::commitOperation(); try { - int elemID = myDlg->myElementId->text().toInt(); - myGeomObj = SMESHGUI::GetSMESHGen()->GetGeometryByMeshElement - ( myMesh.in(), elemID, myDlg->myGeomName->text().latin1()); + QStringList aListId = myDlg->myElementId->text().split( " ", QString::SkipEmptyParts); + if (aListId.count() == 1) + { + int elemID = (aListId.first()).toInt(); + // GEOM_Object is published -> no need to UnRegister() + myGeomObj = GEOM::GEOM_Object::_duplicate + (SMESHGUI::GetSMESHGen()->GetGeometryByMeshElement + ( myMesh.in(), elemID, myDlg->myGeomName->text().toUtf8().constData()) ); + } + else + { + GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh(); + + GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen( aMeshShape ); + if ( geomGen->_is_nil() ) + return; + + GEOM::GEOM_IShapesOperations_wrap aShapesOp = geomGen->GetIShapesOperations(); + if ( aShapesOp->_is_nil() ) + return; + + TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE; + + std::map aGeomObjectsMap; + GEOM::GEOM_Object_wrap aGeomObject; + + for ( int i = 0; i < aListId.count(); i++ ) + { + aGeomObject = // received object need UnRegister()! + SMESHGUI::GetSMESHGen()->FindGeometryByMeshElement(myMesh.in(), aListId[i].toInt()); + + if (aGeomObject->_is_nil()) continue; + + int anId = aShapesOp->GetSubShapeIndex(aMeshShape, aGeomObject); + if (aShapesOp->IsDone() && !aGeomObjectsMap.count(anId) ) + { + aGeomObjectsMap[anId] = aGeomObject; + + TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)aGeomObject->GetShapeType(); + if (i == 0) + aGroupType = aSubShapeType; + else if (aSubShapeType != aGroupType) + aGroupType = TopAbs_SHAPE; + } + } + + int aNumberOfGO = aGeomObjectsMap.size(); + if (aNumberOfGO == 1) + { + aGeomObject = (*aGeomObjectsMap.begin()).second; + } + else if (aNumberOfGO > 1) + { + GEOM::GEOM_IGroupOperations_wrap aGroupOp = geomGen->GetIGroupOperations(); + if ( aGroupOp->_is_nil() ) + return; + + GEOM::ListOfGO_var aGeomObjects = new GEOM::ListOfGO(); + aGeomObjects->length( aNumberOfGO ); + + int i = 0; + std::map::iterator anIter; + for (anIter = aGeomObjectsMap.begin(); anIter!=aGeomObjectsMap.end(); anIter++) + aGeomObjects[i++] = GEOM::GEOM_Object::_duplicate( (*anIter).second.in() ); + + //create geometry group + aGeomObject = aGroupOp->CreateGroup(aMeshShape, aGroupType); + aGroupOp->UnionList(aGeomObject, aGeomObjects); + + if ( !aGroupOp->IsDone() ) + return; + } + + // publish the GEOM object in study + QString aNewGeomGroupName ( myDlg->myGeomName->text() ); + SALOMEDS::SObject_wrap aNewGroupSO = + geomGen->AddInStudy( aGeomObject, + aNewGeomGroupName.toUtf8().data(), aMeshShape); + + // get a GEOM_Object already published, which doesn't need UnRegister() + CORBA::Object_var obj = aNewGroupSO->GetObject(); + myGeomObj = GEOM::GEOM_Object::_narrow( obj ); + } } catch (const SALOME::SALOME_Exception& S_ex) { SalomeApp_Tools::QtCatchCorbaException(S_ex); @@ -294,6 +399,11 @@ void SMESHGUI_ShapeByMeshOp::commitOperation() } +bool SMESHGUI_ShapeByMeshOp::onApply() +{ + return true; +} + //======================================================================= // function : onSelectionDone() // purpose : SLOT called when selection changed. Enable/desable [ OK ] @@ -305,8 +415,8 @@ void SMESHGUI_ShapeByMeshOp::onSelectionDone() try { SALOME_ListIO aList; - selectionMgr()->selectedObjects(aList, SVTK_Viewer::Type()); - if (aList.Extent() != 1) + selectionMgr()->selectedObjects(aList); + if ( aList.IsEmpty() || ( !myIsMultipleAllowed && aList.Extent() != 1) ) return; SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(aList.First()); @@ -316,7 +426,9 @@ void SMESHGUI_ShapeByMeshOp::onSelectionDone() QString aString; int nbElems = SMESH::GetNameOfSelectedElements(selector(),//myViewWindow->GetSelector(), aList.First(), aString); - if ( nbElems == 1 ) { + if (nbElems > 0) { + if (!myIsMultipleAllowed && nbElems != 1 ) + return; setElementID( aString ); myDlg->setButtonEnabled( true, QtxDialog::OK ); } @@ -337,7 +449,7 @@ void SMESHGUI_ShapeByMeshOp::activateSelection() QString geomName; Selection_Mode mode = EdgeSelection; - switch ( myDlg->myElemTypeGroup->id( myDlg->myElemTypeGroup->selected() )) { + switch ( myDlg->myElemTypeGroup->checkedId() ) { case EDGE : mode = EdgeSelection; geomName = tr("GEOM_EDGE"); break; case FACE : @@ -374,31 +486,39 @@ void SMESHGUI_ShapeByMeshOp::onElemIdChanged(const QString& theNewText) myDlg->setButtonEnabled( false, QtxDialog::OK ); if ( myIsManualIdEnter && !myMesh->_is_nil() ) + { if ( SMESH_Actor* actor = SMESH::FindActorByObject(myMesh) ) + { if ( SMDS_Mesh* aMesh = actor->GetObject()->GetMesh() ) { SMDSAbs_ElementType type = SMDSAbs_Edge; - switch ( myDlg->myElemTypeGroup->id( myDlg->myElemTypeGroup->selected() )) { + switch ( myDlg->myElemTypeGroup->checkedId() ) { case EDGE : type = SMDSAbs_Edge; break; case FACE : type = SMDSAbs_Face; break; case VOLUME: type = SMDSAbs_Volume; break; default: return; } TColStd_MapOfInteger newIndices; - QStringList aListId = QStringList::split( " ", theNewText, false); + QStringList aListId = theNewText.split( " ", QString::SkipEmptyParts); for ( int i = 0; i < aListId.count(); i++ ) { if ( const SMDS_MeshElement * e = aMesh->FindElement( aListId[ i ].toInt() )) if ( e->GetType() == type ) newIndices.Add( e->GetID() ); } - - if ( !newIndices.IsEmpty() && newIndices.Extent() == 1 ) + + if ( !newIndices.IsEmpty() ) + { + if (!myIsMultipleAllowed && newIndices.Extent() != 1) + return; if ( SVTK_Selector* s = selector() ) { s->AddOrRemoveIndex( actor->getIO(), newIndices, false ); viewWindow()->highlight( actor->getIO(), true, true ); myDlg->setButtonEnabled( true, QtxDialog::OK ); } + } } + } + } } //=======================================================================