Source code for base_operators

"""Basic NodeCalculator operators.

This is an extension that is loaded by default.

The main difference to the base_functions is that operators are stand-alone
functions that create a Maya node.
"""
import math

from maya import cmds

from node_calculator.core import noca_op
from node_calculator.core import _create_operation_node
from node_calculator.core import NcNode
from node_calculator.core import Node
from node_calculator.core import NcBaseNode
from node_calculator.core import _unravel_item_as_list
from node_calculator.core import _unravel_and_set_or_connect_a_to_b
from node_calculator.core import LOG

# Any Maya plugin that should be loaded for the NodeCalculator
REQUIRED_EXTENSION_PLUGINS = ["matrixNodes", "quatNodes"]


# Dict of all available operations: used node-type, inputs, outputs, etc.
EXTENSION_OPERATORS = {
    "angle_between": {
        "node": "angleBetween",
        "inputs": [
            ["vector1X", "vector1Y", "vector1Z"],
            ["vector2X", "vector2Y", "vector2Z"],
        ],
        "outputs": [
            ["angle"],
        ],
    },

    "average": {
        "node": "plusMinusAverage",
        "inputs": [
            [
                "input3D[{array}].input3Dx",
                "input3D[{array}].input3Dy",
                "input3D[{array}].input3Dz"
            ],
        ],
        "outputs": [
            ["output3Dx", "output3Dy", "output3Dz"],
        ],
        "operation": 3,
    },

    "blend": {
        "node": "blendColors",
        "inputs": [
            ["color1R", "color1G", "color1B"],
            ["color2R", "color2G", "color2B"],
            ["blender"],
        ],
        "outputs": [
            ["outputR", "outputG", "outputB"],
        ],
    },

    "choice": {
        "node": "choice",
        "inputs": [
            ["input[{array}]"],
            ["selector"],
        ],
        "outputs": [
            ["output"],
        ],
    },

    "clamp": {
        "node": "clamp",
        "inputs": [
            ["inputR", "inputG", "inputB"],
            ["minR", "minG", "minB"],
            ["maxR", "maxG", "maxB"],
        ],
        "outputs": [
            ["outputR", "outputG", "outputB"],
        ],
    },

    "closest_point_on_mesh": {
        "node": "closestPointOnMesh",
        "inputs": [
            ["inMesh"],
            ["inPositionX", "inPositionY", "inPositionZ"],
        ],
        "outputs": [
            ["positionX", "positionY", "positionZ"],
            ["parameterU", "parameterV"],
            ["normalX", "normalY", "normalZ"],
            ["closestVertexIndex"],
            ["closestFaceIndex"],
        ],
        "output_is_predetermined": True,
    },

    "closest_point_on_surface": {
        "node": "closestPointOnSurface",
        "inputs": [
            ["inputSurface"],
            ["inPositionX", "inPositionY", "inPositionZ"],
        ],
        "outputs": [
            ["positionX", "positionY", "positionZ"],
            ["parameterU", "parameterV"],
        ],
        "output_is_predetermined": True,
    },

    "compose_matrix": {
        "node": "composeMatrix",
        "inputs": [
            ["inputTranslateX", "inputTranslateY", "inputTranslateZ"],
            ["inputRotateX", "inputRotateY", "inputRotateZ"],
            ["inputScaleX", "inputScaleY", "inputScaleZ"],
            ["inputShearX", "inputShearY", "inputShearZ"],
            ["inputRotateOrder"],
            ["useEulerRotation"],
        ],
        "outputs": [
            ["outputMatrix"],
        ],
    },

    "cross": {
        "node": "vectorProduct",
        "inputs": [
            ["input1X", "input1Y", "input1Z"],
            ["input2X", "input2Y", "input2Z"],
            ["normalizeOutput"],
        ],
        "outputs": [
            ["outputX", "outputY", "outputZ"],
        ],
        "operation": 2,
    },

    "curve_info": {
        "node": "curveInfo",
        "inputs": [
            ["inputCurve"],
        ],
        "outputs": [
            ["arcLength"],
        ],
    },

    "decompose_matrix": {
        "node": "decomposeMatrix",
        "inputs": [
            ["inputMatrix"],
        ],
        "outputs": [
            ["outputTranslateX", "outputTranslateY", "outputTranslateZ"],
            ["outputRotateX", "outputRotateY", "outputRotateZ"],
            ["outputScaleX", "outputScaleY", "outputScaleZ"],
            ["outputShearX", "outputShearY", "outputShearZ"],
        ],
        "output_is_predetermined": True,
    },

    "dot": {
        "node": "vectorProduct",
        "inputs": [
            ["input1X", "input1Y", "input1Z"],
            ["input2X", "input2Y", "input2Z"],
            ["normalizeOutput"],
        ],
        "outputs": [
            ["outputX"],
        ],
        "operation": 1,
    },

    "euler_to_quat": {
        "node": "eulerToQuat",
        "inputs": [
            ["inputRotateX", "inputRotateY", "inputRotateZ"],
            ["inputRotateOrder"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "four_by_four_matrix": {
        "node": "fourByFourMatrix",
        "inputs": [
            [
                "in00", "in01", "in02", "in03",
                "in10", "in11", "in12", "in13",
                "in20", "in21", "in22", "in23",
                "in30", "in31", "in32", "in33",
            ],
        ],
        "outputs": [
            ["output"],
        ],
    },

    "hold_matrix": {
        "node": "holdMatrix",
        "inputs": [
            ["inMatrix"],
        ],
        "outputs": [
            ["outMatrix"],
        ],
    },

    "inverse_matrix": {
        "node": "inverseMatrix",
        "inputs": [
            ["inputMatrix"],
        ],
        "outputs": [
            ["outputMatrix"],
        ],
    },

    "length": {
        "node": "distanceBetween",
        "inputs": [
            ["point1X", "point1Y", "point1Z"],
            ["point2X", "point2Y", "point2Z"],
        ],
        "outputs": [
            ["distance"],
        ],
    },

    "matrix_distance": {
        "node": "distanceBetween",
        "inputs": [
            ["inMatrix1"],
            ["inMatrix2"],
        ],
        "outputs": [
            ["distance"],
        ],
    },

    "mult_matrix": {
        "node": "multMatrix",
        "inputs": [
            [
                "matrixIn[{array}]"
            ],
        ],
        "outputs": [
            ["matrixSum"],
        ],
    },

    "nearest_point_on_curve": {
        "node": "nearestPointOnCurve",
        "inputs": [
            ["inputCurve"],
            ["inPositionX", "inPositionY", "inPositionZ"],
        ],
        "outputs": [
            ["positionX", "positionY", "positionZ"],
            ["parameter"],
        ],
        "output_is_predetermined": True,
    },

    "normalize_vector": {
        "node": "vectorProduct",
        "inputs": [
            ["input1X", "input1Y", "input1Z"],
            ["normalizeOutput"],
        ],
        "outputs": [
            ["outputX", "outputY", "outputZ"],
        ],
        "operation": 0,
    },

    "pair_blend": {
        "node": "pairBlend",
        "inputs": [
            ["inTranslateX1", "inTranslateY1", "inTranslateZ1"],
            ["inRotateX1", "inRotateY1", "inRotateZ1"],
            ["inTranslateX2", "inTranslateY2", "inTranslateZ2"],
            ["inRotateX2", "inRotateY2", "inRotateZ2"],
            ["weight"],
            ["rotInterpolation"],
        ],
        "outputs": [
            ["outTranslateX", "outTranslateY", "outTranslateZ"],
            ["outRotateX", "outRotateY", "outRotateZ"],
        ],
        "output_is_predetermined": True,
    },

    "pass_matrix": {
        "node": "passMatrix",
        "inputs": [
            ["inMatrix"],
            ["inScale"],
        ],
        "outputs": [
            ["outMatrix"],
        ],
    },

    "point_matrix_mult": {
        "node": "pointMatrixMult",
        "inputs": [
            ["inPointX", "inPointY", "inPointZ"],
            ["inMatrix"],
            ["vectorMultiply"],
        ],
        "outputs": [
            ["outputX", "outputY", "outputZ"],
        ],
    },

    "point_on_curve_info": {
        "node": "pointOnCurveInfo",
        "inputs": [
            ["inputCurve"],
            ["parameter"],
            ["turnOnPercentage"],
        ],
        "outputs": [
            ["positionX", "positionY", "positionZ"],
            ["normalX", "normalY", "normalZ"],
            ["normalizedNormalX", "normalizedNormalY", "normalizedNormalZ"],
            ["tangentX", "tangentY", "tangentZ"],
            ["normalizedTangentX", "normalizedTangentY", "normalizedTangentZ"],
            ["curvatureCenterX", "curvatureCenterY", "curvatureCenterZ"],
            ["curvatureRadius"],
        ],
        "output_is_predetermined": True,
    },

    "point_on_surface_info": {
        "node": "pointOnSurfaceInfo",
        "inputs": [
            ["inputSurface"],
            ["parameterU", "parameterV"],
            ["turnOnPercentage"],
        ],
        "outputs": [
            ["positionX", "positionY", "positionZ"],
            ["normalX", "normalY", "normalZ"],
            ["normalizedNormalX", "normalizedNormalY", "normalizedNormalZ"],
            ["tangentUx", "tangentUy", "tangentUz"],
            [
                "normalizedTangentUX",
                "normalizedTangentUY",
                "normalizedTangentUZ",
            ],
            ["tangentVx", "tangentVy", "tangentVz"],
            [
                "normalizedTangentVX",
                "normalizedTangentVY",
                "normalizedTangentVZ",
            ],
        ],
        "output_is_predetermined": True,
    },

    "quat_add": {
        "node": "quatAdd",
        "inputs": [
            ["input1QuatX", "input1QuatY", "input1QuatZ", "input1QuatW"],
            ["input2QuatX", "input2QuatY", "input2QuatZ", "input2QuatW"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "quat_conjugate": {
        "node": "quatConjugate",
        "inputs": [
            ["inputQuatX", "inputQuatY", "inputQuatZ", "inputQuatW"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "quat_invert": {
        "node": "quatInvert",
        "inputs": [
            ["inputQuatX", "inputQuatY", "inputQuatZ", "inputQuatW"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "quat_negate": {
        "node": "quatNegate",
        "inputs": [
            ["inputQuatX", "inputQuatY", "inputQuatZ", "inputQuatW"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "quat_normalize": {
        "node": "quatNormalize",
        "inputs": [
            ["inputQuatX", "inputQuatY", "inputQuatZ", "inputQuatW"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "quat_mul": {
        "node": "quatProd",
        "inputs": [
            ["input1QuatX", "input1QuatY", "input1QuatZ", "input1QuatW"],
            ["input2QuatX", "input2QuatY", "input2QuatZ", "input2QuatW"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "quat_sub": {
        "node": "quatSub",
        "inputs": [
            ["input1QuatX", "input1QuatY", "input1QuatZ", "input1QuatW"],
            ["input2QuatX", "input2QuatY", "input2QuatZ", "input2QuatW"],
        ],
        "outputs": [
            ["outputQuatX", "outputQuatY", "outputQuatZ", "outputQuatW"],
        ],
        "output_is_predetermined": True,
    },

    "quat_to_euler": {
        "node": "quatToEuler",
        "inputs": [
            ["inputQuatX", "inputQuatY", "inputQuatZ", "inputQuatW"],
            ["inputRotateOrder"],
        ],
        "outputs": [
            ["outputRotateX", "outputRotateY", "outputRotateZ"],
        ],
        "output_is_predetermined": True,
    },

    "remap_color": {
        "node": "remapColor",
        "inputs": [
            ["colorR", "colorG", "colorB"],
            ["outputMin"],
            ["outputMax"],
            ["inputMin"],
            ["inputMax"],
        ],
        "outputs": [
            ["outColorR", "outColorG", "outColorB"],
        ],
    },

    "remap_hsv": {
        "node": "remapHsv",
        "inputs": [
            ["colorR", "colorG", "colorB"],
            ["outputMin"],
            ["outputMax"],
            ["inputMin"],
            ["inputMax"],
        ],
        "outputs": [
            ["outColorR", "outColorG", "outColorB"],
        ],
    },

    "remap_value": {
        "node": "remapValue",
        "inputs": [
            ["inputValue"],
            ["outputMin"],
            ["outputMax"],
            ["inputMin"],
            ["inputMax"],
        ],
        "outputs": [
            ["outValue"],
        ],
    },

    "reverse": {
        "node": "reverse",
        "inputs": [
            ["inputX", "inputY", "inputZ"],
        ],
        "outputs": [
            ["outputX", "outputY", "outputZ"],
        ]
    },

    "rgb_to_hsv": {
        "node": "rgbToHsv",
        "inputs": [
            ["inRgbR", "inRgbG", "inRgbB"],
        ],
        "outputs": [
            ["outHsvH", "outHsvS", "outHsvV"],
        ],
        "output_is_predetermined": True,
    },

    "set_range": {
        "node": "setRange",
        "inputs": [
            ["valueX", "valueY", "valueZ"],
            ["minX", "minY", "minZ"],
            ["maxX", "maxY", "maxZ"],
            ["oldMinX", "oldMinY", "oldMinZ"],
            ["oldMaxX", "oldMaxY", "oldMaxZ"],
        ],
        "outputs": [
            ["outValueX", "outValueY", "outValueZ"],
        ],
    },

    "sum": {
        "node": "plusMinusAverage",
        "inputs": [
            [
                "input3D[{array}].input3Dx",
                "input3D[{array}].input3Dy",
                "input3D[{array}].input3Dz"
            ],
        ],
        "outputs": [
            ["output3Dx", "output3Dy", "output3Dz"],
        ],
        "operation": 1,
    },

    "transpose_matrix": {
        "node": "transposeMatrix",
        "inputs": [
            ["inputMatrix"],
        ],
        "outputs": [
            ["outputMatrix"],
        ],
    },

    "weighted_add_matrix": {
        "node": "wtAddMatrix",
        "inputs": [
            ["wtMatrix[{array}].matrixIn", "wtMatrix[{array}].weightIn"],
        ],
        "outputs": [
            ["matrixSum"],
        ],
    },
}


# Define EXTENSION_OPERATORS ---
[docs]def _extension_operators_init(): """Fill EXTENSION_OPERATORS-dictionary with all available operations. Note: EXTENSION_OPERATORS holds the data for each available operation: the necessary node-type, its inputs, outputs, etc. This unified data enables to abstract node creation, connection, .. possible flags: - node: Type of Maya node necessary - inputs: input attributes (list of lists) - outputs: output attributes (list) - operation: set operation-attr for different modes of a node - output_is_predetermined: should always ALL output attrs be added? Use "{array}" in inputs or outputs to denote an array-attribute! """ global EXTENSION_OPERATORS # Fill EXTENSION_OPERATORS with condition operations cond_operators = ["eq", "ne", "gt", "ge", "lt", "le"] for i, condition_operator in enumerate(cond_operators): EXTENSION_OPERATORS[condition_operator] = { "node": "condition", "inputs": [ ["firstTerm"], ["secondTerm"], ], # The condition node is a special case! It gets created during # the magic-method-comparison and fully connected after being # passed on to the condition()-method in this OperatorMetaClass "outputs": [ [None], ], "operation": i, } # Fill EXTENSION_OPERATORS with +,- operations for i, add_sub_operator in enumerate(["add", "sub"]): EXTENSION_OPERATORS[add_sub_operator] = { "node": "plusMinusAverage", "inputs": [ [ "input3D[{array}].input3Dx", "input3D[{array}].input3Dy", "input3D[{array}].input3Dz" ], ], "outputs": [ ["output3Dx", "output3Dy", "output3Dz"], ], "operation": i + 1, } # Fill EXTENSION_OPERATORS with *,/,** operations for i, mult_div_operator in enumerate(["mul", "div", "pow"]): EXTENSION_OPERATORS[mult_div_operator] = { "node": "multiplyDivide", "inputs": [ ["input1X", "input1Y", "input1Z"], ["input2X", "input2Y", "input2Z"], ], "outputs": [ ["outputX", "outputY", "outputZ"], ], "operation": i + 1, }
_extension_operators_init() # Define Operators ---
[docs]@noca_op def angle_between(vector_a, vector_b=(1, 0, 0)): """Create angleBetween-node to find the angle between 2 vectors. Args: vector_a (NcNode or NcAttrs or int or float or list): Vector to consider for angle between. vector_b (NcNode or NcAttrs or int or float or list or tuple): Vector to consider for angle between. Defaults to (1, 0, 0). Returns: NcNode: Instance with angleBetween-node and output-attribute(s) Example: :: matrix = Node("pCube1").worldMatrix pt = Op.point_matrix_mult( [1, 0, 0], matrix, vector_multiply=True ) Op.angle_between(pt, [1, 0, 0]) """ return _create_operation_node("angle_between", vector_a, vector_b)
[docs]@noca_op def average(*attrs): """Create plusMinusAverage-node for averaging input attrs. Args: attrs (NcNode or NcAttrs or NcList or string or list or tuple): Inputs to be averaged. Returns: NcNode: Instance with plusMinusAverage-node and output-attribute(s) Example: :: Op.average(Node("pCube.t"), [1, 2, 3]) """ if len(attrs) == 1: attrs = attrs[0] return _create_operation_node("average", attrs)
[docs]@noca_op def blend(attr_a, attr_b, blend_value=0.5): """Create blendColor-node. Args: attr_a (NcNode or NcAttrs or str or int or float): Plug or value to blend from attr_b (NcNode or NcAttrs or str or int or float): Plug or value to blend to blend_value (NcNode or str or int or float): Plug or value defining blend-amount. Defaults to 0.5. Returns: NcNode: Instance with blend-node and output-attributes Example: :: Op.blend(1, Node("pCube.tx"), Node("pCube.customBlendAttr")) """ return _create_operation_node("blend", attr_a, attr_b, blend_value)
[docs]@noca_op def choice(inputs, selector=0): """Create choice-node to switch between various input attributes. Note: Multi index input seems to also require one "selector" per index. So we package a copy of the same selector for each input. Args: inputs (NcList or NcAttrs or list): Any number of input values or plugs selector (NcNode or NcAttrs or int): Selector-attr on choice node to select one of the inputs based on their index. Defaults to 0. Returns: NcNode: Instance with choice-node and output-attribute(s) Example: :: option_a = Node("pCube1.tx") option_b = Node("pCube2.tx") switch = Node("pSphere1").add_bool("optionSwitch") choice_node = Op.choice([option_a, option_b], selector=switch) Node("pTorus1").tx = choice_node """ if not isinstance(inputs, (list, tuple)): inputs = [inputs] choice_node_obj = _create_operation_node("choice", inputs, selector) return choice_node_obj
[docs]@noca_op def clamp(attr_a, min_value=0, max_value=1): """Create clamp-node. Args: attr_a (NcNode or NcAttrs or str or int or float): Input value min_value (NcNode or NcAttrs or int or float or list): min-value for clamp-operation. Defaults to 0. max_value (NcNode or NcAttrs or int or float or list): max-value for clamp-operation. Defaults to 1. Returns: NcNode: Instance with clamp-node and output-attribute(s) Example: :: Op.clamp(Node("pCube.t"), [1, 2, 3], 5) """ return _create_operation_node("clamp", attr_a, min_value, max_value)
[docs]@noca_op def closest_point_on_mesh(mesh, position=(0, 0, 0), return_all_outputs=False): """Get the closest point on a mesh, from the given position. Args: mesh (NcNode or NcAttrs or str): Mesh node. position (NcNode or NcAttrs or int or float or list): Find closest point on mesh to this position. Defaults to (0, 0, 0). return_all_outputs (bool): Return all outputs as an NcList. Defaults to False. Returns: NcNode or NcList: If return_all_outputs is set to True, an NcList is returned with all outputs. Otherwise only the first output (position) is returned as an NcNode instance. Example: :: cube = Node("pCube1") Op.closest_point_on_mesh(cube.outMesh, [1, 0, 0]) """ return_value = _create_operation_node( "closest_point_on_mesh", mesh, position, ) if return_all_outputs: return return_value return return_value[0]
[docs]@noca_op def closest_point_on_surface( surface, position=(0, 0, 0), return_all_outputs=False): """Get the closest point on a surface, from the given position. Args: surface (NcNode or NcAttrs or str): NURBS surface node. position (NcNode or NcAttrs or int or float or list): Find closest point on surface to this position. Defaults to (0, 0, 0). return_all_outputs (bool): Return all outputs as an NcList. Defaults to False. Returns: NcNode or NcList: If return_all_outputs is set to True, an NcList is returned with all outputs. Otherwise only the first output (position) is returned as an NcNode instance. Example: :: sphere = Node("nurbsSphere1") Op.closest_point_on_surface(sphere.local, [1, 0, 0]) """ return_value = _create_operation_node( "closest_point_on_surface", surface, position, ) if return_all_outputs: return return_value return return_value[0]
[docs]@noca_op def compose_matrix( translate=None, rotate=None, scale=None, shear=None, rotate_order=None, euler_rotation=None, **kwargs): """Create composeMatrix-node to assemble matrix from transforms. Args: translate (NcNode or NcAttrs or str or int or float): translate [t] Defaults to None, which corresponds to value 0. rotate (NcNode or NcAttrs or str or int or float): rotate [r] Defaults to None, which corresponds to value 0. scale (NcNode or NcAttrs or str or int or float): scale [s] Defaults to None, which corresponds to value 1. shear (NcNode or NcAttrs or str or int or float): shear [sh] Defaults to None, which corresponds to value 0. rotate_order (NcNode or NcAttrs or str or int): rot-order [ro] Defaults to None, which corresponds to value 0. euler_rotation (NcNode or NcAttrs or bool): Euler or quaternion [uer] Defaults to None, which corresponds to True. kwargs (dict): Short flags, see in [brackets] for each arg above. Long names take precedence! Returns: NcNode: Instance with composeMatrix-node and output-attribute(s) Example: :: in_a = Node("pCube1") in_b = Node("pCube2") decomp_a = Op.decompose_matrix(in_a.worldMatrix) decomp_b = Op.decompose_matrix(in_b.worldMatrix) Op.compose_matrix(r=decomp_a.outputRotate, s=decomp_b.outputScale) """ translate = translate or kwargs.get("t", 0) rotate = rotate or kwargs.get("r", 0) scale = scale or kwargs.get("s", 1) shear = shear or kwargs.get("sh", 0) rotate_order = rotate_order or kwargs.get("ro", 0) euler_rotation = euler_rotation or kwargs.get("uer", True) compose_matrix_node = _create_operation_node( "compose_matrix", translate, rotate, scale, shear, rotate_order, euler_rotation ) return compose_matrix_node
[docs]@noca_op def condition(condition_node, if_part=False, else_part=True): """Set up condition-node. Note: condition_node can be a NcNode-instance of a Maya condition node. An appropriate NcNode-object gets automatically created when NodeCalculator objects are used in comparisons (==, >, >=, <, <=). Simply use comparison operators in the first argument. See example. Args: condition_node (NcNode or bool or int or float): Condition-statement. See note and example. if_part (NcNode or NcAttrs or str or int or float): Value/plug that is returned if the condition evaluates to true. Defaults to False. else_part (NcNode or NcAttrs or str or int or float): Value/plug that is returned if the condition evaluates to false. Defaults to True. Returns: NcNode: Instance with condition-node and outColor-attributes Example: :: condition_node = Node("pCube1.tx") >= 2 pass_on_if_true = Node("pCube2.ty") + 2 pass_on_if_false = 5 - Node("pCube2.tz").get() # Op.condition(condition-part, "if true"-part, "if false"-part) Op.condition(condition_node, pass_on_if_true, pass_on_if_false) """ # Catch case where condition_node is a static bool/int/... value if not isinstance(condition_node, NcBaseNode): if condition_node: return Node(if_part) else: return Node(else_part) # Make sure condition_node is of expected Node-type! if not isinstance(condition_node, NcBaseNode): LOG.warn("%s isn't NcBaseNode-instance.", condition_node) if cmds.objectType(condition_node.node) != "condition": LOG.warn("%s isn't of type condition.", condition_node) # Determine how many attrs were given & need to be connected max_dim = max( [len(_unravel_item_as_list(part)) for part in [if_part, else_part]] ) # Connect the given if/else parts to the condition node cond_input_attrs = [ ["colorIfTrueR", "colorIfTrueG", "colorIfTrueB"], ["colorIfFalseR", "colorIfFalseG", "colorIfFalseB"], ] node_name = condition_node.node for input_attrs, part in zip(cond_input_attrs, [if_part, else_part]): condition_input_list = [ "{0}.{1}".format(node_name, attr) for attr in input_attrs[:max_dim] ] _unravel_and_set_or_connect_a_to_b(condition_input_list, part) # Return new NcNode instance with condition node and its output attrs. cond_output_attrs = ["outColorR", "outColorG", "outColorB"] return_value = NcNode(node_name, cond_output_attrs[:max_dim]) return return_value
[docs]@noca_op def cross(attr_a, attr_b=0, normalize=False): """Create vectorProduct-node for vector cross-multiplication. Args: attr_a (NcNode or NcAttrs or str or int or float or list): Vector A. attr_b (NcNode or NcAttrs or str or int or float or list): Vector B. Defaults to 0. normalize (NcNode or NcAttrs or bool): Whether resulting vector should be normalized. Defaults to False. Returns: NcNode: Instance with vectorProduct-node and output-attribute(s) Example: :: Op.cross(Node("pCube.t"), [1, 2, 3], True) """ return _create_operation_node("cross", attr_a, attr_b, normalize)
[docs]@noca_op def curve_info(curve): """Measure the length of a curve. Args: curve (NcNode, NcAttrs or string): The curve to be measured. Returns: NcNode: Instance with vectorProduct-node and output-attribute(s) Example: :: Op.curve_info(Node("nurbsCurve.local")) """ return _create_operation_node("curve_info", curve)
[docs]@noca_op def decompose_matrix(in_matrix, return_all_outputs=False): """Create decomposeMatrix-node to disassemble matrix into transforms. Args: in_matrix (NcNode or NcAttrs or string): matrix attr to decompose return_all_outputs (bool): Return all outputs, as an NcList. Defaults to False. Returns: NcNode or NcList: If return_all_outputs is set to True, an NcList is returned with all outputs. Otherwise only the first output (translate) is returned as an NcNode instance. Example: :: driver = Node("pCube1") driven = Node("pSphere1") decomp = Op.decompose_matrix(driver.worldMatrix) driven.t = decomp.outputTranslate driven.r = decomp.outputRotate driven.s = decomp.outputScale """ return_value = _create_operation_node("decompose_matrix", in_matrix) if return_all_outputs: return return_value return return_value[0]
[docs]@noca_op def dot(attr_a, attr_b=0, normalize=False): """Create vectorProduct-node for vector dot-multiplication. Args: attr_a (NcNode or NcAttrs or str or int or float or list): Vector A. attr_b (NcNode or NcAttrs or str or int or float or list): Vector B. Defaults to 0. normalize (NcNode or NcAttrs or bool): Whether resulting vector should be normalized. Defaults to False. Returns: NcNode: Instance with vectorProduct-node and output-attribute(s) Example: :: Op.dot(Node("pCube.t"), [1, 2, 3], True) """ return _create_operation_node("dot", attr_a, attr_b, normalize)
[docs]@noca_op def euler_to_quat(angle, rotate_order=0): """Create eulerToQuat-node to add two quaternions together. Args: angle (NcNode or NcAttrs or str or list or tuple): Euler angles to convert into a quaternion. rotate_order (NcNode or NcAttrs or or int): Order of rotation. Defaults to 0, which represents rotate order "xyz". Returns: NcNode: Instance with eulerToQuat-node and output-attribute(s) Example: :: Op.euler_to_quat(Node("pCube").rotate, 2) """ created_node = _create_operation_node("euler_to_quat", angle, rotate_order) return created_node
[docs]@noca_op def exp(attr_a): """Raise attr_a to the base of natural logarithms. Args: attr_a (NcNode or NcAttrs or str or int or float): Value or attr Returns: NcNode: Instance with multiplyDivide-node and output-attr(s) Example: :: Op.exp(Node("pCube.t")) """ return math.e ** attr_a
[docs]@noca_op def four_by_four_matrix( vector_a=None, vector_b=None, vector_c=None, translate=None): """Create a four by four matrix out of its components. Args: vector_a (NcNode or NcAttrs or str or list or tuple or int or float): First vector of the matrix; the "x-axis". Or can contain all 16 elements that make up the 4x4 matrix. Defaults to None, which means the identity matrix will be used. vector_b (NcNode or NcAttrs or str or list or tuple or int or float): Second vector of the matrix; the "y-axis". Defaults to None, which means the vector (0, 1, 0) will be used, if matrix is not defined solely by vector_a. vector_c (NcNode or NcAttrs or str or list or tuple or int or float): Third vector of the matrix; the "z-axis". Defaults to None, which means the vector (0, 0, 1) will be used, if matrix is not defined solely by vector_a. translate (NcNode or NcAttrs or str or list or tuple or int or float): Translate-elements of the matrix. Defaults to None, which means the vector (0, 0, 0) will be used, if matrix is not defined solely by vector_a. Returns: NcNode: Instance with fourByFourMatrix-node and output-attr(s) Example: :: cube = Node("pCube1") vec_a = Op.point_matrix_mult( [1, 0, 0], cube.worldMatrix, vector_multiply=True ) vec_b = Op.point_matrix_mult( [0, 1, 0], cube.worldMatrix, vector_multiply=True ) vec_c = Op.point_matrix_mult( [0, 0, 1], cube.worldMatrix, vector_multiply=True ) out = Op.four_by_four_matrix( vector_a=vec_a, vector_b=vec_b, vector_c=vec_c, translate=[cube.tx, cube.ty, cube.tz] ) """ # If any vector is not None: The operator won't return the identity matrix. vectors = [vector_a, vector_b, vector_c, translate] if any([vector is not None for vector in vectors]): # If a vector other than vector_a is not None: Assume the matrix # should be created from multiple vectors. if any([vector is not None for vector in vectors[1:]]): # Start with the identity matrix and set/connect any given vector. created_node = _create_operation_node( "four_by_four_matrix", [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] ) if vector_a: _unravel_and_set_or_connect_a_to_b( [created_node.in00, created_node.in01, created_node.in02], vector_a, ) if vector_b: _unravel_and_set_or_connect_a_to_b( [created_node.in10, created_node.in11, created_node.in12], vector_b, ) if vector_c: _unravel_and_set_or_connect_a_to_b( [created_node.in20, created_node.in21, created_node.in22], vector_c, ) if translate: _unravel_and_set_or_connect_a_to_b( [created_node.in30, created_node.in31, created_node.in32], translate, ) # If only vector_a was given: Assume it contains all elements that # should make up the matrix. else: created_node = _create_operation_node( "four_by_four_matrix", vector_a ) else: # Default to identity matrix created_node = _create_operation_node( "four_by_four_matrix", [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] ) return created_node
[docs]@noca_op def hold_matrix(matrix): """Create holdMatrix-node for storing a matrix. Args: matrix (NcNode or NcAttrs or string or list): Matrix to store. Returns: NcNode: Instance with holdMatrix-node and output-attribute(s) Example: :: Op.hold_matrix(Node("pCube1.worldMatrix")) """ return _create_operation_node("hold_matrix", matrix)
[docs]@noca_op def inverse_matrix(in_matrix): """Create inverseMatrix-node to invert the given matrix. Args: in_matrix (NcNode or NcAttrs or str): Matrix to invert Returns: NcNode: Instance with inverseMatrix-node and output-attribute(s) Example: :: Op.inverse_matrix(Node("pCube.worldMatrix")) """ return _create_operation_node("inverse_matrix", in_matrix)
[docs]@noca_op def length(attr_a, attr_b=0): """Create distanceBetween-node to measure length between given points. Args: attr_a (NcNode or NcAttrs or str or int or float): Start point. attr_b (NcNode or NcAttrs or str or int or float): End point. Defaults to 0. Returns: NcNode: Instance with distanceBetween-node and distance-attribute Example: :: Op.len(Node("pCube.t"), [1, 2, 3]) """ return _create_operation_node("length", attr_a, attr_b)
[docs]@noca_op def matrix_distance(matrix_a, matrix_b=None): """Create distanceBetween-node to measure distance between matrices. Args: matrix_a (NcNode or NcAttrs or str): Matrix defining start point. matrix_b (NcNode or NcAttrs or str): Matrix defining end point. Defaults to None, which gives the length between the origin and the point described by matrix_a. Returns: NcNode: Instance with distanceBetween-node and distance-attribute Example: :: Op.len(Node("pCube.worldMatrix"), Node("pCube2.worldMatrix")) """ if matrix_b is None: return _create_operation_node("matrix_distance", matrix_a) return _create_operation_node("matrix_distance", matrix_a, matrix_b)
[docs]@noca_op def mult_matrix(*attrs): """Create multMatrix-node for multiplying matrices. Args: attrs (NcNode or NcAttrs or NcList or string or list or tuple): Matrices to multiply together. Returns: NcNode: Instance with multMatrix-node and output-attribute(s) Example: :: matrix_mult = Op.mult_matrix( Node("pCube1.worldMatrix"), Node("pCube2").worldMatrix ) decomp = Op.decompose_matrix(matrix_mult) out = Node("pSphere") out.translate = decomp.outputTranslate out.rotate = decomp.outputRotate out.scale = decomp.outputScale """ if len(attrs) == 1: attrs = attrs[0] return _create_operation_node("mult_matrix", attrs)
[docs]@noca_op def nearest_point_on_curve( curve, position=(0, 0, 0), return_all_outputs=False): """Get curve data from a particular point on a curve. Args: curve (NcNode or NcAttrs or str): Curve node. position (NcNode or NcAttrs or int or float or list): Find closest point on curve to this position. Defaults to (0, 0, 0). return_all_outputs (bool): Return all outputs as an NcList. Defaults to False. Returns: NcNode or NcList: If return_all_outputs is set to True, an NcList is returned with all outputs. Otherwise only the first output (position) is returned as an NcNode instance. Example: :: curve = Node("curve1") Op.nearest_point_on_curve(curve.local, [1, 0, 0]) """ return_value = _create_operation_node( "nearest_point_on_curve", curve, position, ) if return_all_outputs: return return_value return return_value[0]
[docs]@noca_op def normalize_vector(in_vector, normalize=True): """Create vectorProduct-node to normalize the given vector. Args: in_vector (NcNode or NcAttrs or str or int or float or list): Vect. normalize (NcNode or NcAttrs or bool): Turn normalize on/off. Defaults to True. Returns: NcNode: Instance with vectorProduct-node and output-attribute(s) Example: :: Op.normalize_vector(Node("pCube.t")) """ # Making normalize a flag allows the user to connect attributes to it return_value = _create_operation_node( "normalize_vector", in_vector, normalize ) return return_value
[docs]@noca_op def pair_blend( translate_a=0, rotate_a=0, translate_b=0, rotate_b=0, weight=1, quat_interpolation=False, return_all_outputs=False): """Create pairBlend-node to blend between two transforms. Args: translate_a (NcNode or NcAttrs or str or int or float or list): Translate value of first transform. Defaults to 0. rotate_a (NcNode or NcAttrs or str or int or float or list): Rotate value of first transform. Defaults to 0. translate_b (NcNode or NcAttrs or str or int or float or list): Translate value of second transform. Defaults to 0. rotate_b (NcNode or NcAttrs or str or int or float or list): Rotate value of second transform. Defaults to 0. weight (NcNode or NcAttrs or str or int or float or list): Bias towards first or second transform. Defaults to 1. quat_interpolation (NcNode or NcAttrs or bool): Use euler (False) or quaternions (True) to interpolate rotation Defaults to False. return_all_outputs (bool): Return all outputs, as an NcList. Defaults to False. Returns: NcNode or NcList: If return_all_outputs is set to True, an NcList is returned with all outputs. Otherwise only the first output (translate) is returned as an NcNode instance. Example: :: a = Node("pCube1") b = Node("pSphere1") blend_attr = a.add_float("blend") Op.pair_blend(a.t, a.r, b.t, b.r, blend_attr) """ return_value = _create_operation_node( "pair_blend", translate_a, rotate_a, translate_b, rotate_b, weight, quat_interpolation, ) if return_all_outputs: return return_value return return_value[0]
[docs]@noca_op def pass_matrix(matrix, scale=1): """Create passMatrix-node for passing and optionally scaling a matrix. Args: matrix (NcNode or NcAttrs or string or list): Matrix to store. scale (NcNode or NcAttrs or int or float): Scale to be applied to matrix. Defaults to 1. Returns: NcNode: Instance with passMatrix-node and output-attribute(s) Example: :: Op.pass_matrix(Node("pCube1.worldMatrix")) """ return _create_operation_node("pass_matrix", matrix, scale)
[docs]@noca_op def point_matrix_mult(in_vector, in_matrix, vector_multiply=False): """Create pointMatrixMult-node to transpose the given matrix. Args: in_vector (NcNode or NcAttrs or str or int or float or list): Vect. in_matrix (NcNode or NcAttrs or str): Matrix vector_multiply (NcNode or NcAttrs or str or int or bool): Whether vector multiplication should be performed. Defaults to False. Returns: NcNode: Instance with pointMatrixMult-node and output-attribute(s) Example: :: Op.point_matrix_mult( Node("pSphere.t"), Node("pCube.worldMatrix"), vector_multiply=True ) """ created_node = _create_operation_node( "point_matrix_mult", in_vector, in_matrix, vector_multiply ) return created_node
[docs]@noca_op def quat_add(quat_a, quat_b=(0, 0, 0, 1)): """Create quatAdd-node to add two quaternions together. Args: quat_a (NcNode or NcAttrs or str or list or tuple): First quaternion. quat_b (NcNode or NcAttrs or str or list or tuple): Second quaternion. Defaults to (0, 0, 0, 1). Returns: NcNode: Instance with quatAdd-node and output-attribute(s) Example: :: Op.quat_add( create_node("decomposeMatrix").outputQuat, create_node("decomposeMatrix").outputQuat, ) """ created_node = _create_operation_node("quat_add", quat_a, quat_b) return created_node
[docs]@noca_op def quat_conjugate(quat_a): """Create quatConjugate-node to conjugate a quaternion. Args: quat_a (NcNode or NcAttrs or str or list or tuple): Quaternion to conjugate. Returns: NcNode: Instance with quatConjugate-node and output-attribute(s) Example: :: Op.quat_conjugate(create_node("decomposeMatrix").outputQuat) """ created_node = _create_operation_node("quat_conjugate", quat_a) return created_node
[docs]@noca_op def quat_invert(quat_a): """Create quatInvert-node to invert a quaternion. Args: quat_a (NcNode or NcAttrs or str or list or tuple): Quaternion to invert. Returns: NcNode: Instance with quatInvert-node and output-attribute(s) Example: :: Op.quat_invert(create_node("decomposeMatrix").outputQuat) """ created_node = _create_operation_node("quat_invert", quat_a) return created_node
[docs]@noca_op def quat_negate(quat_a): """Create quatNegate-node to negate a quaternion. Args: quat_a (NcNode or NcAttrs or str or list or tuple): Quaternion to negate. Returns: NcNode: Instance with quatNegate-node and output-attribute(s) Example: :: Op.quat_negate(create_node("decomposeMatrix").outputQuat) """ created_node = _create_operation_node("quat_negate", quat_a) return created_node
[docs]@noca_op def quat_normalize(quat_a): """Create quatNormalize-node to normalize a quaternion. Args: quat_a (NcNode or NcAttrs or str or list or tuple): Quaternion to normalize. Returns: NcNode: Instance with quatNormalize-node and output-attribute(s) Example: :: Op.quat_normalize(create_node("decomposeMatrix").outputQuat) """ created_node = _create_operation_node("quat_normalize", quat_a) return created_node
[docs]@noca_op def quat_mul(quat_a, quat_b=(0, 0, 0, 1)): """Create quatProd-node to multiply two quaternions together. Args: quat_a (NcNode or NcAttrs or str or list or tuple): First quaternion. quat_b (NcNode or NcAttrs or str or list or tuple): Second quaternion. Defaults to (0, 0, 0, 1). Returns: NcNode: Instance with quatProd-node and output-attribute(s) Example: :: Op.quat_mul( create_node("decomposeMatrix").outputQuat, create_node("decomposeMatrix").outputQuat, ) """ created_node = _create_operation_node("quat_mul", quat_a, quat_b) return created_node
[docs]@noca_op def quat_sub(quat_a, quat_b=(0, 0, 0, 1)): """Create quatSub-node to subtract two quaternions from each other. Args: quat_a (NcNode or NcAttrs or str or list or tuple): First quaternion. quat_b (NcNode or NcAttrs or str or list or tuple): Second quaternion that will be subtracted from the first. Defaults to (0, 0, 0, 1). Returns: NcNode: Instance with quatSub-node and output-attribute(s) Example: :: Op.quat_sub( create_node("decomposeMatrix").outputQuat, create_node("decomposeMatrix").outputQuat, ) """ created_node = _create_operation_node("quat_sub", quat_a, quat_b) return created_node
[docs]@noca_op def quat_to_euler(quat_a, rotate_order=0): """Create quatToEuler-node to convert a quaternion into an euler angle. Args: quat_a (NcNode or NcAttrs or str or list or tuple): Quaternion to convert into Euler angles. rotate_order (NcNode or NcAttrs or or int): Order of rotation. Defaults to 0, which represents rotate order "xyz". Returns: NcNode: Instance with quatToEuler-node and output-attribute(s) Example: :: Op.quat_to_euler(create_node("decomposeMatrix").outputQuat, 2) """ created_node = _create_operation_node( "quat_to_euler", quat_a, rotate_order ) return created_node
[docs]@noca_op def point_on_curve_info( curve, parameter=0, as_percentage=False, return_all_outputs=False): """Get curve data from a particular point on a curve. Args: curve (NcNode or NcAttrs or str): Curve node. parameter (NcNode or NcAttrs or int or float or list): Get curve data at the position on the curve specified by this parameter. Defaults to 0. as_percentage (NcNode or NcAttrs or int or float or bool): Use 0-1 values for parameter. Defaults to False. return_all_outputs (bool): Return all outputs as an NcList. Defaults to False. Returns: NcNode or NcList: If return_all_outputs is set to True, an NcList is returned with all outputs. Otherwise only the first output (position) is returned as an NcNode instance. Example: :: curve = Node("curve1") Op.point_on_curve_info(curve.local, 0.5) """ return_value = _create_operation_node( "point_on_curve_info", curve, parameter, as_percentage, ) if return_all_outputs: return return_value return return_value[0]
[docs]@noca_op def point_on_surface_info( surface, parameter=(0, 0), as_percentage=False, return_all_outputs=False): """Get surface data from a particular point on a NURBS surface. Args: surface (NcNode or NcAttrs or str): NURBS surface node. parameter (NcNode or NcAttrs or int or float or list): UV values that define point on NURBS surface. Defaults to (0, 0). as_percentage (NcNode or NcAttrs or int or float or bool): Use 0-1 values for parameters. Defaults to False. return_all_outputs (bool): Return all outputs as an NcList. Defaults to False. Returns: NcNode or NcList: If return_all_outputs is set to True, an NcList is returned with all outputs. Otherwise only the first output (position) is returned as an NcNode instance. Example: :: sphere = Node("nurbsSphere1") Op.point_on_surface_info(sphere.local, [0.5, 0.5]) """ return_value = _create_operation_node( "point_on_surface_info", surface, parameter, as_percentage, ) if return_all_outputs: return return_value return return_value[0]
[docs]@noca_op def pow(attr_a, attr_b=2): """Raise attr_a to the power of attr_b. Args: attr_a (NcNode or NcAttrs or str or int or float): Value or attr. attr_b (NcNode or NcAttrs or str or int or float): Value or attr. Defaults to 2. Returns: NcNode: Instance with multiplyDivide-node and output-attr(s) Example: :: Op.pow(Node("pCube.t"), 2.5) """ return attr_a ** attr_b
[docs]@noca_op def remap_color( attr_a, output_min=0, output_max=1, input_min=0, input_max=1, values_red=None, values_green=None, values_blue=None): """Create remapColor-node to remap the given input. Args: attr_a (NcNode or NcAttrs or str or int or float): Input color. output_min (NcNode or NcAttrs or int or float or list): minValue. Defaults to 0. output_max (NcNode or NcAttrs or int or float or list): maxValue. Defaults to 1. input_min (NcNode or NcAttrs or int or float or list): old minValue. Defaults to 0. input_max (NcNode or NcAttrs or int or float or list): old maxValue. Defaults to 1. values_red (list): List of tuples for red-graph in the form; (value_Position, value_FloatValue, value_Interp) The value interpolation element is optional (default: linear) Defaults to None. values_green (list): List of tuples for green-graph in the form; (value_Position, value_FloatValue, value_Interp) The value interpolation element is optional (default: linear) Defaults to None. values_blue (list): List of tuples for blue-graph in the form; (value_Position, value_FloatValue, value_Interp) The value interpolation element is optional (default: linear) Defaults to None. Returns: NcNode: Instance with remapColor-node and output-attribute(s) Raises: TypeError: If given values isn't a list of either lists or tuples. RuntimeError: If given values isn't a list of lists/tuples of length 2 or 3. Example: :: Op.remap_color( Node("blinn1.outColor"), values_red=[(0.1, .2, 0), (0.4, 0.3)] ) """ created_node = _create_operation_node( "remap_color", attr_a, output_min, output_max, input_min, input_max ) value_lists = [values_red, values_green, values_blue] for values, color in zip(value_lists, ["red", "green", "blue"]): for index, value_data in enumerate(values or []): # value_Position, value_FloatValue, value_Interp # "x-axis", "y-axis", interpolation if not isinstance(value_data, (list, tuple)): msg = ( "The values-flag for remap_color requires a list of " "tuples! Got {0} instead.".format(values) ) raise TypeError(msg) elif len(value_data) == 2: pos, val = value_data interp = 1 elif len(value_data) == 3: pos, val, interp = value_data else: msg = ( "The values-flag for remap_color requires a list of " "tuples of length 2 or 3! Got {0} instead.".format(values) ) raise RuntimeError(msg) _unravel_and_set_or_connect_a_to_b( "{0}.{1}[{2}]".format(created_node.node, color, index), (pos, val, interp) ) return created_node
[docs]@noca_op def remap_hsv( attr_a, output_min=0, output_max=1, input_min=0, input_max=1, values_hue=None, values_saturation=None, values_value=None): """Create remapHsv-node to remap the given input. Args: attr_a (NcNode or NcAttrs or str or int or float): Input color. output_min (NcNode or NcAttrs or int or float or list): minValue. Defaults to 0. output_max (NcNode or NcAttrs or int or float or list): maxValue. Defaults to 1. input_min (NcNode or NcAttrs or int or float or list): old minValue. Defaults to 0. input_max (NcNode or NcAttrs or int or float or list): old maxValue. Defaults to 1. values_hue (list): List of tuples for hue-graph in the form; (value_Position, value_FloatValue, value_Interp) The value interpolation element is optional (default: linear) Defaults to None. values_saturation (list): List of tuples for saturation-graph in form; (value_Position, value_FloatValue, value_Interp) The value interpolation element is optional (default: linear) Defaults to None. values_value (list): List of tuples for value-graph in the form; (value_Position, value_FloatValue, value_Interp) The value interpolation element is optional (default: linear) Defaults to None. Returns: NcNode: Instance with remapHsv-node and output-attribute(s) Raises: TypeError: If given values isn't a list of either lists or tuples. RuntimeError: If given values isn't a list of lists/tuples of length 2 or 3. Example: :: Op.remap_hsv( Node("blinn1.outColor"), values_saturation=[(0.1, .2, 0), (0.4, 0.3)] ) """ created_node = _create_operation_node( "remap_hsv", attr_a, output_min, output_max, input_min, input_max ) value_lists = [values_hue, values_saturation, values_value] for values, setting in zip(value_lists, ["hue", "saturation", "value"]): for index, value_data in enumerate(values or []): # value_Position, value_FloatValue, value_Interp # "x-axis", "y-axis", interpolation if not isinstance(value_data, (list, tuple)): msg = ( "The values-flag for remap_hsv requires a list of " "tuples! Got {0} instead.".format(values) ) raise TypeError(msg) elif len(value_data) == 2: pos, val = value_data interp = 1 elif len(value_data) == 3: pos, val, interp = value_data else: msg = ( "The values-flag for remap_hsv requires a list of " "tuples of length 2 or 3! Got {0} instead.".format(values) ) raise RuntimeError(msg) _unravel_and_set_or_connect_a_to_b( "{0}.{1}[{2}]".format(created_node.node, setting, index), (pos, val, interp) ) return created_node
[docs]@noca_op def remap_value( attr_a, output_min=0, output_max=1, input_min=0, input_max=1, values=None): """Create remapValue-node to remap the given input. Args: attr_a (NcNode or NcAttrs or str or int or float): Input value output_min (NcNode or NcAttrs or int or float or list): minValue. Defaults to 0. output_max (NcNode or NcAttrs or int or float or list): maxValue. Defaults to 1. input_min (NcNode or NcAttrs or int or float or list): old minValue. Defaults to 0. input_max (NcNode or NcAttrs or int or float or list): old maxValue. Defaults to 1. values (list): List of tuples in the following form; (value_Position, value_FloatValue, value_Interp) The value interpolation element is optional (default: linear) Defaults to None. Returns: NcNode: Instance with remapValue-node and output-attribute(s) Raises: TypeError: If given values isn't a list of either lists or tuples. RuntimeError: If given values isn't a list of lists/tuples of length 2 or 3. Example: :: Op.remap_value( Node("pCube.t"), values=[(0.1, .2, 0), (0.4, 0.3)] ) """ created_node = _create_operation_node( "remap_value", attr_a, output_min, output_max, input_min, input_max ) for index, value_data in enumerate(values or []): # value_Position, value_FloatValue, value_Interp # "x-axis", "y-axis", interpolation if not isinstance(value_data, (list, tuple)): msg = ( "The values-flag for remap_value requires a list of " "tuples! Got {0} instead.".format(values) ) raise TypeError(msg) elif len(value_data) == 2: pos, val = value_data interp = 1 elif len(value_data) == 3: pos, val, interp = value_data else: msg = ( "The values-flag for remap_value requires a list of " "tuples of length 2 or 3! Got {0} instead.".format(values) ) raise RuntimeError(msg) _unravel_and_set_or_connect_a_to_b( "{0}.value[{1}]".format(created_node.node, index), (pos, val, interp) ) return created_node
[docs]@noca_op def reverse(attr_a): """Create reverse-node to get 1 minus the input. Args: attr_a (NcNode or NcAttrs or str or int or float): Input value Returns: NcNode: Instance with reverse-node and output-attribute(s) Example: :: Op.reverse(Node("pCube.visibility")) """ return _create_operation_node("reverse", attr_a)
[docs]@noca_op def rgb_to_hsv(rgb_color): """Create rgbToHsv-node to get RGB color in HSV representation. Args: rgb_color (NcNode or NcAttrs or str or int or float): Input RGB color. Returns: NcNode: Instance with rgbToHsv-node and output-attribute(s) Example: :: Op.rgb_to_hsv(Node("blinn1.outColor")) """ return _create_operation_node("rgb_to_hsv", rgb_color)
[docs]@noca_op def set_range( attr_a, min_value=0, max_value=1, old_min_value=0, old_max_value=1): """Create setRange-node to remap the given input attr to a new min/max. Args: attr_a (NcNode or NcAttrs or str or int or float): Input value. min_value (NcNode or NcAttrs or int or float or list): New min. Defaults to 0. max_value (NcNode or NcAttrs or int or float or list): New max. Defaults to 1. old_min_value (NcNode or NcAttrs or int or float or list): Old min. Defaults to 0. old_max_value (NcNode or NcAttrs or int or float or list): Old max. Defaults to 1. Returns: NcNode: Instance with setRange-node and output-attribute(s) Example: :: Op.set_range(Node("pCube.t"), [1, 2, 3], 4, [-1, 0, -2]) """ return_value = _create_operation_node( "set_range", attr_a, min_value, max_value, old_min_value, old_max_value ) return return_value
[docs]@noca_op def sum(*attrs): """Create plusMinusAverage-node for averaging input attrs. Args: attrs (NcNode or NcAttrs or NcList or string or list or tuple): Inputs to be added up. Returns: NcNode: Instance with plusMinusAverage-node and output-attribute(s) Example: :: Op.average(Node("pCube.t"), [1, 2, 3]) """ if len(attrs) == 1: attrs = attrs[0] return _create_operation_node("sum", attrs)
[docs]@noca_op def sqrt(attr_a): """Get the square root of attr_a. Args: attr_a (NcNode or NcAttrs or str or int or float): Value or attr Returns: NcNode: Instance with multiplyDivide-node and output-attr(s) Example: :: Op.sqrt(Node("pCube.tx")) """ return attr_a ** 0.5
[docs]@noca_op def transpose_matrix(in_matrix): """Create transposeMatrix-node to transpose the given matrix. Args: in_matrix (NcNode or NcAttrs or str): Plug or value for in_matrix Returns: NcNode: Instance with transposeMatrix-node and output-attribute(s) Example: :: Op.transpose_matrix(Node("pCube.worldMatrix")) """ return _create_operation_node("transpose_matrix", in_matrix)
[docs]@noca_op def weighted_add_matrix(*matrices): """Add matrices with a weight-bias. Args: matrices (NcNode or NcAttrs or list or tuple): Any number of matrices. Can be a list of tuples; (matrix, weight) or simply a list of matrices. In that case the weight will be evenly distributed between all given matrices. Returns: NcNode: Instance with wtAddMatrix-node and output-attribute(s) Example: :: cube_a = Node("pCube1.worldMatrix") cube_b = Node("pCube2.worldMatrix") Op.weighted_add_matrix(cube_a, cube_b) """ weighted_matrices = [] num_matrices = len(matrices) for matrix in matrices: if isinstance(matrix, tuple) and len(matrix) == 2: weighted_matrices.append(matrix) else: weighted_matrices.append((matrix, 1.0/num_matrices)) return _create_operation_node("weighted_add_matrix", weighted_matrices)