.. include:: ../subst.rst The Pre-deprecated API ====================== What Do You Mean, Pre-Deprecated? --------------------------------- API design is famously difficult, and once an API has been made public it is bad form to make breaking changes to it. We want to provide an initial API that will allow users to do necessary scripting with Contour, but we also plan on creating a more comprehensive, and hopefully more elegant, API in the future. Pre-deprecated may be a bit of a misnomer---we plan to support this API indefinitely, and while we do not absolutely promise not to make breaking changes to it we will avoid doing so without a very compelling reason. The pre-deprecated API is small, but provides what we think users will need to script Contour effectively. If you need functionality it doesn't provide, please get in touch with us at support@notionalpipe.com. Because it might be some time before we introduce a newer API we plan on expanding this one as needed. There are also some useful internal functions that we can expose, though it is very likely that we will make breaking changes to those. General Considerations ---------------------- It is important to use our functions, where we have provided them, to create and delete our nodes, as the connections between joint chains, meshes, deformers, etc. are complicated and finicky. Creating nodes with incorrect connections, or deleting nodes without properly adjusting connections, is likely to lead to errors in graph evaluation. Importing and Calling the API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The API's namespace is Contourlib.predeprecatedAPI. So you could import the API and call one of its functions like this: .. code-block:: python import Contourlib.predeprecatedAPI as api api.createJointSocketAndJoint() Arguments and Return Types ~~~~~~~~~~~~~~~~~~~~~~~~~~ Data Types ########## API functions that take Maya nodes as arguments accept PyNodes, MObjects (either OM1 or OM2,) or the names of the nodes as strings. When passing the names of DAG nodes as strings, enough of the path to uniquely identify the node must be present in the name. Functions that take geometric types, such as vectors, euler rotations, and quaternions, generally accept PyMEL data types from the pymel.core.dt namespace as well as OpenMaya data types. API functions that return Maya nodes return them as PyNodes. Referring to Joint Chains and Splines ##################################### API functions that take an argument that refers to a joint chain, or to the spline that joint chain generates, take the chain's Joint Socket as an argument. Note that this applies when passing joint chains as influences to be bound to a Contour deformer. Referring to Meshes ################### API functions that take a mesh as an argument accept either the mesh (as a PyNode, an MObject, or a string) or the Contour deformer that deforms the mesh (as a PyNode, an MObject, or a string.) Exceptions ~~~~~~~~~~ The API functions can throw a number of custom exceptions, documented in the descriptions of individual functions. Note that while we check for many exceptional situations it is also possible for the API functions to throw exceptions raised by code in Maya libraries called from those functions. All custom exceptions raised by API functions inherit from ContourScriptError. All custom exceptions that can be raised by the API come from the Contourlib.scripts.exceptions namespace. Caveats ~~~~~~~ Creating and Deleting Contour Shape Nodes in a Single Cycle ########################################################### Creating a Contour node that has a shape node, and then immediately deleting it within the same cycle, will cause the shape node to continue to be drawn when using Viewport 2.0. Saving and re-opening the scene will fix this, but to avoid it when scripting you can call the refresh function from the maya.cmds namespace or PyMEL between creating and deleting the node. Creating, Deleting, and Duplicating Contour Joint Chains -------------------------------------------------------- .. function:: createJointSocketAndJoint(\ translation=pymel.core.dt.Vector.zero, \ rotation=pymel.core.dt.EulerRotation.identity, \ parent=None, \ jointSocketName=None, \ jointName=None, \ boneAxis="x") Creates a joint socket and joint :arg translation: the world-space position of the joint socket, as a PyMEL vector, an OpenMaya vector, or a 3-tuple :arg rotation: the world-space rotation of the joint socket, as a PyMEL Euler rotation, a PyMEL quaternion, or a 3-tuple representing an Euler rotation :arg parent: the parent of the joint socket, |api-argument-node-types-description-or-none| :arg jointSocketName: the name of the joint socket, or None to have the API assign a default name :arg jointName: the name of the joint, or None to have the API assign a default name :arg boneAxis: the bone axis of the joint chain, one of "x", "y", "z", "-x", "-y", or "-z" :returns: a tuple containing the newly created joint socket and joint, i.e. (jointSocket, joint), as PyNodes :raises: **ContourBadArgumentsError**: Translation or rotation is not a value that can be used to set translation or rotation using the set function of a PyMEL PyAttribute, or parent is not a Maya node, or is not a transform, or boneAxis is not one of "x", "y", "z", "-x", "-y", or "-z". .. function:: createJointInChain(\ previousJoint, \ boneLength=5.0, \ jointOrient=pymel.core.dt.EulerRotation.identity, \ jointName=None, \ boneName=None) Creates a bone and a joint following previousJoint in the joint chain :arg previousJoint: the joint after which to create the new joint and bone, |api-argument-node-types-description| :arg boneLength: the length of the bone to be created :arg jointOrient: the orientation of the joint, as a PyMEL Euler rotation, a PyMEL quaternion, a 3-tuple representing an Euler rotation, or None :arg jointName: the name of the joint, or None to have the API assign a default name :arg boneName: the name of the bone, or None to have the API assign a default name :returns: a tuple containing the newly created joint and bone, i.e. (joint, bone), as PyNodes :raises: **ContourBadArgumentsError**: previousJoint is not a maya node, or is not a ContourJoint. **ContourDegenerateSceneGraphError**: The joint chain previousJoint belongs to is not correctly connected. .. function:: deleteJointInChain(joint) Deletes joint, its distal bone, and any bone CVs that apply to that bone. Adjusts as many as two proximal bones such that all distal joints and bones maintain their world position when the joint chain is in its zeroed out state. :arg joint: the joint to delete, |api-argument-node-types-description| :returns: None :raises: **ContourBadArgumentsError**: Joint is not a Maya node, or is not a ContourJoint. **ContourDegenerateSceneGraphError**: The joint chain joint belongs to is not correctly connected. .. function:: createBoneCV(jointOrBoneCV) Creates a bone CV after jointOrBoneCV :arg jointOrBoneCV: the joint or bone CV after which to create the new bone CV, |api-argument-node-types-description| :returns: the newly created bone CV, as a PyNode :raises: **ContourBadArgumentsError**: jointOrBoneCV is not a Maya node, or is not a ContourJoint or a ContourBoneCV. **ContourDegenerateSceneGraphError**: The joint chain jointOrBoneCV belongs to is not correctly connected .. function:: deleteBoneCV(boneCV) Deletes boneCV :arg boneCV: the bone CV to delete, |api-argument-node-types-description| :returns: None :raises: **ContourBadArgumentsError**: boneCV is not a Maya node, or is not a ContourBoneCV **ContourDegenerateSceneGraphError**: The joint chain boneCV belongs to is not correctly connected. .. function:: duplicateJointChain(jointSocket) Duplicates jointSocket, its bone chain, and any descendant bone chains. Returns the newly created joint socket corresponding to jointSocket. :arg jointSocket: the joint socket of the joint chain to be duplicated, |api-argument-node-types-description| :returns: the joint socket at the root of the newly created chain, as a PyNode :raises: **ContourBadArgumentsError**: jointSocket is not a Maya node, or is not a ContourJointSocket. **ContourDegenerateSceneGraphError**: The joint chain jointSocket belongs to is not correctly connected. Creating Contour Constraints ---------------------------- .. function:: createDeformFieldConstraint(jointSocket, transform) Given a joint socket and a transform node, creates a Contour constraint that constrains the transform to the joint chain :arg jointSocket: the joint socket of the joint chain to constrain to, |api-argument-node-types-description| :arg transform: the transform to be constrained, |api-argument-node-types-description| :returns: the newly created constraint, as a PyNode :raises: **ContourBadArgumentsError**: jointSocket is not a Maya node, or is not a ContourJointSocket, or transform is not a Maya node, or is not a transform. **ContourDegenerateSceneGraphError**: The joint chain jointSocket belongs to is not correctly connected. **ContourUnbindableInfluenceError**: The joint chain jointSocket belongs to contains only one joint, and cannot be constrained to. .. function:: createSplineConstraint(jointSocket, transform) Given a joint socket and a transform node, creates a Contour Spline constraint that constrains the transform to the Contour spline corresponding to the joint socket :arg jointSocket: the joint socket of the spline to constrain to, |api-argument-node-types-description| :arg transform: the transform to be constrained, |api-argument-node-types-description| :returns: the newly created constraint, as a PyNode :raises: **ContourBadArgumentsError**: jointSocket is not a Maya node, or is not a ContourJointSocket, or transform is not a Maya node, or is not a transform. **ContourDegenerateSceneGraphError**: The joint chain jointSocket belongs to is not correctly connected. **ContourNoSplineError**: The joint chain jointSocket belongs to contains only one joint and cannot be constrained to. **ContourDegenerateSplineError**: The joint chain jointSocket belongs to is connected to a Contour spline node that does not correctly output a spline. Creating and Deleting Contour IK Systems ---------------------------------------- .. function:: createIKSystem(\ firstTransform, \ secondTransform, \ thirdTransform, \ ikHandle=None, \ poleVector=None, \ useOverride=True, \ createConstraint=True, \ allowUnstretchableTransforms) Creates an IK system from three transforms and an optional ik handle and pole vector :arg firstTransform: the first transform of the system (e.g. a shoulder), |api-argument-node-types-description|. This can be any transform other than a Maya joint. :arg secondTransform: the second transform of the system (e.g. an elbow), |api-argument-node-types-description|. This can be any transform other than a Maya joint. :arg thirdTransform: the third transform of the system (e.g. a hand or wrist), |api-argument-node-types-description|. This can be any transform other than a Maya joint. :arg ikHandle: the node to be used as the IK handle of the system, |api-argument-node-types-description|, or None to create a new locator :arg poleVector: the node to be used as the pole vector of the system, |api-argument-node-types-description|, or None to create a new locator :arg useOverride: if True, connects the IK system to the overrideRotation attributes of the first two transforms, instead of the rotation attribute, if they are CountourJoints :arg createConstraint: if True, constrains the third transform to the IK handle using an orient constraint :arg allowUnstretchableTransforms: If False, a ContourIKUnstretchableTransformError will be raised if the IK system would contain transforms that might break autostretch. If True, the IK system will be created even in their presence. See the Raises section for details. :returns: a tuple containing the IK handle, the pole vector, and the ContourIKSolver node, as PyNodes :raises: **ContourBadArgumentsError**: Any of firstTransform, secondTransform, thirdTransform, poleVector, or IKHandle is not a Maya node, or is not a transform, or firstTransform, secondTransform, or thirdTransform is a Maya joint. **ContourIKNodeNotConnectableError**: Any of the attributes that would be connected when making the IK system is not connectable. **ContourIKUnstretchableTransformError**: The IK system would contain transforms other than Contour bones that have translation, the system would have autostretch, and allowUnstretchableTransforms is False. **ContourIKHierarchyError**: secondTransform is not a descendant of firstTransform, thirdTransform is not a descendant of secondTransform, or ikHandle or poleVector is a descendant of firstTransform. **ContourIKCollinearityError**: firstTransform, secondTranform, and thirdTransform are collinear. .. function:: deleteIKSystem(IKHandleOrSolver) Deletes an IK system's handle, pole vector, and solver, given its IK handle or solver :arg IKHandleOrSolver: The IK Handle or IK Solver of the IK system to be deleted, as a name, a PyNode, or an MObject. If a node that is the IK Handle of more than one IK system is passed as this argument, all of the systems it is the IK Handle of will be deleted. :returns: None :raises: **ContourBadArgumentsError**: IKHandleOrSolver is not the IK handle or solver of a Contour IK system. Creating and Deleting Aim Handles --------------------------------- .. function:: createAimHandle(joint, upVector=None) *Added in Contour Rig Tools v1.0.6.1* Creates an aim handle for a Contour Joint. :arg joint: the joint to create an aim handle for, as a name, a PyNode, or an MObject. Joint must have a ContourBone somewhere above it in the DAG hierarchy. :arg upVector: if truthy, an upVector will be created :returns: a tuple of the newly created aim handle and the up vector, as PyNodes. If an up vector was not created, None will be returned for the up vector. :raises: **ContourBadArgumentsError**: joint is not a ContourJoint, or joint does not have a ContourBone somewhere above it in the DAG hierarchy **ContourMayaPluginNotFoundError**: The "matrixNodes" plug-in could not be loaded. Creation of aim handles requires that the "matrixNodes" plug-in, which ships with Maya, be loaded. We attempt to load it if is not loaded. This exception is thrown if it cannot be loaded. .. function:: deleteAimHandle(handle) *Added in Contour Rig Tools v1.0.6.1* Deletes an aim handle, and associated nodes, with the exception of the buffers. The aim system must be connected "canonically"-- that is, as our tools connect it when creating aim handles and their systems. If the system's connections have been altered an exception will be raised, and the system will not be deleted. :arg handle: the handle of the aim system to be deleted, as a name, a PyNode, or an MObject. :returns: None :raises: **ContourBadArgumentsError**: handle is not an aim handle associated with a canonically connected aim system. Creating and Deleting Orients ----------------------------- .. function:: createOrient(driver, targetJoint) *Added in Contour Rig Tools v1.0.6.1* Creates an orient for a Contour Joint. :arg driver: the transform whose world-space orientation the targetJoint will take on, as a name, a PyNode, or an MObject. :arg targetJoint: The Contour Joint to be oriented :returns: a tuple containing driver and targetJoint, as PyNodes :raises: **ContourBadArgumentsError**: Driver is not a transform, or targetJoint is not a Contour Joint. **ContourMayaPluginNotFoundError**: The "matrixNodes" plug-in could not be loaded. Creation of orients requires that the "matrixNodes" plug-in, which ships with Maya, be loaded. We attempt to load it if is not loaded. This exception is thrown if it cannot be loaded. .. function:: deleteOrient(joint) *Added in Contour Rig Tools v1.0.6.1* Deletes a Contour Orient. The orient must be connected "canonically"-- that is, as our tools connect it when creating orients. If the orient's connections have been altered an exception will be raised, and the orient will not be deleted. :arg handle: the Contour Joint associated with the orient to be deleted, as a name, a PyNode, or an MObject. :returns: None :raises: **ContourBadArgumentsError**: joint is not a Contour Joint associated with a canonically connected orient. Binding, Rebinding, and Unbinding --------------------------------- .. function:: bindMeshToDeformer(mesh, influences, bindDescendantChains=False) Binds influences to mesh, creating a new ContourDeformer :arg mesh: the mesh to bind, or its transform, |api-argument-node-types-description| :arg influences: the influences to bind, |api-argument-node-types-description-plural| If an influence is a joint socket, its Contour chain will be bound. Chains with zero radius and chains with only one joint cannot be bound. Contour nodes other than joint sockets cannot be bound. Any transform that is not a Contour node will be bound as a rigid influence. :arg bindDescendantChains: if truthy, will also bind all Contour joint chains that are descendants of any of the influences. *Added in v1.0.7* :returns: the newly created deformer, as a PyNode :raises: **ContourBadArgumentsError**: The mesh or at least one of the influences is not a Maya node, or mesh is not a mesh or the transform of a single mesh. **ContourMeshAlreadyBoundError**: Mesh is already bound to a Contour deformer. **ContourRepeatedInfluenceError**: An influence appears more than once in influences. **ContourUnbindableInfluenceError**: An influence could not be bound for one of the following reasons: * Only transforms can be bound. * Contour nodes other than joint sockets cannot be bound. * A joint chain with less than two joints, or with zero radius, cannot be bound. .. function:: resetBind(influenceOrSpline) Resets the bind position of the joint chain associated with a joint socket or spline to its current position, or resets the bind position of a rigid influence to its current position :arg influenceOrSpline: a bound Contour spline, a bound Contour joint socket, or a transform bound to a Contour deformer as a rigid influence, |api-argument-node-types-description|. If node is a joint socket or spline, resets the bind position of the corresponding Contour joint chain. If node is a rigid influence, resets the bind position of the influence to its current position. :returns: None :raises: **ContourBadArgumentsError**: influenceOrSpline is not a Maya node, or is not either a rigid influence of a Contour deformer, or a joint socket or Contour spline that is an influence of a Contour deformer or a deform field constraint. **ContourDegenerateSceneGraphError**: A joint socket or spline was passed as influenceOrSpline, and its scene graph is not correctly connected. .. function:: addInfluencesToDeformer(meshOrDeformer, influences) Adds influences to a ContourDeformer :arg meshOrDeformer: either the deformer to add influences to, or the mesh deformed by it, |api-argument-node-types-description| :arg influences: the influences to add, |api-argument-node-types-description-plural|. If an influence is a joint socket, its Contour chain will be added. Chains with zero radius and chains with only one joint cannot be added. Contour nodes other than joint sockets cannot be added. Any transform that is not a Contour node will be added as a rigid influence. :returns: None :raises: **ContourBadArgumentsError**: meshOrDeformer or at least one of member of influences is not a Maya node, or meshOrDeformer is not a mesh, the transform of a single mesh, or a ContourDeformer. **ContourRepeatedInfluenceError**: An influence appears more than once in influences. **ContourUnbindableInfluenceError**: An influence could not be added for one of the following reasons: * Only transforms can be added. * Contour nodes other than joint sockets cannot be added. * A joint chain with less than two joints, or with zero radius, cannot be added. * An influence that is already bound to the deformer cannot be added. .. function:: removeInfluencesFromDeformer(meshOrDeformer, influences) Removes influences from a ContourDeformer :arg meshOrDeformer: either the deformer to remove influences from, or the mesh or mesh's transform, |api-argument-node-types-description| :arg influences: the influences to remove, |api-argument-node-types-description-plural| :returns: None :raises: **ContourBadArgumentsError**: meshOrDeformer or at least one member of influences is not a Maya node, or meshOrDeformer is not a mesh, the transform of a single mesh, or a Contour deformer, or a member of influences is not an influence of the deformer. **ContourRepeatedInfluenceError**: An influence appears more than once in influences. Contour Deformer Weights ------------------------ .. function:: getWeightsUsingInfluenceIndices(meshOrDeformer, vertexIndices=None, influenceIndices=None) Returns weight values for meshOrDeformer, with influences specified by index. If vertexIndices is not supplied, returns weight values for all vertices, otherwise returns only weights for the given vertex indices. If influenceIndices is not supplied, returns weight values for all influences. :arg meshOrDeformer: either the deformer to get weights from, or the mesh or mesh's transform, |api-argument-node-types-description| :arg vertexIndices: the indices of the vertices for which to get weights, as an iterable of integers, or None to get weights for all vertices :arg influenceIndices: the indices of the influences for which to get weights, as an iterable of integers, or None to get weights for all influences :returns: a dictionary of dictionaries, the outer keyed on vertex index, the inner on influence index, with the values of the inner dictionary the weights :raises: **ContourBadArgumentsError**: meshOrDeformer is not a Maya node, or meshOrDeformer is not a mesh, the transform of a single mesh, or a ContourDeformer, or vertexIndices or influenceIndices is not an iterable or contains invalid indices. .. function:: getWeightsUsingInfluenceNames(meshOrDeformer, vertexIndices=None, influences=None) Returns weight values for meshOrDeformer, with influences specified by name. If vertexIndices is not supplied, returns weight values for all vertices, otherwise returns only weights for the given vertex indices. If influenceNames is not supplied, returns weight values for all influences. :arg meshOrDeformer: either the deformer to get weights for, or the mesh or mesh's transform, |api-argument-node-types-description| :arg vertexIndices: the indices of the vertices for which to get weights, as an iterable of integers, or None to get weights for all vertices :arg influences: the names of the influences for which to get weights, as an iterable of strings, or None to get weights for all influences :returns: a dictionary of dictionaries, the outer keyed on vertex index, the inner on influence name, with the values of the inner dictionary the weights :raises: **ContourBadArgumentsError**: meshOrDeformer is not a Maya node, or meshOrDeformer is not a mesh, the transform of a single mesh, or a ContourDeformer, or vertexIndices or influenceIndices is not an iterable, or vertexIndices contains invalid indices, or influenceNames contains invalid names. .. function:: setWeights(meshOrDeformer, weights, normalize=True) Sets weights on meshOrDeformer. Weights is a dictionary keyed on vertex index. Its values are dicts keyed on either influence names or influence indices, but not both, whose values are weights. The format setWeights accepts is the same as that returned by getWeightsUsingInfluenceIndices. :arg meshOrDeformer: either the deformer to get weights for, or the mesh or mesh's transform, |api-argument-node-types-description| :arg weights: a dictionary keyed on vertex index, its values dicts keyed on either influence names, or influence indices, but not both, whose values are weights :arg normalize: if truthy, the weights will be normalized after being set :returns: None :raises: **ContourBadArgumentsError**: meshOrDeformer is not a Maya node, or meshOrDeformer is not a mesh, the transform of a single mesh, or a ContourDeformer, or weights contains keys that are not valid vertex indices or the values of weights contain keys that are not valid influence indices or influence names, or the values of weights contain both influence names and influence indices as keys. TypeError: a weight value is not an integer, a floating point number, or something that can be coerced to a floating point number. .. function:: copyWeights(sourceMeshOrDeformer, targetMeshOrDeformer, association="closest_influence", destVertices=None) Copies weights for a ContourDeformer from sourceMeshOrDeformer to targetMeshOrDeformer :arg sourceMeshOrDeformer: either the deformer to copy weights from, or the mesh or mesh's transform, |api-argument-node-types-description| :arg targetMeshOrDeformer: either the deformer to copy weights to, or the mesh or mesh's transform, |api-argument-node-types-description| :arg association: The method used to associate influences of the source and target deformers; one of "closest_influence" or "same_influence". If "closest_influence", each source influence will be associated with the closest target influence, in world space. If "same_influence", each influence of the source deformer must be an influence of the target deformer, and the association will be made by identity. :arg destVertices: An iterable of vertex indices or PyMel MeshVertex instances indicating the vertices of the destination mesh to copy to. If None, all vertices on the destination mesh will be copied to. Defaults to None. :returns: None :raises: **ContourBadArgumentsError**: sourceMeshOrDeformer or targetMeshOrDeformer is not a Maya node, or is not a mesh, the transform of a single mesh, or a ContourDeformer, or association is not one of "closest_influence" or "same_influence", , or destVertices is not either None, or an iterable of vertex indices or PyMel MeshVertexIndices, or destVertices contains vertices that do not belong to targetMeshOrDeformer. **ContourNoCorrespondingInfluenceError**: If association is "closest_influence", either the source deformer or the target deformer has no influences. If association is "same_influence", at least one influence of the source deformer is not an influence of the target deformer. .. function:: mirrorWeights(meshOrDeformer, axis="x", negativeToPositive=False, association="closest_influence", destVertices=None) Mirrors deformer weights across axis :arg sourceMeshOrDeformer: either the deformer to mirror weights for, or the mesh or mesh's transform, |api-argument-node-types-description| :arg axis: The world axis to mirror weights across. One of "x", "y", or "z". :arg negativeToPositive: If truthy, mirrors weights from the negative side of the axis to the positive. Otherwise, mirrors from the positive side of the axis to the negative. :arg association: The method used to associate influences when mirroring. One of "closest_influence" or "equivalent_name". If "closest_influence", each influence will be associated with the influence closest to its position mirrored across axis (which could be the influence itself). If "equivalent_name", each of the deformer's influences whose names begin with "right\_", "right", or "r\_" will be associated with an influence that begins with "left\_", "left", or "l\_", if both names, when stripped of their prefixes are the same, and vice versa. If an influence does not have a name with a prefix, or if no corresponding influence is found, the influence's weights will be mirrored to itself. If an influence could be associated with more than one other influence, for instance, if there is an influence named "right_arm", and influences named "left_arm" and "l_arm", ContourAmbiguousNameAssociationError will be raised. :arg destVertices: An iterable of vertex indices or PyMel MeshVertex instances indicating the vertices of the destination mesh to copy to. If None, all vertices on the destination mesh will be copied to. Defaults to None. :returns: None :raises: **ContourBadArgumentsError**: meshOrDeformer is not a Maya node, or is not a mesh, the transform of a single mesh, or a ContourDeformer, or axis is not one of "x", "y", or "z", or association is not one of "closest_influence" or "equivalent_name", or destVertices contains vertices that do not belong to meshOrDeformer. **ContourNoCorrespondingInfluenceError**: The deformer has no influences. **ContourAmbiguousNameAssociationError**: association is "equivalent_name" and an influence could be associated with more than one other influence, e.g. there is an influence named "right_arm", and influences named "left_arm" and "l_arm". .. function:: mirrorWeightsBetweenMeshes(sourceMeshOrDeformer, targetMeshOrDeformer, axis="x", negativeToPositive=False, association="closest_influence", destVertices=None) *Added in Contour Rig Tools v1.0.8* Mirrors deformer weights across axis between two meshes :arg sourceMeshOrDeformer: either the deformer to mirror weights from, or the corresponding mesh or mesh's transform, |api-argument-node-types-description| :arg targetMeshOrDeformer: either the deformer to mirror weights to, or the corresponding mesh or mesh's transform, |api-argument-node-types-description| :arg axis: The world axis to mirror weights across. One of "x", "y", or "z". :arg negativeToPositive: If truthy, mirrors weights from the negative side of the axis to the positive. Otherwise, mirrors from the positive side of the axis to the negative. :arg association: The method used to associate influences when mirroring. One of "closest_influence" or "equivalent_name". If "closest_influence", each of sourceMeshOrDeformer's influences will be associated with the influence of targetMeshOrDeformer closest to its position mirrored across axis. If "equivalent_name", each of sourceMeshOrDeformer's influences whose names begin with "right\_", "right", or "r\_" will be associated with an influence of targetMeshOrDeformer that begins with "left\_", "left", or "l\_", if both names, when stripped of their prefixes, are the same, and vice versa. If an influence of sourceMeshOrDeformer does not have a name with a prefix, it will be matched with an influence of targetMeshOrDeformer with the same name. If an influence of sourceMeshOrDeformer could be associated with more than one influence of targetMeshOrDeformer, for instance, if sourceMeshOrDeformer has an influence named "right_arm", and targetMeshOrDeformer has influences named "left_arm" and "l_arm", ContourAmbiguousNameAssociationError will be raised. :arg destVertices: An iterable of vertex indices or PyMel MeshVertex instances indicating the vertices of the destination mesh to copy to. If None, all vertices on the destination mesh will be copied to. Defaults to None. :returns: None :raises: **ContourBadArgumentsError**: one of sourceMeshOrDeformer or targetMeshOrDeformer is not a Maya node, or is not a mesh, the transform of a single mesh, or a ContourDeformer, or axis is not one of "x", "y", or "z", or association is not one of "closest_influence" or "equivalent_name", or destVertices contains vertices that do not belong to targetMeshOrDeformer. **ContourNoCorrespondingInfluenceError**: Either sourceMeshOrDeformer or targetMeshOrDeformer has no influences, or association is "equivalent_name" and sourceMeshOrDeformer has an influence that cannot be matched with an influence on targetMeshOrDeformer **ContourAmbiguousNameAssociationError**: association is "equivalent_name" and an influence of sourceMeshOrDeformer could be associated with more than one influence of targetMeshOrDeformer, e.g. sourceMeshOrDeformer has an influence named "right_arm", and targetMeshOrDeformer has influences named "left_arm" and "l_arm". .. function:: pruneSmallWeights(meshOrDeformer, threshold=0.01) Prunes weights from mesh that are smaller than threshold, and normalizes. Small weights for vertices that cannot be normalized (for instance, because there are no unheld influences with non-zero weights) will not be pruned. :arg meshOrDeformer: the deformer for which to prune small weights, or the mesh deformed by it, |api-argument-node-types-description| :arg threshold: a number; all weights smaller than this value will be pruned :returns: None :raises: **ContourBadArgumentsError**: meshOrDeformer is not a Maya node, or is not a mesh, the transform of a single mesh, or a ContourDeformer, or vertices does not contain only vertex indices and PyMel MeshVertex instances, or vertices contains MeshVertex instances that do not belong to the correct mesh. .. function:: weightHammer(meshOrDeformer, vertices) Given a mesh and an iterable of vertices, represented either by vertex indices or a PyMEL MeshVertex, sets each vertex's weight to the average of the weights of its connected vertices :arg meshOrDeformer: either the deformer to hammer weights for, or the mesh or mesh's transform, |api-argument-node-types-description| :arg vertices: an iterable of vertex indices or PyMel MeshVertex instances :returns: None :raises: **ContourBadArgumentsError**: meshOrDeformer is not a Maya node, or is not a mesh, the transform of a single mesh, or a ContourDeformer, or vertices does not contain only vertex indices and PyMEL MeshVertex instances, or vertices contains MeshVertex instances that do not belong to the correct mesh.