From 457214a36e82dde329881652d5516b49ad118fc9 Mon Sep 17 00:00:00 2001 From: vsv Date: Fri, 6 Jun 2014 17:16:27 +0400 Subject: [PATCH] Show/Hide operations and selection synchronization --- src/XGUI/CMakeLists.txt | 3 +- src/XGUI/XGUI_Displayer.cpp | 78 ++++++++++++++++++++++------- src/XGUI/XGUI_Displayer.h | 18 +++++-- src/XGUI/XGUI_DocumentDataModel.cpp | 44 ++++++++++++++-- src/XGUI/XGUI_DocumentDataModel.h | 4 ++ src/XGUI/XGUI_ObjectsBrowser.cpp | 17 ++++++- src/XGUI/XGUI_ObjectsBrowser.h | 2 + src/XGUI/XGUI_PartDataModel.cpp | 6 +-- src/XGUI/XGUI_PartDataModel.h | 2 + src/XGUI/XGUI_SalomeViewer.h | 1 + src/XGUI/XGUI_SelectionMgr.cpp | 21 ++++---- src/XGUI/XGUI_Tools.cpp | 15 +++++- src/XGUI/XGUI_Tools.h | 5 ++ src/XGUI/XGUI_ViewerProxy.cpp | 4 ++ src/XGUI/XGUI_Workshop.cpp | 12 ++++- 15 files changed, 186 insertions(+), 46 deletions(-) diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index 1775cb125..8c9244e52 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -115,7 +115,8 @@ INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/PyInterp ${PROJECT_SOURCE_DIR}/src/PyConsole ${PROJECT_SOURCE_DIR}/src/ModelAPI - ${PROJECT_SOURCE_DIR}/src/Model + ${PROJECT_SOURCE_DIR}/src/GeomAPI + ${PROJECT_SOURCE_DIR}/src/Model ${PROJECT_SOURCE_DIR}/src/ModuleBase ${PROJECT_SOURCE_DIR}/src/PartSetPlugin ${CAS_INCLUDE_DIRS}) diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 54f3728ed..fee4e4230 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -10,6 +10,9 @@ #include #include +#include + +#include #include #include @@ -34,26 +37,31 @@ XGUI_Displayer::~XGUI_Displayer() bool XGUI_Displayer::isVisible(FeaturePtr theFeature) { - return myFeature2AISObjectMap.find(theFeature) != myFeature2AISObjectMap.end(); + FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature); + return myFeature2AISObjectMap.find(aFeature) != myFeature2AISObjectMap.end(); } -//void XGUI_Displayer::Display(FeaturePtr theFeature, -// const bool isUpdateViewer) -//{ -//} +void XGUI_Displayer::display(FeaturePtr theFeature, bool isUpdateViewer) +{ + FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature); + boost::shared_ptr aShapePtr = aFeature->data()->shape(); + + if (aShapePtr) { + TopoDS_Shape aShape = aShapePtr->impl(); + display(aFeature, aShape, isUpdateViewer); + } +} -/*void XGUI_Displayer::Display(FeaturePtr theFeature, - const TopoDS_Shape& theShape, const bool isUpdateViewer) +void XGUI_Displayer::display(FeaturePtr theFeature, + const TopoDS_Shape& theShape, bool isUpdateViewer) { Handle(AIS_InteractiveContext) aContext = AISContext(); Handle(AIS_Shape) anAIS = new AIS_Shape(theShape); myFeature2AISObjectMap[theFeature] = anAIS; - aContext->Display(anAIS, Standard_False); - if (isUpdateViewer) - updateViewer(); -}*/ + aContext->Display(anAIS, isUpdateViewer); +} std::list XGUI_Displayer::getSelected(const int theShapeTypeToSkip) @@ -79,6 +87,21 @@ std::list XGUI_Displayer::getSelected(const int theShapeTypeToSk return aPresentations; } +QFeatureList XGUI_Displayer::selectedFeatures() const +{ + QFeatureList aSelectedList; + + Handle(AIS_InteractiveContext) aContext = AISContext(); + for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) { + Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive(); + FeaturePtr aFeature = getFeature(anIO); + if (aFeature) + aSelectedList.append(aFeature); + } + return aSelectedList; +} + + std::list XGUI_Displayer::getHighlighted(const int theShapeTypeToSkip) { std::set aPrsFeatures; @@ -104,22 +127,22 @@ std::list XGUI_Displayer::getHighlighted(const int theShapeTypeT void XGUI_Displayer::erase(FeaturePtr theFeature, const bool isUpdateViewer) { - if (myFeature2AISObjectMap.find(theFeature) == myFeature2AISObjectMap.end()) + FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature); + + if (myFeature2AISObjectMap.find(aFeature) == myFeature2AISObjectMap.end()) return; Handle(AIS_InteractiveContext) aContext = AISContext(); - Handle(AIS_InteractiveObject) anAIS = myFeature2AISObjectMap[theFeature]; + Handle(AIS_InteractiveObject) anAIS = myFeature2AISObjectMap[aFeature]; Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast(anAIS); if (!anAISShape.IsNull()) { - aContext->Erase(anAISShape); + aContext->Erase(anAISShape, isUpdateViewer); } - myFeature2AISObjectMap.erase(theFeature); - - if (isUpdateViewer) - updateViewer(); + myFeature2AISObjectMap.erase(aFeature); } + bool XGUI_Displayer::redisplay(FeaturePtr theFeature, Handle(AIS_InteractiveObject) theAIS, const int theSelectionMode, @@ -245,6 +268,25 @@ void XGUI_Displayer::setSelected(const std::list& theFeatures, c updateViewer(); } + +void XGUI_Displayer::setSelected(const QFeatureList& theFeatures, const bool isUpdateViewer) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + aContext->ClearSelected(); + foreach(FeaturePtr aFeature, theFeatures) { + FeaturePtr aRFeature = XGUI_Tools::realFeature(aFeature); + if (myFeature2AISObjectMap.find(aRFeature) == myFeature2AISObjectMap.end()) + return; + + Handle(AIS_InteractiveObject) anAIS = myFeature2AISObjectMap[aRFeature]; + if (!anAIS.IsNull()) + aContext->AddOrRemoveSelected(anAIS, false); + } + if (isUpdateViewer) + updateViewer(); +} + + /*void XGUI_Displayer::EraseAll(const bool isUpdateViewer) { Handle(AIS_InteractiveContext) ic = AISContext(); diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index b8389af5d..fdb8c7600 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -6,6 +6,7 @@ #define XGUI_Displayer_H #include "XGUI.h" +#include "XGUI_Constants.h" #include #include @@ -51,20 +52,24 @@ public: /// Display the feature. Obtain the visualized object from the feature. /// \param theFeature a feature instance /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly - //void Display(FeaturePtr theFeature, const bool isUpdateViewer = true); + void display(FeaturePtr theFeature, bool isUpdateViewer = true); /// Display the feature and a shape. This shape would be associated to the given feature /// \param theFeature a feature instance /// \param theShape a shape /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly - //void Display(FeaturePtr theFeature, const TopoDS_Shape& theShape, - // const bool isUpdateViewer = true); + void display(FeaturePtr theFeature, const TopoDS_Shape& theShape, bool isUpdateViewer = true); /// Returns a list of viewer selected presentations /// \param theShapeTypeToSkip the shapes with this type will be skipped during the result list build /// \return list of presentations std::list getSelected(const int theShapeTypeToSkip = -1); + /** + * Returns list of features currently selected in 3d viewer + */ + QFeatureList selectedFeatures() const; + /// Returns a list of viewer highlited presentations /// \param theShapeTypeToSkip the shapes with this type will be skipped during the result list build /// \return list of presentations @@ -104,6 +109,13 @@ public: /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly void setSelected(const std::list& theFeatures, const bool isUpdateViewer); + /** + * Add presentations which corresponds to the given features to current selection + * \param theFeatures a list of features to be selected + * isUpdateViewer the parameter whether the viewer should be update immediatelly + */ + void setSelected(const QFeatureList& theFeatures, bool isUpdateViewer = true); + /// Erase the feature and a shape. /// \param theFeature a feature instance /// \param isUpdateViewer the parameter whether the viewer should be update immediatelly diff --git a/src/XGUI/XGUI_DocumentDataModel.cpp b/src/XGUI/XGUI_DocumentDataModel.cpp index 7c2529bd5..09d530bab 100644 --- a/src/XGUI/XGUI_DocumentDataModel.cpp +++ b/src/XGUI/XGUI_DocumentDataModel.cpp @@ -501,11 +501,8 @@ Qt::ItemFlags XGUI_DocumentDataModel::flags(const QModelIndex& theIndex) const QModelIndex XGUI_DocumentDataModel::partIndex(const FeaturePtr& theFeature) const { - FeaturePtr aFeature = theFeature; - if (XGUI_Tools::isModelObject(aFeature)) { - ObjectPtr aObject = boost::dynamic_pointer_cast(aFeature); - aFeature = aObject->featureRef(); - } + FeaturePtr aFeature = XGUI_Tools::realFeature(theFeature); + int aRow = -1; XGUI_PartModel* aModel = 0; foreach (XGUI_PartModel* aPartModel, myPartModels) { @@ -520,3 +517,40 @@ QModelIndex XGUI_DocumentDataModel::partIndex(const FeaturePtr& theFeature) cons } return QModelIndex(); } + +QModelIndex XGUI_DocumentDataModel::featureIndex(const FeaturePtr theFeature) const +{ + // Check that this feature belongs to root document + DocumentPtr aRootDoc = ModelAPI_PluginManager::get()->rootDocument(); + DocumentPtr aDoc = theFeature->document(); + if (aDoc == aRootDoc) { + // This feature belongs to histrory or top model + if (theFeature->isInHistory()) { + int aId; + for (aId = 0; aId < aRootDoc->size(FEATURES_GROUP); aId++) { + if (theFeature == aRootDoc->feature(FEATURES_GROUP, aId)) + break; + } + return index(aId + historyOffset(), 0, QModelIndex()); + } else { + QModelIndex aIndex = myModel->featureIndex(theFeature); + return aIndex.isValid()? + createIndex(aIndex.row(), aIndex.column(), (void*)getModelIndex(aIndex)) : + QModelIndex(); + } + } else { + XGUI_PartModel* aPartModel = 0; + foreach(XGUI_PartModel* aModel, myPartModels) { + if (aModel->hasDocument(aDoc)) { + aPartModel = aModel; + break; + } + } + if (aPartModel) { + QModelIndex aIndex = aPartModel->featureIndex(theFeature); + return aIndex.isValid()? + createIndex(aIndex.row(), aIndex.column(), (void*)getModelIndex(aIndex)) : + QModelIndex(); + } + } +} \ No newline at end of file diff --git a/src/XGUI/XGUI_DocumentDataModel.h b/src/XGUI/XGUI_DocumentDataModel.h index 6683db4c9..a5257a981 100644 --- a/src/XGUI/XGUI_DocumentDataModel.h +++ b/src/XGUI/XGUI_DocumentDataModel.h @@ -56,6 +56,8 @@ public: //! Returns 0 if the given index is not index of a feature FeaturePtr feature(const QModelIndex& theIndex) const; + QModelIndex featureIndex(const FeaturePtr theFeature) const; + //! Returns QModelIndex which corresponds to the given feature if this is a part //! If the feature is not found then index is not valid QModelIndex partIndex(const FeaturePtr& theFeature) const; @@ -64,8 +66,10 @@ public: //! Returns true if active part changed. bool activatedIndex(const QModelIndex& theIndex); + //! Retrurns Feature which corresponds to active part FeaturePtr activePart() const; + //! Retrurns QModelIndex of active part QModelIndex activePartIndex() const { return myActivePartIndex; } //! Deactivates a Part diff --git a/src/XGUI/XGUI_ObjectsBrowser.cpp b/src/XGUI/XGUI_ObjectsBrowser.cpp index f77f005e8..27b927562 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.cpp +++ b/src/XGUI/XGUI_ObjectsBrowser.cpp @@ -329,4 +329,19 @@ void XGUI_ObjectsBrowser::rebuildDataTree() { myDocModel->rebuildDataTree(); update(); -} \ No newline at end of file +} + +//*************************************************** +void XGUI_ObjectsBrowser::setFeaturesSelected(const QFeatureList& theFeatures) +{ + QList theIndexes; + QItemSelectionModel* aSelectModel = myTreeView->selectionModel(); + aSelectModel->clear(); + + foreach(FeaturePtr aFeature, theFeatures) { + QModelIndex aIndex = myDocModel->featureIndex(aFeature); + if (aIndex.isValid()) { + aSelectModel->select(aIndex, QItemSelectionModel::Select); + } + } +} diff --git a/src/XGUI/XGUI_ObjectsBrowser.h b/src/XGUI/XGUI_ObjectsBrowser.h index f9ae1fed3..70c13d11c 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.h +++ b/src/XGUI/XGUI_ObjectsBrowser.h @@ -66,6 +66,8 @@ public: //! Returns list of currently selected features QFeatureList selectedFeatures() const { return myFeaturesList; } + void setFeaturesSelected(const QFeatureList& theFeatures); + //! Returns currently selected indexes QModelIndexList selectedIndexes() const { return myTreeView->selectionModel()->selectedIndexes(); } diff --git a/src/XGUI/XGUI_PartDataModel.cpp b/src/XGUI/XGUI_PartDataModel.cpp index ea8c1a51a..7ce708e65 100644 --- a/src/XGUI/XGUI_PartDataModel.cpp +++ b/src/XGUI/XGUI_PartDataModel.cpp @@ -445,11 +445,11 @@ QModelIndex XGUI_PartDataModel::featureIndex(const FeaturePtr& theFeature) const return aIndex; std::string aGroup = theFeature->getGroup(); - DocumentPtr aRootDoc = ModelAPI_PluginManager::get()->rootDocument(); - int aNb = aRootDoc->size(aGroup); + DocumentPtr aDoc = theFeature->document(); + int aNb = aDoc->size(aGroup); int aRow = -1; for (int i = 0; i < aNb; i++) { - if (aRootDoc->feature(aGroup, i) == theFeature) { + if (aDoc->feature(aGroup, i) == theFeature) { aRow = i; break; } diff --git a/src/XGUI/XGUI_PartDataModel.h b/src/XGUI/XGUI_PartDataModel.h index 8d43fe46e..fabadeb8b 100644 --- a/src/XGUI/XGUI_PartDataModel.h +++ b/src/XGUI/XGUI_PartDataModel.h @@ -106,6 +106,8 @@ public: virtual FeaturePtr part() const; private: + + //! Returns document of the current part DocumentPtr featureDocument() const; //! Types of QModelIndexes diff --git a/src/XGUI/XGUI_SalomeViewer.h b/src/XGUI/XGUI_SalomeViewer.h index b00d5aea3..a07008bfc 100644 --- a/src/XGUI/XGUI_SalomeViewer.h +++ b/src/XGUI/XGUI_SalomeViewer.h @@ -57,6 +57,7 @@ signals: void keyRelease(QKeyEvent* theEvent); void activated(); + void selectionChanged(); }; #endif \ No newline at end of file diff --git a/src/XGUI/XGUI_SelectionMgr.cpp b/src/XGUI/XGUI_SelectionMgr.cpp index f949c782a..9f830a74e 100644 --- a/src/XGUI/XGUI_SelectionMgr.cpp +++ b/src/XGUI/XGUI_SelectionMgr.cpp @@ -1,10 +1,11 @@ #include "XGUI_SelectionMgr.h" + #include "XGUI_Workshop.h" #include "XGUI_MainWindow.h" #include "XGUI_ObjectsBrowser.h" -#include "XGUI_Viewer.h" #include "XGUI_SalomeConnector.h" #include "XGUI_ViewerProxy.h" +#include "XGUI_Displayer.h" #include #include @@ -29,20 +30,16 @@ void XGUI_SelectionMgr::connectViewers() this, SLOT(onObjectBrowserSelection())); //Connect to other viewers - if (myWorkshop->isSalomeMode()) { - connect(myWorkshop, SIGNAL(salomeViewerSelection()), - this, SLOT(onViewerSelection())); - } else { - connect(myWorkshop->mainWindow()->viewer(), SIGNAL(selectionChanged()), - this, SLOT(onViewerSelection())); - } + connect(myWorkshop->viewer(), SIGNAL(selectionChanged()), + this, SLOT(onViewerSelection())); } //************************************************************** void XGUI_SelectionMgr::onObjectBrowserSelection() { - - // TODO: Highliht selected objects in Viewer 3d + QFeatureList aFeatures = selectedFeatures(); + XGUI_Displayer* aDisplayer = myWorkshop->displayer(); + aDisplayer->setSelected(aFeatures); emit selectionChanged(); } @@ -50,7 +47,9 @@ void XGUI_SelectionMgr::onObjectBrowserSelection() //************************************************************** void XGUI_SelectionMgr::onViewerSelection() { - // TODO: Highliht selected objects in Object Browser + XGUI_Displayer* aDisplayer = myWorkshop->displayer(); + QFeatureList aFeatures = aDisplayer->selectedFeatures(); + myWorkshop->objectBrowser()->setFeaturesSelected(aFeatures); emit selectionChanged(); } diff --git a/src/XGUI/XGUI_Tools.cpp b/src/XGUI/XGUI_Tools.cpp index 3148bc274..5cf560636 100644 --- a/src/XGUI/XGUI_Tools.cpp +++ b/src/XGUI/XGUI_Tools.cpp @@ -1,7 +1,7 @@ #include "XGUI_Tools.h" #include -#include +#include #include @@ -70,4 +70,15 @@ std::string featureInfo(FeaturePtr theFeature) return QString(aStream.str().c_str()).toStdString(); } -} \ No newline at end of file +//****************************************************************** +FeaturePtr realFeature(const FeaturePtr theFeature) +{ + if (theFeature->data()) { + return theFeature; + } else { + ObjectPtr aObject = boost::dynamic_pointer_cast(theFeature); + return aObject->featureRef(); + } +} + +} diff --git a/src/XGUI/XGUI_Tools.h b/src/XGUI/XGUI_Tools.h index f2f2b9d88..fa1c78af5 100644 --- a/src/XGUI/XGUI_Tools.h +++ b/src/XGUI/XGUI_Tools.h @@ -72,6 +72,11 @@ namespace XGUI_Tools \param theFeature a feature */ std::string XGUI_EXPORT featureInfo(FeaturePtr theFeature); + + /** + * Returns pointer on real feature + */ + FeaturePtr realFeature(const FeaturePtr theFeature); } #endif diff --git a/src/XGUI/XGUI_ViewerProxy.cpp b/src/XGUI/XGUI_ViewerProxy.cpp index c3ae206ca..b5c3706da 100644 --- a/src/XGUI/XGUI_ViewerProxy.cpp +++ b/src/XGUI/XGUI_ViewerProxy.cpp @@ -95,6 +95,8 @@ void XGUI_ViewerProxy::connectToViewer() connect(aViewer, SIGNAL(keyRelease(QKeyEvent*)), this, SIGNAL(keyRelease(QKeyEvent*))); + + connect(aViewer, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); } else { XGUI_Viewer* aViewer = myWorkshop->mainWindow()->viewer(); @@ -121,6 +123,8 @@ void XGUI_ViewerProxy::connectToViewer() this, SLOT(onKeyPress(XGUI_ViewWindow*, QKeyEvent*))); connect(aViewer, SIGNAL(keyRelease(XGUI_ViewWindow*, QKeyEvent*)), this, SLOT(onKeyRelease(XGUI_ViewWindow*, QKeyEvent*))); + + connect(aViewer, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); } } diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 8ac845aaa..ca06c5e1f 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -841,6 +841,14 @@ void XGUI_Workshop::deleteFeatures(QFeatureList theList) //************************************************************** void XGUI_Workshop::showFeatures(QFeatureList theList, bool isVisible) { -// foreach (FeaturePtr aFeature, theList) { -// } + if (isVisible) { + foreach (FeaturePtr aFeature, theList) { + myDisplayer->display(aFeature, false); + } + } else { + foreach (FeaturePtr aFeature, theList) { + myDisplayer->erase(aFeature, false); + } + } + myDisplayer->updateViewer(); } -- 2.39.2