How to Rivet Locked Objects to Vertices in Autodesk Maya Using Python
25 Aug 26 (2mo ago)
Attaching accessories, props, or control locators to deforming geometry is a core task in 3D rigging. While traditional MEL rivets often require two intersecting edges, Autodesk Maya's modern pointOnPolyConstraint allows you to snap and pin transforms directly to a single vertex.
When working with constrained rigs or downstream assets, target objects often have locked or hidden translation and rotation channels. Running a constraint script without unlocking these channels causes errors. Below is a streamlined Python solution that handles attribute unlocking and riveting in a single pass.
The Challenge: Locked Transforms in Constraints
Applying a constraint to a transform with locked attributes causes Maya's execution to fail. To automate the process reliably:
- Verify the target object exists in the scene.
- Iterate through translation (
tx,ty,tz) and rotation (rx,ry,rz) attributes to setlock=Falseandkeyable=True. - Apply
cmds.pointOnPolyConstraint()to link the target transform directly to the selected vertex.
Python Solution
Run this script inside Maya's Script Editor (Python tab):
import maya.cmds as cmds
def unlock_and_rivet(mesh_vtx: str, target_transform: str, maintain_offset: bool = False):
"""
Unlocks transformation attributes and pins an object to a target vertex.
"""
# Verify object existence
if not cmds.objExists(target_transform):
cmds.error(f"Target '{target_transform}' does not exist in the scene.")
return
# Unlock and unhide translation and rotation channels
transform_attrs = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz']
for attr in transform_attrs:
full_attr = f"{target_transform}.{attr}"
if cmds.objExists(full_attr):
cmds.setAttr(full_attr, lock=False, keyable=True)
# Apply the pointOnPolyConstraint
constraint = cmds.pointOnPolyConstraint(
mesh_vtx,
target_transform,
maintainOffset=maintain_offset
)
print(f"Successfully unlocked and riveted '{target_transform}' to '{mesh_vtx}'.")
return constraint
# Example Execution
vertex_path = "RabbitZ_MainBody.vtx[2397]"
target_node = "bottle_C_C0_ik_cns"
unlock_and_rivet(vertex_path, target_node)
Key Advantages of pointOnPolyConstraint
- Clean Node Graph: Avoids creating auxiliary curves, lofts, or extra DAG nodes required by legacy MEL rivet scripts.
- Direct Deform Tracking: Moves and rotates synchronously with skinCluster, blendShape, and lattice deformations.
- Offset Control: Toggle
maintain_offset=Trueif you need the prop to preserve its original position relative to the vertex instead of snapping to it.