mirror of
https://git.datalinker.icu/comfyanonymous/ComfyUI
synced 2026-09-04 07:17:05 +08:00
Add files via upload
This commit is contained in:
parent
aee2908d03
commit
19fb502b09
205
comfy_extras/nodes_types.py
Normal file
205
comfy_extras/nodes_types.py
Normal file
@ -0,0 +1,205 @@
|
||||
import re
|
||||
from comfy.comfy_types.node_typing import IO
|
||||
|
||||
ROUND_MODES = ["truncate","round","bankers_rounding"]
|
||||
|
||||
def float_to_int(value: float, mode: str) -> int:
|
||||
if mode == "truncate":
|
||||
return int(value)
|
||||
elif mode == "bankers_rounding":
|
||||
# Python’s round implements “banker’s” (tie-to-even)
|
||||
return int(round(value))
|
||||
elif mode == "round":
|
||||
# half-away-from-zero
|
||||
return int(value + 0.5) if value >= 0 else int(value - 0.5)
|
||||
else:
|
||||
raise ValueError(f"Unknown mode: {mode}")
|
||||
|
||||
class IntToFloat:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"value": ("INT", {"default": 0})}}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value) -> float:
|
||||
return (float(value),)
|
||||
|
||||
class FloatToInt:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {
|
||||
"value": ("FLOAT", {"default": 0.0, "round": False}),
|
||||
"mode": (ROUND_MODES,)
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value, mode) -> int:
|
||||
return (float_to_int(value, mode),)
|
||||
|
||||
class IntToString:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"value": ("INT", {"default": 0})}}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value) -> str:
|
||||
return (str(value),)
|
||||
|
||||
class FloatToString:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {
|
||||
"value": ("FLOAT", {"default": 0.0, "round": False}),
|
||||
"round_value": ("BOOLEAN", {"default": True}),
|
||||
"round_to": ("INT", {"default": 2, "min": 0})
|
||||
}}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value, round_value, round_to) -> str:
|
||||
if round_value:
|
||||
out = f"{value:.{round_to}f}"
|
||||
else:
|
||||
out = str(value)
|
||||
return (out,)
|
||||
|
||||
class StringToNum:
|
||||
|
||||
# Regex that recognises *numeric literals Python will accept as floats*:
|
||||
# • optional sign ([+-]?)
|
||||
# • one of the three mantissa forms:
|
||||
# – digits '.' optional-digits (123. or 123.456)
|
||||
# – '.' digits (.456)
|
||||
# – digits (123)
|
||||
# • optional exponent part with its own optional sign: ([eE][+-]?\d+)?
|
||||
# • \Z anchors the match at the absolute end of the string so
|
||||
# trailing whitespace or characters invalidate the match.
|
||||
_FLOAT_RE = re.compile(
|
||||
r"""
|
||||
[+-]? # optional sign
|
||||
(?:\d+\.\d*|\.\d+|\d+) # mantissa
|
||||
(?:[eE][+-]?\d+)? # optional exponent
|
||||
\Z # end of string
|
||||
""",
|
||||
re.VERBOSE
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {
|
||||
"value": ("STRING", {"default": "0", "multiline": False}),
|
||||
"int_mode": (ROUND_MODES,)
|
||||
}}
|
||||
|
||||
RETURN_TYPES = ("INT","FLOAT",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value, int_mode):
|
||||
s = value.strip()
|
||||
if not self._FLOAT_RE.fullmatch(s):
|
||||
raise ValueError(f"StringToNum: cannot parse '{value}' as a number.")
|
||||
|
||||
float_out = float(s)
|
||||
int_out = float_to_int(float_out, int_mode)
|
||||
|
||||
return (int_out, float_out)
|
||||
|
||||
class BoolToAll:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"value": ("BOOLEAN", {"default": False})}}
|
||||
|
||||
RETURN_TYPES = ("INT","FLOAT","STRING",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value):
|
||||
return (int(value), float(value), str(value),)
|
||||
|
||||
class IntToBool:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"value": ("INT", {"default": 0})}}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value) -> bool:
|
||||
return (bool(value),)
|
||||
|
||||
class FloatToBool:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"value": ("FLOAT", {"default": 0})}}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value) -> bool:
|
||||
return (bool(value),)
|
||||
|
||||
class StringToBool:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {
|
||||
"value": ("STRING", {"default": "False", "multiline": False}),
|
||||
"true_text": ("STRING", {"default": "True", "multiline": False}),
|
||||
"case_sensitive": ("BOOLEAN", {"default": True})
|
||||
}}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, value, true_text, case_sensitive) -> bool:
|
||||
if case_sensitive:
|
||||
match = (value == true_text)
|
||||
else:
|
||||
match = (value.casefold() == true_text.casefold())
|
||||
return (match,)
|
||||
|
||||
class StringToCombo:
|
||||
'''Converts a string into a combo input that may be used with any
|
||||
node with a list widget.
|
||||
'''
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {"required": {"text": (IO.STRING, {"multiline": False})}}
|
||||
|
||||
RETURN_TYPES = (IO.ANY,)
|
||||
RETURN_NAMES = ("COMBO",)
|
||||
FUNCTION = "convert_type"
|
||||
CATEGORY = "utils/type_convert"
|
||||
|
||||
def convert_type(self, text: str):
|
||||
items = [t.strip() for t in text.split(",") if t.strip()]
|
||||
return (items[0] if items else "",)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"Boolean to All": BoolToAll,
|
||||
"Integer to Boolean": IntToBool,
|
||||
"Integer to Float": IntToFloat,
|
||||
"Integer to String": IntToString,
|
||||
"Float to Boolean": FloatToBool,
|
||||
"Float to Integer": FloatToInt,
|
||||
"Float to String": FloatToString,
|
||||
"String to Boolean": StringToBool,
|
||||
"String to Number": StringToNum,
|
||||
"String to Combo": StringToCombo
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user