| 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, |
| } |
|
|