I tried running the script with python tab but nothing happens.
I've placed the script into maya directory folder \Documents\maya\2020\scripts.
It's a script for creating cmuscle spline i was following along a tutorial.
any help would be much appreciated 😊
import string
import maya.cmds as cmds
def make_spline(side, description, index, ctrl_num=3, jnt_num=5, control_mid=True):
"""
create cMuscleSpline
This script is simply convert from Maya muscle's mel script
the mel script location is C:/Program Files/Autodesk/Maya2020/scripts/muscle/cMuscleSplineUI.mel, line 660 cMS_makeSpline
made some changes with the naming to fit current pipeline
add some global offset attr so user can plug into global control to do some overall control
Args:
side(str): muscle spline's side, 'l', 'r' or 'm'
description(str): muscle spline's description
index(i): muscle spline's index
ctrl_num(i): how many controls needed, default is 3
jnt_num(i): how many joints needed, default is 5
control_mid(bool): the start/end control will control in-between controls with falloff, default is True
Returns:
spline(str): cMuscleSpline node name
controls(list): spline controls
joints(list): spline joints
group(str): root group for the spline setup
"""
# make master groups
grp_main = cmds.createNode('transform',
name='grp_{}_{}MusSpline_{:03d}'.format(side, description, index))
# c muscle spline node
spline = cmds.createNode('cMuscleSpline',
name='cMuscleSpline_{}_{}MusSpline_{:03d}Shape'.format(side, description, index))
# lock label attrs
cmds.setAttr(spline + '.DISPLAY', lock=True)
cmds.setAttr(spline + '.TANGENTS', lock=True)
cmds.setAttr(spline + '.LENGTH', lock=True)
# get the transform node of spline shape and parent it under master group
transform_spline = cmds.listRelatives(spline, parent=True)[0]
cmds.parent(transform_spline, grp_main)
# set inheritsTransform to 0 to avoid double transformation
cmds.setAttr(transform_spline + '.inheritsTransform', 0)
# lock the attrs because it shouldn't move
for attr in 'trs':
for axis in 'xyz':
cmds.setAttr('{}.{}{}'.format(transform_spline, attr, axis), lock=True, keyable=False)
# connect time to drive the spline
cmds.connectAttr('time1.outTime', spline + '.inTime', force=True)
# create some attrs so user can view easily in channel box
cmds.addAttr(spline, longName='curLen', keyable=True)
cmds.connectAttr(spline + '.outLen', spline + '.curLen')
# add squash/stretch volume attr to connect with other controller
cmds.addAttr(spline, longName='squashXMult', attributeType='float', minValue=0, defaultValue=1)
cmds.addAttr(spline, longName='squashZMult', attributeType='float', minValue=0, defaultValue=1)
cmds.addAttr(spline, longName='stretchXMult', attributeType='float', minValue=0, defaultValue=1)
cmds.addAttr(spline, longName='stretchZMult', attributeType='float', minValue=0, defaultValue=1)
# add global attr so it can be easily plugged with global control
cmds.addAttr(spline, longName='jiggleMult', defaultValue=1)
cmds.addAttr(spline, longName='jiggleXMult', defaultValue=1)
cmds.addAttr(spline, longName='jiggleYMult', defaultValue=1)
cmds.addAttr(spline, longName='jiggleZMult', defaultValue=1)
cmds.addAttr(spline, longName='jiggleImpactMult', defaultValue=1)
# ctrl grp
grp_ctrls = cmds.createNode('transform',
name='grp_{}_{}MusSplineControls_{:03d}'.format(side, description, index))
cmds.parent(grp_ctrls, grp_main)
for attr in 'trs':
for axis in 'xyz':
cmds.setAttr('{}.{}{}'.format(grp_ctrls, attr, axis), lock=True, keyable=False)
# driven grp for joints
grp_driven = cmds.createNode('transform',
name='grp_{}_{}MusSplineJoints_{:03d}'.format(side, description, index))
cmds.parent(grp_driven, grp_main)
cmds.setAttr(grp_driven + '.inheritsTransform', 0)
for attr in 'trs':
for axis in 'xyz':
cmds.setAttr('{}.{}{}'.format(grp_driven, attr, axis), lock=True, keyable=False)
ctrls = []
# make controls
for i in range(ctrl_num):
ctrl_name = 'ctrl_{}_{}MusSpline{}_{:03d}'.format(side, description, string.ascii_uppercase[i], index)
# create curve
ctrl = cmds.curve(point=[[-0.5, -0.5, -0.5], [-0.5, -0.5, 0.5], [0.5, -0.5, 0.5], [0.5, -0.5, -0.5],
[-0.5, -0.5, -0.5], [-0.5, 0.5, -0.5], [0.5, 0.5, -0.5], [0.5, -0.5, -0.5],
[0.5, -0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, -0.5], [0.5, 0.5, 0.5],
[-0.5, 0.5, 0.5], [-0.5, -0.5, 0.5], [-0.5, 0.5, 0.5], [-0.5, 0.5, -0.5]],
degree=1,
knot=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],
name=ctrl_name)
# rename curve shape
cmds.rename(cmds.listRelatives(ctrl, shapes=True)[0], ctrl_name + 'Shape')
# add to list
ctrls.append(ctrl)
# make control hierarchy
ctrl_nodes = []
for node_type in ['zero', 'driven', 'connect', 'offset']:
grp = cmds.createNode('transform', name=ctrl.replace('ctrl', node_type))
ctrl_nodes.append(grp)
# parent hierarchy
cmds.parent(ctrl, ctrl_nodes[-1])
cmds.parent(ctrl_nodes[-1], ctrl_nodes[-2])
cmds.parent(ctrl_nodes[-2], ctrl_nodes[1])
cmds.parent(ctrl_nodes[1], ctrl_nodes[0])
# store zero node to variable
zero = ctrl_nodes[0]
# place controls vertically
cmds.setAttr(zero + '.translateY', i)
# parent zero group to control group
cmds.parent(zero, grp_ctrls)
# color control
ctrl_shape = cmds.listRelatives(ctrl, shapes=True)[0]
cmds.setAttr(ctrl_shape + '.overrideEnabled', 1)
if side == 'l':
color = 28
elif side == 'r':
color = 31
else:
color = 26
cmds.setAttr(ctrl_shape + '.overrideColor', color)
# add jiggle value, make sure start and end not jiggle
if 0 < i < ctrl_num - 1:
jiggle = 1
else:
jiggle = 0
# add attrs
cmds.addAttr(ctrl, longName='tangentLength', shortName='tanlen', minValue=0, defaultValue=1, keyable=True)
cmds.addAttr(ctrl, longName='jiggle', shortName='jig', defaultValue=jiggle, minValue=0, keyable=True)
cmds.addAttr(ctrl, longName='jiggleX', shortName='jigx', defaultValue=jiggle, minValue=0, keyable=True)
cmds.addAttr(ctrl, longName='jiggleY', shortName='jigy', defaultValue=jiggle * 0.25, minValue=0, keyable=True)
cmds.addAttr(ctrl, longName='jiggleZ', shortName='jigz', defaultValue=jiggle, minValue=0, keyable=True)
cmds.addAttr(ctrl, longName='jiggleImpact', shortName='jigimp', defaultValue=jiggle * 0.5, minValue=0,
keyable=True)
cmds.addAttr(ctrl, longName='jiggleImpactStart', shortName='jigimpst', defaultValue=1000, minValue=0,
keyable=True)
cmds.addAttr(ctrl, longName='jiggleImpactStop', shortName='jigimpsp', defaultValue=0.001, minValue=0,
keyable=True)
cmds.addAttr(ctrl, longName='cycle', shortName='cyc', minValue=1, defaultValue=12, keyable=True)
cmds.addAttr(ctrl, longName='rest', shortName='rst', minValue=1, defaultValue=24, keyable=True)
# lock hide scale and vis
for attr in ['sx', 'sy', 'sz', 'v']:
cmds.setAttr('{}.{}'.format(ctrl, attr), lock=True, keyable=False)
# connect attr
cmds.connectAttr(ctrl + '.worldMatrix[0]', '{}.controlData[{}].insertMatrix'.format(spline, i))
# connect jiggle attr with global mult attr, then plug into controlData
for attr in ['jiggle', 'jiggleX', 'jiggleY', 'jiggleZ', 'jiggleImpact']:
# mult node
mult = 'mult_{}_{}MusSpline{}{}{}_{:03d}'.format(side, description, string.ascii_uppercase[i],
attr[0].upper(), attr[1:], index)
cmds.createNode('multDoubleLinear', name=mult)
cmds.connectAttr('{}.{}'.format(ctrl, attr), mult + '.input1')
cmds.connectAttr('{}.{}Mult'.format(spline, attr), mult + '.input2')
# connect output to controlData
cmds.connectAttr(mult + '.output', '{}.controlData[{}].{}'.format(spline, i, attr))
# connect other attrs directly into controlData
for attr in ['tangentLength', 'jiggleImpactStart', 'jiggleImpactStop', 'cycle', 'rest']:
cmds.connectAttr('{}.{}'.format(ctrl, attr), '{}.controlData[{}].{}'.format(spline, i, attr))
# control mid points
if control_mid:
for i in range(1, ctrl_num - 1):
# get weight value
weight = i / float(ctrl_num - 1)
# get driven group
driven = ctrls[i].replace('ctrl', 'driven')
# point constraint with start and end
pont_con = cmds.pointConstraint(ctrls[0], ctrls[-1], driven, maintainOffset=False)[0]
cmds.setAttr('{}.{}W0'.format(pont_con, ctrls[0]), 1 - weight)
cmds.setAttr('{}.{}W1'.format(pont_con, ctrls[-1]), weight)
# aim constraint dummy node to start and end, and blend to ctrl's orient
grp_aim_start = 'grp_{}_{}MusSpline{}AimStart_{:03d}'.format(side, description,
string.ascii_uppercase[i], index)
grp_aim_end = 'grp_{}_{}MusSpline{}AimEnd_{:03d}'.format(side, description,
string.ascii_uppercase[i], index)
cmds.createNode('transform', name=grp_aim_start)
cmds.createNode('transform', name=grp_aim_end)
# snap to control's position
cmds.matchTransform(grp_aim_start, grp_aim_end, driven, pos=True, rot=True)
# parent dummy groups under zero
cmds.parent(grp_aim_start, grp_aim_end, driven.replace('driven', 'zero'))
# aim constraint with start and end
aim_start = cmds.aimConstraint(ctrls[0], grp_aim_start, aimVector=[0, -1, 0], upVector=[1, 0, 0],
worldUpVector=[1, 0, 0], worldUpType='objectrotation',
worldUpObject=ctrls[0], maintainOffset=False)[0]
aim_end = cmds.aimConstraint(ctrls[-1], grp_aim_end, aimVector=[0, 1, 0], upVector=[1, 0, 0],
worldUpVector=[1, 0, 0], worldUpType='objectrotation',
worldUpObject=ctrls[-1], maintainOffset=False)[0]
# add blend attr to chose either aim with x up or z up
blend = 'blend_{}_{}MusSpline{}AimUp_{:03d}'.format(side, description,
string.ascii_uppercase[i], index)
if not cmds.objExists(blend):
cmds.createNode('blendColors', name=blend)
cmds.connectAttr(spline + '.upAxis', blend + '.blender')
cmds.setAttr(blend + '.color1', 0, 0, 1)
cmds.setAttr(blend + '.color2', 1, 0, 0)
# connect blend to aim constraint
for attr in ['upVector', 'worldUpVector']:
cmds.connectAttr(blend + '.output', '{}.{}'.format(aim_start, attr))
cmds.connectAttr(blend + '.output', '{}.{}'.format(aim_end, attr))
# connect point constraint's output to dummy groups since they are the same place with driver
for attr in ['translateX', 'translateY', 'translateZ']:
for grp in [grp_aim_start, grp_aim_end]:
cmds.connectAttr('{}.constraint{}{}'.format(pont_con, attr[0].upper(), attr[1:]),
'{}.{}'.format(grp, attr))
# orient constraint dummy groups with driver
ont_con = cmds.orientConstraint(grp_aim_start, grp_aim_end, driven, maintainOffset=False)[0]
cmds.setAttr(ont_con + '.interpType', 2)
cmds.setAttr('{}.{}W0'.format(ont_con, grp_aim_start), 1 - weight)
cmds.setAttr('{}.{}W1'.format(ont_con, grp_aim_end), weight)
# create joints
jnts = []
for i in range(jnt_num):
# get u value
u_val = i / float(jnt_num - 1)
# joint name
jnt = 'jnt_{}_{}MusSpline{:03d}_{:03d}'.format(side, description, i + 1, index)
# create joint
cmds.createNode('joint', name=jnt)
# append to jnts list
jnts.append(jnt)
# add uValue to joint
cmds.addAttr(jnt, longName='uValue', minValue=0, maxValue=1, defaultValue=u_val, keyable=True)
# parent to driven group
cmds.parent(jnt, grp_driven)
# connect attr
cmds.connectAttr(jnt + '.uValue', '{}.readData[{}].readU'.format(spline, i))
cmds.connectAttr(jnt + '.rotateOrder', '{}.readData[{}].readRotOrder'.format(spline, i))
cmds.connectAttr('{}.outputData[{}].outTranslate'.format(spline, i), jnt + '.translate')
cmds.connectAttr('{}.outputData[{}].outRotate'.format(spline, i), jnt + '.rotate')
# add scale x, z
# get scale weight, the middle point should be 1, and falloff till the start/end point
mid_num = (jnt_num - 1) * 0.5
scale_weight = 1 - (abs(mid_num - i) / float(mid_num))**2
if scale_weight != 0:
# not the start/end point
# add scale x and scale z attr to spline so user can tweak individually
cmds.addAttr(spline, longName='joint{:03d}SquashX'.format(i + 1), attributeType='float', minValue=0,
defaultValue=1 + scale_weight, keyable=True)
cmds.addAttr(spline, longName='joint{:03d}StretchX'.format(i + 1), attributeType='float', minValue=0,
defaultValue=1 - scale_weight * 0.9, keyable=True)
cmds.addAttr(spline, longName='joint{:03d}SquashZ'.format(i + 1), attributeType='float', minValue=0,
defaultValue=1 + scale_weight, keyable=True)
cmds.addAttr(spline, longName='joint{:03d}StretchZ'.format(i + 1), attributeType='float', minValue=0,
defaultValue=1 - scale_weight * 0.9, keyable=True)
# add blend node to blend squash stretch
blend_squash = 'blend_{}_{}MusSplineSquash{:03d}_{:03d}'.format(side, description, i + 1, index)
blend_stretch = 'blend_{}_{}MusSplineStretch{:03d}_{:03d}'.format(side, description, i + 1, index)
cmds.createNode('blendColors', name=blend_squash)
cmds.createNode('blendColors', name=blend_stretch)
# connect blender with spline's outPctSquash/Stretch
cmds.connectAttr(spline + '.outPctSquash', blend_squash + '.blender')
cmds.connectAttr(spline + '.outPctStretch', blend_stretch + '.blender')
cmds.setAttr(blend_squash + '.color2', 1, 1, 1)
cmds.setAttr(blend_stretch + '.color2', 1, 1, 1)
# mult node to multiply individual joint squash and stretch with global mult
mult_squash = 'mult_{}_{}MusSplineSquash{:03d}_{:03d}'.format(side, description, i + 1, index)
mult_stretch = 'mult_{}_{}MusSplineStretch{:03d}_{:03d}'.format(side, description, i + 1, index)
cmds.createNode('multiplyDivide', name=mult_squash)
cmds.createNode('multiplyDivide', name=mult_stretch)
cmds.connectAttr('{}.joint{:03d}SquashX'.format(spline, i + 1), mult_squash + '.input1X')
cmds.connectAttr('{}.joint{:03d}SquashZ'.format(spline, i + 1), mult_squash + '.input1Z')
cmds.connectAttr('{}.joint{:03d}StretchX'.format(spline, i + 1), mult_stretch + '.input1X')
cmds.connectAttr('{}.joint{:03d}StretchZ'.format(spline, i + 1), mult_stretch + '.input1Z')
cmds.connectAttr(spline + '.squashXMult', mult_squash + '.input2X')
cmds.connectAttr(spline + '.squashZMult', mult_squash + '.input2Z')
cmds.connectAttr(spline + '.stretchXMult', mult_stretch + '.input2X')
cmds.connectAttr(spline + '.stretchZMult', mult_stretch + '.input2Z')
# connect to blend colors input1X
cmds.connectAttr(mult_squash + '.output', blend_squash + '.color1')
cmds.connectAttr(mult_stretch + '.output', blend_stretch + '.color1')
# plus node to add scale together
plus = 'plus_{}_{}MusSplineSquashStretch{:03d}_{:03d}'.format(side, description, i + 1, index)
cmds.createNode('plusMinusAverage', name=plus)
cmds.connectAttr(blend_squash + '.output', plus + '.input3D[0]')
cmds.connectAttr(blend_stretch + '.output', plus + '.input3D[1]')
cmds.setAttr(plus + '.input3D[2]', -1, -1, -1)
# multiply node to mult global scale
mult_scale = 'mult_{}_{}MusSplineScale{:03d}_{:03d}'.format(side, description, i + 1, index)
cmds.createNode('multiplyDivide', name=mult_scale)
cmds.connectAttr(plus + '.output3D', mult_scale + '.input1')
cmds.connectAttr(spline + '.userScale', mult_scale + '.input2X')
cmds.connectAttr(spline + '.userScale', mult_scale + '.input2Y')
cmds.connectAttr(spline + '.userScale', mult_scale + '.input2Z')
# connect back to joint
cmds.connectAttr(mult_scale + '.outputX', jnt + '.scaleX')
cmds.connectAttr(mult_scale + '.outputZ', jnt + '.scaleZ')
cmds.connectAttr(spline + '.userScale', jnt + '.scaleY')
else:
cmds.connectAttr(spline + '.userScale', jnt + '.scaleX')
cmds.connectAttr(spline + '.userScale', jnt + '.scaleY')
cmds.connectAttr(spline + '.userScale', jnt + '.scaleZ')
# set squash stretch values
# get length
length = cmds.getAttr(spline + '.outLen')
# set default length
cmds.setAttr(spline + '.lenDefault', length)
# stretch and squash
cmds.setAttr(spline + '.lenSquash', length * 0.25)
cmds.setAttr(spline + '.lenStretch', length * 2.5)
return spline, ctrls, jnts, grp_main
def add_spline(mus_joint, joint_number=5, control_number=3, control_mid=True, mirror=True, scale_attr=None):
"""
add cMuscle spline setup to given muscle joint
Args:
mus_joint (str): muscle joint need to add cMuscle spline setup
joint_number (int): cMuscle spline joints number
control_number (int): cMuscle spline controls number
control_mid (bool): constraint the mid controller with start/end controller, default is True
mirror (bool): mirror to the right side
scale_attr (str): global scale attribute
"""
# get name parts
name_parts = mus_joint.split('_')
side = name_parts[1]
description = name_parts[2]
index = int(name_parts[3])
# get muscle info
mus_group = cmds.listRelatives(mus_joint, parent=True)[0]
end_joint = cmds.listRelatives(mus_joint, children=True, type='joint')[0]
aim_locator = 'loc_{}_{}AimTarget_{:03d}'.format(side, description, index)
grp_locator = aim_locator.replace('loc_', 'driven_')
pnt_con = cmds.listConnections(grp_locator, source=True, destination=False, plugs=False)[0]
driver_node = cmds.listConnections(pnt_con + '.target[0].targetTranslate', source=True, destination=False,
plugs=False)[0]
# get world up vector
aim_vector = [1, 0, 0]
world_up_vector = [0, 1, 0]
if side == 'r':
aim_vector = [-1, 0, 0]
world_up_vector = [0, -1, 0]
# create cMuscle spline
spline_node, ctrls, jnts, grp_spline = make_spline(side, description, index, ctrl_num=control_number,
jnt_num=joint_number, control_mid=control_mid)
# create pos group to present muscle joint's position
grp_pos = 'zero_{}_{}MusSpline_{:03d}'.format(side, description, index)
cmds.createNode('transform', name=grp_pos)
cmds.matchTransform(grp_pos, mus_joint, position=True, rotation=True)
cmds.parent(grp_pos, mus_group)
# connect with muscle joint's position
cmds.connectAttr(mus_joint + '.translate', grp_pos + '.translate')
cmds.connectAttr(mus_joint + '.rotate', grp_pos + '.rotate')
# parent to muscle joint
cmds.parent(grp_spline, grp_pos)
# snap the position
cmds.matchTransform(grp_spline, grp_pos, position=True, rotation=True)
# do a temp aim constraint to orient the group
cmds.delete(cmds.aimConstraint(end_joint, grp_spline, aimVector=[0, 1, 0], upVector=[-1, 0, 0],
worldUpType='objectrotation', worldUpObject=mus_joint,
worldUpVector=world_up_vector, maintainOffset=False))
# snap each control to its position
# snap the end control
cmds.matchTransform(ctrls[-1].replace('ctrl', 'zero'), end_joint, position=True, rotation=False)
# snap the in-between so driven node will get lesser offset value
for i in range(1, control_number - 1):
# get weight value
weight = i / float(control_number - 1)
# get zero group
zero = ctrls[i].replace('ctrl', 'zero')
# point constraint with start and end
pnt_con = cmds.pointConstraint(ctrls[0], ctrls[-1], zero, maintainOffset=False)[0]
cmds.setAttr('{}.{}W0'.format(pnt_con, ctrls[0]), 1 - weight)
cmds.setAttr('{}.{}W1'.format(pnt_con, ctrls[-1]), weight)
# delete point constraint
cmds.delete(pnt_con)
# point constraint end control driven with muscle joint's end joint
ctrl_end_driven = ctrls[-1].replace('ctrl', 'driven')
cmds.pointConstraint(aim_locator, ctrl_end_driven, maintainOffset=False)
# reverse aim set up for end control
aim_node = cmds.createNode('transform', name='grp_{}_{}EndAim_{:03d}'.format(side, description, index))
zero_aim_node = cmds.createNode('transform', name=aim_node.replace('grp', 'zero'))
cmds.parent(aim_node, zero_aim_node)
cmds.matchTransform(zero_aim_node, end_joint, position=True)
# parent to driver node
cmds.parent(zero_aim_node, driver_node)
# temp aim back to muscle group to get orientation
cmds.delete(cmds.aimConstraint(mus_joint, zero_aim_node, maintainOffset=False,
aimVector=aim_vector, upVector=world_up_vector,
worldUpType='objectrotation', worldUpVector=world_up_vector))
cmds.pointConstraint(aim_locator, aim_node, maintainOffset=False)
cmds.aimConstraint(mus_group, aim_node, maintainOffset=False, aimVector=aim_vector,
upVector=world_up_vector, worldUpType='none')
# add offset transform
offset_grp = cmds.createNode('transform', name='grp_{}_{}EndAimOffset_{:03d}'.format(side, description, index))
cmds.parent(offset_grp, aim_node)
cmds.matchTransform(offset_grp, ctrl_end_driven, position=True, rotation=True)
# orient constraint with end control's driven node
cmds.orientConstraint(offset_grp, ctrl_end_driven, maintainOffset=False)
# reset curve length and stretch squash limit
# get default curve length
crv_length = cmds.getAttr(spline_node + '.curLen')
# set as default
cmds.setAttr(spline_node + '.lenDefault', crv_length)
# set stretch and squash limit
cmds.setAttr(spline_node + '.lenStretch', crv_length * 2)
cmds.setAttr(spline_node + '.lenSquash', crv_length * 0.5)
# connect global scale
if scale_attr:
cmds.connectAttr(scale_attr, spline_node + '.userScale')
# hide muscle joints
cmds.setAttr(mus_joint + '.visibility', 0)
if mirror and side == 'l':
add_spline(mus_joint.replace('_l_', '_r_'), joint_number=joint_number, control_number=control_number,
control_mid=control_mid, mirror=False, scale_attr=scale_attr)
def mirror_muscle_spline_settings():
"""
mirror cMuscleSpline settings from left to right
"""
# get all left side muscle spline node and muscle spline controllers
spline_nodes = cmds.ls('cMuscleSpline_l_*MusSpline_???Shape')
spline_ctrls = cmds.ls('ctrl_l_*MusSpline?_???')
# loop in each node
for node in spline_nodes + spline_ctrls:
node_right = node.replace('_l_', '_r_')
# get all custom attrs
attrs = cmds.listAttr(node, userDefined=True)
for attr in attrs:
# check if it has connection or locked
node_attr = '{}.{}'.format(node, attr)
if not cmds.listConnections(node_attr, source=True, destination=False) and \
not cmds.getAttr(node_attr, lock=True):
val = cmds.getAttr(node_attr)
cmds.setAttr('{}.{}'.format(node_right, attr), val)
Holy code Batman, 505 lines!
I don't have the time to check all your code for mistakes. But I can tell you why nothing happens.
You have a lot of functions, but you aren't calling them anywhere. So all that happens, is that the functions get commited to Memory but they are never called and therefore never exectued.
Here is an easy example:
#This is the functiond definition, it commits what the function does to Memory
def Func():
""" Something happens here """
print("test")
#This is the function call, it gets runs the function from Memory
Func()
So if you want to run your functions, you need to call it.
I hope it helps! 🙂
Can't find what you're looking for? Ask the community or share your knowledge.