diff --git a/README.md b/README.md index 1120f68..0b98a59 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,10 @@ ## UPDATES +**2024/01/04** @1.0.1: +* removing vector nodes + + **2024/12/27** @1.0.0: * initial release * reworked [JOVIMETRIX](https://github.com/amorano/jovimetrix) GLSL into standalone, dynamic node system diff --git a/__init__.py b/__init__.py index 1f658e1..2650cd7 100644 --- a/__init__.py +++ b/__init__.py @@ -16,9 +16,14 @@ @description: Integrates GLSL shader support. @node list: GLSLNode -@version: 1.0.0 +@version: 1.0.1 """ +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"] +__author__ = """Alexander G. Morano""" +__email__ = "amorano@gmail.com" +__version__ = "1.0.1" + import os import sys import json @@ -37,8 +42,6 @@ NODE_CLASS_MAPPINGS = {} NODE_DISPLAY_NAME_MAPPINGS = {} WEB_DIRECTORY = "./web" -__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"] - ROOT = Path(__file__).resolve().parent ROOT_COMFY = ROOT.parent.parent ROOT_DOC = ROOT / 'res/doc' @@ -48,6 +51,8 @@ JOV_INTERNAL = os.getenv("JOV_INTERNAL", 'false').strip().lower() in ('true', '1 JOV_LOG_LEVEL = os.getenv("JOV_LOG_LEVEL", "INFO") logger.configure(handlers=[{"sink": sys.stdout, "level": JOV_LOG_LEVEL}]) +JOV_PACKAGE = "Jovi_GLSL" + # ============================================================================== # === THERE CAN BE ONLY ONE === # ============================================================================== @@ -68,7 +73,7 @@ class Singleton(type): class JOVBaseNode: NOT_IDEMPOTENT = True - CATEGORY = f"JOVI_GLSL 🦚" + CATEGORY = f"{JOV_PACKAGE.upper()} 🦚" RETURN_TYPES = ("IMAGE", "IMAGE", "MASK") RETURN_NAMES = ('RGBA', 'RGB', 'MASK') FUNCTION = "run" @@ -193,19 +198,19 @@ def zip_longest_fill(*iterables: Any) -> Generator[Tuple[Any, ...], None, None]: # === NODE LOADER === # ============================================================================== + def loader(): - node_count = 0 - CLASS_MAPPINGS = {} - CLASS_MAPPINGS_WIP = {} + global NODE_DISPLAY_NAME_MAPPINGS, NODE_CLASS_MAPPINGS NODE_LIST_MAP = {} + for fname in ROOT.glob('core/**/*.py'): if fname.stem.startswith('_'): continue try: - route = str(fname).replace("\\", "/").split("Jovi_GLSL/core/")[1] + route = str(fname).replace("\\", "/").split(f"{JOV_PACKAGE}/core/")[1] route = route.split('.')[0].replace('/', '.') - module = f"Jovi_GLSL.core.{route}" + module = f"{JOV_PACKAGE}.core.{route}" module = importlib.import_module(module) except Exception as e: logger.warning(f"module failed {fname}") @@ -216,36 +221,26 @@ def loader(): try: for class_name, class_def in module.import_dynamic(): setattr(module, class_name, class_def) - logger.debug(f"shader: {class_name}") + # logger.debug(f"shader: {class_name}") except Exception as e: pass classes = inspect.getmembers(module, inspect.isclass) for class_name, class_object in classes: - # assume both attrs are good enough.... if not class_name.endswith('BaseNode') and hasattr(class_object, 'NAME') and hasattr(class_object, 'CATEGORY'): name = class_object.NAME - CLASS_MAPPINGS[name] = class_object - if not name.endswith(GLSL_CUSTOM): - desc = class_object.DESCRIPTION if hasattr(class_object, 'DESCRIPTION') else name - NODE_LIST_MAP[name] = desc.split('.')[0].strip('\n') - else: - logger.debug(f"customs {name}") - node_count += 1 + NODE_DISPLAY_NAME_MAPPINGS[name] = name + NODE_CLASS_MAPPINGS[name] = class_object + desc = class_object.DESCRIPTION if hasattr(class_object, 'DESCRIPTION') else name + NODE_LIST_MAP[name] = desc.split('.')[0].strip('\n') - logger.info(f"✅ {module.__name__}") - logger.info(f"{node_count} nodes loaded") - - global NODE_DISPLAY_NAME_MAPPINGS, NODE_CLASS_MAPPINGS - - NODE_DISPLAY_NAME_MAPPINGS = {k: v.NAME_PRETTY if hasattr(v, 'NAME_PRETTY') else k for k, v in CLASS_MAPPINGS.items()} - CLASS_MAPPINGS.update({k: v for k, v in CLASS_MAPPINGS_WIP.items()}) - NODE_DISPLAY_NAME_MAPPINGS.update({k: k for k in CLASS_MAPPINGS_WIP.keys()}) - CLASS_MAPPINGS = {x[0] : x[1] for x in sorted(CLASS_MAPPINGS.items(), + NODE_CLASS_MAPPINGS = {x[0] : x[1] for x in sorted(NODE_CLASS_MAPPINGS.items(), key=lambda item: getattr(item[1], 'SORT', 0))} - for k, v in CLASS_MAPPINGS.items(): - NODE_CLASS_MAPPINGS[k] = v + keys = NODE_CLASS_MAPPINGS.keys() + for name in keys: + logger.debug(f"✅ {name} :: {NODE_DISPLAY_NAME_MAPPINGS[name]}") + logger.info(f"{len(keys)} nodes loaded") # only do the list on local runs... if JOV_INTERNAL: diff --git a/core/vector.py b/core/vector.py deleted file mode 100644 index c0e8d7f..0000000 --- a/core/vector.py +++ /dev/null @@ -1,186 +0,0 @@ -""" -Jovi_GLSL - http://www.github.com/Amorano/Jovi_GLSL -Vector supports -""" - -import sys - -from Jovi_GLSL import JOVBaseNode - -class VECTOR2Node(JOVBaseNode): - NAME = "VECTOR2 FLOAT (JOV_GL)" - RETURN_TYPES = ("VEC2", ) - RETURN_NAMES = ("VEC2", ) - DESCRIPTION = """ - -""" - SORT = 10030 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "x": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - "y": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - } - } - - def run(self, x, y): - return ((x, y), ) - -class VECTOR2INode(JOVBaseNode): - NAME = "VECTOR2 INTEGER (JOV_GL)" - RETURN_TYPES = ("VEC2INT", ) - RETURN_NAMES = ("VEC2I", ) - DESCRIPTION = """ - -""" - SORT = 10035 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "x": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - "y": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - } - } - - def run(self, x, y): - return ((x, y), ) - -class VECTOR3Node(JOVBaseNode): - NAME = "VECTOR3 FLOAT (JOV_GL)" - RETURN_TYPES = ("VEC3", ) - RETURN_NAMES = ("VEC3", ) - DESCRIPTION = """ - -""" - SORT = 10040 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "x": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - "y": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - "z": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - } - } - - def run(self, x, y, z): - return ((x, y, z), ) - -class VECTOR3INode(JOVBaseNode): - NAME = "VECTOR3 INTEGER (JOV_GL)" - RETURN_TYPES = ("VEC3INT", ) - RETURN_NAMES = ("VEC3", ) - DESCRIPTION = """ - -""" - SORT = 10045 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "x": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - "y": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - "z": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - } - } - - def run(self, x, y, z): - return ((x, y, z), ) - -class VECTOR4Node(JOVBaseNode): - NAME = "VECTOR4 FLOAT (JOV_GL)" - RETURN_TYPES = ("VEC4", ) - RETURN_NAMES = ("VEC4", ) - DESCRIPTION = """ - -""" - SORT = 10050 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "x": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - "y": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - "z": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - "w": ("FLOAT", { "default": 0.0, "step": 0.01, "min": -sys.maxsize, "max": sys.maxsize }), - } - } - - def run(self, x, y, z, w): - return ((x, y, z, w), ) - -class VECTOR4INode(JOVBaseNode): - NAME = "VECTOR4 INTEGER (JOV_GL)" - RETURN_TYPES = ("VEC4INT", ) - RETURN_NAMES = ("VEC4", ) - DESCRIPTION = """ - -""" - SORT = 10055 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "x": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - "y": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - "z": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - "w": ("INT", { "default": 0, "step": 1, "min": -sys.maxsize, "max": sys.maxsize }), - } - } - - def run(self, x, y, z, w): - return ((x, y, z, w), ) - -class RGBAFloatNode(JOVBaseNode): - NAME = "RGBA FLOAT (JOV_GL)" - RETURN_TYPES = ("VEC4", ) - RETURN_NAMES = ("VEC4", ) - DESCRIPTION = """ - -""" - SORT = 10060 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "r": ("FLOAT", { "default": 0.0, "step": 0.01 }), - "g": ("FLOAT", { "default": 0.0, "step": 0.01 }), - "b": ("FLOAT", { "default": 0.0, "step": 0.01 }), - "a": ("FLOAT", { "default": 0.0, "step": 0.01 }), - } - } - - def run(self, r, g, b, a): - return ((r, g, b, a), ) - -class RGBAIntegerNode(JOVBaseNode): - NAME = "RGBA INTEGER (JOV_GL)" - RETURN_TYPES = ("VEC4", ) - RETURN_NAMES = ("VEC4", ) - DESCRIPTION = """ - -""" - SORT = 10065 - - @classmethod - def INPUT_TYPES(cls): - return { - "required": { - "r": ("INT", { "default": 0, "step": 1, "min": 0, "max": 255 }), - "g": ("INT", { "default": 0, "step": 1, "min": 0, "max": 255 }), - "b": ("INT", { "default": 0, "step": 1, "min": 0, "max": 255 }), - "a": ("INT", { "default": 0, "step": 1, "min": 0, "max": 255 }), - } - } - - def run(self, r, g, b, a): - return ((r, g, b, a), ) diff --git a/node_list.json b/node_list.json index ac326c7..2cb0657 100644 --- a/node_list.json +++ b/node_list.json @@ -1,16 +1,21 @@ { - "GLSL (JOV_GL) \ud83c\udf69": "Execute custom GLSL (OpenGL Shading Language) fragment shaders to generate images or apply effects", - "GLSL BLEND LINEAR (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Simple linear blend between two images", - "GLSL COLOR CONVERSION (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Convert an image from one color space (RGB, HSV, LAB, XYZ) to another", - "GLSL COLOR PALETTE (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Color palette creation using the formula: color(t) = a + b * cos[tau(c*t+d)]", - "GLSL CONICAL GRADIENT (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Generate a conical gradient from black to white", - "GLSL DIRECTIONAL WARP (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Domain warp an image with a direction and distortion map", - "GLSL FILTER RANGE (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Select pixels from start color through end color", - "GLSL GRAYSCALE (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Convert input to grayscale", - "GLSL HSV ADJUST (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Hue, Saturation and Value adjustment control", - "GLSL INVERT (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Invert the channels of an image along a scalar [0", - "GLSL NORMAL (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Convert input into a Normal map", - "GLSL NORMAL BLEND (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Blend two Normal maps", - "GLSL POSTERIZE (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Reduce the pixel color data range", - "GLSL TRANSFORM (JOV_GL) \ud83e\uddd9\ud83c\udffd": "Abuse UV space to create repetitions" + "GLSL BLEND LINEAR (JOV_GL) \ud83c\udf08": "Simple linear blend between two images", + "GLSL COLOR CONVERSION (JOV_GL) \ud83c\udf08": "Convert an image from one color space (RGB, HSV, LAB, XYZ) to another", + "GLSL COLOR PALETTE (JOV_GL) \ud83c\udf08": "Color palette creation using the formula: color(t) = a + b * cos[tau(c*t+d)]", + "GLSL CONICAL GRADIENT (JOV_GL) \ud83c\udf08": "Generate a conical gradient from black to white", + "GLSL DIRECTIONAL WARP (JOV_GL) \ud83c\udf08": "Domain warp an image with a direction and distortion map", + "GLSL FILTER RANGE (JOV_GL) \ud83c\udf08": "Select pixels from start color through end color", + "GLSL GRAYSCALE (JOV_GL) \ud83c\udf08": "Convert input to grayscale", + "GLSL HSV ADJUST (JOV_GL) \ud83c\udf08": "Hue, Saturation and Value adjustment control", + "GLSL INVERT (JOV_GL) \ud83c\udf08": "Invert the channels of an image along a scalar [0", + "GLSL MIN MAX (JOV_GL) \ud83c\udf08": "Gets the minimum and maximum of an image", + "GLSL NOISE PERLIN (JOV_GL) \ud83c\udf08": "Classic Perlin noise", + "GLSL NOISE SIMPLEX (JOV_GL) \ud83c\udf08": "Simplex noise, simply", + "GLSL NOISE WORLEY (JOV_GL) \ud83c\udf08": "Worley noise with the best", + "GLSL NORMAL (JOV_GL) \ud83c\udf08": "Convert input into a Normal map", + "GLSL NORMAL BLEND (JOV_GL) \ud83c\udf08": "Blend two Normal maps", + "GLSL PIXELATE (JOV_GL) \ud83c\udf08": "Pixelate input image", + "GLSL POSTERIZE (JOV_GL) \ud83c\udf08": "Reduce the pixel color data range", + "GLSL SOBEL (JOV_GL) \ud83c\udf08": "Finds the edges of an image", + "GLSL TRANSFORM (JOV_GL) \ud83c\udf08": "Move, Rotate, Scale and Tile an image" } \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 623222c..ef970aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "jovi_glsl" description = "Integrates GLSL shader support." -version = "1.0.0" +version = "1.0.1" license = { file = "LICENSE" } dependencies = [ "aenum>=3.1.15",