160 lines
4.6 KiB
Python
160 lines
4.6 KiB
Python
"""
|
||
LLS / Utils
|
||
===========
|
||
功能域:数据类型与逻辑工具(对应功能分类总览第 14 节)
|
||
|
||
职责:封装工作流编排所需的基础类型节点、数学运算、逻辑判断、
|
||
类型转换、分辨率辅助、曲线编辑、NOP 占位等节点。
|
||
|
||
开发规范
|
||
--------
|
||
- CATEGORY = "LLS/Utils"
|
||
- 节点尽量纯 Python 实现,减少对 ComfyUI 内部模块的依赖
|
||
- 对外只暴露 NODE_CLASS_MAPPINGS 和 NODE_DISPLAY_NAME_MAPPINGS
|
||
|
||
节点列表(待实现)
|
||
------------------
|
||
- LLSStringLiteral : 字符串字面量节点
|
||
- LLSIntLiteral : 整数字面量节点
|
||
- LLSFloatLiteral : 浮点数字面量节点
|
||
- LLSBoolLiteral : 布尔字面量节点
|
||
- LLSMathOp : 数学运算(加减乘除/取模/幂/对数)
|
||
- LLSLogicOp : 逻辑判断(与/或/非/比较)
|
||
- LLSIfElse : If/Else 条件分支
|
||
- LLSTypeConvert : 类型转换(数字 ↔ 字符串)
|
||
- LLSResolutionSelector : 常用分辨率选择器(含宽高比计算)
|
||
- LLSBezierCurve : 贝塞尔曲线数值生成
|
||
- LLSStringFormat : 字符串格式化(f-string 风格)
|
||
- LLSStringConcat : 字符串拼接
|
||
- LLSRegexReplace : 正则替换
|
||
- LLSNop : 透传占位节点(调试用)
|
||
- LLSPreviewAny : 预览任意数据类型(String/Number/Dict)
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
|
||
# ---------- 节点类示例(基础类型,纯 Python 无外部依赖) ----------
|
||
|
||
class LLSStringLiteral:
|
||
"""输出一个字符串常量,可复用于多个下游节点。"""
|
||
|
||
CATEGORY = "LLS/Utils"
|
||
FUNCTION = "execute"
|
||
RETURN_TYPES = ("STRING",)
|
||
RETURN_NAMES = ("string",)
|
||
DESCRIPTION = "Output a constant string value."
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {
|
||
"required": {
|
||
"value": ("STRING", {"default": "", "multiline": True}),
|
||
}
|
||
}
|
||
|
||
def execute(self, value: str):
|
||
return (value,)
|
||
|
||
|
||
class LLSIntLiteral:
|
||
"""输出一个整数常量。"""
|
||
|
||
CATEGORY = "LLS/Utils"
|
||
FUNCTION = "execute"
|
||
RETURN_TYPES = ("INT",)
|
||
RETURN_NAMES = ("int",)
|
||
DESCRIPTION = "Output a constant integer value."
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {
|
||
"required": {
|
||
"value": ("INT", {"default": 0, "min": -2**31, "max": 2**31 - 1}),
|
||
}
|
||
}
|
||
|
||
def execute(self, value: int):
|
||
return (value,)
|
||
|
||
|
||
class LLSFloatLiteral:
|
||
"""输出一个浮点数常量。"""
|
||
|
||
CATEGORY = "LLS/Utils"
|
||
FUNCTION = "execute"
|
||
RETURN_TYPES = ("FLOAT",)
|
||
RETURN_NAMES = ("float",)
|
||
DESCRIPTION = "Output a constant float value."
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {
|
||
"required": {
|
||
"value": ("FLOAT", {"default": 0.0, "step": 0.01}),
|
||
}
|
||
}
|
||
|
||
def execute(self, value: float):
|
||
return (value,)
|
||
|
||
|
||
class LLSResolutionSelector:
|
||
"""常用分辨率选择器,返回宽和高。"""
|
||
|
||
CATEGORY = "LLS/Utils"
|
||
FUNCTION = "execute"
|
||
RETURN_TYPES = ("INT", "INT")
|
||
RETURN_NAMES = ("width", "height")
|
||
DESCRIPTION = "Select from common resolutions or enter custom width/height."
|
||
|
||
_PRESETS = [
|
||
"Custom",
|
||
"512x512",
|
||
"768x768",
|
||
"1024x1024",
|
||
"512x768",
|
||
"768x512",
|
||
"768x1024",
|
||
"1024x768",
|
||
"1024x576",
|
||
"576x1024",
|
||
"1280x720",
|
||
"720x1280",
|
||
"1920x1080",
|
||
"1080x1920",
|
||
"2048x2048",
|
||
]
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
return {
|
||
"required": {
|
||
"preset": (cls._PRESETS, {"default": "1024x1024"}),
|
||
"custom_width": ("INT", {"default": 1024, "min": 64, "max": 8192, "step": 8}),
|
||
"custom_height": ("INT", {"default": 1024, "min": 64, "max": 8192, "step": 8}),
|
||
}
|
||
}
|
||
|
||
def execute(self, preset: str, custom_width: int, custom_height: int):
|
||
if preset == "Custom":
|
||
return (custom_width, custom_height)
|
||
w, h = preset.split("x")
|
||
return (int(w), int(h))
|
||
|
||
|
||
# ---------- 注册表 ----------
|
||
|
||
NODE_CLASS_MAPPINGS: dict[str, type] = {
|
||
"LLSStringLiteral": LLSStringLiteral,
|
||
"LLSIntLiteral": LLSIntLiteral,
|
||
"LLSFloatLiteral": LLSFloatLiteral,
|
||
"LLSResolutionSelector": LLSResolutionSelector,
|
||
}
|
||
|
||
NODE_DISPLAY_NAME_MAPPINGS: dict[str, str] = {
|
||
"LLSStringLiteral": "LLS String Literal",
|
||
"LLSIntLiteral": "LLS Int Literal",
|
||
"LLSFloatLiteral": "LLS Float Literal",
|
||
"LLSResolutionSelector": "LLS Resolution Selector",
|
||
}
|