Created
May 24, 2016 21:59
-
-
Save coxevan/947d58894c9772f3365ea7839c288bc6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def applyBtnCmd(self, *args): | |
# Grab and check info from UI lists and scroll areas. | |
attributes_to_mirror_list = self.driverScroll.getSelectItem() | |
driven_object_attribute_list = self.objAttrScroll.getSelectItem() | |
if len(attributes_to_mirror_list) < 1: | |
cmds.warning( 'No attribute to mirror selected' ) | |
return False | |
if len(driven_object_attribute_list) < 1: | |
cmds.warning( 'No driven attribute selected' ) | |
return False | |
# Organize the data from the UI as necesssary | |
attrToMirror = attributes_to_mirror_list[0] | |
driver = cmds.textField(self.driverTxt, query = True, tx = True) | |
driven = cmds.textField(self.drivenTxt, query = True, tx = True) | |
drivenObjs = self.objScroll.getSelectItem() | |
drivenAttr = driven_object_attribute_list[0] | |
# EC NOTE: What if the user has no object selected? | |
if not drivenObjs: | |
cmds.warning( 'No driven objs selected' ) | |
return False | |
# EC NOTE: Try to avoid try/except whenever possible. Bad python practice. | |
# EC NOTE:Strip your functionality from your interface so other tools can access this functionality without having to have the UI filled | |
# out/button clicks etc. | |
# Do the stuff now. | |
result, message = process_mirror_sdk( attrToMirror, driver, driven, driven_objs=drivenObjs, drivenAttr = drivenAttr ) | |
if not result: | |
cmds.warning( message ) | |
return True | |
def process_mirror_sdk( attr_to_mirror, driver, driven, driven_objs = None, drivenAttr = None ): | |
# Store existing animation curves | |
animCurves = cmds.listConnections( | |
driver + '.{}'.format(attrToMirror), | |
source=False, | |
destination=True, | |
type="animCurveUA" | |
) | |
if not animCurves: | |
# Early exit. | |
return False, 'Driver attribute has no connections' | |
for curve in animCurves: | |
curve_destination = pm.listConnections(curve, d=True, s=False, scn=True) | |
if pm.objectType(curve_destination[0], isType='blendWeighted'): | |
curve_destination = pm.listConnections(curve_destination, d=True, s=False, scn=True) | |
crvDest_parentCnt = getNumberOfParents(curve_destination) | |
for obj in drivenObjs: | |
drivenObj = pm.ls(obj) | |
drivenObj_parentCnt = getNumberOfParents(drivenObj) | |
# Instead of just having a conditional that skips the rest of the loop implicity, call it out so the reader is aware. | |
if drivenObj_parentCnt != crvDest_parentCnt: | |
continue | |
# Duplicate animation curve | |
dupCurve = cmds.duplicate(curve) | |
# Output driven obj's attr into the dup curve's input | |
cmds.connectAttr((driven + '.{}'.format(attrToMirror)), (dupCurve[0] + '.input')) | |
# The attribute to output the curve into | |
destination_attr = obj + ".{}".format(drivenAttr) | |
# Check to see if target object already has an incoming connection in given attribute. | |
# If so, a blendWeighted node has to be created | |
if cmds.connectionInfo(destination_attr, isDestination=True): | |
create_blend_weighted_node( dupCurve, destination_attr ) | |
# Output BlendWeighted to target object | |
cmds.connectAttr(blend_weighted + ".output", destination_attr) | |
else: | |
cmds.connectAttr(dupCurve[0] + '.output', destination_attr) | |
return True, 'Success!' | |
def create_blend_weighted_node( dupCurve, destination_attr ): | |
existing_curves = cmds.listConnections( | |
destination_attr, | |
source = True, | |
destination = False | |
) | |
blend_weighted = cmds.createNode( | |
"blendWeighted", | |
n = destination_attr + "_BLEND", | |
ss = True | |
) | |
for i in range(len(existing_curves)): | |
# Break connection b/w existing curve output and destination attr | |
cmds.disconnectAttr((existing_curves[i] + ".output"), destination_attr) | |
# Input existing curve output into blendWeighted | |
cmds.connectAttr((existing_curves[i] + ".output"), blend_weighted + ".input[{}]".format(i)) | |
# Input dup curve into blendWeighted | |
cmds.connectAttr(dupCurve[0] + '.output', blend_weighted + ".input[{}]".format(i + 1)) | |
return blend_weighted | |
def getNumberOfParents( obj ): | |
# Why is this method part of your class? it doesn't rely on any persistant logic. | |
parentsList = obj[0].getAllParents() | |
if parentsList: | |
return len(parentsList) | |
else: | |
return 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment