]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Make selection
authorvsv <vsv@opencascade.com>
Thu, 15 Nov 2018 15:04:17 +0000 (18:04 +0300)
committervsv <vsv@opencascade.com>
Thu, 15 Nov 2018 15:04:17 +0000 (18:04 +0300)
src/CollectionPlugin/CMakeLists.txt
src/Filters/Filters_HorizontalPlane.cpp
src/Filters/Filters_HorizontalPlane.h
src/Filters/Filters_VerticalPlane.cpp
src/Filters/Filters_VerticalPlane.h
src/ModelAPI/ModelAPI_Filter.h
src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp
src/ModuleBase/ModuleBase_WidgetSelectionFilter.h

index 674ea7e083acd72af5fce5378bfa0a70f9553283..93d9b5203b74dbd32b657e901911aaa84a7677e1 100644 (file)
@@ -36,6 +36,7 @@ SET(PROJECT_HEADERS
     CollectionPlugin_WidgetCreator.h
     CollectionPlugin_WidgetField.h
        CollectionPlugin_Validators.h
+       CollectionPlugin_GroupFilters.h
 )
 
 SET(PROJECT_MOC_HEADERS
index 13d5595cc955085bebf1b3eb61c4f3546b6e9ac0..13012a5f0744ab8bb648fde29ccdb760d3d1c550 100644 (file)
@@ -30,7 +30,7 @@ bool Filters_HorizontalPlane::isOk(const GeomShapePtr& theShape) const
 
   if (!theShape->isPlanar())
     return false;
-  GeomFacePtr aFace = std::dynamic_pointer_cast<GeomAPI_Face>(theShape);
+  GeomFacePtr aFace(new GeomAPI_Face(theShape));
 
   GeomPlanePtr aPlane = aFace->getPlane();
   GeomDirPtr aDir = aPlane->direction();
index e5ad861f5aa370a33d862a019acdbabef6d34896..cca9a88168c811d6cf6e0856cb0c7d64e7d54c54 100644 (file)
@@ -28,6 +28,8 @@
 class Filters_HorizontalPlane : public ModelAPI_Filter
 {
 public:
+  Filters_HorizontalPlane() : ModelAPI_Filter() {}
+
   virtual bool isOk(const GeomShapePtr& theShape) const;
 
   /// Returns list of supported types of shapes (see GeomAPI_Shape::ShapeType)
index 48334749d008fa44e224486aef312884b9978f81..ac09a72395fd6d4ef046dd1402d5feae1ceb6af2 100644 (file)
@@ -30,11 +30,11 @@ bool Filters_VerticalPlane::isOk(const GeomShapePtr& theShape) const
 
   if (!theShape->isPlanar())
     return false;
-  GeomFacePtr aFace = std::dynamic_pointer_cast<GeomAPI_Face>(theShape);
+  GeomFacePtr aFace(new GeomAPI_Face(theShape));
 
   GeomPlanePtr aPlane = aFace->getPlane();
   GeomDirPtr aDir = aPlane->direction();
-  if (aDir->z() <= 1.e-7)
+  if (fabs(aDir->z()) <= 1.e-7)
     return true;
   return false;
 }
index 2dc201fd5e420f13fed99527e09fa15ea9d4caea..69fb248b2b43630c68dedfada5c7d09f63140a06 100644 (file)
@@ -28,6 +28,8 @@
 class Filters_VerticalPlane : public ModelAPI_Filter
 {
 public:
+  Filters_VerticalPlane() : ModelAPI_Filter() {}
+
   virtual bool isOk(const GeomShapePtr& theShape) const;
 
   /// Returns list of supported types of shapes (see GeomAPI_Shape::ShapeType)
index 660cb26924f7a0dc5f3bd1267c65d3831d7b6544..76f3549ce090b74fe2794ff22b23799b442ed080 100644 (file)
@@ -43,13 +43,11 @@ public:
     ObjectParameter
   };
 
+  ModelAPI_Filter(): myIsReverse(false) {}
+
   /// Returns name of the filter to represent it in GUI
   virtual std::string name() const = 0;
 
-  /// Returns true if the given shape is accepted by filter
-  /// \param theShape the given shape
-  virtual bool isOk(const GeomShapePtr& theShape) const = 0;
-
   /// Returns list of supported types of shapes (see GeomAPI_Shape::ShapeType)
   virtual std::list<int> shapeTypes() const = 0;
 
@@ -77,6 +75,26 @@ public:
   /// Returns shape parameter type. Types from GeomAPI_Shape  have to be used.
   /// A type GeomAPI_Shape::SHAPE means any shape
   virtual int shapeParameterType() const { return GeomAPI_Shape::SHAPE; }
+
+  /// Set reversed flag for the filter
+  void setReversed(bool theRev) { myIsReverse = theRev; }
+
+  bool isReversed() const { return myIsReverse; }
+
+  bool isValid(const GeomShapePtr& theShape)
+  {
+    if (myIsReverse)
+      return !isOk(theShape);
+    return isOk(theShape);
+  }
+
+protected:
+  /// Returns true if the given shape is accepted by filter
+  /// \param theShape the given shape
+  virtual bool isOk(const GeomShapePtr& theShape) const = 0;
+
+private:
+  bool myIsReverse;
 };
 
 typedef std::shared_ptr<ModelAPI_Filter> FilterPtr;
index 7f91db2b32c5c253b9ee6ef125825f145e0c6f0f..07d0ff4d550d003175b52b93ee518df79b617b43 100644 (file)
 #include "ModuleBase_Tools.h"
 #include "ModuleBase_IWorkshop.h"
 #include "ModuleBase_IModule.h"
+#include "ModuleBase_IViewer.h"
 #include "ModuleBase_IPropertyPanel.h"
 #include "ModuleBase_PageWidget.h"
-#include "ModuleBase_WidgetSelector.h"
+#include "ModuleBase_WidgetMultiSelector.h"
 
 #include <ModelAPI_Session.h>
+#include <GeomAPI_ShapeExplorer.h>
+
+#include <AIS_InteractiveContext.hxx>
+#include <StdSelect_BRepOwner.hxx>
+#include <TopoDS_Compound.hxx>
+#include <BRep_Builder.hxx>
 
 #include <QLayout>
 #include <QPushButton>
@@ -68,8 +75,11 @@ ModuleBase_FilterStarter::ModuleBase_FilterStarter(const std::string& theFeature
 void ModuleBase_FilterStarter::onFiltersLaunch()
 {
   SelectionType = myShapeType;
-  ModuleBase_WidgetSelector* aSelector = dynamic_cast<ModuleBase_WidgetSelector*>(parent());
+  ModuleBase_WidgetMultiSelector* aSelector =
+    dynamic_cast<ModuleBase_WidgetMultiSelector*>(parent());
+  aSelector->onSelectionTypeChanged(); // In order to clear current selection
   aSelector->storeValue(); // Store values defined by user
+
   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
     (myWorkshop->module()->createOperation(myFeatureName));
   myWorkshop->processLaunchOperation(aFOperation);
@@ -113,6 +123,7 @@ ModuleBase_FilterItem::ModuleBase_FilterItem(const FilterPtr& theFilter, QWidget
   myRevBtn->setChecked(false);
   myRevBtn->setAutoRaise(true);
   myRevBtn->setIcon(QIcon(":pictures/accept.png"));
+  myRevBtn->setToolTip(tr("Reverse the filter"));
   connect(myRevBtn, SIGNAL(toggled(bool)), SLOT(onReverse(bool)));
   aLayout->addWidget(myRevBtn);
 
@@ -121,13 +132,17 @@ ModuleBase_FilterItem::ModuleBase_FilterItem(const FilterPtr& theFilter, QWidget
   QToolButton* aDelBtn = new QToolButton(this);
   aDelBtn->setIcon(QIcon(":pictures/button_cancel.png"));
   aDelBtn->setAutoRaise(true);
+  aDelBtn->setToolTip(tr("Delete the filter"));
   connect(aDelBtn, SIGNAL(clicked(bool)), SLOT(onDelete()));
   aLayout->addWidget(aDelBtn);
+
+  myRevBtn->setChecked(myFilter->isReversed());
 }
 
 
 void ModuleBase_FilterItem::onReverse(bool theCheck)
 {
+  myFilter->setReversed(theCheck);
   if (theCheck)
     myRevBtn->setIcon(QIcon(":pictures/stop.png"));
   else
@@ -148,6 +163,8 @@ ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theP
   : ModuleBase_ModelWidget(theParent, theData),
   myWorkshop(theWorkshop), mySelectionType(SelectionType)
 {
+  myOwners = new SelectMgr_IndexedMapOfOwner();
+
   QVBoxLayout* aMainLayout = new QVBoxLayout(this);
   ModuleBase_Tools::adjustMargins(aMainLayout);
 
@@ -176,7 +193,7 @@ ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theP
   QToolButton* aAddBtn = new QToolButton(aFiltersWgt);
   aAddBtn->setIcon(QIcon(":pictures/add.png"));
   aAddBtn->setAutoRaise(true);
-  aAddBtn->setToolTip(tr("Add current filter"));
+  aAddBtn->setToolTip(tr("Add the current filter"));
   connect(aAddBtn, SIGNAL(clicked()), SLOT(onAddItem()));
 
   aFiltersLay->addWidget(aFilterLbl);
@@ -187,21 +204,70 @@ ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theP
 
   aMainLayout->addWidget(myFiltersGroup);
 
+  // Select Button
   QWidget* aBtnWgt = new QWidget(this);
   QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnWgt);
   ModuleBase_Tools::adjustMargins(aBtnLayout);
 
   aBtnLayout->addStretch(1);
 
-  QPushButton* aSelectBtn = new QPushButton(tr("Select"), aBtnWgt);
-  connect(aSelectBtn, SIGNAL(clicked()), SLOT(onSelect()));
-  aBtnLayout->addWidget(aSelectBtn);
+  mySelectBtn = new QPushButton(tr("Select"), aBtnWgt);
+  connect(mySelectBtn, SIGNAL(clicked()), SLOT(onSelect()));
+  aBtnLayout->addWidget(mySelectBtn);
 
   aMainLayout->addWidget(aBtnWgt);
 
+  // Label widgets
+  QWidget* aLblWgt = new QWidget(this);
+  QHBoxLayout* aLblLayout = new QHBoxLayout(aLblWgt);
+  ModuleBase_Tools::adjustMargins(aLblLayout);
+
+  aLblLayout->addWidget(new QLabel(tr("Number of selected objects:"), aLblWgt));
+
+  myNbLbl = new QLabel("0", aLblWgt);
+  aLblLayout->addWidget(myNbLbl);
+
+  aMainLayout->addWidget(aLblWgt);
+
+  // Show only button
+  QWidget* aBtn2Wgt = new QWidget(this);
+  QHBoxLayout* aBtn2Layout = new QHBoxLayout(aBtn2Wgt);
+  ModuleBase_Tools::adjustMargins(aBtn2Layout);
+
+  aBtn2Layout->addStretch(1);
+
+  myShowBtn = new QPushButton(tr("Show only"), aBtn2Wgt);
+  myShowBtn->setCheckable(true);
+  connect(myShowBtn, SIGNAL(toggled(bool)), SLOT(onShowOnly(bool)));
+  aBtn2Layout->addWidget(myShowBtn);
+
+  aMainLayout->addWidget(aBtn2Wgt);
+
   aMainLayout->addStretch(1);
+
+  updateSelectBtn();
 }
 
+ModuleBase_WidgetSelectionFilter::~ModuleBase_WidgetSelectionFilter()
+{
+  myOwners.Nullify();
+  if ((!myPreview.IsNull()) && myShowBtn->isChecked()) {
+    Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext();
+    aCtx->Remove(myPreview, false);
+    myPreview.Nullify();
+    AIS_ListOfInteractive::const_iterator aIt;
+    Handle(AIS_Shape) aShapeIO;
+    for (aIt = myListIO.cbegin(); aIt != myListIO.cend(); aIt++) {
+      aShapeIO = Handle(AIS_Shape)::DownCast(*aIt);
+      if (!aShapeIO.IsNull()) {
+        aCtx->Display(aShapeIO, false);
+      }
+    }
+    aCtx->UpdateCurrentViewer();
+  }
+}
+
+
 void ModuleBase_WidgetSelectionFilter::onAddItem()
 {
   int aId = myFiltersCombo->currentIndex();
@@ -224,6 +290,9 @@ void ModuleBase_WidgetSelectionFilter::onAddItem()
       SLOT(onDeleteItem(ModuleBase_FilterItem*)));
     myGroupLayout->addWidget(aItem);
   }
+  updateSelectBtn();
+  clearCurrentSelection(true);
+  updateNumberSelected();
 }
 
 void ModuleBase_WidgetSelectionFilter::onDeleteItem(ModuleBase_FilterItem* theItem)
@@ -235,14 +304,135 @@ void ModuleBase_WidgetSelectionFilter::onDeleteItem(ModuleBase_FilterItem* theIt
   myUseFilters.remove(aFilter);
   myFilters.push_back(aFilter);
   myFiltersCombo->addItem(aFilter->name().c_str());
+
+  updateSelectBtn();
+  clearCurrentSelection(true);
+  updateNumberSelected();
 }
 
 void ModuleBase_WidgetSelectionFilter::onSelect()
 {
+  if (myUseFilters.size() == 0)
+    return;
+  Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext();
+  if (aCtx.IsNull())
+    return;
+
+  clearCurrentSelection();
+
+  BRep_Builder aBuilder;
+  TopoDS_Compound aComp;
+  aBuilder.MakeCompound(aComp);
+
+  if (!myShowBtn->isChecked()) {
+    aCtx->DisplayedObjects(AIS_KOI_Shape, -1, myListIO);
+    if (!myPreview.IsNull())
+      myListIO.Remove(myPreview);
+  }
+  AIS_ListOfInteractive::const_iterator aIt;
+  Handle(AIS_Shape) aShapeIO;
+  for (aIt = myListIO.cbegin(); aIt != myListIO.cend(); aIt++) {
+    aShapeIO = Handle(AIS_Shape)::DownCast(*aIt);
+    if (!aShapeIO.IsNull()) {
+      GeomShapePtr aShape(new GeomAPI_Shape);
+      aShape->setImpl(new TopoDS_Shape(aShapeIO->Shape()));
+      std::list<GeomShapePtr> aSubShapes =
+        aShape->subShapes((GeomAPI_Shape::ShapeType)mySelectionType);
+      std::list<GeomShapePtr>::const_iterator aShapesIt;
+      for (aShapesIt = aSubShapes.cbegin(); aShapesIt != aSubShapes.cend(); aShapesIt++) {
+        GeomShapePtr aShape = (*aShapesIt);
+        bool isValid = true;
+        std::list<FilterPtr>::const_iterator aFilterIt;
+        for (aFilterIt = myUseFilters.cbegin(); aFilterIt != myUseFilters.cend(); aFilterIt++) {
+          if (!(*aFilterIt)->isValid(aShape)) {
+            isValid = false;
+            break;
+          }
+        }
+        if (isValid) {
+          TopoDS_Shape aTShape = aShape->impl<TopoDS_Shape>();
+          Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(aTShape, aShapeIO, true);
+          myOwners->Add(aOwner);
+          aBuilder.Add(aComp, aTShape);
+        }
+      }
+    }
+  }
+  if (myOwners->Size() > 0)
+    updatePreview(aComp);
+  updateNumberSelected();
+}
+
+void ModuleBase_WidgetSelectionFilter::updatePreview(const TopoDS_Shape& theShape)
+{
+  Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext();
+  if (aCtx.IsNull())
+    return;
+
+  if (myPreview.IsNull()) {
+    myPreview = new AIS_Shape(theShape);
+    myPreview->SetDisplayMode(myShowBtn->isChecked()? AIS_Shaded : AIS_WireFrame);
+    myPreview->SetColor(Quantity_NOC_YELLOW);
+    myPreview->SetTransparency();
+    aCtx->Display(myPreview, true);
+    aCtx->Deactivate(myPreview);
+  }
+  else {
+    myPreview->Set(theShape);
+    aCtx->Redisplay(myPreview, true);
+  }
+}
+
+
+void ModuleBase_WidgetSelectionFilter::onShowOnly(bool theErase)
+{
+  if (myPreview.IsNull())
+    return;
+  Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext();
+
+  if (theErase) {
+    aCtx->SetDisplayMode(myPreview, AIS_Shaded, false);
+    myListIO.Clear();
+    aCtx->DisplayedObjects(AIS_KOI_Shape, -1, myListIO);
+    myListIO.Remove(myPreview);
+  }
+  else {
+    aCtx->SetDisplayMode(myPreview, AIS_WireFrame, false);
+  }
+  AIS_ListOfInteractive::const_iterator aIt;
+  Handle(AIS_Shape) aShapeIO;
+  for (aIt = myListIO.cbegin(); aIt != myListIO.cend(); aIt++) {
+    aShapeIO = Handle(AIS_Shape)::DownCast(*aIt);
+    if (!aShapeIO.IsNull()) {
+      if (theErase)
+        aCtx->Erase(aShapeIO, false);
+      else
+        aCtx->Display(aShapeIO, false);
+    }
+  }
+  aCtx->UpdateCurrentViewer();
+}
 
+void ModuleBase_WidgetSelectionFilter::updateSelectBtn()
+{
+  mySelectBtn->setEnabled(myUseFilters.size() > 0);
 }
 
+void ModuleBase_WidgetSelectionFilter::updateNumberSelected()
+{
+  myNbLbl->setText(QString::number(myOwners->Size()));
+}
 QList<QWidget*> ModuleBase_WidgetSelectionFilter::getControls() const
 {
   return QList<QWidget*>();
 }
+
+void ModuleBase_WidgetSelectionFilter::clearCurrentSelection(bool toUpdate)
+{
+  myOwners->Clear();
+  if (!myPreview.IsNull()) {
+    Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext();
+    aCtx->Remove(myPreview, toUpdate);
+    myPreview.Nullify();
+  }
+}
index 842f236a5db882af934ca62d8a0ca6ab6702e7bc..797af8a997bda836a87091ad6636d7bbf2820e39 100644 (file)
 #include "ModuleBase_ModelWidget.h"
 
 #include <ModelAPI_Filter.h>
+
+#include <SelectMgr_IndexedMapOfOwner.hxx>
+#include <AIS_Shape.hxx>
+#include <AIS_ListOfInteractive.hxx>
+
 #include <QWidget>
 
 class QLabel;
@@ -32,6 +37,7 @@ class QComboBox;
 class QGroupBox;
 class QToolButton;
 class QVBoxLayout;
+class QPushButton;
 
 class ModuleBase_IWorkshop;
 
@@ -86,6 +92,8 @@ public:
   ModuleBase_WidgetSelectionFilter(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop,
     const Config_WidgetAPI* theData);
 
+  ~ModuleBase_WidgetSelectionFilter();
+
   /// Returns list of widget controls
   /// \return a control list
   virtual QList<QWidget*> getControls() const;
@@ -102,6 +110,13 @@ private slots:
   void onAddItem();
   void onDeleteItem(ModuleBase_FilterItem* theItem);
   void onSelect();
+  void onShowOnly(bool theErase);
+
+private:
+  void updateSelectBtn();
+  void updateNumberSelected();
+  void clearCurrentSelection(bool toUpdate = false);
+  void updatePreview(const TopoDS_Shape& theShape);
 
 private:
   ModuleBase_IWorkshop* myWorkshop;
@@ -109,10 +124,18 @@ private:
   QComboBox* myFiltersCombo;
   QGroupBox* myFiltersGroup;
   QVBoxLayout* myGroupLayout;
+  QPushButton* mySelectBtn;
+  QLabel* myNbLbl;
+  QPushButton* myShowBtn;
 
   int mySelectionType;
   std::list<FilterPtr> myFilters;
   std::list<FilterPtr> myUseFilters;
+
+  Handle(SelectMgr_IndexedMapOfOwner) myOwners;
+  Handle(AIS_Shape) myPreview;
+
+  AIS_ListOfInteractive myListIO;
 };