// AVIARIGG PERSONAL REFERENCE — MAYA 2026 // PYTHON 3
⌗
7
Total Scripts
◈
Python 3
Language
◎
2022+
Maya Version
// Script Index
Last updated: April 2026
SHAPE ED.
Fix Broken Shape EditorFixes a blank Shape Editor caused by a duplicate shapeEditorManager node. Migrates all blendshapes to the primary node.
▶
ARNOLD
Fix Arnold Mesh VisibilityRestore Arnold render visibility flags on a mesh that is invisible in the Arnold viewport despite being unhidden.
▶
IK / FK
IK / FK Switch with MatchToggle arm between IK and FK while preserving pose via matchTransform. Assign to a picker button.
▶
UVS
Transfer UVsTransfer UVs from one mesh to multiple targets using polyTransfer. Select source first, then shift-select targets.
▶
ATTRIBUTES
Change Default Attribute ValueEdit the default value of any existing attribute, including enums.
▶
DEFORMERS
Add Geometry to DeformerAdd a control group or mesh to a nonLinear deformer, with optional hierarchy exclusions.
▶
DEFORMERS
Mirror NonLinear Deformer WeightsMirror painted deformer weights left→right on a symmetrical mesh. Maya 2022+ method.
▶
REFERENCE
Naming ConventionsFull suffix reference for all node types used in AviaRigg rigs, including shaders and texture naming.
▶
// Deformers
Mirror NonLinear Deformer Weights
Mirrors painted deformer weights from the left side to the right side across the YZ plane on a symmetrical mesh.
Uses closestPoint surface association —
required for nonLinear deformers in Maya 2022+. The old Relationship Editor method no longer works.
NonLinearMirrorWeightsPythonMaya 2022+
// Script
Python
import maya.cmds as cmds
cmds.copyDeformerWeights(
sourceDeformer="head_bend_lo", # replace with your deformer namedestinationDeformer="head_bend_lo", # same deformersourceShape="Bdt_Body_FinalShape", # replace with your mesh shape nodedestinationShape="Bdt_Body_FinalShape",
mirrorMode="YZ", # YZ = left/right (Z forward, Y up)mirrorInverse=False, # flip to True if wrong directionsurfaceAssociation="closestPoint"# critical — vertex ID fails on nonLinear
)
// Parameters
Parameter
Type
Description
sourceDeformer
str
Name of the nonLinear deformer node (e.g. head_bend_lo, head_squash)
destinationDeformer
str
Same as sourceDeformer — mirroring within the same deformer
sourceShape
str
Shape node of the mesh (not the transform). Find via Attribute Editor tab name.
mirrorMode
str
"YZ" for left/right mirror on Z-forward Y-up rigs. Use "XY" or "XZ" for other orientations.
mirrorInverse
bool
False = mirrors left→right. True = mirrors right→left. Flip if result is wrong.
surfaceAssociation
str
"closestPoint" is required for nonLinear deformers. Vertex ID association fails.
// Notes
▸Works for any nonLinear deformer: head_bend, head_squash, head_bend_lo, etc.
▸The old Maya 2020 method (Relationship Editor → Deformer Sets) no longer works in Maya 2022+. Component tags replaced deformer sets.
▸Mesh must be symmetrical. Works as long as the skinCluster mirror works on the same mesh.
▸Do NOT use influenceAssociation flag — that is skinCluster only and will error.
▸Always save your scene before running mirror operations on weights.
// Attributes
Change Default Attribute Value
Changes the default value of an existing attribute on a node. Useful for enum attributes
(e.g. off/on) where you want the default to be something other than 0.
Works on any numeric or enum attribute.
PythonAttributes
// Script
Python
import maya.cmds as cmds
cmds.addAttr("your_node.your_attribute", edit=True, defaultValue=1)
# replace "your_node" with your node name
# replace "your_attribute" with your attribute name
# replace 1 with your desired default value
// Parameters
Parameter
Type
Description
node.attribute
str
The node and attribute in dot notation (e.g. "head_ctl.tweak")
edit
bool
Must be True to modify an existing attribute rather than create a new one
defaultValue
float
The new default value. For enums: 0 = first option, 1 = second option, etc.
// Notes
▸For enum attributes, the default value is the index — 0 = first enum, 1 = second, etc.
▸This only changes the default — it does not change the current value. Use setAttr separately if needed.
▸The default value is what the attribute resets to when you right-click → Set Default Value in Maya.
// Deformers
Add Geometry to Deformer
Adds a geometry group (e.g. controller shapes under ctl_grp) to an existing nonLinear deformer.
Used in Maya 2022+ as a replacement for the old Relationship Editor method, which no longer works due to component tags replacing deformer sets.
Useful for making controllers squash and stretch along with the mesh.
NonLinearPythonMaya 2022+
// Script — Simple (add entire group)
Python
import maya.cmds as cmds
cmds.deformer("head_squash", edit=True, geometry="ctl_grp")
# replace "head_squash" with your deformer name
# replace "ctl_grp" with your group or geometry name
// Script — Verbose (add individual shapes with error handling)
Python
import maya.cmds as cmds
ctls = cmds.listRelatives("ctl_grp", allDescendants=True, type="nurbsCurve")
for shape in ctls:
try:
cmds.deformer("head_squash", edit=True, geometry=shape)
exceptExceptionas e:
print(f"Skipped {shape}: {e}")
// Parameters
Parameter
Type
Description
deformer name
str
The nonLinear deformer node to add geometry to (e.g. head_squash, head_bend)
geometry
str
The group or shape node to add. Can be a transform group (ctl_grp) or individual nurbsCurve shape.
edit
bool
Must be True to modify an existing deformer rather than create a new one.
// Notes
▸In Maya 2022+, the Relationship Editor no longer shows nonLinear deformer sets. Use this script instead.
▸Adding ctl_grp makes controller shapes squash and stretch with the deformer — intentional for cartoon rigs.
▸Use the simple version first. Use the verbose version if the simple one errors on nurbs curves.
▸Works for any nonLinear deformer: head_squash, head_bend, head_bend_lo, etc.
// Add with Exclusions
Add an entire group to the deformer but exclude specific control hierarchies from being affected.
Run this as a single script — it adds the group first, then removes the excluded roots and all their descendants.
Python
import maya.cmds as cmds
# Step 1 — Add the entire control group to the deformer
cmds.deformer("jaw_bend", edit=True, geometry="ctl_grp")
# Step 2 — List every control root you want to EXCLUDE
# Add as many as needed — entire hierarchy under each will be removed
exclude_roots = [
"l_ear_master_ctl", # exclude left ear and all children"r_ear_master_ctl", # exclude right ear and all children"jaw_deformer_ctl", # exclude jaw deformer ctl (avoids double transform)
]
# Step 3 — Remove excluded hierarchies from the deformerfor root in exclude_roots:
descendants = cmds.listRelatives(root, allDescendents=True, type="nurbsCurve", fullPath=True) or []
shapes = cmds.listRelatives(root, shapes=True, type="nurbsCurve", fullPath=True) or []
all_shapes = list(set(descendants + shapes))
for shape in all_shapes:
try:
cmds.deformer("jaw_bend", edit=True, remove=True, geometry=shape)
exceptExceptionas e:
print(f"Skipped {shape}: {e}")
print("Done")
▸Replace "jaw_bend" with your deformer name and "ctl_grp" with your group name.
▸Add or remove entries in exclude_roots as needed — one name per line.
▸Note the spelling: allDescendents — Maya uses an 'e', not 'a'. Wrong spelling will error.
▸fullPath=True is required — without it Maya errors if two shapes share the same name.
▸Exclude controllers that would get double transforms — any ctl that drives the deformer itself should be in the exclusion list.
// UVs
Transfer UVs
Transfer UVs from one mesh to multiple others using polyTransfer.
Select the source mesh first, then shift-select all target meshes. Run the script.
PythonUVsMaya 2022+
// Script
Select new UV mesh first → then shift-select old geo → run
Python
# transfer uvs
# select new uvs mesh and then old geoimport maya.cmds as mc
selection = mc.ls(sl=True)
for i, x inenumerate(selection):
if i != 0:
mc.polyTransfer(selection[i], uvSets=True, ao=selection[0], constructionHistory=False)
mc.warning("uvs transfered correctly")
// Notes
▸Selection order matters — first selected is always the source. All subsequent objects receive the UVs.
▸Requires identical topology between source and targets. Won't work across different polygon counts.
▸No construction history left behind — constructionHistory=False keeps the scene clean.
// IK / FK
IK / FK Switch with Match
Toggles the arm between IK and FK while preserving pose. When switching from IK → FK,
the FK controls match the IK joint positions. When switching FK → IK, the IK controls
match the FK joint positions. Assign to a picker button for one-click switching.
PythonRiggingAnimationMaya 2022+
// Script
Python
import maya.cmds as mc
ikfk = mc.getAttr('l_arm_settings_ctl.IKFK')
if ikfk == 0:
# FK → IK : match IK controls to FK joint positions
mc.setAttr('l_arm_settings_ctl.IKFK', 1)
mc.matchTransform('l_shoulder_fk_ctl', 'l_shoulder_ik_jnt')
mc.matchTransform('l_elbow_fk_ctl', 'l_elbow_ik_jnt')
mc.matchTransform('l_wrist_fk_ctl', 'l_wrist_ik_jnt')
else:
# IK → FK : match FK controls to IK joint positions
mc.setAttr('l_arm_settings_ctl.IKFK', 0)
mc.matchTransform('l_wrist_ik_ctl', 'l_wrist_fk_jnt')
mc.matchTransform('l_elbow_ik_ctl', 'l_elbow_fk_jnt')
mc.matchTransform('l_shoulder_ik_ctl', 'l_shoulder_fk_jnt')
// Notes
▸IKFK = 0 is FK mode, IKFK = 1 is IK mode. The switch attribute is set before matching so the controls are active when matched.
▸Node names are hardcoded for the Nordic Bandit rig left arm — update l_arm_settings_ctl and the control/joint names to match your rig. For referenced rigs, prepend the namespace: 'NordBand:l_arm_settings_ctl'.
▸Assign to a picker button in MGPicker Studio for one-click switching during animation. For namespace-agnostic picker buttons, retrieve the namespace dynamically via mc.MGPickerView(view, query=True, namespace=True).
// Reference
Naming Conventions
Standard suffix conventions for all node types used in AviaRigg rigs.
Consistent naming keeps rigs readable, maintainable, and scriptable.
Transforms & Hierarchy
Transformtransform
Groupgrp
Offsetoffset
Locatorloc
Connection Offsetcon
Controllers
Controlctl
Control Offsetctl_offset
Gimbal Controlgimbal_ctl
Set Driven Keysdk
Joints
Jointjnt
Bind Jointbind_jnt
Twist Jointtwist_jnt
End Jointend_jnt
IK Jointik_jnt
FK Jointfk_jnt
Driver Jointdrv_jnt
Geometry
Meshgeo
NURBS Surfacenrb
NURBS Curvecrv
Deformers
Skin Clustersc
Blendshapebs
Clustercls
Latticelat
Wrapwrap
Delta Mushdm
Squashsquash
Bendbend
NonLinearnonLin
Utility Nodes
Multiply Dividemd
Plus Minus Averagepma
Conditioncond
Clampclamp
Remap Valuermv
Blend Colorsbc
Blend Two Attrbta
Reverserev
Set Rangesr
Math / Matrix Nodes
Sumsum
Decompose Matrixdcm
Compose Matrixcm
Inverse MatrixinvMat
Mult Matrixmmx
Constraints
Parent Constraintpc
Point ConstraintpointCon
Orient Constraintoc
Scale Constraintsc
Aim Constraintac
Matrix ConstraintmatCon
IK
IK Handleikh
IK Effectorike
Spline IKsplineIK
Spaces & Locators
Local Space Locatorlocal_loc
World Space Locatorworld_loc
Space Switchspace_sw
Rigging Misc
Folliclefol
Curve Infocrv_info
Motion Pathmpath
Display & Organization
Display Layerlayer
Setset
Shaders & Materials
Shader / Material_mat
Shading Group_mat_sg
File Node_file
Place2D Texture_p2d
// Arnold / Viewport
Fix Arnold Mesh Visibility
Restores Arnold render visibility flags on a mesh that appears invisible in the Arnold viewport
even though it is not hidden in the outliner. Caused by Arnold's primaryVisibility,
visibleInReflections, and visibleInRefractions flags
being silently set to False — commonly triggered by blend shape target editing sessions.
PythonArnoldViewportMaya 2022+
// Diagnose — check visibility flags
Python
import maya.cmds as mc
shape = "Bdt_Body_FinalShape"# replace with your shape node nameprint("primaryVisibility :", mc.getAttr(shape + ".primaryVisibility"))
print("visibleInReflections:", mc.getAttr(shape + ".visibleInReflections"))
print("visibleInRefractions:", mc.getAttr(shape + ".visibleInRefractions"))
// Fix — restore flags on a single mesh
Python
import maya.cmds as mc
shape = "Bdt_Body_FinalShape"# replace with your shape node name
mc.setAttr(shape + ".primaryVisibility", True)
mc.setAttr(shape + ".visibleInReflections", True)
mc.setAttr(shape + ".visibleInRefractions", True)
print(f"[AviaRigg] Arnold visibility restored on {shape}")
// Fix All — restore flags on every affected mesh in scene
Run this if multiple meshes were affected at once. Safe to run as a post-blend-shape sanity check.
Python
import maya.cmds as mc
fixed = []
for shape in mc.ls(type="mesh"):
if mc.attributeQuery("primaryVisibility", node=shape, exists=True):
ifnot mc.getAttr(shape + ".primaryVisibility"):
mc.setAttr(shape + ".primaryVisibility", True)
mc.setAttr(shape + ".visibleInReflections", True)
mc.setAttr(shape + ".visibleInRefractions", True)
fixed.append(shape)
print(f"[AviaRigg] Fixed {len(fixed)} mesh(es): {fixed}")
// Parameters
Attribute
Type
Description
primaryVisibility
bool
Controls whether Arnold renders the mesh at all. False = completely invisible in Arnold viewport and final render.
visibleInReflections
bool
Whether the mesh appears in reflections on other surfaces.
visibleInRefractions
bool
Whether the mesh appears in refractions through transparent materials.
// Notes
▸These are Arnold-specific attributes — they have no effect in Viewport 2.0. A mesh can look fine in VP2 and be completely invisible in Arnold.
▸The flags are silently set to False during blend shape target editing. Exiting edit mode does not restore them.
▸Confirmed trigger: entering blend shape target edit mode (Deform → Edit Blend Shape → Edit) on a mesh with MtoA loaded.
▸The shape node name is not the same as the transform. Find it in the Attribute Editor — it's the tab ending in "Shape".
▸Run the "Fix All" version after any blend shape editing session as a sanity check.
// Shape Editor
Fix Broken Shape Editor
Fixes a blank or incomplete Shape Editor caused by a duplicate shapeEditorManager node.
Maya's Shape Editor UI only reads from the default node — if a second one exists (from a scene merge, import, or reference),
blendshapes registered there will be invisible in the UI. This script reconnects all blendshapes
to the correct node via .message and removes the duplicate.
PythonShape EditorBlendShapeMaya 2022+
// When to use this
▸Shape Editor opens but shows 0 or only some blendshapes, even though the nodes exist in the scene.
▸Node Editor shows two shapeEditorManager nodes — one connected to all blendshapes, one empty.
▸Caused by scene merges, imports, or references creating a second manager node.
// Step 1 — Diagnose: check which manager has which connections
Python
import maya.cmds as mc
for node in ["shapeEditorManager", "shapeEditorManager1"]:
if not mc.objExists(node):
print(f"{node} — does not exist")
continue
indices = mc.getAttr(node + ".blendShapeParent", multiIndices=True) or []
print(f"\n{node} — {len(indices)} blendshapes connected:")
for i in indices:
conn = mc.listConnections(f"{node}.blendShapeParent[{i}]", source=True, plugs=True) or []
print(f" [{i}]: {conn}")
// Step 2 — Fix: reconnect all blendshapes via .message to primary manager
Python
import maya.cmds as mc
node = "shapeEditorManager"# Collect blendshapes and disconnect wrong plugs
indices = mc.getAttr(node + ".blendShapeParent", multiIndices=True) or []
bs_nodes = []
for i in indices:
plug = f"{node}.blendShapeParent[{i}]"
conns = mc.listConnections(plug, source=True, plugs=True) or []
for c in conns:
bs_name = c.split(".")[0]
bs_nodes.append(bs_name)
mc.disconnectAttr(c, plug)
# Reconnect via .message — the only plug the Shape Editor readsfor i, bs inenumerate(bs_nodes):
mc.connectAttr(f"{bs}.message", f"{node}.blendShapeParent[{i}]", force=True)
print(f"Fixed: {bs}.message → {node}.blendShapeParent[{i}]")
print("Done — reopen Shape Editor.")
// Notes
▸shapeEditorManager is a protected Maya default node — it cannot be deleted, only the duplicate can be removed.
▸The correct connection is blendShape.message → shapeEditorManager.blendShapeParent[i]. Any other plug (e.g. .midLayerParent) won't register in the UI.
▸Save a backup before running if your scene uses referenced rigs — the duplicate manager may belong to a reference.