From d084f679e91280d214027f9274822f5022d2472f Mon Sep 17 00:00:00 2001
From: Markus Grotz <markus.grotz@kit.edu>
Date: Fri, 5 Mar 2021 13:54:02 +0100
Subject: [PATCH] add export button to ArViz

---
 .../components/ArViz/Coin/Visualizer.cpp      | 42 +++++++++++++++++++
 .../components/ArViz/Coin/Visualizer.h        |  2 +
 .../RobotAPI/gui-plugins/ArViz/ArVizWidget.ui | 24 +++++++++++
 .../ArViz/ArVizWidgetController.cpp           | 25 +++++++++++
 .../gui-plugins/ArViz/ArVizWidgetController.h |  1 +
 5 files changed, 94 insertions(+)

diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
index ffc286590..ff525ff98 100644
--- a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
+++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
@@ -7,6 +7,15 @@
 #include <Inventor/nodes/SoUnits.h>
 #include <thread>
 
+
+#include <Inventor/actions/SoWriteAction.h>
+#include <Inventor/actions/SoToVRML2Action.h>
+#include <Inventor/VRMLnodes/SoVRMLGroup.h>
+#include <Inventor/nodes/SoRotation.h>
+#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h>
+#include <VirtualRobot/Visualization/VisualizationFactory.h>
+
+
 #include "VisualizationRobot.h"
 
 namespace armarx::viz
@@ -416,4 +425,37 @@ namespace armarx::viz
             }
         }
     }
+
+    void CoinVisualizer::exportToVRML(const std::string& s)
+    {
+
+
+        SoOutput* so = new SoOutput();
+        if (!so->openFile(s.c_str()))
+        {
+            ARMARX_ERROR << "Could not open file " << s << " for writing." << std::endl;
+            return;
+        }
+
+        so->setHeaderString("#VRML V2.0 utf8");
+
+        SoGroup* n = new SoGroup;
+        n->ref();
+        n->addChild(root);
+        SoGroup* newVisu = VirtualRobot::CoinVisualizationFactory::convertSoFileChildren(n);
+        newVisu->ref();
+
+        SoToVRML2Action tovrml2;
+        tovrml2.apply(newVisu);
+        SoVRMLGroup* newroot = tovrml2.getVRML2SceneGraph();
+        newroot->ref();
+        SoWriteAction wra(so);
+        wra.apply(newroot);
+        newroot->unref();
+
+        so->closeFile();
+
+        newVisu->unref();
+        n->unref();
+    }
 }
diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.h b/source/RobotAPI/components/ArViz/Coin/Visualizer.h
index f3a224825..e2d9a4634 100644
--- a/source/RobotAPI/components/ArViz/Coin/Visualizer.h
+++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.h
@@ -129,6 +129,8 @@ namespace armarx::viz
 
         void update();
 
+        void exportToVRML(const std::string& s);
+
         template <typename ElementVisuT>
         void registerVisualizerFor()
         {
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui b/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui
index b5dc5e5dd..f5bb28f2f 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui
@@ -99,6 +99,30 @@
            </column>
           </widget>
          </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout_12">
+           <item>
+            <spacer name="horizontalSpacer_7">
+             <property name="orientation">
+              <enum>Qt::Horizontal</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>40</width>
+               <height>20</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+           <item>
+            <widget class="QPushButton" name="exportToVRMLButton">
+             <property name="text">
+              <string>Export To VRML</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
         </layout>
        </item>
        <item>
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
index 697ce64b0..cf42b9ff2 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
@@ -34,6 +34,10 @@
 
 #include <ArmarXCore/observers/variant/Variant.h>
 
+
+#include <QFileDialog>
+#include  <boost/algorithm/string/predicate.hpp>
+
 #define ENABLE_INTROSPECTION 1
 
 
@@ -89,6 +93,8 @@ namespace armarx
         connect(widget.replayStopButton, &QPushButton::clicked, this, &This::onReplayStop);
         connect(widget.replayTimedButton, &QPushButton::toggled, this, &This::onReplayTimedStart);
 
+        connect(widget.exportToVRMLButton, &QPushButton::clicked, this, &This::exportToVRML);
+
         connect(this, &This::connectGui, this, &This::onConnectGui, Qt::QueuedConnection);
         connect(this, &This::disconnectGui, this, &This::onDisconnectGui, Qt::QueuedConnection);
 
@@ -989,4 +995,23 @@ namespace armarx
             debugObserverName = configDialog->getProxyName(CONFIG_KEY_DEBUG_OBSERVER);
         }
     }
+
+
+    void ArVizWidgetController::exportToVRML()
+    {
+
+        QString fi = QFileDialog::getSaveFileName(Q_NULLPTR, tr("VRML 2.0 File"), QString(), tr("VRML Files (*.wrl)"));
+        std::string s = std::string(fi.toLatin1());
+
+        if (s.empty())
+        {
+            return;
+        }
+        if (!boost::algorithm::ends_with(s, ".wrl"))
+        {
+            s += ".wrl";
+        }
+
+        visualizer.exportToVRML(s);
+    }
 }
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
index 4e9c887de..e59b68579 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
@@ -162,6 +162,7 @@ namespace armarx
         long getRevisionForTimestamp(long timestamp);
         void onReplayTimedStart(bool checked);
         void onReplayTimerTick();
+        void exportToVRML();
 
         void changeMode(ArVizWidgetMode newMode);
         void enableWidgetAccordingToMode();
-- 
GitLab