|
|
|
import math |
|
|
|
from evalidate import Expr, EvalException, base_eval_model |
|
|
|
from .categories import * |
|
from .err import on_error |
|
from .shared import hashed_as_strings |
|
|
|
|
|
class DreamCalculation: |
|
NODE_NAME = "Calculation" |
|
ICON = "🖩" |
|
|
|
@classmethod |
|
def INPUT_TYPES(cls): |
|
return { |
|
"required": { |
|
"expression": ("STRING", {"default": "a + b + c - (r * s * t)", "multiline": True}) |
|
}, |
|
"optional": { |
|
"a_int": ("INT", {"default": 0, "multiline": False}), |
|
"b_int": ("INT", {"default": 0, "multiline": False}), |
|
"c_int": ("INT", {"default": 0, "multiline": False}), |
|
"r_float": ("FLOAT", {"default": 0.0, "multiline": False}), |
|
"s_float": ("FLOAT", {"default": 0.0, "multiline": False}), |
|
"t_float": ("FLOAT", {"default": 0.0, "multiline": False}) |
|
} |
|
} |
|
|
|
CATEGORY = NodeCategories.UTILS |
|
RETURN_TYPES = ("FLOAT", "INT") |
|
RETURN_NAMES = ("FLOAT", "INT") |
|
FUNCTION = "result" |
|
|
|
@classmethod |
|
def IS_CHANGED(cls, *values): |
|
return hashed_as_strings(*values) |
|
|
|
def _make_model(self): |
|
funcs = self._make_functions() |
|
m = base_eval_model.clone() |
|
m.nodes.append('Mult') |
|
m.nodes.append('Call') |
|
for funname in funcs.keys(): |
|
m.allowed_functions.append(funname) |
|
return (m, funcs) |
|
|
|
def _make_functions(self): |
|
return { |
|
"round": round, |
|
"float": float, |
|
"int": int, |
|
"abs": abs, |
|
"min": min, |
|
"max": max, |
|
"tan": math.tan, |
|
"tanh": math.tanh, |
|
"sin": math.sin, |
|
"sinh": math.sinh, |
|
"cos": math.cos, |
|
"cosh": math.cosh, |
|
"pow": math.pow, |
|
"sqrt": math.sqrt, |
|
"ceil": math.ceil, |
|
"floor": math.floor, |
|
"pi": math.pi, |
|
"log": math.log, |
|
"log2": math.log2, |
|
"acos": math.acos, |
|
"asin": math.asin, |
|
"acosh": math.acosh, |
|
"asinh": math.asinh, |
|
"atan": math.atan, |
|
"atanh": math.atanh, |
|
"exp": math.exp, |
|
"fmod": math.fmod, |
|
"factorial": math.factorial, |
|
"dist": math.dist, |
|
"atan2": math.atan2, |
|
"log10": math.log10 |
|
} |
|
|
|
def result(self, expression, **values): |
|
model, funcs = self._make_model() |
|
vars = funcs |
|
for key in ("a_int", "b_int", "c_int", "r_float", "s_float", "t_float"): |
|
nm = key.split("_")[0] |
|
v = values.get(key, None) |
|
if v is not None: |
|
vars[nm] = v |
|
try: |
|
data = Expr(expression, model=model).eval(vars) |
|
if isinstance(data, (int, float)): |
|
return float(data), int(round(data)) |
|
else: |
|
return 0.0, 0 |
|
except EvalException as e: |
|
on_error(DreamCalculation, str(e)) |
|
|