Lexicon updated to come from comfy_cozy
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
|
||||
from enum import Enum
|
||||
|
||||
class EnumFillOperation(Enum):
|
||||
DEFAULT = 0
|
||||
FILL_ZERO = 20
|
||||
FILL_ALL = 10
|
||||
|
||||
+58
-59
@@ -12,6 +12,9 @@ from cozy_comfyui import \
|
||||
InputType, EnumConvertType, \
|
||||
deep_merge, parse_param, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_ANY, \
|
||||
CozyBaseNode
|
||||
@@ -61,47 +64,46 @@ A timer and frame counter, emitting pulses or signals based on time intervals. I
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
# data to pass on a pulse of the loop
|
||||
"TRIGGER": (COZY_TYPE_ANY, {
|
||||
Lexicon.TRIGGER: (COZY_TYPE_ANY, {
|
||||
"default": None,
|
||||
"tooltip":"Output to send when beat (BPM setting) is hit"
|
||||
"tooltip": "Output to send when beat (BPM setting) is hit"
|
||||
}),
|
||||
# forces a MOD on CYCLE
|
||||
"VALUE": ("INT", {
|
||||
Lexicon.VALUE: ("INT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize,
|
||||
"tooltip": "the current frame number of the tick"
|
||||
"tooltip": "Current frame number of the tick"
|
||||
}),
|
||||
"LOOP": ("INT", {
|
||||
Lexicon.LOOP: ("INT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize,
|
||||
"tooltip": "number of frames before looping starts. 0 means continuous playback (no loop point)"
|
||||
"tooltip": "Number of frames before looping starts. 0 means continuous playback (no loop point)"
|
||||
}),
|
||||
"FPS": ("INT", {
|
||||
"default": 24, "min": 1,
|
||||
"tooltip": "Fixed frame step rate based on FPS (1/FPS)"
|
||||
Lexicon.FPS: ("INT", {
|
||||
"default": 24, "min": 1
|
||||
}),
|
||||
"BPM": ("INT", {
|
||||
Lexicon.BPM: ("INT", {
|
||||
"default": 120, "min": 1, "max": 60000,
|
||||
"tooltip": "BPM trigger rate to send the input. If input is empty, TRUE is sent on trigger"
|
||||
}),
|
||||
"NOTE": ("INT", {
|
||||
Lexicon.NOTE: ("INT", {
|
||||
"default": 4, "min": 1, "max": 256,
|
||||
"tooltip":"Number of beats per measure. Quarter note is 4, Eighth is 8, 16 is 16, etc."}),
|
||||
"tooltip": "Number of beats per measure. Quarter note is 4, Eighth is 8, 16 is 16, etc."}),
|
||||
# stick the current "count"
|
||||
"HOLD": ("BOOLEAN", {
|
||||
Lexicon.HOLD: ("BOOLEAN", {
|
||||
"default": False}),
|
||||
# manual total = 0
|
||||
"RESET": ("BOOLEAN", {
|
||||
Lexicon.RESET: ("BOOLEAN", {
|
||||
"default": False}),
|
||||
# how many frames to dump....
|
||||
"BATCH": ("INT", {
|
||||
Lexicon.BATCH: ("INT", {
|
||||
"default": 1, "min": 1, "max": 32767,
|
||||
"tooltip": "Number of frames wanted"
|
||||
}),
|
||||
"STEP": ("INT", {
|
||||
Lexicon.STEP: ("INT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize
|
||||
}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def __init__(self, *arg, **kw) -> None:
|
||||
super().__init__(*arg, **kw)
|
||||
@@ -109,21 +111,21 @@ A timer and frame counter, emitting pulses or signals based on time intervals. I
|
||||
self.__frame = 0
|
||||
|
||||
def run(self, ident, **kw) -> tuple[int, float, float, Any]:
|
||||
passthru = parse_param(kw, "TRIGGER", EnumConvertType.ANY, None)[0]
|
||||
stride = parse_param(kw, "STEP", EnumConvertType.INT, 0, 0, sys.maxsize)[0]
|
||||
loop = parse_param(kw, "LOOP", EnumConvertType.INT, 0, 0, sys.maxsize)[0]
|
||||
self.__frame = parse_param(kw, "VALUE", EnumConvertType.INT, self.__frame, 0, sys.maxsize)[0]
|
||||
passthru = parse_param(kw, Lexicon.TRIGGER, EnumConvertType.ANY, None)[0]
|
||||
stride = parse_param(kw, Lexicon.STEP, EnumConvertType.INT, 0, 0, sys.maxsize)[0]
|
||||
loop = parse_param(kw, Lexicon.LOOP, EnumConvertType.INT, 0, 0, sys.maxsize)[0]
|
||||
self.__frame = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, self.__frame, 0, sys.maxsize)[0]
|
||||
if loop != 0:
|
||||
self.__frame %= loop
|
||||
# start_frame = max(0, start_frame)
|
||||
hold = parse_param(kw, "HOLD", EnumConvertType.BOOLEAN, False)[0]
|
||||
fps = parse_param(kw, "FPS", EnumConvertType.INT, 24, 1)[0]
|
||||
bpm = parse_param(kw, "BPM", EnumConvertType.INT, 120, 1)[0]
|
||||
divisor = parse_param(kw, "NOTE", EnumConvertType.INT, 4, 1)[0]
|
||||
hold = parse_param(kw, Lexicon.HOLD, EnumConvertType.BOOLEAN, False)[0]
|
||||
fps = parse_param(kw, Lexicon.FPS, EnumConvertType.INT, 24, 1)[0]
|
||||
bpm = parse_param(kw, Lexicon.BPM, EnumConvertType.INT, 120, 1)[0]
|
||||
divisor = parse_param(kw, Lexicon.NOTE, EnumConvertType.INT, 4, 1)[0]
|
||||
beat = 60. / max(1., bpm) / divisor
|
||||
batch = parse_param(kw, "BATCH", EnumConvertType.INT, 1, 1)[0]
|
||||
batch = parse_param(kw, Lexicon.BATCH, EnumConvertType.INT, 1, 1)[0]
|
||||
step_fps = 1. / max(1., float(fps))
|
||||
reset = parse_param(kw, "RESET", EnumConvertType.BOOLEAN, False)[0]
|
||||
reset = parse_param(kw, Lexicon.RESET, EnumConvertType.BOOLEAN, False)[0]
|
||||
if loop == 0 and (parse_reset(ident) > 0 or reset):
|
||||
self.__frame = 0
|
||||
trigger = None
|
||||
@@ -172,33 +174,33 @@ Value generator with normalized values based on based on time interval.
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
# forces a MOD on CYCLE
|
||||
"VALUE": ("INT", {
|
||||
Lexicon.VALUE: ("INT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Starting value of the tick"
|
||||
}),
|
||||
# interval between frames
|
||||
"STEP": ("FLOAT", {
|
||||
Lexicon.STEP: ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize, "precision": 3,
|
||||
"tooltip": "Amount to add to each frame per tick"
|
||||
}),
|
||||
"LOOP": ("INT", {
|
||||
Lexicon.LOOP: ("INT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "What value before looping starts. 0 means linear playback (no loop point)"
|
||||
}),
|
||||
# how many frames to dump....
|
||||
"BATCH": ("INT", {
|
||||
Lexicon.BATCH: ("INT", {
|
||||
"default": 1, "min": 1, "max": 1500,
|
||||
"tooltip": "Total frames wanted"
|
||||
}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[int, float|int]:
|
||||
value = parse_param(kw, "VALUE", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)[0]
|
||||
step = parse_param(kw, "STEP", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)[0]
|
||||
loop = parse_param(kw, "LOOP", EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)[0]
|
||||
batch = parse_param(kw, "BATCH", EnumConvertType.INT, 1, 1, 1500)[0]
|
||||
value = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)[0]
|
||||
step = parse_param(kw, Lexicon.STEP, EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)[0]
|
||||
loop = parse_param(kw, Lexicon.LOOP, EnumConvertType.INT, 0, -sys.maxsize, sys.maxsize)[0]
|
||||
batch = parse_param(kw, Lexicon.BATCH, EnumConvertType.INT, 1, 1, 1500)[0]
|
||||
if loop == 0:
|
||||
loop = batch
|
||||
|
||||
@@ -230,38 +232,35 @@ Produce waveforms like sine, square, or sawtooth with adjustable frequency, ampl
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"WAVE": (EnumWave._member_names_, {
|
||||
Lexicon.WAVE: (EnumWave._member_names_, {
|
||||
"default": EnumWave.SIN.name}),
|
||||
"FREQ": ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": sys.maxsize, "step": 0.01,
|
||||
"tooltip": "Frequency"}),
|
||||
"AMP": ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": sys.maxsize, "step": 0.01,
|
||||
"tooltip": "Amplitude"}),
|
||||
"PHASE": ("FLOAT", {
|
||||
Lexicon.FREQ: ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": sys.maxsize, "step": 0.01,}),
|
||||
Lexicon.AMP: ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": sys.maxsize, "step": 0.01,}),
|
||||
Lexicon.PHASE: ("FLOAT", {
|
||||
"default": 0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"OFFSET": ("FLOAT", {
|
||||
Lexicon.OFFSET: ("FLOAT", {
|
||||
"default": 0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"TIME": ("FLOAT", {
|
||||
Lexicon.TIME: ("FLOAT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize, "step": 0.0001}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False}),
|
||||
"ABSOLUTE": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltips": "Return the absolute value of the input"}),
|
||||
Lexicon.ABSOLUTE: ("BOOLEAN", {
|
||||
"default": False,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[float, int]:
|
||||
op = parse_param(kw, "WAVE", EnumWave, EnumWave.SIN.name)
|
||||
freq = parse_param(kw, "FREQ", EnumConvertType.FLOAT, 1., 0.000001, sys.maxsize)
|
||||
amp = parse_param(kw, "AMP", EnumConvertType.FLOAT, 1., 0., sys.maxsize)
|
||||
phase = parse_param(kw, "PHASE", EnumConvertType.FLOAT, 0.)
|
||||
shift = parse_param(kw, "OFFSET", EnumConvertType.FLOAT, 0.)
|
||||
delta_time = parse_param(kw, "TIME", EnumConvertType.FLOAT, 0., 0., sys.maxsize)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
absolute = parse_param(kw, "ABSOLUTE", EnumConvertType.BOOLEAN, False)
|
||||
op = parse_param(kw, Lexicon.WAVE, EnumWave, EnumWave.SIN.name)
|
||||
freq = parse_param(kw, Lexicon.FREQ, EnumConvertType.FLOAT, 1., 0.000001, sys.maxsize)
|
||||
amp = parse_param(kw, Lexicon.AMP, EnumConvertType.FLOAT, 1., 0., sys.maxsize)
|
||||
phase = parse_param(kw, Lexicon.PHASE, EnumConvertType.FLOAT, 0.)
|
||||
shift = parse_param(kw, Lexicon.OFFSET, EnumConvertType.FLOAT, 0.)
|
||||
delta_time = parse_param(kw, Lexicon.TIME, EnumConvertType.FLOAT, 0., 0., sys.maxsize)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
absolute = parse_param(kw, Lexicon.ABSOLUTE, EnumConvertType.BOOLEAN, False)
|
||||
results = []
|
||||
params = list(zip_longest_fill(op, freq, amp, phase, shift, delta_time, invert, absolute))
|
||||
pbar = ProgressBar(len(params))
|
||||
|
||||
+158
-177
@@ -8,7 +8,6 @@ from typing import Any, List
|
||||
from collections import Counter
|
||||
|
||||
import torch
|
||||
import numpy as np
|
||||
from scipy.special import gamma
|
||||
|
||||
from comfy.utils import ProgressBar
|
||||
@@ -18,10 +17,16 @@ from cozy_comfyui import \
|
||||
TensorType, InputType, EnumConvertType, \
|
||||
deep_merge, parse_dynamic, parse_param, parse_value, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_ANY, COZY_TYPE_NUMERICAL, COZY_TYPE_FULL, \
|
||||
CozyBaseNode
|
||||
|
||||
from . import \
|
||||
EnumFillOperation
|
||||
|
||||
from ..sup.anim import \
|
||||
EnumEase, \
|
||||
ease_op
|
||||
@@ -233,17 +238,22 @@ IMAGE and MASK will return a TRUE bit for any non-black pixel, as a stream of bi
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"VALUE": (COZY_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"})
|
||||
Lexicon.VALUE: (COZY_TYPE_FULL, {
|
||||
"default": None,
|
||||
"tooltip": "Value to convert into bits"}),
|
||||
Lexicon.BIT: ("INT", {
|
||||
"default": 8, "min": 1, "max": 64,
|
||||
"tooltip": "Number of output bits requested"}),
|
||||
Lexicon.MSB: ("BOOLEAN", {
|
||||
"default": False})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
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)
|
||||
value = parse_param(kw, Lexicon.VALUE, EnumConvertType.ANY, 0)
|
||||
bits = parse_param(kw, Lexicon.BIT, EnumConvertType.INT, 8, 1, 64)
|
||||
msb = parse_param(kw, Lexicon.MSB, EnumConvertType.INT, False)
|
||||
params = list(zip_longest_fill(value, bits))
|
||||
pbar = ProgressBar(len(params))
|
||||
results = []
|
||||
@@ -288,45 +298,44 @@ Evaluates two inputs (A and B) with a specified comparison operators and optiona
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"A": (COZY_TYPE_FULL, {
|
||||
Lexicon.IN_A: (COZY_TYPE_FULL, {
|
||||
"default": 0,
|
||||
"tooltip":"First value to compare"}),
|
||||
"B": (COZY_TYPE_FULL, {
|
||||
Lexicon.IN_B: (COZY_TYPE_FULL, {
|
||||
"default": 0,
|
||||
"tooltip":"Second value to compare"}),
|
||||
"PASS": (COZY_TYPE_ANY, {
|
||||
Lexicon.SUCCESS: (COZY_TYPE_ANY, {
|
||||
"default": 0,
|
||||
"tooltip": "Passed to OUT on a successful condition"}),
|
||||
"FAIL": (COZY_TYPE_ANY, {
|
||||
"tooltip": "Sent to OUT on a successful condition"}),
|
||||
Lexicon.FAIL: (COZY_TYPE_ANY, {
|
||||
"default": 0,
|
||||
"tooltip": "Passed to OUT on a failure condition"}),
|
||||
"COMPARE": (EnumComparison._member_names_, {
|
||||
"tooltip": "Sent to OUT on a failure condition"}),
|
||||
Lexicon.FUNCTION: (EnumComparison._member_names_, {
|
||||
"default": EnumComparison.EQUAL.name,
|
||||
"tooltip": "Comparison function. Sends the data in PASS on successful comparison to OUT, otherwise sends the value in FAIL"}),
|
||||
"FLIP": ("BOOLEAN", {
|
||||
Lexicon.SWAP: ("BOOLEAN", {
|
||||
"default": False,}),
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Reverse the inputs A and B"}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Reverse the successful and failure inputs"}),
|
||||
"tooltip": "Reverse the PASS and FAIL inputs"}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[Any, Any]:
|
||||
A = parse_param(kw, "A", EnumConvertType.ANY, 0)
|
||||
B = parse_param(kw, "B", EnumConvertType.ANY, 0)
|
||||
size = max(len(A), len(B))
|
||||
good = parse_param(kw, "PASS", EnumConvertType.ANY, 0)[:size]
|
||||
fail = parse_param(kw, "FAIL", EnumConvertType.ANY, 0)[:size]
|
||||
op = parse_param(kw, "COMPARE", EnumComparison, EnumComparison.EQUAL.name)[:size]
|
||||
flip = parse_param(kw, "FLIP", EnumConvertType.BOOLEAN, False)[:size]
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)[:size]
|
||||
params = list(zip_longest_fill(A, B, good, fail, op, flip, invert))
|
||||
in_a = parse_param(kw, Lexicon.IN_A, EnumConvertType.ANY, 0)
|
||||
in_b = parse_param(kw, Lexicon.IN_B, EnumConvertType.ANY, 0)
|
||||
size = max(len(in_a), len(in_b))
|
||||
good = parse_param(kw, Lexicon.SUCCESS, EnumConvertType.ANY, 0)[:size]
|
||||
fail = parse_param(kw, Lexicon.FAIL, EnumConvertType.ANY, 0)[:size]
|
||||
op = parse_param(kw, Lexicon.FUNCTION, EnumComparison, EnumComparison.EQUAL.name)[:size]
|
||||
swap = parse_param(kw, Lexicon.SWAP, EnumConvertType.BOOLEAN, False)[:size]
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)[:size]
|
||||
params = list(zip_longest_fill(in_a, in_b, good, fail, op, swap, invert))
|
||||
pbar = ProgressBar(len(params))
|
||||
vals = []
|
||||
results = []
|
||||
for idx, (A, B, good, fail, op, flip, invert) in enumerate(params):
|
||||
for idx, (A, B, good, fail, op, swap, invert) in enumerate(params):
|
||||
if not isinstance(A, (tuple, list,)):
|
||||
A = [A]
|
||||
if not isinstance(B, (tuple, list,)):
|
||||
@@ -343,7 +352,7 @@ Evaluates two inputs (A and B) with a specified comparison operators and optiona
|
||||
if not isinstance(val_b, (list,)):
|
||||
val_b = [val_b]
|
||||
|
||||
if flip:
|
||||
if swap:
|
||||
val_a, val_b = val_b, val_a
|
||||
|
||||
match op:
|
||||
@@ -406,7 +415,7 @@ class LerpNode(CozyBaseNode):
|
||||
NAME = "LERP (JOV) 🔰"
|
||||
CATEGORY = JOV_CATEGORY
|
||||
RETURN_TYPES = (COZY_TYPE_ANY,)
|
||||
RETURN_NAMES = ("🦄",)
|
||||
RETURN_NAMES = ("❔",)
|
||||
OUTPUT_IS_LIST = (True,)
|
||||
OUTPUT_TOOLTIPS = (
|
||||
f"Output can vary depending on the type chosen in the {"TYPE"} parameter"
|
||||
@@ -426,47 +435,40 @@ Additionally, you can specify the easing function (EASE) and the desired output
|
||||
names_convert = EnumConvertType._member_names_[:6]
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"A": (COZY_TYPE_FULL, {
|
||||
"tooltip": "Custom Start Point"
|
||||
}),
|
||||
"B": (COZY_TYPE_FULL, {
|
||||
"tooltip": "Custom End Point"
|
||||
}),
|
||||
"ALPHA": ("VEC4", {
|
||||
"default": (0.5, 0.5, 0.5, 0.5), "mij": 0., "maj": 1.0,
|
||||
"tooltip": "Blend Amount. 0 = full A, 1 = full B"
|
||||
}),
|
||||
"AA": ("VEC4", {
|
||||
"default": (0, 0, 0, 0),
|
||||
"tooltip":"default value vector for A"
|
||||
}),
|
||||
"BB": ("VEC4", {
|
||||
"default": (1,1,1,1),
|
||||
"tooltip":"default value vector for B"
|
||||
}),
|
||||
"TYPE": (names_convert, {
|
||||
Lexicon.IN_A: (COZY_TYPE_FULL, {
|
||||
"tooltip": "Custom Start Point"}),
|
||||
Lexicon.IN_B: (COZY_TYPE_FULL, {
|
||||
"tooltip": "Custom End Point"}),
|
||||
Lexicon.ALPHA: ("VEC4", {
|
||||
"default": (0.5, 0.5, 0.5, 0.5), "mij": 0., "maj": 1.0,}),
|
||||
Lexicon.TYPE: (names_convert, {
|
||||
"default": "FLOAT",
|
||||
"tooltip":"Output type desired from resultant operation"
|
||||
}),
|
||||
"EASE": (["NONE"] + EnumEase._member_names_, {
|
||||
"default": "NONE"
|
||||
}),
|
||||
"tooltip": "Output type desired from resultant operation"}),
|
||||
Lexicon.EASE: (["NONE"] + EnumEase._member_names_, {
|
||||
"default": "NONE"}),
|
||||
Lexicon.DEFAULT_A: ("VEC4", {
|
||||
"default": (0, 0, 0, 0)}),
|
||||
Lexicon.DEFAULT_B: ("VEC4", {
|
||||
"default": (1,1,1,1)}),
|
||||
Lexicon.FILL: (EnumFillOperation._member_names_, {
|
||||
"default": EnumFillOperation.DEFAULT.name}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[Any, Any]:
|
||||
A = parse_param(kw, "A", EnumConvertType.ANY, 0)
|
||||
B = parse_param(kw, "B", EnumConvertType.ANY, 0)
|
||||
a_xyzw = parse_param(kw, "AA", EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
b_xyzw = parse_param(kw, "BB", EnumConvertType.VEC4, (1, 1, 1, 1))
|
||||
alpha = parse_param(kw, "FLOAT",EnumConvertType.VEC4, (0.5,0.5,0.5,0.5), 0, 1)
|
||||
op = parse_param(kw, "EASE", EnumEase, EnumEase.SIN_IN_OUT.name)
|
||||
typ = parse_param(kw, "TYPE", EnumNumberType, EnumNumberType.FLOAT.name)
|
||||
A = parse_param(kw, Lexicon.IN_A, EnumConvertType.ANY, 0)
|
||||
B = parse_param(kw, Lexicon.IN_B, EnumConvertType.ANY, 0)
|
||||
alpha = parse_param(kw, Lexicon.ALPHA,EnumConvertType.VEC4, (0.5,0.5,0.5,0.5), 0, 1)
|
||||
typ = parse_param(kw, Lexicon.TYPE, EnumNumberType, EnumNumberType.FLOAT.name)
|
||||
op = parse_param(kw, Lexicon.EASE, EnumEase, EnumEase.SIN_IN_OUT.name)
|
||||
a_xyzw = parse_param(kw, Lexicon.DEFAULT_A, EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
b_xyzw = parse_param(kw, Lexicon.DEFAULT_B, EnumConvertType.VEC4, (1, 1, 1, 1))
|
||||
fill = parse_param(kw, Lexicon.FILL, EnumConvertType.BOOLEAN, False)
|
||||
values = []
|
||||
params = list(zip_longest_fill(A, B, a_xyzw, b_xyzw, alpha, op, typ))
|
||||
params = list(zip_longest_fill(A, B, alpha, typ, op, a_xyzw, b_xyzw, fill,))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (A, B, a_xyzw, b_xyzw, alpha, op, typ) in enumerate(params):
|
||||
for idx, (A, B, alpha, typ, op, a_xyzw, b_xyzw, fill,) in enumerate(params):
|
||||
size = int(typ.value / 10)
|
||||
|
||||
if A is None:
|
||||
@@ -528,39 +530,36 @@ Perform single function operations like absolute value, mean, median, mode, magn
|
||||
typ = EnumConvertType._member_names_[:6]
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"A": (COZY_TYPE_NUMERICAL, {
|
||||
Lexicon.IN_A: (COZY_TYPE_NUMERICAL, {
|
||||
"default": None}),
|
||||
"FUNCTION": (EnumUnaryOperation._member_names_, {
|
||||
Lexicon.FUNCTION: (EnumUnaryOperation._member_names_, {
|
||||
"default": EnumUnaryOperation.ABS.name}),
|
||||
"TYPE": (typ, {
|
||||
"default": EnumConvertType.FLOAT.name,
|
||||
"tooltip":"Take the input and convert it into the selected type"}),
|
||||
"FILL": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"If the value should fill the output type (VEC*)"}),
|
||||
Lexicon.TYPE: (typ, {
|
||||
"default": EnumConvertType.FLOAT.name,}),
|
||||
Lexicon.DEFAULT_A: ("VEC4", {
|
||||
"default": (0,0,0,0),
|
||||
"label": ["X", "Y", "Z", "W"]}),
|
||||
Lexicon.FILL: (EnumFillOperation._member_names_, {
|
||||
"default": EnumFillOperation.DEFAULT.name}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[bool]:
|
||||
results = []
|
||||
A = parse_param(kw, "A", EnumConvertType.ANY, 0)
|
||||
op = parse_param(kw, "FUNCTION", EnumUnaryOperation, EnumUnaryOperation.ABS.name)
|
||||
out = parse_param(kw, "TYPE", EnumConvertType, EnumConvertType.FLOAT.name)
|
||||
fill = parse_param(kw, "FILL", EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(A, op, out, fill))
|
||||
A = parse_param(kw, Lexicon.IN_A, EnumConvertType.ANY, 0)
|
||||
op = parse_param(kw, Lexicon.FUNCTION, EnumUnaryOperation, EnumUnaryOperation.ABS.name)
|
||||
out = parse_param(kw, Lexicon.TYPE, EnumConvertType, EnumConvertType.FLOAT.name)
|
||||
a_xyzw = parse_param(kw, Lexicon.DEFAULT_A, EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
fill = parse_param(kw, Lexicon.FILL, EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(A, op, out, a_xyzw, fill))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (A, op, out, fill) in enumerate(params):
|
||||
typ = EnumConvertType.FLOAT
|
||||
if isinstance(A, (bool, )):
|
||||
typ = EnumConvertType.BOOLEAN
|
||||
elif isinstance(A, (list, set, tuple,)):
|
||||
typ = EnumConvertType(len(A) * 10)
|
||||
|
||||
val = parse_value(A, typ, 0)
|
||||
if not isinstance(val, (list, tuple, )):
|
||||
val = [val]
|
||||
val = [float(v) for v in val]
|
||||
for idx, (A, op, out, a_xyzw, fill) in enumerate(params):
|
||||
size = min(3, max(0 if not isinstance(A, (list,)) else len(A)))
|
||||
best_type = [EnumConvertType.FLOAT, EnumConvertType.VEC2, EnumConvertType.VEC3, EnumConvertType.VEC4][size]
|
||||
val = parse_value(A, best_type, a_xyzw)
|
||||
val = parse_value(val, EnumConvertType.VEC4, a_xyzw)
|
||||
# val = [float(v) for v in val]
|
||||
match op:
|
||||
case EnumUnaryOperation.MEAN:
|
||||
val = [sum(val) / len(val)]
|
||||
@@ -626,62 +625,57 @@ Execute binary operations like addition, subtraction, multiplication, division,
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"A": (COZY_TYPE_NUMERICAL, {
|
||||
"default": None,
|
||||
"tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}),
|
||||
"B": (COZY_TYPE_NUMERICAL, {
|
||||
"default": None,
|
||||
"tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}),
|
||||
"FUNCTION": (EnumBinaryOperation._member_names_, {
|
||||
"default": EnumBinaryOperation.ADD.name,
|
||||
"tooltip":"Arithmetic operation to perform"}),
|
||||
"TYPE": (names_convert, {
|
||||
Lexicon.IN_A: (COZY_TYPE_NUMERICAL, {
|
||||
"default": None}),
|
||||
Lexicon.IN_B: (COZY_TYPE_NUMERICAL, {
|
||||
"default": None}),
|
||||
Lexicon.FUNCTION: (EnumBinaryOperation._member_names_, {
|
||||
"default": EnumBinaryOperation.ADD.name,}),
|
||||
Lexicon.TYPE: (names_convert, {
|
||||
"default": names_convert[2],
|
||||
"tooltip":"Output type desired from resultant operation"}),
|
||||
"FLIP": ("BOOLEAN", {
|
||||
Lexicon.SWAP: ("BOOLEAN", {
|
||||
"default": False}),
|
||||
"AA": ("VEC4", {
|
||||
Lexicon.DEFAULT_A: ("VEC4", {
|
||||
"default": (0,0,0,0),
|
||||
"label": ["X", "Y", "Z", "W"],
|
||||
"tooltip":"value vector"}),
|
||||
"BB": ("VEC4", {
|
||||
"label": ["X", "Y", "Z", "W"]}),
|
||||
Lexicon.DEFAULT_B: ("VEC4", {
|
||||
"default": (0,0,0,0),
|
||||
"label": ["X", "Y", "Z", "W"],
|
||||
"tooltip":"value vector"}),
|
||||
"label": ["X", "Y", "Z", "W"]}),
|
||||
Lexicon.FILL: (EnumFillOperation._member_names_, {
|
||||
"default": EnumFillOperation.DEFAULT.name}),
|
||||
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[bool]:
|
||||
results = []
|
||||
A = parse_param(kw, "A", EnumConvertType.ANY, None)
|
||||
B = parse_param(kw, "B", EnumConvertType.ANY, None)
|
||||
a_xyzw = parse_param(kw, "AA", EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
b_xyzw = parse_param(kw, "BB", EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
op = parse_param(kw, "FUNCTION", EnumBinaryOperation, EnumBinaryOperation.ADD.name)
|
||||
typ = parse_param(kw, "TYPE", EnumConvertType, EnumConvertType.FLOAT.name)
|
||||
flip = parse_param(kw, "FLIP", EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(A, B, a_xyzw, b_xyzw, op, typ, flip))
|
||||
A = parse_param(kw, Lexicon.IN_A, EnumConvertType.ANY, None)
|
||||
B = parse_param(kw, Lexicon.IN_B, EnumConvertType.ANY, None)
|
||||
op = parse_param(kw, Lexicon.FUNCTION, EnumBinaryOperation, EnumBinaryOperation.ADD.name)
|
||||
typ = parse_param(kw, Lexicon.TYPE, EnumConvertType, EnumConvertType.FLOAT.name)
|
||||
swap = parse_param(kw, Lexicon.SWAP, EnumConvertType.BOOLEAN, False)
|
||||
a_xyzw = parse_param(kw, Lexicon.DEFAULT_A, EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
b_xyzw = parse_param(kw, Lexicon.DEFAULT_B, EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
fill = parse_param(kw, Lexicon.FILL, EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(A, B, a_xyzw, b_xyzw, op, typ, swap, fill))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (A, B, a_xyzw, b_xyzw, op, typ, flip) in enumerate(params):
|
||||
for idx, (A, B, a_xyzw, b_xyzw, op, typ, swap, fill) in enumerate(params):
|
||||
size = min(3, max(0 if not isinstance(A, (list,)) else len(A), 0 if not isinstance(B, (list,)) else len(B)))
|
||||
best_type = [EnumConvertType.FLOAT, EnumConvertType.VEC2, EnumConvertType.VEC3, EnumConvertType.VEC4][size]
|
||||
print(type(A), type(B), A, B, a_xyzw)
|
||||
val_a = parse_value(A, best_type, a_xyzw)
|
||||
print(val_a)
|
||||
return
|
||||
val_a = parse_value(val_a, EnumConvertType.VEC4, a_xyzw)
|
||||
val_b = parse_value(B, best_type, b_xyzw)
|
||||
val_b = parse_value(val_b, EnumConvertType.VEC4, b_xyzw)
|
||||
|
||||
print(val_a, val_b)
|
||||
|
||||
#val_a = parse_value(A, EnumConvertType.VEC4, A if A is not None else a_xyzw)
|
||||
#val_b = parse_value(B, EnumConvertType.VEC4, B if B is not None else b_xyzw)
|
||||
|
||||
if flip:
|
||||
if swap:
|
||||
val_a, val_b = val_b, val_a
|
||||
#size = max(1, int(typ.value / 10))
|
||||
|
||||
size = max(1, int(typ.value / 10))
|
||||
val_a = val_a[:size+1]
|
||||
val_b = val_b[:size+1]
|
||||
|
||||
@@ -756,10 +750,11 @@ Execute binary operations like addition, subtraction, multiplication, division,
|
||||
default = val
|
||||
if len(val) == 0:
|
||||
default = [0]
|
||||
|
||||
val = parse_value(val, typ, default)
|
||||
results.append(val)
|
||||
pbar.update_absolute(idx)
|
||||
return results
|
||||
return (results,)
|
||||
|
||||
class StringerNode(CozyBaseNode):
|
||||
NAME = "STRINGER (JOV) 🪀"
|
||||
@@ -778,34 +773,32 @@ Manipulate strings through filtering
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
# split, join, replace, trim/lift
|
||||
"FUNCTION": (EnumConvertString._member_names_, {
|
||||
"default": EnumConvertString.SPLIT.name,
|
||||
"tooltip":"Operation to perform on the input string"}),
|
||||
"KEY": ("STRING", {
|
||||
Lexicon.FUNCTION: (EnumConvertString._member_names_, {
|
||||
"default": EnumConvertString.SPLIT.name}),
|
||||
Lexicon.KEY: ("STRING", {
|
||||
"default":"", "dynamicPrompt":False,
|
||||
"tooltip":"Delimiter (SPLIT/JOIN) or string to use as search string (FIND/REPLACE)."}),
|
||||
"REPLACE": ("STRING", {
|
||||
"tooltip": "Delimiter (SPLIT/JOIN) or string to use as search string (FIND/REPLACE)."}),
|
||||
Lexicon.REPLACE: ("STRING", {
|
||||
"default":"", "dynamicPrompt":False}),
|
||||
"RANGE": ("VEC3", {
|
||||
Lexicon.RANGE: ("VEC3", {
|
||||
"default":(0, -1, 1), "int": True,
|
||||
"tooltip":"Start, End and Step. Values will clip to the actual list size(s)."}),
|
||||
"tooltip": "Start, End and Step. Values will clip to the actual list size(s)."}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[TensorType, ...]:
|
||||
# turn any all inputs into the
|
||||
data_list = parse_dynamic(kw, "STRING", EnumConvertType.ANY, "")
|
||||
data_list = parse_dynamic(kw, Lexicon.STRING, EnumConvertType.ANY, "")
|
||||
if data_list is None:
|
||||
logger.warn("no data for list")
|
||||
return ([], 0)
|
||||
|
||||
op = parse_param(kw, "FUNCTION", EnumConvertString, EnumConvertString.SPLIT.name)[0]
|
||||
key = parse_param(kw, "KEY", EnumConvertType.STRING, "")[0]
|
||||
replace = parse_param(kw, "REPLACE", EnumConvertType.STRING, "")[0]
|
||||
stenst = parse_param(kw, "RANGE", EnumConvertType.VEC3INT, (0, -1, 1))[0]
|
||||
op = parse_param(kw, Lexicon.FUNCTION, EnumConvertString, EnumConvertString.SPLIT.name)[0]
|
||||
key = parse_param(kw, Lexicon.KEY, EnumConvertType.STRING, "")[0]
|
||||
replace = parse_param(kw, Lexicon.REPLACE, EnumConvertType.STRING, "")[0]
|
||||
stenst = parse_param(kw, Lexicon.RANGE, EnumConvertType.VEC3INT, (0, -1, 1))[0]
|
||||
results = []
|
||||
print(data_list)
|
||||
match op:
|
||||
case EnumConvertString.SPLIT:
|
||||
results = data_list
|
||||
@@ -837,7 +830,7 @@ class SwizzleNode(CozyBaseNode):
|
||||
NAME = "SWIZZLE (JOV) 😵"
|
||||
CATEGORY = JOV_CATEGORY
|
||||
RETURN_TYPES = (COZY_TYPE_ANY,)
|
||||
RETURN_NAMES = ("🦄",)
|
||||
RETURN_NAMES = ("❔",)
|
||||
OUTPUT_IS_LIST = (True,)
|
||||
SORT = 40
|
||||
DESCRIPTION = """
|
||||
@@ -850,44 +843,32 @@ Swap components between two vectors based on specified swizzle patterns and valu
|
||||
names_convert = EnumConvertType._member_names_[3:6]
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"A": (COZY_TYPE_NUMERICAL, {}),
|
||||
"B": (COZY_TYPE_NUMERICAL, {}),
|
||||
"TYPE": (names_convert, {
|
||||
"default": names_convert[2],
|
||||
"tooltip":"Output type desired from resultant operation"
|
||||
}),
|
||||
"SWAP_X": (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_X.name,
|
||||
"tooltip": "Replace input Red channel with target channel or constant"
|
||||
}),
|
||||
"SWAP_Y": (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_Y.name,
|
||||
"tooltip": "Replace input Green channel with target channel or constant"
|
||||
}),
|
||||
"SWAP_Z": (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_Z.name,
|
||||
"tooltip": "Replace input Blue channel with target channel or constant"
|
||||
}),
|
||||
"SWAP_W": (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_W.name,
|
||||
"tooltip": "Replace input W channel with target channel or constant"
|
||||
}),
|
||||
"VEC": ("VEC4", {
|
||||
"default": (0,0,0,0), "mij": -sys.maxsize, "maj": sys.maxsize,
|
||||
"tooltip": "Default values for missing channels"
|
||||
})
|
||||
Lexicon.IN_A: (COZY_TYPE_NUMERICAL, {}),
|
||||
Lexicon.IN_B: (COZY_TYPE_NUMERICAL, {}),
|
||||
Lexicon.TYPE: (names_convert, {
|
||||
"default": names_convert[2]}),
|
||||
Lexicon.SWAP_X: (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_X.name,}),
|
||||
Lexicon.SWAP_Y: (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_Y.name,}),
|
||||
Lexicon.SWAP_Z: (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_Z.name,}),
|
||||
Lexicon.SWAP_W: (EnumSwizzle._member_names_, {
|
||||
"default": EnumSwizzle.A_W.name,}),
|
||||
Lexicon.DEFAULT: ("VEC4", {
|
||||
"default": (0,0,0,0), "mij": -sys.maxsize, "maj": sys.maxsize})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[TensorType, ...]:
|
||||
pA = parse_param(kw, "A", EnumConvertType.VEC4, (0,0,0,0))
|
||||
pB = parse_param(kw, "B", EnumConvertType.VEC4, (0,0,0,0))
|
||||
swap_x = parse_param(kw, "SWAP_X", EnumSwizzle, EnumSwizzle.A_X.name)
|
||||
swap_y = parse_param(kw, "SWAP_Y", EnumSwizzle, EnumSwizzle.A_Y.name)
|
||||
swap_z = parse_param(kw, "SWAP_Z", EnumSwizzle, EnumSwizzle.A_W.name)
|
||||
swap_w = parse_param(kw, "SWAP_W", EnumSwizzle, EnumSwizzle.A_Z.name)
|
||||
default = parse_param(kw, "VEC", EnumConvertType.VEC4, 0, -sys.maxsize, sys.maxsize)
|
||||
pA = parse_param(kw, Lexicon.IN_A, EnumConvertType.VEC4, (0,0,0,0))
|
||||
pB = parse_param(kw, Lexicon.IN_B, EnumConvertType.VEC4, (0,0,0,0))
|
||||
swap_x = parse_param(kw, Lexicon.SWAP_X, EnumSwizzle, EnumSwizzle.A_X.name)
|
||||
swap_y = parse_param(kw, Lexicon.SWAP_Y, EnumSwizzle, EnumSwizzle.A_Y.name)
|
||||
swap_z = parse_param(kw, Lexicon.SWAP_Z, EnumSwizzle, EnumSwizzle.A_W.name)
|
||||
swap_w = parse_param(kw, Lexicon.SWAP_W, EnumSwizzle, EnumSwizzle.A_Z.name)
|
||||
default = parse_param(kw, Lexicon.DEFAULT, EnumConvertType.VEC4, 0, -sys.maxsize, sys.maxsize)
|
||||
|
||||
params = list(zip_longest_fill(pA, pB, swap_x, x, swap_y, y, swap_z, z, swap_w, w))
|
||||
results = []
|
||||
|
||||
+95
-129
@@ -13,6 +13,9 @@ from cozy_comfyui import \
|
||||
InputType, RGBAMaskType, EnumConvertType, TensorType, \
|
||||
deep_merge, parse_param, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_IMAGE, \
|
||||
CozyBaseNode, CozyImageNode
|
||||
@@ -72,30 +75,22 @@ Simulate color blindness effects on images. You can select various types of colo
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"DEFICIENCY": (EnumCBDeficiency._member_names_, {
|
||||
"default": EnumCBDeficiency.PROTAN.name,
|
||||
"tooltip": "Type of color deficiency: Red (Protanopia), Green (Deuteranopia), Blue (Tritanopia)"
|
||||
}),
|
||||
"SIMULATOR": (EnumCBSimulator._member_names_, {
|
||||
"default": EnumCBSimulator.AUTOSELECT.name,
|
||||
"tooltip": "Solver to use when translating to new color space"
|
||||
}),
|
||||
"VAL": ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": 1, "step": 0.001,
|
||||
"tooltip": "alpha blending"
|
||||
}),
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.DEFICIENCY: (EnumCBDeficiency._member_names_, {
|
||||
"default": EnumCBDeficiency.PROTAN.name,}),
|
||||
Lexicon.SOLVER: (EnumCBSimulator._member_names_, {
|
||||
"default": EnumCBSimulator.AUTOSELECT.name,}),
|
||||
Lexicon.ALPHA: ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": 1, "step": 0.001,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
deficiency = parse_param(kw, "DEFICIENCY", EnumCBDeficiency, EnumCBDeficiency.PROTAN.name)
|
||||
simulator = parse_param(kw, "SIMULATOR", EnumCBSimulator, EnumCBSimulator.AUTOSELECT.name)
|
||||
severity = parse_param(kw, "VAL", EnumConvertType.FLOAT, 1)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
deficiency = parse_param(kw, Lexicon.DEFICIENCY, EnumCBDeficiency, EnumCBDeficiency.PROTAN.name)
|
||||
simulator = parse_param(kw, Lexicon.SOLVER, EnumCBSimulator, EnumCBSimulator.AUTOSELECT.name)
|
||||
severity = parse_param(kw, Lexicon.VALUE, EnumConvertType.FLOAT, 1)
|
||||
params = list(zip_longest_fill(pA, deficiency, simulator, severity))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -118,55 +113,43 @@ Adjust the color scheme of one image to match another with the Color Match Node.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"SOURCE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"TARGET": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"MODE": (EnumColorMatchMode._member_names_, {
|
||||
Lexicon.IMAGE_SOURCE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.IMAGE_TARGET: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.MODE: (EnumColorMatchMode._member_names_, {
|
||||
"default": EnumColorMatchMode.REINHARD.name,
|
||||
"tooltip": "Match colors from an image or built-in (LUT), Histogram lookups or Reinhard method"
|
||||
}),
|
||||
"MAP": (EnumColorMatchMap._member_names_, {
|
||||
"default": EnumColorMatchMap.USER_MAP.name,
|
||||
"tooltip": "Custom image that will be transformed into a LUT or a built-in cv2 LUT"
|
||||
}),
|
||||
"COLORMAP": (EnumColorMap._member_names_, {
|
||||
"default": EnumColorMap.HSV.name,
|
||||
"tooltip": "One of two dozen CV2 Built-in Colormap LUT (Look Up Table) Presets"
|
||||
}),
|
||||
"VAL": ("INT", {
|
||||
"tooltip": "Match colors from an image or built-in (LUT), Histogram lookups or Reinhard method"}),
|
||||
Lexicon.MAP: (EnumColorMatchMap._member_names_, {
|
||||
"default": EnumColorMatchMap.USER_MAP.name, }),
|
||||
Lexicon.COLORMAP: (EnumColorMap._member_names_, {
|
||||
"default": EnumColorMap.HSV.name,}),
|
||||
Lexicon.VALUE: ("INT", {
|
||||
"default": 255, "min": 0, "max": 255,
|
||||
"tooltip":"The number of colors to use from the LUT during the remap. Will quantize the LUT range."}),
|
||||
"FLIP": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Flip the SOURCE and TARGET inputs"}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Invert the color match output"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"}),
|
||||
Lexicon.SWAP: ("BOOLEAN", {
|
||||
"default": False,}),
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "SOURCE", EnumConvertType.IMAGE, None)
|
||||
pB = parse_param(kw, "TARGET", EnumConvertType.IMAGE, None)
|
||||
colormatch_mode = parse_param(kw, "MODE", EnumColorMatchMode, EnumColorMatchMode.REINHARD.name)
|
||||
colormatch_map = parse_param(kw, f"MAP", EnumColorMatchMap, EnumColorMatchMap.USER_MAP.name)
|
||||
colormap = parse_param(kw, "COLORMAP", EnumColorMap, EnumColorMap.HSV.name)
|
||||
num_colors = parse_param(kw, "VAL", EnumConvertType.INT, 255)
|
||||
flip = parse_param(kw, "FLIP", EnumConvertType.BOOLEAN, False)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4, (0, 0, 0, 255), 0, 255)
|
||||
params = list(zip_longest_fill(pA, pB, colormap, colormatch_mode, colormatch_map, num_colors, flip, invert, matte))
|
||||
pA = parse_param(kw, Lexicon.IMAGE_SOURCE, EnumConvertType.IMAGE, None)
|
||||
pB = parse_param(kw, Lexicon.IMAGE_TARGET, EnumConvertType.IMAGE, None)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumColorMatchMode, EnumColorMatchMode.REINHARD.name)
|
||||
cmap = parse_param(kw, Lexicon.MAP, EnumColorMatchMap, EnumColorMatchMap.USER_MAP.name)
|
||||
colormap = parse_param(kw, Lexicon.COLORMAP, EnumColorMap, EnumColorMap.HSV.name)
|
||||
num_colors = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, 255)
|
||||
swap = parse_param(kw, Lexicon.SWAP, EnumConvertType.BOOLEAN, False)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4, (0, 0, 0, 255), 0, 255)
|
||||
params = list(zip_longest_fill(pA, pB, mode, cmap, colormap, num_colors, swap, invert, matte))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (pA, pB, colormap, mode, cmap, num_colors, flip, invert, matte) in enumerate(params):
|
||||
if flip == True:
|
||||
for idx, (pA, pB, mode, cmap, colormap, num_colors, swap, invert, matte) in enumerate(params):
|
||||
if swap == True:
|
||||
pA, pB = pB, pA
|
||||
|
||||
mask = None
|
||||
@@ -223,35 +206,30 @@ The top-k colors ordered from most->least used as a strip, tonal palette and 3D
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"VAL": ("INT", {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.VALUE: ("INT", {
|
||||
"default": 12, "min": 1, "max": 255,
|
||||
"tooltip":"The top K colors to select."
|
||||
}),
|
||||
"SIZE": ("INT", {
|
||||
"tooltip": "The top K colors to select"}),
|
||||
Lexicon.SIZE: ("INT", {
|
||||
"default": 32, "min": 1, "max": 256,
|
||||
"tooltip":"Height of the tones in the strip. Width is based on input."
|
||||
}),
|
||||
"COUNT": ("INT", {
|
||||
"tooltip": "Height of the tones in the strip. Width is based on input"}),
|
||||
Lexicon.COUNT: ("INT", {
|
||||
"default": 33, "min": 3, "max": 256,
|
||||
"tooltip":"Number of nodes to use in interpolation of full LUT (256 is every pixel)."
|
||||
}),
|
||||
"WH": ("VEC2", {
|
||||
"tooltip": "Number of nodes to use in interpolation of full LUT (256 is every pixel)"}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (256, 256), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"]
|
||||
}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
kcolors = parse_param(kw, "VAL", EnumConvertType.INT, 12, 1, 255)
|
||||
lut_height = parse_param(kw, "SIZE", EnumConvertType.INT, 32, 1, 256)
|
||||
nodes = parse_param(kw, "COUNT", EnumConvertType.INT, 33, 1, 255)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (256, 256), IMAGE_SIZE_MIN)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
kcolors = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, 12, 1, 255)
|
||||
lut_height = parse_param(kw, Lexicon.SIZE, EnumConvertType.INT, 32, 1, 256)
|
||||
nodes = parse_param(kw, Lexicon.COUNT, EnumConvertType.INT, 33, 1, 255)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (256, 256), IMAGE_SIZE_MIN)
|
||||
|
||||
params = list(zip_longest_fill(pA, kcolors, nodes, lut_height, wihi))
|
||||
top_colors = []
|
||||
@@ -299,27 +277,23 @@ Users can customize the angle of separation for color calculations, offering fle
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"SCHEME": (EnumColorTheory._member_names_, {
|
||||
"default": EnumColorTheory.COMPLIMENTARY.name
|
||||
}),
|
||||
"VAL": ("INT", {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.SCHEME: (EnumColorTheory._member_names_, {
|
||||
"default": EnumColorTheory.COMPLIMENTARY.name}),
|
||||
Lexicon.VALUE: ("INT", {
|
||||
"default": 45, "min": -90, "max": 90,
|
||||
"tooltip": "Custom angle of separation to use when calculating colors"
|
||||
}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
"tooltip": "Custom angle of separation to use when calculating colors"}),
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[List[TensorType], List[TensorType]]:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
scheme = parse_param(kw, "SCHEME", EnumColorTheory, EnumColorTheory.COMPLIMENTARY.name)
|
||||
user = parse_param(kw, "VAL", EnumConvertType.INT, 0, -180, 180)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
scheme = parse_param(kw, Lexicon.SCHEME, EnumColorTheory, EnumColorTheory.COMPLIMENTARY.name)
|
||||
user = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, 0, -180, 180)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(pA, scheme, user, invert))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -347,48 +321,38 @@ The gradient image will be translated into a single row lookup table.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip":"Image to remap with gradient input"
|
||||
}),
|
||||
"GRADIENT": (COZY_TYPE_IMAGE, {
|
||||
"tooltip":f"Look up table (LUT) to remap the input image in `{"IMAGE"}`"
|
||||
}),
|
||||
"FLIP": ("BOOLEAN", {
|
||||
"default":False,
|
||||
"tooltip":"Reverse the gradient from left-to-right "
|
||||
}),
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"
|
||||
}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Image to remap with gradient input"}),
|
||||
Lexicon.GRADIENT: (COZY_TYPE_IMAGE, {
|
||||
"tooltip": f"Look up table (LUT) to remap the input image in `{"IMAGE"}`"}),
|
||||
Lexicon.REVERSE: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Reverse the gradient from left-to-right"}),
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"]
|
||||
}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"
|
||||
}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"
|
||||
})
|
||||
"label": ["W", "H"] }),
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
gradient = parse_param(kw, "GRADIENT", EnumConvertType.IMAGE, None)
|
||||
flip = parse_param(kw, "FLIP", EnumConvertType.BOOLEAN, False)
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
gradient = parse_param(kw, Lexicon.GRADIENT, EnumConvertType.IMAGE, None)
|
||||
reverse = parse_param(kw, Lexicon.REVERSE, EnumConvertType.BOOLEAN, False)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
images = []
|
||||
params = list(zip_longest_fill(pA, gradient, flip, mode, sample, wihi, matte))
|
||||
params = list(zip_longest_fill(pA, gradient, reverse, mode, sample, wihi, matte))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (pA, gradient, flip, mode, sample, wihi, matte) in enumerate(params):
|
||||
for idx, (pA, gradient, reverse, mode, sample, wihi, matte) in enumerate(params):
|
||||
pA = channel_solid(chan=EnumImageType.BGR) if pA is None else tensor_to_cv(pA)
|
||||
mask = None
|
||||
if pA.ndim == 3 and pA.shape[2] == 4:
|
||||
@@ -399,8 +363,10 @@ The gradient image will be translated into a single row lookup table.
|
||||
if mode != EnumScaleMode.MATTE:
|
||||
w, h = wihi
|
||||
pA = image_scalefit(pA, w, h, mode, sample)
|
||||
|
||||
if mask is not None:
|
||||
pA = image_mask_add(pA, mask)
|
||||
|
||||
images.append(cv_to_tensor_full(pA, matte))
|
||||
pbar.update_absolute(idx)
|
||||
return image_stack(images)
|
||||
|
||||
+144
-189
@@ -10,6 +10,9 @@ from cozy_comfyui import \
|
||||
InputType, RGBAMaskType, EnumConvertType, \
|
||||
deep_merge, parse_param, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_IMAGE, \
|
||||
CozyBaseNode, CozyImageNode
|
||||
@@ -62,57 +65,49 @@ Advanced options include pixelation, quantization, and morphological operations
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"MASK": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"FUNCTION": (EnumAdjustOP._member_names_, {
|
||||
"default": EnumAdjustOP.BLUR.name,
|
||||
"tooltip":"Type of adjustment (e.g., blur, sharpen, invert)"}),
|
||||
"RADIUS": ("INT", {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.MASK: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.FUNCTION: (EnumAdjustOP._member_names_, {
|
||||
"default": EnumAdjustOP.BLUR.name,}),
|
||||
Lexicon.RADIUS: ("INT", {
|
||||
"default": 3, "min": 3}),
|
||||
"VAL": ("FLOAT", {
|
||||
Lexicon.VALUE: ("FLOAT", {
|
||||
"default": 1, "min": 0, "step": 0.01}),
|
||||
"LoHi": ("VEC2", {
|
||||
Lexicon.LOHI: ("VEC2", {
|
||||
"default": (0, 1), "mij": 0, "maj": 1,
|
||||
"label": ["Low", "HI"]}),
|
||||
"LMH": ("VEC3", {
|
||||
Lexicon.LMH: ("VEC3", {
|
||||
"default": (0, 0.5, 1), "mij": 0, "maj": 1,
|
||||
"label": ["Low", "MID", "HI"],
|
||||
"tooltip": "Low, Middle, High"}),
|
||||
"HSV": ("VEC3",{
|
||||
"label": ["Low", "MID", "HI"],}),
|
||||
Lexicon.HSV: ("VEC3",{
|
||||
"default": (0, 1, 1), "mij": 0, "maj": 1,
|
||||
"label": ["H", "S", "V"],
|
||||
"tooltip": "Hue, Saturation and Value"}),
|
||||
"CONTRAST": ("FLOAT", {
|
||||
"label": ["H", "S", "V"],}),
|
||||
Lexicon.CONTRAST: ("FLOAT", {
|
||||
"default": 0, "min": 0, "max": 1, "step": 0.01}),
|
||||
"GAMMA": ("FLOAT", {
|
||||
Lexicon.GAMMA: ("FLOAT", {
|
||||
"default": 1, "min": 0.00001, "max": 1, "step": 0.01}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,}),
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Invert the mask input"})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, "MASK", EnumConvertType.IMAGE, None)
|
||||
op = parse_param(kw, "FUNCTION", EnumAdjustOP, EnumAdjustOP.BLUR.name)
|
||||
radius = parse_param(kw, "RADIUS", EnumConvertType.INT, 3, 3)
|
||||
val = parse_param(kw, "VAL", EnumConvertType.FLOAT, 0, 0)
|
||||
lohi = parse_param(kw, "LoHi", EnumConvertType.VEC2, (0, 1), 0, 1)
|
||||
lmh = parse_param(kw, "LMH", EnumConvertType.VEC3, (0, 0.5, 1), 0, 1)
|
||||
hsv = parse_param(kw, "HSV", EnumConvertType.VEC3, (0, 1, 1), 0, 1)
|
||||
contrast = parse_param(kw, "CONTRAST", EnumConvertType.FLOAT, 1, 0, 1)
|
||||
gamma = parse_param(kw, "GAMMA", EnumConvertType.FLOAT, 1, 0, 1)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, Lexicon.MASK, EnumConvertType.IMAGE, None)
|
||||
op = parse_param(kw, Lexicon.FUNCTION, EnumAdjustOP, EnumAdjustOP.BLUR.name)
|
||||
radius = parse_param(kw, Lexicon.RADIUS, EnumConvertType.INT, 3, 3)
|
||||
val = parse_param(kw, Lexicon.VALUE, EnumConvertType.FLOAT, 0, 0)
|
||||
lohi = parse_param(kw, Lexicon.LOHI, EnumConvertType.VEC2, (0, 1), 0, 1)
|
||||
lmh = parse_param(kw, Lexicon.LMH, EnumConvertType.VEC3, (0, 0.5, 1), 0, 1)
|
||||
hsv = parse_param(kw, Lexicon.HSV, EnumConvertType.VEC3, (0, 1, 1), 0, 1)
|
||||
contrast = parse_param(kw, Lexicon.CONTRAST, EnumConvertType.FLOAT, 1, 0, 1)
|
||||
gamma = parse_param(kw, Lexicon.GAMMA, EnumConvertType.FLOAT, 1, 0, 1)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(pA, mask, op, radius, val, lohi,
|
||||
lmh, hsv, contrast, gamma, matte, invert))
|
||||
images = []
|
||||
@@ -228,50 +223,43 @@ Combine two input images using various blending modes, such as normal, screen, m
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE_A": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Background Plate"}),
|
||||
"IMAGE_B": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Image to Overlay on Background Plate"}),
|
||||
"MASK": (COZY_TYPE_IMAGE, {
|
||||
Lexicon.IMAGE_BACK: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.IMAGE_FORE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.MASK: (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Optional Mask to use for Alpha Blend Operation. If empty, will use the ALPHA of B"}),
|
||||
"FUNCTION": (EnumBlendType._member_names_, {
|
||||
"default": EnumBlendType.NORMAL.name,
|
||||
"tooltip": "Blending Operation"}),
|
||||
"ALPHA": ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": 1, "step": 0.01,
|
||||
"tooltip": "Amount of Blending to Perform on the Selected Operation"}),
|
||||
"FLIP": ("BOOLEAN", {
|
||||
Lexicon.FUNCTION: (EnumBlendType._member_names_, {
|
||||
"default": EnumBlendType.NORMAL.name,}),
|
||||
Lexicon.ALPHA: ("FLOAT", {
|
||||
"default": 1, "min": 0, "max": 1, "step": 0.01,}),
|
||||
Lexicon.FLIP: ("BOOLEAN", {
|
||||
"default": False}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False, "tooltip": "Invert the mask input"}),
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"]}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"})
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE_A", EnumConvertType.IMAGE, None)
|
||||
pB = parse_param(kw, "IMAGE_B", EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, "MASK", EnumConvertType.MASK, None)
|
||||
func = parse_param(kw, "FUNCTION", EnumBlendType, EnumBlendType.NORMAL.name)
|
||||
alpha = parse_param(kw, "ALPHA", EnumConvertType.FLOAT, 1, 0, 1)
|
||||
flip = parse_param(kw, "FLIP", EnumConvertType.BOOLEAN, False)
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
pA = parse_param(kw, Lexicon.IMAGE_BACK, EnumConvertType.IMAGE, None)
|
||||
pB = parse_param(kw, Lexicon.IMAGE_FORE, EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, Lexicon.MASK, EnumConvertType.MASK, None)
|
||||
func = parse_param(kw, Lexicon.FUNCTION, EnumBlendType, EnumBlendType.NORMAL.name)
|
||||
alpha = parse_param(kw, Lexicon.ALPHA, EnumConvertType.FLOAT, 1, 0, 1)
|
||||
flip = parse_param(kw, Lexicon.FLIP, EnumConvertType.BOOLEAN, False)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(pA, pB, mask, func, alpha, flip, mode, wihi, sample, matte, invert))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -335,33 +323,29 @@ Create masks based on specific color ranges within an image. Specify the color r
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"START": ("VEC3", {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.START: ("VEC3", {
|
||||
"default": (128, 128, 128), "rgb": True}),
|
||||
"RANGE": ("BOOLEAN", {
|
||||
Lexicon.RANGE: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "use an end point (start->end) when calculating the filter range"}),
|
||||
"END": ("VEC3", {
|
||||
"tooltip": "Use an end point (start->end) when calculating the filter range"}),
|
||||
Lexicon.END: ("VEC3", {
|
||||
"default": (128, 128, 128), "rgb": True}),
|
||||
"FUZZ": ("VEC3", {
|
||||
"default": (0.5,0.5,0.5), "mij":0, "maj":1,
|
||||
"tooltip": "the fuzziness use to extend the start and end range(s)"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"}),
|
||||
Lexicon.FUZZ: ("VEC3", {
|
||||
"default": (0.5,0.5,0.5), "mij":0, "maj":1,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
start = parse_param(kw, "START", EnumConvertType.VEC3INT, (128,128,128), 0, 255)
|
||||
use_range = parse_param(kw, "RANGE", EnumConvertType.BOOLEAN, False, 0, 255)
|
||||
end = parse_param(kw, "END", EnumConvertType.VEC3INT, (128,128,128), 0, 255)
|
||||
fuzz = parse_param(kw, "FUZZ", EnumConvertType.VEC3, (0.5,0.5,0.5), 0, 1)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
start = parse_param(kw, Lexicon.START, EnumConvertType.VEC3INT, (128,128,128), 0, 255)
|
||||
use_range = parse_param(kw, Lexicon.RANGE, EnumConvertType.BOOLEAN, False, 0, 255)
|
||||
end = parse_param(kw, Lexicon.END, EnumConvertType.VEC3INT, (128,128,128), 0, 255)
|
||||
fuzz = parse_param(kw, Lexicon.FUZZ, EnumConvertType.VEC3, (0.5,0.5,0.5), 0, 1)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
params = list(zip_longest_fill(pA, start, use_range, end, fuzz, matte))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -390,56 +374,41 @@ Combines individual color channels (red, green, blue) along with an optional mas
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"🟥": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Red"
|
||||
}),
|
||||
"🟩": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Green"
|
||||
}),
|
||||
"🟦": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Blue"
|
||||
}),
|
||||
"⬜": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Alpha"
|
||||
}),
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.CHAN_RED: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.CHAN_GREEN: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.CHAN_BLUE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.CHAN_ALPHA: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"],
|
||||
"tooltip": "Width and Height"}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"}),
|
||||
"FLIP": ("VEC4", {
|
||||
"label": ["W", "H"],}),
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,}),
|
||||
Lexicon.FLIP: ("VEC4", {
|
||||
"default": (0,0,0,0), "mij":0, "maj":1,
|
||||
"tooltip": "Invert specific input prior to merging. R, G, B, A."}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Invert the final merged output"})
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
rgba = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
R = parse_param(kw, "🟥", EnumConvertType.MASK, None)
|
||||
G = parse_param(kw, "🟩", EnumConvertType.MASK, None)
|
||||
B = parse_param(kw, "🟦", EnumConvertType.MASK, None)
|
||||
A = parse_param(kw, "⬜", EnumConvertType.MASK, None)
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
flip = parse_param(kw, "FLIP", EnumConvertType.VEC4, (0, 0, 0, 0), 0., 1.)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
rgba = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
R = parse_param(kw, Lexicon.CHAN_RED, EnumConvertType.MASK, None)
|
||||
G = parse_param(kw, Lexicon.CHAN_GREEN, EnumConvertType.MASK, None)
|
||||
B = parse_param(kw, Lexicon.CHAN_BLUE, EnumConvertType.MASK, None)
|
||||
A = parse_param(kw, Lexicon.CHAN_ALPHA, EnumConvertType.MASK, None)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
flip = parse_param(kw, Lexicon.FLIP, EnumConvertType.VEC4, (0, 0, 0, 0), 0., 1.)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(rgba, R, G, B, A, mode, wihi, sample, matte, flip, invert))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -498,16 +467,14 @@ Takes an input image and splits it into its individual color channels (red, gree
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
})
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
images = []
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
pbar = ProgressBar(len(pA))
|
||||
for idx, pA in enumerate(pA):
|
||||
pA = channel_solid(chan=EnumImageType.BGRA) if pA is None else tensor_to_cv(pA)
|
||||
@@ -528,39 +495,30 @@ Swap pixel values between two input images based on specified channel swizzle op
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE_A": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"IMAGE_B": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"SWAP_R": (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.RED_A.name,
|
||||
"tooltip": "Replace input Red channel with target channel or constant"}),
|
||||
"SWAP_G": (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.GREEN_A.name,
|
||||
"tooltip": "Replace input Green channel with target channel or constant"}),
|
||||
"SWAP_B": (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.BLUE_A.name,
|
||||
"tooltip": "Replace input Blue channel with target channel or constant"}),
|
||||
"SWAP_A": (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.ALPHA_A.name,
|
||||
"tooltip": "Replace input Alpha channel with target channel or constant"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"})
|
||||
Lexicon.IMAGE_SOURCE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.IMAGE_TARGET: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.SWAP_R: (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.RED_A.name,}),
|
||||
Lexicon.SWAP_G: (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.GREEN_A.name,}),
|
||||
Lexicon.SWAP_B: (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.BLUE_A.name,}),
|
||||
Lexicon.SWAP_A: (EnumPixelSwizzle._member_names_, {
|
||||
"default": EnumPixelSwizzle.ALPHA_A.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE_A", EnumConvertType.IMAGE, None)
|
||||
pB = parse_param(kw, "IMAGE_B", EnumConvertType.IMAGE, None)
|
||||
swap_r = parse_param(kw, "SWAP_R", EnumPixelSwizzle, EnumPixelSwizzle.RED_A.name)
|
||||
swap_g = parse_param(kw, "SWAP_G", EnumPixelSwizzle, EnumPixelSwizzle.GREEN_A.name)
|
||||
swap_b = parse_param(kw, "SWAP_B", EnumPixelSwizzle, EnumPixelSwizzle.BLUE_A.name)
|
||||
swap_a = parse_param(kw, "SWAP_A", EnumPixelSwizzle, EnumPixelSwizzle.ALPHA_A.name)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
pA = parse_param(kw, Lexicon.IMAGE_SOURCE, EnumConvertType.IMAGE, None)
|
||||
pB = parse_param(kw, Lexicon.IMAGE_TARGET, EnumConvertType.IMAGE, None)
|
||||
swap_r = parse_param(kw, Lexicon.SWAP_R, EnumPixelSwizzle, EnumPixelSwizzle.RED_A.name)
|
||||
swap_g = parse_param(kw, Lexicon.SWAP_G, EnumPixelSwizzle, EnumPixelSwizzle.GREEN_A.name)
|
||||
swap_b = parse_param(kw, Lexicon.SWAP_B, EnumPixelSwizzle, EnumPixelSwizzle.BLUE_A.name)
|
||||
swap_a = parse_param(kw, Lexicon.SWAP_A, EnumPixelSwizzle, EnumPixelSwizzle.ALPHA_A.name)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
params = list(zip_longest_fill(pA, pB, swap_r, swap_g, swap_b, swap_a, matte))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -602,32 +560,29 @@ Define a range and apply it to an image for segmentation and feature extraction.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"ADAPT": ( EnumThresholdAdapt._member_names_, {
|
||||
"default": EnumThresholdAdapt.ADAPT_NONE.name,
|
||||
"tooltip": "X-Men"}),
|
||||
"FUNCTION": ( EnumThreshold._member_names_, {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.ADAPT: ( EnumThresholdAdapt._member_names_, {
|
||||
"default": EnumThresholdAdapt.ADAPT_NONE.name,}),
|
||||
Lexicon.FUNCTION: ( EnumThreshold._member_names_, {
|
||||
"default": EnumThreshold.BINARY.name}),
|
||||
"THRESHOLD": ("FLOAT", {
|
||||
Lexicon.THRESHOLD: ("FLOAT", {
|
||||
"default": 0.5, "min": 0, "max": 1, "step": 0.005}),
|
||||
"SIZE": ("INT", {
|
||||
Lexicon.SIZE: ("INT", {
|
||||
"default": 3, "min": 3, "max": 103}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Invert the mask input"})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
mode = parse_param(kw, "FUNCTION", EnumThreshold, EnumThreshold.BINARY.name)
|
||||
adapt = parse_param(kw, "ADAPT", EnumThresholdAdapt, EnumThresholdAdapt.ADAPT_NONE.name)
|
||||
threshold = parse_param(kw, "THRESHOLD", EnumConvertType.FLOAT, 1, 0, 1)
|
||||
block = parse_param(kw, "SIZE", EnumConvertType.INT, 3, 3)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
mode = parse_param(kw, Lexicon.FUNCTION, EnumThreshold, EnumThreshold.BINARY.name)
|
||||
adapt = parse_param(kw, Lexicon.ADAPT, EnumThresholdAdapt, EnumThresholdAdapt.ADAPT_NONE.name)
|
||||
threshold = parse_param(kw, Lexicon.THRESHOLD, EnumConvertType.FLOAT, 1, 0, 1)
|
||||
block = parse_param(kw, Lexicon.SIZE, EnumConvertType.INT, 3, 3)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(pA, mode, adapt, threshold, block, invert))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -656,14 +611,14 @@ The Histogram Node generates a histogram representation of the input image, show
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
Lexicon.IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", None), EnumConvertType.IMAGE, None)
|
||||
pA = parse_param(kw, Lexicon.IMAGE", None), EnumConvertType.IMAGE, None)
|
||||
params = list(zip_longest_fill(pA,))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
|
||||
+86
-195
@@ -11,6 +11,9 @@ from cozy_comfyui import \
|
||||
InputType, EnumConvertType, RGBAMaskType, \
|
||||
deep_merge, parse_param, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_IMAGE, \
|
||||
CozyImageNode
|
||||
@@ -58,34 +61,31 @@ Generate a constant image or mask of a specified size and color. It can be used
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {
|
||||
"tooltip":"Optional Image to Matte with Selected Color"}),
|
||||
"MASK": (COZY_TYPE_IMAGE, {
|
||||
Lexicon.MASK: (COZY_TYPE_IMAGE, {
|
||||
"tooltip":"Override Image mask"}),
|
||||
"COLOR": ("VEC4", {
|
||||
Lexicon.COLOR: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Constant Color to Output"}),
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "int": True,
|
||||
"label": ["W", "H"],
|
||||
"tooltip": "Desired Width and Height of the Color Output"}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"})
|
||||
"label": ["W", "H"],}),
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, "MASK", EnumConvertType.IMAGE, None)
|
||||
matte = parse_param(kw, "COLOR", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, Lexicon.MASK, EnumConvertType.IMAGE, None)
|
||||
matte = parse_param(kw, Lexicon.COLOR, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
images = []
|
||||
params = list(zip_longest_fill(pA, mask, matte, wihi, mode, sample))
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -125,47 +125,43 @@ Create n-sided polygons. These shapes can be customized by adjusting parameters
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"SHAPE": (EnumShapes._member_names_, {
|
||||
Lexicon.SHAPE: (EnumShapes._member_names_, {
|
||||
"default": EnumShapes.CIRCLE.name}),
|
||||
"SIDES": ("INT", {
|
||||
Lexicon.SIDES: ("INT", {
|
||||
"default": 3, "min": 3, "max": 100}),
|
||||
"COLOR": ("VEC4", {
|
||||
Lexicon.COLOR: ("VEC4", {
|
||||
"default": (255, 255, 255, 255), "rgb": True,
|
||||
"tooltip": "Main Shape Color"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (256, 256), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"],
|
||||
"tooltip": "Width and Height"}),
|
||||
"XY": ("VEC2", {
|
||||
"label": ["W", "H"],}),
|
||||
Lexicon.XY: ("VEC2", {
|
||||
"default": (0, 0,), "label": ["X", "Y"]}),
|
||||
"ANGLE": ("FLOAT", {
|
||||
"default": 0, "min": -180, "max": 180, "step": 0.01,
|
||||
"tooltip": "Rotation Angle"}),
|
||||
"SIZE": ("VEC2", {
|
||||
Lexicon.ANGLE: ("FLOAT", {
|
||||
"default": 0, "min": -180, "max": 180, "step": 0.01,}),
|
||||
Lexicon.SIZE: ("VEC2", {
|
||||
"default": (1., 1.), "label": ["X", "Y"]}),
|
||||
"EDGE": (EnumEdge._member_names_, {
|
||||
Lexicon.EDGE: (EnumEdge._member_names_, {
|
||||
"default": EnumEdge.CLIP.name}),
|
||||
"BLUR": ("FLOAT", {
|
||||
"default": 0, "min": 0, "step": 0.01,
|
||||
"tooltip": "Edge blur amount (Gaussian blur)"}),
|
||||
Lexicon.BLUR: ("FLOAT", {
|
||||
"default": 0, "min": 0, "step": 0.01,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
shape = parse_param(kw, "SHAPE", EnumShapes, EnumShapes.CIRCLE.name)
|
||||
sides = parse_param(kw, "SIDES", EnumConvertType.INT, 3, 3, 100)
|
||||
angle = parse_param(kw, "ANGLE", EnumConvertType.FLOAT, 0)
|
||||
edge = parse_param(kw, "EDGE", EnumEdge, EnumEdge.CLIP.name)
|
||||
offset = parse_param(kw, "XY", EnumConvertType.VEC2, (0, 0))
|
||||
size = parse_param(kw, "SIZE", EnumConvertType.VEC2, (1, 1), zero=0.001)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (256, 256), IMAGE_SIZE_MIN)
|
||||
color = parse_param(kw, "COLOR", EnumConvertType.VEC4INT, (255, 255, 255, 255), 0, 255)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
blur = parse_param(kw, "BLUR", EnumConvertType.FLOAT, 0)
|
||||
shape = parse_param(kw, Lexicon.SHAPE, EnumShapes, EnumShapes.CIRCLE.name)
|
||||
sides = parse_param(kw, Lexicon.SIDES, EnumConvertType.INT, 3, 3, 100)
|
||||
angle = parse_param(kw, Lexicon.ANGLE, EnumConvertType.FLOAT, 0)
|
||||
edge = parse_param(kw, Lexicon.EDGE, EnumEdge, EnumEdge.CLIP.name)
|
||||
offset = parse_param(kw, Lexicon.XY, EnumConvertType.VEC2, (0, 0))
|
||||
size = parse_param(kw, Lexicon.SIZE, EnumConvertType.VEC2, (1, 1), zero=0.001)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (256, 256), IMAGE_SIZE_MIN)
|
||||
color = parse_param(kw, Lexicon.COLOR, EnumConvertType.VEC4INT, (255, 255, 255, 255), 0, 255)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
blur = parse_param(kw, Lexicon.BLUR, EnumConvertType.FLOAT, 0)
|
||||
params = list(zip_longest_fill(shape, sides, offset, angle, edge, size, wihi, color, matte, blur))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -217,78 +213,71 @@ Generates images containing text based on parameters such as font, size, alignme
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"STRING": ("STRING", {
|
||||
Lexicon.STRING: ("STRING", {
|
||||
"default": "jovimetrix", "multiline": True,
|
||||
"dynamicPrompts": False,
|
||||
"tooltip": "Your Message"}),
|
||||
"FONT": (cls.FONT_NAMES, {
|
||||
Lexicon.FONT: (cls.FONT_NAMES, {
|
||||
"default": cls.FONT_NAMES[0]}),
|
||||
"LETTER": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "If each letter be generated and output in a batch"}),
|
||||
"AUTOSIZE": ("BOOLEAN", {
|
||||
Lexicon.LETTER: ("BOOLEAN", {
|
||||
"default": False,}),
|
||||
Lexicon.AUTOSIZE: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Scale based on Width & Height"}),
|
||||
"COLOR": ("VEC4", {
|
||||
Lexicon.COLOR: ("VEC4", {
|
||||
"default": (255, 255, 255, 255), "rgb": True,
|
||||
"tooltip": "Color of the letters"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"}),
|
||||
"COLS": ("INT", {
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,}),
|
||||
Lexicon.COLUMNS: ("INT", {
|
||||
"default": 0, "min": 0}),
|
||||
# if auto on, hide these...
|
||||
"SIZE": ("INT", {
|
||||
Lexicon.SIZE: ("INT", {
|
||||
"default": 16, "min": 8}),
|
||||
"ALIGN": (EnumAlignment._member_names_, {
|
||||
"default": EnumAlignment.CENTER.name,
|
||||
"tooltip": "Top, Center or Bottom alignment"}),
|
||||
"JUSTIFY": (EnumJustify._member_names_, {
|
||||
"default": EnumJustify.CENTER.name,
|
||||
"tooltip": "How to align the text to the side margins of the canvas: Left, Right, or Centered"}),
|
||||
"MARGIN": ("INT", {
|
||||
"default": 0, "min": -1024, "max": 1024,
|
||||
"tooltip": "Whitespace padding around canvas"}),
|
||||
"SPACING": ("INT", {
|
||||
Lexicon.ALIGN: (EnumAlignment._member_names_, {
|
||||
"default": EnumAlignment.CENTER.name,}),
|
||||
Lexicon.JUSTIFY: (EnumJustify._member_names_, {
|
||||
"default": EnumJustify.CENTER.name,}),
|
||||
Lexicon.MARGIN: ("INT", {
|
||||
"default": 0, "min": -1024, "max": 1024,}),
|
||||
Lexicon.SPACING: ("INT", {
|
||||
"default": 0, "min": -1024, "max": 1024}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (256, 256), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"],
|
||||
"tooltip": "Width and Height"}),
|
||||
"XY": ("VEC2", {
|
||||
"label": ["W", "H"],}),
|
||||
Lexicon.XY: ("VEC2", {
|
||||
"default": (0, 0,), "mij": -1, "maj": 1,
|
||||
"label": ["X", "Y"],
|
||||
"tooltip":"Offset the position"}),
|
||||
"ANGLE": ("FLOAT", {
|
||||
"default": 0, "step": 0.01,
|
||||
"tooltip": "Rotation Angle"}),
|
||||
"EDGE": (EnumEdge._member_names_, {
|
||||
Lexicon.ANGLE: ("FLOAT", {
|
||||
"default": 0, "step": 0.01,}),
|
||||
Lexicon.EDGE: (EnumEdge._member_names_, {
|
||||
"default": EnumEdge.CLIP.name}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
Lexicon.INVERT: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip": "Invert the mask input"})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
full_text = parse_param(kw, "STRING", EnumConvertType.STRING, "jovimetrix")
|
||||
font_idx = parse_param(kw, "FONT", EnumConvertType.STRING, self.FONT_NAMES[0])
|
||||
autosize = parse_param(kw, "AUTOSIZE", EnumConvertType.BOOLEAN, False)
|
||||
letter = parse_param(kw, "LETTER", EnumConvertType.BOOLEAN, False)
|
||||
color = parse_param(kw, "COLOR", EnumConvertType.VEC4INT, (255,255,255,255), 0, 255)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0,0,0,255), 0, 255)
|
||||
columns = parse_param(kw, "COLS", EnumConvertType.INT, 0)
|
||||
font_size = parse_param(kw, "SIZE", EnumConvertType.INT, 1)
|
||||
align = parse_param(kw, "ALIGN", EnumAlignment, EnumAlignment.CENTER.name)
|
||||
justify = parse_param(kw, "JUSTIFY", EnumJustify, EnumJustify.CENTER.name)
|
||||
margin = parse_param(kw, "MARGIN", EnumConvertType.INT, 0)
|
||||
line_spacing = parse_param(kw, "SPACING", EnumConvertType.INT, 0)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
pos = parse_param(kw, "XY", EnumConvertType.VEC2, (0, 0), -1, 1)
|
||||
angle = parse_param(kw, "ANGLE", EnumConvertType.INT, 0)
|
||||
edge = parse_param(kw, "EDGE", EnumEdge, EnumEdge.CLIP.name)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
full_text = parse_param(kw, Lexicon.STRING, EnumConvertType.STRING, "jovimetrix")
|
||||
font_idx = parse_param(kw, Lexicon.FONT, EnumConvertType.STRING, self.FONT_NAMES[0])
|
||||
autosize = parse_param(kw, Lexicon.AUTOSIZE, EnumConvertType.BOOLEAN, False)
|
||||
letter = parse_param(kw, Lexicon.LETTER, EnumConvertType.BOOLEAN, False)
|
||||
color = parse_param(kw, Lexicon.COLOR, EnumConvertType.VEC4INT, (255,255,255,255), 0, 255)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0,0,0,255), 0, 255)
|
||||
columns = parse_param(kw, Lexicon.COLUMNS, EnumConvertType.INT, 0)
|
||||
font_size = parse_param(kw, Lexicon.SIZE, EnumConvertType.INT, 1)
|
||||
align = parse_param(kw, Lexicon.ALIGN, EnumAlignment, EnumAlignment.CENTER.name)
|
||||
justify = parse_param(kw, Lexicon.JUSTIFY, EnumJustify, EnumJustify.CENTER.name)
|
||||
margin = parse_param(kw, Lexicon.MARGIN, EnumConvertType.INT, 0)
|
||||
line_spacing = parse_param(kw, Lexicon.SPACING, EnumConvertType.INT, 0)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
pos = parse_param(kw, Lexicon.XY, EnumConvertType.VEC2, (0, 0), -1, 1)
|
||||
angle = parse_param(kw, Lexicon.ANGLE, EnumConvertType.INT, 0)
|
||||
edge = parse_param(kw, Lexicon.EDGE, EnumEdge, EnumEdge.CLIP.name)
|
||||
invert = parse_param(kw, Lexicon.INVERT, EnumConvertType.BOOLEAN, False)
|
||||
images = []
|
||||
params = list(zip_longest_fill(full_text, font_idx, autosize, letter, color,
|
||||
matte, columns, font_size, align, justify, margin,
|
||||
@@ -328,101 +317,3 @@ Generates images containing text based on parameters such as font, size, alignme
|
||||
images.append(cv_to_tensor_full(img, matte))
|
||||
pbar.update_absolute(idx)
|
||||
return image_stack(images)
|
||||
|
||||
'''
|
||||
class StereogramNode(CozyImageNode):
|
||||
NAME = "STEREOGRAM (JOV) 📻"
|
||||
CATEGORY = JOV_CATEGORY
|
||||
DESCRIPTION = """
|
||||
Generates false perception 3D images from 2D input. Set tile divisions, noise, gamma, and shift parameters to control the stereogram's appearance.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> InputType:
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"DEPTH": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Grayscale image representing a depth map"
|
||||
}),
|
||||
"TILE": ("INT", {
|
||||
"default": 8, "min": 1}),
|
||||
"NOISE": ("FLOAT", {
|
||||
"default": 0.33, "min": 0, "max": 1, "step": 0.01}),
|
||||
"GAMMA": ("FLOAT", {
|
||||
"default": 0.33, "min": 0, "max": 1, "step": 0.01}),
|
||||
"SHIFT": ("FLOAT", {
|
||||
"default": 1., "min": -1, "max": 1, "step": 0.01}),
|
||||
"INVERT": ("BOOLEAN", {
|
||||
"default": False}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
depth = parse_param(kw, "DEPTH", EnumConvertType.IMAGE, None)
|
||||
divisions = parse_param(kw, "TILE", EnumConvertType.INT, 1, 1, 8)
|
||||
noise = parse_param(kw, "NOISE", EnumConvertType.FLOAT, 1, 0)
|
||||
gamma = parse_param(kw, "GAMMA", EnumConvertType.FLOAT, 1, 0)
|
||||
shift = parse_param(kw, "SHIFT", EnumConvertType.FLOAT, 0, 1, -1)
|
||||
invert = parse_param(kw, "INVERT", EnumConvertType.BOOLEAN, False)
|
||||
params = list(zip_longest_fill(pA, depth, divisions, noise, gamma, shift, invert))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (pA, depth, divisions, noise, gamma, shift, invert) in enumerate(params):
|
||||
pA = channel_solid(chan=EnumImageType.BGRA) if pA is None else tensor_to_cv(pA)
|
||||
h, w = pA.shape[:2]
|
||||
depth = channel_solid(w, h, chan=EnumImageType.BGRA) if depth is None else tensor_to_cv(depth)
|
||||
if invert:
|
||||
depth = image_invert(depth, 1.0)
|
||||
pA = image_stereogram(pA, depth, divisions, noise, gamma, shift)
|
||||
images.append(cv_to_tensor_full(pA))
|
||||
pbar.update_absolute(idx)
|
||||
return image_stack(images)
|
||||
|
||||
class StereoscopicNode(CozyBaseNode):
|
||||
NAME = "STEREOSCOPIC (JOV) 🕶️"
|
||||
CATEGORY = JOV_CATEGORY
|
||||
RETURN_TYPES = ("IMAGE", )
|
||||
RETURN_NAMES = ("IMAGE", )
|
||||
DESCRIPTION = """
|
||||
Simulates depth perception in images by generating stereoscopic views. It accepts an optional input image for color matte. Adjust baseline and focal length for customized depth effects.
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> InputType:
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip":"Optional Image to Matte with Selected Color"}),
|
||||
"INT": ("FLOAT", {
|
||||
"default": 0.1, "min": 0, "max": 1, "step": 0.01,
|
||||
"tooltip":"Baseline"}),
|
||||
"FOCAL": ("FLOAT", {
|
||||
"default": 500, "min": 0, "step": 0.01}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
|
||||
def run(self, **kw) -> tuple[TensorType]:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
baseline = parse_param(kw, "INT", EnumConvertType.FLOAT, 0, 0.1, 1)
|
||||
focal_length = parse_param(kw, "VAL", EnumConvertType.FLOAT, 500, 0)
|
||||
images = []
|
||||
params = list(zip_longest_fill(pA, baseline, focal_length))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (pA, baseline, focal_length) in enumerate(params):
|
||||
pA = tensor_to_cv(pA) if pA is not None else channel_solid(chan=EnumImageType.GRAYSCALE)
|
||||
# Convert depth image to disparity map
|
||||
disparity_map = np.divide(1.0, pA.astype(np.float32), where=pA!=0)
|
||||
# Compute disparity values based on baseline and focal length
|
||||
disparity_map *= baseline * focal_length
|
||||
images.append(cv_to_tensor(pA))
|
||||
pbar.update_absolute(idx)
|
||||
return torch.stack(images)
|
||||
|
||||
'''
|
||||
+94
-111
@@ -10,6 +10,9 @@ from cozy_comfyui import \
|
||||
InputType, RGBAMaskType, EnumConvertType, \
|
||||
deep_merge, parse_param, parse_dynamic, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_IMAGE, \
|
||||
CozyImageNode
|
||||
@@ -72,41 +75,36 @@ Extract a portion of an input image or resize it. It supports various cropping m
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"FUNCTION": (EnumCropMode._member_names_, {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.FUNCTION: (EnumCropMode._member_names_, {
|
||||
"default": EnumCropMode.CENTER.name}),
|
||||
"XY": ("VEC2", {
|
||||
Lexicon.XY: ("VEC2", {
|
||||
"default": (0, 0), "mij": 0.5, "maj": 0.5,
|
||||
"label": ["X", "Y"]}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij": IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"]}),
|
||||
"TLTR": ("VEC4", {
|
||||
Lexicon.TLTR: ("VEC4", {
|
||||
"default": (0, 0, 0, 1), "mij": 0, "maj": 1,
|
||||
"label": ["TOP", "LEFT", "TOP", "RIGHT"],
|
||||
"tooltip": "Top Left - Top Right"}),
|
||||
"BLBR": ("VEC4", {
|
||||
"label": ["TOP", "LEFT", "TOP", "RIGHT"],}),
|
||||
Lexicon.BLBR: ("VEC4", {
|
||||
"default": (1, 0, 1, 1), "mij": 0, "maj": 1,
|
||||
"label": ["BOTTOM", "LEFT", "BOTTOM", "RIGHT"],
|
||||
"tooltip": "Bottom Left - Bottom Right"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"})
|
||||
"label": ["BOTTOM", "LEFT", "BOTTOM", "RIGHT"],}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
func = parse_param(kw, "FUNCTION", EnumCropMode, EnumCropMode.CENTER.name)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
func = parse_param(kw, Lexicon.FUNCTION, EnumCropMode, EnumCropMode.CENTER.name)
|
||||
# if less than 1 then use as scalar, over 1 = int(size)
|
||||
xy = parse_param(kw, "XY", EnumConvertType.VEC2, (0, 0,), 0, 1)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
tltr = parse_param(kw, "TLTR", EnumConvertType.VEC4, (0, 0, 0, 1,), 0, 1)
|
||||
blbr = parse_param(kw, "BLBR", EnumConvertType.VEC4, (1, 0, 1, 1,), 0, 1)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
xy = parse_param(kw, Lexicon.XY, EnumConvertType.VEC2, (0, 0,), 0, 1)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
tltr = parse_param(kw, Lexicon.TLTR, EnumConvertType.VEC4, (0, 0, 0, 1,), 0, 1)
|
||||
blbr = parse_param(kw, Lexicon.BLBR, EnumConvertType.VEC4, (1, 0, 1, 1,), 0, 1)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
params = list(zip_longest_fill(pA, func, xy, wihi, tltr, blbr, matte))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
@@ -151,34 +149,31 @@ Combine multiple input images into a single image by summing their pixel values.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"]}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"})
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
imgs = parse_dynamic(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
imgs = parse_dynamic(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
if imgs is None:
|
||||
logger.warning("no images to flatten")
|
||||
return ()
|
||||
|
||||
# be less dumb when merging
|
||||
pA = [tensor_to_cv(i) for i in imgs]
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
|
||||
images = []
|
||||
params = list(zip_longest_fill(mode, sample, wihi, matte))
|
||||
@@ -206,41 +201,37 @@ The axis parameter allows for horizontal, vertical, or grid stacking of images,
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"AXIS": (EnumOrientation._member_names_, {
|
||||
"default": EnumOrientation.GRID.name,
|
||||
"tooltip":"Choose the direction in which to stack the images. Options include horizontal, vertical, or a grid layout"}),
|
||||
"STEP": ("INT", {
|
||||
Lexicon.AXIS: (EnumOrientation._member_names_, {
|
||||
"default": EnumOrientation.GRID.name,}),
|
||||
Lexicon.STEP: ("INT", {
|
||||
"default": 1, "min": 0,
|
||||
"tooltip":"How many images are placed before a new row starts (stride)."}),
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"}),
|
||||
"WH": ("VEC2", {
|
||||
"tooltip":"How many images are placed before a new row starts (stride)"}),
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"]}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"})
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
images = parse_dynamic(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
images = parse_dynamic(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
if len(images) == 0:
|
||||
logger.warning("no images to stack")
|
||||
return
|
||||
|
||||
images = [tensor_to_cv(i) for i in images]
|
||||
axis = parse_param(kw, "AXIS", EnumOrientation, EnumOrientation.GRID.name)[0]
|
||||
stride = parse_param(kw, "STEP", EnumConvertType.INT, 1)[0]
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)[0]
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)[0]
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)[0]
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)[0]
|
||||
axis = parse_param(kw, Lexicon.AXIS, EnumOrientation, EnumOrientation.GRID.name)[0]
|
||||
stride = parse_param(kw, Lexicon.STEP, EnumConvertType.INT, 1)[0]
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)[0]
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)[0]
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)[0]
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)[0]
|
||||
img = image_stacker(images, axis, stride) #, matte)
|
||||
if mode != EnumScaleMode.MATTE:
|
||||
w, h = wihi
|
||||
@@ -261,76 +252,68 @@ Apply various geometric transformations to images, including translation, rotati
|
||||
d = super().INPUT_TYPES(prompt=True, dynprompt=True)
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"MASK": (COZY_TYPE_IMAGE, {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.MASK: (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Override Image mask"}),
|
||||
"XY": ("VEC2", {
|
||||
Lexicon.XY: ("VEC2", {
|
||||
"default": (0., 0.,), "mij": -1., "maj": 1.,
|
||||
"label": ["X", "Y"]}),
|
||||
"ANGLE": ("FLOAT", {
|
||||
"default": 0, "step": 0.01,
|
||||
"tooltip": "Rotation Angle"}),
|
||||
"SIZE": ("VEC2", {
|
||||
Lexicon.ANGLE: ("FLOAT", {
|
||||
"default": 0, "step": 0.01,}),
|
||||
Lexicon.SIZE: ("VEC2", {
|
||||
"default": (1., 1.), "mij": 0.001,
|
||||
"label": ["X", "Y"]}),
|
||||
"TILE": ("VEC2", {
|
||||
Lexicon.TILE: ("VEC2", {
|
||||
"default": (1., 1.), "mij": 1.,
|
||||
"label": ["X", "Y"]}),
|
||||
"EDGE": (EnumEdge._member_names_, {
|
||||
Lexicon.EDGE: (EnumEdge._member_names_, {
|
||||
"default": EnumEdge.CLIP.name}),
|
||||
"MIRROR": (EnumMirrorMode._member_names_, {
|
||||
Lexicon.MIRROR: (EnumMirrorMode._member_names_, {
|
||||
"default": EnumMirrorMode.NONE.name}),
|
||||
"PIVOT": ("VEC2", {
|
||||
Lexicon.PIVOT: ("VEC2", {
|
||||
"default": (0.5, 0.5), "step": 0.005,
|
||||
"label": ["X", "Y"]}),
|
||||
"PROJ": (EnumProjection._member_names_, {
|
||||
Lexicon.PROJECTION: (EnumProjection._member_names_, {
|
||||
"default": EnumProjection.NORMAL.name}),
|
||||
"TLTR": ("VEC4", {
|
||||
Lexicon.TLTR: ("VEC4", {
|
||||
"default": (0., 0., 1., 0.), "mij": 0., "maj": 1., "step": 0.005,
|
||||
"label": ["TOP", "LEFT", "TOP", "RIGHT"],
|
||||
"tooltip": "Top Left - Top Right"}),
|
||||
"BLBR": ("VEC4", {
|
||||
"label": ["TOP", "LEFT", "TOP", "RIGHT"],}),
|
||||
Lexicon.BLBR: ("VEC4", {
|
||||
"default": (0., 1., 1., 1.), "mij": 0., "maj": 1., "step": 0.005,
|
||||
"label": ["BOTTOM", "LEFT", "BOTTOM", "RIGHT"],
|
||||
"tooltip": "Bottom Left - Bottom Right"}),
|
||||
"STRENGTH": ("FLOAT", {
|
||||
"label": ["BOTTOM", "LEFT", "BOTTOM", "RIGHT"],}),
|
||||
Lexicon.STRENGTH: ("FLOAT", {
|
||||
"default": 1, "min": 0, "step": 0.005}),
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"]}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background Color"})
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> RGBAMaskType:
|
||||
pA = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, "MASK", EnumConvertType.IMAGE, None)
|
||||
offset = parse_param(kw, "XY", EnumConvertType.VEC2, (0., 0.), -2.5, 2.5)
|
||||
angle = parse_param(kw, "ANGLE", EnumConvertType.FLOAT, 0)
|
||||
size = parse_param(kw, "SIZE", EnumConvertType.VEC2, (1., 1.), 0.001)
|
||||
edge = parse_param(kw, "EDGE", EnumEdge, EnumEdge.CLIP.name)
|
||||
mirror = parse_param(kw, "MIRROR", EnumMirrorMode, EnumMirrorMode.NONE.name)
|
||||
mirror_pivot = parse_param(kw, "PIVOT", EnumConvertType.VEC2, (0.5, 0.5), 0, 1)
|
||||
tile_xy = parse_param(kw, "TILE", EnumConvertType.VEC2, (1., 1.), 1)
|
||||
proj = parse_param(kw, "PROJ", EnumProjection, EnumProjection.NORMAL.name)
|
||||
tltr = parse_param(kw, "TLTR", EnumConvertType.VEC4, (0., 0., 1., 0.), 0, 1)
|
||||
blbr = parse_param(kw, "BLBR", EnumConvertType.VEC4, (0., 1., 1., 1.), 0, 1)
|
||||
strength = parse_param(kw, "STRENGTH", EnumConvertType.FLOAT, 1, 0, 1)
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
pA = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
mask = parse_param(kw, Lexicon.MASK, EnumConvertType.IMAGE, None)
|
||||
offset = parse_param(kw, Lexicon.XY, EnumConvertType.VEC2, (0., 0.), -2.5, 2.5)
|
||||
angle = parse_param(kw, Lexicon.ANGLE, EnumConvertType.FLOAT, 0)
|
||||
size = parse_param(kw, Lexicon.SIZE, EnumConvertType.VEC2, (1., 1.), 0.001)
|
||||
edge = parse_param(kw, Lexicon.EDGE, EnumEdge, EnumEdge.CLIP.name)
|
||||
mirror = parse_param(kw, Lexicon.MIRROR, EnumMirrorMode, EnumMirrorMode.NONE.name)
|
||||
mirror_pivot = parse_param(kw, Lexicon.PIVOT, EnumConvertType.VEC2, (0.5, 0.5), 0, 1)
|
||||
tile_xy = parse_param(kw, Lexicon.TILE, EnumConvertType.VEC2, (1., 1.), 1)
|
||||
proj = parse_param(kw, Lexicon.PROJECTION, EnumProjection, EnumProjection.NORMAL.name)
|
||||
tltr = parse_param(kw, Lexicon.TLTR, EnumConvertType.VEC4, (0., 0., 1., 0.), 0, 1)
|
||||
blbr = parse_param(kw, Lexicon.BLBR, EnumConvertType.VEC4, (0., 1., 1., 1.), 0, 1)
|
||||
strength = parse_param(kw, Lexicon.STRENGTH, EnumConvertType.FLOAT, 1, 0, 1)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)
|
||||
params = list(zip_longest_fill(pA, mask, offset, angle, size, edge, tile_xy, mirror, mirror_pivot, proj, strength, tltr, blbr, mode, wihi, sample, matte))
|
||||
images = []
|
||||
pbar = ProgressBar(len(params))
|
||||
|
||||
+64
-66
@@ -22,6 +22,9 @@ from cozy_comfyui import \
|
||||
InputType, EnumConvertType, TensorType, \
|
||||
deep_merge, parse_dynamic, parse_param
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_ANY, \
|
||||
CozyBaseNode
|
||||
@@ -83,7 +86,7 @@ class ArrayNode(CozyBaseNode):
|
||||
)
|
||||
SORT = 50
|
||||
DESCRIPTION = """
|
||||
Processes a batch of data based on the selected mode. Merge, pick, slice, random select, or index items. Can reverse the order of items and divide the data into chunks.
|
||||
Processes a batch of data based on the selected mode. Merge, pick, slice, random select, or index items. Can also reverse the order of items.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
@@ -91,27 +94,26 @@ Processes a batch of data based on the selected mode. Merge, pick, slice, random
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"MODE": (EnumBatchMode._member_names_, {
|
||||
Lexicon.MODE: (EnumBatchMode._member_names_, {
|
||||
"default": EnumBatchMode.MERGE.name,
|
||||
"tooltip":"Select a single index, specific range, custom index list or randomized"}),
|
||||
"RANGE": ("VEC3", {
|
||||
"tooltip": "Select a single index, specific range, custom index list or randomized"}),
|
||||
Lexicon.RANGE: ("VEC3", {
|
||||
"default": (0, 0, 1), "mij": 0, "int": True,
|
||||
"tooltip":"The start, end and step for the range"}),
|
||||
"INDEX": ("STRING", {
|
||||
"tooltip": "The start, end and step for the range"}),
|
||||
Lexicon.INDEX: ("STRING", {
|
||||
"default": "",
|
||||
"tooltip":"Comma separated list of indicies to export"}),
|
||||
"COUNT": ("INT", {
|
||||
"tooltip": "Comma separated list of indicies to export"}),
|
||||
Lexicon.COUNT: ("INT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize,
|
||||
"tooltip":"How many items to return"}),
|
||||
"REVERSE": ("BOOLEAN", {
|
||||
"tooltip": "How many items to return"}),
|
||||
Lexicon.REVERSE: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"reverse the calculated output list"}),
|
||||
"SEED": ("INT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize,
|
||||
"tooltip":"Random seed value"}),
|
||||
"tooltip": "Reverse the calculated output list"}),
|
||||
Lexicon.SEED: ("INT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
@classmethod
|
||||
def batched(cls, iterable, chunk_size, expand:bool=False, fill:Any=None) -> List[Any]:
|
||||
@@ -121,13 +123,13 @@ Processes a batch of data based on the selected mode. Merge, pick, slice, random
|
||||
return [iterable[i: i + chunk_size] for i in range(0, len(iterable), chunk_size)]
|
||||
|
||||
def run(self, **kw) -> tuple[int, list]:
|
||||
data_list = parse_dynamic(kw, "❔", EnumConvertType.ANY, None)
|
||||
mode = parse_param(kw, "MODE", EnumBatchMode, EnumBatchMode.MERGE.name)[0]
|
||||
slice_range = parse_param(kw, "RANGE", EnumConvertType.VEC3INT, (0, 0, 1))[0]
|
||||
index = parse_param(kw, "INDEX", EnumConvertType.STRING, "")[0]
|
||||
count = parse_param(kw, "COUNT", EnumConvertType.INT, 0, 0, sys.maxsize)[0]
|
||||
reverse = parse_param(kw, "REVERSE", EnumConvertType.BOOLEAN, False)[0]
|
||||
seed = parse_param(kw, "SEED", EnumConvertType.INT, 0)[0]
|
||||
data_list = parse_dynamic(kw, Lexicon.DYNAMIC, EnumConvertType.ANY, None)
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumBatchMode, EnumBatchMode.MERGE.name)[0]
|
||||
slice_range = parse_param(kw, Lexicon.RANGE, EnumConvertType.VEC3INT, (0, 0, 1))[0]
|
||||
index = parse_param(kw, Lexicon.INDEX, EnumConvertType.STRING, "")[0]
|
||||
count = parse_param(kw, Lexicon.COUNT, EnumConvertType.INT, 0, 0, sys.maxsize)[0]
|
||||
reverse = parse_param(kw, Lexicon.REVERSE, EnumConvertType.BOOLEAN, False)[0]
|
||||
seed = parse_param(kw, Lexicon.SEED, EnumConvertType.INT, 0)[0]
|
||||
|
||||
data = []
|
||||
# track latents since they need to be added back to Dict['samples']
|
||||
@@ -246,7 +248,7 @@ Processes a batch of data based on the selected mode. Merge, pick, slice, random
|
||||
class QueueBaseNode(CozyBaseNode):
|
||||
CATEGORY = JOV_CATEGORY
|
||||
RETURN_TYPES = (COZY_TYPE_ANY, COZY_TYPE_ANY, "STRING", "INT", "INT", "BOOLEAN")
|
||||
RETURN_NAMES = ("🦄", "QUEUE", "CURRENT", "INDEX", "TOTAL", "TRIGGER", )
|
||||
RETURN_NAMES = ("❔", "QUEUE", "CURRENT", "INDEX", "TOTAL", "TRIGGER", )
|
||||
#OUTPUT_IS_LIST = (True, True, True, True, True, True,)
|
||||
VIDEO_FORMATS = ['.wav', '.mp3', '.webm', '.mp4', '.avi', '.wmv', '.mkv', '.mov', '.mxf']
|
||||
|
||||
@@ -259,33 +261,33 @@ class QueueBaseNode(CozyBaseNode):
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"Q": ("STRING", {
|
||||
Lexicon.QUEUE: ("STRING", {
|
||||
"default": "./res/img/test-a.png", "multiline": True,
|
||||
"tooltip": "Current items to process during Queue iteration."}),
|
||||
"RECURSE": ("BOOLEAN", {
|
||||
"tooltip": "Current items to process during Queue iteration"}),
|
||||
Lexicon.RECURSE: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"Recurse through all subdirectories found"}),
|
||||
"BATCH": ("BOOLEAN", {
|
||||
"tooltip": "Recurse through all subdirectories found"}),
|
||||
Lexicon.BATCH: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"Load all items, if they are loadable items, i.e. batch load images from the Queue's list."}),
|
||||
"SELECT": ("INT", {
|
||||
"tooltip": "Load all items, if they are loadable items, i.e. batch load images from the Queue's list"}),
|
||||
Lexicon.SELECT: ("INT", {
|
||||
"default": 0, "min": 0,
|
||||
"tooltip": "What index to use for the current queue item. 0 will move to the next item each queue run"}),
|
||||
"HOLD": ("BOOLEAN", {
|
||||
"tooltip": "The index to use for the current queue item. 0 will move to the next item each queue run"}),
|
||||
Lexicon.HOLD: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"Hold the item at the current queue index"}),
|
||||
"STOP": ("BOOLEAN", {
|
||||
"tooltip": "Hold the item at the current queue index"}),
|
||||
Lexicon.STOP: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"When the Queue is out of items, send a `HALT` to ComfyUI."}),
|
||||
"LOOP": ("BOOLEAN", {
|
||||
"tooltip": "When the Queue is out of items, send a `HALT` to ComfyUI"}),
|
||||
Lexicon.LOOP: ("BOOLEAN", {
|
||||
"default": True,
|
||||
"tooltip":"If the queue should loop. If `False` and if there are more iterations, will send the previous image."}),
|
||||
"RESET": ("BOOLEAN", {
|
||||
"tooltip": "If the queue should loop. If `False` and if there are more iterations, will send the previous image"}),
|
||||
Lexicon.RESET: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"Reset the queue back to index 1"}),
|
||||
"tooltip": "Reset the queue back to index 1"}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.__index = 0
|
||||
@@ -368,26 +370,26 @@ class QueueBaseNode(CozyBaseNode):
|
||||
self.__ident = ident
|
||||
# should work headless as well
|
||||
|
||||
if (new_val := parse_param(kw, "SELECT", EnumConvertType.INT, 0)[0]) > 0:
|
||||
if (new_val := parse_param(kw, Lexicon.SELECT, EnumConvertType.INT, 0)[0]) > 0:
|
||||
self.__index = new_val - 1
|
||||
|
||||
reset = parse_reset(ident) > 0
|
||||
if reset or parse_param(kw, "RESET", EnumConvertType.BOOLEAN, False)[0]:
|
||||
if reset or parse_param(kw, Lexicon.RESET, EnumConvertType.BOOLEAN, False)[0]:
|
||||
self.__q = None
|
||||
self.__index = 0
|
||||
|
||||
mode = parse_param(kw, "MODE", EnumScaleMode, EnumScaleMode.MATTE.name)[0]
|
||||
sample = parse_param(kw, "SAMPLE", EnumInterpolation, EnumInterpolation.LANCZOS4.name)[0]
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)[0]
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumScaleMode, EnumScaleMode.MATTE.name)[0]
|
||||
sample = parse_param(kw, Lexicon.SAMPLE, EnumInterpolation, EnumInterpolation.LANCZOS4.name)[0]
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), IMAGE_SIZE_MIN)[0]
|
||||
w, h = wihi
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)[0]
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)[0]
|
||||
|
||||
if self.__q is None:
|
||||
# process Q into ...
|
||||
# check if folder first, file, then string.
|
||||
# entry is: data, <filter if folder:*.png,*.jpg>, <repeats:1+>
|
||||
recurse = parse_param(kw, "RECURSE", EnumConvertType.BOOLEAN, False)[0]
|
||||
q = parse_param(kw, "Q", EnumConvertType.STRING, "")[0]
|
||||
recurse = parse_param(kw, Lexicon.RECURSE, EnumConvertType.BOOLEAN, False)[0]
|
||||
q = parse_param(kw, Lexicon.QUEUE, EnumConvertType.STRING, "")[0]
|
||||
self.__q = self.__parseQ(q, recurse)
|
||||
self.__len = len(self.__q)
|
||||
self.__index_last = 0
|
||||
@@ -396,17 +398,17 @@ class QueueBaseNode(CozyBaseNode):
|
||||
self.__previous = self.process(self.__previous)
|
||||
|
||||
# make sure we have more to process if are a single fire queue
|
||||
stop = parse_param(kw, "STOP", EnumConvertType.BOOLEAN, False)[0]
|
||||
stop = parse_param(kw, Lexicon.STOP, EnumConvertType.BOOLEAN, False)[0]
|
||||
if stop and self.__index >= self.__len:
|
||||
comfy_api_post("jovi-queue-done", ident, self.status)
|
||||
interrupt_processing()
|
||||
return self.__previous, self.__q, self.__current, self.__index_last+1, self.__len
|
||||
|
||||
if (wait := parse_param(kw, "HOLD", EnumConvertType.BOOLEAN, False))[0] == True:
|
||||
if (wait := parse_param(kw, Lexicon.HOLD, EnumConvertType.BOOLEAN, False))[0] == True:
|
||||
self.__index = self.__index_last
|
||||
|
||||
# otherwise loop around the end
|
||||
loop = parse_param(kw, "LOOP", EnumConvertType.BOOLEAN, False)[0]
|
||||
loop = parse_param(kw, Lexicon.LOOP, EnumConvertType.BOOLEAN, False)[0]
|
||||
if loop == True:
|
||||
self.__index %= self.__len
|
||||
else:
|
||||
@@ -417,7 +419,7 @@ class QueueBaseNode(CozyBaseNode):
|
||||
self.__index_last = self.__index
|
||||
info = f"QUEUE #{ident} [{self.__current}] ({self.__index})"
|
||||
batched = False
|
||||
if (batched := parse_param(kw, "BATCH", EnumConvertType.BOOLEAN, False)[0]) == True:
|
||||
if (batched := parse_param(kw, Lexicon.BATCH, EnumConvertType.BOOLEAN, False)[0]) == True:
|
||||
data = []
|
||||
mw, mh, mc = 0, 0, 0
|
||||
for idx in range(self.__len):
|
||||
@@ -506,30 +508,26 @@ Manage a queue of specific items: media files. Supports various image and video
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"MODE": (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name,
|
||||
"tooltip": "If the image should be resized to fit within given dimensions or keep the original size"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.MODE: (EnumScaleMode._member_names_, {
|
||||
"default": EnumScaleMode.MATTE.name}),
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"],
|
||||
"tooltip": "Width and Height"}),
|
||||
"SAMPLE": (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,
|
||||
"tooltip": "Sampling method for resizing images"}),
|
||||
"MATTE": ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,
|
||||
"tooltip": "Background color for padding"}),
|
||||
"label": ["W", "H"],}),
|
||||
Lexicon.SAMPLE: (EnumInterpolation._member_names_, {
|
||||
"default": EnumInterpolation.LANCZOS4.name,}),
|
||||
Lexicon.MATTE: ("VEC4", {
|
||||
"default": (0, 0, 0, 255), "rgb": True,}),
|
||||
},
|
||||
"hidden": d.get("hidden", {})
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, ident, **kw) -> tuple[TensorType, TensorType, TensorType, str, int, int, bool]:
|
||||
data, _, current, index, total, trigger = super().run(ident, **kw)
|
||||
if not isinstance(data, (TensorType, )):
|
||||
data = [None, None, None]
|
||||
else:
|
||||
matte = parse_param(kw, "MATTE", EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)[0]
|
||||
matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, (0, 0, 0, 255), 0, 255)[0]
|
||||
data = [tensor_to_cv(d) for d in data]
|
||||
data = [cv_to_tensor_full(d, matte) for d in data]
|
||||
data = [torch.stack(d) for d in zip(*data)]
|
||||
|
||||
+15
-15
@@ -14,6 +14,9 @@ from cozy_comfyui import \
|
||||
InputType, EnumConvertType, TensorType, \
|
||||
deep_merge, parse_dynamic, parse_param
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_IMAGE, \
|
||||
CozyBaseNode
|
||||
@@ -155,19 +158,18 @@ Visualize a series of data points over time. It accepts a dynamic number of valu
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"RESET": ("BOOLEAN", {
|
||||
Lexicon.RESET: ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"Clear the graph history"}),
|
||||
"VAL": ("INT", {
|
||||
Lexicon.VALUE: ("INT", {
|
||||
"default": 60, "min": 0,
|
||||
"tooltip":"Number of values to graph and display"}),
|
||||
"WH": ("VEC2", {
|
||||
Lexicon.WH: ("VEC2", {
|
||||
"default": (512, 512), "mij":IMAGE_SIZE_MIN, "int": True,
|
||||
"label": ["W", "H"],
|
||||
"tooltip":"Width and Height of the graph output"}),
|
||||
"label": ["W", "H"]}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
@classmethod
|
||||
def IS_CHANGED(cls) -> float:
|
||||
@@ -179,12 +181,12 @@ Visualize a series of data points over time. It accepts a dynamic number of valu
|
||||
self.__fig, self.__ax = plt.subplots(figsize=(5.12, 5.12))
|
||||
|
||||
def run(self, ident, **kw) -> tuple[TensorType]:
|
||||
slice = parse_param(kw, "VAL", EnumConvertType.INT, 60)[0]
|
||||
wihi = parse_param(kw, "WH", EnumConvertType.VEC2INT, (512, 512), 1)[0]
|
||||
if parse_reset(ident) > 0 or parse_param(kw, "RESET", EnumConvertType.BOOLEAN, False)[0]:
|
||||
slice = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, 60)[0]
|
||||
wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, (512, 512), 1)[0]
|
||||
if parse_reset(ident) > 0 or parse_param(kw, Lexicon.RESET, EnumConvertType.BOOLEAN, False)[0]:
|
||||
self.__history = []
|
||||
longest_edge = 0
|
||||
dynamic = parse_dynamic(kw, "❔", EnumConvertType.FLOAT, 0)
|
||||
dynamic = parse_dynamic(kw, Lexicon.DYNAMIC, EnumConvertType.FLOAT, 0)
|
||||
dynamic = [i[0] for i in dynamic]
|
||||
self.__ax.clear()
|
||||
for idx, val in enumerate(dynamic):
|
||||
@@ -236,14 +238,12 @@ Exports and Displays immediate information about images.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"default": None,
|
||||
"tooltip":"The image to examine"})
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[int, list]:
|
||||
image = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
image = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
height, width, cc = image[0].shape
|
||||
return (len(image), width, height, cc, (width, height), (width, height, cc))
|
||||
|
||||
+61
-70
@@ -20,6 +20,9 @@ from cozy_comfyui import \
|
||||
InputType, EnumConvertType, \
|
||||
deep_merge, parse_param, parse_param_list, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_IMAGE, COZY_TYPE_ANY, \
|
||||
CozyBaseNode
|
||||
@@ -99,30 +102,30 @@ Introduce pauses in the workflow that accept an optional input to pass through a
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IN": (COZY_TYPE_ANY, {
|
||||
Lexicon.PASS_IN: (COZY_TYPE_ANY, {
|
||||
"default": None,
|
||||
"tooltip":"The data that should be held until the timer completes."}),
|
||||
"TIMER": ("INT", {
|
||||
Lexicon.TIMER: ("INT", {
|
||||
"default" : 0, "min": -1,
|
||||
"tooltip":"How long to delay if enabled. 0 means no delay."}),
|
||||
"ENABLE": ("BOOLEAN", {
|
||||
Lexicon.ENABLE: ("BOOLEAN", {
|
||||
"default": True,
|
||||
"tooltip":"Enable or disable the screensaver."})
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
@classmethod
|
||||
def IS_CHANGED(cls, **kw) -> float:
|
||||
return float("NaN")
|
||||
|
||||
def run(self, ident, **kw) -> tuple[Any]:
|
||||
delay = parse_param(kw, "TIMER", EnumConvertType.INT, -1, 0, JOV_DELAY_MAX)[0]
|
||||
delay = parse_param(kw, Lexicon.TIMER, EnumConvertType.INT, -1, 0, JOV_DELAY_MAX)[0]
|
||||
if delay < 0:
|
||||
delay = JOV_DELAY_MAX
|
||||
if delay > JOV_DELAY_MIN:
|
||||
comfy_api_post("jovi-delay-user", ident, {"id": ident, "timeout": delay})
|
||||
# enable = parse_param(kw, "ENABLE", EnumConvertType.BOOLEAN, True)
|
||||
# enable = parse_param(kw, Lexicon.ENABLE, EnumConvertType.BOOLEAN, True)[0]
|
||||
|
||||
step = 1
|
||||
pbar = ProgressBar(delay)
|
||||
@@ -139,7 +142,7 @@ Introduce pauses in the workflow that accept an optional input to pass through a
|
||||
logger.info(f"delay [continue] ({step}): {ident}")
|
||||
pbar.update_absolute(step)
|
||||
step += 1
|
||||
return kw["IN"],
|
||||
return kw[Lexicon.PASS_IN],
|
||||
|
||||
class ExportNode(CozyBaseNode):
|
||||
NAME = "EXPORT (JOV) 📽"
|
||||
@@ -156,52 +159,45 @@ Responsible for saving images or animations to disk. It supports various output
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": (COZY_TYPE_IMAGE, {
|
||||
"tooltip": "Pixel Data (RGBA, RGB or Grayscale)"
|
||||
}),
|
||||
"OUT": ("STRING", {
|
||||
Lexicon.IMAGE: (COZY_TYPE_IMAGE, {}),
|
||||
Lexicon.PATH: ("STRING", {
|
||||
"default": get_output_directory(),
|
||||
"default_top":"<comfy output dir>",
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
"FORMAT": (FORMATS, {
|
||||
"default": FORMATS[0],
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
"PREFIX": ("STRING", {
|
||||
"default": "jovi",
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
"OVERWRITE": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
"default_top": "<comfy output dir>",}),
|
||||
Lexicon.FORMAT: (FORMATS, {
|
||||
"default": FORMATS[0],}),
|
||||
Lexicon.PREFIX: ("STRING", {
|
||||
"default": "jovi",}),
|
||||
Lexicon.OVERWRITE: ("BOOLEAN", {
|
||||
"default": False,}),
|
||||
# GIF ONLY
|
||||
"OPT": ("BOOLEAN", {
|
||||
"default": False,
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
Lexicon.OPTIMIZE: ("BOOLEAN", {
|
||||
"default": False,}),
|
||||
# GIFSKI ONLY
|
||||
"QUALITY": ("INT", {"default": 90, "min": 1, "max": 100,
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
"QUALITY_M": ("INT", {"default": 100, "min": 1, "max": 100,
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
Lexicon.QUALITY: ("INT", {
|
||||
"default": 90, "min": 1, "max": 100,}),
|
||||
Lexicon.QUALITY_M: ("INT", {
|
||||
"default": 100, "min": 1, "max": 100,}),
|
||||
# GIF OR GIFSKI
|
||||
"FPS": ("INT", {"default": 24, "min": 1, "max": 60,
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
Lexicon.FPS: ("INT", {
|
||||
"default": 24, "min": 1, "max": 60,}),
|
||||
# GIF OR GIFSKI
|
||||
"LOOP": ("INT", {"default": 0, "min": 0,
|
||||
"tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
Lexicon.LOOP: ("INT", {
|
||||
"default": 0, "min": 0,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> None:
|
||||
images = parse_param(kw, "IMAGE", EnumConvertType.IMAGE, None)
|
||||
suffix = parse_param(kw, "PREFIX", EnumConvertType.STRING, uuid4().hex[:16])[0]
|
||||
output_dir = parse_param(kw, "OUT", EnumConvertType.STRING, "")[0]
|
||||
format = parse_param(kw, "FORMAT", EnumConvertType.STRING, "gif")[0]
|
||||
overwrite = parse_param(kw, "OVERWRITE", EnumConvertType.BOOLEAN, False)[0]
|
||||
optimize = parse_param(kw, "OPT", EnumConvertType.BOOLEAN, False)[0]
|
||||
quality = parse_param(kw, "QUALITY", EnumConvertType.INT, 90, 0, 100)[0]
|
||||
motion = parse_param(kw, "QUALITY_M", EnumConvertType.INT, 100, 0, 100)[0]
|
||||
fps = parse_param(kw, "FPS", EnumConvertType.INT, 24, 1, 60)[0]
|
||||
loop = parse_param(kw, "LOOP", EnumConvertType.INT, 0, 0)[0]
|
||||
images = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
suffix = parse_param(kw, Lexicon.PREFIX, EnumConvertType.STRING, uuid4().hex[:16])[0]
|
||||
output_dir = parse_param(kw, Lexicon.PATH, EnumConvertType.STRING, "")[0]
|
||||
format = parse_param(kw, Lexicon.FORMAT, EnumConvertType.STRING, "gif")[0]
|
||||
overwrite = parse_param(kw, Lexicon.OVERWRITE, EnumConvertType.BOOLEAN, False)[0]
|
||||
optimize = parse_param(kw, Lexicon.OPTIMIZE, EnumConvertType.BOOLEAN, False)[0]
|
||||
quality = parse_param(kw, Lexicon.QUALITY, EnumConvertType.INT, 90, 0, 100)[0]
|
||||
motion = parse_param(kw, Lexicon.QUALITY_M, EnumConvertType.INT, 100, 0, 100)[0]
|
||||
fps = parse_param(kw, Lexicon.FPS, EnumConvertType.INT, 24, 1, 60)[0]
|
||||
loop = parse_param(kw, Lexicon.LOOP, EnumConvertType.INT, 0, 0)[0]
|
||||
output_dir = Path(output_dir)
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -273,16 +269,17 @@ Routes the input data from the optional input ports to the output port, preservi
|
||||
d = super().INPUT_TYPES()
|
||||
e = {
|
||||
"optional": {
|
||||
"ROUTE": ("BUS", {"default": None, "tooltip":"Pass through another route node to pre-populate the outputs."}),
|
||||
Lexicon.ROUTE: ("BUS", {
|
||||
"default": None,}),
|
||||
}
|
||||
}
|
||||
d = deep_merge(d, e)
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[Any, ...]:
|
||||
inout = parse_param(kw, "ROUTE", EnumConvertType.ANY, None)
|
||||
inout = parse_param(kw, Lexicon.ROUTE, EnumConvertType.ANY, None)
|
||||
vars = kw.copy()
|
||||
vars.pop("ROUTE", None)
|
||||
vars.pop(Lexicon.ROUTE, None)
|
||||
vars.pop('ident', None)
|
||||
|
||||
parsed = []
|
||||
@@ -300,7 +297,7 @@ class SaveOutputNode(CozyBaseNode):
|
||||
RETURN_TYPES = ()
|
||||
SORT = 85
|
||||
DESCRIPTION = """
|
||||
Save the output image along with its metadata to the specified path. Supports saving additional user metadata and prompt information.
|
||||
Save images with metadata to any specified path. Can save user metadata and prompt information.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
@@ -308,31 +305,25 @@ Save the output image along with its metadata to the specified path. Supports sa
|
||||
d = super().INPUT_TYPES(True, True)
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IMAGE": ("IMAGE", {
|
||||
"default": None,
|
||||
"tooltip":""}),
|
||||
"PATH": ("STRING", {
|
||||
"default": "", "dynamicPrompts":False,
|
||||
"tooltip":"Destination path to save the output"}),
|
||||
"NAME": ("STRING", {
|
||||
"default": "output", "dynamicPrompts":False,
|
||||
"tooltip":"Filename of the output"}),
|
||||
"META": ("JSON", {
|
||||
"default": None,
|
||||
"tooltip":"Extra metadata to save in the file"}),
|
||||
"USER": ("STRING", {
|
||||
"default": "", "multiline": True, "dynamicPrompts":False,
|
||||
"tooltip":"Custom user metadat to save with the file"}),
|
||||
Lexicon.IMAGE: ("IMAGE", {}),
|
||||
Lexicon.PATH: ("STRING", {
|
||||
"default": "", "dynamicPrompts":False}),
|
||||
Lexicon.NAME: ("STRING", {
|
||||
"default": "output", "dynamicPrompts":False,}),
|
||||
Lexicon.META: ("JSON", {
|
||||
"default": None,}),
|
||||
Lexicon.USER: ("STRING", {
|
||||
"default": "", "multiline": True, "dynamicPrompts":False,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> dict[str, Any]:
|
||||
image = parse_param(kw, 'IMAGE', EnumConvertType.IMAGE, None)
|
||||
path = parse_param(kw, 'PATH', EnumConvertType.STRING, "")
|
||||
fname = parse_param(kw, 'NAME', EnumConvertType.STRING, "output")
|
||||
metadata = parse_param(kw, 'META', EnumConvertType.DICT, {})
|
||||
usermeta = parse_param(kw, 'USER', EnumConvertType.DICT, {})
|
||||
image = parse_param(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
path = parse_param(kw, Lexicon.PATH, EnumConvertType.STRING, "")
|
||||
fname = parse_param(kw, Lexicon.NAME, EnumConvertType.STRING, "output")
|
||||
metadata = parse_param(kw, Lexicon.META, EnumConvertType.DICT, {})
|
||||
usermeta = parse_param(kw, Lexicon.USER, EnumConvertType.DICT, {})
|
||||
prompt = parse_param(kw, 'prompt', EnumConvertType.STRING, "")
|
||||
pnginfo = parse_param(kw, 'extra_pnginfo', EnumConvertType.DICT, {})
|
||||
params = list(zip_longest_fill(image, path, fname, metadata, usermeta, prompt, pnginfo))
|
||||
|
||||
+80
-126
@@ -9,10 +9,16 @@ from cozy_comfyui import \
|
||||
InputType, EnumConvertType, \
|
||||
deep_merge, parse_param, parse_value, zip_longest_fill
|
||||
|
||||
from cozy_comfyui.lexicon import \
|
||||
Lexicon
|
||||
|
||||
from cozy_comfyui.node import \
|
||||
COZY_TYPE_ANY, COZY_TYPE_NUMERICAL, COZY_TYPE_NUMBER, \
|
||||
CozyBaseNode
|
||||
|
||||
from . import \
|
||||
EnumFillOperation
|
||||
|
||||
JOV_CATEGORY = "VARIABLE"
|
||||
|
||||
# ==============================================================================
|
||||
@@ -23,7 +29,8 @@ class ValueNode(CozyBaseNode):
|
||||
NAME = "VALUE (JOV) 🧬"
|
||||
CATEGORY = JOV_CATEGORY
|
||||
RETURN_TYPES = (COZY_TYPE_ANY, COZY_TYPE_ANY, COZY_TYPE_ANY, COZY_TYPE_ANY, COZY_TYPE_ANY,)
|
||||
RETURN_NAMES = ("🦄", "X", "Y", "Z", "W",)
|
||||
RETURN_NAMES = ("❔", Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W,)
|
||||
OUTPUT_IS_LIST = (True, True, True, True, True,)
|
||||
SORT = 5
|
||||
DESCRIPTION = """
|
||||
Supplies raw or default values for various data types, supporting vector input with components for X, Y, Z, and W. It also provides a string input option.
|
||||
@@ -36,55 +43,53 @@ Supplies raw or default values for various data types, supporting vector input w
|
||||
typ = EnumConvertType._member_names_[:6]
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"A": (COZY_TYPE_ANY, {
|
||||
"default": None,
|
||||
"tooltip":"Passes a raw value directly, or supplies defaults for any value inputs without connections"}),
|
||||
"TYPE": (typ, {
|
||||
"default": EnumConvertType.BOOLEAN.name,
|
||||
"tooltip":"Take the input and convert it into the selected type."}),
|
||||
"X": (COZY_TYPE_NUMERICAL, {
|
||||
Lexicon.IN_A: (COZY_TYPE_ANY, {
|
||||
"default": None,}),
|
||||
Lexicon.X: (COZY_TYPE_NUMERICAL, {
|
||||
"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize,
|
||||
"forceInput": True}),
|
||||
"Y": (COZY_TYPE_NUMERICAL, {
|
||||
Lexicon.Y: (COZY_TYPE_NUMERICAL, {
|
||||
"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize,
|
||||
"forceInput": True}),
|
||||
"Z": (COZY_TYPE_NUMERICAL, {
|
||||
Lexicon.Z: (COZY_TYPE_NUMERICAL, {
|
||||
"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize,
|
||||
"forceInput": True}),
|
||||
"W": (COZY_TYPE_NUMERICAL, {
|
||||
Lexicon.W: (COZY_TYPE_NUMERICAL, {
|
||||
"default": 0, "mij": -sys.maxsize, "maj": sys.maxsize,
|
||||
"forceInput": True}),
|
||||
"AA": ("VEC4", {
|
||||
Lexicon.TYPE: (typ, {
|
||||
"default": EnumConvertType.BOOLEAN.name}),
|
||||
Lexicon.DEFAULT_A: ("VEC4", {
|
||||
"default": (0, 0, 0, 0), #"mij": -sys.maxsize, "maj": sys.maxsize,
|
||||
"label": ["X", "Y"],
|
||||
"tooltip":"default value vector for A"}),
|
||||
"BB": ("VEC4", {
|
||||
"label": [Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W]}),
|
||||
Lexicon.DEFAULT_B: ("VEC4", {
|
||||
"default": (1,1,1,1), #"mij": -sys.maxsize, "maj": sys.maxsize,
|
||||
"label": ["X", "Y", "Z", "W"],
|
||||
"tooltip":"default value vector for B"}),
|
||||
"SEED": ("INT", {
|
||||
"label": [Lexicon.X, Lexicon.Y, Lexicon.Z, Lexicon.W]}),
|
||||
Lexicon.FILL: (EnumFillOperation._member_names_, {
|
||||
"default": EnumFillOperation.DEFAULT.name}),
|
||||
Lexicon.SEED: ("INT", {
|
||||
"default": 0, "min": 0, "max": sys.maxsize}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[bool]:
|
||||
raw = parse_param(kw, "A", EnumConvertType.ANY, 0)
|
||||
r_x = parse_param(kw, "X", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
r_y = parse_param(kw, "Y", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
r_z = parse_param(kw, "Z", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
r_w = parse_param(kw, "W", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
typ = parse_param(kw, "TYPE", EnumConvertType, EnumConvertType.BOOLEAN.name)
|
||||
xyzw = parse_param(kw, "AA", EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
seed = parse_param(kw, "SEED", EnumConvertType.INT, 0, 0)
|
||||
yyzw = parse_param(kw, "BB", EnumConvertType.VEC4, (1, 1, 1, 1))
|
||||
x_str = parse_param(kw, "STRING", EnumConvertType.STRING, "")
|
||||
params = list(zip_longest_fill(raw, r_x, r_y, r_z, r_w, typ, xyzw, seed, yyzw, x_str))
|
||||
raw = parse_param(kw, Lexicon.IN_A, EnumConvertType.ANY, 0)
|
||||
r_x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
r_y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
r_z = parse_param(kw, Lexicon.Z, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
r_w = parse_param(kw, Lexicon.W, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
typ = parse_param(kw, Lexicon.TYPE, EnumConvertType, EnumConvertType.BOOLEAN.name)
|
||||
xyzw = parse_param(kw, Lexicon.DEFAULT_A, EnumConvertType.VEC4, (0, 0, 0, 0))
|
||||
yyzw = parse_param(kw, Lexicon.DEFAULT_B, EnumConvertType.VEC4, (1, 1, 1, 1))
|
||||
fill = parse_param(kw, Lexicon.FILL, EnumConvertType.BOOLEAN, False)
|
||||
seed = parse_param(kw, Lexicon.SEED, EnumConvertType.INT, 0, 0)
|
||||
params = list(zip_longest_fill(raw, r_x, r_y, r_z, r_w, typ, xyzw, yyzw, fill, seed))
|
||||
results = []
|
||||
pbar = ProgressBar(len(params))
|
||||
old_seed = -1
|
||||
for idx, (raw, r_x, r_y, r_z, r_w, typ, xyzw, seed, yyzw, x_str) in enumerate(params):
|
||||
default = [x_str]
|
||||
for idx, (raw, r_x, r_y, r_z, r_w, typ, xyzw, yyzw, fill, seed) in enumerate(params):
|
||||
# default = [x_str]
|
||||
default2 = None
|
||||
a, b, c, d = xyzw
|
||||
a2, b2, c2, d2 = yyzw
|
||||
@@ -126,6 +131,7 @@ Supplies raw or default values for various data types, supporting vector input w
|
||||
items[i] = out[i]
|
||||
results.append([out, *items])
|
||||
pbar.update_absolute(idx)
|
||||
|
||||
if len(results) < 2:
|
||||
return results[0]
|
||||
return *list(zip(*results)),
|
||||
@@ -149,34 +155,28 @@ Outputs a VECTOR2.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"X": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.X: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "X channel value"}),
|
||||
"Y": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.Y: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Y channel value"}),
|
||||
"A": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default X channel value"}),
|
||||
"B": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default Y channel value"}),
|
||||
Lexicon.DEFAULT: ("VEC2", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[tuple[float, ...], tuple[int, ...]]:
|
||||
x = parse_param(kw, "X", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
y = parse_param(kw, "Y", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
a = parse_param(kw, "A", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
b = parse_param(kw, "B", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
|
||||
x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
default = parse_param(kw, Lexicon.DEFAULT, EnumConvertType.VEC2, 0, -sys.maxsize, sys.maxsize)
|
||||
result = []
|
||||
params = list(zip_longest_fill(x, y, a, b))
|
||||
params = list(zip_longest_fill(x, y, default))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (x, y, a, b) in enumerate(params):
|
||||
x = round(a, 9) if x is None else round(x, 9)
|
||||
y = round(b, 9) if y is None else round(y, 9)
|
||||
for idx, (x, y, default) in enumerate(params):
|
||||
x = round(default[0], 9) if x is None else round(x, 9)
|
||||
y = round(default[1], 9) if y is None else round(y, 9)
|
||||
result.append((x, y,))
|
||||
pbar.update_absolute(idx)
|
||||
return result,
|
||||
@@ -200,42 +200,34 @@ Outputs a VECTOR3.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"X": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.X: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "X channel value"}),
|
||||
"Y": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.Y: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Y channel value"}),
|
||||
"Z": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.Z: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Z channel value"}),
|
||||
"A": ("FLOAT", {
|
||||
Lexicon.DEFAULT: ("VEC3", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default X channel value"}),
|
||||
"B": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default Y channel value"}),
|
||||
"C": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default Z channel value"}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[tuple[float, ...], tuple[int, ...]]:
|
||||
x = parse_param(kw, "X", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
y = parse_param(kw, "Y", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
z = parse_param(kw, "Z", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
a = parse_param(kw, "A", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
b = parse_param(kw, "B", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
c = parse_param(kw, "C", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
z = parse_param(kw, Lexicon.Z, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
default = parse_param(kw, Lexicon.DEFAULT, EnumConvertType.VEC3, 0, -sys.maxsize, sys.maxsize)
|
||||
result = []
|
||||
params = list(zip_longest_fill(x, y, z, a, b, c))
|
||||
params = list(zip_longest_fill(x, y, z, default))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (x, y, z, a, b, c) in enumerate(params):
|
||||
x = round(a, 9) if x is None else round(x, 9)
|
||||
y = round(b, 9) if y is None else round(y, 9)
|
||||
z = round(c, 9) if z is None else round(z, 9)
|
||||
for idx, (x, y, z, default) in enumerate(params):
|
||||
x = round(default[0], 9) if x is None else round(x, 9)
|
||||
y = round(default[1], 9) if y is None else round(y, 9)
|
||||
z = round(default[2], 9) if z is None else round(z, 9)
|
||||
result.append((x, y, z,))
|
||||
pbar.update_absolute(idx)
|
||||
return result,
|
||||
@@ -259,76 +251,38 @@ Outputs a VEC4.
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"X": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.X: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "X channel value"}),
|
||||
"Y": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.Y: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Y channel value"}),
|
||||
"Z": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.Z: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Z channel value"}),
|
||||
"W": (COZY_TYPE_NUMBER, {
|
||||
Lexicon.W: (COZY_TYPE_NUMBER, {
|
||||
"min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "W channel value"}),
|
||||
"A": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default X channel value"}),
|
||||
"B": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default Y channel value"}),
|
||||
"C": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default Z channel value"}),
|
||||
"D": ("FLOAT", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,
|
||||
"tooltip": "Default W channel value"}),
|
||||
Lexicon.DEFAULT: ("VEC4", {
|
||||
"default": 0, "min": -sys.maxsize, "max": sys.maxsize,}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
return Lexicon._parse(d)
|
||||
|
||||
def run(self, **kw) -> tuple[tuple[float, ...], tuple[int, ...]]:
|
||||
x = parse_param(kw, "X", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
y = parse_param(kw, "Y", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
z = parse_param(kw, "Z", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
w = parse_param(kw, "W", EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
a = parse_param(kw, "A", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
b = parse_param(kw, "B", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
c = parse_param(kw, "C", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
d = parse_param(kw, "D", EnumConvertType.FLOAT, 0, -sys.maxsize, sys.maxsize)
|
||||
x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
y = parse_param(kw, Lexicon.Y, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
z = parse_param(kw, Lexicon.Z, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
w = parse_param(kw, Lexicon.W, EnumConvertType.FLOAT, None, -sys.maxsize, sys.maxsize)
|
||||
default = parse_param(kw, Lexicon.DEFAULT, EnumConvertType.VEC4, 0, -sys.maxsize, sys.maxsize)
|
||||
result = []
|
||||
params = list(zip_longest_fill(x, y, z, w, a, b, c, d))
|
||||
pbar = ProgressBar(len(params))
|
||||
for idx, (x, y, z, w, a, b, c, d) in enumerate(params):
|
||||
x = round(a, 9) if x is None else round(x, 9)
|
||||
y = round(b, 9) if y is None else round(y, 9)
|
||||
z = round(c, 9) if z is None else round(z, 9)
|
||||
w = round(d, 9) if w is None else round(w, 9)
|
||||
x = round(default[0], 9) if x is None else round(x, 9)
|
||||
y = round(default[1], 9) if y is None else round(y, 9)
|
||||
z = round(default[2], 9) if z is None else round(z, 9)
|
||||
w = round(default[3], 9) if w is None else round(w, 9)
|
||||
result.append((x, y, z, w,))
|
||||
pbar.update_absolute(idx)
|
||||
return result,
|
||||
|
||||
'''
|
||||
class ParameterNode(CozyBaseNode):
|
||||
NAME = "PARAMETER (JOV) ⚙️"
|
||||
CATEGORY = JOV_CATEGORY
|
||||
RETURN_TYPES = ()
|
||||
RETURN_NAMES = ()
|
||||
SORT = 100
|
||||
DESCRIPTION = """
|
||||
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> InputType:
|
||||
d = super().INPUT_TYPES()
|
||||
d = deep_merge(d, {
|
||||
"optional": {
|
||||
"IN": (COZY_TYPE_ANY, {"default": None}),
|
||||
}
|
||||
})
|
||||
return d
|
||||
|
||||
def run(self, ident, **kw) -> tuple[Any]:
|
||||
return kw["IN"],
|
||||
'''
|
||||
+2
-2
@@ -65,8 +65,8 @@ app.registerExtension({
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = async function () {
|
||||
const me = onNodeCreated?.apply(this);
|
||||
const widget_time = this.widgets.find(w => w.name == 'TIME');
|
||||
const widget_enable = this.widgets.find(w => w.name == 'ENABLE');
|
||||
const widget_time = this.widgets.find(w => w.name == 'time');
|
||||
const widget_enable = this.widgets.find(w => w.name == 'enable');
|
||||
this.total_timeout = 0;
|
||||
let showing = false;
|
||||
let delay_modal;
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ app.registerExtension({
|
||||
nodeType.prototype.onNodeCreated = async function () {
|
||||
const me = onNodeCreated?.apply(this);
|
||||
const self = this;
|
||||
const widget_reset = this.widgets.find(w => w.name == 'RESET');
|
||||
const widget_reset = this.widgets.find(w => w.name == 'reset');
|
||||
widget_reset.callback = async() => {
|
||||
widget_reset.value = false;
|
||||
apiJovimetrix(self.id, "reset");
|
||||
|
||||
+4
-4
@@ -15,10 +15,10 @@ app.registerExtension({
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
const me = onNodeCreated?.apply(this);
|
||||
const alpha = this.widgets.find(w => w.name == 'ALPHA');
|
||||
widgetHookControl(this, 'TYPE', alpha, true);
|
||||
widgetHookValue(this, 'TYPE', 'AA');
|
||||
widgetHookValue(this, 'TYPE', 'BB');
|
||||
const alpha = this.widgets.find(w => w.name == 'alpha');
|
||||
widgetHookControl(this, 'type', alpha, true);
|
||||
widgetHookValue(this, 'type', 'aa');
|
||||
widgetHookValue(this, 'type', 'bb');
|
||||
return me;
|
||||
}
|
||||
return nodeType;
|
||||
|
||||
@@ -15,8 +15,8 @@ app.registerExtension({
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
const me = onNodeCreated?.apply(this);
|
||||
widgetHookValue(this, 'TYPE', 'AA');
|
||||
widgetHookValue(this, 'TYPE', 'BB');
|
||||
widgetHookValue(this, 'type', 'aa');
|
||||
widgetHookValue(this, 'type', 'bb');
|
||||
return me;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ app.registerExtension({
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
const me = onNodeCreated?.apply(this);
|
||||
widgetHookValue(this, 'TYPE', 'AA');
|
||||
widgetHookValue(this, 'type', 'aa');
|
||||
return me;
|
||||
}
|
||||
/*
|
||||
|
||||
+6
-6
@@ -47,10 +47,10 @@ app.registerExtension({
|
||||
this.widget_report.inputEl.readOnly = true;
|
||||
this.widget_report.serializeValue = async () => { };
|
||||
|
||||
const widget_queue = this.widgets.find(w => w.name == 'Q');
|
||||
const widget_batch = this.widgets.find(w => w.name == 'BATCH');
|
||||
const widget_hold = this.widgets.find(w => w.name == 'HOLD');
|
||||
const widget_reset = this.widgets.find(w => w.name == 'RESET');
|
||||
const widget_queue = this.widgets.find(w => w.name == 'q');
|
||||
const widget_batch = this.widgets.find(w => w.name == 'batch');
|
||||
const widget_hold = this.widgets.find(w => w.name == 'hold');
|
||||
const widget_reset = this.widgets.find(w => w.name == 'reset');
|
||||
|
||||
widget_queue.inputEl.addEventListener('input', function () {
|
||||
const value = widget_queue.value.split('\n');
|
||||
@@ -98,7 +98,7 @@ app.registerExtension({
|
||||
if (outputIndex == 0 && inputType == "COMBO") {
|
||||
// can link the "same" list -- user breaks it past that, their problem atm.
|
||||
|
||||
const widget_queue = this.widgets.find(w => w.name == 'Q');
|
||||
const widget_queue = this.widgets.find(w => w.name == 'queue');
|
||||
const widget = inputNode.widgets.find(w => w.name == inputSlot.name);
|
||||
const values = widget.options.values.join('\n');
|
||||
if (this.outputs[0].name != _prefix && widget_queue.value != values) {
|
||||
@@ -129,7 +129,7 @@ app.registerExtension({
|
||||
this.outputs[0].name = widget.name;
|
||||
if (widget?.origType == "combo" || widget.type == "COMBO") {
|
||||
const values = widget.options.values;
|
||||
const widget_queue = this.widgets.find(w => w.name == 'Q');
|
||||
const widget_queue = this.widgets.find(w => w.name == 'queue');
|
||||
// remove all connections that don't match the list?
|
||||
widget_queue.value = values.join('\n');
|
||||
update_list(this, values);
|
||||
|
||||
+2
-2
@@ -17,13 +17,13 @@ app.registerExtension({
|
||||
nodeType.prototype.onNodeCreated = async function () {
|
||||
const me = onNodeCreated?.apply(this);
|
||||
const self = this;
|
||||
const widget_reset = this.widgets.find(w => w.name == 'RESET');
|
||||
const widget_reset = this.widgets.find(w => w.name == 'reset');
|
||||
widget_reset.callback = async() => {
|
||||
widget_reset.value = false;
|
||||
apiJovimetrix(self.id, "reset");
|
||||
}
|
||||
|
||||
self.widget_count = this.widgets.find(w => w.name == 'VAL');
|
||||
self.widget_count = this.widgets.find(w => w.name == 'value');
|
||||
async function python_tick(event) {
|
||||
if (event.detail.id != self.id) {
|
||||
return;
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@ app.registerExtension({
|
||||
this.outputs[3].type = "*";
|
||||
this.outputs[4].type = "*";
|
||||
|
||||
const ab_data = widgetHookValue(this, 'TYPE', 'AA');
|
||||
widgetHookValue(this, 'TYPE', 'BB');
|
||||
const ab_data = widgetHookValue(this, 'type', 'aa');
|
||||
widgetHookValue(this, 'type', 'bb');
|
||||
|
||||
const oldCallback = ab_data.callback;
|
||||
ab_data.callback = () => {
|
||||
|
||||
Reference in New Issue
Block a user