Skip to content

Commit

Permalink
Merge pull request #2929 from maitag/main
Browse files Browse the repository at this point in the history
adding a new "MathTerm"-node
  • Loading branch information
luboslenco authored Sep 19, 2023
2 parents 0f1b9ae + 1f434e8 commit 9706d20
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 0 deletions.
127 changes: 127 additions & 0 deletions Sources/armory/logicnode/MathTermNode.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package armory.logicnode;

import haxe.io.Bytes;
import haxe.io.BytesInput;
import haxe.io.BytesOutput;
import armory.logicnode.MathExpressionNode.Formula;
import armory.logicnode.MathExpressionNode.FormulaException;

class MathTermNode extends LogicNode {

public var property0:Bool; // bind param values

public function new(tree: LogicTree) {
super(tree);
}

var simplifyError:String = null;
var derivateError:String = null;
var resultError:String = null;

override function get(from: Int): Dynamic {

var error:String = null;
var errorPos:Int = -1;

var formula:Formula = null;

try {
formula = new Formula(inputs[0].get());
}
catch(e:FormulaException) {
error = e.msg;
errorPos = e.pos;
}

// bind input values to formula parameters
if ((error == null) && (property0 || from == 3)) {
try {
bindValuesToFormulaParams(formula);
}
catch(e:FormulaException) {
error = e.msg;
errorPos = e.pos;
}
}

if (from == 0) { // -------- Formula ----------
return (error == null) ? formula : null;
}
else if (from == 1) { // -------- Simplifyed ----------
var f:Formula = null;
simplifyError = null;
if (error == null) {
try {
f = formula.simplify();
}
catch(e:FormulaException) {
simplifyError = e.msg;
}
}
return f;
}
else if (from == 2) { // -------- Derivate ----------
var f:Formula = null;
derivateError = null;
if (error == null) {
try {
f = formula.derivate( inputs[1].get() );
}
catch(e:FormulaException) {
derivateError = e.msg;
}
}
return f;
}
else if (from == 3) { // -------- Result ----------
var result:Float = 0.0;
resultError = null;
if (error == null) {
try {
result = formula.result;
}
catch(e:FormulaException) {
resultError = e.msg;
}
}
return result;
}
else if (from == 4) { // -------- Error ----------
if (error != null) return error;
else {
var errorMessage:String = "";
if (simplifyError != null) errorMessage += "Simplifyed:" + simplifyError + " ";
if (derivateError != null) errorMessage += "Derivate:" + derivateError + " ";
if (resultError != null) errorMessage += "Result:" + resultError + " ";
return errorMessage;
}
}
else { // -------- Error Position ----------
return errorPos;
}
}

public inline function bindValuesToFormulaParams(formula:Formula) {
var i = 1;
while (i < inputs.length)
{
if (inputs[i+1].get() != null)
{
if (Std.isOfType(inputs[i+1].get(), Float)) {
// trace ("Float param")
formula.bind( (inputs[i+1].get():Float), inputs[i].get() );
}
else if (Std.isOfType(inputs[i+1].get(), String)) {
// trace ("String param")
formula.bind( (inputs[i+1].get():String), inputs[i].get() );
}
else {
// trace ("Formula param")
formula.bind( (inputs[i+1].get():Formula), inputs[i].get() );
}
}
i+=2;
}

}
}
70 changes: 70 additions & 0 deletions blender/arm/logicnode/math/LN_math_term.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from arm.logicnode.arm_nodes import *
import re

class MathTermNode(ArmLogicTreeNode):
"""Formula for symbolic Math"""
bl_idname = 'LNMathTermNode'
bl_label = 'Math Term'
arm_version = 0

num_params: IntProperty(default=2, min=0)

property0: HaxeBoolProperty('property0', name='Resolve params', description='Resolve input param values/subterms for output term/transformations', default=False)

def __init__(self):
super(MathTermNode, self).__init__()
self.register_id()


def arm_init(self, context):

# OUTPUTS:
self.add_output('ArmDynamicSocket', 'Math Term')
self.add_output('ArmDynamicSocket', 'Simplifyed')
self.add_output('ArmDynamicSocket', 'Derivate')
self.add_output('ArmFloatSocket', 'Result')
self.add_output('ArmStringSocket', 'Error')
self.add_output('ArmIntSocket', 'ErrorPos')

# INPUTS:

# HOW to setup a Tooltip here and how to put it above the param-add/remove-buttons into layout ?
self.add_input('ArmStringSocket', 'Math Term', default_value='a+b')

# two default parameters at start
self.add_input('ArmStringSocket', 'Param 0', default_value='a')
self.add_input('ArmDynamicSocket', 'Value / Term 0')

self.add_input('ArmStringSocket', 'Param 1', default_value='b')
self.add_input('ArmDynamicSocket', 'Value / Term 1')

def add_sockets(self):
self.add_input('ArmStringSocket', 'Name ' + str(self.num_params))
#self.add_input('ArmFloatSocket', 'Value ' + str(self.num_params))
self.add_input('ArmDynamicSocket', 'Value / Term ' + str(self.num_params))
self.num_params += 1

def remove_sockets(self):
if self.num_params > 0:
self.inputs.remove(self.inputs.values()[-1])
self.inputs.remove(self.inputs.values()[-1])
self.num_params -= 1

def draw_buttons(self, context, layout):
# Bind values to params Property
layout.prop(self, 'property0')

# Button ADD parameter
row = layout.row(align=True)
column = row.column(align=True)
op = column.operator('arm.node_call_func', text='Add Param', icon='PLUS', emboss=True)
op.node_index = self.get_id_str()
op.callback_name = 'add_sockets'

# Button REMOVE parameter
column = row.column(align=True)
op = column.operator('arm.node_call_func', text='', icon='X', emboss=True)
op.node_index = self.get_id_str()
op.callback_name = 'remove_sockets'
if self.num_params == 0:
column.enabled = False

0 comments on commit 9706d20

Please sign in to comment.