Files
Endless-Nodes/randomizers/endless_randomizers.py
tusharbhutt 84b4e42a4b Add files via upload
Updated randomizers, README, init.py
2025-06-23 23:28:47 -06:00

274 lines
12 KiB
Python

import random
def ensure_order(a, b):
return (a, b) if a <= b else (b, a)
class EndlessNode_Mayhem:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"steps_min": ("INT", {"default": 20, "min": 1, "max": 150}),
"steps_max": ("INT", {"default": 40, "min": 1, "max": 150}),
"cfg_min": ("FLOAT", {"default": 6.0, "min": 1.0, "max": 20.0}),
"cfg_max": ("FLOAT", {"default": 12.0, "min": 1.0, "max": 20.0}),
"guidance_min": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 6.0}),
"guidance_max": ("FLOAT", {"default": 3.5, "min": 0.0, "max": 6.0}),
"height_min": ("INT", {"default": 512, "min": 256, "max": 4096}),
"height_max": ("INT", {"default": 768, "min": 256, "max": 4096}),
"width_min": ("INT", {"default": 512, "min": 256, "max": 4096}),
"width_max": ("INT", {"default": 768, "min": 256, "max": 4096}),
"flip_dimensions": ("BOOLEAN", {"default": True}),
"divisible_by_64": ("BOOLEAN", {"default": False}),
"seed_min": ("INT", {"default": 0, "min": 0, "max": 2**32 - 1}),
"seed_max": ("INT", {"default": 8675309, "min": 0, "max": 2**32 - 1}),
"seed": ("INT", {
"default": 0,
"min": 0,
"max": 2**32 - 1
}),
}
}
RETURN_TYPES = ("INT", "FLOAT", "FLOAT", "INT", "INT", "INT")
RETURN_NAMES = ("steps", "cfg_scale", "cfg_guidance", "height", "width", "seed")
FUNCTION = "randomize_with_flip"
CATEGORY = "Endless 🌊✨/Randomizers"
def randomize_with_flip(self, steps_min, steps_max, cfg_min, cfg_max, guidance_min, guidance_max, height_min, height_max, width_min, width_max, flip_dimensions, divisible_by_64, seed_min, seed_max, seed):
# Use the seed to ensure reproducible randomness
random.seed(seed)
# Set divisibility requirement
divisor = 64 if divisible_by_64 else 16
# Min and max sanity checks
steps_min, steps_max = ensure_order(steps_min, steps_max)
cfg_min, cfg_max = ensure_order(cfg_min, cfg_max)
guidance_min, guidance_max = ensure_order(guidance_min, guidance_max)
height_min, height_max = ensure_order(height_min, height_max)
width_min, width_max = ensure_order(width_min, width_max)
seed_min, seed_max = ensure_order(seed_min, seed_max)
# Ensure dimensions are divisible by divisor and at least 256
height_min = max(256, (height_min // divisor) * divisor)
height_max = max(256, (height_max // divisor) * divisor)
width_min = max(256, (width_min // divisor) * divisor)
width_max = max(256, (width_max // divisor) * divisor)
# Random values
steps = random.randint(steps_min, steps_max)
cfg_scale = round(random.uniform(cfg_min, cfg_max), 2)
cfg_guidance = round(random.uniform(guidance_min, guidance_max), 2)
# Pick values based on user-defined intent
height = random.randint(height_min // divisor, height_max // divisor) * divisor
width = random.randint(width_min // divisor, width_max // divisor) * divisor
# Flip output if requested
if flip_dimensions and random.random() < 0.5:
width, height = height, width
output_seed = random.randint(seed_min, seed_max)
return (steps, cfg_scale, cfg_guidance, height, width, output_seed)
class EndlessNode_Chaos:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"steps_min": ("INT", {"default": 20, "min": 1, "max": 150}),
"steps_max": ("INT", {"default": 40, "min": 1, "max": 150}),
"cfg_min": ("FLOAT", {"default": 6.0, "min": 1.0, "max": 20.0}),
"cfg_max": ("FLOAT", {"default": 12.0, "min": 1.0, "max": 20.0}),
"guidance_min": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 6.0}),
"guidance_max": ("FLOAT", {"default": 3.5, "min": 0.0, "max": 6.0}),
"dimension_min": ("INT", {"default": 512, "min": 256, "max": 4096}),
"dimension_max": ("INT", {"default": 1024, "min": 256, "max": 4096}),
"orientation": (["portrait", "landscape", "square", "random"], {"default": "random"}),
"divisible_by_64": ("BOOLEAN", {"default": False}),
"seed_min": ("INT", {"default": 0, "min": 0, "max": 2**32 - 1}),
"seed_max": ("INT", {"default": 8675309, "min": 0, "max": 2**32 - 1}),
"seed": ("INT", {
"default": 0,
"min": 0,
"max": 2**32 - 1
}),
}
}
RETURN_TYPES = ("INT", "FLOAT", "FLOAT", "INT", "INT", "INT")
RETURN_NAMES = ("steps", "cfg_scale", "cfg_guidance", "height", "width", "seed")
FUNCTION = "randomize_aspect_ratio_chaos"
CATEGORY = "Endless 🌊✨/Randomizers"
def randomize_aspect_ratio_chaos(self, steps_min, steps_max, cfg_min, cfg_max, guidance_min, guidance_max, dimension_min, dimension_max, orientation, divisible_by_64, seed_min, seed_max, seed):
# Use the seed to ensure reproducible randomness
random.seed(seed)
# Set divisibility requirement
divisor = 64 if divisible_by_64 else 16
# Min and max sanity checks
steps_min, steps_max = ensure_order(steps_min, steps_max)
cfg_min, cfg_max = ensure_order(cfg_min, cfg_max)
guidance_min, guidance_max = ensure_order(guidance_min, guidance_max)
dimension_min, dimension_max = ensure_order(dimension_min, dimension_max)
seed_min, seed_max = ensure_order(seed_min, seed_max)
# Ensure min/max dimensions are properly divisible
dimension_min = max(256, (dimension_min // divisor) * divisor)
dimension_max = max(256, (dimension_max // divisor) * divisor)
# Common aspect ratios (width:height)
aspect_ratios = [
(1, 1), # 1:1 Square
(4, 3), # 4:3 Classic
(3, 2), # 3:2 Classic photo
(16, 9), # 16:9 Widescreen
(5, 4), # 5:4
(5, 3), # 5:3
(7, 5), # 7:5
(8, 5), # 8:5
(192, 100), # 1.92:1 Instagram Stories
(21, 9), # 21:9 Ultrawide (2.33:1)
(9, 21), # 9:21 Ultra-tall mobile
(22, 10), # 2.2:1 70mm Cinema
(28, 10), # 2.8:1 Facebook Cover (approx)
(185, 100), # 1.85:1 Cinema
(239, 100), # 2.39:1 Anamorphic
]
# Filter aspect ratios based on orientation
if orientation == "square":
filtered_ratios = [(1, 1)]
elif orientation == "landscape":
filtered_ratios = [(w, h) for w, h in aspect_ratios if w > h]
elif orientation == "portrait":
filtered_ratios = [(h, w) for w, h in aspect_ratios if w > h] # Flip to portrait
filtered_ratios.append((1, 1)) # Include square
else: # random
# Include both orientations for non-square ratios
all_ratios = []
for w, h in aspect_ratios:
all_ratios.append((w, h)) # Landscape
if w != h: # Don't duplicate square
all_ratios.append((h, w)) # Portrait
filtered_ratios = all_ratios
# Find valid dimensions for each aspect ratio
valid_dimensions = []
for aspect_w, aspect_h in filtered_ratios:
# Try different scales to find dimensions within our bounds
for scale in range(1, 100): # Reasonable scale range
width = (aspect_w * scale * divisor) // divisor * divisor
height = (aspect_h * scale * divisor) // divisor * divisor
# Check if dimensions are within bounds
if (dimension_min <= width <= dimension_max and
dimension_min <= height <= dimension_max):
valid_dimensions.append((width, height))
# If we've exceeded max dimension, no point in larger scales
if width > dimension_max or height > dimension_max:
break
# Remove duplicates and ensure we have at least one option
valid_dimensions = list(set(valid_dimensions))
if not valid_dimensions:
# Fallback to square if no valid aspect ratios found
size = (dimension_min // divisor) * divisor
valid_dimensions = [(size, size)]
# Choose random dimensions
width, height = random.choice(valid_dimensions)
# Generate other random values
steps = random.randint(steps_min, steps_max)
cfg_scale = round(random.uniform(cfg_min, cfg_max), 2)
output_seed = random.randint(seed_min, seed_max)
cfg_guidance = round(random.uniform(guidance_min, guidance_max), 2)
return (steps, cfg_scale, cfg_guidance, height, width, output_seed)
class EndlessNode_Pandemonium:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"divisible_by_64": ("BOOLEAN", {"default": False}),
"seed": ("INT", {
"default": 0,
"min": 0,
"max": 2**32 - 1
}),
}
}
RETURN_TYPES = ("INT", "FLOAT", "FLOAT", "INT", "INT", "INT")
RETURN_NAMES = ("steps", "cfg_scale", "cfg_guidance", "height", "width", "seed")
FUNCTION = "randomize_aspect_ratio_mayhem"
CATEGORY = "Endless 🌊✨/Randomizers"
def randomize_aspect_ratio_mayhem(self, divisible_by_64, seed):
import random
random.seed(seed)
# Fixed internal config
dimension_min = 512
dimension_max = 1536
divisor = 64 if divisible_by_64 else 16
dimension_min = max(256, (dimension_min // divisor) * divisor)
dimension_max = max(256, (dimension_max // divisor) * divisor)
# All aspect ratios (landscape + portrait + square)
aspect_ratios = [
(1, 1),
(4, 3), (3, 2),
(16, 9), (9, 16),
(5, 4), (4, 5),
(5, 3), (3, 5),
(7, 5), (5, 7),
(8, 5), (5, 8),
(192, 100), (100, 192),
(21, 9), (9, 21),
(22, 10), (10, 22),
(28, 10), (10, 28),
(185, 100), (100, 185),
(239, 100), (100, 239)
]
valid_dimensions = []
for aspect_w, aspect_h in aspect_ratios:
for scale in range(1, 100):
width = (aspect_w * scale * divisor) // divisor * divisor
height = (aspect_h * scale * divisor) // divisor * divisor
if dimension_min <= width <= dimension_max and dimension_min <= height <= dimension_max:
valid_dimensions.append((width, height))
if width > dimension_max or height > dimension_max:
break
if not valid_dimensions:
fallback = (dimension_min // divisor) * divisor
valid_dimensions = [(fallback, fallback)]
width, height = random.choice(valid_dimensions)
steps = random.randint(5, 60)
cfg_scale = round(random.uniform(0, 15), 2)
cfg_guidance = round(random.uniform(1, 4), 2)
output_seed = random.randint(0, seed)
return (steps, cfg_scale, cfg_guidance, height, width, output_seed)