removed duplicated nodes for vector INT* types

better akashic outputs
parse_param* ANY parse adjustment for all input
This commit is contained in:
Alexander G. Morano
2025-02-24 02:18:24 -05:00
parent 77fab84b8a
commit 6cf6c1861b
6 changed files with 117 additions and 209 deletions
+24 -27
View File
@@ -109,6 +109,29 @@ MARKDOWN = [
"MIDI-FILTER", "STREAM-WRITER"
]
# ==============================================================================
# === TYPE ===
# ==============================================================================
class AnyType(str):
"""AnyType input wildcard trick taken from pythongossss's:
https://github.com/pythongosssss/ComfyUI-Custom-Scripts
"""
def __ne__(self, __value: object) -> bool:
return False
JOV_TYPE_ANY = AnyType("*")
# want to make explicit entries; comfy only looks for single type
JOV_TYPE_NUMBER = "BOOLEAN,FLOAT,INT"
JOV_TYPE_VECTOR = "VEC2,VEC3,VEC4,VEC2INT,VEC3INT,VEC4INT,COORD2D,COORD3D"
JOV_TYPE_NUMERICAL = f"{JOV_TYPE_NUMBER},{JOV_TYPE_VECTOR}"
JOV_TYPE_IMAGE = "IMAGE,MASK"
JOV_TYPE_FULL = f"{JOV_TYPE_NUMBER},{JOV_TYPE_IMAGE}"
JOV_TYPE_FULL = JOV_TYPE_ANY
# ==============================================================================
# === LEXICON ===
# ==============================================================================
@@ -406,12 +429,9 @@ class JOVBaseNode:
NOT_IDEMPOTENT = True
RETURN_TYPES = ()
FUNCTION = "run"
# instance map for caching
INSTANCE = {}
@classmethod
def VALIDATE_INPUTS(cls, *arg, **kw) -> bool:
# logger.debug(f'validate -- {arg} {kw}')
def VALIDATE_INPUTS(cls, input_types) -> bool:
return True
@classmethod
@@ -458,14 +478,6 @@ class DynamicInputType(dict):
def __contains__(self, key: Any) -> Literal[True]:
return True
class AnyType(str):
"""AnyType input wildcard trick taken from pythongossss's:
https://github.com/pythongosssss/ComfyUI-Custom-Scripts
"""
def __ne__(self, __value: object) -> bool:
return False
class DynamicOutputType(tuple):
"""A special class that will return additional "AnyType" strings beyond defined values.
@@ -478,21 +490,6 @@ class DynamicOutputType(tuple):
return AnyType("*")
return super().__getitem__(index)
JOV_TYPE_ANY = AnyType("*")
# want to make explicit entries; comfy only looks for single type
JOV_TYPE_COMFY = "BOOLEAN,FLOAT,INT"
JOV_TYPE_VECTOR = "VEC2,VEC3,VEC4,VEC2INT,VEC3INT,VEC4INT,COORD2D"
JOV_TYPE_NUMBER = f"{JOV_TYPE_COMFY},{JOV_TYPE_VECTOR}"
JOV_TYPE_IMAGE = "IMAGE,MASK"
JOV_TYPE_FULL = f"{JOV_TYPE_NUMBER},{JOV_TYPE_IMAGE}"
JOV_TYPE_COMFY = JOV_TYPE_ANY
JOV_TYPE_VECTOR = JOV_TYPE_ANY
JOV_TYPE_NUMBER = JOV_TYPE_ANY
JOV_TYPE_IMAGE = JOV_TYPE_ANY
JOV_TYPE_FULL = JOV_TYPE_ANY
# ==============================================================================
# === DOCUMENTATION SUPPORT
# ==============================================================================
+74 -159
View File
@@ -3,11 +3,12 @@ Jovimetrix - http://www.github.com/amorano/jovimetrix
Calculation
"""
import struct
import sys
import math
import random
from enum import Enum
from typing import Any, Dict, Tuple
from typing import Any, Dict, List, Tuple
from collections import Counter
import torch
@@ -17,7 +18,7 @@ from loguru import logger
from comfy.utils import ProgressBar
from .. import JOV_TYPE_ANY, JOV_TYPE_FULL, JOV_TYPE_NUMBER, JOV_TYPE_VECTOR, \
from .. import JOV_TYPE_ANY, JOV_TYPE_FULL, JOV_TYPE_NUMBER, JOV_TYPE_NUMERICAL, \
Lexicon, JOVBaseNode, \
comfy_api_post, deep_merge, parse_reset
@@ -31,7 +32,7 @@ from ..sup.anim import EnumWave, EnumEase, ease_op, wave_op
JOV_CATEGORY = "CALC"
# ==============================================================================
# === LAMBDA ===
# === SUPPORT ===
# ==============================================================================
LAMBDA_FLATTEN = lambda data: [item for sublist in data for item in sublist]
@@ -42,6 +43,17 @@ def flatten(data):
else:
return [data]
def to_bits(value):
if isinstance(value, int):
return bin(value)[2:]
elif isinstance(value, float):
packed = struct.pack('>d', value)
return ''.join(f'{byte:08b}' for byte in packed)
elif isinstance(value, str):
return ''.join(f'{ord(c):08b}' for c in value)
else:
raise TypeError(f"Unsupported type: {type(value)}")
# ==============================================================================
# === ENUMERATION ===
# ==============================================================================
@@ -192,7 +204,7 @@ class ResultObject(object):
class BitSplitNode(JOVBaseNode):
NAME = "BIT SPLIT (JOV) ⭄"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = (JOV_TYPE_NUMBER, "BOOLEAN",)
RETURN_TYPES = (JOV_TYPE_ANY, "BOOLEAN",)
RETURN_NAMES = (Lexicon.BIT, Lexicon.BOOLEAN,)
OUTPUT_TOOLTIPS = (
"Bits as Numerical output (0 or 1)",
@@ -200,30 +212,55 @@ class BitSplitNode(JOVBaseNode):
)
SORT = 10
DESCRIPTION = """
Split an input into separate bits. `BOOL`, `INT` and `FLOAT` use their numbers,
`STRING` is treated as a list of `CHARACTER`. `IMAGE` and `MASK` will return a
`TRUE` bit for any non-black pixel, as a stream of bits for all pixels in the
image.
Split an input into separate bits.
BOOL, INT and FLOAT use their numbers,
STRING is treated as a list of CHARACTER.
IMAGE and MASK will return a TRUE bit for any non-black pixel, as a stream of bits for all pixels in the image.
"""
@classmethod
def INPUT_TYPES(cls) -> Dict[str, str]:
d = super().INPUT_TYPES()
d = deep_merge(d, {
"optional": {
Lexicon.UNKNOWN: (JOV_TYPE_FULL, {"default": None}),
Lexicon.VALUE: ("INT", {"default": 8, "min": 1, "max": 64, "tooltip":"Number of output bits requested."})
"VALUE": (JOV_TYPE_FULL, {"default": None, "tooltip":"the value to convert into bits"}),
"BITS": ("INT", {"default": 8, "min": 1, "max": 64, "tooltip":"number of output bits requested"}),
"MSB": ("BOOLEAN", {"default": False, "tooltip":"return the most signifigant bits (True) or least signifigant bits first"})
}
})
return Lexicon._parse(d)
def run(self, **kw) -> Tuple[bool]:
return (0,)
def run(self, **kw) -> Tuple[List[int], List[bool]]:
value = parse_param(kw, "VALUE", EnumConvertType.ANY, [0])
bits = parse_param(kw, "BITS", EnumConvertType.INT, 8, 1, 64)
msb = parse_param(kw, "MSB", EnumConvertType.INT, False)
params = list(zip_longest_fill(value, bits))
pbar = ProgressBar(len(params))
results = []
for idx, (value, bits) in enumerate(params):
bit_repr = to_bits(value)
if len(bit_repr) > bits:
if msb:
bit_repr = bit_repr[bits]
else:
bit_repr = bit_repr[-bits:]
elif msb:
bit_repr = bit_repr.zfill(bits)
else:
bit_repr = bit_repr.ljust(bits, '0')
int_bits = []
bool_bits = []
for b in bit_repr:
bit = int(b)
int_bits.append(bit)
bool_bits.append(bool(bit))
results.append([int_bits, bool_bits])
pbar.update_absolute(idx)
return *list(zip(*results)),
class CalcUnaryOPNode(JOVBaseNode):
NAME = "OP UNARY (JOV) 🎲"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = (JOV_TYPE_NUMBER,)
RETURN_TYPES = (JOV_TYPE_ANY,)
RETURN_NAMES = (Lexicon.UNKNOWN,)
OUTPUT_TOOLTIPS = (
"Output type will match the input type"
@@ -324,7 +361,7 @@ Perform single function operations like absolute value, mean, median, mode, magn
class CalcBinaryOPNode(JOVBaseNode):
NAME = "OP BINARY (JOV) 🌟"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = (JOV_TYPE_NUMBER,)
RETURN_TYPES = (JOV_TYPE_ANY,)
RETURN_NAMES = (Lexicon.UNKNOWN,)
OUTPUT_TOOLTIPS = (
"Output type will match the input type"
@@ -466,10 +503,10 @@ Execute binary operations like addition, subtraction, multiplication, division,
class ComparisonNode(JOVBaseNode):
NAME = "COMPARISON (JOV) 🕵🏽"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = (JOV_TYPE_ANY, JOV_TYPE_NUMBER,)
RETURN_TYPES = (JOV_TYPE_ANY, JOV_TYPE_ANY,)
RETURN_NAMES = (Lexicon.TRIGGER, Lexicon.VALUE,)
OUTPUT_TOOLTIPS = (
f"Outputs the input at {Lexicon.IN_A} or {Lexicon.IN_B} depending on which evaluated `TRUE`",
f"Outputs the input at {Lexicon.IN_A} or {Lexicon.IN_B} depending on which evaluated TRUE",
"The comparison result value"
)
SORT = 130
@@ -585,7 +622,7 @@ Evaluates two inputs (A and B) with a specified comparison operators and optiona
class LerpNode(JOVBaseNode):
NAME = "LERP (JOV) 🔰"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = (JOV_TYPE_FULL,)
RETURN_TYPES = (JOV_TYPE_ANY,)
RETURN_NAMES = (Lexicon.ANY_OUT,)
OUTPUT_TOOLTIPS = (
f"Output can vary depending on the type chosen in the {Lexicon.TYPE} parameter"
@@ -742,7 +779,7 @@ Manipulate strings through filtering
class SwizzleNode(JOVBaseNode):
NAME = "SWIZZLE (JOV) 😵"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = (JOV_TYPE_VECTOR,)
RETURN_TYPES = (JOV_TYPE_ANY,)
RETURN_NAMES = (Lexicon.ANY_OUT,)
SORT = 40
DESCRIPTION = """
@@ -755,8 +792,8 @@ Swap components between two vectors based on specified swizzle patterns and valu
names_convert = EnumConvertType._member_names_[3:10]
d = deep_merge(d, {
"optional": {
Lexicon.IN_A: (JOV_TYPE_VECTOR, {}),
Lexicon.IN_B: (JOV_TYPE_VECTOR, {}),
Lexicon.IN_A: (JOV_TYPE_NUMERICAL, {}),
Lexicon.IN_B: (JOV_TYPE_NUMERICAL, {}),
Lexicon.TYPE: (names_convert, {"default": names_convert[2],
"tooltip":"Output type desired from resultant operation"}),
Lexicon.SWAP_X: (EnumSwizzle._member_names_, {"default": EnumSwizzle.A_X.name}),
@@ -886,8 +923,7 @@ A timer and frame counter, emitting pulses or signals based on time intervals. I
class ValueNode(JOVBaseNode):
NAME = "VALUE (JOV) 🧬"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
# INPUT_IS_LIST = True
RETURN_TYPES = (JOV_TYPE_NUMBER, JOV_TYPE_NUMBER, JOV_TYPE_NUMBER, JOV_TYPE_NUMBER, JOV_TYPE_NUMBER,)
RETURN_TYPES = (JOV_TYPE_ANY, JOV_TYPE_ANY, JOV_TYPE_ANY, JOV_TYPE_ANY, JOV_TYPE_ANY,)
RETURN_NAMES = (Lexicon.ANY_OUT, Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W)
SORT = 5
DESCRIPTION = """
@@ -910,22 +946,24 @@ Supplies raw or default values for various data types, supporting vector input w
"tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}),
Lexicon.TYPE: (typ, {"default": EnumConvertType.BOOLEAN.name,
"tooltip":"Take the input and convert it into the selected type."}),
Lexicon.X: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize,
Lexicon.X: (JOV_TYPE_NUMERICAL, {"default": 0, "mij": -sys.maxsize,
"maj": sys.maxsize, "step": 0.01, "forceInput": True}),
Lexicon.Y: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize,
Lexicon.Y: (JOV_TYPE_NUMERICAL, {"default": 0, "mij": -sys.maxsize,
"maj": sys.maxsize, "step": 0.01, "forceInput": True}),
Lexicon.Z: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize,
Lexicon.Z: (JOV_TYPE_NUMERICAL, {"default": 0, "mij": -sys.maxsize,
"maj": sys.maxsize, "step": 0.01, "forceInput": True}),
Lexicon.W: (JOV_TYPE_ANY, {"default": 0, "mij": -sys.maxsize,
Lexicon.W: (JOV_TYPE_NUMERICAL, {"default": 0, "mij": -sys.maxsize,
"maj": sys.maxsize, "step": 0.01, "forceInput": True}),
Lexicon.IN_A+Lexicon.IN_A: ("VEC4", {"default": (0, 0, 0, 0),
#"mij": -sys.maxsize, "maj": sys.maxsize,
"precision": 2,
"step": 0.01,
"label": [Lexicon.X, Lexicon.Y],
"tooltip":"default value vector for A"}),
Lexicon.SEED: ("INT", {"default": 0, "min": 0, "max": sys.maxsize}),
Lexicon.IN_B+Lexicon.IN_B: ("VEC4", {"default": (1,1,1,1),
#"mij": -sys.maxsize, "maj": sys.maxsize,
"precision": 2,
"step": 0.01,
"label": [Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W],
"tooltip":"default value vector for B"}),
@@ -1070,8 +1108,8 @@ Outputs a VEC2 or VEC2INT.
d = super().INPUT_TYPES()
d = deep_merge(d, {
"optional": {
"X": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "1st channel value"}),
"Y": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "2nd channel value"}),
"X": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "1st channel value"}),
"Y": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "2nd channel value"}),
}
})
return Lexicon._parse(d)
@@ -1089,44 +1127,6 @@ Outputs a VEC2 or VEC2INT.
pbar.update_absolute(idx)
return *list(zip(*results)),
class Vector2IntNode(JOVBaseNode):
NAME = "VECTOR2INT (JOV)"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = ("VEC2", "VEC2INT", )
RETURN_NAMES = ("VEC2", "VEC2INT", )
OUTPUT_TOOLTIPS = (
"Vector2 with float values",
"Vector2 with integer values",
)
SORT = 291
DESCRIPTION = """
Outputs a VEC2 or VEC2INT.
"""
@classmethod
def INPUT_TYPES(cls) -> Dict[str, str]:
d = super().INPUT_TYPES()
d = deep_merge(d, {
"optional": {
"X": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "1st channel value"}),
"Y": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "2nd channel value"}),
}
})
return Lexicon._parse(d)
def run(self, **kw) -> Tuple[Tuple[float, ...], Tuple[int, ...]]:
x = parse_param(kw, "X", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
y = parse_param(kw, "Y", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
results = []
params = list(zip_longest_fill(x, y))
pbar = ProgressBar(len(params))
for idx, (x, y) in enumerate(params):
x = round(x, 6)
y = round(y, 6)
results.append([(x, y,), (int(x), int(y),)])
pbar.update_absolute(idx)
return *list(zip(*results)),
class Vector3Node(JOVBaseNode):
NAME = "VECTOR3 (JOV)"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
@@ -1146,9 +1146,9 @@ Outputs a VEC3 or VEC3INT.
d = super().INPUT_TYPES()
d = deep_merge(d, {
"optional": {
"X": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "1st channel value"}),
"Y": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "2nd channel value"}),
"Z": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "3rd channel value"}),
"X": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "1st channel value"}),
"Y": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "2nd channel value"}),
"Z": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "3rd channel value"}),
}
})
return Lexicon._parse(d)
@@ -1168,47 +1168,6 @@ Outputs a VEC3 or VEC3INT.
pbar.update_absolute(idx)
return *list(zip(*results)),
class Vector3IntNode(JOVBaseNode):
NAME = "VECTOR3INT (JOV)"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = ("VEC3", "VEC3INT", )
RETURN_NAMES = ("VEC3", "VEC3INT", )
OUTPUT_TOOLTIPS = (
"Vector3 with float values",
"Vector3 with integer values",
)
SORT = 293
DESCRIPTION = """
Outputs a VEC3 or VEC3INT.
"""
@classmethod
def INPUT_TYPES(cls) -> Dict[str, str]:
d = super().INPUT_TYPES()
d = deep_merge(d, {
"optional": {
"X": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "1st channel value"}),
"Y": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "2nd channel value"}),
"Z": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "3rd channel value"}),
}
})
return Lexicon._parse(d)
def run(self, **kw) -> Tuple[Tuple[float, ...], Tuple[int, ...]]:
x = parse_param(kw, "X", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
y = parse_param(kw, "Y", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
z = parse_param(kw, "Z", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
results = []
params = list(zip_longest_fill(x, y, z))
pbar = ProgressBar(len(params))
for idx, (x, y, z) in enumerate(params):
x = round(x, 6)
y = round(y, 6)
z = round(z, 6)
results.append([(x, y, z,), (int(x), int(y), int(z),)])
pbar.update_absolute(idx)
return *list(zip(*results)),
class Vector4Node(JOVBaseNode):
NAME = "VECTOR4 (JOV)"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
@@ -1228,10 +1187,10 @@ Outputs a VEC4 or VEC4INT.
d = super().INPUT_TYPES()
d = deep_merge(d, {
"optional": {
"X": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "1st channel value"}),
"Y": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "2nd channel value"}),
"Z": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "3rd channel value"}),
"W": ("FLOAT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "4th channel value"}),
"X": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "1st channel value"}),
"Y": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "2nd channel value"}),
"Z": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "3rd channel value"}),
"W": (JOV_TYPE_NUMBER, {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 0.01, "tooltip": "4th channel value"}),
}
})
return Lexicon._parse(d)
@@ -1253,50 +1212,6 @@ Outputs a VEC4 or VEC4INT.
pbar.update_absolute(idx)
return *list(zip(*results)),
class Vector4IntNode(JOVBaseNode):
NAME = "VECTOR4INT (JOV)"
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
RETURN_TYPES = ("VEC4", "VEC4INT", )
RETURN_NAMES = ("VEC4", "VEC4INT", )
OUTPUT_TOOLTIPS = (
"Vector4 with float values",
"Vector4 with integer values",
)
SORT = 295
DESCRIPTION = """
Outputs a VEC4 or VEC4INT.
"""
@classmethod
def INPUT_TYPES(cls) -> Dict[str, str]:
d = super().INPUT_TYPES()
d = deep_merge(d, {
"optional": {
"X": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "1st channel value"}),
"Y": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "2nd channel value"}),
"Z": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "3rd channel value"}),
"W": ("INT", {"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "step": 1, "tooltip": "4th channel value"}),
}
})
return Lexicon._parse(d)
def run(self, **kw) -> Tuple[Tuple[float, ...], Tuple[int, ...]]:
x = parse_param(kw, "X", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
y = parse_param(kw, "Y", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
z = parse_param(kw, "Z", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
w = parse_param(kw, "W", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)
results = []
params = list(zip_longest_fill(x, y, z, w))
pbar = ProgressBar(len(params))
for idx, (x, y, z, w,) in enumerate(params):
x = round(x, 6)
y = round(y, 6)
z = round(z, 6)
w = round(w, 6)
results.append([(x, y, z, w,), (int(x), int(y), int(z), int(w),)])
pbar.update_absolute(idx)
return *list(zip(*results)),
'''
class ParameterNode(JOVBaseNode):
NAME = "PARAMETER (JOV) ⚙️"
+12 -9
View File
@@ -64,7 +64,7 @@ Visualize data. It accepts various types of data, including images, text, and ot
return output
def __parse(val) -> str:
ret = val
ret = ''
typ = ''.join(repr(type(val)).split("'")[1:2])
if isinstance(val, dict):
# mixlab layer?
@@ -95,11 +95,10 @@ Visualize data. It accepts various types of data, including images, text, and ot
ret = json.dumps(val, indent=3, separators=(',', ': '))
except Exception as e:
ret = str(e)
elif isinstance(val, (tuple, set, list,)):
ret = ''
if (size := len(val)) > 0:
if type(val) == np.ndarray:
if isinstance(val, (np.ndarray,)):
ret = str(val)
typ = "NUMPY ARRAY"
elif isinstance(val[0], (torch.Tensor,)):
ret = decode_tensor(val[0])
@@ -107,16 +106,20 @@ Visualize data. It accepts various types of data, including images, text, and ot
elif size == 1 and isinstance(val[0], (list,)) and isinstance(val[0][0], (torch.Tensor,)):
ret = decode_tensor(val[0][0])
typ = "CONDITIONING"
elif all(isinstance(i, list) for i in val):
# Serialize each inner list on a separate line
ret = [json.dumps(i, separators=(',', ': ')) for i in val]
elif all(isinstance(i, (tuple, set, list)) for i in val):
ret = "[\n" + ",\n".join(f" {row}" for row in val) + "\n]"
# ret = json.dumps(val, indent=4)
elif all(isinstance(i, (bool, int, float)) for i in val):
ret = ','.join([str(x) for x in val])
else:
ret = str(val)
elif isinstance(val, bool):
ret = "True" if val else "False"
elif isinstance(val, torch.Tensor):
ret = decode_tensor(val)
else:
ret = str(ret)
return json.dumps({typ: val}, separators=(',', ': '))
ret = str(val)
return json.dumps({typ: ret}, separators=(',', ': '))
for x in o:
output["ui"]["text"].append(__parse(x))
-3
View File
@@ -61,10 +61,7 @@
"TRANSFORM (JOV) \ud83c\udfdd\ufe0f": "Apply various geometric transformations to images, including translation, rotation, scaling, mirroring, tiling and perspective projection",
"VALUE (JOV) \ud83e\uddec": "Supplies raw or default values for various data types, supporting vector input with components for X, Y, Z, and W",
"VECTOR2 (JOV)": "Outputs a VEC2 or VEC2INT",
"VECTOR2INT (JOV)": "Outputs a VEC2 or VEC2INT",
"VECTOR3 (JOV)": "Outputs a VEC3 or VEC3INT",
"VECTOR3INT (JOV)": "Outputs a VEC3 or VEC3INT",
"VECTOR4 (JOV)": "Outputs a VEC4 or VEC4INT",
"VECTOR4INT (JOV)": "Outputs a VEC4 or VEC4INT",
"WAVE GEN (JOV) \ud83c\udf0a": "Produce waveforms like sine, square, or sawtooth with adjustable frequency, amplitude, phase, and offset"
}
+3 -4
View File
@@ -277,10 +277,9 @@ def parse_param(data:dict, key:str, typ:EnumConvertType, default: Any,
val = data.get(key, default)
if typ == EnumConvertType.ANY:
if val is None:
val = [default]
return val
elif isinstance(val, (list,)):
val = val[0]
return [default]
#elif isinstance(val, (list,)):
# val = val[0]
if isinstance(val, (str,)):
try: val = json.loads(val.replace("'", '"'))
+4 -7
View File
@@ -38,13 +38,10 @@ app.registerExtension({
textWidget.inputEl.style.padding = "1px";
textWidget.inputEl.style.border = "1px";
textWidget.inputEl.style.backgroundColor = "#222";
textWidget.value = this.inputs[i].name + "::\n";
const msg = message["text"][i];
if (!msg.split("],[").length > 1) {
textWidget.value += msg.split(",").join(",\n");
} else {
textWidget.value += msg;
}
textWidget.value = this.inputs[i].name + " ";
textWidget.value += message["text"][i]
.replace(/\\n/g, '\n')
.replace(/"/g, '');
}
}
return me;