|
|
|
|
|
|
|
|
|
|
|
import comfy.sd |
|
import os |
|
import sys |
|
import folder_paths |
|
from nodes import LoraLoader |
|
from .functions_animation import keyframe_scheduler, prompt_scheduler |
|
from ..categories import icons |
|
|
|
|
|
|
|
|
|
class CR_SimpleSchedule: |
|
|
|
@classmethod |
|
def INPUT_TYPES(s): |
|
schedule_types = ["Value", "Text", "Prompt", "Prompt Weight", "Model", "LoRA", "ControlNet", "Style", "Upscale", "Camera", "Job"] |
|
return {"required": {"schedule": ("STRING", |
|
{"multiline": True, "default": "frame_number, item_alias, [attr_value1, attr_value2]"} |
|
), |
|
"schedule_type": (schedule_types,), |
|
"schedule_alias": ("STRING", {"default": "", "multiline": False}), |
|
"schedule_format": (["CR", "Deforum"],), |
|
}, |
|
} |
|
|
|
RETURN_TYPES = ("SCHEDULE", "STRING", ) |
|
RETURN_NAMES = ("SCHEDULE", "show_help", ) |
|
FUNCTION = "send_schedule" |
|
CATEGORY = icons.get("Comfyroll/Animation/Schedule") |
|
|
|
def send_schedule(self, schedule, schedule_type, schedule_alias, schedule_format): |
|
|
|
schedule_lines = list() |
|
|
|
|
|
if schedule != "" and schedule_alias != "": |
|
lines = schedule.split('\n') |
|
for line in lines: |
|
|
|
if not line.strip(): |
|
print(f"[Warning] CR Simple Schedule. Skipped blank line: {line}") |
|
continue |
|
|
|
schedule_lines.extend([(schedule_alias, line)]) |
|
|
|
|
|
show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Schedule-Nodes#cr-simple-schedule" |
|
|
|
return (schedule_lines, show_help, ) |
|
|
|
|
|
class CR_CombineSchedules: |
|
|
|
@classmethod |
|
def INPUT_TYPES(cls): |
|
return {"required": { |
|
}, |
|
"optional":{ |
|
"schedule_1": ("SCHEDULE",), |
|
"schedule_2": ("SCHEDULE",), |
|
"schedule_3": ("SCHEDULE",), |
|
"schedule_4": ("SCHEDULE",), |
|
}, |
|
} |
|
|
|
RETURN_TYPES = ("SCHEDULE", "STRING", ) |
|
RETURN_NAMES = ("SCHEDULE", "show_text", ) |
|
FUNCTION = "combine" |
|
CATEGORY = icons.get("Comfyroll/Animation/Schedule") |
|
|
|
def combine(self, schedule_1=None, schedule_2=None, schedule_3=None, schedule_4=None): |
|
|
|
|
|
schedules = list() |
|
schedule_text = list() |
|
|
|
|
|
if schedule_1 is not None: |
|
schedules.extend([l for l in schedule_1]), |
|
schedule_text.extend(schedule_1), |
|
|
|
if schedule_2 is not None: |
|
schedules.extend([l for l in schedule_2]), |
|
schedule_text.extend(schedule_2), |
|
|
|
if schedule_3 is not None: |
|
schedules.extend([l for l in schedule_3]), |
|
schedule_text.extend(schedule_3), |
|
|
|
if schedule_4 is not None: |
|
schedules.extend([l for l in schedule_4]), |
|
schedule_text.extend(schedule_4), |
|
|
|
print(f"[Debug] CR Combine Schedules: {schedules}") |
|
|
|
show_text = "".join(str(schedule_text)) |
|
|
|
return (schedules, show_text, ) |
|
|
|
|
|
class CR_CentralSchedule: |
|
|
|
@classmethod |
|
def INPUT_TYPES(cls): |
|
schedule_types = ["Value", "Text", "Prompt", "Prompt Weight", "Model", "LoRA", "ControlNet", "Style", "Upscale", "Camera", "Job"] |
|
return {"required": { |
|
"schedule_1": ("STRING", {"multiline": True, "default": "schedule"}), |
|
"schedule_type1": (schedule_types,), |
|
"schedule_alias1": ("STRING", {"multiline": False, "default": ""}), |
|
"schedule_2": ("STRING", {"multiline": True, "default": "schedule"}), |
|
"schedule_type2": (schedule_types,), |
|
"schedule_alias2": ("STRING", {"multiline": False, "default": ""}), |
|
"schedule_3": ("STRING", {"multiline": True, "default": "schedule"}), |
|
"schedule_type3": (schedule_types,), |
|
"schedule_alias3": ("STRING", {"multiline": False, "default": ""}), |
|
"schedule_format": (["CR", "Deforum"],), |
|
}, |
|
"optional": {"schedule": ("SCHEDULE",) |
|
}, |
|
} |
|
|
|
RETURN_TYPES = ("SCHEDULE", "STRING", ) |
|
RETURN_NAMES = ("SCHEDULE", "show_text", ) |
|
FUNCTION = "build_schedule" |
|
CATEGORY = icons.get("Comfyroll/Animation/Schedule") |
|
|
|
def build_schedule(self, schedule_1, schedule_type1, schedule_alias1, schedule_2, schedule_type2, schedule_alias2, schedule_3, schedule_type3, schedule_alias3, schedule_format, schedule=None): |
|
|
|
|
|
|
|
|
|
schedules = list() |
|
schedule_text = list() |
|
|
|
|
|
if schedule is not None: |
|
schedules.extend([l for l in schedule]) |
|
schedule_text.extend([l for l in schedule]), |
|
|
|
|
|
if schedule_1 != "" and schedule_alias1 != "": |
|
lines = schedule_1.split('\n') |
|
for line in lines: |
|
schedules.extend([(schedule_alias1, line)]), |
|
schedule_text.extend([(schedule_alias1 + "," + schedule_1 + "\n")]), |
|
|
|
if schedule_2 != "" and schedule_alias2 != "": |
|
lines = schedule_2.split('\n') |
|
for line in lines: |
|
schedules.extend([(schedule_alias2, line)]), |
|
schedule_text.extend([(schedule_alias2 + "," + schedule_2 + "\n")]), |
|
|
|
if schedule_3 != "" and schedule_alias3 != "": |
|
lines = schedule_3.split('\n') |
|
for line in lines: |
|
schedules.extend([(schedule_alias3, line)]), |
|
schedule_text.extend([(schedule_alias3 + "," + schedule_3 + "\n")]), |
|
|
|
|
|
|
|
show_text = "".join(schedule_text) |
|
|
|
return (schedules, show_text, ) |
|
|
|
|
|
class Comfyroll_ScheduleInputSwitch: |
|
def __init__(self): |
|
pass |
|
|
|
@classmethod |
|
def INPUT_TYPES(cls): |
|
return { |
|
"required": { |
|
"Input": ("INT", {"default": 1, "min": 1, "max": 2}), |
|
"schedule1": ("SCHEDULE",), |
|
"schedule2": ("SCHEDULE",) |
|
} |
|
} |
|
|
|
RETURN_TYPES = ("SCHEDULE", "STRING", ) |
|
RETURN_NAMES = ("SCHEDULE", "show_help", ) |
|
OUTPUT_NODE = True |
|
FUNCTION = "switch" |
|
|
|
CATEGORY = icons.get("Comfyroll/Animation/Schedule") |
|
|
|
def switch(self, Input, schedule1, schedule2): |
|
show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Schedule-Nodes#cr-schedule-input-switch" |
|
if Input == 1: |
|
return (schedule1, show_help, ) |
|
else: |
|
return (schedule2, show_help, ) |
|
|
|
|
|
class CR_OutputScheduleToFile: |
|
|
|
@classmethod |
|
def INPUT_TYPES(s): |
|
return {"required": { |
|
"output_file_path": ("STRING", {"multiline": False, "default": ""}), |
|
"file_name": ("STRING", {"multiline": False, "default": ""}), |
|
"file_extension": (["txt", "csv"],), |
|
"schedule": ("SCHEDULE",), |
|
} |
|
} |
|
|
|
RETURN_TYPES = () |
|
OUTPUT_NODE = True |
|
FUNCTION = "csvoutput" |
|
CATEGORY = icons.get("Comfyroll/Animation/Schedule") |
|
|
|
def csvoutput(self, output_file_path, file_name, schedule, file_extension): |
|
filepath = output_file_path + "\\" + file_name + "." + file_extension |
|
|
|
index = 2 |
|
|
|
if(output_file_path == "" or file_name == ""): |
|
print(f"[Warning] CR Output Schedule To File. No file details found. No file output.") |
|
return () |
|
|
|
while os.path.exists(filepath): |
|
if os.path.exists(filepath): |
|
filepath = output_file_path + "\\" + file_name + str(index) + "." + file_extension |
|
|
|
index = index + 1 |
|
else: |
|
break |
|
|
|
print(f"[Info] CR Output Schedule To File: Saving to {filepath}") |
|
|
|
if file_extension == "csv": |
|
with open(filepath, "w", newline="") as csv_file: |
|
csv_writer = csv.writer(csv_file) |
|
csv_writer.writerows(schedule) |
|
else: |
|
with open(filepath, "w", newline="") as text_writer: |
|
for line in schedule: |
|
str_item = f'{line[0]},"{line[1]}"\n' |
|
text_writer.write(str_item) |
|
|
|
|
|
return () |
|
|
|
|
|
class CR_LoadScheduleFromFile: |
|
|
|
@classmethod |
|
def INPUT_TYPES(s): |
|
return {"required": { |
|
"input_file_path": ("STRING", {"multiline": False, "default": ""}), |
|
"file_name": ("STRING", {"multiline": False, "default": ""}), |
|
"file_extension": (["txt", "csv"],), |
|
} |
|
} |
|
|
|
RETURN_TYPES = ("SCHEDULE", "STRING", ) |
|
RETURN_NAMES = ("SCHEDULE", "show_text", ) |
|
FUNCTION = "csvinput" |
|
CATEGORY = icons.get("Comfyroll/Animation/Schedule") |
|
|
|
def csvinput(self, input_file_path, file_name, file_extension): |
|
|
|
show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Schedule-Nodes#cr-load-schedule-from-file" |
|
|
|
filepath = input_file_path + "\\" + file_name + "." + file_extension |
|
print(f"CR Load Schedule From File: Loading {filepath}") |
|
|
|
lists = [] |
|
|
|
if file_extension == "csv": |
|
with open(filepath, "r") as csv_file: |
|
reader = csv.reader(csv_file) |
|
|
|
for row in reader: |
|
lists.append(row) |
|
|
|
else: |
|
with open(filepath, "r") as txt_file: |
|
for row in txt_file: |
|
parts = row.strip().split(",", 1) |
|
|
|
if len(parts) >= 2: |
|
second_part = parts[1].strip('"') |
|
lists.append([parts[0], second_part]) |
|
|
|
|
|
|
|
return(lists,str(lists),) |
|
|
|
def binary_string_to_schedule(binary_string): |
|
schedule = [] |
|
for i, bit in enumerate(binary_string): |
|
schedule.append(f"{i},{int(bit)}") |
|
return '\n'.join(schedule) |
|
|
|
|
|
class CR_BitSchedule: |
|
|
|
@classmethod |
|
def INPUT_TYPES(s): |
|
return {"required": { |
|
"binary_string": ("STRING", {"multiline": True, "default": ""}), |
|
"interval": ("INT", {"default": 1, "min": 1, "max": 99999}), |
|
"loops": ("INT", {"default": 1, "min": 1, "max": 99999}), |
|
} |
|
} |
|
|
|
RETURN_TYPES = ("STRING", "STRING", ) |
|
RETURN_NAMES = ("SCHEDULE", "show_text", ) |
|
FUNCTION = "bit_schedule" |
|
CATEGORY = icons.get("Comfyroll/Animation/Schedule") |
|
|
|
def bit_schedule(self, binary_string, interval, loops=1): |
|
|
|
show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Schedule-Nodes#cr-bit-schedule" |
|
|
|
schedule = [] |
|
|
|
|
|
binary_string = binary_string.replace(" ", "").replace("\n", "") |
|
''' |
|
for i in range(len(binary_string) * loops): |
|
index = i % len(binary_string) # Use modulo to ensure the index continues in a single sequence |
|
bit = int(binary_string[index]) |
|
schedule.append(f"{i},{bit}") |
|
''' |
|
for i in range(len(binary_string) * loops): |
|
schedule_index = i * interval |
|
bit_index = i % len(binary_string) |
|
bit = int(binary_string[bit_index]) |
|
schedule.append(f"{schedule_index},{bit}") |
|
|
|
schedule_out = '\n'.join(schedule) |
|
|
|
return (schedule_out, show_help,) |
|
|
|
|
|
|
|
|
|
|
|
|
|
''' |
|
NODE_CLASS_MAPPINGS = { |
|
### Schedules |
|
"CR Simple Schedule":CR_SimpleSchedule, |
|
"CR Combine Schedules":CR_CombineSchedules, |
|
"CR Central Schedule":CR_CentralSchedule, |
|
"CR Schedule To ScheduleList":CR_ScheduleToScheduleList, |
|
"CR Schedule Input Switch": Comfyroll_ScheduleInputSwitch, |
|
"CR Output Schedule To File":CR_OutputScheduleToFile, |
|
"CR Load Schedule From File":CR_LoadScheduleFromFile, |
|
"CR Bit Schedule": CR_BitCyclicSchedule, |
|
} |
|
''' |
|
|
|
|