From 8dae07f1480ad7af3fc847c46f9e7ceabd9091d0 Mon Sep 17 00:00:00 2001 From: vsv Date: Fri, 7 Nov 2014 15:14:02 +0300 Subject: [PATCH] Issue #236: Provide filtering of selected objects for extrusion --- src/FeaturesPlugin/extrusion_widget.xml | 1 + src/ModuleBase/ModuleBase_IViewer.h | 8 +++ src/ModuleBase/ModuleBase_ViewerFilters.cpp | 30 +++++++++++ src/ModuleBase/ModuleBase_ViewerFilters.h | 23 +++++++- .../ModuleBase_WidgetShapeSelector.cpp | 53 ++++++++++++++++--- .../ModuleBase_WidgetShapeSelector.h | 22 ++++++-- src/NewGeom/NewGeom_SalomeViewer.cpp | 29 +++++++++- src/NewGeom/NewGeom_SalomeViewer.h | 9 ++++ src/XGUI/XGUI_ViewerProxy.cpp | 27 ++++++++++ src/XGUI/XGUI_ViewerProxy.h | 9 ++++ 10 files changed, 199 insertions(+), 12 deletions(-) diff --git a/src/FeaturesPlugin/extrusion_widget.xml b/src/FeaturesPlugin/extrusion_widget.xml index c7c5f4bdd..da2d99d2d 100644 --- a/src/FeaturesPlugin/extrusion_widget.xml +++ b/src/FeaturesPlugin/extrusion_widget.xml @@ -5,6 +5,7 @@ tooltip="Select a face for extrusion" activate="true" shape_types="face" + object_types="construction" use_subshapes="true" /> diff --git a/src/ModuleBase/ModuleBase_IViewer.h b/src/ModuleBase/ModuleBase_IViewer.h index 6858fbefc..3e573d223 100644 --- a/src/ModuleBase/ModuleBase_IViewer.h +++ b/src/ModuleBase/ModuleBase_IViewer.h @@ -53,6 +53,14 @@ Q_OBJECT /// \param theZ the Z projection value virtual void setViewProjection(double theX, double theY, double theZ) = 0; + /// Add selection filter to the viewer + virtual void addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) = 0; + + /// Remove selection filter from the viewer + virtual void removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) = 0; + + /// Remove all selection filters from the viewer + virtual void clearSelectionFilters() = 0; signals: void lastViewClosed(); diff --git a/src/ModuleBase/ModuleBase_ViewerFilters.cpp b/src/ModuleBase/ModuleBase_ViewerFilters.cpp index b10437101..c18fd0eae 100644 --- a/src/ModuleBase/ModuleBase_ViewerFilters.cpp +++ b/src/ModuleBase/ModuleBase_ViewerFilters.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -81,3 +82,32 @@ Standard_Boolean ModuleBase_ShapeInPlaneFilter::IsOk(const Handle(SelectMgr_Enti } return Standard_False; } + + +IMPLEMENT_STANDARD_HANDLE(ModuleBase_ObjectTypesFilter, SelectMgr_Filter); +IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ObjectTypesFilter, SelectMgr_Filter); + + +//TODO (VSV): Check bug in OCCT: Filter result is ignored (bug25340) +Standard_Boolean ModuleBase_ObjectTypesFilter::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const +{ + Standard_Boolean isOk = ModuleBase_ShapeDocumentFilter::IsOk(theOwner); + if (isOk && theOwner->HasSelectable()) { + Handle(AIS_InteractiveObject) aAisObj = + Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable()); + if (!aAisObj.IsNull()) { + boost::shared_ptr aAISObj = AISObjectPtr(new GeomAPI_AISObject()); + aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aAisObj)); + ObjectPtr aObj = myWorkshop->findPresentedObject(aAISObj); + + foreach (QString aType, myTypes) { + if (aType.toLower() == "construction") { + ResultConstructionPtr aConstr = + boost::dynamic_pointer_cast(aObj); + return (aConstr != NULL); + } // ToDo: Process other types of objects + } + } + } + return Standard_False; +} diff --git a/src/ModuleBase/ModuleBase_ViewerFilters.h b/src/ModuleBase/ModuleBase_ViewerFilters.h index d26d3db3e..e4aa93ae2 100644 --- a/src/ModuleBase/ModuleBase_ViewerFilters.h +++ b/src/ModuleBase/ModuleBase_ViewerFilters.h @@ -6,6 +6,8 @@ #ifndef ModuleBase_ViewerFilters_H #define ModuleBase_ViewerFilters_H +#include + #include #include #include @@ -30,7 +32,7 @@ public: DEFINE_STANDARD_RTTI(ModuleBase_ShapeDocumentFilter) -private: +protected: ModuleBase_IWorkshop* myWorkshop; }; @@ -52,4 +54,23 @@ private: gp_Pln myPlane; }; + +/** +* A filter which provides filtering of selection in 3d viewer. +* Installing of this filter lets to select only object of requested type +*/ +DEFINE_STANDARD_HANDLE(ModuleBase_ObjectTypesFilter, SelectMgr_Filter); +class ModuleBase_ObjectTypesFilter: public ModuleBase_ShapeDocumentFilter +{ +public: + Standard_EXPORT ModuleBase_ObjectTypesFilter(ModuleBase_IWorkshop* theWorkshop, const QStringList& theTypes): + ModuleBase_ShapeDocumentFilter(theWorkshop), myTypes(theTypes) {} + + Standard_EXPORT virtual Standard_Boolean IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const; + + DEFINE_STANDARD_RTTI(ModuleBase_ObjectTypesFilter) +private: + QStringList myTypes; +}; + #endif \ No newline at end of file diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp index 4a53eb043..caf3e0b4d 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp @@ -6,8 +6,10 @@ #include #include #include +#include #include #include + #include #include #include @@ -19,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +111,9 @@ ModuleBase_WidgetShapeSelector::ModuleBase_WidgetShapeSelector(QWidget* theParen std::string aTypes = theData->getProperty("shape_types"); myShapeTypes = QString(aTypes.c_str()).split(' '); + std::string aObjTypes = theData->getProperty("object_types"); + myObjectTypes = QString(aObjTypes.c_str()).split(' '); + myUseSubShapes = theData->getBooleanAttribute("use_subshapes", false); } @@ -213,6 +219,10 @@ void ModuleBase_WidgetShapeSelector::onSelectionChanged() if (!aShape) return; + /// Check that object has acceptable type + if (!acceptObjectType(aObject)) + return; + // Get sub-shapes from local selection if (myUseSubShapes) { NCollection_List aShapeList; @@ -226,10 +236,10 @@ void ModuleBase_WidgetShapeSelector::onSelectionChanged() // Check that the selection corresponds to selection type if (myUseSubShapes) { - if (!isAccepted(aShape)) + if (!acceptSubShape(aShape)) return; } else { - if (!isAccepted(aObject)) + if (!acceptObjectShape(aObject)) return; } setObject(aObject, aShape); @@ -256,7 +266,7 @@ void ModuleBase_WidgetShapeSelector::setObject(ObjectPtr theObj, boost::shared_p } //******************************************************************** -bool ModuleBase_WidgetShapeSelector::isAccepted(const ObjectPtr theResult) const +bool ModuleBase_WidgetShapeSelector::acceptObjectShape(const ObjectPtr theResult) const { ResultPtr aResult = boost::dynamic_pointer_cast(theResult); @@ -285,7 +295,7 @@ bool ModuleBase_WidgetShapeSelector::isAccepted(const ObjectPtr theResult) const } //******************************************************************** -bool ModuleBase_WidgetShapeSelector::isAccepted(boost::shared_ptr theShape) const +bool ModuleBase_WidgetShapeSelector::acceptSubShape(boost::shared_ptr theShape) const { TopoDS_Shape aShape = theShape->impl(); foreach (QString aType, myShapeTypes) { @@ -295,6 +305,26 @@ bool ModuleBase_WidgetShapeSelector::isAccepted(boost::shared_ptr return false; } +//******************************************************************** +bool ModuleBase_WidgetShapeSelector::acceptObjectType(const ObjectPtr theObject) const +{ + // Definition of types is not obligatory. If types are not defined then + // it means that accepted any type + if (myObjectTypes.isEmpty()) + return true; + + foreach (QString aType, myObjectTypes) { + if (aType.toLower() == "construction") { + ResultConstructionPtr aConstr = + boost::dynamic_pointer_cast(theObject); + return (aConstr != NULL); + } // ToDo: Process other types of objects + } + // Object type is defined but not found + return false; +} + + //******************************************************************** void ModuleBase_WidgetShapeSelector::updateSelectionName() { @@ -331,15 +361,26 @@ void ModuleBase_WidgetShapeSelector::activateSelection(bool toActivate) if (myIsActive) { connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); if (myUseSubShapes) { + QIntList aList; foreach (QString aType, myShapeTypes) aList.append(shapeType(aType)); myWorkshop->activateSubShapesSelection(aList); + if (!myObjectTypes.isEmpty()) { + myObjTypeFilter = new ModuleBase_ObjectTypesFilter(myWorkshop, myObjectTypes); + myWorkshop->viewer()->clearSelectionFilters(); + myWorkshop->viewer()->addSelectionFilter(myObjTypeFilter); + } } } else { disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - if (myUseSubShapes) + if (myUseSubShapes) { + if (!myObjTypeFilter.IsNull()) { + myWorkshop->viewer()->removeSelectionFilter(myObjTypeFilter); + myObjTypeFilter.Nullify(); + } myWorkshop->deactivateSubShapesSelection(); + } } } @@ -385,7 +426,7 @@ bool ModuleBase_WidgetShapeSelector::setValue(ModuleBase_WidgetValue* theValue) dynamic_cast(theValue); if (aFeatureValue && aFeatureValue->object()) { ObjectPtr aObject = aFeatureValue->object(); - if (isAccepted(aObject)) { + if (acceptObjectShape(aObject)) { setObject(aObject); return true; } diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.h b/src/ModuleBase/ModuleBase_WidgetShapeSelector.h index 7d0a453f6..9396c21e6 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.h @@ -7,6 +7,7 @@ #include "ModuleBase.h" #include "ModuleBase_ModelWidget.h" +#include "ModuleBase_ViewerFilters.h" #include #include @@ -74,19 +75,29 @@ private slots: protected: bool eventFilter(QObject* theObj, QEvent* theEvent); -private: void updateSelectionName(); void raisePanel() const; - bool isAccepted(const ObjectPtr theObject) const; - bool isAccepted(boost::shared_ptr theShape) const; + + /// Returns true if Sape of given object corresponds to requested shape type + /// This method is called only in non sub-shapes selection mode + virtual bool acceptObjectShape(const ObjectPtr theObject) const; + + /// Returns true if selected shape corresponds to requested shape types + /// This method is called only in sub-shapes selection mode + virtual bool acceptSubShape(boost::shared_ptr theShape) const; + + /// Returns true if selected object corresponds to requested Object type + /// Thid method is used in any selection mode + virtual bool acceptObjectType(const ObjectPtr theObject) const; + // Set the given object as a value of the widget void setObject(ObjectPtr theObj, boost::shared_ptr theShape = boost::shared_ptr()); + //----------- Class members ------------- QWidget* myContainer; QLabel* myLabel; QLineEdit* myTextLine; - //QToolButton* myActivateBtn; ModuleBase_IWorkshop* myWorkshop; @@ -94,6 +105,7 @@ private: boost::shared_ptr myShape; QStringList myShapeTypes; + QStringList myObjectTypes; /// If true then local selector has to be activated in context bool myUseSubShapes; @@ -102,6 +114,8 @@ private: QPalette myInactivePalet; bool myIsActive; + + Handle(ModuleBase_ObjectTypesFilter) myObjTypeFilter; }; #endif diff --git a/src/NewGeom/NewGeom_SalomeViewer.cpp b/src/NewGeom/NewGeom_SalomeViewer.cpp index fe9cd2310..419c5d0b8 100644 --- a/src/NewGeom/NewGeom_SalomeViewer.cpp +++ b/src/NewGeom/NewGeom_SalomeViewer.cpp @@ -174,4 +174,31 @@ void NewGeom_SalomeViewer::setViewProjection(double theX, double theY, double th aView3d->SetZSize(0.); } } -} \ No newline at end of file +} + +//*************************************** +void NewGeom_SalomeViewer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + aContext->AddFilter(theFilter); + } +} + +//*************************************** +void NewGeom_SalomeViewer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + aContext->RemoveFilter(theFilter); + } +} + +//*************************************** +void NewGeom_SalomeViewer::clearSelectionFilters() +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + aContext->RemoveFilters(); + } +} diff --git a/src/NewGeom/NewGeom_SalomeViewer.h b/src/NewGeom/NewGeom_SalomeViewer.h index 29bdd5218..5148dcc6d 100644 --- a/src/NewGeom/NewGeom_SalomeViewer.h +++ b/src/NewGeom/NewGeom_SalomeViewer.h @@ -50,6 +50,15 @@ Q_OBJECT void setSelector(NewGeom_OCCSelector* theSel); + /// Add selection filter to the viewer + virtual void addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter); + + /// Remove selection filter from the viewer + virtual void removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter); + + /// Remove all selection filters from the viewer + virtual void clearSelectionFilters(); + NewGeom_OCCSelector* selector() const { return mySelector; diff --git a/src/XGUI/XGUI_ViewerProxy.cpp b/src/XGUI/XGUI_ViewerProxy.cpp index fee0419dd..782023d87 100644 --- a/src/XGUI/XGUI_ViewerProxy.cpp +++ b/src/XGUI/XGUI_ViewerProxy.cpp @@ -187,3 +187,30 @@ bool XGUI_ViewerProxy::isMultiSelectionEnabled() const return myWorkshop->mainWindow()->viewer()->isMultiSelectionEnabled(); } } + +//*************************************** +void XGUI_ViewerProxy::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + aContext->AddFilter(theFilter); + } +} + +//*************************************** +void XGUI_ViewerProxy::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + aContext->RemoveFilter(theFilter); + } +} + +//*************************************** +void XGUI_ViewerProxy::clearSelectionFilters() +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (!aContext.IsNull()) { + aContext->RemoveFilters(); + } +} diff --git a/src/XGUI/XGUI_ViewerProxy.h b/src/XGUI/XGUI_ViewerProxy.h index 9c39bdf20..caca6ec42 100644 --- a/src/XGUI/XGUI_ViewerProxy.h +++ b/src/XGUI/XGUI_ViewerProxy.h @@ -52,6 +52,15 @@ Q_OBJECT /// Connects to a viewer according to current environment void connectToViewer(); + /// Add selection filter to the viewer + virtual void addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter); + + /// Remove selection filter from the viewer + virtual void removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter); + + /// Remove all selection filters from the viewer + virtual void clearSelectionFilters(); + private slots: void onMousePress(XGUI_ViewWindow*, QMouseEvent*); void onMouseRelease(XGUI_ViewWindow*, QMouseEvent*); -- 2.39.2