From 2fd5bfd00d55a8b6764f70b6a4bc426eab9fe4fc Mon Sep 17 00:00:00 2001 From: Fabian Paus <fabian.paus@kit.edu> Date: Tue, 4 Jan 2022 16:02:06 +0100 Subject: [PATCH] ArViz: Implement selection via double-click --- .../RobotAPI/components/ArViz/Client/Client.h | 4 +- .../components/ArViz/Coin/Visualizer.cpp | 51 +++++++++++-------- .../components/ArViz/Coin/Visualizer.h | 1 + .../components/ArViz/Example/ArVizExample.cpp | 23 ++++++--- .../RobotAPI/gui-plugins/ArViz/ArVizWidget.ui | 4 +- .../ArViz/ArVizWidgetController.cpp | 12 +++++ .../gui-plugins/ArViz/ArVizWidgetController.h | 1 + 7 files changed, 64 insertions(+), 32 deletions(-) diff --git a/source/RobotAPI/components/ArViz/Client/Client.h b/source/RobotAPI/components/ArViz/Client/Client.h index 4b5e09faf..0a93e7025 100644 --- a/source/RobotAPI/components/ArViz/Client/Client.h +++ b/source/RobotAPI/components/ArViz/Client/Client.h @@ -313,14 +313,14 @@ namespace viz return StagedCommit(); } - CommitResult apply(StagedCommit const& commit) + CommitResult commit(StagedCommit const& commit) { CommitResult result; result.data_ = storage->commitAndReceiveInteractions(commit.data_); return result; } - CommitResultAsync applyAsync(StagedCommit const& commit) + CommitResultAsync commitAsync(StagedCommit const& commit) { CommitResultAsync result; result.async = storage->begin_commitAndReceiveInteractions(commit.data_); diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp index b71d5e48d..3ef94f45d 100644 --- a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp +++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp @@ -548,6 +548,36 @@ namespace coin } } + void CoinVisualizer::selectElement(int index) + { + if (index >= (int)elementInteractions.size()) + { + return; + } + + ElementInteractionData const* id = elementInteractions[index].get(); + + CoinLayer* layer = layers.findLayer(id->layer); + if (layer == nullptr) + { + ARMARX_WARNING << "Selected an element whose layer does not exist: \n" + << "Layer: " << id->layer.first << "/" << id->layer.second + << ", element: " << id->element; + return; + } + CoinLayerElement* element = layer->findElement(id->element); + if (element == nullptr) + { + ARMARX_WARNING << "Selected an element which does not exist: \n" + << "Layer: " << id->layer.first << "/" << id->layer.second + << ", element: " << id->element; + return; + } + + selection->deselectAll(); + selection->select(element->visu->separator); + } + static ElementInteractionData* findInteractionDataOnPath(SoPath* path) { // Search for user data in the path @@ -591,27 +621,6 @@ namespace coin return; } - CoinLayer* layer = layers.findLayer(id->layer); - if (layer == nullptr) - { - ARMARX_WARNING << "Selected/Deselected an element whose layer does not exist: \n" - << "Layer: " << id->layer.first << "/" << id->layer.second - << ", element: " << id->element; - return; - } - CoinLayerElement* element = layer->findElement(id->element); - if (element == nullptr) - { - ARMARX_WARNING << "Selected/Deselected an element which does not exist: \n" - << "Layer: " << id->layer.first << "/" << id->layer.second - << ", element: " << id->element; - return; - } - - // ARMARX_INFO << "Selected/Deselected element: \n" - // << "Layer: " << id->layer.first << "/" << id->layer.second - // << ", element: " << id->element; - if (eventType == data::InteractionFeedbackType::SELECT) { selectedElement = id; diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.h b/source/RobotAPI/components/ArViz/Coin/Visualizer.h index a3c9da6fa..adda36b9a 100644 --- a/source/RobotAPI/components/ArViz/Coin/Visualizer.h +++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.h @@ -236,6 +236,7 @@ namespace armarx::viz void emitLayersChanged(std::vector<CoinLayerID> const& layerIDs); void emitLayerUpdated(CoinLayerID const& layerID, CoinLayer const& layer); + void selectElement(int index); void onSelectEvent(SoPath* path, int eventType); // These are selectable element IDs and need to be persistent in memory. // We store a raw pointer to these into the SoSeperator objects of Coin. diff --git a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp index 97899d9cf..d772854de 100644 --- a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp +++ b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp @@ -503,8 +503,7 @@ namespace armarx void fillInteractionLayer(viz::Layer& layer) { - // TODO: Add interaction to client code - // 1. Make box selectable + // Make box selectable viz::Box box = viz::Box("box") .position(Eigen::Vector3f(2000.0f, 0.0f, 2000.0f)) .size(Eigen::Vector3f(200.0f, 200.0f, 200.0f)) @@ -581,7 +580,7 @@ namespace armarx stage.add(interactionLayer); // Apply the staged commits in a single network call - viz::CommitResult result = arviz.apply(stage); + viz::CommitResult result = arviz.commit(stage); ARMARX_INFO << "Permanent layers committed in revision: " << result.revision(); @@ -617,7 +616,7 @@ namespace armarx stage.requestInteraction(interactionLayer); // This sends the layer updates and receives interaction feedback in a single network call - result = arviz.apply(stage); + result = arviz.commit(stage); // Be careful: The interactions are stored in the CommitResult // So the range is only valid as long as result is in scope and not overriden. viz::InteractionFeedbackRange interactions = result.interactions(); @@ -626,9 +625,19 @@ namespace armarx ARMARX_INFO << "We got some interactions: " << interactions.size(); for (viz::InteractionFeedback const& interaction: interactions) { - ARMARX_INFO << "[" << interaction.layer() - << "/" << interaction.element() - << "] " << toString(interaction.type()); + if (interaction.type() == viz::InteractionFeedbackType::ContextMenuChosen) + { + ARMARX_INFO << "[" << interaction.layer() + << "/" << interaction.element() + << "] Chosen context menu: " + << interaction.chosenContextMenuEntry(); + } + else + { + ARMARX_INFO << "[" << interaction.layer() + << "/" << interaction.element() + << "] " << toString(interaction.type()); + } } } diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui b/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui index 782e9d704..c43cbd71a 100644 --- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui +++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui @@ -17,7 +17,7 @@ <item> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> - <number>2</number> + <number>0</number> </property> <widget class="QWidget" name="tabLayerSelection"> <attribute name="title"> @@ -655,7 +655,7 @@ <item> <widget class="QGroupBox" name="groupBoxInteractiveElements"> <property name="title"> - <string>Interactive Elements</string> + <string>Interactive Elements (Double click to select in 3D Viewer)</string> </property> <layout class="QVBoxLayout" name="verticalLayout_10"> <item> diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp index 183592534..7aa05e3a1 100644 --- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp +++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp @@ -87,6 +87,7 @@ namespace armarx connect(widget.exportToVRMLButton, &QPushButton::clicked, this, &This::exportToVRML); connect(widget.deselectButton, &QPushButton::clicked, this, &This::onDeselectElement); + connect(widget.listInteractiveElements, &QListWidget::itemDoubleClicked, this, &This::onInteractiveElementSelected); connect(this, &This::connectGui, this, &This::onConnectGui, Qt::QueuedConnection); connect(this, &This::disconnectGui, this, &This::onDisconnectGui, Qt::QueuedConnection); @@ -461,6 +462,17 @@ namespace armarx } } + void ArVizWidgetController::onInteractiveElementSelected(QListWidgetItem* item) + { + int index = widget.listInteractiveElements->row(item); + if (index < 0) + { + return; + } + + visualizer.selectElement(index); + } + static QString toQString(viz::ElementInteractionData const& inter) { std::string id = inter.layer.first + "/" diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h index 9fd1fa47f..cb10e285b 100644 --- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h +++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h @@ -140,6 +140,7 @@ namespace armarx void onDeselectElement(); void onContextMenuClicked(); + void onInteractiveElementSelected(QListWidgetItem* item); void onUpdate(); void onTimingObserverUpdate(); -- GitLab