← Back to maya
Generate Custom Skin Boxes from Joint Selections in Maya Python
26 Feb 26 (Today)
This was inspired from Advance Skeleton's skin boxes where it creates a pseudo geometry to represent the joint hierarchy, and eventually make the blocking of skin weightings much more manageable.
In context, a character might have high poly and low poly. The high poly for rendering. The low poly for animating/rigging. But the low poly might still not be "low" enough for blocking weights, so we usually create skin boxes to simplify the process.
The script below is too rudimentary I admit. It creates the edges for each joint but the connecting the edges to each other to create the actual geometry is a hit and miss.
For best results, have the aim axis on the joints set to Y.
import maya.cmds as cmds
def create_precise_lofted_geo(size=1.0):
# 1. Get selected joints
selection = cmds.ls(selection=True, type='joint')
if not selection:
cmds.warning("Please select a joint chain.")
return
rects = []
# Calculate half-size for coordinates
s = size * 0.5
for jnt in selection:
# 2. Create the Rectangle (NURBS curve) with custom size
# The points are defined based on the 'size' parameter
rect = cmds.curve(d=1, p=[(-s, 0, -s), (s, 0, -s), (s, 0, s), (-s, 0, s), (-s, 0, -s)], k=[0, 1, 2, 3, 4])
rects.append(rect)
# 3. Match position and rotation to joint
cmds.delete(cmds.parentConstraint(jnt, rect, mo=False))
# 4. Perform the Loft
# d=1 (Linear) ensures flat facets between joints
loft_result = cmds.loft(rects, ch=True, rn=True, ar=True, d=1, name="JointLoft_SURF")
loft_surface = loft_result[0]
# 5. Convert to Polygons with "Per Span" logic
# This ensures exactly one segment per joint
poly_mesh = cmds.nurbsToPoly(loft_surface,
mnd=1, # Quads
format=3, # General
uType=1, # Per Span
vType=1, # Per Span
uNumber=1,
vNumber=1,
ch=True,
name="JointChain_Loft_GEO")[0]
# 6. Cleanup
cmds.delete(rects)
cmds.delete(loft_surface)
# Visual Style
cmds.setAttr(f"{poly_mesh}.overrideEnabled", 1)
cmds.setAttr(f"{poly_mesh}.overrideColor", 17) # Yellow
print(f"Created lofted mesh with size {size}.")
# Change the number below to adjust the radius/size
create_precise_lofted_geo(size=20.0)