Files
danipisca07-ComfyUI-SimpleL…/nodes.py
T

471 lines
13 KiB
Python

# SimpleLogics - ComfyUI node library for logic, math, and type conversion
# --- Type Conversion ---
class IntToFloat:
DESCRIPTION = "Converts an integer to a float."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("INT", {"default": 0})}}
RETURN_TYPES = ("FLOAT",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (float(value),)
class FloatToInt:
DESCRIPTION = "Converts a float to an integer by truncating the decimal part."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("FLOAT", {"default": 0.0})}}
RETURN_TYPES = ("INT",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (int(value),)
class IntToString:
DESCRIPTION = "Converts an integer to its string representation."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("INT", {"default": 0})}}
RETURN_TYPES = ("STRING",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (str(value),)
class FloatToString:
DESCRIPTION = "Converts a float to its string representation."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("FLOAT", {"default": 0.0})}}
RETURN_TYPES = ("STRING",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (str(value),)
class StringToInt:
DESCRIPTION = "Parses a string into an integer. Accepts decimal strings like '3.9' (truncated to 3)."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("STRING", {"default": "0"})}}
RETURN_TYPES = ("INT",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (int(float(value)),)
class StringToFloat:
DESCRIPTION = "Parses a string into a float."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("STRING", {"default": "0.0"})}}
RETURN_TYPES = ("FLOAT",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (float(value),)
class BoolToInt:
DESCRIPTION = "Converts a boolean to an integer: True → 1, False → 0."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("INT",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (1 if value else 0,)
class IntToBool:
DESCRIPTION = "Converts an integer to a boolean: 0 → False, any other value → True."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"value": ("INT", {"default": 0})}}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "convert"
CATEGORY = "SimpleLogics/Convert"
def convert(self, value):
return (value != 0,)
# --- Logic Operators ---
class LogicAND:
DESCRIPTION = "Returns True only if both inputs are True."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("BOOLEAN", {"default": False}), "b": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Logic"
def op(self, a, b):
return (a and b,)
class LogicOR:
DESCRIPTION = "Returns True if at least one input is True."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("BOOLEAN", {"default": False}), "b": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Logic"
def op(self, a, b):
return (a or b,)
class LogicNOT:
DESCRIPTION = "Returns the opposite boolean value of the input."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Logic"
def op(self, a):
return (not a,)
class LogicXOR:
DESCRIPTION = "Returns True if exactly one of the two inputs is True."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("BOOLEAN", {"default": False}), "b": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Logic"
def op(self, a, b):
return (a ^ b,)
class LogicNAND:
DESCRIPTION = "Returns False only if both inputs are True (NOT AND)."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("BOOLEAN", {"default": False}), "b": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Logic"
def op(self, a, b):
return (not (a and b),)
class LogicNOR:
DESCRIPTION = "Returns True only if both inputs are False (NOT OR)."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("BOOLEAN", {"default": False}), "b": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Logic"
def op(self, a, b):
return (not (a or b),)
# --- Comparison ---
class CompareInt:
DESCRIPTION = "Compares two integers using the selected operator and returns a boolean result."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"a": ("INT", {"default": 0}),
"b": ("INT", {"default": 0}),
"op": (["==", "!=", ">", "<", ">=", "<="],),
}
}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "compare"
CATEGORY = "SimpleLogics/Compare"
def compare(self, a, b, op):
result = {"==": a == b, "!=": a != b, ">": a > b, "<": a < b, ">=": a >= b, "<=": a <= b}[op]
return (result,)
class CompareFloat:
DESCRIPTION = "Compares two floats using the selected operator and returns a boolean result."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"a": ("FLOAT", {"default": 0.0}),
"b": ("FLOAT", {"default": 0.0}),
"op": (["==", "!=", ">", "<", ">=", "<="],),
}
}
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "compare"
CATEGORY = "SimpleLogics/Compare"
def compare(self, a, b, op):
result = {"==": a == b, "!=": a != b, ">": a > b, "<": a < b, ">=": a >= b, "<=": a <= b}[op]
return (result,)
# --- Math ---
class MathMaxInt:
DESCRIPTION = "Returns the larger of two integers."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("INT", {"default": 0}), "b": ("INT", {"default": 0})}}
RETURN_TYPES = ("INT",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Math"
def op(self, a, b):
return (max(a, b),)
class MathMinInt:
DESCRIPTION = "Returns the smaller of two integers."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("INT", {"default": 0}), "b": ("INT", {"default": 0})}}
RETURN_TYPES = ("INT",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Math"
def op(self, a, b):
return (min(a, b),)
class MathMaxFloat:
DESCRIPTION = "Returns the larger of two floats."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("FLOAT", {"default": 0.0}), "b": ("FLOAT", {"default": 0.0})}}
RETURN_TYPES = ("FLOAT",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Math"
def op(self, a, b):
return (max(a, b),)
class MathMinFloat:
DESCRIPTION = "Returns the smaller of two floats."
@classmethod
def INPUT_TYPES(cls):
return {"required": {"a": ("FLOAT", {"default": 0.0}), "b": ("FLOAT", {"default": 0.0})}}
RETURN_TYPES = ("FLOAT",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Math"
def op(self, a, b):
return (min(a, b),)
class MathClampInt:
DESCRIPTION = "Clamps an integer between a minimum and maximum value."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"value": ("INT", {"default": 0}),
"min_val": ("INT", {"default": 0}),
"max_val": ("INT", {"default": 100}),
}
}
RETURN_TYPES = ("INT",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Math"
def op(self, value, min_val, max_val):
return (max(min_val, min(max_val, value)),)
class MathClampFloat:
DESCRIPTION = "Clamps a float between a minimum and maximum value."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"value": ("FLOAT", {"default": 0.0}),
"min_val": ("FLOAT", {"default": 0.0}),
"max_val": ("FLOAT", {"default": 1.0}),
}
}
RETURN_TYPES = ("FLOAT",)
FUNCTION = "op"
CATEGORY = "SimpleLogics/Math"
def op(self, value, min_val, max_val):
return (max(min_val, min(max_val, value)),)
# --- Switch Nodes ---
class SwitchInt:
DESCRIPTION = "Returns if_true when condition is True, otherwise returns if_false. Works with integers."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"condition": ("BOOLEAN", {"default": False}),
"if_true": ("INT", {"default": 0}),
"if_false": ("INT", {"default": 0}),
}
}
RETURN_TYPES = ("INT",)
FUNCTION = "switch"
CATEGORY = "SimpleLogics/Switch"
def switch(self, condition, if_true, if_false):
return (if_true if condition else if_false,)
class SwitchFloat:
DESCRIPTION = "Returns if_true when condition is True, otherwise returns if_false. Works with floats."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"condition": ("BOOLEAN", {"default": False}),
"if_true": ("FLOAT", {"default": 0.0}),
"if_false": ("FLOAT", {"default": 0.0}),
}
}
RETURN_TYPES = ("FLOAT",)
FUNCTION = "switch"
CATEGORY = "SimpleLogics/Switch"
def switch(self, condition, if_true, if_false):
return (if_true if condition else if_false,)
class SwitchString:
DESCRIPTION = "Returns if_true when condition is True, otherwise returns if_false. Works with strings."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"condition": ("BOOLEAN", {"default": False}),
"if_true": ("STRING", {"default": ""}),
"if_false": ("STRING", {"default": ""}),
}
}
RETURN_TYPES = ("STRING",)
FUNCTION = "switch"
CATEGORY = "SimpleLogics/Switch"
def switch(self, condition, if_true, if_false):
return (if_true if condition else if_false,)
class SwitchAny:
DESCRIPTION = "Returns if_true when condition is True, otherwise returns if_false. Works with any type."
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"condition": ("BOOLEAN", {"default": False}),
"if_true": ("*",),
"if_false": ("*",),
}
}
RETURN_TYPES = ("*",)
FUNCTION = "switch"
CATEGORY = "SimpleLogics/Switch"
def switch(self, condition, if_true, if_false):
return (if_true if condition else if_false,)
# --- Mappings ---
NODE_CLASS_MAPPINGS = {
# Convert
"SL_IntToFloat": IntToFloat,
"SL_FloatToInt": FloatToInt,
"SL_IntToString": IntToString,
"SL_FloatToString": FloatToString,
"SL_StringToInt": StringToInt,
"SL_StringToFloat": StringToFloat,
"SL_BoolToInt": BoolToInt,
"SL_IntToBool": IntToBool,
# Logic
"SL_AND": LogicAND,
"SL_OR": LogicOR,
"SL_NOT": LogicNOT,
"SL_XOR": LogicXOR,
"SL_NAND": LogicNAND,
"SL_NOR": LogicNOR,
# Compare
"SL_CompareInt": CompareInt,
"SL_CompareFloat": CompareFloat,
# Math
"SL_MaxInt": MathMaxInt,
"SL_MinInt": MathMinInt,
"SL_MaxFloat": MathMaxFloat,
"SL_MinFloat": MathMinFloat,
"SL_ClampInt": MathClampInt,
"SL_ClampFloat": MathClampFloat,
# Switch
"SL_SwitchInt": SwitchInt,
"SL_SwitchFloat": SwitchFloat,
"SL_SwitchString": SwitchString,
"SL_SwitchAny": SwitchAny,
}
NODE_DISPLAY_NAME_MAPPINGS = {
# Convert
"SL_IntToFloat": "Int → Float",
"SL_FloatToInt": "Float → Int",
"SL_IntToString": "Int → String",
"SL_FloatToString": "Float → String",
"SL_StringToInt": "String → Int",
"SL_StringToFloat": "String → Float",
"SL_BoolToInt": "Bool → Int",
"SL_IntToBool": "Int → Bool",
# Logic
"SL_AND": "AND",
"SL_OR": "OR",
"SL_NOT": "NOT",
"SL_XOR": "XOR",
"SL_NAND": "NAND",
"SL_NOR": "NOR",
# Compare
"SL_CompareInt": "Compare Int",
"SL_CompareFloat": "Compare Float",
# Math
"SL_MaxInt": "Max Int",
"SL_MinInt": "Min Int",
"SL_MaxFloat": "Max Float",
"SL_MinFloat": "Min Float",
"SL_ClampInt": "Clamp Int",
"SL_ClampFloat": "Clamp Float",
# Switch
"SL_SwitchInt": "Switch Int",
"SL_SwitchFloat": "Switch Float",
"SL_SwitchString": "Switch String",
"SL_SwitchAny": "Switch Any",
}