From 961801cbc09aebaee83b57af754265f146b383f1 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 31 Jan 2017 17:31:06 +0300 Subject: [PATCH] Issue #1897 Selection of edges in Group feature with SHIFT Key --- src/GeomAPI/GeomAPI_Shape.cpp | 12 ++++ src/GeomAPI/GeomAPI_Shape.h | 4 ++ src/Model/Model_AttributeSelectionList.cpp | 8 ++- .../ModuleBase_WidgetMultiSelector.cpp | 17 +++++- .../ModuleBase_WidgetMultiSelector.h | 3 + src/XGUI/XGUI_Displayer.cpp | 55 ++++++++++++------- src/XGUI/XGUI_Selection.cpp | 18 ------ src/XGUI/XGUI_SelectionMgr.cpp | 2 +- 8 files changed, 77 insertions(+), 42 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index 9d3694bf1..6c0c7f27a 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -61,6 +61,18 @@ bool GeomAPI_Shape::isEqual(const std::shared_ptr theShape) const return MY_SHAPE->IsEqual(theShape->impl()) == Standard_True; } +bool GeomAPI_Shape::isSame(const std::shared_ptr theShape) const +{ + if (!theShape.get()) + return false; + if (isNull()) + return theShape->isNull(); + if (theShape->isNull()) + return false; + + return MY_SHAPE->IsSame(theShape->impl()) == Standard_True; +} + bool GeomAPI_Shape::isVertex() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index ccb1153d3..093779c7b 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -50,6 +50,10 @@ public: GEOMAPI_EXPORT virtual bool isEqual(const std::shared_ptr theShape) const; + /// Returns whether the shapes are same + GEOMAPI_EXPORT + virtual bool isSame(const std::shared_ptr theShape) const; + /// Returns whether the shape is a vertex GEOMAPI_EXPORT virtual bool isVertex() const; diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index 29f23b24e..16e5d73de 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -217,14 +217,15 @@ bool Model_AttributeSelectionList::isInList(const ResultPtr& theContext, std::map > >::iterator aContext = myCash.find(theContext); if (aContext != myCash.end()) { - // iterate shapes because "isEqual" method must be called for each shape + // iterate shapes because "isSame" method must be called for each shape std::list >::iterator aShapes = aContext->second.begin(); for(; aShapes != aContext->second.end(); aShapes++) { if (!theSubShape.get()) { if (!aShapes->get()) return true; } else { - if (theSubShape->isEqual(*aShapes)) + // we need to call here isSame instead of isEqual to do not check shapes orientation + if (theSubShape->isSame(*aShapes)) return true; } } @@ -242,7 +243,8 @@ bool Model_AttributeSelectionList::isInList(const ResultPtr& theContext, return true; } } else { - if (aValue->isEqual(theSubShape)) // shapes are equal + // we need to call here isSame instead of isEqual to do not check shapes orientation + if (aValue->isSame(theSubShape)) // shapes are equal return true; } } diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index fe5e99ecc..81bf3970f 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -91,7 +91,8 @@ protected: ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData) -: ModuleBase_WidgetSelector(theParent, theWorkshop, theData) +: ModuleBase_WidgetSelector(theParent, theWorkshop, theData), + myIsSetSelectionBlocked(false) { QGridLayout* aMainLay = new QGridLayout(this); ModuleBase_Tools::adjustMargins(aMainLay); @@ -225,6 +226,9 @@ bool ModuleBase_WidgetMultiSelector::restoreValueCustom() bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues, const bool theToValidate) { + if (myIsSetSelectionBlocked) + return false; + AttributeSelectionListPtr aSelectionListAttr; if (attribute()->attributeType() == ModelAPI_AttributeSelectionList::typeId()) aSelectionListAttr = std::dynamic_pointer_cast(attribute()); @@ -271,6 +275,17 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList //emit valuesChanged(); //} + // Restore selection in the viewer by the attribute selection list + // it is possible that diring selection attribute filling, selection in Object Browser + // is changed(some items were removed/added) and as result, selection in the viewer + // differs from the selection come to this method. By next rows, we restore selection + // in the viewer according to content of selection attribute. Case is Edge selection in Group + myIsSetSelectionBlocked = true; + static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION); + ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent); + Events_Loop::loop()->flush(anEvent); + myIsSetSelectionBlocked = false; + if (aSelectionListAttr.get()) aSelectionListAttr->cashValues(false); diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h index 1e61a581e..e7713928a 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h @@ -195,6 +195,9 @@ protected: /// A flag to clear selection by click in empty place in the viewer bool myIsNeutralPointClear; + + /// A flag to block set selection perform if the method is in process + bool myIsSetSelectionBlocked; }; #endif /* MODULEBASE_WIDGETFILESELECTOR_H_ */ diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index fc9b169df..506ae75d6 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -16,8 +16,7 @@ #endif #ifdef VINSPECTOR -#include -#include +#include #ifndef HAVE_SALOME #include #endif @@ -67,7 +66,7 @@ static bool VInspector_FirstCall = true; #include #ifdef VINSPECTOR -#include +#include #endif #include @@ -1047,14 +1046,19 @@ Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const #ifdef VINSPECTOR if (VInspector_FirstCall) { XGUI_Displayer* aDisplayer = (XGUI_Displayer*)this; - VInspectorAPI_Communicator* aCommunicator = VInspectorAPI_PluginMgr::activateVInspector( - "VInspector.dll", aContext); - aDisplayer->setCommunicator(aCommunicator); - #ifndef HAVE_SALOME - AppElements_Viewer* aViewer = myWorkshop->mainWindow()->viewer(); - if (aViewer) - aViewer->setCallBack(aCommunicator->getCallBack()); - #endif + + VInspectorAPI_Communicator* aCommunicator = + VInspectorAPI_Communicator::loadPluginLibrary("TKVInspector.dll"); + if (aCommunicator) { + aCommunicator->setContext(aContext); + + aDisplayer->setCommunicator(aCommunicator); + #ifndef HAVE_SALOME + AppElements_Viewer* aViewer = myWorkshop->mainWindow()->viewer(); + if (aViewer) + aViewer->setCallBack(aCommunicator->getCallBack()); + #endif + } VInspector_FirstCall = false; } #endif @@ -1578,14 +1582,27 @@ void XGUI_Displayer::AddOrRemoveSelectedShapes(Handle(AIS_InteractiveContext) th Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(anOwner); if (!BROwnr.IsNull() && BROwnr->HasShape()) { const TopoDS_Shape& aShape = BROwnr->Shape(); - if (!aShape.IsNull() && theShapesToBeSelected.IsBound(aShape)) { - Handle(AIS_InteractiveObject) anOwnerPresentation = - Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); - NCollection_Map aPresentations = - theShapesToBeSelected.Find(aShape); - if (aPresentations.Contains(anOwnerPresentation)) { - theContext->AddOrRemoveSelected(anOwner); - anOwner->SetSelected (Standard_True); + if (aShape.IsNull()) + continue; + + NCollection_DataMap >::Iterator aShapeIt(theShapesToBeSelected); + for (; aShapeIt.More(); aShapeIt.Next()) { + if (aShapeIt.Key().IsSame(aShape)) { + const TopoDS_Shape& aParameterShape = aShapeIt.Key(); + // isSame should be used here as it does not check orientation of shapes + // despite on isEqual of shapes or IsBound for shape in QMap + // orientation is different for Edges shapes in model and owner even if this is one shape + if (aParameterShape.IsSame(aShape)) { + Handle(AIS_InteractiveObject) anOwnerPresentation = + Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable()); + NCollection_Map aPresentations = + theShapesToBeSelected.Find(aParameterShape); + if (aPresentations.Contains(anOwnerPresentation)) { + theContext->AddOrRemoveSelected(anOwner); + anOwner->SetSelected (Standard_True); + } + } } } } diff --git a/src/XGUI/XGUI_Selection.cpp b/src/XGUI/XGUI_Selection.cpp index bccb7ddcf..5af4ea4c3 100644 --- a/src/XGUI/XGUI_Selection.cpp +++ b/src/XGUI/XGUI_Selection.cpp @@ -242,24 +242,6 @@ QList XGUI_Selection::getHighlighted() const fillPresentation(aPrs, anOwner); aPresentations.push_back(aPrs); } - else { // TODO: check why the entity owner is null here, case is selection point on a line - Handle(AIS_InteractiveObject) anIO = aContext->DetectedInteractive(); - ModuleBase_ViewerPrsPtr aPrs(new ModuleBase_ViewerPrs()); - aPrs->setInteractive(anIO); - - ObjectPtr aResult = aDisplayer->getObject(anIO); - // we should not check the appearance of this feature because there can be some selected - // shapes for one feature - aPrs->setObject(aResult); - TopoDS_Shape aShape = aContext->DetectedShape(); - if (!aShape.IsNull()) { - std::shared_ptr aGeomShape = - std::shared_ptr(new GeomAPI_Shape()); - aGeomShape->setImpl(new TopoDS_Shape(aShape)); - aPrs->setShape(aGeomShape); - } - aPresentations.push_back(aPrs); - } } return aPresentations; } diff --git a/src/XGUI/XGUI_SelectionMgr.cpp b/src/XGUI/XGUI_SelectionMgr.cpp index a442f465c..df975ca95 100755 --- a/src/XGUI/XGUI_SelectionMgr.cpp +++ b/src/XGUI/XGUI_SelectionMgr.cpp @@ -27,7 +27,7 @@ #include #ifdef VINSPECTOR -#include +#include #endif XGUI_SelectionMgr::XGUI_SelectionMgr(XGUI_Workshop* theParent) -- 2.39.2