def _buildPoseDict(self, nodes): ''' Build the internal poseDict up from the given nodes. This is the core of the Pose System ''' if self.metaPose: getMetaDict=self.metaRig.getNodeConnectionMetaDataMap # optimisation for i,node in enumerate(nodes): key=r9Core.nodeNameStrip(node) self.poseDict[key]={} self.poseDict[key]['ID']=i # selection order index self.poseDict[key]['longName']=node # longNode name if self.metaPose: self.poseDict[key]['metaData']=getMetaDict(node) # metaSystem the node is wired too channels=r9Anim.getSettableChannels(node,incStatics=True) if channels: self.poseDict[key]['attrs']={} for attr in channels: try: if cmds.getAttr('%s.%s' % (node,attr),type=True)=='TdataCompound': # blendShape weights support attrs=cmds.aliasAttr(node, q=True)[::2] # extract the target channels from the multi for attr in attrs: self.poseDict[key]['attrs'][attr]=cmds.getAttr('%s.%s' % (node,attr)) else: self.poseDict[key]['attrs'][attr]=cmds.getAttr('%s.%s' % (node,attr)) except: log.debug('%s : attr is invalid in this instance' % attr)
def _buildPoseDict(self, nodes): """ Build the internal poseDict up from the given nodes. This is the core of the Pose System """ if self.metaPose: getMetaDict = self.metaRig.getNodeConnectionMetaDataMap # optimisation for i, node in enumerate(nodes): key = r9Core.nodeNameStrip(node) self.poseDict[key] = {} self.poseDict[key]["ID"] = i # selection order index self.poseDict[key]["longName"] = node # longNode name if self.metaPose: self.poseDict[key]["metaData"] = getMetaDict(node) # metaSystem the node is wired too channels = r9Anim.getSettableChannels(node, incStatics=True) if channels: self.poseDict[key]["attrs"] = {} for attr in channels: if attr in self.skipAttrs: log.debug("Skipping attr as requested : %s" % attr) continue try: if ( cmds.getAttr("%s.%s" % (node, attr), type=True) == "TdataCompound" ): # blendShape weights support attrs = cmds.aliasAttr(node, q=True)[::2] # extract the target channels from the multi for attr in attrs: self.poseDict[key]["attrs"][attr] = cmds.getAttr("%s.%s" % (node, attr)) else: self.poseDict[key]["attrs"][attr] = cmds.getAttr("%s.%s" % (node, attr)) except: log.debug("%s : attr is invalid in this instance" % attr)
def _buildPoseDict(self, nodes): ''' Build the internal poseDict up from the given nodes. This is the core of the Pose System ''' getMirrorID = r9Anim.MirrorHierarchy().getMirrorCompiledID if self.metaPose: getMetaDict = self.metaRig.getNodeConnectionMetaDataMap # optimisation for i, node in enumerate(nodes): key = r9Core.nodeNameStrip(node) self.poseDict[key] = {} self.poseDict[key]['ID'] = i # selection order index self.poseDict[key]['longName'] = node # longNode name mirrorID = getMirrorID(node) if mirrorID: self.poseDict[key]['mirrorID'] = mirrorID if self.metaPose: self.poseDict[key]['metaData'] = getMetaDict( node) # metaSystem the node is wired too channels = r9Anim.getSettableChannels(node, incStatics=True) if channels: self.poseDict[key]['attrs'] = {} for attr in channels: if attr in self.skipAttrs: log.debug('Skipping attr as requested : %s' % attr) continue try: if cmds.getAttr( '%s.%s' % (node, attr), type=True ) == 'TdataCompound': # blendShape weights support attrs = cmds.aliasAttr( node, q=True )[:: 2] # extract the target channels from the multi for attr in attrs: self.poseDict[key]['attrs'][ attr] = cmds.getAttr('%s.%s' % (node, attr)) else: self.poseDict[key]['attrs'][attr] = cmds.getAttr( '%s.%s' % (node, attr)) except: log.debug('%s : attr is invalid in this instance' % attr)
def removeAttrsToRecord(self, attrs=None, *args): node = cmds.ls(sl=True, l=True)[0] if not attrs: attrs = r9Anim.getChannelBoxSelection() if attrs: cmds.recordAttr(node, at=attrs, delete=True) else: raise StandardError('No Channels selected in the ChannelBox to Set')
def removeAttrsToRecord(self,attrs=None,*args): node=cmds.ls(sl=True,l=True)[0] if not attrs: attrs=r9Anim.getChannelBoxSelection() if attrs: cmds.recordAttr(node,at=attrs,delete=True) else: raise StandardError('No Channels selected in the ChannelBox to Set')
def _matchNodesToPoseData(self, nodes): ''' Main filter to extract matching data pairs prior to processing return : tuple such that : (poseDict[key], destinationNode) NOTE: I've changed this so that matchMethod is now an internal PoseData attr :param nodes: nodes to try and match from the poseDict ''' matchedPairs = [] log.info('using matchMethod : %s' % self.matchMethod) if self.matchMethod == 'stripPrefix' or self.matchMethod == 'base': log.info('matchMethodStandard : %s' % self.matchMethod) matchedPairs = r9Core.matchNodeLists( [key for key in self.poseDict.keys()], nodes, matchMethod=self.matchMethod) if self.matchMethod == 'index': for i, node in enumerate(nodes): for key in self.poseDict.keys(): if int(self.poseDict[key]['ID']) == i: matchedPairs.append((key, node)) log.info('poseKey : %s %s >> matchedSource : %s %i' % (key, self.poseDict[key]['ID'], node, i)) break if self.matchMethod == 'mirrorIndex': getMirrorID = r9Anim.MirrorHierarchy().getMirrorCompiledID for node in nodes: mirrorID = getMirrorID(node) if not mirrorID: continue for key in self.poseDict.keys(): if self.poseDict[key]['mirrorID'] and self.poseDict[key][ 'mirrorID'] == mirrorID: matchedPairs.append((key, node)) log.info( 'poseKey : %s %s >> matched MirrorIndex : %s' % (key, node, self.poseDict[key]['mirrorID'])) break if self.matchMethod == 'metaData': getMetaDict = self.metaRig.getNodeConnectionMetaDataMap # optimisation poseKeys = dict(self.poseDict) # optimisation for node in nodes: try: metaDict = getMetaDict(node) for key in poseKeys: if poseKeys[key]['metaData'] == metaDict: matchedPairs.append((key, node)) poseKeys.pop(key) break except: log.info( 'FAILURE to load MetaData pose blocks - Reverting to Name' ) matchedPairs = r9Core.matchNodeLists( [key for key in self.poseDict.keys()], nodes) return matchedPairs
def addAttrsToRecord(self, attrs=None, *args): node = cmds.ls(sl=True, l=True)[0] if not attrs: attrs = r9Anim.getChannelBoxSelection() if attrs: try: if self.rotateInRads and self.currAngularUnits == 'deg': log.info('setting AngularUnits to Radians') cmds.currentUnit(angle='rad') cmds.recordAttr(node, at=attrs) except: pass finally: cmds.currentUnit(angle=self.currAngularUnits) log.info('setting AngularUnits back to Degrees') else: raise StandardError('No Channels selected in the ChannelBox to Set')
def addAttrsToRecord(self,attrs=None,*args): node=cmds.ls(sl=True,l=True)[0] if not attrs: attrs=r9Anim.getChannelBoxSelection() if attrs: try: if self.rotateInRads and self.currAngularUnits=='deg': log.info('setting AngularUnits to Radians') cmds.currentUnit(angle='rad') cmds.recordAttr(node,at=attrs) except: pass finally: cmds.currentUnit(angle=self.currAngularUnits) log.info('setting AngularUnits back to Degrees') else: raise StandardError('No Channels selected in the ChannelBox to Set')
def bind_skeletons(source, dest, method='connect', scales=False, verbose=False, unlock=False, bindroot=True): ''' From 2 given root joints search through each hierarchy for child joints, match them based on node name, then connect their trans/rots directly, or parentConstrain them. Again cmds for speed :param source: the root node of the driving skeleton :param dest: the root node of the driven skeleton :param method: the method used for the connection, either 'connect' or 'constrain' :param scale: do we bind the scales of the destination skel to the source?? :param unlock: if True force unlock the required transform attrs on the destination skeleton first ''' sourceJoints = cmds.listRelatives(source, ad=True, f=True, type='joint') destJoints = cmds.listRelatives(dest, ad=True, f=True, type='joint') if verbose: result = cmds.confirmDialog( title='Bind Skeletons SCALES', message= ("Would you also like to process the SCALE channels within the bind?" ), button=['Yes', 'No'], messageAlign='center', icon='question', dismissString='Cancel') if result == 'Yes': scales = True else: scales = False # parent constrain the root nodes regardless of bindType, fixes issues where # we have additional rotated parent groups on the source if bindroot: cmds.parentConstraint(source, dest) if scales: cmds.scaleConstraint(source, dest, mo=True) # attrs to 'connect' and also to ensure are unlocked attrs = [ 'rotateX', 'rotateY', 'rotateZ', 'translateX', 'translateY', 'translateZ' ] if scales: attrs = attrs + ['scaleX', 'scaleY', 'scaleZ', 'inverseScale'] if unlock: r9Core.LockChannels().processState(dest, attrs=attrs, mode='fullkey', hierarchy=True) for sJnt, dJnt in match_given_hierarchys(sourceJoints, destJoints): if method == 'connect': for attr in attrs: try: cmds.connectAttr('%s.%s' % (sJnt, attr), '%s.%s' % (dJnt, attr), f=True) except: pass elif method == 'constrain': # need to see if the channels are open if not, change this binding code try: cmds.parentConstraint(sJnt, dJnt, mo=True) except: chns = r9Anim.getSettableChannels(dJnt) if all([ 'translateX' in chns, 'translateY' in chns, 'translateZ' in chns ]): cmds.pointConstraint(sJnt, dJnt, mo=True) elif all( ['rotateX' in chns, 'rotateY' in chns, 'rotateZ' in chns]): cmds.orientConstraint(sJnt, dJnt, mo=True) else: log.info('Failed to Bind joints: %s >> %s' % (sJnt, dJnt)) # if we have incoming scale connections then run the scaleConstraint if scales: # and cmds.listConnections('%s.sx' % sJnt): try: cmds.scaleConstraint(sJnt, dJnt, mo=True) # turn off the compensation so that the rig can still be scaled correctly by the MasterNode # cmds.setAttr('%s.segmentScaleCompensate' % dJnt, 0) except: print('failed : scales ', dJnt)
def bind_skeletons(source, dest, method='connect', scales=False, verbose=False): ''' From 2 given root joints search through each hierarchy for child joints, match them based on node name, then connect their trans/rots directly, or parentConstrain them. Again cmds for speed :param source: the root node of the driving skeleton :param dest: the root node of the driven skeleton :param method: the method used for the connection, either 'connect' or 'constrain' :param scale: do we bind the scales of the destination skel to the source?? ''' sourceJoints = cmds.listRelatives(source, ad=True, f=True, type='joint') destJoints = cmds.listRelatives(dest, ad=True, f=True, type='joint') if verbose: result = cmds.confirmDialog(title='Bind Skeletons SCALES', message=("Would you also like to process the SCALE channels within the bind?"), button=['Yes', 'No'], messageAlign='center', icon='question', dismissString='Cancel') if result == 'Yes': scales = True else: scales = False # parent constrain the root nodes regardless of bindType, fixes issues where # we have additional rotated parent groups on the source cmds.parentConstraint(source, dest) if scales: cmds.scaleConstraint(source, dest, mo=True) attrs = ['rotateX', 'rotateY', 'rotateZ', 'translateX', 'translateY', 'translateZ'] if scales: attrs = attrs + ['scaleX', 'scaleY', 'scaleZ'] for sJnt, dJnt in match_given_hierarchys(sourceJoints, destJoints): if method == 'connect': for attr in attrs: try: cmds.connectAttr('%s.%s' % (sJnt, attr), '%s.%s' % (dJnt, attr), f=True) except: pass elif method == 'constrain': # need to see if the channels are open if not, change this binding code try: cmds.parentConstraint(sJnt, dJnt, mo=True) except: chns = r9Anim.getSettableChannels(dJnt) if all(['translateX' in chns, 'translateY' in chns, 'translateZ' in chns]): cmds.pointConstraint(sJnt, dJnt, mo=True) elif all(['rotateX' in chns, 'rotateY' in chns, 'rotateZ' in chns]): cmds.orientConstraint(sJnt, dJnt, mo=True) else: log.info('Failed to Bind joints: %s >> %s' % (sJnt, dJnt)) # if we have incoming scale connections then run the scaleConstraint if scales: # and cmds.listConnections('%s.sx' % sJnt): try: cmds.scaleConstraint(sJnt, dJnt, mo=True) # turn off the compensation so that the rig can still be scaled correctly by the MasterNode # cmds.setAttr('%s.segmentScaleCompensate' % dJnt, 0) except: print 'failed : scales ', dJnt