From fdca07d5e473bafe29e836f02a8faffda6f13ab1 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 16 Feb 2021 12:58:45 +0100
Subject: [PATCH 01/12] Testing xml templating

---
 VsiMetadata/print.xml | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/VsiMetadata/print.xml b/VsiMetadata/print.xml
index 6e73d6d..2c5bb81 100644
--- a/VsiMetadata/print.xml
+++ b/VsiMetadata/print.xml
@@ -10,4 +10,19 @@
       printingplugin.printView();
     </code>
   </element>
+  <element name="printing_println">
+    <category>Misc</category>
+    <short>Console Ouput</short>
+    <long>Print Number to console.</long>
+    <dataflow>true</dataflow>
+    <inputs>
+      <input name="Value" type="Number">
+        <short>Value</short>
+        <precision>0.000001</precision>
+      </input>
+    </inputs>
+    <code>
+      print( [input="Value"] )
+    </code>
+  </element>
 </OpenFlipper>
-- 
GitLab


From b06fddf6e05010459e3f70f99700ccc602a7057a Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 16 Feb 2021 14:11:46 +0100
Subject: [PATCH 02/12] Started translating templates to python code

---
 VsiMetadata/decimater.xml       |  29 ++++----
 VsiMetadata/dialogs.xml         |  18 ++---
 VsiMetadata/infomeshobject.xml  |  24 +++----
 VsiMetadata/loopsConditions.xml |   6 +-
 VsiMetadata/math.xml            | 124 +++++++++++++++++++-------------
 VsiMetadata/meshselection.xml   |   2 +-
 VsiMetadata/object.xml          |   8 +--
 VsiMetadata/tests.xml           |  18 ++---
 8 files changed, 125 insertions(+), 104 deletions(-)

diff --git a/VsiMetadata/decimater.xml b/VsiMetadata/decimater.xml
index a928b0b..671d471 100644
--- a/VsiMetadata/decimater.xml
+++ b/VsiMetadata/decimater.xml
@@ -79,34 +79,31 @@
         <short>Independent Sets</short>
       </input>
     </inputs>
-    <precode>
-      var decimater_constraints
-    </precode>
     <code>
-      decimater_constraints = new Object ();
-      if ([is_set="decimation_order"])
+      decimater_constraints = {};
+      if ([is_set="decimation_order"]):
         decimater_constraints["decimation_order"] = [input="decimation_order"];
-      if ([is_set="decimater_type"])
+      if ([is_set="decimater_type"]):
         decimater_constraints["decimater_type"] = [input="decimater_type"];
-      if ([is_set="random_samples"])
+      if ([is_set="random_samples"]):
         decimater_constraints["random_samples"] = [input="random_samples"];
-      if ([is_set="incremental_percentage"])
+      if ([is_set="incremental_percentage"]):
         decimater_constraints["incremental_percentage"] = [input="incremental_percentage"];
-      if ([is_set="vertices"])
+      if ([is_set="vertices"]):
         decimater_constraints["vertices"] = [input="vertices"];
-      if ([is_set="triangles"])
+      if ([is_set="triangles"]):
         decimater_constraints["triangles"] = [input="triangles"];
-      if ([is_set="distance"])
+      if ([is_set="distance"]):
         decimater_constraints["distance"] = [input="distance"];
-      if ([is_set="edge_length"])
+      if ([is_set="edge_length"]):
         decimater_constraints["edge_length"] = [input="edge_length"];
-      if ([is_set="normal_deviation"])
+      if ([is_set="normal_deviation"]):
         decimater_constraints["normal_deviation"] = [input="normal_deviation"];
-      if ([is_set="roundness"])
+      if ([is_set="roundness"]):
         decimater_constraints["roundness"] = [input="roundness"];
-      if ([is_set="aspect_ratio"])
+      if ([is_set="aspect_ratio"]):
         decimater_constraints["aspect_ratio"] = [input="aspect_ratio"];
-      if ([is_set="independent_sets"])
+      if ([is_set="independent_sets"]):
         decimater_constraints["independent_sets"] = [input="independent_sets"];
       decimater.decimate ([input="obj"],decimater_constraints);
     </code>
diff --git a/VsiMetadata/dialogs.xml b/VsiMetadata/dialogs.xml
index 86c64fa..ee8f937 100644
--- a/VsiMetadata/dialogs.xml
+++ b/VsiMetadata/dialogs.xml
@@ -25,11 +25,11 @@
       </input>
     </inputs>
     <code>
-      var message = [input="message"];
+      message = [input="message"];
 
-      message = message.replace(/\$1/g, [input="in1"]);
-      message = message.replace(/\$2/g, [input="in2"]);
-      message = message.replace(/\$3/g, [input="in3"]);
+      message = message.replace("$1", [input="in1"]);
+      message = message.replace("$2", [input="in2"]);
+      message = message.replace("$3", [input="in3"]);
 
       visualscripting.messageBox (message);
     </code>
@@ -89,11 +89,11 @@
       </output>
     </outputs>
     <code>
-      var message = [input="message"];
+      message = [input="message"];
 
-      message = message.replace(/\$1/g, [input="in1"]);
-      message = message.replace(/\$2/g, [input="in2"]);
-      message = message.replace(/\$3/g, [input="in3"]);
+      message = message.replace("$1", [input="in1"]);
+      message = message.replace("$2", [input="in2"]);
+      message = message.replace("$3", [input="in3"]);
 
       [output="ret"] = visualscripting.questionBox (message);
     </code>
@@ -136,7 +136,7 @@
       </output>
     </outputs>
     <code>
-      var dialog_stop_box_message = [input="message"];
+      dialog_stop_box_message = [input="message"];
 
       [output="continue"] = visualscripting.continueBox(dialog_stop_box_message);
     </code>
diff --git a/VsiMetadata/infomeshobject.xml b/VsiMetadata/infomeshobject.xml
index 2496faf..fe94bcd 100644
--- a/VsiMetadata/infomeshobject.xml
+++ b/VsiMetadata/infomeshobject.xml
@@ -33,15 +33,15 @@
       </output>
     </outputs>
     <code>
-      if ([is_connected="nVert"])
+      if ([is_connected="nVert"]):
         [output="nVert"] = infomeshobject.vertexCount([input="obj"]);
-      if ([is_connected="nEdge"])
+      if ([is_connected="nEdge"]):
         [output="nEdge"] = infomeshobject.edgeCount([input="obj"]);
-      if ([is_connected="nFace"])
+      if ([is_connected="nFace"]):
         [output="nFace"] = infomeshobject.faceCount([input="obj"]);
-      if ([is_connected="nBound"])
+      if ([is_connected="nBound"]):
         [output="nBound"] = infomeshobject.boundaryCount([input="obj"]);
-      if ([is_connected="nComp"])
+      if ([is_connected="nComp"]):
         [output="nComp"] = infomeshobject.componentCount([input="obj"]);
     </code>
   </element>
@@ -72,11 +72,11 @@
       </output>
     </outputs>
     <code>
-      if ([is_connected="minEdgeLength"])
+      if ([is_connected="minEdgeLength"]):
         [output="minEdgeLength"] = infomeshobject.minEdgeLength([input="obj"]);
-      if ([is_connected="maxEdgeLength"])
+      if ([is_connected="maxEdgeLength"]):
         [output="maxEdgeLength"] = infomeshobject.maxEdgeLength([input="obj"]);
-      if ([is_connected="meanEdgeLength"])
+      if ([is_connected="meanEdgeLength"]):
         [output="meanEdgeLength"] = infomeshobject.meanEdgeLength([input="obj"]);
     </code>
   </element>
@@ -111,13 +111,13 @@
       </output>
     </outputs>
     <code>
-      if ([is_connected="min"])
+      if ([is_connected="min"]):
         [output="min"] = infomeshobject.boundingBoxMin([input="obj"]);
-      if ([is_connected="max"])
+      if ([is_connected="max"]):
         [output="max"] = infomeshobject.boundingBoxMax([input="obj"]);
-      if ([is_connected="size"])
+      if ([is_connected="size"]):
         [output="size"] = infomeshobject.boundingBoxSize([input="obj"]);
-      if ([is_connected="cog"])
+      if ([is_connected="cog"]):
         [output="cog"] = infomeshobject.cog([input="obj"]);
     </code>
   </element>
diff --git a/VsiMetadata/loopsConditions.xml b/VsiMetadata/loopsConditions.xml
index 047fdd9..8ea3994 100644
--- a/VsiMetadata/loopsConditions.xml
+++ b/VsiMetadata/loopsConditions.xml
@@ -18,7 +18,7 @@
       </function>
     </functions>
     <code>
-      while ([function="condition"]().out)
+      while ([function="condition"]().out):
         [function="content"]();
     </code>
   </element>
@@ -42,9 +42,9 @@
       </function>
     </functions>
     <code>
-      if ([input="condition"])
+      if ([input="condition"]):
         [function="true"]();
-      else
+      else:
         [function="false"]();
     </code>
   </element>
diff --git a/VsiMetadata/math.xml b/VsiMetadata/math.xml
index cdbc9ed..889ea17 100644
--- a/VsiMetadata/math.xml
+++ b/VsiMetadata/math.xml
@@ -32,16 +32,16 @@
       </output>
     </outputs>
     <code>
-      if ([is_connected="add"])
-        [output="add"] = Number([input="a"]) + Number([input="b"]);
-      if ([is_connected="sub"])
+      if ([is_connected="add"]):
+        [output="add"] = [input="a"] + [input="b"];
+      if ([is_connected="sub"]):
         [output="sub"] = [input="a"] - [input="b"];
-      if ([is_connected="mul"])
+      if ([is_connected="mul"]):
         [output="mul"] = [input="a"] * [input="b"];
-      if ([is_connected="div"])
+      if ([is_connected="div"]):
         [output="div"] = [input="a"] / [input="b"];
-      if ([is_connected="pow"])
-        [output="pow"] = Math.pow ([input="a"],[input="b"]);
+      if ([is_connected="pow"]):
+        [output="pow"] = pow ([input="a"],[input="b"]);
     </code>
   </element>
   <element name="minmax">
@@ -69,10 +69,10 @@
       </output>
     </outputs>
     <code>
-      if ([is_connected="min"])
-        [output="min"] = Math.min ([input="a"], [input="b"]);
-      if ([is_connected="max"])
-        [output="max"] = Math.max ([input="a"], [input="b"]);
+      if ([is_connected="min"]):
+        [output="min"] = min ([input="a"], [input="b"]);
+      if ([is_connected="max"]):
+        [output="max"] = max ([input="a"], [input="b"]);
     </code>
   </element>
   <element name="round">
@@ -103,15 +103,18 @@
         <long>Returns the smallest integer greater than or equal to X. (round up).</long>
       </output>
     </outputs>
+    <precode>
+      import math
+    </precode>
     <code>
-      if ([is_connected="abs"])
-        [output="abs"] = Math.abs ([input="x"]);
-      if ([is_connected="round"])
-        [output="round"] = Math.round ([input="x"]);
-      if ([is_connected="floor"])
-        [output="floor"] = Math.floor ([input="x"]);
-      if ([is_connected="ceil"])
-        [output="ceil"] = Math.ceil ([input="x"]);
+      if ([is_connected="abs"]):
+        [output="abs"] = abs ([input="x"]);
+      if ([is_connected="round"]):
+        [output="round"] = round ([input="x"]);
+      if ([is_connected="floor"]):
+        [output="floor"] = math.floor ([input="x"]);
+      if ([is_connected="ceil"]):
+        [output="ceil"] = math.ceil ([input="x"]);
     </code>
   </element>
   <element name="random">
@@ -124,8 +127,11 @@
         <long>Returns a pseudorandom number between 0 and 1.</long>
       </output>
     </outputs>
+    <precode>
+      import random
+    </precode>
     <code>
-      [output="random"] = Math.random ();
+      [output="random"] = random.random ();
     </code>
   </element>
   <element name="trig">
@@ -172,23 +178,26 @@
         <long>Converts radians to degrees.</long>
       </output>
     </outputs>
+    <precode>
+      import math
+    </precode>
     <code>
-      if ([is_connected="sin"])
-        [output="sin"] = Math.sin([input="x"]);
-      if ([is_connected="cos"])
-        [output="cos"] = Math.cos([input="x"]);
-      if ([is_connected="tan"])
-        [output="tan"] = Math.tan([input="x"]);
-      if ([is_connected="asin"])
-        [output="asin"] = Math.asin([input="x"]);
-      if ([is_connected="acos"])
-        [output="acos"] = Math.acos([input="x"]);
-      if ([is_connected="atan"])
-        [output="atan"] = Math.atan([input="x"]);
-      if ([is_connected="deg2rad"])
-        [output="deg2rad"] = [input="x"] * (Math.PI / 180.0);
-      if ([is_connected="rad2deg"])
-        [output="rad2deg"] = [input="x"] * (180.0 / Math.PI);
+      if ([is_connected="sin"]):
+        [output="sin"] = math.sin([input="x"]);
+      if ([is_connected="cos"]):
+        [output="cos"] = math.cos([input="x"]);
+      if ([is_connected="tan"]):
+        [output="tan"] = math.tan([input="x"]);
+      if ([is_connected="asin"]):
+        [output="asin"] = math.asin([input="x"]);
+      if ([is_connected="acos"]):
+        [output="acos"] = math.acos([input="x"]);
+      if ([is_connected="atan"]):
+        [output="atan"] = math.atan([input="x"]);
+      if ([is_connected="deg2rad"]):
+        [output="deg2rad"] = [input="x"] * (math.pi / 180.0);
+      if ([is_connected="rad2deg"]):
+        [output="rad2deg"] = [input="x"] * (180.0 / math.pi);
     </code>
   </element>
   <element name="logarithm">
@@ -211,11 +220,14 @@
       </output>
 
     </outputs>
+    <precode>
+      import math
+    </precode>
     <code>
-      if ([is_connected="ln"])
-        [output="ln"] = Math.log([input="x"]);
-      if ([is_connected="exp"])
-        [output="exp"] = Math.exp([input="x"]);
+      if ([is_connected="ln"]):
+        [output="ln"] = math.log([input="x"]);
+      if ([is_connected="exp"]):
+        [output="exp"] = math.exp([input="x"]);
     </code>
   </element>
   
@@ -278,15 +290,27 @@
         <long>Square root of 2.</long>
       </output>
     </outputs>
+    <precode>
+      import math
+      MathConstants = {}
+      MathConstants["SQRT2"] = math.sqrt(2)
+      MathConstants["SQRT1_2"] = math.sqrt(0.5)
+      MathConstants["PI"] = math.pi
+      MathConstants["LOG10E"] = math.log10(math.e)
+      MathConstants["LOG2E"] = math.log2(math.e)
+      MathConstants["LN10"] = math.log(10)
+      MathConstants["LN2"] = math.log(2)
+      MathConstants["E"] = math.e
+    </precode>
     <code>
-      [output="e"] = Math.E;
-      [output="ln2"] = Math.LN2;
-      [output="ln10"] = Math.LN10;
-      [output="log2E"] = Math.LOG2E;
-      [output="log10E"] = Math.LOG10E;
-      [output="pi"] = Math.PI;
-      [output="sqrt1_2"] = Math.SQRT1_2;
-      [output="sqrt2"] = Math.SQRT2;
+      [output="e"] = MathConstants["E"];
+      [output="ln2"] = MathConstants["LN2"];
+      [output="ln10"] = MathConstants["LN10"];
+      [output="log2E"] = MathConstants["LOG2E"];
+      [output="log10E"] = MathConstants["LOG10E"];
+      [output="pi"] = MathConstants["PI"];
+      [output="sqrt1_2"] = MathConstants["SQRT1_2"];
+      [output="sqrt2"] = MathConstants["SQRT2"];
     </code>
   </element>
 
@@ -305,8 +329,8 @@
       </output>
     </outputs>
     <code>
-      [output="out_true"]  = true;
-      [output="out_false"] = false;
+      [output="out_true"]  = True;
+      [output="out_false"] = False;
     </code>
   </element>
 
diff --git a/VsiMetadata/meshselection.xml b/VsiMetadata/meshselection.xml
index 615e39a..d34bd6c 100644
--- a/VsiMetadata/meshselection.xml
+++ b/VsiMetadata/meshselection.xml
@@ -12,7 +12,7 @@
       <input name="deselect" type="Bool" external="true" runtime="true">
           <short>Deselect original Selection</short>
           <long>Deselect the original selection or keep it intact</long>
-          <default>true</default>
+          <default>True</default>
       </input>
       <input name="input_selection" type="Selection" external="false" runtime="true">
           <short>Input selection</short>
diff --git a/VsiMetadata/object.xml b/VsiMetadata/object.xml
index b52d087..b7ba1bd 100644
--- a/VsiMetadata/object.xml
+++ b/VsiMetadata/object.xml
@@ -35,11 +35,11 @@
       </function>
     </functions>
     <code>
-      var types = [input="types"].split(",");
-      if ([is_set="custom_type"])
+      types = [input="types"].split(",");
+      if ([is_set="custom_type"]):
         types = types.concat([input="custom_type"]);
-      var ids = core.objectList ([input="selection"], types);
-      for (var i in ids)
+      ids = core.objectList ([input="selection"], types);
+      for (var i in ids):
         [function="content"] (ids[i]);
     </code>
   </element>
diff --git a/VsiMetadata/tests.xml b/VsiMetadata/tests.xml
index 5107445..09a869d 100644
--- a/VsiMetadata/tests.xml
+++ b/VsiMetadata/tests.xml
@@ -27,13 +27,13 @@
       </output>
     </outputs>
     <code>
-      if ([is_connected="bigger"])
+      if ([is_connected="bigger"]):
         [output="bigger"] = [input="a"] > [input="b"];
-      if ([is_connected="biggerorequal"])
+      if ([is_connected="biggerorequal"]):
         [output="biggerorequal"] = [input="a"] >= [input="b"];
-      if ([is_connected="equal"])
+      if ([is_connected="equal"]):
         [output="equal"] = [input="a"] == [input="b"];
-      if ([is_connected="notequal"])
+      if ([is_connected="notequal"]):
         [output="notequal"] = [input="a"] != [input="b"];
     </code>
   </element>
@@ -52,7 +52,7 @@
       </output>
     </outputs>
     <code>
-      [output="nota"] = !([input="a"]);
+      [output="nota"] = not ([input="a"]);
     </code>
    </element>
 
@@ -76,10 +76,10 @@
       </output>
     </outputs>
     <code>
-      if ([is_connected="and"])
-        [output="and"] = [input="a"] &amp;&amp; [input="b"];
-      if ([is_connected="or"])
-        [output="or"] = [input="a"] || [input="b"];
+      if ([is_connected="and"]):
+        [output="and"] = [input="a"] and [input="b"];
+      if ([is_connected="or"]):
+        [output="or"] = [input="a"] or [input="b"];
     </code>
   </element>
 
-- 
GitLab


From 7e95744f10f6555869c09f6bf5f2fdb5cf1e0668 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 23 Feb 2021 11:20:37 +0100
Subject: [PATCH 03/12] Python indentation for template blocks

---
 parser/context.cc | 58 +++++++++++++++++++++++++++++++++++++++++++++--
 parser/context.hh |  3 +++
 2 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/parser/context.cc b/parser/context.cc
index cb832c0..0b7dfae 100644
--- a/parser/context.cc
+++ b/parser/context.cc
@@ -316,8 +316,8 @@ void Context::parseElement (QXmlQuery &_xml)
   e->code_ = getXmlString (_xml, "code/string(text())", "");
 
   // remove spaces at line begin
-  e->precode_ = e->precode_.replace (QRegExp ("\\n\\s*"),"\n");
-  e->code_ = e->code_.replace (QRegExp ("\\n\\s*"),"\n");
+  e->precode_ = removeCommonTrailingSpaces(e->precode_);
+  e->code_ = removeCommonTrailingSpaces(e->code_);
 
 }
 
@@ -596,4 +596,58 @@ Type * Context::getType(QString _type)
 
 //------------------------------------------------------------------------------
 
+/// Removes trailing spaces from string which are present in each line - relative trailing spaces are not removed
+//      test
+//        abcd
+//      qwertz
+// is transformed to
+// test
+//  abcd
+// qwertz
+QString Context::removeCommonTrailingSpaces(QString in) {
+    QStringList lines = in.split("\n");
+
+    const int INF = 1e6;
+    int commonTrailingSpaces = INF;
+
+    for (int line=0;line<lines.length();line++) {
+        int lenWithoutTrailingSpaces = QString(lines[line]).replace(QRegExp ("^\\s*"), "").length();
+
+        if (lenWithoutTrailingSpaces > 0) {
+            // line not empty
+            int trailingSpaces = lines[line].length() - lenWithoutTrailingSpaces;
+
+            if (trailingSpaces < commonTrailingSpaces) {
+                // here are fewer trailing spaces than before discovered
+                commonTrailingSpaces = trailingSpaces;
+            }
+        } else {
+            // line empty
+        }
+    }
+
+    if (commonTrailingSpaces >= INF) {
+        // no content
+        return QString("");
+    } else {
+        QString placeHolder = "";
+
+        for (int line=0;line<lines.length();line++) {
+            int subLength = lines[line].length() - commonTrailingSpaces;
+
+            if (subLength < 0) {
+                // line is empty
+                lines[line] = QString("");
+            } else {
+                // remove common trailing whitespaces
+                QStringRef ref = QStringRef(&lines[line], commonTrailingSpaces, subLength);
+                lines[line] = ref.toString();
+            }
+        }
+
+        QString output = lines.join("\n");
+        return output;
+    }
+}
+
 }
diff --git a/parser/context.hh b/parser/context.hh
index 1907845..470dbb0 100644
--- a/parser/context.hh
+++ b/parser/context.hh
@@ -112,6 +112,9 @@ class Context {
     /// Gets the string of a xml query
     static QString getXmlString (QXmlQuery &_xml, QString _expr, QString _default = "");
 
+    /// Removes trailing spaces from string which are present in each line - relative trailing spaces are not removed
+    static QString removeCommonTrailingSpaces(QString in);
+
   private:
 
     // parse element from xml
-- 
GitLab


From 6a594d6cf7d75c68bb65e7468c395d191304c49f Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 23 Feb 2021 15:13:40 +0100
Subject: [PATCH 04/12] python function identation now working

---
 VsiMetadata/datacontrol.xml     | 10 +++----
 VsiMetadata/loopsConditions.xml |  2 +-
 parser/context.cc               | 15 ++++++++--
 parser/context.hh               |  5 +++-
 scene/graphicsScene.cc          | 51 +++++++++++++--------------------
 vsiPlugin.cc                    |  2 +-
 vsiPlugin.hh                    | 10 +++++--
 7 files changed, 51 insertions(+), 44 deletions(-)

diff --git a/VsiMetadata/datacontrol.xml b/VsiMetadata/datacontrol.xml
index 031967d..4ca78cc 100644
--- a/VsiMetadata/datacontrol.xml
+++ b/VsiMetadata/datacontrol.xml
@@ -55,10 +55,10 @@
       </input>
     </inputs>
     <code>
-	if ([input="visible"])
-            datacontrol.showObject([input="obj"]);
-	else
-            datacontrol.hideObject([input="obj"]);
+      if ([input="visible"]):
+        datacontrol.showObject([input="obj"]);
+      else:
+        datacontrol.hideObject([input="obj"]);
     </code>
   </element>  
   <element name="datacontrol_objectdelete">
@@ -73,7 +73,7 @@
       </input>
     </inputs>
     <code>
-        datacontrol.objectDelete([input="obj"]);
+      datacontrol.objectDelete([input="obj"]);
     </code>
   </element>
   <element name="datacontrol_objectcopy">
diff --git a/VsiMetadata/loopsConditions.xml b/VsiMetadata/loopsConditions.xml
index 8ea3994..ad07ff4 100644
--- a/VsiMetadata/loopsConditions.xml
+++ b/VsiMetadata/loopsConditions.xml
@@ -18,7 +18,7 @@
       </function>
     </functions>
     <code>
-      while ([function="condition"]().out):
+      while ([function="condition"]()["out"]):
         [function="content"]();
     </code>
   </element>
diff --git a/parser/context.cc b/parser/context.cc
index 0b7dfae..ccc48ee 100644
--- a/parser/context.cc
+++ b/parser/context.cc
@@ -75,8 +75,8 @@ namespace VSI {
 //=============================================================================
 
 /// Constructor
-Context::Context (QScriptEngine *_engine) :
-  scriptEngine_ (_engine)
+Context::Context (QScriptEngine *_engine, LoggingInterface *_loggingInterface) :
+  scriptEngine_ (_engine), loggingInterface_(_loggingInterface)
 {
   // add start element
   Element *e = new Element (this, "start");
@@ -315,6 +315,15 @@ void Context::parseElement (QXmlQuery &_xml)
   e->precode_ = getXmlString (_xml, "precode/string(text())", "");
   e->code_ = getXmlString (_xml, "code/string(text())", "");
 
+  if (e->precode_.contains(QRegExp("^\\s*\\t"))) {
+      // precode contains tab symbol
+      emit loggingInterface_->log(LOGWARN, "Precode block of "+e->name()+" contains tab identation");
+  }
+  if (e->code_.contains(QRegExp("^\\s*\\t"))) {
+      // precode contains tab symbol
+      emit loggingInterface_->log(LOGWARN, "Code block of "+e->name()+" contains tab identation");
+  }
+
   // remove spaces at line begin
   e->precode_ = removeCommonTrailingSpaces(e->precode_);
   e->code_ = removeCommonTrailingSpaces(e->code_);
@@ -518,7 +527,7 @@ Function* Context::parseFunction (QXmlQuery &_xml, Element *_e)
 
     QString endCode = "return { ";
     foreach (Input *i, f->end_->inputs ())
-      endCode += i->name () + " : [input=\"" + i->name () + "\"], ";
+      endCode += "\"" + i->name () + "\" : [input=\"" + i->name () + "\"], ";
     endCode.remove (endCode.length () - 2, 2);
     endCode += " };\n";
 
diff --git a/parser/context.hh b/parser/context.hh
index 470dbb0..ebd2185 100644
--- a/parser/context.hh
+++ b/parser/context.hh
@@ -48,6 +48,7 @@
 #include <QVector>
 #include <QStringList>
 #include <QXmlQuery>
+#include <OpenFlipper/BasePlugin/LoggingInterface.hh>
 
 #include "element.hh"
 
@@ -71,7 +72,7 @@ class Context {
 
   public:
     /// Constructor
-    explicit Context (QScriptEngine *_engine);
+    explicit Context (QScriptEngine *_engine, LoggingInterface *_loggingInterface);
 
     /// Destructor
     ~Context ();
@@ -140,6 +141,8 @@ class Context {
     QList <Type *> types_;
 
     QScriptEngine *scriptEngine_;
+
+    LoggingInterface *loggingInterface_;
 };
 
 //=============================================================================
diff --git a/scene/graphicsScene.cc b/scene/graphicsScene.cc
index 62e01d0..0eda56b 100644
--- a/scene/graphicsScene.cc
+++ b/scene/graphicsScene.cc
@@ -477,7 +477,7 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
     foreach (Element *e, set)
       if (!e->precode ().isEmpty ())
       {
-        rv += "// - ";
+        rv += "# - ";
         rv += e->shortDescription ();
         rv += " -\n";
         rv += e->precode ();
@@ -487,17 +487,17 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
     // add functiond
     if (!functions.isEmpty ())
     {
-      rv += "// ------- FUNCTIONS -----------\n\n";
+      rv += "# ------- FUNCTIONS -----------\n\n";
     }
 
     foreach (ElementFunction *ef, functions)
     {
-      rv += "// - ";
+      rv += "# - ";
       rv += ef->element ()->element ()->shortDescription ();
       rv += " - ";
       rv += ef->function ()->shortDescription ();
       rv += " -\n";
-      rv += "function func_" + ef->element ()->variableId () + "_" + ef->function ()->name ();
+      rv += "def func_" + ef->element ()->variableId () + "_" + ef->function ()->name ();
 
       QString param;
       foreach (Output *o, ef->function ()->start ()->outputs ())
@@ -508,16 +508,22 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
       if (!param.isEmpty ())
         param.remove (param.length () - 2, 2);
 
-      rv += " (" + param + ")\n{\n";
+      rv += " (" + param + "):\n";
 
       QString code = ef->scene ()->generateCode (errors, true);
 
-      rv += code + "}\n\n";
+      // Add identation
+      QString ident("  ");
+      QStringList lines = code.split("\n");
+      for (int l=0;l<lines.length();l++) lines[l] = ident + lines[l];
+      code = lines.join("\n");
+
+      rv += code + "\n\n";
     }
 
     if (!functions.isEmpty ())
     {
-      rv += "// ------- END FUNCTIONS -------\n\n";
+      rv += "# ------- END FUNCTIONS -------\n\n";
     }
   }
 
@@ -554,7 +560,7 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
   if (elements.isEmpty() && end->inputs().isEmpty ())
     end = NULL;
 
-  rv += "// --- CODE BEGIN ---\n\n";
+  rv += "# --- CODE BEGIN ---\n\n";
 
   updateConnections (start, true);
 
@@ -603,7 +609,7 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
     {
       elements.removeAll (found);
 
-      rv += "// - ";
+      rv += "# - ";
       rv += found->element ()->shortDescription ();
       rv += " -\n";
       rv += updateConnections (found, false);
@@ -632,7 +638,7 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
           else
           {
             found->replaceCodeBlock ("is_set", i->inOut ()->name (), "true");
-            found->replaceCodeBlock ("input", i->inOut ()->name (), dName + "." + i->inOut ()->name ());
+            found->replaceCodeBlock ("input", i->inOut ()->name (), dName + "[\"" + i->inOut ()->name ()+"\"]");
             dInputs += i->inOut ()->name () + ",";
           }
         }
@@ -651,8 +657,8 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
       {
         // remove last ,
         dInputs.remove (dInputs.length () - 1, 1);
-        rv += "// Ask user for missing input values\n";
-        rv += "var " + dName + " = visualscripting.askForInputs (\"" + found->element ()->name ();
+        rv += "# Ask user for missing input values\n";
+        rv += "" + dName + " = visualscripting.askForInputs (\"" + found->element ()->name ();
         rv += "\", \"" + dInputs + "\");\n";
       }
 
@@ -661,7 +667,7 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
     }
   }
 
-  rv += "// --- CODE END ---\n";
+  rv += "# --- CODE END ---\n";
 
   if (end)
     elements.append (end);
@@ -736,23 +742,6 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
     return "";
   }
 
-  // indent code
-  if (!_codeOnly)
-  {
-    QStringList code = rv.split ('\n');
-    QString indent = "";
-    rv.clear ();
-
-    foreach (QString s, code)
-    {
-      if (s.contains ('}') && !indent.isEmpty ())
-        indent.remove (indent.length () - 2, 2);
-      rv += indent + s + "\n";
-      if (s.contains ('{'))
-        indent += "  ";
-    }
-  }
-
   return rv;
 }
 
@@ -769,7 +758,7 @@ QString GraphicsScene::updateConnections (SceneElement *_from, bool _isStart)
     if (!_isStart)
     {
       oName = "output_" + _from->variableId() + "_" + o->inOut ()->name ();
-      rv += "var " + oName + "\n";
+      rv += "" + oName + " = None;\n";
 
       _from->replaceCodeBlock ("output", o->inOut ()->name (), oName);
 
diff --git a/vsiPlugin.cc b/vsiPlugin.cc
index 48b49e0..603ab29 100644
--- a/vsiPlugin.cc
+++ b/vsiPlugin.cc
@@ -132,7 +132,7 @@ void VsiPlugin::initContext()
   emit getScriptingEngine (engine);
 
   // empty context
-  context_ = new VSI::Context (engine);
+  context_ = new VSI::Context (engine, this);
 
   // parse all metadata xml files
   QDir dir = OpenFlipper::Options::dataDir ();
diff --git a/vsiPlugin.hh b/vsiPlugin.hh
index 418576e..6b0213c 100644
--- a/vsiPlugin.hh
+++ b/vsiPlugin.hh
@@ -53,6 +53,7 @@
 #include <OpenFlipper/BasePlugin/MenuInterface.hh>
 #include <OpenFlipper/BasePlugin/ScriptInterface.hh>
 #include <OpenFlipper/BasePlugin/RPCInterface.hh>
+#include <OpenFlipper/BasePlugin/LoggingInterface.hh>
 
 #include <QPushButton>
 #include <QHBoxLayout>
@@ -68,13 +69,14 @@ namespace VSI {
 
 /** Plugin that provides a visual scripting interface
 */
-class VsiPlugin : public QObject, BaseInterface, MenuInterface, ScriptInterface, RPCInterface
+class VsiPlugin : public QObject, BaseInterface, MenuInterface, ScriptInterface, RPCInterface, LoggingInterface
 {
   Q_OBJECT
   Q_INTERFACES(BaseInterface)
   Q_INTERFACES(MenuInterface)
   Q_INTERFACES(ScriptInterface)
   Q_INTERFACES(RPCInterface)
+  Q_INTERFACES(LoggingInterface)
 
   Q_PLUGIN_METADATA(IID "org.OpenFlipper.Plugins.Plugin-VSI")
 
@@ -90,7 +92,11 @@ class VsiPlugin : public QObject, BaseInterface, MenuInterface, ScriptInterface,
     void pluginExists (QString _pluginName, bool& _exists) ;
     void functionExists (QString _pluginName, QString _functionName, bool& _exists);
 
-  public:
+    //LoggingInterface
+    void log(Logtype _type, QString _message);
+    void log(QString _message);
+
+public:
 
     /// Constructor
     VsiPlugin ();
-- 
GitLab


From 4d7594675cd28a9d7b5d25d119b1f048112dd333 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 23 Feb 2021 16:29:11 +0100
Subject: [PATCH 05/12] removed qtscript engine and begun integrating pybind

---
 CMakeLists.txt            |  2 +-
 PythonInterface/Python.cc | 83 +++++++++++++++++++++++++++++++++++++++
 baseWidget.cc             |  3 --
 parser/context.cc         |  4 +-
 parser/context.hh         | 10 +----
 scene/graphicsScene.cc    | 16 ++++----
 vsiPlugin.cc              | 39 ++++++------------
 vsiPlugin.hh              | 10 ++---
 8 files changed, 111 insertions(+), 56 deletions(-)
 create mode 100644 PythonInterface/Python.cc

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f99a592..1dc09ea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,2 +1,2 @@
 include (plugin)
-openflipper_plugin (DIRS config parser scene types types/objectId INSTALLDATA Icons VsiMetadata)
+openflipper_plugin (PYTHONINTERFACE DIRS config parser scene types types/objectId INSTALLDATA Icons VsiMetadata)
diff --git a/PythonInterface/Python.cc b/PythonInterface/Python.cc
new file mode 100644
index 0000000..bca6c76
--- /dev/null
+++ b/PythonInterface/Python.cc
@@ -0,0 +1,83 @@
+/*===========================================================================*\
+*                                                                            *
+*                              OpenFlipper                                   *
+ *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
+ *           Department of Computer Graphics and Multimedia                  *
+ *                          All rights reserved.                             *
+ *                            www.openflipper.org                            *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * This file is part of OpenFlipper.                                         *
+ *---------------------------------------------------------------------------*
+ *                                                                           *
+ * Redistribution and use in source and binary forms, with or without        *
+ * modification, are permitted provided that the following conditions        *
+ * are met:                                                                  *
+ *                                                                           *
+ * 1. Redistributions of source code must retain the above copyright notice, *
+ *    this list of conditions and the following disclaimer.                  *
+ *                                                                           *
+ * 2. Redistributions in binary form must reproduce the above copyright      *
+ *    notice, this list of conditions and the following disclaimer in the    *
+ *    documentation and/or other materials provided with the distribution.   *
+ *                                                                           *
+ * 3. Neither the name of the copyright holder nor the names of its          *
+ *    contributors may be used to endorse or promote products derived from   *
+ *    this software without specific prior written permission.               *
+ *                                                                           *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
+*                                                                            *
+\*===========================================================================*/
+
+
+#include <pybind11/include/pybind11/pybind11.h>
+#include <pybind11/include/pybind11/embed.h>
+
+
+#include <vsiPlugin.hh>
+#include <OpenFlipper/BasePlugin/PythonFunctions.hh>
+#include <OpenFlipper/PythonInterpreter/PythonTypeConversions.hh>
+
+namespace py = pybind11;
+
+PYBIND11_EMBEDDED_MODULE(VsiPlugin, m) {
+
+  QObject* pluginPointer = getPluginPointer("VsiPlugin");
+
+  if (!pluginPointer) {
+     std::cerr << "Error Getting plugin pointer for Plugin-VSI" << std::endl;
+     return;
+   }
+
+    VsiPlugin* plugin = qobject_cast<VsiPlugin*>(pluginPointer);
+
+  if (!plugin) {
+    std::cerr << "Error converting plugin pointer for Plugin-VSI" << std::endl;
+    return;
+  }
+
+  // Export our core. Make sure that the c++ worlds core object is not deleted if
+  // the python side gets deleted!!
+  py::class_< VsiPlugin,std::unique_ptr<VsiPlugin, py::nodelete> > vsi(m, "visualscripting");
+
+  // On the c++ side we will just return the existing core instance
+  // and prevent the system to recreate a new core as we need
+  // to work on the existing one.
+  vsi.def(py::init([plugin]() { return plugin; }));
+
+  vsi.def("askForInputs",   &VsiPlugin::askForInputs,
+                                          QCoreApplication::translate("PythonDocVsi","Shows a popup and asks for inputs").toLatin1().data(),
+                                  py::arg(QCoreApplication::translate("PythonDocVsi","Element").toLatin1().data()),
+                                  py::arg(QCoreApplication::translate("PythonDocVsi","Inputs").toLatin1().data()));
+
+}
diff --git a/baseWidget.cc b/baseWidget.cc
index 9a83299..bf677ae 100644
--- a/baseWidget.cc
+++ b/baseWidget.cc
@@ -204,9 +204,6 @@ void BaseWidget::executeCode ()
 
   if (errors.isEmpty ())
   {
-    ctx_->scriptEngine ()->pushContext ();
-    ctx_->scriptEngine ()->evaluate (code);
-    ctx_->scriptEngine ()->popContext ();
     return;
   }
 
diff --git a/parser/context.cc b/parser/context.cc
index ccc48ee..0ca3914 100644
--- a/parser/context.cc
+++ b/parser/context.cc
@@ -75,8 +75,8 @@ namespace VSI {
 //=============================================================================
 
 /// Constructor
-Context::Context (QScriptEngine *_engine, LoggingInterface *_loggingInterface) :
-  scriptEngine_ (_engine), loggingInterface_(_loggingInterface)
+Context::Context (LoggingInterface *_loggingInterface) :
+  loggingInterface_(_loggingInterface)
 {
   // add start element
   Element *e = new Element (this, "start");
diff --git a/parser/context.hh b/parser/context.hh
index ebd2185..a40403e 100644
--- a/parser/context.hh
+++ b/parser/context.hh
@@ -52,9 +52,6 @@
 
 #include "element.hh"
 
-//== FORWARDDECLARATIONS ======================================================
-class QScriptEngine;
-
 //== NAMESPACES ===============================================================
 namespace VSI {
 
@@ -72,7 +69,7 @@ class Context {
 
   public:
     /// Constructor
-    explicit Context (QScriptEngine *_engine, LoggingInterface *_loggingInterface);
+    explicit Context (LoggingInterface *_loggingInterface);
 
     /// Destructor
     ~Context ();
@@ -104,9 +101,6 @@ class Context {
     /// Can the given types be converted to each other
     bool canConvert (QString _type1, QString _type2);
 
-    /// Return script engine pointer
-    QScriptEngine *scriptEngine () { return scriptEngine_; };
-
     /// Converts the given string to bool
     static bool strToBool (QString _str);
 
@@ -140,8 +134,6 @@ class Context {
 
     QList <Type *> types_;
 
-    QScriptEngine *scriptEngine_;
-
     LoggingInterface *loggingInterface_;
 };
 
diff --git a/scene/graphicsScene.cc b/scene/graphicsScene.cc
index 0eda56b..8d35abc 100644
--- a/scene/graphicsScene.cc
+++ b/scene/graphicsScene.cc
@@ -621,23 +621,23 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
       foreach (ElementInput *i, found->inputs ()){
         if (i->isSet ())
         {
-          found->replaceCodeBlock ("is_set", i->inOut ()->name (), "true");
+          found->replaceCodeBlock ("is_set", i->inOut ()->name (), "True");
           found->replaceCodeBlock ("input", i->inOut ()->name (), i->value ());
         }
         else if (!i->connections ().isEmpty ())
         {
-          found->replaceCodeBlock ("is_set", i->inOut ()->name (), "true");
+          found->replaceCodeBlock ("is_set", i->inOut ()->name (), "rue");
         }
         else if (i->connections ().isEmpty ())
         {
           if (i->state () & Input::Optional && !i->isForceAskSet ())
           {
             found->replaceCodeBlock ("input", i->inOut ()->name (), "\"\"");
-            found->replaceCodeBlock ("is_set", i->inOut ()->name (), "false");
+            found->replaceCodeBlock ("is_set", i->inOut ()->name (), "False");
           }
           else
           {
-            found->replaceCodeBlock ("is_set", i->inOut ()->name (), "true");
+            found->replaceCodeBlock ("is_set", i->inOut ()->name (), "True");
             found->replaceCodeBlock ("input", i->inOut ()->name (), dName + "[\"" + i->inOut ()->name ()+"\"]");
             dInputs += i->inOut ()->name () + ",";
           }
@@ -645,9 +645,9 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
 
         // Replace the is_connected block for inputs as well.
         if (i->connections ().isEmpty ())
-          found->replaceCodeBlock ("is_connected", i->inOut ()->name (), "false");
+          found->replaceCodeBlock ("is_connected", i->inOut ()->name (), "False");
         else
-          found->replaceCodeBlock ("is_connected", i->inOut ()->name (), "true");
+          found->replaceCodeBlock ("is_connected", i->inOut ()->name (), "True");
       }
 
       foreach (ElementFunction *ef, found->functions ())
@@ -763,9 +763,9 @@ QString GraphicsScene::updateConnections (SceneElement *_from, bool _isStart)
       _from->replaceCodeBlock ("output", o->inOut ()->name (), oName);
 
       if (o->connections ().isEmpty ())
-        _from->replaceCodeBlock ("is_connected", o->inOut ()->name (), "false");
+        _from->replaceCodeBlock ("is_connected", o->inOut ()->name (), "False");
       else
-        _from->replaceCodeBlock ("is_connected", o->inOut ()->name (), "true");
+        _from->replaceCodeBlock ("is_connected", o->inOut ()->name (), "True");
     }
     else
       oName = o->inOut ()->name ();
diff --git a/vsiPlugin.cc b/vsiPlugin.cc
index 603ab29..eeca779 100644
--- a/vsiPlugin.cc
+++ b/vsiPlugin.cc
@@ -50,7 +50,6 @@
 //== INCLUDES =================================================================
 
 #include <QAction>
-#include <QScriptEngine>
 #include <QMessageBox>
 
 #include <OpenFlipper/BasePlugin/PluginFunctions.hh>
@@ -128,11 +127,8 @@ void VsiPlugin::initContext()
   if (context_)
     return;
 
-  QScriptEngine *engine;
-  emit getScriptingEngine (engine);
-
   // empty context
-  context_ = new VSI::Context (engine, this);
+  context_ = new VSI::Context (this);
 
   // parse all metadata xml files
   QDir dir = OpenFlipper::Options::dataDir ();
@@ -166,14 +162,16 @@ void VsiPlugin::initContext()
 //------------------------------------------------------------------------------
 
 /// Gererates a dialog for the given element inputs
-QScriptValue VsiPlugin::askForInputs(QString _element, QString _inputs)
+py::dict VsiPlugin::askForInputs(QString _element, QString _inputs)
 {
   initContext ();
 
+    py::dict dict;
+
   VSI::Element *e = context_->element (_element);
 
   if (!e)
-    return QScriptValue ();
+    return dict;
 
   QVector<VSI::Input *> inputs;
 
@@ -192,7 +190,7 @@ QScriptValue VsiPlugin::askForInputs(QString _element, QString _inputs)
     }
 
   if (inputs.isEmpty ())
-    return QScriptValue ();
+    return dict;
 
   VSI::DynamicDialog d (inputs);
   d.setWindowTitle (e->shortDescription () + " Input Configuration");
@@ -200,27 +198,12 @@ QScriptValue VsiPlugin::askForInputs(QString _element, QString _inputs)
 
   QMap<QString, QString> results = d.getResults ();
 
-  QString script = "inputs = { ";
-
-#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
-  foreach (QString s, _inputs.split (",", QString::SkipEmptyParts))
-      script += s + ": " + results[s] + ",";
-#else
-  foreach (QString s, _inputs.split (",", Qt::SkipEmptyParts))
-      script += s + ": " + results[s] + ",";
-#endif
-
-  script.remove (script.length () - 1, 1);
-
-  script += "};";
-
-  context_->scriptEngine ()->pushContext ();
-  QScriptValue rv = context_->scriptEngine ()->evaluate (script);
-  context_->scriptEngine ()->globalObject ().setProperty ("inputs", rv);
-  //rv = context_->scriptEngine ()->globalObject ().property ("inputs");
-  context_->scriptEngine ()->popContext ();
+  foreach (QString s, _inputs.split (",", QString::SkipEmptyParts)) {
+      std::vector<char> name(s.begin(), s.end());
+      dict[&name[0]] = results[s];
+  }
 
-  return rv;
+  return dict;
 }
 
 //------------------------------------------------------------------------------
diff --git a/vsiPlugin.hh b/vsiPlugin.hh
index 6b0213c..c3ad1d5 100644
--- a/vsiPlugin.hh
+++ b/vsiPlugin.hh
@@ -46,8 +46,9 @@
 #ifndef VSIPLUGIN_HH
 #define VSIPLUGIN_HH
 
+#include <pybind11/embed.h>
+
 #include <QObject>
-#include <QScriptValue>
 
 #include <OpenFlipper/BasePlugin/BaseInterface.hh>
 #include <OpenFlipper/BasePlugin/MenuInterface.hh>
@@ -65,6 +66,8 @@ namespace VSI {
   class BaseWidget;
 }
 
+namespace py = pybind11;
+
 //== CLASS DEFINITION =========================================================
 
 /** Plugin that provides a visual scripting interface
@@ -85,9 +88,6 @@ class VsiPlugin : public QObject, BaseInterface, MenuInterface, ScriptInterface,
     // MenuInterface
     void getMenubarMenu (QString _name, QMenu *& _menu, bool _create);
 
-    // ScriptInterface
-    void getScriptingEngine (QScriptEngine*& _engine);
-
     // RPC Interface
     void pluginExists (QString _pluginName, bool& _exists) ;
     void functionExists (QString _pluginName, QString _functionName, bool& _exists);
@@ -113,7 +113,7 @@ public:
   public slots:
 
     /// Scripting function, that allows to ask the user for inputs during script execution
-    QScriptValue askForInputs (QString _element, QString _inputs);
+    py::dict askForInputs (QString _element, QString _inputs);
 
     /// Scripting function, that displays a message box
     void messageBox (QString _message);
-- 
GitLab


From 081ad07fd409d6c61bb46e15ac51d687ed7d0f78 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 2 Mar 2021 10:25:41 +0100
Subject: [PATCH 06/12] Changed askForInputs method to return a string

---
 VsiMetadata/math.xml   |  2 +-
 scene/graphicsScene.cc |  4 ++--
 vsiPlugin.cc           | 22 ++++++++++++++--------
 vsiPlugin.hh           |  6 +-----
 4 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/VsiMetadata/math.xml b/VsiMetadata/math.xml
index 889ea17..9788f4b 100644
--- a/VsiMetadata/math.xml
+++ b/VsiMetadata/math.xml
@@ -41,7 +41,7 @@
       if ([is_connected="div"]):
         [output="div"] = [input="a"] / [input="b"];
       if ([is_connected="pow"]):
-        [output="pow"] = pow ([input="a"],[input="b"]);
+        [output="pow"] = pow ([input="a"], [input="b"]);
     </code>
   </element>
   <element name="minmax">
diff --git a/scene/graphicsScene.cc b/scene/graphicsScene.cc
index 8d35abc..b129248 100644
--- a/scene/graphicsScene.cc
+++ b/scene/graphicsScene.cc
@@ -658,8 +658,8 @@ QString GraphicsScene::generateCode (QString &errors, bool _codeOnly)
         // remove last ,
         dInputs.remove (dInputs.length () - 1, 1);
         rv += "# Ask user for missing input values\n";
-        rv += "" + dName + " = visualscripting.askForInputs (\"" + found->element ()->name ();
-        rv += "\", \"" + dInputs + "\");\n";
+        rv += "" + dName + " = eval(visualscripting.askForInputs (\"" + found->element ()->name ();
+        rv += "\", \"" + dInputs + "\"));\n";
       }
 
       rv += found->code ();
diff --git a/vsiPlugin.cc b/vsiPlugin.cc
index eeca779..c88561d 100644
--- a/vsiPlugin.cc
+++ b/vsiPlugin.cc
@@ -162,16 +162,14 @@ void VsiPlugin::initContext()
 //------------------------------------------------------------------------------
 
 /// Gererates a dialog for the given element inputs
-py::dict VsiPlugin::askForInputs(QString _element, QString _inputs)
+QString VsiPlugin::askForInputs(QString _element, QString _inputs)
 {
   initContext ();
 
-    py::dict dict;
-
   VSI::Element *e = context_->element (_element);
 
   if (!e)
-    return dict;
+    return QString("{}");
 
   QVector<VSI::Input *> inputs;
 
@@ -190,7 +188,7 @@ py::dict VsiPlugin::askForInputs(QString _element, QString _inputs)
     }
 
   if (inputs.isEmpty ())
-    return dict;
+    return QString("{}");
 
   VSI::DynamicDialog d (inputs);
   d.setWindowTitle (e->shortDescription () + " Input Configuration");
@@ -198,12 +196,20 @@ py::dict VsiPlugin::askForInputs(QString _element, QString _inputs)
 
   QMap<QString, QString> results = d.getResults ();
 
+  QString result("{");
+
+  bool first = true;
   foreach (QString s, _inputs.split (",", QString::SkipEmptyParts)) {
-      std::vector<char> name(s.begin(), s.end());
-      dict[&name[0]] = results[s];
+      QString value(results[s]);
+      if (first) result += ",";
+      result.replace("\"", "\\\"");
+      result += "\""+s+"\":"+value;
+      first = false;
   }
 
-  return dict;
+  result += "}";
+
+  return result;
 }
 
 //------------------------------------------------------------------------------
diff --git a/vsiPlugin.hh b/vsiPlugin.hh
index c3ad1d5..2a64ab8 100644
--- a/vsiPlugin.hh
+++ b/vsiPlugin.hh
@@ -46,8 +46,6 @@
 #ifndef VSIPLUGIN_HH
 #define VSIPLUGIN_HH
 
-#include <pybind11/embed.h>
-
 #include <QObject>
 
 #include <OpenFlipper/BasePlugin/BaseInterface.hh>
@@ -66,8 +64,6 @@ namespace VSI {
   class BaseWidget;
 }
 
-namespace py = pybind11;
-
 //== CLASS DEFINITION =========================================================
 
 /** Plugin that provides a visual scripting interface
@@ -113,7 +109,7 @@ public:
   public slots:
 
     /// Scripting function, that allows to ask the user for inputs during script execution
-    py::dict askForInputs (QString _element, QString _inputs);
+    QString askForInputs (QString _element, QString _inputs);
 
     /// Scripting function, that displays a message box
     void messageBox (QString _message);
-- 
GitLab


From 145d30d6e5716c1345dead90d7c4191f6e02f0c7 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 2 Mar 2021 12:02:45 +0100
Subject: [PATCH 07/12] Cleaned up cmake file

---
 CMakeLists.txt            | 5 ++++-
 PythonInterface/Python.cc | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1dc09ea..6652c54 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,2 +1,5 @@
 include (plugin)
-openflipper_plugin (PYTHONINTERFACE DIRS config parser scene types types/objectId INSTALLDATA Icons VsiMetadata)
+openflipper_plugin (
+        PYTHONINTERFACE
+        DIRS config parser scene types types/objectId
+        INSTALLDATA Icons VsiMetadata)
diff --git a/PythonInterface/Python.cc b/PythonInterface/Python.cc
index bca6c76..4915b6f 100644
--- a/PythonInterface/Python.cc
+++ b/PythonInterface/Python.cc
@@ -68,7 +68,7 @@ PYBIND11_EMBEDDED_MODULE(VsiPlugin, m) {
 
   // Export our core. Make sure that the c++ worlds core object is not deleted if
   // the python side gets deleted!!
-  py::class_< VsiPlugin,std::unique_ptr<VsiPlugin, py::nodelete> > vsi(m, "visualscripting");
+  py::class_< VsiPlugin,std::unique_ptr<VsiPlugin, py::nodelete> > vsi(m, "VsiPlugin");
 
   // On the c++ side we will just return the existing core instance
   // and prevent the system to recreate a new core as we need
-- 
GitLab


From 888e35931efdf57706e6582ff2afa0de1dbba7cd Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 9 Mar 2021 11:33:29 +0100
Subject: [PATCH 08/12] Python Interface now working

---
 CMakeLists.txt            | 7 +++----
 PythonInterface/Python.cc | 7 ++++---
 vsiPlugin.cc              | 2 +-
 vsiPlugin.hh              | 8 ++++----
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6652c54..b8224ff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,4 @@
 include (plugin)
-openflipper_plugin (
-        PYTHONINTERFACE
-        DIRS config parser scene types types/objectId
-        INSTALLDATA Icons VsiMetadata)
+openflipper_plugin (PYTHONINTERFACE
+                    DIRS config parser scene types types/objectId
+                    INSTALLDATA Icons VsiMetadata)
diff --git a/PythonInterface/Python.cc b/PythonInterface/Python.cc
index 4915b6f..e104bef 100644
--- a/PythonInterface/Python.cc
+++ b/PythonInterface/Python.cc
@@ -50,9 +50,9 @@
 
 namespace py = pybind11;
 
-PYBIND11_EMBEDDED_MODULE(VsiPlugin, m) {
+PYBIND11_EMBEDDED_MODULE(VisualScripting, m) {
 
-  QObject* pluginPointer = getPluginPointer("VsiPlugin");
+  QObject* pluginPointer = getPluginPointer("VisualScripting");
 
   if (!pluginPointer) {
      std::cerr << "Error Getting plugin pointer for Plugin-VSI" << std::endl;
@@ -68,7 +68,8 @@ PYBIND11_EMBEDDED_MODULE(VsiPlugin, m) {
 
   // Export our core. Make sure that the c++ worlds core object is not deleted if
   // the python side gets deleted!!
-  py::class_< VsiPlugin,std::unique_ptr<VsiPlugin, py::nodelete> > vsi(m, "VsiPlugin");
+
+  py::class_< VsiPlugin,std::unique_ptr<VsiPlugin, py::nodelete> > vsi(m, "VisualScripting");
 
   // On the c++ side we will just return the existing core instance
   // and prevent the system to recreate a new core as we need
diff --git a/vsiPlugin.cc b/vsiPlugin.cc
index c88561d..9bef416 100644
--- a/vsiPlugin.cc
+++ b/vsiPlugin.cc
@@ -201,7 +201,7 @@ QString VsiPlugin::askForInputs(QString _element, QString _inputs)
   bool first = true;
   foreach (QString s, _inputs.split (",", QString::SkipEmptyParts)) {
       QString value(results[s]);
-      if (first) result += ",";
+      if (!first) result += ",";
       result.replace("\"", "\\\"");
       result += "\""+s+"\":"+value;
       first = false;
diff --git a/vsiPlugin.hh b/vsiPlugin.hh
index 2a64ab8..22bdcf8 100644
--- a/vsiPlugin.hh
+++ b/vsiPlugin.hh
@@ -50,7 +50,7 @@
 
 #include <OpenFlipper/BasePlugin/BaseInterface.hh>
 #include <OpenFlipper/BasePlugin/MenuInterface.hh>
-#include <OpenFlipper/BasePlugin/ScriptInterface.hh>
+#include <OpenFlipper/BasePlugin/PythonInterface.hh>
 #include <OpenFlipper/BasePlugin/RPCInterface.hh>
 #include <OpenFlipper/BasePlugin/LoggingInterface.hh>
 
@@ -68,14 +68,14 @@ namespace VSI {
 
 /** Plugin that provides a visual scripting interface
 */
-class VsiPlugin : public QObject, BaseInterface, MenuInterface, ScriptInterface, RPCInterface, LoggingInterface
+class VsiPlugin : public QObject, BaseInterface, MenuInterface, RPCInterface, LoggingInterface, PythonInterface
 {
   Q_OBJECT
   Q_INTERFACES(BaseInterface)
   Q_INTERFACES(MenuInterface)
-  Q_INTERFACES(ScriptInterface)
   Q_INTERFACES(RPCInterface)
   Q_INTERFACES(LoggingInterface)
+  Q_INTERFACES(PythonInterface)
 
   Q_PLUGIN_METADATA(IID "org.OpenFlipper.Plugins.Plugin-VSI")
 
@@ -101,7 +101,7 @@ public:
     ~VsiPlugin ();
 
     /// Name of the Plugin
-    QString name () { return QString ("Visual Scripting"); };
+    QString name () { return QString ("VisualScripting"); };
 
     /// Description of the Plugin
     QString description () { return QString ("Visual Scripting interface for OpenFlipper"); };
-- 
GitLab


From edf5c6af688ac7422283b08aca3f9da60d900226 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 9 Mar 2021 14:40:15 +0100
Subject: [PATCH 09/12] Added python interface functions

---
 baseWidget.cc     |  1 +
 parser/context.cc | 12 ++++++++++--
 parser/context.hh | 12 ++++++++++--
 vsiPlugin.cc      |  7 +++++--
 vsiPlugin.hh      |  6 +++++-
 5 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/baseWidget.cc b/baseWidget.cc
index bf677ae..52ef8f6 100644
--- a/baseWidget.cc
+++ b/baseWidget.cc
@@ -204,6 +204,7 @@ void BaseWidget::executeCode ()
 
   if (errors.isEmpty ())
   {
+    ctx_->executeScript(code);
     return;
   }
 
diff --git a/parser/context.cc b/parser/context.cc
index 0ca3914..aba76ce 100644
--- a/parser/context.cc
+++ b/parser/context.cc
@@ -75,8 +75,8 @@ namespace VSI {
 //=============================================================================
 
 /// Constructor
-Context::Context (LoggingInterface *_loggingInterface) :
-  loggingInterface_(_loggingInterface)
+Context::Context (LoggingInterface *_loggingInterface, PythonInterface *_pythonInterface) :
+  loggingInterface_(_loggingInterface), pythonInterface_(_pythonInterface)
 {
   // add start element
   Element *e = new Element (this, "start");
@@ -659,4 +659,12 @@ QString Context::removeCommonTrailingSpaces(QString in) {
     }
 }
 
+void Context::executeScript(QString _script) {
+    emit pythonInterface_->executePythonScript(_script);
+}
+
+void Context::openScriptInEditor(QString _script) {
+    emit pythonInterface_->openPythonScriptInEditor(_script);
+}
+
 }
diff --git a/parser/context.hh b/parser/context.hh
index a40403e..0c527cd 100644
--- a/parser/context.hh
+++ b/parser/context.hh
@@ -49,6 +49,7 @@
 #include <QStringList>
 #include <QXmlQuery>
 #include <OpenFlipper/BasePlugin/LoggingInterface.hh>
+#include <OpenFlipper/BasePlugin/PythonInterface.hh>
 
 #include "element.hh"
 
@@ -69,7 +70,7 @@ class Context {
 
   public:
     /// Constructor
-    explicit Context (LoggingInterface *_loggingInterface);
+    explicit Context (LoggingInterface *_loggingInterface, PythonInterface *_pythonInterface);
 
     /// Destructor
     ~Context ();
@@ -110,7 +111,13 @@ class Context {
     /// Removes trailing spaces from string which are present in each line - relative trailing spaces are not removed
     static QString removeCommonTrailingSpaces(QString in);
 
-  private:
+    // execute script
+    void executeScript(QString _script);
+
+    // open script
+    void openScriptInEditor(QString _script);
+
+private:
 
     // parse element from xml
     void parseElement (QXmlQuery &_xml);
@@ -135,6 +142,7 @@ class Context {
     QList <Type *> types_;
 
     LoggingInterface *loggingInterface_;
+    PythonInterface *pythonInterface_;
 };
 
 //=============================================================================
diff --git a/vsiPlugin.cc b/vsiPlugin.cc
index 9bef416..01c44f8 100644
--- a/vsiPlugin.cc
+++ b/vsiPlugin.cc
@@ -128,7 +128,7 @@ void VsiPlugin::initContext()
     return;
 
   // empty context
-  context_ = new VSI::Context (this);
+  context_ = new VSI::Context (this, this);
 
   // parse all metadata xml files
   QDir dir = OpenFlipper::Options::dataDir ();
@@ -217,6 +217,9 @@ QString VsiPlugin::askForInputs(QString _element, QString _inputs)
 /// shows the given script in the textual script editor
 void VsiPlugin::showInScriptEditor(QString _script)
 {
+  emit openPythonScriptInEditor(_script);
+
+  /*
   bool ok;
 
   emit functionExists ("scripting", "showScriptInEditor(QString)", ok);
@@ -224,7 +227,7 @@ void VsiPlugin::showInScriptEditor(QString _script)
   if (!ok)
     return;
 
-  RPC::callFunction ("scripting", "showScriptInEditor", _script);
+  RPC::callFunction ("scripting", "showScriptInEditor", _script);*/
 }
 
 //------------------------------------------------------------------------------
diff --git a/vsiPlugin.hh b/vsiPlugin.hh
index 22bdcf8..2b98e01 100644
--- a/vsiPlugin.hh
+++ b/vsiPlugin.hh
@@ -88,10 +88,14 @@ class VsiPlugin : public QObject, BaseInterface, MenuInterface, RPCInterface, Lo
     void pluginExists (QString _pluginName, bool& _exists) ;
     void functionExists (QString _pluginName, QString _functionName, bool& _exists);
 
-    //LoggingInterface
+    // LoggingInterface
     void log(Logtype _type, QString _message);
     void log(QString _message);
 
+    // Python Interface
+    void executePythonScript(QString _script);
+    void openPythonScriptInEditor(QString _script);
+
 public:
 
     /// Constructor
-- 
GitLab


From 7d210dbdf91f4ed325d3f6ddc7377ed095f11072 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 16 Mar 2021 12:30:58 +0100
Subject: [PATCH 10/12] Changed math vector types to python arrays

---
 VsiMetadata/math.xml     |  4 ++--
 types/boolWidget.cc      |  2 +-
 types/matrix4x4Widget.cc | 44 ++++++++++++++++++++++++++++------------
 types/vec3dWidget.cc     | 10 ++++-----
 types/vec4dWidget.cc     | 10 ++++-----
 vsiPlugin.cc             |  2 +-
 6 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/VsiMetadata/math.xml b/VsiMetadata/math.xml
index 9788f4b..d504852 100644
--- a/VsiMetadata/math.xml
+++ b/VsiMetadata/math.xml
@@ -359,7 +359,7 @@
       </input>
     </inputs>
     <code>
-      [output="out_vec"]  = Vector([input="x"],[input="y"],[input="z"]);
+      [output="out_vec"]  = [[input="x"],[input="y"],[input="z"]];
     </code>
   </element>
 
@@ -392,7 +392,7 @@
       </input>
     </inputs>
     <code>
-      [output="out_vec"]  = Vector4([input="x"],[input="y"],[input="z"],[input="w"]);
+      [output="out_vec"]  = [[input="x"],[input="y"],[input="z"],[input="w"]];
     </code>
   </element>
 
diff --git a/types/boolWidget.cc b/types/boolWidget.cc
index b1622a2..a6cc862 100644
--- a/types/boolWidget.cc
+++ b/types/boolWidget.cc
@@ -95,7 +95,7 @@ BoolWidget::~BoolWidget()
 /// Convert current value to string
 QString BoolWidget::toValue()
 {
-  return (true_->isChecked()) ? "true" : "false";
+  return (true_->isChecked()) ? "True" : "False";
 }
 
 //------------------------------------------------------------------------------
diff --git a/types/matrix4x4Widget.cc b/types/matrix4x4Widget.cc
index 72a009c..21bae5c 100644
--- a/types/matrix4x4Widget.cc
+++ b/types/matrix4x4Widget.cc
@@ -126,12 +126,17 @@ Matrix4x4Widget::~ Matrix4x4Widget()
 /// Convert current value to string
 QString Matrix4x4Widget::toValue()
 {
-  QString rv = "Matrix4x4 (";
-  for (int i = 0; i < 16; i++)
-    rv += QString::number (current_[i]) + ",";
-
-  rv.remove (rv.length () - 1, 1);
-  rv += ")";
+  QString rv = "[";
+  for (int y = 0; y < 4; y++) {
+      rv += "[";
+      for (int x = 0; x < 4; x++) {
+          rv += QString::number (current_[x+y*4]);
+          if (x < 3) rv += ",";
+      }
+      rv += "]";
+      if (y < 3) rv += ", ";
+  }
+  rv += "]";
   return rv;
 }
 
@@ -140,20 +145,33 @@ QString Matrix4x4Widget::toValue()
 /// Read value from string
 void Matrix4x4Widget::fromValue(QString _from)
 {
-  if (_from.startsWith ("Matrix4x4 ("))
-    _from.remove (0, 11);
-  if (_from.endsWith (")"))
+  if (_from.startsWith ("["))
+    _from.remove (0, 1);
+  if (_from.endsWith ("]"))
     _from.remove (_from.length () - 1, 1);
   
-  QStringList sl = _from.split (',');
+  QStringList ys = _from.split (',');
 
   float v[16];
   bool ok = true;
 
-  if (sl.length () == 16)
+  if (ys.length () == 4)
   {
-    for (int i = 0; i < 16 && ok; i++)
-      v[i] = sl[i].toFloat (&ok);
+    for (int y = 0; y < 4 && ok; y++) {
+        if (ys[y].startsWith ("["))
+            ys[y].remove(0, 1);
+        else ok = false;
+
+        if (ys[y].endsWith("]"))
+            ys[y].remove(ys[y].length() - 1, 1);
+        else ok = false;
+
+        QStringList xs = ys[y].split(",");
+
+        for (int x=0;x<4 && ok ; x++) {
+            v[y*4+x] = xs[x].toFloat(&ok);
+        }
+    }
 
     if (ok)
       for (int i = 0; i < 16; i++)
diff --git a/types/vec3dWidget.cc b/types/vec3dWidget.cc
index 7c04eab..adbc2c5 100644
--- a/types/vec3dWidget.cc
+++ b/types/vec3dWidget.cc
@@ -117,10 +117,10 @@ Vec3DWidget::~ Vec3DWidget()
 /// Convert current value to string
 QString Vec3DWidget::toValue()
 {
-  QString rv = "Vector (";
+  QString rv = "[";
   rv += QString::number (current_[0]) + ",";
   rv += QString::number (current_[1]) + ",";
-  rv += QString::number (current_[2]) + ")";
+  rv += QString::number (current_[2]) + "]";
   return rv;
 }
 
@@ -129,9 +129,9 @@ QString Vec3DWidget::toValue()
 /// Read value from string
 void Vec3DWidget::fromValue(QString _from)
 {
-  if (_from.startsWith ("Vector ("))
-    _from.remove (0, 8);
-  if (_from.endsWith (")"))
+  if (_from.startsWith ("["))
+    _from.remove (0, 1);
+  if (_from.endsWith ("]"))
     _from.remove (_from.length () - 1, 1);
   
   QStringList sl = _from.split (',');
diff --git a/types/vec4dWidget.cc b/types/vec4dWidget.cc
index a39499b..ba4fe0b 100644
--- a/types/vec4dWidget.cc
+++ b/types/vec4dWidget.cc
@@ -118,11 +118,11 @@ Vec4DWidget::~ Vec4DWidget()
 /// Convert current value to string
 QString Vec4DWidget::toValue()
 {
-  QString rv = "Vector4 (";
+  QString rv = "[";
   rv += QString::number (current_[0]) + ",";
   rv += QString::number (current_[1]) + ",";
   rv += QString::number (current_[2]) + ",";
-  rv += QString::number (current_[3]) + ")";
+  rv += QString::number (current_[3]) + "]";
   return rv;
 }
 
@@ -131,9 +131,9 @@ QString Vec4DWidget::toValue()
 /// Read value from string
 void Vec4DWidget::fromValue(QString _from)
 {
-  if (_from.startsWith ("Vector4 ("))
-    _from.remove (0, 8);
-  if (_from.endsWith (")"))
+  if (_from.startsWith ("["))
+    _from.remove (0, 1);
+  if (_from.endsWith ("]"))
     _from.remove (_from.length () - 1, 1);
   
   QStringList sl = _from.split (',');
diff --git a/vsiPlugin.cc b/vsiPlugin.cc
index 01c44f8..c86172b 100644
--- a/vsiPlugin.cc
+++ b/vsiPlugin.cc
@@ -202,7 +202,7 @@ QString VsiPlugin::askForInputs(QString _element, QString _inputs)
   foreach (QString s, _inputs.split (",", QString::SkipEmptyParts)) {
       QString value(results[s]);
       if (!first) result += ",";
-      result.replace("\"", "\\\"");
+      value.replace("\"", "\\\"");
       result += "\""+s+"\":"+value;
       first = false;
   }
-- 
GitLab


From d94305f0e746bf4df3ba418f1380a45a6b540132 Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 16 Mar 2021 12:48:28 +0100
Subject: [PATCH 11/12] fixed matrix 4x4 data type for python

---
 types/matrix4x4Widget.cc | 38 ++++++++++----------------------------
 1 file changed, 10 insertions(+), 28 deletions(-)

diff --git a/types/matrix4x4Widget.cc b/types/matrix4x4Widget.cc
index 21bae5c..f5ac047 100644
--- a/types/matrix4x4Widget.cc
+++ b/types/matrix4x4Widget.cc
@@ -1,6 +1,6 @@
 /*===========================================================================*\
-*                                                                            *
-*                              OpenFlipper                                   *
+ *                                                                           *
+ *                             OpenFlipper                                   *
  *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
  *           Department of Computer Graphics and Multimedia                  *
  *                          All rights reserved.                             *
@@ -127,15 +127,10 @@ Matrix4x4Widget::~ Matrix4x4Widget()
 QString Matrix4x4Widget::toValue()
 {
   QString rv = "[";
-  for (int y = 0; y < 4; y++) {
-      rv += "[";
-      for (int x = 0; x < 4; x++) {
-          rv += QString::number (current_[x+y*4]);
-          if (x < 3) rv += ",";
-      }
-      rv += "]";
-      if (y < 3) rv += ", ";
-  }
+  for (int i = 0; i < 16; i++)
+    rv += QString::number (current_[i]) + ",";
+
+  rv.remove (rv.length () - 1, 1);
   rv += "]";
   return rv;
 }
@@ -150,28 +145,15 @@ void Matrix4x4Widget::fromValue(QString _from)
   if (_from.endsWith ("]"))
     _from.remove (_from.length () - 1, 1);
   
-  QStringList ys = _from.split (',');
+  QStringList sl = _from.split (',');
 
   float v[16];
   bool ok = true;
 
-  if (ys.length () == 4)
+  if (sl.length () == 16)
   {
-    for (int y = 0; y < 4 && ok; y++) {
-        if (ys[y].startsWith ("["))
-            ys[y].remove(0, 1);
-        else ok = false;
-
-        if (ys[y].endsWith("]"))
-            ys[y].remove(ys[y].length() - 1, 1);
-        else ok = false;
-
-        QStringList xs = ys[y].split(",");
-
-        for (int x=0;x<4 && ok ; x++) {
-            v[y*4+x] = xs[x].toFloat(&ok);
-        }
-    }
+    for (int i = 0; i < 16 && ok; i++)
+      v[i] = sl[i].toFloat (&ok);
 
     if (ok)
       for (int i = 0; i < 16; i++)
-- 
GitLab


From d2a5d594708b692e34951287ae48c23059120d0a Mon Sep 17 00:00:00 2001
From: Johannes Lenzen <johannes.lenzen@rwth-aachen.de>
Date: Tue, 16 Mar 2021 14:39:03 +0100
Subject: [PATCH 12/12] Message box now working

---
 PythonInterface/Python.cc | 20 ++++++++++++++++----
 VsiMetadata/decimater.xml | 29 +++++++++++++++--------------
 VsiMetadata/dialogs.xml   | 12 ++++++------
 VsiMetadata/print.xml     | 15 ---------------
 vsiPlugin.cc              |  2 +-
 5 files changed, 38 insertions(+), 40 deletions(-)

diff --git a/PythonInterface/Python.cc b/PythonInterface/Python.cc
index e104bef..43bffc3 100644
--- a/PythonInterface/Python.cc
+++ b/PythonInterface/Python.cc
@@ -76,9 +76,21 @@ PYBIND11_EMBEDDED_MODULE(VisualScripting, m) {
   // to work on the existing one.
   vsi.def(py::init([plugin]() { return plugin; }));
 
-  vsi.def("askForInputs",   &VsiPlugin::askForInputs,
-                                          QCoreApplication::translate("PythonDocVsi","Shows a popup and asks for inputs").toLatin1().data(),
-                                  py::arg(QCoreApplication::translate("PythonDocVsi","Element").toLatin1().data()),
-                                  py::arg(QCoreApplication::translate("PythonDocVsi","Inputs").toLatin1().data()));
+    vsi.def("askForInputs",   &VsiPlugin::askForInputs,
+            QCoreApplication::translate("PythonDocVsi","Shows a popup and asks for inputs").toLatin1().data(),
+            py::arg(QCoreApplication::translate("PythonDocVsi","Element").toLatin1().data()),
+            py::arg(QCoreApplication::translate("PythonDocVsi","Inputs").toLatin1().data()));
+
+    vsi.def("messageBox",   &VsiPlugin::messageBox,
+            QCoreApplication::translate("PythonDocVsi","Shows a popup with text").toLatin1().data(),
+            py::arg(QCoreApplication::translate("PythonDocVsi","text to display").toLatin1().data()));
+
+    vsi.def("questionBox",   &VsiPlugin::questionBox,
+            QCoreApplication::translate("PythonDocVsi","Shows a question box with text").toLatin1().data(),
+            py::arg(QCoreApplication::translate("PythonDocVsi","text to display").toLatin1().data()));
+
+    vsi.def("continueBox",   &VsiPlugin::continueBox,
+            QCoreApplication::translate("PythonDocVsi","Shows a continue box with text").toLatin1().data(),
+            py::arg(QCoreApplication::translate("PythonDocVsi","text to display").toLatin1().data()));
 
 }
diff --git a/VsiMetadata/decimater.xml b/VsiMetadata/decimater.xml
index 671d471..ba45e3d 100644
--- a/VsiMetadata/decimater.xml
+++ b/VsiMetadata/decimater.xml
@@ -80,32 +80,33 @@
       </input>
     </inputs>
     <code>
-      decimater_constraints = {};
+      decimater_constraints = "";
       if ([is_set="decimation_order"]):
-        decimater_constraints["decimation_order"] = [input="decimation_order"];
+        decimater_constraints = decimater_constraints + ";decimater_order=" + str([input="decimation_order"]);
       if ([is_set="decimater_type"]):
-        decimater_constraints["decimater_type"] = [input="decimater_type"];
+        decimater_constraints = decimater_constraints + ";decimater_type=" + str([input="decimater_type"]);
       if ([is_set="random_samples"]):
-        decimater_constraints["random_samples"] = [input="random_samples"];
+        decimater_constraints = decimater_constraints + ";random_samples=" + str([input="random_samples"]);
       if ([is_set="incremental_percentage"]):
-        decimater_constraints["incremental_percentage"] = [input="incremental_percentage"];
+        decimater_constraints = decimater_constraints + ";incremental_percentage=" + str([input="incremental_percentage"]);
       if ([is_set="vertices"]):
-        decimater_constraints["vertices"] = [input="vertices"];
+        decimater_constraints = decimater_constraints + ";vertices=" + str([input="vertices"]);
       if ([is_set="triangles"]):
-        decimater_constraints["triangles"] = [input="triangles"];
+        decimater_constraints = decimater_constraints + ";triangles=" + str([input="triangles"]);
       if ([is_set="distance"]):
-        decimater_constraints["distance"] = [input="distance"];
+        decimater_constraints = decimater_constraints + ";distance=" + str([input="distance"]);
       if ([is_set="edge_length"]):
-        decimater_constraints["edge_length"] = [input="edge_length"];
+        decimater_constraints = decimater_constraints + ";edge_length=" + str([input="edge_length"]);
       if ([is_set="normal_deviation"]):
-        decimater_constraints["normal_deviation"] = [input="normal_deviation"];
+        decimater_constraints = decimater_constraints + ";normal_deviation=" + str([input="normal_deviation"]);
       if ([is_set="roundness"]):
-        decimater_constraints["roundness"] = [input="roundness"];
+        decimater_constraints = decimater_constraints + ";roundness=" + str([input="roundness"]);
       if ([is_set="aspect_ratio"]):
-        decimater_constraints["aspect_ratio"] = [input="aspect_ratio"];
+        decimater_constraints = decimater_constraints + ";aspect_ratio=" + str([input="aspect_ratio"]);
       if ([is_set="independent_sets"]):
-        decimater_constraints["independent_sets"] = [input="independent_sets"];
-      decimater.decimate ([input="obj"],decimater_constraints);
+        decimater_constraints = decimater_constraints + ";independent_sets=" + str([input="independent_sets"]);
+
+      decimater.decimate ([input="obj"],decimater_constraints[1:]);
     </code>
   </element>
 </OpenFlipper>
\ No newline at end of file
diff --git a/VsiMetadata/dialogs.xml b/VsiMetadata/dialogs.xml
index ee8f937..ddf3818 100644
--- a/VsiMetadata/dialogs.xml
+++ b/VsiMetadata/dialogs.xml
@@ -27,9 +27,9 @@
     <code>
       message = [input="message"];
 
-      message = message.replace("$1", [input="in1"]);
-      message = message.replace("$2", [input="in2"]);
-      message = message.replace("$3", [input="in3"]);
+      message = message.replace("$1", str([input="in1"]));
+      message = message.replace("$2", str([input="in2"]));
+      message = message.replace("$3", str([input="in3"]));
 
       visualscripting.messageBox (message);
     </code>
@@ -91,9 +91,9 @@
     <code>
       message = [input="message"];
 
-      message = message.replace("$1", [input="in1"]);
-      message = message.replace("$2", [input="in2"]);
-      message = message.replace("$3", [input="in3"]);
+      message = message.replace("$1", str([input="in1"]));
+      message = message.replace("$2", str([input="in2"]));
+      message = message.replace("$3", str([input="in3"]));
 
       [output="ret"] = visualscripting.questionBox (message);
     </code>
diff --git a/VsiMetadata/print.xml b/VsiMetadata/print.xml
index 2c5bb81..6e73d6d 100644
--- a/VsiMetadata/print.xml
+++ b/VsiMetadata/print.xml
@@ -10,19 +10,4 @@
       printingplugin.printView();
     </code>
   </element>
-  <element name="printing_println">
-    <category>Misc</category>
-    <short>Console Ouput</short>
-    <long>Print Number to console.</long>
-    <dataflow>true</dataflow>
-    <inputs>
-      <input name="Value" type="Number">
-        <short>Value</short>
-        <precision>0.000001</precision>
-      </input>
-    </inputs>
-    <code>
-      print( [input="Value"] )
-    </code>
-  </element>
 </OpenFlipper>
diff --git a/vsiPlugin.cc b/vsiPlugin.cc
index c86172b..309681d 100644
--- a/vsiPlugin.cc
+++ b/vsiPlugin.cc
@@ -202,7 +202,7 @@ QString VsiPlugin::askForInputs(QString _element, QString _inputs)
   foreach (QString s, _inputs.split (",", QString::SkipEmptyParts)) {
       QString value(results[s]);
       if (!first) result += ",";
-      value.replace("\"", "\\\"");
+      // value.replace("\"", "\\\"");
       result += "\""+s+"\":"+value;
       first = false;
   }
-- 
GitLab