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"] && [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