diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a34d887..b607c19 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -2,7 +2,7 @@ * Python version: * Operating System: -### Description +### tooltip Describe what you were trying to get done. Tell us what happened, what went wrong, and what you expected to happen. diff --git a/README.md b/README.md index 7dc5dff..486b77a 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ You can also get the node from comfy manager under the name of More math. - Audio-specific: `fft` (short-time FFT), `ifft` (inverse sFFT **always return audio back to time domain before leaving node**) ## Variables -- **Inputs**: `a`, `b`, `c`, `d` (matches node input type) +- **inputs**: `a`, `b`, `c`, `d` (matches node input type) - **Extra floats**: `w`, `x`, `y`, `z` - **Tensor positions**: `C` (channel), `B` (batch), `X`, `Y`, `W` (width), `H` (height) (not for FLOAT/AUDIO/CONDITIONING) - **Special**: diff --git a/__init__.py b/__init__.py index 91dfe96..5e16eb4 100644 --- a/__init__.py +++ b/__init__.py @@ -2,7 +2,7 @@ __all__ = [ "NODE_CLASS_MAPPINGS", - "NODE_DISPLAY_NAME_MAPPINGS", + "NODE_id_MAPPINGS", ] @@ -10,7 +10,6 @@ __author__ = """Daniel Martinek""" __email__ = "danda.martinek@gmail.com" __version__ = "0.0.1" -from .src.more_math.nodes import NODE_CLASS_MAPPINGS -from .src.more_math.nodes import NODE_DISPLAY_NAME_MAPPINGS +from .src.more_math.nodes import comfy_entrypoint diff --git a/pyproject.toml b/pyproject.toml index f6c2395..1719386 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "more_math" version = "0.0.2" -description = "Adds math nodes for numbers and types which do not need it." +tooltip = "Adds math nodes for numbers and types which do not need it." authors = [ {name = "Daniel Martinek", email = "danda.martinek@gmail.com"} ] diff --git a/src/more_math/AudioMathNode.py b/src/more_math/AudioMathNode.py index 3dbb746..dd72db1 100644 --- a/src/more_math/AudioMathNode.py +++ b/src/more_math/AudioMathNode.py @@ -6,10 +6,12 @@ from .Parser.MathExprLexer import MathExprLexer from .Parser.TensorEvalVisitor import TensorEvalVisitor from .helper_functions import getIndexTensorAlongDim -class AudioMathNode: +from comfy_api.latest import ComfyExtension, io + +class AudioMathNode(io.ComfyNode): """ This node enables the use of math expressions on AUDIO tensors. - INPUTS: + inputs: a, b, c, d: AUDIO, bound to variables with the same name. Defaults to zero AUDIO if not provided. w, x, y, z: @@ -17,66 +19,36 @@ class AudioMathNode: Audio expression: String, describing expression to apply to audio tensors. - OUTPUTS: + outputs: AUDIO: Returns an AUDIO object that contains the result of the math expression applied to the input audio tensors. """ def __init__(self): pass - @classmethod - def INPUT_TYPES(s): - """ - """ - return { - "required": { - "a": ("AUDIO", { - "description": "Input audio tensor" - }), - "AudioExpr": ("STRING", { - "multiline": False, - "default": "a*(1-w)+b*w", - "description": "Expression to apply on input audio tensors" - }), - }, - "optional": { - "b": ("AUDIO", { - "default": 0, - "description": "Second input audio tensor" - }), - "c": ("AUDIO", { - "default": 0, - "description": "Third input audio tensor" - }), - "d": ("AUDIO", { - "default": 0, - "description": "Fourth input audio tensor" - }), - "w": ("FLOAT", { - "default": 0, - "forceInput": True - }), - "x": ("FLOAT", { - "default": 0, - "forceInput": True - }), - "y": ("FLOAT", { - "default": 0, - "forceInput": True - }), - "z": ("FLOAT", { - "default": 0, - "forceInput": True - }), - } - } + @classmethod + def define_schema(cls) -> io.Schema: + return io.Schema( + node_id="mrmth_AudioMathNode", + category="More math", + inputs=[ + io.Audio.Input(id="a", tooltip="Input audio tensor"), + io.Audio.Input(id="b", optional=True, tooltip="Second input audio tensor"), + io.Audio.Input(id="c", optional=True, tooltip="Third input audio tensor"), + io.Audio.Input(id="d", optional=True, tooltip="Fourth input audio tensor"), + io.Float.Input(id="w", default=0.0, optional=True, force_input=True), + io.Float.Input(id="x", default=0.0, optional=True, force_input=True), + io.Float.Input(id="y", default=0.0, optional=True, force_input=True), + io.Float.Input(id="z", default=0.0, optional=True, force_input=True), + io.String.Input(id="AudioExpr", default="a*(1-w)+b*w", tooltip="Expression to apply on input audio tensors"), + ], + outputs=[ + io.Audio.Output(), + ], + ) - RETURN_TYPES = ("AUDIO",) - DESCRIPTION = cleandoc(__doc__) - FUNCTION = "audioMathNode" - CATEGORY = "More math" - - def audioMathNode(self, a, AudioExpr, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): + @classmethod + def execute(self,cls, a, AudioExpr, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): bv = b if b else {'waveform':torch.zeros_like(a['waveform']),'sample_rate':a['sample_rate']} diff --git a/src/more_math/ConditioningMathNode.py b/src/more_math/ConditioningMathNode.py index b7d1868..5ec5bc0 100644 --- a/src/more_math/ConditioningMathNode.py +++ b/src/more_math/ConditioningMathNode.py @@ -6,12 +6,12 @@ from .Parser.MathExprParser import MathExprParser from .Parser.MathExprLexer import MathExprLexer from .Parser.TensorEvalVisitor import TensorEvalVisitor +from comfy_api.latest import ComfyExtension, io - -class ConditioningMathNode: +class ConditioningMathNode(io.ComfyNode): """ This node enables the use of math on conditionings. It is recommended to keep the Tensor expression the same as the pooled_output expression. - INPUTS: + inputs: a, b, c, d: Conditioning, bound to variables with the same name. Defaults to zero conditioning if not provided. w, x, y, z: @@ -21,7 +21,7 @@ class ConditioningMathNode: Pooled output expression: String, describing expression to mix pooled_output part of conditioning. pooled_output does not have that much say in the image but can change some details of the image or completly change the image in some cases, probably also used for positional and temporal conditioning. Expression uses same syntax as Tensor expression. - OUTPUTS: + outputs: CONDITIONING: Returns a CONDITIONING object that contains the result of the math expression applied to the input conditionings. """ @@ -29,71 +29,34 @@ class ConditioningMathNode: pass @classmethod - def INPUT_TYPES(s): - """ - """ - return { - "required": { - "a": ("CONDITIONING", { + def define_schema(cls) -> io.Schema: + return io.Schema( + node_id="mrmth_ConditioningMathNode", + category="More math", + inputs=[ + io.Conditioning.Input(id="a"), + io.Conditioning.Input(id="b", optional=True), + io.Conditioning.Input(id="c", optional=True), + io.Conditioning.Input(id="d", optional=True), + io.Float.Input(id="w", default=0.0,optional=True, force_input=True), + io.Float.Input(id="x", default=0.0,optional=True, force_input=True), + io.Float.Input(id="y", default=0.0,optional=True, force_input=True), + io.Float.Input(id="z", default=0.0,optional=True, force_input=True), + io.String.Input(id="Tensor", default="a*(1-w)+b*w", tooltip="Describes composition of the image."), + io.String.Input(id="pooled_output", default="a*(1-w)+b*w", tooltip="Can change some details of the image. Idk."), + ], + outputs=[ + io.Conditioning.Output(), + ], + ) - }), - - "Tensor": ("STRING", { - "multiline": False, #True if you want the field to look like the one on the ClipTextEncode node - "default": "a*(1-w)+b*w", - "description": "Describes composition of the image. Valid functions are sin, cos, tan, asin, acos, atan, atan2, sinh, cosh, tanh, asinh, acosh, atanh, abs, sqrt, ln, log, exp, pow, min, max, norm, floor, ceil, round, gamma. Valid operators are +, -, *, /, %, ^,!˛&,|. Usable constants are e and pi." - - }), - "pooled_output": ("STRING", { - "multiline": False, #True if you want the field to look like the one on the ClipTextEncode node - "default": "a*(1-w)+b*w", - "description": "Can change some details of the image, probably also used for positional and temporal conditioning." - }), - }, - "optional": { - "b": ("CONDITIONING", { - "default": 0, - }), - "c": ("CONDITIONING", { - "default": 0, - }), - "d": ("CONDITIONING", { - "default": 0, - }), - "w": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "x": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "y": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "z": ("FLOAT", { - "default": 0, - "forceInput":True - }), - - - # "int_field": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}), - # "float_field": ("FLOAT", {"default": 0.5, "min": -10.0, "max": 10.0, "step": 0.001}), - } - } - - RETURN_TYPES = ("CONDITIONING",) - #RETURN_NAMES = ("image_output_name",) - DESCRIPTION = cleandoc(__doc__) - FUNCTION = "condMathNode" + tooltip = cleandoc(__doc__) #OUTPUT_NODE = False #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node - CATEGORY = "More math" - - def condMathNode(self, Tensor,pooled_output, a, b=None, c=None, d=None,w=0.0,x=0.0,y=0.0,z=0.0): + @classmethod + def execute(self,cls, Tensor,pooled_output, a, b=None, c=None, d=None,w=0.0,x=0.0,y=0.0,z=0.0): if b is None: b = [[torch.zeros_like(a[0][0]), {"pooled_output": torch.zeros_like(a[0][1]["pooled_output"])}]] if c is None: diff --git a/src/more_math/FloatMathNode.py b/src/more_math/FloatMathNode.py index 2a6fd4e..ca573d6 100644 --- a/src/more_math/FloatMathNode.py +++ b/src/more_math/FloatMathNode.py @@ -9,10 +9,12 @@ from .Parser.MathExprParser import MathExprParser from .Parser.MathExprLexer import MathExprLexer from .Parser.FloatEvalVisitor import FloatEvalVisitor -class FloatMathNode: +from comfy_api.latest import ComfyExtension, io + +class FloatMathNode(io.ComfyNode): """ This node enables the use of math expressions on Latents. - INPUTS: + inputs: a, b, c, d: Floats, bound to variables with the same name. Defaults to 0.0 if not provided. w, x, y, z: @@ -20,7 +22,7 @@ class FloatMathNode: Latent expression: String, describing expression to mix latents. Valid functions are sin, cos, tan, abs, sqrt, min, max, norm. Valid operators are +, -, *, /, ^, %. Usable constants are e and pi. - OUTPUTS: + outputs: LATENT: Returns a LATENT object that contains the result of the math expression applied to the input conditionings. """ @@ -28,70 +30,35 @@ class FloatMathNode: pass @classmethod - def INPUT_TYPES(s): + def define_schema(cls) -> io.Schema: """ """ - return { - "required": { - "a": ("FLOAT", { - "default": 0, - "forceInput":True - }), + return io.Schema( + node_id="mrmth_FloatMathNode", + category="More math", + inputs=[ + io.Float.Input(id="a", force_input=True), + io.Float.Input(id="b", default=0.0,optional=True, force_input=True), + io.Float.Input(id="c", default=0.0,optional=True, force_input=True), + io.Float.Input(id="d", default=0.0,optional=True, force_input=True), + io.Float.Input(id="w", default=0.0,optional=True, force_input=True), + io.Float.Input(id="x", default=0.0,optional=True, force_input=True), + io.Float.Input(id="y", default=0.0,optional=True, force_input=True), + io.Float.Input(id="z", default=0.0,optional=True, force_input=True), + io.String.Input(id="FloatFunc", default="a*(1-w)+b*w", tooltip="Expression to use on inputs"), + ], + outputs=[ + io.Float.Output(), + ], + ) - "FloatFunc": ("STRING", { - "multiline": False, #True if you want the field to look like the one on the ClipTextEncode node - "default": "a*(1-w)+b*w", - "description": "Expression to use on inputs" - - }), - }, - "optional": { - "b": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "c": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "d": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "w": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "x": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "y": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "z": ("FLOAT", { - "default": 0, - "forceInput":True - }), - - - # "int_field": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}), - # "float_field": ("FLOAT", {"default": 0.5, "min": -10.0, "max": 10.0, "step": 0.001}), - } - } - - RETURN_TYPES = ("FLOAT",) #RETURN_NAMES = ("image_output_name",) - DESCRIPTION = cleandoc(__doc__) - FUNCTION = "fltMathNode" + tooltip = cleandoc(__doc__) #OUTPUT_NODE = False #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node - - CATEGORY = "More math" - - def fltMathNode(self, FloatFunc, a, b=0.0, c=0.0, d=0.0, w=0.0, x=0.0, y=0.0, z=0.0): + @classmethod + def execute(self,cls, FloatFunc, a, b=0.0, c=0.0, d=0.0, w=0.0, x=0.0, y=0.0, z=0.0): diff --git a/src/more_math/ImageMathNode.py b/src/more_math/ImageMathNode.py index f7f11c2..1cd6150 100644 --- a/src/more_math/ImageMathNode.py +++ b/src/more_math/ImageMathNode.py @@ -9,10 +9,12 @@ from .Parser.MathExprParser import MathExprParser from .Parser.MathExprLexer import MathExprLexer from .Parser.TensorEvalVisitor import TensorEvalVisitor -class ImageMathNode: +from comfy_api.latest import ComfyExtension, io + +class ImageMathNode(io.ComfyNode): """ This node enables the use of math expressions on Latents. - INPUTS: + inputs: a, b, c, d: Latent, bound to variables with the same name. Defaults to zero latent if not provided. w, x, y, z: @@ -20,86 +22,49 @@ class ImageMathNode: Image expression: String, describing expression to mix images. Valid functions are sin, cos, tan, asin, acos, atan, atan2, sinh, cosh, tanh, asinh, acosh, atanh, abs, sqrt, ln, log, exp, pow, min, max, norm, floor, ceil, round, gamma. Valid operators are +, -, *, /, %, ^,!˛&,|. Usable constants are e and pi. - OUTPUTS: + outputs: LATENT: Returns a LATENT object that contains the result of the math expression applied to the input conditionings. """ def __init__(self): - shape = [] - B = None - C = None - X = None - Y = None + pass @classmethod - def INPUT_TYPES(s): + def define_schema(cls) -> io.Schema: """ """ - return { - "required": { - "a": ("IMAGE", { + return io.Schema( + node_id="mrmth_ImageMathNode", + category="More math", + inputs=[ + io.Image.Input(id="a"), + io.Image.Input(id="b", optional=True), + io.Image.Input(id="c", optional=True), + io.Image.Input(id="d", optional=True), + io.Float.Input(id="w", default=0.0,optional=True, force_input=True), + io.Float.Input(id="x", default=0.0,optional=True, force_input=True), + io.Float.Input(id="y", default=0.0,optional=True, force_input=True), + io.Float.Input(id="z", default=0.0,optional=True, force_input=True), + io.String.Input(id="Image", default="a*(1-w)+b*w", tooltip="Expression to apply on input images"), + ], + outputs=[ + io.Image.Output(), + ], + ) - }), - - "Image": ("STRING", { - "multiline": False, #True if you want the field to look like the one on the ClipTextEncode node - "default": "a*(1-w)+b*w", - "description": "Describes expression to apply to the image." - - }), - }, - "optional": { - "b": ("IMAGE", { - "default": 0, - }), - "c": ("IMAGE", { - "default": 0, - }), - "d": ("IMAGE", { - "default": 0, - }), - "w": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "x": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "y": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "z": ("FLOAT", { - "default": 0, - "forceInput":True - }), - - - # "int_field": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}), - # "float_field": ("FLOAT", {"default": 0.5, "min": -10.0, "max": 10.0, "step": 0.001}), - } - } - - RETURN_TYPES = ("IMAGE",) + #RETURN_NAMES = ("image_output_name",) - DESCRIPTION = cleandoc(__doc__) - FUNCTION = "imgMathNode" + tooltip = cleandoc(__doc__) #OUTPUT_NODE = False #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node CATEGORY = "More math" - - def imgMathNode(self, Image, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): + @classmethod + def execute(self,cls, Image, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): b = torch.zeros_like(a) if b is None else b c = torch.zeros_like(a) if c is None else c d = torch.zeros_like(a) if d is None else d - - batch = range(0,a.shape[0],1) - width = range(0,a.shape[2],1) - height = range(0,a.shape[1],1) - color = range(0,a.shape[3],1) B = getIndexTensorAlongDim(a, 0) W = getIndexTensorAlongDim(a, 2) diff --git a/src/more_math/LatentMathNode.py b/src/more_math/LatentMathNode.py index 54b178f..aca1feb 100644 --- a/src/more_math/LatentMathNode.py +++ b/src/more_math/LatentMathNode.py @@ -1,5 +1,6 @@ from inspect import cleandoc -from math import e + +from comfy_api.latest import ComfyExtension, io from antlr4 import CommonTokenStream, InputStream import torch @@ -10,10 +11,10 @@ from .Parser.MathExprParser import MathExprParser from .Parser.MathExprLexer import MathExprLexer from .Parser.TensorEvalVisitor import TensorEvalVisitor -class LatentMathNode: +class LatentMathNode(io.ComfyNode): """ This node enables the use of math expressions on Latents. - INPUTS: + inputs: a, b, c, d: Latent, bound to variables with the same name. Defaults to zero latent if not provided. w, x, y, z: @@ -21,7 +22,7 @@ class LatentMathNode: Latent expression: String, describing expression to aply to latents. - OUTPUTS: + outputs: LATENT: Returns a LATENT object that contains the result of the math expression applied to the input conditionings. """ @@ -29,66 +30,37 @@ class LatentMathNode: pass @classmethod - def INPUT_TYPES(s): + def define_schema(cls) -> io.Schema: """ """ - return { - "required": { - "a": ("LATENT", { + return io.Schema( + node_id="mrmth_LatentMathNode", + category="More math", + inputs=[ + io.Latent.Input(id="a"), + io.Latent.Input(id="b", optional=True), + io.Latent.Input(id="c", optional=True), + io.Latent.Input(id="d", optional=True), + io.Float.Input(id="w", default=0.0,optional=True, force_input=True), + io.Float.Input(id="x", default=0.0,optional=True, force_input=True), + io.Float.Input(id="y", default=0.0,optional=True, force_input=True), + io.Float.Input(id="z", default=0.0,optional=True, force_input=True), + io.String.Input(id="Latent", default="a*(1-w)+b*w", tooltip="Expression to apply on input latents"), + ], + outputs=[ + io.Latent.Output(), + ], + ) - }), - - "Latent": ("STRING", { - "multiline": False, #True if you want the field to look like the one on the ClipTextEncode node - "default": "a*(1-w)+b*w", - "description": "Expression to apply on input latents" - - }), - }, - "optional": { - "b": ("LATENT", { - "default": 0, - }), - "c": ("LATENT", { - "default": 0, - }), - "d": ("LATENT", { - "default": 0, - }), - "w": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "x": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "y": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "z": ("FLOAT", { - "default": 0, - "forceInput":True - }), - - - # "int_field": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}), - # "float_field": ("FLOAT", {"default": 0.5, "min": -10.0, "max": 10.0, "step": 0.001}), - } - } - - RETURN_TYPES = ("LATENT",) #RETURN_NAMES = ("image_output_name",) - DESCRIPTION = cleandoc(__doc__) - FUNCTION = "latMathNode" + tooltip = cleandoc(__doc__) #OUTPUT_NODE = False #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node - CATEGORY = "More math" - def latMathNode(self, Latent, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): + @classmethod + def execute(cls, Latent, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0) -> io.NodeOutput: a = a["samples"] b = torch.zeros_like(a) if b is None else b["samples"] c = torch.zeros_like(a) if c is None else c["samples"] diff --git a/src/more_math/NoiseMathNode.py b/src/more_math/NoiseMathNode.py index 6e1383b..8bd82e0 100644 --- a/src/more_math/NoiseMathNode.py +++ b/src/more_math/NoiseMathNode.py @@ -10,10 +10,12 @@ from .Parser.MathExprParser import MathExprParser from .Parser.MathExprLexer import MathExprLexer from .Parser.TensorEvalVisitor import TensorEvalVisitor -class NoiseMathNode: +from comfy_api.latest import ComfyExtension, io + +class NoiseMathNode(io.ComfyNode): """ This node enables the use of math expressions on Latents. - INPUTS: + inputs: a, b, c, d: Noise generators, bound to variables with the same name. Defaults to zero latent if not provided. w, x, y, z: @@ -21,7 +23,7 @@ class NoiseMathNode: Latent expression: String, describing expression to mix noise. - OUTPUTS: + outputs: LATENT: Returns a LATENT object that contains the result of the math expression applied to the input conditionings. """ @@ -36,66 +38,37 @@ class NoiseMathNode: vz= 0.0 expr=""; @classmethod - def INPUT_TYPES(s): + def define_schema(cls) -> io.Schema: """ """ - return { - "required": { - "a": ("NOISE", { - - }), - - "Noise": ("STRING", { - "multiline": False, #True if you want the field to look like the one on the ClipTextEncode node - "default": "a*(1-w)+b*w", - "description": "Expression describing manipulation of noise." - - }), - }, - "optional": { - "b": ("NOISE", { - "default": 0, - }), - "c": ("NOISE", { - "default": 0, - }), - "d": ("NOISE", { - "default": 0, - }), - "w": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "x": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "y": ("FLOAT", { - "default": 0, - "forceInput":True - }), - "z": ("FLOAT", { - "default": 0, - "forceInput":True - }), - - - # "int_field": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}), - # "float_field": ("FLOAT", {"default": 0.5, "min": -10.0, "max": 10.0, "step": 0.001}), - } - } - - RETURN_TYPES = ("NOISE",) + return io.Schema( + node_id="mrmth_NoiseMathNode", + category="More math", + inputs=[ + io.Noise.Input(id="a"), + io.Noise.Input(id="b", optional=True), + io.Noise.Input(id="c", optional=True), + io.Noise.Input(id="d", optional=True), + io.Float.Input(id="w", default=0.0,optional=True, force_input=True), + io.Float.Input(id="x", default=0.0,optional=True, force_input=True), + io.Float.Input(id="y", default=0.0,optional=True, force_input=True), + io.Float.Input(id="z", default=0.0,optional=True, force_input=True), + io.String.Input(id="Noise", default="a*(1-w)+b*w", tooltip="Expression to apply on input noise generators"), + ], + outputs=[ + io.Noise.Output(), + ], + ) #RETURN_NAMES = ("image_output_name",) - DESCRIPTION = cleandoc(__doc__) - FUNCTION = "noiMathNode" + tooltip = cleandoc(__doc__) seed = 0 #OUTPUT_NODE = False #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node CATEGORY = "More math" - def noiMathNode(self, Noise, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): + @classmethod + def execute(self, cls, Noise, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): self.va = a self.vb = b self.vc = c diff --git a/src/more_math/nodes.py b/src/more_math/nodes.py index dfb64ab..f222806 100644 --- a/src/more_math/nodes.py +++ b/src/more_math/nodes.py @@ -7,56 +7,54 @@ from .LatentMathNode import LatentMathNode from .ImageMathNode import ImageMathNode from .AudioMathNode import AudioMathNode -class IntToFloatNode: +from comfy_api.latest import ComfyExtension, io + +class IntToFloatNode(io.ComfyNode): """ Converts int to float. """ @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "value": ("INT", {"default": 0}), - } - } - - RETURN_TYPES = ("FLOAT",) - FUNCTION = "convert" - CATEGORY = "More math" - - def convert(self, value): + def define_schema(cls) -> io.Schema: + """ + """ + return io.Schema( + node_id="mrmth_IntToFloat", + category="More math", + inputs=[ + io.Int.Input(id="value", default=0), + ], + outputs=[ + io.Float.Output(), + ], + ) + @classmethod + def execute(self,cls, value): return (float(value),) -class FloatToIntNode: +class FloatToIntNode(io.ComfyNode): """ Converts float to int. """ @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "value": ("FLOAT", {"default": 0.0}), - } - } - - RETURN_TYPES = ("INT",) - FUNCTION = "convert" - CATEGORY = "More math" - - def convert(self, value): + def define_schema(cls) -> io.Schema: + """ + """ + return io.Schema( + node_id="mrmth_FloatToInt", + category="More math", + inputs=[ + io.Float.Input(id="value", default=0.0), + ], + outputs=[ + io.Int.Output(), + ], + ) + @classmethod + def execute(self, value): return (int(value),) -NODE_CLASS_MAPPINGS = { - "mrmth_ConditioningMathNode": ConditioningMathNode, - "mrmth_LatentMathNode": LatentMathNode, - "mrmth_ImageMathNode": ImageMathNode, - "mrmth_FloatMathNode": FloatMathNode, - "mrmth_NoiseMathNode": NoiseMathNode, - "mrmth_IntToFloat": IntToFloatNode, - "mrmth_FloatToInt": FloatToIntNode, - "mrmth_AudioMathNode": AudioMathNode, -} -NODE_DISPLAY_NAME_MAPPINGS = { +NODE_id_MAPPINGS = { "mrmth_ConditioningMathNode": "Conditioning math", "mrmth_LatentMathNode": "Latent math", "mrmth_ImageMathNode": "Image math", @@ -72,5 +70,20 @@ NODE_DISPLAY_NAME_MAPPINGS = { "pooled_output": "Pooled output tensor expression" } - - +class MoreMathExtension(ComfyExtension): + def __init__(self): + pass + @classmethod + async def get_node_list(self) -> list[type[io.ComfyNode]]: + return [ + ConditioningMathNode, + LatentMathNode, + ImageMathNode, + FloatMathNode, + NoiseMathNode, + IntToFloatNode, + FloatToIntNode, + AudioMathNode, + ] +async def comfy_entrypoint() -> MoreMathExtension: + return MoreMathExtension()