diff --git a/doc/salome/gui/GEOM/images/editgroup.png b/doc/salome/gui/GEOM/images/editgroup.png index d0a3c314b..c7f55074e 100755 Binary files a/doc/salome/gui/GEOM/images/editgroup.png and b/doc/salome/gui/GEOM/images/editgroup.png differ diff --git a/doc/salome/gui/GEOM/images/geomcreategroup.png b/doc/salome/gui/GEOM/images/geomcreategroup.png index b74b00dfb..0f67a625c 100755 Binary files a/doc/salome/gui/GEOM/images/geomcreategroup.png and b/doc/salome/gui/GEOM/images/geomcreategroup.png differ diff --git a/doc/salome/gui/GEOM/images/neo-obj1.png b/doc/salome/gui/GEOM/images/neo-obj1.png index df078a1fe..438c6339b 100755 Binary files a/doc/salome/gui/GEOM/images/neo-obj1.png and b/doc/salome/gui/GEOM/images/neo-obj1.png differ diff --git a/doc/salome/gui/GEOM/input/creating_explode.doc b/doc/salome/gui/GEOM/input/creating_explode.doc index e3ae84893..6caf20df1 100644 --- a/doc/salome/gui/GEOM/input/creating_explode.doc +++ b/doc/salome/gui/GEOM/input/creating_explode.doc @@ -42,6 +42,27 @@ Switching on Select Sub-shapes check box allows manual selection of sub-s to be extracted from the main object. In this mode the user can select sub-shapes directly in 3D viewer. +When Select Sub-shapes check box is switched on, additional \b Filter controls +allow to automatically pick up entites which satisfy specified threshold value(s). +The numerical functor for each sub-shape that is compared with threshold value(s) +is computed according to the shape's topological properties: +- length for edges and wires +- area for faces and shells +- volume for solids, compounds, compsolids + +Filtering capabilities are not available for vertices. + +In order to filter out some entities: +- Activate one or two filtering controls by switching on corresponding check boxes; +- Select required threshold comparator type; the following choices are available: + - Less Than or Equal or Less Than for the first comparator; + - Greater Than or Equal or Greater Than for the second comparator; +- Enter required threshold value (values); +- Press \b Apply button in the \b Filter group. + +The entities which satisfy entered filtering parameters will be automatically highlighted +in the 3D viewer. + Using TUI Commands you can perform this operation in a variety of ways: - geompy.ExtractShapes(Shape, Type, isSorted) explodes a diff --git a/doc/salome/gui/GEOM/input/working_with_groups.doc b/doc/salome/gui/GEOM/input/working_with_groups.doc index d1eac3994..36a0d49a3 100644 --- a/doc/salome/gui/GEOM/input/working_with_groups.doc +++ b/doc/salome/gui/GEOM/input/working_with_groups.doc @@ -57,7 +57,7 @@ to the main and the second shape.
  • Hide selected - hides the sub-shapes selected in the list box.
  • Show all sub-shapes - displays only the sub-shapes of the Main Shape.
  • -
  • You can select the elements of your group in two ways: +
  • You can select the elements of your group in several ways: +
  • +
  • Filtering out some entities according to the specified threshold value or values +(see below).
  • Finally, confirm your selection by clicking Apply and Close (also closes the Menu) or \b Apply (leaves the Menu open for @@ -79,6 +81,26 @@ creation of other groups), or skip it by clicking \b Close button. \n The Result of the operation will be a \b GEOM_Object. +The \b Filter controls allow to automatically pick up entites which satisfy specified +threshold value(s). The numerical functor for each sub-shape that is compared with +threshold value(s) is computed according to the shape's topological properties: +- length for edges and wires +- area for faces and shells +- volume for solids, compounds, compsolids + +Filtering capabilities are not available for vertices. + +In order to filter out some entities: +- Activate one or two filtering controls by switching on corresponding check boxes; +- Select required threshold comparator type; the following choices are available: + - Less Than or Equal or Less Than for the first comparator; + - Greater Than or Equal or Greater Than for the second comparator; +- Enter required threshold value (values); +- Press \b Apply button in the \b Filter group. + +The entities which satisfy entered filtering parameters will be automatically highlighted +in the 3D viewer. + \n TUI Command: geompy.CreateGroup(MainShape, ShapeType), where MainShape is a shape for which the group is created, ShapeType is a type of shapes in the created group. diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx index d17b41504..3b075c804 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.cxx +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include @@ -51,8 +53,6 @@ #include -#include - #include namespace @@ -70,6 +70,8 @@ namespace "Flat" }; + enum { Filter_LT, Filter_LE, Filter_GT, Filter_GE }; + unsigned int NumberOfSubShapes(const TopoDS_Shape& S, const int shapeType, TopTools_MapOfShape& M) { unsigned int index = 0; @@ -149,9 +151,34 @@ EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidge GroupPoints->PushButton4->setText(tr("SHOW_ALL_SUB_SHAPES")); GroupPoints->LineEdit1->setReadOnly(true); + //filter group + + myFilterGrp = new QGroupBox(tr("GEOM_FILTER"), centralWidget()); + myLessFilterCheck = new QCheckBox(myFilterGrp); + myLessFilterCombo = new QComboBox(myFilterGrp); + myLessFilterCombo->addItem( tr("GEOM_LESS_THAN"), Filter_LT ); + myLessFilterCombo->addItem( tr("GEOM_LESSOREQUAL_THAN"), Filter_LE ); + myGreaterFilterCheck = new QCheckBox(myFilterGrp); + myGreaterFilterCombo = new QComboBox(myFilterGrp); + myGreaterFilterCombo->addItem( tr("GEOM_GREAT_THAN"), Filter_GT ); + myGreaterFilterCombo->addItem( tr("GEOM_GREATOREQUAL_THAN"), Filter_GE ); + myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); + myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); + myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp); + + QGridLayout* filterLayout = new QGridLayout(myFilterGrp); + filterLayout->addWidget(myLessFilterCheck, 0, 0); + filterLayout->addWidget(myLessFilterCombo, 0, 1); + filterLayout->addWidget(myLessFilterSpin, 0, 2); + filterLayout->addWidget(myGreaterFilterCheck, 1, 0); + filterLayout->addWidget(myGreaterFilterCombo, 1, 1); + filterLayout->addWidget(myGreaterFilterSpin, 1, 2); + filterLayout->addWidget(myApplyFilterButton, 0, 3); + QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); layout->addWidget(GroupPoints); + layout->addWidget(myFilterGrp); /***************************************************************/ setIsOptimizedBrowsing(true); @@ -183,6 +210,16 @@ EntityGUI_SubShapeDlg::~EntityGUI_SubShapeDlg() //================================================================================= void EntityGUI_SubShapeDlg::Init() { + // Get setting of step value from file configuration + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + double step = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100); + + // min, max, step and decimals for spin boxes + initSpinBox(myLessFilterSpin, 0., COORD_MAX, step, "length_precision" ); + initSpinBox(myGreaterFilterSpin, 0., COORD_MAX, step, "length_precision" ); + myLessFilterSpin->setValue( 0. ); + myGreaterFilterSpin->setValue( 0. ); + /* init variables */ myDmMode = -1; myEditCurrentArgument = GroupPoints->LineEdit1; @@ -212,6 +249,10 @@ void EntityGUI_SubShapeDlg::Init() connect(GroupPoints->PushButton3, SIGNAL(clicked()), this, SLOT(showOnlySelected())); connect(GroupPoints->PushButton4, SIGNAL(clicked()), this, SLOT(showOnlySelected())); + connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter())); + connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); + connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); @@ -219,6 +260,7 @@ void EntityGUI_SubShapeDlg::Init() resize(100,100); SelectionIntoArgument(); SubShapeToggled(); + MeasureToggled(); } //================================================================================= @@ -270,12 +312,11 @@ void EntityGUI_SubShapeDlg::ClickOnOk() /* More than 30 sub-shapes : ask confirmation */ unsigned int nb = NumberOfSubShapes(myShape, shapeType()); if (nb > 30) { - const QString caption = tr("GEOM_CONFIRM"); - const QString text = tr("GEOM_CONFIRM_INFO").arg(nb); - const QString button0 = tr("GEOM_BUT_EXPLODE"); - const QString button1 = tr("GEOM_BUT_CANCEL"); - - if (QMessageBox::warning(this, caption, text, button0, button1) != 0) + if (SUIT_MessageBox::question( this, + tr("GEOM_CONFIRM"), + tr("GEOM_CONFIRM_INFO").arg(nb), + tr("GEOM_BUT_EXPLODE"), + tr("GEOM_BUT_CANCEL") ) != 0 ) isOk = false; /* aborted */ } } @@ -300,12 +341,11 @@ bool EntityGUI_SubShapeDlg::ClickOnApply() /* More than 30 sub-shapes : ask confirmation */ unsigned int nb = NumberOfSubShapes(myShape, shapeType()); if (nb > 30) { - const QString caption = tr("GEOM_CONFIRM"); - const QString text = tr("GEOM_CONFIRM_INFO").arg(nb); - const QString button0 = tr("GEOM_BUT_EXPLODE"); - const QString button1 = tr("GEOM_BUT_CANCEL"); - - if (QMessageBox::warning(this, caption, text, button0, button1) != 0) + if (SUIT_MessageBox::question( this, + tr("GEOM_CONFIRM"), + tr("GEOM_CONFIRM_INFO").arg(nb), + tr("GEOM_BUT_EXPLODE"), + tr("GEOM_BUT_CANCEL") ) != 0 ) return false; /* aborted */ } } @@ -447,6 +487,9 @@ void EntityGUI_SubShapeDlg::SubShapeToggled() GroupPoints->PushButton2->setEnabled(!isAllSubShapes()); GroupPoints->PushButton3->setEnabled(!isAllSubShapes()); GroupPoints->PushButton4->setEnabled(!isAllSubShapes()); + myFilterGrp->setEnabled(GroupPoints->CheckButton1->isEnabled() && + GroupPoints->CheckButton1->isChecked() && + shapeType() < GEOM::VERTEX); activateSelection(); } @@ -479,6 +522,7 @@ void EntityGUI_SubShapeDlg::updateButtonState() GroupPoints->CheckButton1->setChecked( false ); GroupPoints->CheckButton1->setEnabled( false ); } + myFilterGrp->setEnabled(GroupPoints->CheckButton1->isEnabled() && GroupPoints->CheckButton1->isChecked()); } //================================================================================= @@ -834,3 +878,73 @@ QString EntityGUI_SubShapeDlg::getNewObjectName (int) const { return QString::null; } + +//================================================================================= +// function : ClickOnOkFilter() +// purpose : highlight and select entities which parameters (length, area or volume) are less than the value specified by the user +//================================================================================= +void EntityGUI_SubShapeDlg::ClickOnOkFilter() +{ + if (CORBA::is_nil(myObject) || isAllSubShapes() || shapeType() >= GEOM::VERTEX) + return; + + TopTools_IndexedMapOfShape aSubShapesMap; + TopExp::MapShapes(myShape, aSubShapesMap); + SALOME_View* view = GEOM_Displayer::GetActiveView(); + getDisplayer()->Erase(myObject, false, false); + CORBA::String_var aMainEntry = myObject->GetStudyEntry(); + QString anEntryBase = aMainEntry.in(); + + SALOME_ListIO toSelect; + + TopExp_Explorer anExp (myShape, (TopAbs_ShapeEnum)shapeType()); + for (; anExp.More(); anExp.Next()) + { + TopoDS_Shape aSubShape = anExp.Current(); + int index = aSubShapesMap.FindIndex(aSubShape); + QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index); + if ( !getDisplayer()->IsDisplayed( anEntry ) ) + continue; + + double factor = GEOMUtils::ShapeToDouble(aSubShape).second; + double v1 = myLessFilterSpin->value(); + double v2 = myGreaterFilterSpin->value(); + bool isLess = myLessFilterCombo->itemData(myLessFilterCombo->currentIndex()).toInt() == Filter_LT ? factor < v1 : factor <= v1; + bool isGreater = myGreaterFilterCombo->itemData(myGreaterFilterCombo->currentIndex()).toInt() == Filter_GT ? factor > v2 : factor >= v2; + if ( ( myLessFilterCheck->isChecked() && myGreaterFilterCheck->isChecked() && isLess && isGreater ) || + ( myLessFilterCheck->isChecked() && !myGreaterFilterCheck->isChecked() && isLess ) || + ( myGreaterFilterCheck->isChecked() && !myLessFilterCheck->isChecked() && isGreater ) ) { + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject(); + io->setEntry( anEntry.toLatin1().constData() ); + toSelect.Append(io); + } + } + if ( toSelect.Extent() > 0 ) { + myGeomGUI->getApp()->selectionMgr()->setSelectedObjects(toSelect); + SUIT_MessageBox::information( this, + tr( "INF_INFO" ), + tr( "GEOM_SOME_SHAPES_SELECTED").arg( toSelect.Extent() ), + tr( "BUT_OK" ) ); + } + else { + SUIT_MessageBox::information( this, + tr( "INF_INFO" ), + tr( "GEOM_NO_SHAPES_SELECTED" ), + tr( "BUT_OK" ) ); + } + updateButtonState(); +} + +//================================================================================= +// function : MeasureToggled() +// purpose : +// : Called when 'myLessFilterCheck' or 'myGreaterFilterCheck' state change +//================================================================================= +void EntityGUI_SubShapeDlg::MeasureToggled() +{ + myLessFilterSpin->setEnabled(myLessFilterCheck->isChecked()); + myLessFilterCombo->setEnabled(myLessFilterCheck->isChecked()); + myGreaterFilterSpin->setEnabled(myGreaterFilterCheck->isChecked()); + myGreaterFilterCombo->setEnabled(myGreaterFilterCheck->isChecked()); + myApplyFilterButton->setEnabled(myLessFilterCheck->isChecked() || myGreaterFilterCheck->isChecked()); +} diff --git a/src/EntityGUI/EntityGUI_SubShapeDlg.h b/src/EntityGUI/EntityGUI_SubShapeDlg.h index 56bb3311d..da3b65c74 100644 --- a/src/EntityGUI/EntityGUI_SubShapeDlg.h +++ b/src/EntityGUI/EntityGUI_SubShapeDlg.h @@ -31,6 +31,11 @@ #include +class QCheckBox; +class QComboBox; +class QGroupBox; +class QPushButton; +class SalomeApp_DoubleSpinBox; class DlgRef_1Sel1List1Check3Btn; //================================================================================= @@ -66,6 +71,8 @@ private slots: void ComboTextChanged(); void showOnlySelected(); + void ClickOnOkFilter(); + void MeasureToggled(); private: void Init(); @@ -87,6 +94,14 @@ private: bool myIsHiddenMain; DlgRef_1Sel1List1Check3Btn* GroupPoints; + QCheckBox* myLessFilterCheck; + QCheckBox* myGreaterFilterCheck; + QComboBox* myLessFilterCombo; + QComboBox* myGreaterFilterCombo; + SalomeApp_DoubleSpinBox* myLessFilterSpin; + SalomeApp_DoubleSpinBox* myGreaterFilterSpin; + QPushButton* myApplyFilterButton; + QGroupBox* myFilterGrp; }; #endif // ENTITYGUI_SUBSHAPEDLG_H diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 52e6b7809..3a6f293de 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -5152,6 +5152,34 @@ shells and solids on the other hand. CC_PNT_ITEM_X_Y_Z X=%1, Y=%2, Z=%3 + + GEOM_FILTER + Filter + + + GEOM_LESS_THAN + Less Than + + + GEOM_LESSOREQUAL_THAN + Equal or Less Than + + + GEOM_GREAT_THAN + Greater Than + + + GEOM_GREATOREQUAL_THAN + Equal or Greater Than + + + GEOM_SOME_SHAPES_SELECTED + %1 shape(s) has(have) been selected + + + GEOM_NO_SHAPES_SELECTED + There are no shapes that meet filtering parameters + GeometryGUI diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 07c02e244..148f80ca7 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -5108,6 +5108,34 @@ le paramètre '%1' aux préférences du module Géométrie.CC_PNT_ITEM_X_Y_Z X=%1, Y=%2, Z=%3 + + GEOM_FILTER + Filter + + + GEOM_LESS_THAN + Less Than + + + GEOM_LESSOREQUAL_THAN + Equal or Less Than + + + GEOM_GREAT_THAN + Greater Than + + + GEOM_GREATOREQUAL_THAN + Equal or Greater Than + + + GEOM_SOME_SHAPES_SELECTED + %1 shape(s) has(have) been selected + + + GEOM_NO_SHAPES_SELECTED + There are no shapes that meet filtering parameters + GeometryGUI diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index 8d7cd8e2d..2798b3f46 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -5095,6 +5095,34 @@ CC_PNT_ITEM_X_Y_Z X=%1, Y=%2, Z=%3 + + GEOM_FILTER + Filter + + + GEOM_LESS_THAN + Less Than + + + GEOM_LESSOREQUAL_THAN + Equal or Less Than + + + GEOM_GREAT_THAN + Greater Than + + + GEOM_GREATOREQUAL_THAN + Equal or Greater Than + + + GEOM_SOME_SHAPES_SELECTED + %1 shape(s) has(have) been selected + + + GEOM_NO_SHAPES_SELECTED + There are no shapes that meet filtering parameters + GeometryGUI diff --git a/src/GEOMUtils/GEOMUtils.cxx b/src/GEOMUtils/GEOMUtils.cxx index aa8c3d7a3..a0baf02f3 100644 --- a/src/GEOMUtils/GEOMUtils.cxx +++ b/src/GEOMUtils/GEOMUtils.cxx @@ -212,46 +212,6 @@ namespace return isModified; } - //======================================================================= - //function : ShapeToDouble - //purpose : used by CompareShapes::operator() - //======================================================================= - std::pair ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting) - { - // Computing of CentreOfMass - gp_Pnt GPoint; - double Len; - - if (S.ShapeType() == TopAbs_VERTEX) { - GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S)); - Len = (double)S.Orientation(); - } - else { - GProp_GProps GPr; - // BEGIN: fix for Mantis issue 0020842 - if (isOldSorting) { - BRepGProp::LinearProperties(S, GPr); - } - else { - if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { - BRepGProp::LinearProperties(S, GPr); - } - else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { - BRepGProp::SurfaceProperties(S, GPr); - } - else { - BRepGProp::VolumeProperties(S, GPr); - } - } - // END: fix for Mantis issue 0020842 - GPoint = GPr.CentreOfMass(); - Len = GPr.Mass(); - } - - double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9; - return std::make_pair(dMidXYZ, Len); - } - void parseWard( const GEOMUtils::LevelsList &theLevelList, std::string &treeStr ) { treeStr.append( "{" ); @@ -324,6 +284,46 @@ namespace } +//======================================================================= +//function : ShapeToDouble +//purpose : used by CompareShapes::operator() +//======================================================================= +std::pair GEOMUtils::ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting) +{ + // Computing of CentreOfMass + gp_Pnt GPoint; + double Len; + + if (S.ShapeType() == TopAbs_VERTEX) { + GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S)); + Len = (double)S.Orientation(); + } + else { + GProp_GProps GPr; + // BEGIN: fix for Mantis issue 0020842 + if (isOldSorting) { + BRepGProp::LinearProperties(S, GPr); + } + else { + if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { + BRepGProp::LinearProperties(S, GPr); + } + else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { + BRepGProp::SurfaceProperties(S, GPr); + } + else { + BRepGProp::VolumeProperties(S, GPr); + } + } + // END: fix for Mantis issue 0020842 + GPoint = GPr.CentreOfMass(); + Len = GPr.Mass(); + } + + double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9; + return std::make_pair(dMidXYZ, Len); +} + //======================================================================= //function : GetPosition //purpose : diff --git a/src/GEOMUtils/GEOMUtils.hxx b/src/GEOMUtils/GEOMUtils.hxx index 95c0e7c0f..0fd9d22a0 100644 --- a/src/GEOMUtils/GEOMUtils.hxx +++ b/src/GEOMUtils/GEOMUtils.hxx @@ -60,6 +60,28 @@ namespace GEOMUtils typedef std::vector LevelsList; typedef std::map > TreeModel; + /*! + * \brief Compute numerical functor for the shape. + * + * Resulting value can be used to sort out shapes according to some parameter. + * + * Returns a pair of two values (dist, functor) where + * - \a dist is a some value that is computed according to the center of mass of given shape; + * - \a functor is a numerical functor value + * + * The numerical functor is computed according to the shape's topological properties as follows: + * - orientation for vertices + * - length for edges and wires + * - area for faces and shells + * - volume for solids, compounds, compsolids + * + * If \a isOldSorting parameter is set to \c true, for all cases linear properties of the shape + * are used (to support backward compatibility in some methods). By default, this parameter is + * set to \c false. + */ + Standard_EXPORT std::pair ShapeToDouble (const TopoDS_Shape& theShape, + bool isOldSorting = false); + /*! * \brief Get Local Coordinate System, corresponding to the given shape. * diff --git a/src/GroupGUI/CMakeLists.txt b/src/GroupGUI/CMakeLists.txt index 72673f3be..bccf3e3ad 100755 --- a/src/GroupGUI/CMakeLists.txt +++ b/src/GroupGUI/CMakeLists.txt @@ -34,6 +34,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_BINARY_DIR}/idl ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/src/OBJECT + ${PROJECT_SOURCE_DIR}/src/GEOMUtils ${PROJECT_SOURCE_DIR}/src/GEOMClient ${PROJECT_SOURCE_DIR}/src/GEOMImpl ${PROJECT_SOURCE_DIR}/src/GEOMGUI @@ -54,6 +55,7 @@ ADD_DEFINITIONS( # libraries to link to SET(_link_LIBRARIES GEOMBase + GEOMUtils ) # --- resources --- diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index fa50a5357..c2c62441c 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,10 @@ #define GROUP_IDLST_COLOR Qt::blue // Specific color for the IDs of subShapes in the dialog box #define GROUP_NEWIDLST_COLOR Qt::red // Specific color for the new IDs of subShapes in the dialog box -enum { ALL_SUBSHAPES = 0, GET_IN_PLACE, SUBSHAPES_OF_SHAPE2, SUBSHAPES_OF_INVISIBLE_SHAPE2 }; +namespace { + enum { ALL_SUBSHAPES = 0, GET_IN_PLACE, SUBSHAPES_OF_SHAPE2, SUBSHAPES_OF_INVISIBLE_SHAPE2 }; + enum { Filter_LT, Filter_LE, Filter_GT, Filter_GE }; +} GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QWidget* parent) : GEOMBase_Skeleton(theGeometryGUI, parent, false), @@ -180,9 +184,34 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW aMedLayout->setRowStretch(5, 5); aMedLayout->setRowStretch(8, 5); + //filter group + + myFilterGrp = new QGroupBox(tr("GEOM_FILTER"), centralWidget()); + myLessFilterCheck = new QCheckBox(myFilterGrp); + myLessFilterCombo = new QComboBox(myFilterGrp); + myLessFilterCombo->addItem( tr("GEOM_LESS_THAN"), Filter_LT ); + myLessFilterCombo->addItem( tr("GEOM_LESSOREQUAL_THAN"), Filter_LE ); + myGreaterFilterCheck = new QCheckBox(myFilterGrp); + myGreaterFilterCombo = new QComboBox(myFilterGrp); + myGreaterFilterCombo->addItem( tr("GEOM_GREAT_THAN"), Filter_GT ); + myGreaterFilterCombo->addItem( tr("GEOM_GREATOREQUAL_THAN"), Filter_GE ); + myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); + myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp); + myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp); + + QGridLayout* filterLayout = new QGridLayout(myFilterGrp); + filterLayout->addWidget(myLessFilterCheck, 0, 0); + filterLayout->addWidget(myLessFilterCombo, 0, 1); + filterLayout->addWidget(myLessFilterSpin, 0, 2); + filterLayout->addWidget(myGreaterFilterCheck, 1, 0); + filterLayout->addWidget(myGreaterFilterCombo, 1, 1); + filterLayout->addWidget(myGreaterFilterSpin, 1, 2); + filterLayout->addWidget(myApplyFilterButton, 0, 3); + QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); layout->addWidget(GroupMedium); + layout->addWidget(myFilterGrp); setHelpFileName("work_with_groups_page.html"); @@ -210,6 +239,16 @@ GroupGUI_GroupDlg::~GroupGUI_GroupDlg() //================================================================================= void GroupGUI_GroupDlg::Init() { + // Get setting of step value from file configuration + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + double step = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100); + + // min, max, step and decimals for spin boxes + initSpinBox(myLessFilterSpin, 0., COORD_MAX, step, "length_precision" ); + initSpinBox(myGreaterFilterSpin, 0., COORD_MAX, step, "length_precision" ); + myLessFilterSpin->setValue( 0. ); + myGreaterFilterSpin->setValue( 0. ); + myDmMode = -1; LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr(); @@ -282,11 +321,16 @@ void GroupGUI_GroupDlg::Init() connect(myShowAllBtn, SIGNAL(clicked()), this, SLOT(showOnlySelected())); connect(myIdList, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged())); + connect(myApplyFilterButton, SIGNAL(clicked()), this, SLOT(ClickOnOkFilter())); + connect(myLessFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); + connect(myGreaterFilterCheck, SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled())); + setInPlaceObj(GEOM::GEOM_Object::_nil()); myBusy = true; // just activate but do not select in the list activateSelection(); myBusy = false; + MeasureToggled(); } //================================================================================= @@ -1080,9 +1124,13 @@ void GroupGUI_GroupDlg::updateState (bool isAdd) myRemBtn->setEnabled(hasSel); myRestrictGroupBox->setEnabled(!CORBA::is_nil(myMainObj)); mySelAllBtn->setEnabled(!CORBA::is_nil(myMainObj)); - + mySelBtn2->setEnabled(subSelectionWay() != ALL_SUBSHAPES); myShape2Name->setEnabled(subSelectionWay() != ALL_SUBSHAPES); + myFilterGrp->setEnabled(!CORBA::is_nil(myMainObj) && + subSelectionWay() == ALL_SUBSHAPES && + myIsShapeType && + getShapeType() != TopAbs_VERTEX); if (subSelectionWay() == ALL_SUBSHAPES) setInPlaceObj(GEOM::GEOM_Object::_nil()); } @@ -1317,3 +1365,65 @@ GEOM::GEOM_Object_ptr GroupGUI_GroupDlg::getFather(GEOM::GEOM_Object_ptr theObj) } return aFatherObj._retn(); } + +void GroupGUI_GroupDlg::ClickOnOkFilter() +{ + if (CORBA::is_nil(myMainObj) || subSelectionWay() != ALL_SUBSHAPES || !myIsShapeType || getShapeType() == TopAbs_VERTEX) + return; + + TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj); + TopTools_IndexedMapOfShape aSubShapesMap; + TopExp::MapShapes(aMainShape, aSubShapesMap); + SALOME_View* view = GEOM_Displayer::GetActiveView(); + getDisplayer()->Erase(myMainObj, false, false); + CORBA::String_var aMainEntry = myMainObj->GetStudyEntry(); + QString anEntryBase = aMainEntry.in(); + + SALOME_ListIO toSelect; + + TopExp_Explorer anExp (aMainShape, (TopAbs_ShapeEnum)getShapeType()); + for (; anExp.More(); anExp.Next()) + { + TopoDS_Shape aSubShape = anExp.Current(); + int index = aSubShapesMap.FindIndex(aSubShape); + QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index); + if ( !getDisplayer()->IsDisplayed( anEntry ) ) + continue; + + double factor = GEOMUtils::ShapeToDouble(aSubShape).second; + double v1 = myLessFilterSpin->value(); + double v2 = myGreaterFilterSpin->value(); + bool isLess = myLessFilterCombo->itemData(myLessFilterCombo->currentIndex()).toInt() == Filter_LT ? factor < v1 : factor <= v1; + bool isGreater = myGreaterFilterCombo->itemData(myGreaterFilterCombo->currentIndex()).toInt() == Filter_GT ? factor > v2 : factor >= v2; + if ( ( myLessFilterCheck->isChecked() && myGreaterFilterCheck->isChecked() && isLess && isGreater ) || + ( myLessFilterCheck->isChecked() && !myGreaterFilterCheck->isChecked() && isLess ) || + ( myGreaterFilterCheck->isChecked() && !myLessFilterCheck->isChecked() && isGreater ) ) { + Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject(); + io->setEntry( anEntry.toLatin1().constData() ); + toSelect.Append(io); + } + } + if ( toSelect.Extent() > 0 ) { + myGeomGUI->getApp()->selectionMgr()->setSelectedObjects(toSelect); + SUIT_MessageBox::information( this, + tr( "INF_INFO" ), + tr( "GEOM_SOME_SHAPES_SELECTED").arg( toSelect.Extent() ), + tr( "BUT_OK" ) ); + } + else { + SUIT_MessageBox::information( this, + tr( "INF_INFO" ), + tr( "GEOM_NO_SHAPES_SELECTED" ), + tr( "BUT_OK" ) ); + } + updateState(true); +} + +void GroupGUI_GroupDlg::MeasureToggled() +{ + myLessFilterSpin->setEnabled(myLessFilterCheck->isChecked()); + myLessFilterCombo->setEnabled(myLessFilterCheck->isChecked()); + myGreaterFilterSpin->setEnabled(myGreaterFilterCheck->isChecked()); + myGreaterFilterCombo->setEnabled(myGreaterFilterCheck->isChecked()); + myApplyFilterButton->setEnabled(myLessFilterCheck->isChecked() || myGreaterFilterCheck->isChecked()); +} diff --git a/src/GroupGUI/GroupGUI_GroupDlg.h b/src/GroupGUI/GroupGUI_GroupDlg.h index fe43e2221..e47a90a33 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.h +++ b/src/GroupGUI/GroupGUI_GroupDlg.h @@ -33,10 +33,14 @@ #include #include +class QCheckBox; +class QComboBox; +class QPushButton; class QGroupBox; class QLineEdit; class QListWidget; class QButtonGroup; +class SalomeApp_DoubleSpinBox; //================================================================================= // class : GroupGUI_GroupDlg @@ -77,6 +81,8 @@ private slots: void remove(); void showOnlySelected(); void selectionChanged(); + void ClickOnOkFilter(); + void MeasureToggled(); private: void Init(); @@ -119,6 +125,14 @@ private: QPushButton* myHideSelBtn; QPushButton* myShowAllBtn; QListWidget* myIdList; + QCheckBox* myLessFilterCheck; + QCheckBox* myGreaterFilterCheck; + QComboBox* myLessFilterCombo; + QComboBox* myGreaterFilterCombo; + SalomeApp_DoubleSpinBox* myLessFilterSpin; + SalomeApp_DoubleSpinBox* myGreaterFilterSpin; + QPushButton* myApplyFilterButton; + QGroupBox* myFilterGrp; }; #endif