From c18706c873fc7af3a41070c17500832466762b9c Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Tue, 24 Aug 2021 08:12:19 +0200
Subject: [PATCH] Implement adding edges

---
 .../LocationGraphEditorWidgetController.cpp   | 69 +++++++++++++------
 .../LocationGraphEditorWidgetController.h     |  2 +
 .../widgets/EdgeTableWidget.cpp               |  9 ++-
 .../widgets/EdgeTableWidget.h                 | 11 ++-
 .../widgets/graph_scene/Scene.cpp             | 27 +++-----
 .../widgets/graph_scene/Scene.h               | 23 ++++++-
 6 files changed, 97 insertions(+), 44 deletions(-)

diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.cpp b/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.cpp
index 649b6631..50e45488 100644
--- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.cpp
+++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.cpp
@@ -341,21 +341,59 @@ namespace armarx::nav::locgrapheditor
     GuiGraph::Edge
     LocationGraphEditorWidgetController::addEdge(graph::Graph::ConstEdge edge)
     {
-        ARMARX_CHECK(not model.graph.hasEdge(edge.sourceObjectID(), edge.targetObjectID()))
-                << "Edge must not exist before being added: '"
-                << edge.source().attrib().getName() << "' -> '"
-                << edge.target().attrib().getName() << "'";
-
         auto source = model.graph.vertex(edge.sourceObjectID());
         auto target = model.graph.vertex(edge.targetObjectID());
 
-        EdgeData attrib { edge.attrib() };
-        attrib.tableWidgetItem = view.edgeTable->addEdge(edge);
-        attrib.graphicsItem = view.graph->scene()->addEdge(edge);
-        return model.graph.addEdge(source, target, attrib);
+        return addEdge(source, target, { edge.attrib() });
+    }
+
+
+    GuiGraph::Edge
+    LocationGraphEditorWidgetController::addEdge(
+            GuiGraph::ConstVertex source,
+            GuiGraph::ConstVertex target,
+            const EdgeData& defaultAttribs)
+    {
+        ARMARX_CHECK(not model.graph.hasEdge(source.objectID(), target.objectID()))
+                << "Edge must not exist before being added: '"
+                << source.attrib().getName() << "' -> '"
+                << target.attrib().getName() << "'";
+
+        GuiGraph::Edge edge = model.graph.addEdge(source, target, defaultAttribs);
+        edge.attrib().tableWidgetItem = view.edgeTable->addEdge(edge);
+        edge.attrib().graphicsItem = view.graph->scene()->addEdge(edge);
+        return edge;
     }
 
 
+    void LocationGraphEditorWidgetController::addEdges(
+            QList<QPair<QTableWidgetItem*, QTableWidgetItem*>> vertexItems)
+    {
+        if (/* DISABLES CODE */ (false))
+        {
+            std::stringstream ss;
+            ss << "Adding edges ...";
+            for (const auto& [source, target] : vertexItems)
+            {
+                ss << "\n- " << source->text() << " to " << target->text();
+            }
+            ARMARX_IMPORTANT << ss.str();
+        }
+
+        const auto itemToVertexMap = model.graph.getTableItemToVertexMap();
+        for (const auto& [sourceItem, targetItem] : vertexItems)
+        {
+            GuiGraph::Vertex source = itemToVertexMap.at(sourceItem);
+            GuiGraph::Vertex target = itemToVertexMap.at(targetItem);
+            if (not model.graph.hasEdge(source, target))
+            {
+                addEdge(source, target, {});
+            }
+        }
+
+        emit graphChanged();
+    }
+
 
     void LocationGraphEditorWidgetController::updateGraphView()
     {
@@ -466,19 +504,6 @@ namespace armarx::nav::locgrapheditor
     }
 
 
-    void LocationGraphEditorWidgetController::addEdges(
-            QList<QPair<QTableWidgetItem*, QTableWidgetItem*>> vertexItems)
-    {
-        std::stringstream ss;
-        ss << "Adding edges ...";
-        for (const auto& [source, target] : vertexItems)
-        {
-            ss << "\n- " << source->text() << " to " << target->text();
-        }
-        ARMARX_IMPORTANT << ss.str();
-    }
-
-
     void LocationGraphEditorWidgetController::resetHighlighting()
     {
         for (auto vertex : model.graph.vertices())
diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.h b/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.h
index 0fb66749..3a7d9dd3 100644
--- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.h
+++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/LocationGraphEditorWidgetController.h
@@ -142,6 +142,8 @@ namespace armarx::nav::locgrapheditor
         void setGraph(graph::Graph& nav);
         GuiGraph::Vertex addVertex(graph::Graph::ConstVertex vertex);
         GuiGraph::Edge addEdge(graph::Graph::ConstEdge edge);
+        GuiGraph::Edge addEdge(GuiGraph::ConstVertex source, GuiGraph::ConstVertex target,
+                               const EdgeData& defaultAttribs);
 
         void clearEdges();
         void clearGraph();
diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.cpp b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.cpp
index 45d852df..9e7a16ff 100644
--- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.cpp
+++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.cpp
@@ -51,12 +51,15 @@ namespace armarx::nav::locgrapheditor
 
 
     QTableWidgetItem*
-    EdgeTableWidget::addEdge(graph::Graph::ConstEdge edge)
+    EdgeTableWidget::addEdge(
+            const graph::VertexAttribs& sourceAttrib,
+            const graph::VertexAttribs& targetAttrib)
     {
         int row = rowCount();
         setRowCount(row + 1);
-        setItem(row, 0, new QTableWidgetItem {QString::fromStdString(edge.source().attrib().getName())});
-        setItem(row, 1, new QTableWidgetItem {QString::fromStdString(edge.target().attrib().getName())});
+
+        setItem(row, 0, new QTableWidgetItem {QString::fromStdString(sourceAttrib.getName())});
+        setItem(row, 1, new QTableWidgetItem {QString::fromStdString(targetAttrib.getName())});
 
         return item(row, 0);
     }
diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.h b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.h
index bf6a496f..296e6a6f 100644
--- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.h
+++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/EdgeTableWidget.h
@@ -42,7 +42,16 @@ namespace armarx::nav::locgrapheditor
         EdgeTableWidget();
 
 
-        QTableWidgetItem* addEdge(graph::Graph::ConstEdge edge);
+        template <class EdgeT>
+        QTableWidgetItem* addEdge(const EdgeT& edge)
+        {
+            return addEdge(edge.source().attrib(), edge.target().attrib());
+        }
+
+        QTableWidgetItem*
+        addEdge(const graph::VertexAttribs& sourceAttrib,
+                const graph::VertexAttribs& targetAttrib);
+
 
         void updateEdge(GuiGraph::Edge edge);
 
diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.cpp b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.cpp
index 32c33382..cfa598c2 100644
--- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.cpp
+++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.cpp
@@ -11,38 +11,34 @@ namespace armarx::nav::locgrapheditor::graph_scene
 {
 
     QGraphicsEllipseItem*
-    Scene::addVertex(graph::Graph::ConstVertex vertex)
+    Scene::addVertex(semrel::ShapeID vertexID, const graph::VertexAttribs& attrib)
     {
-        const Eigen::Matrix4d pose = vertex.attrib().getPose().cast<qreal>();
-
-        // To capture by copy
-        semrel::ShapeID vertexID = vertex.objectID();
+        const Eigen::Matrix4d pose = attrib.getPose().cast<qreal>();
 
         GraphVisualizerGraphicsEllipseItem* item = new GraphVisualizerGraphicsEllipseItem
         {
             [this, vertexID]() { emit vertexSelected(vertexID); },
-            pose(0, 3), - pose(1, 3),
-            1, 1
+            pose(0, 3),
+            - pose(1, 3),
+            2, 2
         };
         addItem(item);
 
         // setToolTip on graphicsItem does not work
         item->setZValue(std::numeric_limits<qreal>::max());
         // dynamic_cast<QGraphicsItem*>(item)->setToolTip(QString::fromStdString("Vertex '" + name + "'"));
-        item->setToolTip(QString::fromStdString("Vertex '" + vertex.attrib().getName() + "'"));
+        item->setToolTip(QString::fromStdString("Vertex '" + attrib.getName() + "'"));
 
         return item;
     }
 
 
     QGraphicsLineItem*
-    Scene::addEdge(graph::Graph::ConstEdge edge)
+    Scene::addEdge(semrel::ShapeID sourceID, const graph::VertexAttribs& sourceAttrib,
+                   semrel::ShapeID targetID, const graph::VertexAttribs& targetAttrib)
     {
-        semrel::ShapeID sourceID = edge.sourceObjectID();
-        semrel::ShapeID targetID = edge.targetObjectID();
-
-        Eigen::Matrix4d sourcePose = edge.source().attrib().getPose().cast<qreal>();
-        Eigen::Matrix4d targetPose = edge.target().attrib().getPose().cast<qreal>();
+        Eigen::Matrix4d sourcePose = sourceAttrib.getPose().cast<qreal>();
+        Eigen::Matrix4d targetPose = targetAttrib.getPose().cast<qreal>();
 
         GraphVisualizerGraphicsLineItem* item = new GraphVisualizerGraphicsLineItem
         {
@@ -54,8 +50,7 @@ namespace armarx::nav::locgrapheditor::graph_scene
 
         // setToolTip on item does not work
         std::stringstream toolTip;
-        toolTip << "Edge '" << edge.source().attrib().getName()
-                << "' -> '"  << edge.target().attrib().getName();
+        toolTip << "Edge '" << sourceAttrib.getName() << "' -> '"  << targetAttrib.getName();
         item->setToolTip(QString::fromStdString(toolTip.str()));
 
         return item;
diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.h b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.h
index 95965d34..6afc6a7f 100644
--- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.h
+++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/widgets/graph_scene/Scene.h
@@ -24,8 +24,27 @@ namespace armarx::nav::locgrapheditor::graph_scene
 
         using QGraphicsScene::QGraphicsScene;
 
-        QGraphicsEllipseItem* addVertex(graph::Graph::ConstVertex vertex);
-        QGraphicsLineItem* addEdge(graph::Graph::ConstEdge Edge);
+        template <class VertexT>
+        QGraphicsEllipseItem*
+        addVertex(const VertexT& vertex)
+        {
+            return addVertex(vertex.objectID(), vertex.attrib());
+        }
+        QGraphicsEllipseItem*
+        addVertex(semrel::ShapeID vertexID, const graph::VertexAttribs& attribs);
+
+
+        template <class EdgeT>
+        QGraphicsLineItem*
+        addEdge(const EdgeT& edge)
+        {
+            return addEdge(edge.sourceObjectID(), edge.source().attrib(),
+                           edge.targetObjectID(), edge.target().attrib());
+        }
+        QGraphicsLineItem*
+        addEdge(semrel::ShapeID sourceID, const graph::VertexAttribs& sourceAttrib,
+                semrel::ShapeID targetID, const graph::VertexAttribs& targetAttrib);
+
 
         void updateVertex(GuiGraph::Vertex& vertex);
         void updateEdge(GuiGraph::Edge& edge);
-- 
GitLab