]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
0022764: [EDF] Filtering operators in Group and Explode dialog boxes
authorvsr <vsr@opencascade.com>
Wed, 12 Nov 2014 16:40:11 +0000 (19:40 +0300)
committervsr <vsr@opencascade.com>
Thu, 13 Nov 2014 13:05:45 +0000 (16:05 +0300)
15 files changed:
doc/salome/gui/GEOM/images/editgroup.png
doc/salome/gui/GEOM/images/geomcreategroup.png
doc/salome/gui/GEOM/images/neo-obj1.png
doc/salome/gui/GEOM/input/creating_explode.doc
doc/salome/gui/GEOM/input/working_with_groups.doc
src/EntityGUI/EntityGUI_SubShapeDlg.cxx
src/EntityGUI/EntityGUI_SubShapeDlg.h
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GEOM_msg_fr.ts
src/GEOMGUI/GEOM_msg_ja.ts
src/GEOMUtils/GEOMUtils.cxx
src/GEOMUtils/GEOMUtils.hxx
src/GroupGUI/CMakeLists.txt
src/GroupGUI/GroupGUI_GroupDlg.cxx
src/GroupGUI/GroupGUI_GroupDlg.h

index d0a3c314b7cc10e2d0579a82beb39457e11a1d95..c7f55074e27ea482a3fe678945ae82c6b0ea61e4 100755 (executable)
Binary files a/doc/salome/gui/GEOM/images/editgroup.png and b/doc/salome/gui/GEOM/images/editgroup.png differ
index b74b00dfbb48dbfb206df831565e7cc3ed66421b..0f67a625c1f772ed7a469793c067a109ff01e0e1 100755 (executable)
Binary files a/doc/salome/gui/GEOM/images/geomcreategroup.png and b/doc/salome/gui/GEOM/images/geomcreategroup.png differ
index df078a1fef32fcb7cffc628472dae353679a5524..438c6339bf7e3fa068256ff7cb0ebafc2aade0fd 100755 (executable)
Binary files a/doc/salome/gui/GEOM/images/neo-obj1.png and b/doc/salome/gui/GEOM/images/neo-obj1.png differ
index e3ae84893776131bb4b53a52eee059e943bb3d62..6caf20df12b9275f058ac9f177a2e9ccef3409de 100644 (file)
@@ -42,6 +42,27 @@ Switching on <b>Select Sub-shapes</b> 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 <b>Select Sub-shapes</b> 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:
+  - <b>Less Than</b> or <b>Equal or Less Than</b> for the first comparator;
+  - <b>Greater Than</b> or <b>Equal or Greater Than</b> 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 <b>TUI Commands</b> you can perform this operation in a
 variety of ways:
 - <em>geompy.ExtractShapes(Shape, Type, isSorted)</em> explodes a
index d1eac3994c018e6efdb3729809da5fa45a4ac578..36a0d49a30b84f48fb5abc434f6493376a53eba7 100644 (file)
@@ -57,7 +57,7 @@ to the main and the second shape.</li>
 <li><b>Hide selected</b> - hides the sub-shapes selected in the list box.</li>
 <li><b>Show all sub-shapes</b> - displays only the sub-shapes of the Main Shape.</li>
 </ul>
-<li> You can select the elements of your group in two ways:
+<li> You can select the elements of your group in several ways:
 <ul>
 <li>You can select them manually in the 3D Viewer, and add to the
 group by clicking the \b Add button (keep down the Shift button on the
@@ -70,7 +70,9 @@ elements of a certain type in the list of the elements of the
 group. If the <b>Second Shape</b> is used, the elements are added 
 according to <b>Main Shape Selection restriction</b> settings. To delete elements 
 from the list, select them and click \b Remove button.
-</li></ul>
+</li>
+<li>Filtering out some entities according to the specified threshold value or values
+(see below).</li></ul>
 </li>
 <li>Finally, confirm your selection by clicking <b>Apply and Close
 </b> (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:
+  - <b>Less Than</b> or <b>Equal or Less Than</b> for the first comparator;
+  - <b>Greater Than</b> or <b>Equal or Greater Than</b> 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 <b>TUI Command:</b> <em>geompy.CreateGroup(MainShape,
 ShapeType),</em> where MainShape is a shape for which the group is
 created, ShapeType is a type of shapes in the created group.
index 9e6114394fbc0f5183bb0073bb5b30ccb980a966..ec0f3891c31062c934af6f1cd0224ac81e26c977 100644 (file)
@@ -29,6 +29,7 @@
 #include <DlgRef.h>
 #include <GeometryGUI.h>
 #include <GEOMBase.h>
+#include <GEOMUtils.hxx>
 
 #include <OCCViewer_ViewModel.h>
 #include <SVTK_ViewModel.h>
@@ -36,6 +37,7 @@
 #include <SalomeApp_Application.h>
 #include <LightApp_SelectionMgr.h>
 #include <SALOME_ListIO.hxx>
+#include <SUIT_MessageBox.h>
 
 #include <SUIT_Desktop.h>
 #include <SUIT_ResourceMgr.h>
@@ -51,8 +53,6 @@
 
 #include <TColStd_IndexedMapOfInteger.hxx>
 
-#include <QMessageBox>
-
 #include <GEOMImpl_Types.hxx>
 
 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());
+}
index 56bb3311de7367ade3e90a762df9dc890e378221..da3b65c745d7cc2966a1f16e7d8b277bc5af1817 100644 (file)
 
 #include <TColStd_IndexedMapOfInteger.hxx>
 
+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
index 6f80399afc03c11140c1465f6f267a4db40b94e1..a3de0e03148ee49efdf9d801f7f9dba2fbcdfcf0 100644 (file)
@@ -5152,6 +5152,34 @@ shells and solids on the other hand.</translation>
         <source>CC_PNT_ITEM_X_Y_Z</source>
         <translation>X=%1, Y=%2, Z=%3</translation>
     </message>
+    <message>
+        <source>GEOM_FILTER</source>
+        <translation>Filter</translation>
+    </message>
+    <message>
+        <source>GEOM_LESS_THAN</source>
+        <translation>Less Than</translation>
+    </message>
+    <message>
+        <source>GEOM_LESSOREQUAL_THAN</source>
+        <translation>Equal or Less Than</translation>
+    </message>
+    <message>
+        <source>GEOM_GREAT_THAN</source>
+        <translation>Greater Than</translation>
+    </message>
+    <message>
+        <source>GEOM_GREATOREQUAL_THAN</source>
+        <translation>Equal or Greater Than</translation>
+    </message>
+    <message>
+        <source>GEOM_SOME_SHAPES_SELECTED</source>
+        <translation>%1 shape(s) has(have) been selected</translation>
+    </message>
+    <message>
+        <source>GEOM_NO_SHAPES_SELECTED</source>
+        <translation>There are no shapes that meet filtering parameters</translation>
+    </message>
 </context>
 <context>
     <name>GeometryGUI</name>
index 7bb28365f6bc1f7b20c3b4416fdfbe8024f40e4b..45f12ad4f95407d644d17c910305638120012d6d 100644 (file)
@@ -5100,6 +5100,34 @@ le paramètre &apos;%1&apos; aux préférences du module Géométrie.</translati
         <source>CC_PNT_ITEM_X_Y_Z</source>
         <translation>X=%1, Y=%2, Z=%3</translation>
     </message>
+    <message>
+        <source>GEOM_FILTER</source>
+        <translation type="unfinished">Filter</translation>
+    </message>
+    <message>
+        <source>GEOM_LESS_THAN</source>
+        <translation type="unfinished">Less Than</translation>
+    </message>
+    <message>
+        <source>GEOM_LESSOREQUAL_THAN</source>
+        <translation type="unfinished">Equal or Less Than</translation>
+    </message>
+    <message>
+        <source>GEOM_GREAT_THAN</source>
+        <translation type="unfinished">Greater Than</translation>
+    </message>
+    <message>
+        <source>GEOM_GREATOREQUAL_THAN</source>
+        <translation type="unfinished">Equal or Greater Than</translation>
+    </message>
+    <message>
+        <source>GEOM_SOME_SHAPES_SELECTED</source>
+        <translation type="unfinished">%1 shape(s) has(have) been selected</translation>
+    </message>
+    <message>
+        <source>GEOM_NO_SHAPES_SELECTED</source>
+        <translation type="unfinished">There are no shapes that meet filtering parameters</translation>
+    </message>
 </context>
 <context>
     <name>GeometryGUI</name>
index 8ee7476d70b46e967325b103cc7f780a372ca50c..f68d1c4b948e848fd308da3802fc793efd8ac8d2 100644 (file)
       <source>CC_PNT_ITEM_X_Y_Z</source>
       <translation>X=%1, Y=%2, Z=%3</translation>
     </message>
+    <message>
+        <source>GEOM_FILTER</source>
+        <translation type="unfinished">Filter</translation>
+    </message>
+    <message>
+        <source>GEOM_LESS_THAN</source>
+        <translation type="unfinished">Less Than</translation>
+    </message>
+    <message>
+        <source>GEOM_LESSOREQUAL_THAN</source>
+        <translation type="unfinished">Equal or Less Than</translation>
+    </message>
+    <message>
+        <source>GEOM_GREAT_THAN</source>
+        <translation type="unfinished">Greater Than</translation>
+    </message>
+    <message>
+        <source>GEOM_GREATOREQUAL_THAN</source>
+        <translation type="unfinished">Equal or Greater Than</translation>
+    </message>
+    <message>
+        <source>GEOM_SOME_SHAPES_SELECTED</source>
+        <translation type="unfinished">%1 shape(s) has(have) been selected</translation>
+    </message>
+    <message>
+        <source>GEOM_NO_SHAPES_SELECTED</source>
+        <translation type="unfinished">There are no shapes that meet filtering parameters</translation>
+    </message>
   </context>
   <context>
     <name>GeometryGUI</name>
index 2a28e34ccaa25eed3e3c26bf5db6ff63dc483ce3..5b5cc2574a167a061354e90e033e212f285b127f 100644 (file)
@@ -212,46 +212,6 @@ namespace
     return isModified;
   }
 
-  //=======================================================================
-  //function : ShapeToDouble
-  //purpose  : used by CompareShapes::operator()
-  //=======================================================================
-  std::pair<double, double> 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<double, double> 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  :
index 95c0e7c0f0201531a4a10d9912e00fc8fb5913c9..0fd9d22a06f7369d8f69c67f97885a32c04b8c80 100644 (file)
@@ -60,6 +60,28 @@ namespace GEOMUtils
   typedef std::vector<LevelInfo> LevelsList;
   typedef std::map<std::string,std::pair<LevelsList,LevelsList> > 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<double, double> ShapeToDouble (const TopoDS_Shape& theShape,
+                                                           bool isOldSorting = false);
+
   /*!
    * \brief Get Local Coordinate System, corresponding to the given shape.
    *
index 72673f3be397a0c43901cd3b748a3e670d9a70ca..bccf3e3ad242158712ed8169ebd9a91c4e4cfb45 100755 (executable)
@@ -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 ---
index a34a137d427e28795587b15c5a4f813c32640971..63127af248c5b37cbf204c352ad25a947b8a2a03 100644 (file)
@@ -30,6 +30,7 @@
 #include <GEOMBase.h>
 #include <GeometryGUI.h>
 #include <GEOM_Displayer.h>
+#include <GEOMUtils.hxx>
 
 #include <SalomeApp_Application.h>
 #include <SalomeApp_Study.h>
 #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());
+}
index fe43e22213ebbee9a33bb497ed58da0216ec7d16..e47a90a33494fb61e4c4d2ec88f6a7cc8e962092 100644 (file)
 #include <TColStd_DataMapOfIntegerInteger.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
 
+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