Add custom nodes, Civitai loras (LFS), and vast.ai setup script
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.10, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.11, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.12, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-unix-nightly (12.1, , linux, 3.11, [self-hosted Linux], nightly) (push) Has been cancelled
Execution Tests / test (macos-latest) (push) Has been cancelled
Execution Tests / test (ubuntu-latest) (push) Has been cancelled
Execution Tests / test (windows-latest) (push) Has been cancelled
Test server launches without errors / test (push) Has been cancelled
Unit Tests / test (macos-latest) (push) Has been cancelled
Unit Tests / test (ubuntu-latest) (push) Has been cancelled
Unit Tests / test (windows-2022) (push) Has been cancelled
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.10, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.11, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-stable (12.1, , linux, 3.12, [self-hosted Linux], stable) (push) Has been cancelled
Full Comfy CI Workflow Runs / test-unix-nightly (12.1, , linux, 3.11, [self-hosted Linux], nightly) (push) Has been cancelled
Execution Tests / test (macos-latest) (push) Has been cancelled
Execution Tests / test (ubuntu-latest) (push) Has been cancelled
Execution Tests / test (windows-latest) (push) Has been cancelled
Test server launches without errors / test (push) Has been cancelled
Unit Tests / test (macos-latest) (push) Has been cancelled
Unit Tests / test (ubuntu-latest) (push) Has been cancelled
Unit Tests / test (windows-2022) (push) Has been cancelled
Includes 30 custom nodes committed directly, 7 Civitai-exclusive loras stored via Git LFS, and a setup script that installs all dependencies and downloads HuggingFace-hosted models on vast.ai. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
0
custom_nodes/ComfyMath/src/comfymath/__init__.py
Normal file
0
custom_nodes/ComfyMath/src/comfymath/__init__.py
Normal file
59
custom_nodes/ComfyMath/src/comfymath/bool.py
Normal file
59
custom_nodes/ComfyMath/src/comfymath/bool.py
Normal file
@@ -0,0 +1,59 @@
|
||||
from typing import Any, Callable, Mapping
|
||||
|
||||
DEFAULT_BOOL = ("BOOLEAN", {"default": False})
|
||||
|
||||
|
||||
BOOL_UNARY_OPERATIONS: Mapping[str, Callable[[bool], bool]] = {
|
||||
"Not": lambda a: not a,
|
||||
}
|
||||
|
||||
BOOL_BINARY_OPERATIONS: Mapping[str, Callable[[bool, bool], bool]] = {
|
||||
"Nor": lambda a, b: not (a or b),
|
||||
"Xor": lambda a, b: a ^ b,
|
||||
"Nand": lambda a, b: not (a and b),
|
||||
"And": lambda a, b: a and b,
|
||||
"Xnor": lambda a, b: not (a ^ b),
|
||||
"Or": lambda a, b: a or b,
|
||||
"Eq": lambda a, b: a == b,
|
||||
"Neq": lambda a, b: a != b,
|
||||
}
|
||||
|
||||
|
||||
class BoolUnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {"op": (list(BOOL_UNARY_OPERATIONS.keys()),), "a": DEFAULT_BOOL}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/bool"
|
||||
|
||||
def op(self, op: str, a: bool) -> tuple[bool]:
|
||||
return (BOOL_UNARY_OPERATIONS[op](a),)
|
||||
|
||||
|
||||
class BoolBinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(BOOL_BINARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_BOOL,
|
||||
"b": DEFAULT_BOOL,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/bool"
|
||||
|
||||
def op(self, op: str, a: bool, b: bool) -> tuple[bool]:
|
||||
return (BOOL_BINARY_OPERATIONS[op](a, b),)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"CM_BoolUnaryOperation": BoolUnaryOperation,
|
||||
"CM_BoolBinaryOperation": BoolBinaryOperation,
|
||||
}
|
||||
3
custom_nodes/ComfyMath/src/comfymath/control.py
Normal file
3
custom_nodes/ComfyMath/src/comfymath/control.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from typing import Any, Mapping
|
||||
|
||||
NODE_CLASS_MAPPINGS: Mapping[str, Any] = {}
|
||||
273
custom_nodes/ComfyMath/src/comfymath/convert.py
Normal file
273
custom_nodes/ComfyMath/src/comfymath/convert.py
Normal file
@@ -0,0 +1,273 @@
|
||||
from typing import Any, Mapping
|
||||
|
||||
from .vec import VEC2_ZERO, VEC3_ZERO, VEC4_ZERO
|
||||
from .types import Number, Vec2, Vec3, Vec4
|
||||
|
||||
|
||||
class BoolToInt:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("BOOLEAN", {"default": False})}}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: bool) -> tuple[int]:
|
||||
return (int(a),)
|
||||
|
||||
|
||||
class IntToBool:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("INT", {"default": 0})}}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: int) -> tuple[bool]:
|
||||
return (a != 0,)
|
||||
|
||||
|
||||
class FloatToInt:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("FLOAT", {"default": 0.0, "round": False})}}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: float) -> tuple[int]:
|
||||
return (int(a),)
|
||||
|
||||
|
||||
class IntToFloat:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("INT", {"default": 0})}}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: int) -> tuple[float]:
|
||||
return (float(a),)
|
||||
|
||||
|
||||
class IntToNumber:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("INT", {"default": 0})}}
|
||||
|
||||
RETURN_TYPES = ("NUMBER",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: int) -> tuple[Number]:
|
||||
return (a,)
|
||||
|
||||
|
||||
class NumberToInt:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("NUMBER", {"default": 0.0})}}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: Number) -> tuple[int]:
|
||||
return (int(a),)
|
||||
|
||||
|
||||
class FloatToNumber:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("FLOAT", {"default": 0.0, "round": False})}}
|
||||
|
||||
RETURN_TYPES = ("NUMBER",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: float) -> tuple[Number]:
|
||||
return (a,)
|
||||
|
||||
|
||||
class NumberToFloat:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("NUMBER", {"default": 0.0})}}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: Number) -> tuple[float]:
|
||||
return (float(a),)
|
||||
|
||||
|
||||
class ComposeVec2:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"x": ("FLOAT", {"default": 0.0, "round": False}),
|
||||
"y": ("FLOAT", {"default": 0.0, "round": False}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC2",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, x: float, y: float) -> tuple[Vec2]:
|
||||
return ((x, y),)
|
||||
|
||||
|
||||
class FillVec2:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"a": ("FLOAT", {"default": 0.0, "round": False}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC2",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: float) -> tuple[Vec2]:
|
||||
return ((a, a),)
|
||||
|
||||
|
||||
class BreakoutVec2:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("VEC2", {"default": VEC2_ZERO})}}
|
||||
|
||||
RETURN_TYPES = ("FLOAT", "FLOAT")
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: Vec2) -> tuple[float, float]:
|
||||
return (a[0], a[1])
|
||||
|
||||
|
||||
class ComposeVec3:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"x": ("FLOAT", {"default": 0.0}),
|
||||
"y": ("FLOAT", {"default": 0.0}),
|
||||
"z": ("FLOAT", {"default": 0.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC3",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, x: float, y: float, z: float) -> tuple[Vec3]:
|
||||
return ((x, y, z),)
|
||||
|
||||
|
||||
class FillVec3:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"a": ("FLOAT", {"default": 0.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC3",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: float) -> tuple[Vec3]:
|
||||
return ((a, a, a),)
|
||||
|
||||
|
||||
class BreakoutVec3:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("VEC3", {"default": VEC3_ZERO})}}
|
||||
|
||||
RETURN_TYPES = ("FLOAT", "FLOAT", "FLOAT")
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: Vec3) -> tuple[float, float, float]:
|
||||
return (a[0], a[1], a[2])
|
||||
|
||||
|
||||
class ComposeVec4:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"x": ("FLOAT", {"default": 0.0}),
|
||||
"y": ("FLOAT", {"default": 0.0}),
|
||||
"z": ("FLOAT", {"default": 0.0}),
|
||||
"w": ("FLOAT", {"default": 0.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC4",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, x: float, y: float, z: float, w: float) -> tuple[Vec4]:
|
||||
return ((x, y, z, w),)
|
||||
|
||||
|
||||
class FillVec4:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"a": ("FLOAT", {"default": 0.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC4",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: float) -> tuple[Vec4]:
|
||||
return ((a, a, a, a),)
|
||||
|
||||
|
||||
class BreakoutVec4:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"a": ("VEC4", {"default": VEC4_ZERO})}}
|
||||
|
||||
RETURN_TYPES = ("FLOAT", "FLOAT", "FLOAT", "FLOAT")
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/conversion"
|
||||
|
||||
def op(self, a: Vec4) -> tuple[float, float, float, float]:
|
||||
return (a[0], a[1], a[2], a[3])
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"CM_BoolToInt": BoolToInt,
|
||||
"CM_IntToBool": IntToBool,
|
||||
"CM_FloatToInt": FloatToInt,
|
||||
"CM_IntToFloat": IntToFloat,
|
||||
"CM_IntToNumber": IntToNumber,
|
||||
"CM_NumberToInt": NumberToInt,
|
||||
"CM_FloatToNumber": FloatToNumber,
|
||||
"CM_NumberToFloat": NumberToFloat,
|
||||
"CM_ComposeVec2": ComposeVec2,
|
||||
"CM_ComposeVec3": ComposeVec3,
|
||||
"CM_ComposeVec4": ComposeVec4,
|
||||
"CM_BreakoutVec2": BreakoutVec2,
|
||||
"CM_BreakoutVec3": BreakoutVec3,
|
||||
"CM_BreakoutVec4": BreakoutVec4,
|
||||
}
|
||||
159
custom_nodes/ComfyMath/src/comfymath/float.py
Normal file
159
custom_nodes/ComfyMath/src/comfymath/float.py
Normal file
@@ -0,0 +1,159 @@
|
||||
import math
|
||||
|
||||
from typing import Any, Callable, Mapping
|
||||
|
||||
DEFAULT_FLOAT = ("FLOAT", {"default": 0.0, "step": 0.001, "round": False})
|
||||
|
||||
FLOAT_UNARY_OPERATIONS: Mapping[str, Callable[[float], float]] = {
|
||||
"Neg": lambda a: -a,
|
||||
"Inc": lambda a: a + 1,
|
||||
"Dec": lambda a: a - 1,
|
||||
"Abs": lambda a: abs(a),
|
||||
"Sqr": lambda a: a * a,
|
||||
"Cube": lambda a: a * a * a,
|
||||
"Sqrt": lambda a: math.sqrt(a),
|
||||
"Exp": lambda a: math.exp(a),
|
||||
"Ln": lambda a: math.log(a),
|
||||
"Log10": lambda a: math.log10(a),
|
||||
"Log2": lambda a: math.log2(a),
|
||||
"Sin": lambda a: math.sin(a),
|
||||
"Cos": lambda a: math.cos(a),
|
||||
"Tan": lambda a: math.tan(a),
|
||||
"Asin": lambda a: math.asin(a),
|
||||
"Acos": lambda a: math.acos(a),
|
||||
"Atan": lambda a: math.atan(a),
|
||||
"Sinh": lambda a: math.sinh(a),
|
||||
"Cosh": lambda a: math.cosh(a),
|
||||
"Tanh": lambda a: math.tanh(a),
|
||||
"Asinh": lambda a: math.asinh(a),
|
||||
"Acosh": lambda a: math.acosh(a),
|
||||
"Atanh": lambda a: math.atanh(a),
|
||||
"Round": lambda a: round(a),
|
||||
"Floor": lambda a: math.floor(a),
|
||||
"Ceil": lambda a: math.ceil(a),
|
||||
"Trunc": lambda a: math.trunc(a),
|
||||
"Erf": lambda a: math.erf(a),
|
||||
"Erfc": lambda a: math.erfc(a),
|
||||
"Gamma": lambda a: math.gamma(a),
|
||||
"Radians": lambda a: math.radians(a),
|
||||
"Degrees": lambda a: math.degrees(a),
|
||||
}
|
||||
|
||||
FLOAT_UNARY_CONDITIONS: Mapping[str, Callable[[float], bool]] = {
|
||||
"IsZero": lambda a: a == 0.0,
|
||||
"IsPositive": lambda a: a > 0.0,
|
||||
"IsNegative": lambda a: a < 0.0,
|
||||
"IsNonZero": lambda a: a != 0.0,
|
||||
"IsPositiveInfinity": lambda a: math.isinf(a) and a > 0.0,
|
||||
"IsNegativeInfinity": lambda a: math.isinf(a) and a < 0.0,
|
||||
"IsNaN": lambda a: math.isnan(a),
|
||||
"IsFinite": lambda a: math.isfinite(a),
|
||||
"IsInfinite": lambda a: math.isinf(a),
|
||||
"IsEven": lambda a: a % 2 == 0.0,
|
||||
"IsOdd": lambda a: a % 2 != 0.0,
|
||||
}
|
||||
|
||||
FLOAT_BINARY_OPERATIONS: Mapping[str, Callable[[float, float], float]] = {
|
||||
"Add": lambda a, b: a + b,
|
||||
"Sub": lambda a, b: a - b,
|
||||
"Mul": lambda a, b: a * b,
|
||||
"Div": lambda a, b: a / b,
|
||||
"Mod": lambda a, b: a % b,
|
||||
"Pow": lambda a, b: a**b,
|
||||
"FloorDiv": lambda a, b: a // b,
|
||||
"Max": lambda a, b: max(a, b),
|
||||
"Min": lambda a, b: min(a, b),
|
||||
"Log": lambda a, b: math.log(a, b),
|
||||
"Atan2": lambda a, b: math.atan2(a, b),
|
||||
}
|
||||
|
||||
FLOAT_BINARY_CONDITIONS: Mapping[str, Callable[[float, float], bool]] = {
|
||||
"Eq": lambda a, b: a == b,
|
||||
"Neq": lambda a, b: a != b,
|
||||
"Gt": lambda a, b: a > b,
|
||||
"Gte": lambda a, b: a >= b,
|
||||
"Lt": lambda a, b: a < b,
|
||||
"Lte": lambda a, b: a <= b,
|
||||
}
|
||||
|
||||
|
||||
class FloatUnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_UNARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_FLOAT,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/float"
|
||||
|
||||
def op(self, op: str, a: float) -> tuple[float]:
|
||||
return (FLOAT_UNARY_OPERATIONS[op](a),)
|
||||
|
||||
|
||||
class FloatUnaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_UNARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_FLOAT,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/float"
|
||||
|
||||
def op(self, op: str, a: float) -> tuple[bool]:
|
||||
return (FLOAT_UNARY_CONDITIONS[op](a),)
|
||||
|
||||
|
||||
class FloatBinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_BINARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_FLOAT,
|
||||
"b": DEFAULT_FLOAT,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/float"
|
||||
|
||||
def op(self, op: str, a: float, b: float) -> tuple[float]:
|
||||
return (FLOAT_BINARY_OPERATIONS[op](a, b),)
|
||||
|
||||
|
||||
class FloatBinaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_BINARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_FLOAT,
|
||||
"b": DEFAULT_FLOAT,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/float"
|
||||
|
||||
def op(self, op: str, a: float, b: float) -> tuple[bool]:
|
||||
return (FLOAT_BINARY_CONDITIONS[op](a, b),)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"CM_FloatUnaryOperation": FloatUnaryOperation,
|
||||
"CM_FloatUnaryCondition": FloatUnaryCondition,
|
||||
"CM_FloatBinaryOperation": FloatBinaryOperation,
|
||||
"CM_FloatBinaryCondition": FloatBinaryCondition,
|
||||
}
|
||||
153
custom_nodes/ComfyMath/src/comfymath/graphics.py
Normal file
153
custom_nodes/ComfyMath/src/comfymath/graphics.py
Normal file
@@ -0,0 +1,153 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Mapping, Sequence, Tuple
|
||||
|
||||
|
||||
SDXL_SUPPORTED_RESOLUTIONS = [
|
||||
(1024, 1024, 1.0),
|
||||
(1152, 896, 1.2857142857142858),
|
||||
(896, 1152, 0.7777777777777778),
|
||||
(1216, 832, 1.4615384615384615),
|
||||
(832, 1216, 0.6842105263157895),
|
||||
(1344, 768, 1.75),
|
||||
(768, 1344, 0.5714285714285714),
|
||||
(1536, 640, 2.4),
|
||||
(640, 1536, 0.4166666666666667),
|
||||
]
|
||||
|
||||
SDXL_EXTENDED_RESOLUTIONS = [
|
||||
(512, 2048, 0.25),
|
||||
(512, 1984, 0.26),
|
||||
(512, 1920, 0.27),
|
||||
(512, 1856, 0.28),
|
||||
(576, 1792, 0.32),
|
||||
(576, 1728, 0.33),
|
||||
(576, 1664, 0.35),
|
||||
(640, 1600, 0.4),
|
||||
(640, 1536, 0.42),
|
||||
(704, 1472, 0.48),
|
||||
(704, 1408, 0.5),
|
||||
(704, 1344, 0.52),
|
||||
(768, 1344, 0.57),
|
||||
(768, 1280, 0.6),
|
||||
(832, 1216, 0.68),
|
||||
(832, 1152, 0.72),
|
||||
(896, 1152, 0.78),
|
||||
(896, 1088, 0.82),
|
||||
(960, 1088, 0.88),
|
||||
(960, 1024, 0.94),
|
||||
(1024, 1024, 1.0),
|
||||
(1024, 960, 1.8),
|
||||
(1088, 960, 1.14),
|
||||
(1088, 896, 1.22),
|
||||
(1152, 896, 1.30),
|
||||
(1152, 832, 1.39),
|
||||
(1216, 832, 1.47),
|
||||
(1280, 768, 1.68),
|
||||
(1344, 768, 1.76),
|
||||
(1408, 704, 2.0),
|
||||
(1472, 704, 2.10),
|
||||
(1536, 640, 2.4),
|
||||
(1600, 640, 2.5),
|
||||
(1664, 576, 2.90),
|
||||
(1728, 576, 3.0),
|
||||
(1792, 576, 3.12),
|
||||
(1856, 512, 3.63),
|
||||
(1920, 512, 3.76),
|
||||
(1984, 512, 3.89),
|
||||
(2048, 512, 4.0),
|
||||
]
|
||||
|
||||
|
||||
class Resolution(ABC):
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def resolutions(cls) -> Sequence[Tuple[int, int, float]]: ...
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"resolution": ([f"{res[0]}x{res[1]}" for res in cls.resolutions()],)
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT", "INT")
|
||||
RETURN_NAMES = ("width", "height")
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/graphics"
|
||||
|
||||
def op(self, resolution: str) -> tuple[int, int]:
|
||||
width, height = resolution.split("x")
|
||||
return (int(width), int(height))
|
||||
|
||||
|
||||
class NearestResolution(ABC):
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def resolutions(cls) -> Sequence[Tuple[int, int, float]]: ...
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {"required": {"image": ("IMAGE",)}}
|
||||
|
||||
RETURN_TYPES = ("INT", "INT")
|
||||
RETURN_NAMES = ("width", "height")
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/graphics"
|
||||
|
||||
def op(self, image) -> tuple[int, int]:
|
||||
image_width = image.size()[2]
|
||||
image_height = image.size()[1]
|
||||
print(f"Input image resolution: {image_width}x{image_height}")
|
||||
image_ratio = image_width / image_height
|
||||
differences = [
|
||||
(abs(image_ratio - resolution[2]), resolution)
|
||||
for resolution in self.resolutions()
|
||||
]
|
||||
smallest = None
|
||||
for difference in differences:
|
||||
if smallest is None:
|
||||
smallest = difference
|
||||
else:
|
||||
if difference[0] < smallest[0]:
|
||||
smallest = difference
|
||||
if smallest is not None:
|
||||
width = smallest[1][0]
|
||||
height = smallest[1][1]
|
||||
else:
|
||||
width = 1024
|
||||
height = 1024
|
||||
print(f"Selected resolution: {width}x{height}")
|
||||
return (width, height)
|
||||
|
||||
|
||||
class SDXLResolution(Resolution):
|
||||
@classmethod
|
||||
def resolutions(cls):
|
||||
return SDXL_SUPPORTED_RESOLUTIONS
|
||||
|
||||
|
||||
class SDXLExtendedResolution(Resolution):
|
||||
@classmethod
|
||||
def resolutions(cls):
|
||||
return SDXL_EXTENDED_RESOLUTIONS
|
||||
|
||||
|
||||
class NearestSDXLResolution(NearestResolution):
|
||||
@classmethod
|
||||
def resolutions(cls):
|
||||
return SDXL_SUPPORTED_RESOLUTIONS
|
||||
|
||||
|
||||
class NearestSDXLExtendedResolution(NearestResolution):
|
||||
@classmethod
|
||||
def resolutions(cls):
|
||||
return SDXL_EXTENDED_RESOLUTIONS
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"CM_SDXLResolution": SDXLResolution,
|
||||
"CM_NearestSDXLResolution": NearestSDXLResolution,
|
||||
"CM_SDXLExtendedResolution": SDXLExtendedResolution,
|
||||
"CM_NearestSDXLExtendedResolution": NearestSDXLExtendedResolution,
|
||||
}
|
||||
129
custom_nodes/ComfyMath/src/comfymath/int.py
Normal file
129
custom_nodes/ComfyMath/src/comfymath/int.py
Normal file
@@ -0,0 +1,129 @@
|
||||
import math
|
||||
|
||||
from typing import Any, Callable, Mapping
|
||||
|
||||
DEFAULT_INT = ("INT", {"default": 0})
|
||||
|
||||
INT_UNARY_OPERATIONS: Mapping[str, Callable[[int], int]] = {
|
||||
"Abs": lambda a: abs(a),
|
||||
"Neg": lambda a: -a,
|
||||
"Inc": lambda a: a + 1,
|
||||
"Dec": lambda a: a - 1,
|
||||
"Sqr": lambda a: a * a,
|
||||
"Cube": lambda a: a * a * a,
|
||||
"Not": lambda a: ~a,
|
||||
"Factorial": lambda a: math.factorial(a),
|
||||
}
|
||||
|
||||
INT_UNARY_CONDITIONS: Mapping[str, Callable[[int], bool]] = {
|
||||
"IsZero": lambda a: a == 0,
|
||||
"IsNonZero": lambda a: a != 0,
|
||||
"IsPositive": lambda a: a > 0,
|
||||
"IsNegative": lambda a: a < 0,
|
||||
"IsEven": lambda a: a % 2 == 0,
|
||||
"IsOdd": lambda a: a % 2 == 1,
|
||||
}
|
||||
|
||||
INT_BINARY_OPERATIONS: Mapping[str, Callable[[int, int], int]] = {
|
||||
"Add": lambda a, b: a + b,
|
||||
"Sub": lambda a, b: a - b,
|
||||
"Mul": lambda a, b: a * b,
|
||||
"Div": lambda a, b: a // b,
|
||||
"Mod": lambda a, b: a % b,
|
||||
"Pow": lambda a, b: a**b,
|
||||
"And": lambda a, b: a & b,
|
||||
"Nand": lambda a, b: ~a & b,
|
||||
"Or": lambda a, b: a | b,
|
||||
"Nor": lambda a, b: ~a & b,
|
||||
"Xor": lambda a, b: a ^ b,
|
||||
"Xnor": lambda a, b: ~a ^ b,
|
||||
"Shl": lambda a, b: a << b,
|
||||
"Shr": lambda a, b: a >> b,
|
||||
"Max": lambda a, b: max(a, b),
|
||||
"Min": lambda a, b: min(a, b),
|
||||
}
|
||||
|
||||
INT_BINARY_CONDITIONS: Mapping[str, Callable[[int, int], bool]] = {
|
||||
"Eq": lambda a, b: a == b,
|
||||
"Neq": lambda a, b: a != b,
|
||||
"Gt": lambda a, b: a > b,
|
||||
"Lt": lambda a, b: a < b,
|
||||
"Geq": lambda a, b: a >= b,
|
||||
"Leq": lambda a, b: a <= b,
|
||||
}
|
||||
|
||||
|
||||
class IntUnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {"op": (list(INT_UNARY_OPERATIONS.keys()),), "a": DEFAULT_INT}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/int"
|
||||
|
||||
def op(self, op: str, a: int) -> tuple[int]:
|
||||
return (INT_UNARY_OPERATIONS[op](a),)
|
||||
|
||||
|
||||
class IntUnaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {"op": (list(INT_UNARY_CONDITIONS.keys()),), "a": DEFAULT_INT}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/int"
|
||||
|
||||
def op(self, op: str, a: int) -> tuple[bool]:
|
||||
return (INT_UNARY_CONDITIONS[op](a),)
|
||||
|
||||
|
||||
class IntBinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(INT_BINARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_INT,
|
||||
"b": DEFAULT_INT,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/int"
|
||||
|
||||
def op(self, op: str, a: int, b: int) -> tuple[int]:
|
||||
return (INT_BINARY_OPERATIONS[op](a, b),)
|
||||
|
||||
|
||||
class IntBinaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(INT_BINARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_INT,
|
||||
"b": DEFAULT_INT,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/int"
|
||||
|
||||
def op(self, op: str, a: int, b: int) -> tuple[bool]:
|
||||
return (INT_BINARY_CONDITIONS[op](a, b),)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"CM_IntUnaryOperation": IntUnaryOperation,
|
||||
"CM_IntUnaryCondition": IntUnaryCondition,
|
||||
"CM_IntBinaryOperation": IntBinaryOperation,
|
||||
"CM_IntBinaryCondition": IntBinaryCondition,
|
||||
}
|
||||
94
custom_nodes/ComfyMath/src/comfymath/number.py
Normal file
94
custom_nodes/ComfyMath/src/comfymath/number.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Callable, Mapping
|
||||
|
||||
from .float import (
|
||||
FLOAT_UNARY_OPERATIONS,
|
||||
FLOAT_UNARY_CONDITIONS,
|
||||
FLOAT_BINARY_OPERATIONS,
|
||||
FLOAT_BINARY_CONDITIONS,
|
||||
)
|
||||
from .types import Number
|
||||
|
||||
DEFAULT_NUMBER = ("NUMBER", {"default": 0.0})
|
||||
|
||||
|
||||
class NumberUnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_UNARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_NUMBER,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("NUMBER",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/number"
|
||||
|
||||
def op(self, op: str, a: Number) -> tuple[float]:
|
||||
return (FLOAT_UNARY_OPERATIONS[op](float(a)),)
|
||||
|
||||
|
||||
class NumberUnaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_UNARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_NUMBER,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/Number"
|
||||
|
||||
def op(self, op: str, a: Number) -> tuple[bool]:
|
||||
return (FLOAT_UNARY_CONDITIONS[op](float(a)),)
|
||||
|
||||
|
||||
class NumberBinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_BINARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_NUMBER,
|
||||
"b": DEFAULT_NUMBER,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("NUMBER",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/number"
|
||||
|
||||
def op(self, op: str, a: Number, b: Number) -> tuple[float]:
|
||||
return (FLOAT_BINARY_OPERATIONS[op](float(a), float(b)),)
|
||||
|
||||
|
||||
class NumberBinaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(FLOAT_BINARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_NUMBER,
|
||||
"b": DEFAULT_NUMBER,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/float"
|
||||
|
||||
def op(self, op: str, a: Number, b: Number) -> tuple[bool]:
|
||||
return (FLOAT_BINARY_CONDITIONS[op](float(a), float(b)),)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"CM_NumberUnaryOperation": NumberUnaryOperation,
|
||||
"CM_NumberUnaryCondition": NumberUnaryCondition,
|
||||
"CM_NumberBinaryOperation": NumberBinaryOperation,
|
||||
"CM_NumberBinaryCondition": NumberBinaryCondition,
|
||||
}
|
||||
0
custom_nodes/ComfyMath/src/comfymath/py.typed
Normal file
0
custom_nodes/ComfyMath/src/comfymath/py.typed
Normal file
16
custom_nodes/ComfyMath/src/comfymath/types.py
Normal file
16
custom_nodes/ComfyMath/src/comfymath/types.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import sys
|
||||
|
||||
if sys.version_info[1] < 10:
|
||||
from typing import Tuple, Union
|
||||
|
||||
Number = Union[int, float]
|
||||
Vec2 = Tuple[float, float]
|
||||
Vec3 = Tuple[float, float, float]
|
||||
Vec4 = Tuple[float, float, float, float]
|
||||
else:
|
||||
from typing import TypeAlias
|
||||
|
||||
Number: TypeAlias = int | float
|
||||
Vec2: TypeAlias = tuple[float, float]
|
||||
Vec3: TypeAlias = tuple[float, float, float]
|
||||
Vec4: TypeAlias = tuple[float, float, float, float]
|
||||
500
custom_nodes/ComfyMath/src/comfymath/vec.py
Normal file
500
custom_nodes/ComfyMath/src/comfymath/vec.py
Normal file
@@ -0,0 +1,500 @@
|
||||
import numpy
|
||||
|
||||
from typing import Any, Callable, Mapping
|
||||
|
||||
from .types import Vec2, Vec3, Vec4
|
||||
|
||||
VEC2_ZERO = (0.0, 0.0)
|
||||
DEFAULT_VEC2 = ("VEC2", {"default": VEC2_ZERO})
|
||||
|
||||
VEC3_ZERO = (0.0, 0.0, 0.0)
|
||||
DEFAULT_VEC3 = ("VEC3", {"default": VEC3_ZERO})
|
||||
|
||||
VEC4_ZERO = (0.0, 0.0, 0.0, 0.0)
|
||||
DEFAULT_VEC4 = ("VEC4", {"default": VEC4_ZERO})
|
||||
|
||||
VEC_UNARY_OPERATIONS: Mapping[str, Callable[[numpy.ndarray], numpy.ndarray]] = {
|
||||
"Neg": lambda a: -a,
|
||||
"Normalize": lambda a: a / numpy.linalg.norm(a),
|
||||
}
|
||||
|
||||
VEC_TO_SCALAR_UNARY_OPERATION: Mapping[str, Callable[[numpy.ndarray], float]] = {
|
||||
"Norm": lambda a: numpy.linalg.norm(a).astype(float),
|
||||
}
|
||||
|
||||
VEC_UNARY_CONDITIONS: Mapping[str, Callable[[numpy.ndarray], bool]] = {
|
||||
"IsZero": lambda a: not numpy.any(a).astype(bool),
|
||||
"IsNotZero": lambda a: numpy.any(a).astype(bool),
|
||||
"IsNormalized": lambda a: numpy.allclose(a, a / numpy.linalg.norm(a)),
|
||||
"IsNotNormalized": lambda a: not numpy.allclose(a, a / numpy.linalg.norm(a)),
|
||||
}
|
||||
|
||||
VEC_BINARY_OPERATIONS: Mapping[
|
||||
str, Callable[[numpy.ndarray, numpy.ndarray], numpy.ndarray]
|
||||
] = {
|
||||
"Add": lambda a, b: a + b,
|
||||
"Sub": lambda a, b: a - b,
|
||||
"Cross": lambda a, b: numpy.cross(a, b),
|
||||
}
|
||||
|
||||
VEC_TO_SCALAR_BINARY_OPERATION: Mapping[
|
||||
str, Callable[[numpy.ndarray, numpy.ndarray], float]
|
||||
] = {
|
||||
"Dot": lambda a, b: numpy.dot(a, b),
|
||||
"Distance": lambda a, b: numpy.linalg.norm(a - b).astype(float),
|
||||
}
|
||||
|
||||
VEC_BINARY_CONDITIONS: Mapping[str, Callable[[numpy.ndarray, numpy.ndarray], bool]] = {
|
||||
"Eq": lambda a, b: numpy.allclose(a, b),
|
||||
"Neq": lambda a, b: not numpy.allclose(a, b),
|
||||
}
|
||||
|
||||
VEC_SCALAR_OPERATION: Mapping[str, Callable[[numpy.ndarray, float], numpy.ndarray]] = {
|
||||
"Mul": lambda a, b: a * b,
|
||||
"Div": lambda a, b: a / b,
|
||||
}
|
||||
|
||||
|
||||
def _vec2_from_numpy(a: numpy.ndarray) -> Vec2:
|
||||
return (
|
||||
float(a[0]),
|
||||
float(a[1]),
|
||||
)
|
||||
|
||||
|
||||
def _vec3_from_numpy(a: numpy.ndarray) -> Vec3:
|
||||
return (
|
||||
float(a[0]),
|
||||
float(a[1]),
|
||||
float(a[2]),
|
||||
)
|
||||
|
||||
|
||||
def _vec4_from_numpy(a: numpy.ndarray) -> Vec4:
|
||||
return (
|
||||
float(a[0]),
|
||||
float(a[1]),
|
||||
float(a[2]),
|
||||
float(a[3]),
|
||||
)
|
||||
|
||||
|
||||
class Vec2UnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_UNARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_VEC2,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC2",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec2"
|
||||
|
||||
def op(self, op: str, a: Vec2) -> tuple[Vec2]:
|
||||
return (_vec2_from_numpy(VEC_UNARY_OPERATIONS[op](numpy.array(a))),)
|
||||
|
||||
|
||||
class Vec2ToScalarUnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_TO_SCALAR_UNARY_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC2,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec2"
|
||||
|
||||
def op(self, op: str, a: Vec2) -> tuple[float]:
|
||||
return (VEC_TO_SCALAR_UNARY_OPERATION[op](numpy.array(a)),)
|
||||
|
||||
|
||||
class Vec2UnaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_UNARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_VEC2,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec2"
|
||||
|
||||
def op(self, op: str, a: Vec2) -> tuple[bool]:
|
||||
return (VEC_UNARY_CONDITIONS[op](numpy.array(a)),)
|
||||
|
||||
|
||||
class Vec2BinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_BINARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_VEC2,
|
||||
"b": DEFAULT_VEC2,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC2",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec2"
|
||||
|
||||
def op(self, op: str, a: Vec2, b: Vec2) -> tuple[Vec2]:
|
||||
return (
|
||||
_vec2_from_numpy(VEC_BINARY_OPERATIONS[op](numpy.array(a), numpy.array(b))),
|
||||
)
|
||||
|
||||
|
||||
class Vec2ToScalarBinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_TO_SCALAR_BINARY_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC2,
|
||||
"b": DEFAULT_VEC2,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec2"
|
||||
|
||||
def op(self, op: str, a: Vec2, b: Vec2) -> tuple[float]:
|
||||
return (VEC_TO_SCALAR_BINARY_OPERATION[op](numpy.array(a), numpy.array(b)),)
|
||||
|
||||
|
||||
class Vec2BinaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_BINARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_VEC2,
|
||||
"b": DEFAULT_VEC2,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec2"
|
||||
|
||||
def op(self, op: str, a: Vec2, b: Vec2) -> tuple[bool]:
|
||||
return (VEC_BINARY_CONDITIONS[op](numpy.array(a), numpy.array(b)),)
|
||||
|
||||
|
||||
class Vec2ScalarOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_SCALAR_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC2,
|
||||
"b": ("FLOAT",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC2",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec2"
|
||||
|
||||
def op(self, op: str, a: Vec2, b: float) -> tuple[Vec2]:
|
||||
return (_vec2_from_numpy(VEC_SCALAR_OPERATION[op](numpy.array(a), b)),)
|
||||
|
||||
|
||||
class Vec3UnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_UNARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_VEC3,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC3",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec3"
|
||||
|
||||
def op(self, op: str, a: Vec3) -> tuple[Vec3]:
|
||||
return (_vec3_from_numpy(VEC_UNARY_OPERATIONS[op](numpy.array(a))),)
|
||||
|
||||
|
||||
class Vec3ToScalarUnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_TO_SCALAR_UNARY_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC3,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec3"
|
||||
|
||||
def op(self, op: str, a: Vec3) -> tuple[float]:
|
||||
return (VEC_TO_SCALAR_UNARY_OPERATION[op](numpy.array(a)),)
|
||||
|
||||
|
||||
class Vec3UnaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_UNARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_VEC3,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec3"
|
||||
|
||||
def op(self, op: str, a: Vec3) -> tuple[bool]:
|
||||
return (VEC_UNARY_CONDITIONS[op](numpy.array(a)),)
|
||||
|
||||
|
||||
class Vec3BinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_BINARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_VEC3,
|
||||
"b": DEFAULT_VEC3,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC3",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec3"
|
||||
|
||||
def op(self, op: str, a: Vec3, b: Vec3) -> tuple[Vec3]:
|
||||
return (
|
||||
_vec3_from_numpy(VEC_BINARY_OPERATIONS[op](numpy.array(a), numpy.array(b))),
|
||||
)
|
||||
|
||||
|
||||
class Vec3ToScalarBinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_TO_SCALAR_BINARY_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC3,
|
||||
"b": DEFAULT_VEC3,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec3"
|
||||
|
||||
def op(self, op: str, a: Vec3, b: Vec3) -> tuple[float]:
|
||||
return (VEC_TO_SCALAR_BINARY_OPERATION[op](numpy.array(a), numpy.array(b)),)
|
||||
|
||||
|
||||
class Vec3BinaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_BINARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_VEC3,
|
||||
"b": DEFAULT_VEC3,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec3"
|
||||
|
||||
def op(self, op: str, a: Vec3, b: Vec3) -> tuple[bool]:
|
||||
return (VEC_BINARY_CONDITIONS[op](numpy.array(a), numpy.array(b)),)
|
||||
|
||||
|
||||
class Vec3ScalarOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_SCALAR_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC3,
|
||||
"b": ("FLOAT",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC3",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec3"
|
||||
|
||||
def op(self, op: str, a: Vec3, b: float) -> tuple[Vec3]:
|
||||
return (_vec3_from_numpy(VEC_SCALAR_OPERATION[op](numpy.array(a), b)),)
|
||||
|
||||
|
||||
class Vec4UnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_UNARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_VEC4,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC4",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec4"
|
||||
|
||||
def op(self, op: str, a: Vec4) -> tuple[Vec4]:
|
||||
return (_vec4_from_numpy(VEC_UNARY_OPERATIONS[op](numpy.array(a))),)
|
||||
|
||||
|
||||
class Vec4ToScalarUnaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_TO_SCALAR_UNARY_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC4,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec4"
|
||||
|
||||
def op(self, op: str, a: Vec4) -> tuple[float]:
|
||||
return (VEC_TO_SCALAR_UNARY_OPERATION[op](numpy.array(a)),)
|
||||
|
||||
|
||||
class Vec4UnaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_UNARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_VEC4,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec4"
|
||||
|
||||
def op(self, op: str, a: Vec4) -> tuple[bool]:
|
||||
return (VEC_UNARY_CONDITIONS[op](numpy.array(a)),)
|
||||
|
||||
|
||||
class Vec4BinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_BINARY_OPERATIONS.keys()),),
|
||||
"a": DEFAULT_VEC4,
|
||||
"b": DEFAULT_VEC4,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC4",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec4"
|
||||
|
||||
def op(self, op: str, a: Vec4, b: Vec4) -> tuple[Vec4]:
|
||||
return (
|
||||
_vec4_from_numpy(VEC_BINARY_OPERATIONS[op](numpy.array(a), numpy.array(b))),
|
||||
)
|
||||
|
||||
|
||||
class Vec4ToScalarBinaryOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_TO_SCALAR_BINARY_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC4,
|
||||
"b": DEFAULT_VEC4,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec4"
|
||||
|
||||
def op(self, op: str, a: Vec4, b: Vec4) -> tuple[float]:
|
||||
return (VEC_TO_SCALAR_BINARY_OPERATION[op](numpy.array(a), numpy.array(b)),)
|
||||
|
||||
|
||||
class Vec4BinaryCondition:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_BINARY_CONDITIONS.keys()),),
|
||||
"a": DEFAULT_VEC4,
|
||||
"b": DEFAULT_VEC4,
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOL",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec4"
|
||||
|
||||
def op(self, op: str, a: Vec4, b: Vec4) -> tuple[bool]:
|
||||
return (VEC_BINARY_CONDITIONS[op](numpy.array(a), numpy.array(b)),)
|
||||
|
||||
|
||||
class Vec4ScalarOperation:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Mapping[str, Any]:
|
||||
return {
|
||||
"required": {
|
||||
"op": (list(VEC_SCALAR_OPERATION.keys()),),
|
||||
"a": DEFAULT_VEC4,
|
||||
"b": ("FLOAT",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("VEC4",)
|
||||
FUNCTION = "op"
|
||||
CATEGORY = "math/vec4"
|
||||
|
||||
def op(self, op: str, a: Vec4, b: float) -> tuple[Vec4]:
|
||||
return (_vec4_from_numpy(VEC_SCALAR_OPERATION[op](numpy.array(a), b)),)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"CM_Vec2UnaryOperation": Vec2UnaryOperation,
|
||||
"CM_Vec2UnaryCondition": Vec2UnaryCondition,
|
||||
"CM_Vec2ToScalarUnaryOperation": Vec2ToScalarUnaryOperation,
|
||||
"CM_Vec2BinaryOperation": Vec2BinaryOperation,
|
||||
"CM_Vec2BinaryCondition": Vec2BinaryCondition,
|
||||
"CM_Vec2ToScalarBinaryOperation": Vec2ToScalarBinaryOperation,
|
||||
"CM_Vec2ScalarOperation": Vec2ScalarOperation,
|
||||
"CM_Vec3UnaryOperation": Vec3UnaryOperation,
|
||||
"CM_Vec3UnaryCondition": Vec3UnaryCondition,
|
||||
"CM_Vec3ToScalarUnaryOperation": Vec3ToScalarUnaryOperation,
|
||||
"CM_Vec3BinaryOperation": Vec3BinaryOperation,
|
||||
"CM_Vec3BinaryCondition": Vec3BinaryCondition,
|
||||
"CM_Vec3ToScalarBinaryOperation": Vec3ToScalarBinaryOperation,
|
||||
"CM_Vec3ScalarOperation": Vec3ScalarOperation,
|
||||
"CM_Vec4UnaryOperation": Vec4UnaryOperation,
|
||||
"CM_Vec4UnaryCondition": Vec4UnaryCondition,
|
||||
"CM_Vec4ToScalarUnaryOperation": Vec4ToScalarUnaryOperation,
|
||||
"CM_Vec4BinaryOperation": Vec4BinaryOperation,
|
||||
"CM_Vec4BinaryCondition": Vec4BinaryCondition,
|
||||
"CM_Vec4ToScalarBinaryOperation": Vec4ToScalarBinaryOperation,
|
||||
"CM_Vec4ScalarOperation": Vec4ScalarOperation,
|
||||
}
|
||||
Reference in New Issue
Block a user