5 Commits
9 changed files with 130 additions and 42 deletions
-2
View File
@@ -8,8 +8,6 @@ from .src.comfymath.control import NODE_CLASS_MAPPINGS as control_NCM
from .src.comfymath.graphics import NODE_CLASS_MAPPINGS as graphics_NCM
NODE_CLASS_MAPPINGS = {
**convert_NCM,
**bool_NCM,
+1 -1
View File
@@ -3,7 +3,7 @@ name = "comfymath"
version = "0.1.0"
description = "Math nodes for ComfyUI"
authors = ["Evan Spearman <evan@spearman.mb.ca>"]
license = "Apache-2.0"
license = { text = "Apache License 2.0" }
readme = "README.md"
[tool.poetry.dependencies]
+3 -3
View File
@@ -1,6 +1,6 @@
from typing import Any, Callable, Mapping
DEFAULT_BOOL = ("BOOL", {"default": False})
DEFAULT_BOOL = ("BOOLEAN", {"default": False})
BOOL_UNARY_OPERATIONS: Mapping[str, Callable[[bool], bool]] = {
@@ -26,7 +26,7 @@ class BoolUnaryOperation:
"required": {"op": (list(BOOL_UNARY_OPERATIONS.keys()),), "a": DEFAULT_BOOL}
}
RETURN_TYPES = ("BOOL",)
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "math/bool"
@@ -45,7 +45,7 @@ class BoolBinaryOperation:
}
}
RETURN_TYPES = ("BOOL",)
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "math/bool"
+13 -13
View File
@@ -1,13 +1,13 @@
from typing import Any, Mapping
from .vec import Vec2, VEC2_ZERO, Vec3, VEC3_ZERO, Vec4, VEC4_ZERO
from .number import number
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": ("BOOL", {"default": False})}}
return {"required": {"a": ("BOOLEAN", {"default": False})}}
RETURN_TYPES = ("INT",)
FUNCTION = "op"
@@ -22,7 +22,7 @@ class IntToBool:
def INPUT_TYPES(cls) -> Mapping[str, Any]:
return {"required": {"a": ("INT", {"default": 0})}}
RETURN_TYPES = ("BOOL",)
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "math/conversion"
@@ -33,7 +33,7 @@ class IntToBool:
class FloatToInt:
@classmethod
def INPUT_TYPES(cls) -> Mapping[str, Any]:
return {"required": {"a": ("FLOAT", {"default": 0.0})}}
return {"required": {"a": ("FLOAT", {"default": 0.0, "round": False})}}
RETURN_TYPES = ("INT",)
FUNCTION = "op"
@@ -65,7 +65,7 @@ class IntToNumber:
FUNCTION = "op"
CATEGORY = "math/conversion"
def op(self, a: int) -> tuple[number]:
def op(self, a: int) -> tuple[Number]:
return (a,)
@@ -78,20 +78,20 @@ class NumberToInt:
FUNCTION = "op"
CATEGORY = "math/conversion"
def op(self, a: number) -> tuple[int]:
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})}}
return {"required": {"a": ("FLOAT", {"default": 0.0, "round": False})}}
RETURN_TYPES = ("NUMBER",)
FUNCTION = "op"
CATEGORY = "math/conversion"
def op(self, a: float) -> tuple[number]:
def op(self, a: float) -> tuple[Number]:
return (a,)
@@ -104,7 +104,7 @@ class NumberToFloat:
FUNCTION = "op"
CATEGORY = "math/conversion"
def op(self, a: number) -> tuple[float]:
def op(self, a: Number) -> tuple[float]:
return (float(a),)
@@ -113,8 +113,8 @@ class ComposeVec2:
def INPUT_TYPES(cls) -> Mapping[str, Any]:
return {
"required": {
"x": ("FLOAT", {"default": 0.0}),
"y": ("FLOAT", {"default": 0.0}),
"x": ("FLOAT", {"default": 0.0, "round": False}),
"y": ("FLOAT", {"default": 0.0, "round": False}),
}
}
@@ -131,7 +131,7 @@ class FillVec2:
def INPUT_TYPES(cls) -> Mapping[str, Any]:
return {
"required": {
"a": ("FLOAT", {"default": 0.0}),
"a": ("FLOAT", {"default": 0.0, "round": False}),
}
}
+3 -3
View File
@@ -2,7 +2,7 @@ import math
from typing import Any, Callable, Mapping
DEFAULT_FLOAT = ("FLOAT", {"default": 0.0})
DEFAULT_FLOAT = ("FLOAT", {"default": 0.0, "step": 0.001, "round": False})
FLOAT_UNARY_OPERATIONS: Mapping[str, Callable[[float], float]] = {
"Neg": lambda a: -a,
@@ -105,7 +105,7 @@ class FloatUnaryCondition:
}
}
RETURN_TYPES = ("BOOL",)
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "math/float"
@@ -143,7 +143,7 @@ class FloatBinaryCondition:
}
}
RETURN_TYPES = ("BOOL",)
RETURN_TYPES = ("BOOLEAN",)
FUNCTION = "op"
CATEGORY = "math/float"
+84 -8
View File
@@ -1,4 +1,5 @@
from typing import Any, Mapping
from abc import ABC, abstractmethod
from typing import Any, Mapping, Sequence, Tuple
SDXL_SUPPORTED_RESOLUTIONS = [
@@ -13,15 +14,60 @@ SDXL_SUPPORTED_RESOLUTIONS = [
(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]]: ...
class SDXLResolution:
@classmethod
def INPUT_TYPES(cls) -> Mapping[str, Any]:
return {
"required": {
"resolution": (
[f"{res[0]}x{res[1]}" for res in SDXL_SUPPORTED_RESOLUTIONS],
)
"resolution": ([f"{res[0]}x{res[1]}" for res in cls.resolutions()],)
}
}
@@ -35,7 +81,11 @@ class SDXLResolution:
return (int(width), int(height))
class NearestSDXLResolution:
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",)}}
@@ -52,7 +102,7 @@ class NearestSDXLResolution:
image_ratio = image_width / image_height
differences = [
(abs(image_ratio - resolution[2]), resolution)
for resolution in SDXL_SUPPORTED_RESOLUTIONS
for resolution in self.resolutions()
]
smallest = None
for difference in differences:
@@ -67,11 +117,37 @@ class NearestSDXLResolution:
else:
width = 1024
height = 1024
print(f"Selected SDXL resolution: {width}x{height}")
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,
}
+7 -8
View File
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Any, Callable, Mapping, TypeAlias
from typing import Any, Callable, Mapping
from .float import (
FLOAT_UNARY_OPERATIONS,
@@ -7,11 +7,10 @@ from .float import (
FLOAT_BINARY_OPERATIONS,
FLOAT_BINARY_CONDITIONS,
)
from .types import Number
DEFAULT_NUMBER = ("NUMBER", {"default": 0.0})
number: TypeAlias = int | float
class NumberUnaryOperation:
@classmethod
@@ -27,7 +26,7 @@ class NumberUnaryOperation:
FUNCTION = "op"
CATEGORY = "math/number"
def op(self, op: str, a: number) -> tuple[float]:
def op(self, op: str, a: Number) -> tuple[float]:
return (FLOAT_UNARY_OPERATIONS[op](float(a)),)
@@ -43,9 +42,9 @@ class NumberUnaryCondition:
RETURN_TYPES = ("BOOL",)
FUNCTION = "op"
CATEGORY = "math/number"
CATEGORY = "math/Number"
def op(self, op: str, a: number) -> tuple[bool]:
def op(self, op: str, a: Number) -> tuple[bool]:
return (FLOAT_UNARY_CONDITIONS[op](float(a)),)
@@ -64,7 +63,7 @@ class NumberBinaryOperation:
FUNCTION = "op"
CATEGORY = "math/number"
def op(self, op: str, a: number, b: number) -> tuple[float]:
def op(self, op: str, a: Number, b: Number) -> tuple[float]:
return (FLOAT_BINARY_OPERATIONS[op](float(a), float(b)),)
@@ -83,7 +82,7 @@ class NumberBinaryCondition:
FUNCTION = "op"
CATEGORY = "math/float"
def op(self, op: str, a: number, b: number) -> tuple[bool]:
def op(self, op: str, a: Number, b: Number) -> tuple[bool]:
return (FLOAT_BINARY_CONDITIONS[op](float(a), float(b)),)
+16
View 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]
+3 -4
View File
@@ -1,16 +1,15 @@
import numpy
from typing import Any, Callable, Mapping, TypeAlias
from typing import Any, Callable, Mapping
from .types import Vec2, Vec3, Vec4
Vec2: TypeAlias = tuple[float, float]
VEC2_ZERO = (0.0, 0.0)
DEFAULT_VEC2 = ("VEC2", {"default": VEC2_ZERO})
Vec3: TypeAlias = tuple[float, float, float]
VEC3_ZERO = (0.0, 0.0, 0.0)
DEFAULT_VEC3 = ("VEC3", {"default": VEC3_ZERO})
Vec4: TypeAlias = tuple[float, float, float, float]
VEC4_ZERO = (0.0, 0.0, 0.0, 0.0)
DEFAULT_VEC4 = ("VEC4", {"default": VEC4_ZERO})