From 6c1a9f06ce6fbab6d1931950eceb2097ffec3408 Mon Sep 17 00:00:00 2001
From: Fabian Paus <fabian.paus@kit.edu>
Date: Wed, 29 Dec 2021 14:25:24 +0100
Subject: [PATCH] ArViz: Add client API to define possible interactions

---
 .../components/ArViz/Client/Elements.h        | 37 ++++------
 .../components/ArViz/Client/elements/Color.h  |  4 +-
 .../ArViz/Client/elements/ElementOps.h        | 68 +++++++++++++++++--
 .../components/ArViz/Example/ArVizExample.cpp |  4 ++
 4 files changed, 81 insertions(+), 32 deletions(-)

diff --git a/source/RobotAPI/components/ArViz/Client/Elements.h b/source/RobotAPI/components/ArViz/Client/Elements.h
index 9f3157c9f..0a871fe79 100644
--- a/source/RobotAPI/components/ArViz/Client/Elements.h
+++ b/source/RobotAPI/components/ArViz/Client/Elements.h
@@ -5,7 +5,7 @@
 
 
 
-#include "Color.h"
+#include "elements/Color.h"
 #include "elements/ElementOps.h"
 #include "elements/Mesh.h"
 #include "elements/PointCloud.h"
@@ -46,9 +46,8 @@ namespace armarx::viz
 {
     using data::ColoredPoint;
 
-    class Box : public ElementOps<Box, data::ElementBox>
+    struct Box : ElementOps<Box, data::ElementBox>
     {
-    public:
         using ElementOps::ElementOps;
 
         Box& size(Eigen::Vector3f const& s)
@@ -70,9 +69,8 @@ namespace armarx::viz
     };
 
 
-    class Cylinder : public ElementOps<Cylinder, data::ElementCylinder>
+    struct Cylinder : ElementOps<Cylinder, data::ElementCylinder>
     {
-    public:
         using ElementOps::ElementOps;
 
         Cylinder& radius(float r)
@@ -93,9 +91,8 @@ namespace armarx::viz
     };
 
 
-    class Cylindroid : public ElementOps<Cylindroid, data::ElementCylindroid>
+    struct Cylindroid : ElementOps<Cylindroid, data::ElementCylindroid>
     {
-    public:
         Cylindroid(const std::string& name) :
             ElementOps(name)
         {
@@ -130,9 +127,8 @@ namespace armarx::viz
     };
 
 
-    class Sphere : public ElementOps<Sphere, data::ElementSphere>
+    struct Sphere : ElementOps<Sphere, data::ElementSphere>
     {
-    public:
         using ElementOps::ElementOps;
 
         Sphere& radius(float r)
@@ -144,9 +140,8 @@ namespace armarx::viz
     };
 
 
-    class Ellipsoid : public ElementOps<Ellipsoid, data::ElementEllipsoid>
+    struct Ellipsoid : ElementOps<Ellipsoid, data::ElementEllipsoid>
     {
-    public:
         Ellipsoid(const std::string& name) :
             ElementOps(name)
         {
@@ -177,16 +172,14 @@ namespace armarx::viz
     };
 
 
-    class Pose : public ElementOps<Pose, data::ElementPose>
+    struct Pose : ElementOps<Pose, data::ElementPose>
     {
-    public:
         using ElementOps::ElementOps;
     };
 
 
-    class Text : public ElementOps<Text, data::ElementText>
+    struct Text : ElementOps<Text, data::ElementText>
     {
-    public:
         using ElementOps::ElementOps;
 
         Text& text(std::string const& t)
@@ -198,9 +191,8 @@ namespace armarx::viz
     };
 
 
-    class Arrow : public ElementOps<Arrow, data::ElementArrow>
+    struct Arrow : ElementOps<Arrow, data::ElementArrow>
     {
-    public:
         using ElementOps::ElementOps;
 
         Arrow& direction(Eigen::Vector3f dir);
@@ -230,9 +222,8 @@ namespace armarx::viz
     };
 
 
-    class ArrowCircle : public ElementOps<ArrowCircle, data::ElementArrowCircle>
+    struct ArrowCircle : ElementOps<ArrowCircle, data::ElementArrowCircle>
     {
-    public:
         using ElementOps::ElementOps;
 
         ArrowCircle& normal(Eigen::Vector3f dir);
@@ -244,7 +235,6 @@ namespace armarx::viz
             return *this;
         }
 
-
         ArrowCircle& width(float w)
         {
             data_->width = w;
@@ -261,9 +251,8 @@ namespace armarx::viz
     };
 
 
-    class Polygon : public ElementOps<Polygon, data::ElementPolygon>
+    struct Polygon : ElementOps<Polygon, data::ElementPolygon>
     {
-    public:
         using ElementOps::ElementOps;
 
         Polygon& clear()
@@ -320,13 +309,11 @@ namespace armarx::viz
     };
 
 
-    class Object : public ElementOps<Object, data::ElementObject>
+    struct Object : ElementOps<Object, data::ElementObject>
     {
-    private:
         static const std::string DefaultObjectsPackage;
         static const std::string DefaultRelativeObjectsDirectory;
 
-    public:
         using ElementOps::ElementOps;
 
         Object& file(std::string const& project, std::string const& filename)
diff --git a/source/RobotAPI/components/ArViz/Client/elements/Color.h b/source/RobotAPI/components/ArViz/Client/elements/Color.h
index 4abfe40dd..272e25b44 100644
--- a/source/RobotAPI/components/ArViz/Client/elements/Color.h
+++ b/source/RobotAPI/components/ArViz/Client/elements/Color.h
@@ -1,10 +1,10 @@
 #pragma once
 
-#include <Eigen/Core>
+#include <RobotAPI/interface/ArViz/Elements.h>
 
 #include <SimoxUtility/color/Color.h>
 
-#include <RobotAPI/interface/ArViz/Elements.h>
+#include <Eigen/Core>
 
 
 namespace armarx::viz
diff --git a/source/RobotAPI/components/ArViz/Client/elements/ElementOps.h b/source/RobotAPI/components/ArViz/Client/elements/ElementOps.h
index b763c4301..b4dc3c192 100644
--- a/source/RobotAPI/components/ArViz/Client/elements/ElementOps.h
+++ b/source/RobotAPI/components/ArViz/Client/elements/ElementOps.h
@@ -1,24 +1,77 @@
 #pragma once
 
-#pragma once
+#include "Color.h"
+
+#include <RobotAPI/interface/ArViz/Elements.h>
 
 #include <SimoxUtility/color/GlasbeyLUT.h>
 #include <SimoxUtility/math/convert/rpy_to_quat.h>
 
-#include <RobotAPI/interface/ArViz/Elements.h>
-
 #include <Eigen/Core>
 #include <Eigen/Geometry>
 
 #include <string>
 
-#include "Color.h"
-
 
 namespace armarx::viz
 {
     using data::ColoredPoint;
 
+    struct InteractionDescription
+    {
+        using Self = InteractionDescription;
+
+        Self& none()
+        {
+            data_.enableFlags = 0;
+            return *this;
+        }
+
+        Self& selection()
+        {
+            data_.enableFlags |= data::InteractionEnableFlags::SELECT;
+            return *this;
+        }
+
+        Self& contextMenu(std::vector<std::string> const& options)
+        {
+            data_.enableFlags |= data::InteractionEnableFlags::CONTEXT_MENU;
+            data_.contextMenuOptions = options;
+            // Context menu (right click) implies selection
+            return selection();
+        }
+
+        Self& translation(bool x = true, bool y = true, bool z = true)
+        {
+            data_.enableFlags |= (x ? data::InteractionEnableFlags::TRANSLATION_X : 0);
+            data_.enableFlags |= (y ? data::InteractionEnableFlags::TRANSLATION_Y : 0);
+            data_.enableFlags |= (z ? data::InteractionEnableFlags::TRANSLATION_Z : 0);
+            // Translation implies selection
+            return selection();
+        }
+
+        Self& rotation(bool x = true, bool y = true, bool z = true)
+        {
+            data_.enableFlags |= (x ? data::InteractionEnableFlags::ROTATION_X : 0);
+            data_.enableFlags |= (y ? data::InteractionEnableFlags::ROTATION_Y : 0);
+            data_.enableFlags |= (z ? data::InteractionEnableFlags::ROTATION_Z : 0);
+            // Rotation implies selection
+            return selection();
+        }
+
+        Self& fullTransform()
+        {
+            return translation().rotation();
+        }
+
+        data::InteractionDescription data_;
+    };
+
+    inline InteractionDescription interaction()
+    {
+        return InteractionDescription();
+    }
+
     // Move the ice datatypes into their own namespace
     template <typename DerivedT, typename ElementT>
     class ElementOps
@@ -171,6 +224,11 @@ namespace armarx::viz
             }
         }
 
+        DerivedT& enable(InteractionDescription const& interactionDescription)
+        {
+            data_->interaction = interactionDescription.data_;
+        }
+
 
         IceInternal::Handle<ElementT> data_;
     };
diff --git a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
index b6e606ae9..c61c26054 100644
--- a/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
+++ b/source/RobotAPI/components/ArViz/Example/ArVizExample.cpp
@@ -508,6 +508,10 @@ namespace armarx
                        .position(Eigen::Vector3f(2000.0f, 0.0f, 2000.0f))
                        .size(Eigen::Vector3f(200.0f, 200.0f, 200.0f))
                        .color(viz::Color::fromRGBA(0, 165, 255));
+        // Enable some interaction possibilities
+        box.enable(viz::interaction()
+                   .selection()
+                   .contextMenu({"First Option", "Second Option", "Third Option"}));
 
         layer.add(box);
     }
-- 
GitLab