def test_iterMetaChildrenLargeNetwork(self): # large network children = [] parentMeta = base.MetaBase(nodes.createDGNode("parentMeta", "network")) # to test connecting multiple nodes to a single parent for i in range(100): child = base.MetaBase( nodes.createDGNode("child{}".format(i), "network")) parentMeta.addChild(child) children.append(child) self.assertTrue(len(parentMeta.metaChildren()), len(children)) parent = parentMeta for child in children: child.removeParent() child.addParent(parent) parent = child self.assertEquals( len([i for i in parentMeta.iterMetaChildren(depthLimit=1)]), 1) # we hit a depth limit self.assertEquals( len([i for i in parentMeta.iterMetaChildren(depthLimit=100)]), 100) self.assertEquals( len([ i for i in parentMeta.iterMetaChildren(depthLimit=len(children) + 1) ]), len(children))
def multiplyDivide(input1, input2, operation, name): """Creates a multiply divide node with the given and setups the input connections. List of operations:: no operation = 0, multipy = 1, divide = 2, power = 3 :param input1:the node attribute to connect to the input1 value or use int for value :type input1: MPlug or MVector :param input2:the node attribute to connect to the input2 value or use int for value :type input2: MPlug or MVector :param operation: the int value for operation :type operation: int :return, the multiplyDivide node MObject :rtype: MObject """ mult = om2.MFnDependencyNode(nodes.createDGNode(name, "multiplyDivide")) # assume connection type if isinstance(input1, om2.MPlug): plugs.connectPlugs(input1, mult.findPlug("input1", False)) # plug set else: plugs.setPlugValue(mult.findPlug("input1", False), input1) if isinstance(input2, om2.MPlug): plugs.connectPlugs(input2, mult.findPlug("input2", False)) else: plugs.setPlugValue(mult.findPlug("input2", False), input1) plugs.setPlugValue(mult.findPlug("operation", False), operation) return mult.object()
def createControllerTag(node, name, parent=None, visibilityPlug=None): """Create a maya kControllerTag and connects it up to the 'node'. :param node: The Dag node MObject to tag :type node: om2.MObject :param name: The name for the kControllerTag :type name: str :param parent: The Parent kControllerTag mObject or None :type parent: om2.MObject or None :param visibilityPlug: The Upstream Plug to connect to the visibility mode Plug :type visibilityPlug: om2.MPlug or None :return: The newly created kController node as a MObject :rtype: om.MObject """ ctrl = nodes.createDGNode(name, "controller") fn = om2.MFnDependencyNode(ctrl) plugs.connectPlugs( om2.MFnDependencyNode(node).findPlug("message", False), fn.findPlug("controllerObject", False)) if visibilityPlug is not None: plugs.connectPlugs(visibilityPlug, fn.findPlug("visibilityMode", False)) if parent is not None: parentFn = om2.MFnDependencyNode(parent) plugs.connectPlugs( fn.findPlug("parent", False), plugs.nextAvailableDestElementPlug( parentFn.findPlug("children", False))) plugs.connectPlugs(parentFn.findPlug("prepopulate", False), fn.findPlug("prepopulate", False)) return ctrl
def distanceBetween(firstNode, secondNode, name): """Creates a distance between node and connects the 'firstNode' and 'secondNode' world space matrices. :param firstNode: The start transform node :type firstNode: MObject :param secondNode: The second transform node :type secondNode: MObject :return: the Three nodes created by the function in the form of a tuple, the first element \ is the distance between node, the second is the start node decompose matrix, the third element \ is the second node decompose matrix. :rtype: tuple(om2.MObject, om2.MObject, om2.MObject) """ firstFn = om2.MFnDependencyNode(firstNode) secondFn = om2.MFnDependencyNode(secondNode) distanceBetweenNode = nodes.createDGNode(name, "distanceBetween") distFn = om2.MFnDependencyNode(distanceBetweenNode) firstFnWorldMat = firstFn.findPlug("worldMatrix", False) firstFnWorldMat.evaluateNumElements() secondFnWorldMat = secondFn.findPlug("worldMatrix", False) secondFnWorldMat.evaluateNumElements() plugs.connectPlugs(firstFnWorldMat.elementByPhysicalIndex(0), distFn.findPlug("inMatrix1", False)) plugs.connectPlugs(secondFnWorldMat.elementByPhysicalIndex(0), distFn.findPlug("inMatrix2", False)) return distanceBetweenNode
def blendTwoAttr(input1, input2, blender, name): fn = om2.MFnDependencyNode(nodes.createDGNode(name, "blendTwoAttr")) inputArray = fn.findPlug("input", False) plugs.connectPlugs(input1, inputArray.elementByLogicalIndex(-1)) plugs.connectPlugs(input2, inputArray.elementByLogicalIndex(-1)) plugs.connectPlugs(blender, fn.findPlug("attributesBlender", False)) return fn.object()
def floatMath(floatA, floatB, operation, name): """Creates a floatMath node from the lookdev kit builtin plugin :param floatA: If the type is a MPlug then the floatA plug on the new node\ will be connected the given plug. :type floatA: float or om2.MPlug :param floatB: If the type is a MPlug then the floatB plug on the new node\ will be connected the given plug. :type floatB: float or om2.MPlug :param operation: The operation attributes value :type operation: int :param name: The new floatMath node name. :type name: str :return: The floatMath node MObject :rtype: om2.MObject """ floatMathFn = om2.MFnDependencyNode(nodes.createDGNode(name, "floatMath")) if isinstance(floatA, om2.MPlug): plugs.connectPlugs(floatA, floatMathFn.findPlug("floatA", False)) else: plugs.setPlugValue(floatMathFn.findPlug("floatA", False), floatA) if isinstance(floatB, om2.MPlug): plugs.connectPlugs(floatB, floatMathFn.findPlug("floatB", False)) else: plugs.setPlugValue(floatMathFn.findPlug("floatB", False), floatB) plugs.setPlugValue(floatMathFn.findPlug("operation", False), operation) return floatMathFn.object()
def blendColors(color1, color2, name, blender): """Creates a blend colors node. :param color1: If the type is a MPlug then the color1 plug on the new node\ will be connected the given plug. :type color1: om2.MColor or om2.MPlug :param color2: If the type is a MPlug then the color2 plug on the new node\ will be connected the given plug. :type color2: om2.MColor or om2.MPlug :param name: The new floatMath node name. :type name: str :param blender: If the type is a MPlug then the blender plug on the new node\ will be connected the given plug. :type blender: float or om2.MPlug :return: The new colorBlend node as a MObject :rtype: om2.MObject """ blendFn = om2.MFnDependencyNode(nodes.createDGNode(name, "blendColors")) if isinstance(color1, om2.MPlug): plugs.connectPlugs(color1, blendFn.findPlug("color1", False)) else: plugs.setPlugValue(blendFn.findPlug("color1", False), color1) if isinstance(color2, om2.MPlug): plugs.connectPlugs(color2, blendFn.findPlug("color2", False)) else: plugs.setPlugValue(blendFn.findPlug("color2", False), color2) if isinstance(blender, om2.MPlug): plugs.connectPlugs(blender, blendFn.findPlug("blender", False)) else: plugs.setPlugValue(blendFn.findPlug("blender", False), blender) return blendFn.object()
def attachNodeToCurveAtParam(curve, node, param, name): """Attaches the given node to the curve using a motion path node. :param curve: nurbsCurve Shape to attach to :type curve: om2.MObject :param node: the node to attach to the curve :type node: om2.MObject :param param: the parameter float value along the curve :type param: float :param name: the motion path node name to use :type name: str :return: motion path node :rtype: om2.MObject """ nodeFn = om2.MFnDependencyNode(node) crvFn = om2.MFnDependencyNode(curve) mp = nodes.createDGNode(name, "motionPath") mpFn = om2.MFnDependencyNode(mp) plugs.connectVectorPlugs(mpFn.findPlug("rotate", False), nodeFn.findPlug("rotate", False), (True, True, True)) plugs.connectVectorPlugs(mpFn.findPlug("allCoordinates", False), nodeFn.findPlug("translate", False), (True, True, True)) crvWorld = crvFn.findPlug("worldSpace", False) plugs.connectPlugs(crvWorld.elementByLogicalIndex(0), mpFn.findPlug("geometryPath", False)) mpFn.findPlug("uValue", False).setFloat(param) mpFn.findPlug("frontAxis", False).setInt(0) mpFn.findPlug("upAxis", False).setInt(1) return mp
def createPlusMinusAverage2D(name, inputs, output=None, operation=1): """ Create's a plusMinusAverage node and connects the 2D inputs and outputs. :param name: the plus minus average node name :type name: str :param inputs: tuple of MPlugs and/or float values, each value will be applied to / a new Input2D element. If the value is MPlug then it will be connected :type inputs: iterable(plug or float) :param output: A tuple of downstream MPlugs to connect to. :type output: iterable(plug) :return: The plus minus average MObject :rtype: om2.MObject """ pma = nodes.createDGNode(name, "plusMinusAverage") fn = om2.MFnDependencyNode(pma) inPlug = fn.findPlug("input2D", False) fn.findPlug("operation", False).setInt(operation) for i, p in enumerate(inputs): if p is None: continue child = plugs.nextAvailableElementPlug(inPlug) if isinstance(p, om2.MPlug): plugs.connectPlugs(p, child) continue plugs.setPlugValue(child, p) if output is not None: ouPlug = fn.findPlug("output2D", False) for index, out in enumerate(output): if out is None: continue plugs.connectPlugs(ouPlug, out) return pma
def conditionVector(firstTerm, secondTerm, colorIfTrue, colorIfFalse, operation, name): """ :param firstTerm: :type firstTerm: om2.MPlug or float :param secondTerm: :type secondTerm: om2.MPlug or float :param colorIfTrue: seq of MPlugs or a single MPlug(compound) :type colorIfTrue: om2.MPlug or list(om2.Plug) or om2.MVector :param colorIfFalse: seq of MPlugs or a single MPlug(compound) :type colorIfFalse: om2.MPlug or list(om2.Plug) or om2.MVector :param operation: the comparsion operator :type operation: int :param name: the new name for the node :type name: str :return: :rtype: om2.MObject """ condNode = om2.MFnDependencyNode(nodes.createDGNode(name, "condition")) if isinstance(firstTerm, float): plugs.setPlugValue(condNode.findPlug("firstTerm", False), firstTerm) else: plugs.connectPlugs(firstTerm, condNode.findPlug("firstTerm", False)) if isinstance(operation, int): plugs.setPlugValue(condNode.findPlug("operation", False), operation) else: plugs.connectPlugs(operation, condNode.findPlug("operation", False)) if isinstance(secondTerm, float): plugs.setPlugValue(condNode.findPlug("secondTerm", False), firstTerm) else: plugs.connectPlugs(secondTerm, condNode.findPlug("secondTerm", False)) if isinstance(colorIfTrue, om2.MPlug): plugs.connectPlugs(colorIfTrue, condNode.findPlug("colorIfTrue", False)) elif isinstance(colorIfTrue, om2.MVector): plugs.setPlugValue(condNode.findPlug("colorIfTrue", False), colorIfTrue) else: color = condNode.findPlug("colorIfTrue", False) # expecting seq of plugs for i, p in enumerate(colorIfTrue): child = color.child(i) plugs.connectPlugs(p, child) if isinstance(colorIfFalse, om2.MPlug): plugs.connectPlugs(colorIfFalse, condNode.findPlug("colorIfFalse", False)) elif isinstance(colorIfFalse, om2.MVector): plugs.setPlugValue(condNode.findPlug("colorIfFalse", False), colorIfFalse) else: color = condNode.findPlug("colorIfFalse", False) # expecting seq of plugs for i, p in enumerate(colorIfFalse): child = color.child(i) plugs.connectPlugs(p, child) return condNode.object()
def _createInScene(self, node, name): if node is None: name = "_".join([name or self.__class__.__name__, "meta"]) node = nodes.createDGNode(name, "network") self._handle = om2.MObjectHandle(node) if node.hasFn(om2.MFn.kDagNode): self._mfn = om2.MFnDagNode(node) else: self._mfn = om2.MFnDependencyNode(node)
def distanceBetween(firstNode, secondNode, name): """Creates a distance between node and connects the 'firstNode' and 'secondNode' world space matrices. :param firstNode: The start transform node :type firstNode: MObject :param secondNode: The second transform node :type secondNode: MObject :return: the Three nodes created by the function in the form of a tuple, the first element is the distance between node, the second is the start node decompose matrix, the third element is the second node decompose matrix :rtype: tuple(om2.MObject, om2.MObject, om2.MObject) """ firstFn = om2.MFnDependencyNode(firstNode) secondFn = om2.MFnDependencyNode(secondNode) distanceBetweenNode = nodes.createDGNode(name, "distanceBetween") distFn = om2.MFnDependencyNode(distanceBetweenNode) firstFnWorldMat = firstFn.findPlug("worldMatrix", False) firstFnWorldMat.evaluateNumElements() secondFnWorldMat = secondFn.findPlug("worldMatrix", False) secondFnWorldMat.evaluateNumElements() startDecomposeMat = nodes.createDGNode( "_".join([firstFn.name(), secondFn.name(), "start_decomp"]), "decomposeMatrix") endDecomposeMat = nodes.createDGNode( "_".join([firstFn.name(), secondFn.name(), "end_decomp"]), "decomposeMatrix") startDecomFn = om2.MFnDependencyNode(startDecomposeMat) endDecomFn = om2.MFnDependencyNode(endDecomposeMat) plugs.connectPlugs(firstFnWorldMat.elementByPhysicalIndex(0), startDecomFn.findPlug("inputMatrix", False)) plugs.connectPlugs(secondFnWorldMat.elementByPhysicalIndex(0), endDecomFn.findPlug("inputMatrix", False)) plugs.connectPlugs(startDecomFn.findPlug("outputTranslate", False), distFn.findPlug("point1", False)) plugs.connectPlugs(endDecomFn.findPlug("outputTranslate", False), distFn.findPlug("point2", False)) return distanceBetweenNode, startDecomposeMat, endDecomposeMat
def floatMath(floatA, floatB, operation, name): floatMathFn = om2.MFnDependencyNode(nodes.createDGNode(name, "floatMath")) if isinstance(floatA, om2.MPlug): plugs.connectPlugs(floatA, floatMathFn.findPlug("floatA", False)) else: plugs.setPlugValue(floatMathFn.findPlug("floatA", False), floatA) if isinstance(floatB, om2.MPlug): plugs.connectPlugs(floatB, floatMathFn.findPlug("floatB", False)) else: plugs.setPlugValue(floatMathFn.findPlug("floatB", False), floatB) plugs.setPlugValue(floatMathFn.findPlug("operation", False), operation) return floatMathFn.object()
def createMultMatrix(name, inputs, output): multMatrix = nodes.createDGNode(name, "multMatrix") fn = om2.MFnDependencyNode(multMatrix) plugs.connectPlugs(fn.findPlug("matrixSum", False), output) compound = fn.findPlug("matrixIn", False) compound.evaluateNumElements() for i in xrange(len(inputs)): inp = inputs[i] if isinstance(inp, om2.MPlug): plugs.connectPlugs(inp, compound.elementByLogicalIndex(i)) continue plugs.setPlugValue(compound.elementByLogicalIndex(i), inp) return multMatrix
def blendColors(color1, color2, name, blender): blendFn = om2.MFnDependencyNode(nodes.createDGNode(name, "blendColors")) if isinstance(color1, om2.MPlug): plugs.connectPlugs(color1, blendFn.findPlug("color1", False)) else: plugs.setPlugValue(blendFn.findPlug("color1", False), color1) if isinstance(color2, om2.MPlug): plugs.connectPlugs(color2, blendFn.findPlug("color2", False)) else: plugs.setPlugValue(blendFn.findPlug("color2", False), color2) if isinstance(blender, om2.MPlug): plugs.connectPlugs(blender, blendFn.findPlug("blender", False)) else: plugs.setPlugValue(blendFn.findPlug("blender", False), blender) return blendFn.object()
def createReverse(name, inputs, outputs): """ Create a Reverse Node :param name: The name for the reverse node to have, must be unique :type name: str :param inputs: If Plug then the plug must be a compound. :type inputs: om2.MPlug or tuple :param outputs: If Plug then the plug must be a compound. :type outputs: om2.MPlug or tuple :return: OpenMaya 2.0 MObject representing the reverse node :rtype: om2.MObject :raises: ValueError if the inputs or outputs is not an om2.MPlug """ rev = nodes.createDGNode(name, "reverse") fn = om2.MFnDependencyNode(rev) inPlug = fn.findPlug("input", False) ouPlug = fn.findPlug("output", False) if isinstance(inputs, om2.MPlug): if inputs.isCompound: plugs.connectPlugs(inputs, inPlug) return rev else: raise ValueError( "Inputs Argument must be a compound when passing a single plug" ) elif isinstance(outputs, om2.MPlug): if outputs.isCompound: plugs.connectPlugs(outputs, ouPlug) return rev else: raise ValueError( "Outputs Argument must be a compound when passing a single plug" ) # passed the dealings with om2.MPlug so deal with seq type for childIndex in range(len(inputs)): inA = inputs[childIndex] if inA is None: continue plugs.connectPlugs(inputs[childIndex], inPlug.child(childIndex)) for childIndex in range(len(outputs)): inA = outputs[childIndex] if inA is None: continue plugs.connectPlugs(ouPlug.child(childIndex), outputs[childIndex]) return rev
def createPlusMinusAverage3D(name, inputs, output=None, operation=1): """ Create's a plusMinusAverage node and connects the 3D inputs and outputs. :param name: the plus minus average node name. :type name: str :param inputs: tuple of MPlugs and/or float values, each value will be applied to / a new Input3D element. If the value is MPlug then it will be connected. :type inputs: iterable(plug or float) :param output: A tuple of downstream MPlugs to connect to. :type output: iterable(plug) or None :return: The plus minus average MObject. :rtype: om2.MObject .. code-block:: python one = nodes.createDagNode("one", "transform") two = nodes.createDagNode("two", "transform") end = nodes.createDagNode("end", "transform") oneFn = om2.MFnDagNode(one) twoFn = om2.MFnDagNode(two) endFn = om2.MFnDagNode(end) inputs = [oneFn.findPlug("translate", False), twoFn.findPlug("translate", False)] outputs = [endFn.findPlug("translate", False)] pma = creation.createPlusMinusAverage3D("test_pma", inputs, outputs) # Result: <OpenMaya.MObject object at 0x000002AECB23AE50> # """ pma = nodes.createDGNode(name, "plusMinusAverage") fn = om2.MFnDependencyNode(pma) inPlug = fn.findPlug("input3D", False) fn.findPlug("operation", False).setInt(operation) for i, p in enumerate(inputs): if p is None: continue child = plugs.nextAvailableElementPlug(inPlug) if isinstance(p, om2.MPlug): plugs.connectPlugs(p, child) continue plugs.setPlugValue(child, p) if output is not None: ouPlug = fn.findPlug("output3D", False) for index, out in enumerate(output): if out is None: continue plugs.connectPlugs(ouPlug, out) return pma
def createDecompose(name, destination, translateValues, scaleValues, rotationValues, inputMatrixPlug=None): """Creates a decompose node and connects it to the destination node. :param name: the decompose Matrix name. :type name: str :param destination: the node to connect to :type destination: om2.MObject :param translateValues: the x,y,z to apply must have all three if all three are true then the compound will be \ connected. :type translateValues: list(str) :param scaleValues: the x,y,z to apply must have all three if all three are true then the compound will be \ connected. :type scaleValues: list(str) :param rotationValues: the x,y,z to apply must have all three if all three are true then the compound will be \ connected. :type rotationValues: list(str) :param inputMatrixPlug: The input matrix plug to connect from. :type inputMatrixPlug: om2.MPlug :return: the decompose node :rtype: om2.MObject """ decompose = nodes.createDGNode(name, "decomposeMatrix") mfn = om2.MFnDependencyNode(decompose) if inputMatrixPlug is not None: plugs.connectPlugs(inputMatrixPlug, mfn.findPlug("inputMatrix", False)) if destination: destFn = om2.MFnDependencyNode(destination) # translation plugs.connectVectorPlugs(mfn.findPlug("outputTranslate", False), destFn.findPlug("translate", False), translateValues) plugs.connectVectorPlugs(mfn.findPlug("outputRotate", False), destFn.findPlug("rotate", False), rotationValues) plugs.connectVectorPlugs(mfn.findPlug("outputScale", False), destFn.findPlug("scale", False), scaleValues) return decompose
def pairBlend(name, inRotateA=None, inRotateB=None, inTranslateA=None, inTranslateB=None, weight=None, rotInterpolation=None): blendPairNode = om2.MFnDependencyNode(nodes.createDGNode( name, "pairBlend")) if inRotateA is not None: plugs.connectPlugs(inRotateA, blendPairNode.findPlug("inRotate1", False)) if inRotateB is not None: plugs.connectPlugs(inRotateB, blendPairNode.findPlug("inRotate2", False)) if inTranslateA is not None: plugs.connectPlugs(inTranslateA, blendPairNode.findPlug("inTranslate1", False)) if inTranslateB is not None: plugs.connectPlugs(inTranslateB, blendPairNode.findPlug("inTranslate2", False)) if weight is not None: if isinstance(weight, om2.MPlug): plugs.connectPlugs(weight, blendPairNode.findPlug("weight", False)) else: plugs.setPlugValue(blendPairNode.findPlug("weight", False), weight) if rotInterpolation is not None: if isinstance(rotInterpolation, om2.MPlug): plugs.connectPlugs( rotInterpolation, blendPairNode.findPlug("rotInterpolation", False)) else: plugs.setPlugValue( blendPairNode.findPlug("rotInterpolation", False), rotInterpolation) return blendPairNode.object()
def test_createDGNode(self): node = nodes.createDGNode("new", "network") self.assertIsInstance(node, om2.MObject)
def createSetRange(name, value, min_, max_, oldMin, oldMax, outValue=None): """ Generates and connects a setRange node. input/output arguments take an iterable, possibles values are om2.MPlug, float or None. if a value is None it will be skipped this is useful when you want some not connected or set to a value but the other is left to the default state. If MPlug is passed and its a compound it'll be connected. :param name: the new name for the set Range node :type name: str :param value: :type value: iterable(om2.MPlug or float or None) :param min_: :type min_: iterable(om2.MPlug or float or None) :param max_: :type max_: iterable(om2.MPlug or float or None) :param oldMin: :type oldMin: iterable(om2.MPlug or float or None) :param oldMax: :type oldMax: iterable(om2.MPlug or float or None) :param outValue: :type outValue: iterable(om2.MPlug or float or None) :return: the created setRange node :rtype: om2.MObject .. code-block:: python one = nodes.createDagNode("one", "transform") two = nodes.createDagNode("two", "transform") end = nodes.createDagNode("end", "transform") oneFn = om2.MFnDagNode(one) twoFn = om2.MFnDagNode(two) endFn = om2.MFnDagNode(end) values = [oneFn.findPlug("translate", False)] min_ = [twoFn.findPlug("translate", False)] max_ = [twoFn.findPlug("translate", False)] oldMax = [0.0,180,360] oldMin = [-10,-720,-360] reload(creation) outValues = [endFn.findPlug("translateX", False), endFn.findPlug("translateY", False), None] pma = creation.createSetRange("test_pma", values, min_, max_, oldMin, oldMax, outValues) """ setRange = nodes.createDGNode(name, "setRange") fn = om2.MFnDependencyNode(setRange) valuePlug = fn.findPlug("value", False) oldMinPlug = fn.findPlug("oldMin", False) oldMaxPlug = fn.findPlug("oldMax", False) minPlug = fn.findPlug("min", False) maxPlug = fn.findPlug("max", False) # deal with all the inputs # source list, destination plug for source, destination in ((value, valuePlug), (min_, minPlug), (max_, maxPlug), (oldMin, oldMinPlug), (oldMax, oldMaxPlug)): if source is None: continue for index, inner in enumerate(source): if inner is None: continue elif isinstance(inner, om2.MPlug): if inner.isCompound: plugs.connectPlugs(inner, destination) break child = destination.child(index) plugs.connectPlugs(inner, child) continue child = destination.child(index) plugs.setPlugValue(child, inner) if outValue is None: return setRange outPlug = fn.findPlug("outValue", False) # now the outputs for index, out in enumerate(outValue): if out is None: continue if isinstance(out, om2.MPlug): if out.isCompound: plugs.connectPlugs(outPlug, out) break child = outPlug.child(index) plugs.connectPlugs(child, out) continue child = outPlug.child(index) # not a plug must be a plug value plugs.setPlugValue(child, out) return setRange