swap index param for key in dynamic parse for multi-dynamics
purz node -- but not. fonts should comp with rgbA was RGB
This commit is contained in:
+4
-4
@@ -326,6 +326,7 @@ The Binary Operation node executes binary operations like addition, subtraction,
|
||||
results = []
|
||||
A = parse_param(kw, Lexicon.IN_A, EnumConvertType.ANY, [None])
|
||||
B = parse_param(kw, Lexicon.IN_B, EnumConvertType.ANY, [None])
|
||||
print(A, '-', B)
|
||||
a_x = parse_param(kw, Lexicon.X, EnumConvertType.FLOAT, 0)
|
||||
a_xy = parse_param(kw, Lexicon.IN_A+"2", EnumConvertType.VEC2, [(0, 0)])
|
||||
a_xyz = parse_param(kw, Lexicon.IN_A+"3", EnumConvertType.VEC3, [(0, 0, 0)])
|
||||
@@ -750,7 +751,6 @@ class TickNode(JOVBaseNode):
|
||||
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/{JOV_CATEGORY}"
|
||||
RETURN_TYPES = (WILDCARD, "FLOAT", "FLOAT", WILDCARD)
|
||||
RETURN_NAMES = (Lexicon.VALUE, Lexicon.LINEAR, Lexicon.FPS, Lexicon.TRIGGER)
|
||||
# OUTPUT_IS_LIST = (True, True, True, True)
|
||||
DESCRIPTION = """
|
||||
The `Tick` node acts as a timer and frame counter, emitting pulses or signals based on time intervals or BPM settings. It allows precise synchronization and control over animation sequences, with options to adjust FPS, BPM, and loop points. This node is useful for generating time-based events or driving animations with rhythmic precision.
|
||||
"""
|
||||
@@ -800,7 +800,7 @@ The `Tick` node acts as a timer and frame counter, emitting pulses or signals ba
|
||||
self.__frame = parse_param(kw, Lexicon.VALUE, EnumConvertType.INT, self.__frame)[0]
|
||||
if loop != 0:
|
||||
self.__frame %= loop
|
||||
self.__frame = max(0, self.__frame)
|
||||
# start_frame = max(0, start_frame)
|
||||
hold = parse_param(kw, Lexicon.WAIT, 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]
|
||||
@@ -809,7 +809,7 @@ The `Tick` node acts as a timer and frame counter, emitting pulses or signals ba
|
||||
batch = parse_param(kw, Lexicon.BATCH, EnumConvertType.INT, 1, 1)[0]
|
||||
step_fps = 1. / max(1., float(fps))
|
||||
reset = parse_param(kw, Lexicon.RESET, EnumConvertType.BOOLEAN, False)[0]
|
||||
if parse_reset(ident) > 0 or reset:
|
||||
if loop == 0 and (parse_reset(ident) > 0 or reset):
|
||||
self.__frame = 0
|
||||
trigger = None
|
||||
results = Results()
|
||||
@@ -832,7 +832,7 @@ The `Tick` node acts as a timer and frame counter, emitting pulses or signals ba
|
||||
pbar.update_absolute(idx)
|
||||
if batch < 2:
|
||||
comfy_message(ident, "jovi-tick", {"i": self.__frame})
|
||||
return results.frame, results.lin, results.fixed, results.trigger
|
||||
return (results.frame, results.lin, results.fixed, results.trigger,)
|
||||
|
||||
class ValueNode(JOVBaseNode):
|
||||
NAME = "VALUE (JOV) 🧬"
|
||||
|
||||
+2
-2
@@ -584,7 +584,7 @@ Combine multiple input images into a single image by summing their pixel values.
|
||||
return Lexicon._parse(d, cls)
|
||||
|
||||
def run(self, **kw) -> torch.Tensor:
|
||||
pA = parse_dynamic(kw, 0, EnumConvertType.IMAGE, None)
|
||||
pA = parse_dynamic(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
#pA = [item for sublist in pA for item in sublist]
|
||||
if len(pA) == 0:
|
||||
logger.error("no images to flatten")
|
||||
@@ -809,7 +809,7 @@ Merge multiple input images into a single composite image by stacking them along
|
||||
return Lexicon._parse(d, cls)
|
||||
|
||||
def run(self, **kw) -> Tuple[torch.Tensor, torch.Tensor]:
|
||||
images = parse_dynamic(kw, 0, EnumConvertType.IMAGE, None)
|
||||
images = parse_dynamic(kw, Lexicon.IMAGE, EnumConvertType.IMAGE, None)
|
||||
if len(images) == 0:
|
||||
logger.warning("no images to stack")
|
||||
return
|
||||
|
||||
+32
-1
@@ -206,7 +206,7 @@ The Text Generation node generates images containing text based on user-defined
|
||||
Lexicon.FONT: (cls.FONT_NAMES, {"default": cls.FONT_NAMES[0]}),
|
||||
Lexicon.LETTER: ("BOOLEAN", {"default": False}),
|
||||
Lexicon.AUTOSIZE: ("BOOLEAN", {"default": False}),
|
||||
Lexicon.RGBA_A: ("VEC3", {"default": (255, 255, 255, 255), "step": 1,
|
||||
Lexicon.RGBA_A: ("VEC4", {"default": (255, 255, 255, 255), "step": 1,
|
||||
"label": [Lexicon.R, Lexicon.G, Lexicon.B, Lexicon.A],
|
||||
"rgb": True, "tooltip": "Color of the letters"}),
|
||||
Lexicon.MATTE: ("VEC3", {"default": (0, 0, 0), "step": 1,
|
||||
@@ -426,3 +426,34 @@ The Wave Graph node visualizes audio waveforms as bars. Adjust parameters like t
|
||||
images.append(cv2tensor_full(img))
|
||||
pbar.update_absolute(idx)
|
||||
return [torch.cat(i, dim=0) for i in list(zip(*images))]
|
||||
|
||||
|
||||
'''
|
||||
class PurzNode(JOVBaseNode):
|
||||
NAME = "PURZ (JOV) 🟪"
|
||||
CATEGORY = f"JOVIMETRIX 🔺🟩🔵/PURZ"
|
||||
RETURN_TYPES = ("IMAGE", "IMAGE", "MASK")
|
||||
RETURN_NAMES = (Lexicon.IMAGE, Lexicon.RGB, Lexicon.MASK)
|
||||
DESCRIPTION = """
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> dict:
|
||||
d = super().INPUT_TYPES()
|
||||
d.update({
|
||||
"optional": {
|
||||
Lexicon.PIXEL: (WILDCARD, {"tooltip":"🫥 🥰 🫳 📍 😵💫 😃 🥲 🪯"}),
|
||||
"🐪": (WILDCARD, {"tooltip": "🐪 🙋 💬 😀 🇧🇦 🤣 🥯 👣 🥴 😍 🅾️ 🧞 🙊"}),
|
||||
Lexicon.WH: ("VEC2", {"default": (512, 512), "tooltip": "🥯 👣 🥰 🫳 💬 🥴 😀 📍"}),
|
||||
"🙋": (["😍", "😀", "🤣", "🥴"], {"default": ["😍"]}),
|
||||
"📍": ("INT", {"default": 256}),
|
||||
"🧞": ("INT", {"default": 256}),
|
||||
"🙊": ("VEC4", {"default": (255, 255, 255, 255), "step": 1, "rgb": True})
|
||||
|
||||
}
|
||||
})
|
||||
return Lexicon._parse(d, cls)
|
||||
|
||||
def run(self, **kw) -> Tuple[torch.Tensor, torch.Tensor]:
|
||||
return ()
|
||||
'''
|
||||
+5
-2
@@ -163,7 +163,7 @@ Processes a batch of data based on the selected mode, such as merging, picking,
|
||||
self.__seed = None
|
||||
|
||||
def run(self, **kw) -> Tuple[int, list]:
|
||||
data_list = parse_dynamic(kw, 0, EnumConvertType.ANY, None)
|
||||
data_list = parse_dynamic(kw, Lexicon.UNKNOWN, EnumConvertType.ANY, None)
|
||||
mode = parse_param(kw, Lexicon.BATCH_MODE, EnumConvertType.STRING, EnumBatchMode.MERGE.name)
|
||||
index = parse_param(kw, Lexicon.INDEX, EnumConvertType.INT, EnumBatchMode.MERGE.name)
|
||||
slice_range = parse_param(kw, Lexicon.RANGE, EnumConvertType.VEC3INT, [(0, 0, 1)])
|
||||
@@ -395,10 +395,12 @@ The Graph node visualizes a series of data points over time. It accepts a dynami
|
||||
if parse_reset(ident) > 0 or parse_param(kw, Lexicon.RESET, EnumConvertType.BOOLEAN, False)[0]:
|
||||
self.__history = []
|
||||
longest_edge = 0
|
||||
dynamic = parse_dynamic(kw, 0, EnumConvertType.FLOAT, 0)
|
||||
dynamic = parse_dynamic(kw, Lexicon.UNKNOWN, EnumConvertType.FLOAT, 0)
|
||||
# each of the plugs
|
||||
self.__ax.clear()
|
||||
for idx, val in enumerate(dynamic):
|
||||
logger.debug(idx)
|
||||
logger.debug(val)
|
||||
if isinstance(val, (set, tuple,)):
|
||||
val = list(val)
|
||||
if not isinstance(val, (list, )):
|
||||
@@ -425,6 +427,7 @@ The Graph node visualizes a series of data points over time. It accepts a dynami
|
||||
return (pil2tensor(image),)
|
||||
|
||||
'''
|
||||
# OLD LOAD BATCH NODE -- add to queue?
|
||||
def run(self, **kw) -> None:
|
||||
q = parse_param(kw, Lexicon.QUEUE, EnumConvertType.STRING, "")
|
||||
mode = parse_param(kw, Lexicon.MODE, EnumConvertType.STRING, EnumScaleMode.NONE.name)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
+23
-9
@@ -54,18 +54,32 @@ class EnumSwizzle(Enum):
|
||||
# === SUPPORT ===
|
||||
# =============================================================================
|
||||
|
||||
def parse_dynamic(data:dict, index:int, typ:EnumConvertType, default: Any) -> List[Any]:
|
||||
def parse_dynamic(data:dict, prefix:str, typ:EnumConvertType, default: Any, with_prefix:bool=False) -> List[Any]:
|
||||
"""Convert iterated input field(s) based on a s into a single compound list of entries.
|
||||
|
||||
The default will just look for all keys as integer:
|
||||
|
||||
#_<field name>
|
||||
|
||||
If prefix is non-null, then the format for the key entry is:
|
||||
|
||||
#_<prefix>_<field name>
|
||||
|
||||
This will return N entries in a list based on the prefix pattern or not.
|
||||
|
||||
"""
|
||||
vals = []
|
||||
count = index
|
||||
for k in data:
|
||||
name = k.split('_')
|
||||
try: val = int(name[0])
|
||||
except: continue
|
||||
val = parse_param(data, k, typ, default)
|
||||
if not isinstance(val, (list,)):
|
||||
val = [val]
|
||||
vals.extend(val)
|
||||
count += 1
|
||||
# do we need the prefix (in the case of more than one dynamic param)
|
||||
if (not with_prefix and len(name)== 2) or (with_prefix and len(name) == 3 and name[1] != prefix):
|
||||
# check the index is valid number
|
||||
try: val = int(name[0])
|
||||
except: continue
|
||||
val = parse_param(data, k, typ, default)
|
||||
#if not isinstance(val, (list,)):
|
||||
# val = [val]
|
||||
vals.append(val)
|
||||
return vals
|
||||
|
||||
def parse_value(val:Any, typ:EnumConvertType, default: Any,
|
||||
|
||||
@@ -23,7 +23,7 @@ app.registerExtension({
|
||||
const onComputeSize = nodeType.prototype.computeSize;
|
||||
nodeType.computeSize = () => {
|
||||
const size = onComputeSize?.apply(this);
|
||||
console.info(size);
|
||||
// console.info(size);
|
||||
return [0, 4];
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ app.registerExtension({
|
||||
if (nodeData.name !== _id) {
|
||||
return;
|
||||
}
|
||||
nodeType = node_add_dynamic(nodeType, _prefix, "*", 7);
|
||||
nodeType = node_add_dynamic(nodeType, _prefix);
|
||||
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = async function () {
|
||||
const me = onNodeCreated?.apply(this);
|
||||
@@ -49,8 +50,12 @@ app.registerExtension({
|
||||
for (let i = 0; i < this.inputs.length; i++) {
|
||||
const link_id = this.inputs[i].link;
|
||||
const link = app.graph.links[link_id];
|
||||
if(link && this.inputs[i].name.substring(0, _prefix.length) === _prefix) {
|
||||
const nameParts = this.inputs[i].name.split('_');
|
||||
const isInteger = nameParts.length > 1 && !isNaN(nameParts[0]) && Number.isInteger(parseFloat(nameParts[0]));
|
||||
if (link && isInteger && nameParts[1].substring(0, _prefix.length) === _prefix) {
|
||||
//if(link && this.inputs[i].name.substring(0, _prefix.length) === _prefix) {
|
||||
link.type = `JOV_VG_${count}`;
|
||||
console.info(count)
|
||||
this.inputs[i].color_on = LGraphCanvas.link_type_colors[link.type];
|
||||
count += 1;
|
||||
}
|
||||
+2
-2
@@ -77,7 +77,7 @@ export function node_add_dynamic(nodeType, prefix, dynamic_type='*', index_start
|
||||
let count = self.inputs.length;
|
||||
while (idx < self.inputs.length-1 && count > 0) {
|
||||
const slot = self.inputs[idx];
|
||||
console.info(slot, count)
|
||||
// console.info(slot, count)
|
||||
if (slot) {
|
||||
const parts = slot.name.split('_');
|
||||
// a dynamic jovian slot prefix_
|
||||
@@ -101,7 +101,7 @@ export function node_add_dynamic(nodeType, prefix, dynamic_type='*', index_start
|
||||
}
|
||||
count -= 1;
|
||||
}
|
||||
console.info(idx)
|
||||
//console.info(idx)
|
||||
}
|
||||
|
||||
index_start = Math.max(0, index_start);
|
||||
|
||||
Reference in New Issue
Block a user