Skip to content

Commit

Permalink
CR Prompt List, animation nodes to leacy
Browse files Browse the repository at this point in the history
  • Loading branch information
Suzie1 committed Jan 2, 2024
1 parent 8e16140 commit 54441a0
Show file tree
Hide file tree
Showing 10 changed files with 846 additions and 180 deletions.
6 changes: 6 additions & 0 deletions Patch_Notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# 🧩 Comfyroll Studio - Patch Notes

## v1.58 Jan 2, 2024
- updated CR Binary Pattern, added bias parameter and fixed a problem with the swaure size calculation
- added CR Simple List
- added CR XY Product
- moved text utility nodes to a new file and menu category

## v1.57 Jan 1, 2024
- added CR Prompt List
- moved animation prompt nodes to legacy
Expand Down
4 changes: 2 additions & 2 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@author: Suzie1
@title: Comfyroll Studio
@nickname: Comfyroll Studio
@description: 150 custom nodes for Graphics, Animation, IO, Aspect Ratio, Model Merge, ControlNet, LoRA, XY Grid, and Utilities.
@description: 152 custom nodes for artists, designers and animators.
"""

from .live_node_mappings import LIVE_NODE_CLASS_MAPPINGS, LIVE_NODE_DISPLAY_NAME_MAPPINGS
Expand All @@ -36,7 +36,7 @@
NODE_DISPLAY_NAME_MAPPINGS = LIVE_NODE_DISPLAY_NAME_MAPPINGS

print("------------------------------------------")
print("\033[34mComfyroll Studio v1.57 : \033[92m 150 Nodes Loaded\033[0m")
print("\033[34mComfyroll Studio v1.58 : \033[92m 152 Nodes Loaded\033[0m")
print("------------------------------------------")
print("** For changes, please see patch notes at https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/blob/main/Patch_Notes.md")
print("** For help, please see the wiki at https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki")
Expand Down
2 changes: 2 additions & 0 deletions categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
"Comfyroll/Utils/Index": "🧩 Comfyroll Studio/🛠️ Utils/🔢 Index",
"Comfyroll/Utils/Conversion": "🧩 Comfyroll Studio/🛠️ Utils/🔧 Conversion",
"Comfyroll/Utils/Random": "🧩 Comfyroll Studio/🛠️ Utils/🎲 Random",
"Comfyroll/Utils/Text": "🧩 Comfyroll Studio/🛠️ Utils/🔤 Text",
"Comfyroll/Utils/Other": "🧩 Comfyroll Studio/🛠️ Utils/⚙️ Other",
"Comfyroll/LoRA": "🧩 Comfyroll Studio/💊 LoRA",
"Comfyroll/ControlNet": "🧩 Comfyroll Studio/🕹️ ControlNet",
"Comfyroll/XY Grid": "🧩 Comfyroll Studio/📉 XY Grid",
"Comfyroll/SDXL": "🧩 Comfyroll Studio/🌟 SDXL",
"Comfyroll/List": "🧩 Comfyroll Studio/📜 List",
"Comfyroll/List/Utils": "🧩 Comfyroll Studio/📜 List/🛠️ Utils",
"Comfyroll/Aspect Ratio": "🧩 Comfyroll Studio/🔳 Aspect Ratio",
"Comfyroll/Pipe/Module": "🧩 Comfyroll Studio/🎷 Pipe/✈️ Module",
"Comfyroll/Pipe/Image": "🧩 Comfyroll Studio/🎷 Pipe/🛩️ Image",
Expand Down
83 changes: 50 additions & 33 deletions live_node_mappings.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
from .nodes.nodes import *
from .nodes.nodes_aspect_ratio import *
from .nodes.nodes_list import *
from .nodes.nodes_lora import *
from .nodes.nodes_controlnet import *
from .nodes.nodes_pipe import *
from .nodes.nodes_sdxl import *
from .nodes.nodes_model_merge import *
from .nodes.nodes_upscale import *
from .nodes.nodes_xygrid import *
from .nodes.nodes_graphics_matplot import *
from .nodes.nodes_graphics_text import *
from .nodes.nodes_graphics_layout import *
from .nodes.nodes_graphics_filter import *
from .nodes.nodes_graphics_template import *
from .nodes.nodes_graphics_pattern import *
from .nodes.nodes_utils_logic import *
from .nodes.nodes_utils_index import *
from .nodes.nodes_utils_conversion import *
from .nodes.nodes_utils_random import *
from .nodes.nodes_utils_other import *
from .nodes.nodes_legacy import *
try:
from .nodes.nodes import *
from .nodes.nodes_aspect_ratio import *
from .nodes.nodes_list import *
from .nodes.nodes_lora import *
from .nodes.nodes_controlnet import *
from .nodes.nodes_pipe import *
from .nodes.nodes_sdxl import *
from .nodes.nodes_model_merge import *
from .nodes.nodes_upscale import *
from .nodes.nodes_xygrid import *
from .nodes.nodes_legacy import *
except ImportError:
print("\033[34mComfyroll Studio: \033[92mFailed to load Core nodes\033[0m")

try:
from .nodes.nodes_graphics_matplot import *
from .nodes.nodes_graphics_text import *
from .nodes.nodes_graphics_layout import *
from .nodes.nodes_graphics_filter import *
from .nodes.nodes_graphics_template import *
from .nodes.nodes_graphics_pattern import *
except ImportError:
print("\033[34mComfyroll Studio: \033[92mFailed to load Graphics nodes\033[0m")

try:
from .animation_nodes.nodes_interpolation import *
Expand All @@ -32,32 +34,40 @@
from .animation_nodes.nodes_cyclers import *
except ImportError:
print("\033[34mComfyroll Studio: \033[92mFailed to load Animation nodes\033[0m")

try:
from .nodes.nodes_utils_logic import *
from .nodes.nodes_utils_index import *
from .nodes.nodes_utils_conversion import *
from .nodes.nodes_utils_random import *
from .nodes.nodes_utils_text import *
from .nodes.nodes_utils_other import *
except ImportError:
print("\033[34mComfyroll Studio: \033[92mFailed to load Utility nodes\033[0m")

LIVE_NODE_CLASS_MAPPINGS = {
### Other Nodes
"CR Image Output": CR_ImageOutput,
"CR Latent Batch Size": CR_LatentBatchSize,
"CR Conditioning Mixer": CR_ConditioningMixer,
"CR Select Model": CR_SelectModel,
"CR Seed": CR_Seed,
### Text Nodes
"CR Prompt Text": CR_PromptText,
"CR Split String": CR_SplitString,
"CR Multiline Text": CR_MultilineText,
"CR Save Text To File": CR_SaveTextToFile,
"CR Seed": CR_Seed,
"CR Prompt Text": CR_PromptText,
### List Nodes
"CR Text List": CR_TextList,
"CR Prompt List": CR_PromptList,
"CR Prompt List": CR_PromptList,
"CR Simple List": CR_SimpleList,
"CR Load Image List": CR_LoadImageList,
"CR Load Image List Plus": CR_LoadImageListPlus,
"CR Float Range List": CR_FloatRangeList,
"CR Integer Range List": CR_IntegerRangeList,
"CR Load Text List": CR_LoadTextList,
"CR Intertwine Lists" : CR_IntertwineLists,
"CR XY Product": CR_XYProduct,
"CR Batch Images From List": CR_BatchImagesFromList,
"CR Text List To String": CR_TextListToString,
"CR Font File List": CR_FontFileList,
"CR Binary To Bit List": CR_BinaryToBitList,
"CR Binary To Bit List": CR_BinaryToBitList,
### Aspect Ratio Nodes
"CR SD1.5 Aspect Ratio": CR_AspectRatioSD15,
"CR SDXL Aspect Ratio": CR_SDXLAspectRatio,
Expand Down Expand Up @@ -181,7 +191,11 @@
"CR Random Multiline Values": CR_RandomMultilineValues,
"CR Random Multiline Colors": CR_RandomMultilineColors,
"CR Random RGB Gradient": CR_RandomRGBGradient,
"CR Random Panel Codes": CR_RandomPanelCodes,
"CR Random Panel Codes": CR_RandomPanelCodes,
### Text Nodes
"CR Split String": CR_SplitString,
"CR Multiline Text": CR_MultilineText,
"CR Save Text To File": CR_SaveTextToFile,
### Utils Other
"CR Integer Multiple": CR_IntegerMultipleOf,
"CR Value": CR_Value,
Expand Down Expand Up @@ -262,15 +276,18 @@
"CR Font File List": "📜 CR Font File List",
"CR Text List": "📜 CR Text List",
"CR Prompt List": "📜 CR Prompt List",
"CR Simple List": "📜 CR Simple List",
"CR Load Image List": "📜 CR Load Image List",
"CR Load Image List Plus": "📜 CR Load Image List Plus",
"CR Float Range List": "📜 CR Float Range List",
"CR Integer Range List": "📜 CR Integer Range List",
"CR Load Value List": "📜 CR Load Value List",
"CR Load Text List": "📜 CR Load Text List",
"CR Intertwine Lists" : "📜 CR Intertwine Lists",
"CR Binary To Bit List": "📜 CR Binary To Bit List",
"CR Binary To Bit List": "📜 CR Binary To Bit List",
### List Utils
"CR Batch Images From List": "📜 CR Batch Images From List",
"CR Intertwine Lists" : "📜 CR Intertwine Lists",
"CR XY Product": "📜 CR XY Product",
"CR Text List To String": "📜 CR Text List To String",
### Aspect Ratio Nodes
"CR SD1.5 Aspect Ratio": "🔳 CR SD1.5 Aspect Ratio",
Expand Down
10 changes: 9 additions & 1 deletion nodes/functions_graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,4 +473,12 @@ def make_grid_panel(images, max_columns):
x_offset = 0
y_offset += image.height

return combined_image
return combined_image


def interpolate_color(color0, color1, t):
"""
Interpolate between two colors.
"""
return tuple(int(c0 * (1 - t) + c1 * t) for c0, c1 in zip(color0, color1))

102 changes: 30 additions & 72 deletions nodes/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import datetime
import io
from server import PromptServer, BinaryEventTypes
#from nodes import common_ksampler
from PIL import Image
from PIL.PngImagePlugin import PngInfo
from pathlib import Path
Expand Down Expand Up @@ -216,6 +217,7 @@ def get_value(self, prompt):
return (prompt, show_help, )

#---------------------------------------------------------------------------------------------------------------------#
'''
class CR_SplitString:
@classmethod
Expand All @@ -229,7 +231,7 @@ def INPUT_TYPES(s):
RETURN_TYPES = ("STRING", "STRING", "STRING", "STRING", "STRING", )
RETURN_NAMES = ("string_1", "string_2", "string_3", "string_4", "show_help", )
FUNCTION = "split"
CATEGORY = icons.get("Comfyroll/Other")
CATEGORY = icons.get("Comfyroll/Utils/Text")
def split(self, text, delimiter):
Expand All @@ -241,7 +243,7 @@ def split(self, text, delimiter):
show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Other-Nodes#cr-split-string"
return (string_1, string_2, string_3, string_4, show_help, )

'''
#---------------------------------------------------------------------------------------------------------------------#
class CR_ConditioningMixer:

Expand Down Expand Up @@ -317,7 +319,7 @@ def conditioning(self, mix_method, conditioning_1, conditioning_2, average_stren
n = [tw, conditioning_to[i][1].copy()]
out.append(n)
return (out, show_help, )

#---------------------------------------------------------------------------------------------------------------------#
class CR_SelectModel:

Expand Down Expand Up @@ -368,77 +370,34 @@ def select_model(self, ckpt_name1, ckpt_name2, ckpt_name3, ckpt_name4, ckpt_name
show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Other-Nodes#cr-select-model"

return (model, clip, vae, model_name, show_help, )

#---------------------------------------------------------------------------------------------------------------------#
# based on WAS Text Multiline node
class CR_MultilineText:

#---------------------------------------------------------------------------------------------------------------------#
'''
class CR_KSampler:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"text": ("STRING", {"default": '', "multiline": True}),
"convert_from_csv": ("BOOLEAN", {"default": False}),
"csv_quote_char": ("STRING", {"default": "'", "choices": ["'", '"']}),
"remove_chars": ("BOOLEAN", {"default": False}),
"chars_to_remove": ("STRING", {"multiline": False, "default": ""}),
"split_string": ("BOOLEAN", {"default": False}),
}
}
def INPUT_TYPES(s):
return {"required":
{"model": ("MODEL",),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"steps": ("INT", {"default": 20, "min": 1, "max": 10000, "forceInput": True}),
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0, "step":0.1, "round": 0.01, "forceInput": True}),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
"positive": ("CONDITIONING", ),
"negative": ("CONDITIONING", ),
"latent_image": ("LATENT", ),
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
}
}
RETURN_TYPES = ("STRING", "STRING", )
RETURN_NAMES = ("multiline_text", "show_help", )
FUNCTION = "text_multiline"
CATEGORY = icons.get("Comfyroll/Other")
RETURN_TYPES = ("LATENT",)
FUNCTION = "sample"
def text_multiline(self, text, chars_to_remove, split_string=False, remove_chars=False, convert_from_csv=False, csv_quote_char="'"):

new_text = []

# Remove trailing commas
text = text.rstrip(',')

if convert_from_csv:
# Convert CSV to multiline text
csv_reader = csv.reader(io.StringIO(text), quotechar=csv_quote_char)
for row in csv_reader:
new_text.extend(row)
if split_string:
if text.startswith("'") and text.endswith("'"):
text = text[1:-1] # Remove outer single quotes
values = [value.strip() for value in text.split("', '")]
new_text.extend(values)
elif text.startswith('"') and text.endswith('"'):
text = text[1:-1] # Remove outer single quotes
values = [value.strip() for value in text.split('", "')]
new_text.extend(values)
elif ',' in text and text.count("'") % 2 == 0:
# Assume it's a list-like string and split accordingly
text = text.replace("'", '') # Remove single quotes
values = [value.strip() for value in text.split(",")]
new_text.extend(values)
elif ',' in text and text.count('"') % 2 == 0:
# Assume it's a list-like string and split accordingly
text = text.replace('"', '') # Remove single quotes
values = [value.strip() for value in text.split(",")]
new_text.extend(values)
if convert_from_csv == False and split_string == False:
# Process multiline text
for line in io.StringIO(text):
if not line.strip().startswith('#'):
if not line.strip().startswith("\n"):
line = line.replace("\n", '')
if remove_chars:
# Remove quotes from each line
line = line.replace(chars_to_remove, '')
new_text.append(line)

new_text = "\n".join(new_text)

show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Other-Nodes#cr-multiline-text"
CATEGORY = "sampling"
return (new_text, show_help,)

def sample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=1.0):
return common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=denoise)
'''
#---------------------------------------------------------------------------------------------------------------------#
# MAPPINGS
#---------------------------------------------------------------------------------------------------------------------#
Expand All @@ -450,10 +409,9 @@ def text_multiline(self, text, chars_to_remove, split_string=False, remove_chars
"CR Latent Batch Size": CR_LatentBatchSize,
"CR Seed": CR_Seed,
"CR Prompt Text": CR_PromptText,
"CR Split String": CR_SplitString,
"CR Conditioning Mixer": CR_ConditioningMixer,
"CR Select Model": CR_SelectModel,
"CR Multiline Text": CR_MultilineText,
"CR Select Model": CR_SelectModel,
#"CR KSampler": CR_KSampler,
}
'''

16 changes: 12 additions & 4 deletions nodes/nodes_graphics_pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def INPUT_TYPES(cls):
"outline_thickness": ("INT", {"default": 0, "min": 0, "max": 1024}),
"outline_color": (COLORS,),
"jitter_distance": ("INT", {"default": 0, "min": 0, "max": 1024}),
"bias": ("FLOAT", {"default": 0.50, "min": 0.00, "max": 1.00, "step": 0.05}),
},
"optional": {
"bg_color_hex": ("STRING", {"multiline": False, "default": "#000000"}),
Expand All @@ -110,7 +111,7 @@ def draw_pattern(self, binary_pattern, width, height,
color_0="white", color_1="black", outline_thickness=0,
color0_hex='#000000', color1_hex='#000000',
bg_color_hex='#000000', outline_color_hex='#000000',
jitter_distance = 0):
jitter_distance = 0, bias=0.5):

# Get RGB values
color0 = get_color_values(color_0, color0_hex, color_mapping)
Expand All @@ -123,8 +124,8 @@ def draw_pattern(self, binary_pattern, width, height,
grid = [[int(bit) for bit in row.strip()] for row in rows]

# Calculate the size of each square
square_width = width // len(rows[0])
square_height = height // len(rows)
square_width = width / len(rows[0])
square_height = height / len(rows)

# Create a new image
image = Image.new("RGB", (width, height), color=bg_color)
Expand All @@ -145,7 +146,14 @@ def draw_pattern(self, binary_pattern, width, height,
y2 = y1 + square_height + y_jitter

# Draw black square if bit is 1, else draw white square
color = color1 if bit == 1 else color0
#color = color1 if bit == 1 else color0

# Adjust color based on bias
if random.uniform(0, 1) < abs(bias):

This comment has been minimized.

Copy link
@Phen-Ro

Phen-Ro Jan 7, 2024

This means we can never get deterministic output from the binary pattern. Is this intended?

This comment has been minimized.

Copy link
@Suzie1

Suzie1 Jan 8, 2024

Author Owner

Do you have a suggestion for how the bias can be better implemented. Suzie

This comment has been minimized.

Copy link
@Phen-Ro

Phen-Ro Jan 8, 2024

Thinking out loud - a random bias towards one color or another is actually a random bias away from the specified input and towards an "override". Rather than a single parameter to control this, you'd need two. One for the randomness, and the other for the color override. If the randomness is 0.0, then the output is always the input bit pattern regardless of the bias, and if the randomness is 1.0, then the output is always a color chosen from a random bias. If the bias is 0.5, then the random choice is distributed evenly.

So let's say we have two parameters randomness and color_bias

It could be implemented maybe something like this.

if random.uniform(0, 1) < randomness:
    color = color1 if random.uniform(0, 1) < color_bias else color0
else:
    color = color1 if bit == 1 else color0

(Python is not my native tongue and I have no idea if the above is idiomatic.)

color = color1
else:
color = color0

draw.rectangle([x1, y1, x2, y2], fill=color, outline=outline_color, width=outline_thickness)

image_out = pil2tensor(image)
Expand Down
Loading

0 comments on commit 54441a0

Please sign in to comment.