Source code for zBuilder.nodes.deformers.skinCluster

from zBuilder.nodes.dg_node import DGNode
import maya.cmds as mc
import maya.OpenMaya as OpenMaya
import maya.OpenMayaAnim as OpenMayaAnim


[docs]class SkinCluster(DGNode): """ The base node for the node functionality of all nodes """ type = 'skinCluster' TYPES = [] """ The type of node. """ SEARCH_EXCLUDE = ['_class', 'attrs', '_builder_type', 'type'] """ List of attributes to exclude with a string_replace""" EXTEND_ATTR_LIST = list() """ List of maya attributes to add to attribute list when capturing.""" def __init__(self, *args, **kwargs): self.influences = list() self.weights = dict() DGNode.__init__(self, *args, **kwargs)
[docs] def populate(self, maya_node=None): """ This extends ZivaBase.populate() Adds parent and child storage. Args: maya_node: Maya node to populate with. """ super(SkinCluster, self).populate(maya_node=maya_node) self.weights = get_weights(self.name) self.influences = get_influences(self.name) self.association = get_associations(self.name)
[docs] def build(self, *args, **kwargs): interp_maps = kwargs.get('interp_maps', 'auto') attr_filter = kwargs.get('attr_filter', None) name = self.name if not mc.objExists(name): mc.select(self.influences, self.association, r=True) skin_cluster = mc.skinCluster(tsb=True, n=name) self.mobject = skin_cluster[0] else: self.mobject = name self.set_maya_attrs(attr_filter=attr_filter)
# self.set_maya_weights(interp_maps=interp_maps) # apply_weights(self.name, self.association, self.influences, self.weights)
[docs]def get_associations(skin_cluster): return mc.skinCluster(skin_cluster, g=True, q=True)
[docs]def get_influences(skin_cluster): return mc.skinCluster(skin_cluster, q=True, influence=True)
[docs]def apply_weights(skin_cluster, mesh, influences, weights): # unlock influences used by skincluster for inf in influences: mc.setAttr('%s.liw' % inf, 0) # normalize needs turned off for the prune to work skinNorm = mc.getAttr('%s.normalizeWeights' % skin_cluster) if skinNorm != 0: mc.setAttr('%s.normalizeWeights' % skin_cluster, 0) mc.skinPercent(skin_cluster, mesh, nrm=False, prw=100) # restore normalize setting if skinNorm != 0: mc.setAttr('%s.normalizeWeights' % skin_cluster, skinNorm) # set the weights for attr, vals in weights.items(): for idx, val in vals.items(): # print cluster,attr,idx,val mc.setAttr('%s.%s[%s]' % (skin_cluster, attr, str(idx)), val)
[docs]def get_weights(skin_cluster): # get the MFnSkinCluster for skinCluster selList = OpenMaya.MSelectionList() selList.add(skin_cluster) clusterNode = OpenMaya.MObject() selList.getDependNode(0, clusterNode) skinFn = OpenMayaAnim.MFnSkinCluster(clusterNode) # get the MDagPath for all influence infDags = OpenMaya.MDagPathArray() skinFn.influenceObjects(infDags) # create a dictionary whose key is the MPlug indice id and # whose value is the influence list id infIds = {} infs = [] for x in xrange(infDags.length()): infPath = infDags[x].fullPathName() infId = int(skinFn.indexForInfluenceObject(infDags[x])) infIds[infId] = x infs.append(infPath) # get the MPlug for the weightList and weights attributes wlPlug = skinFn.findPlug('weightList') wPlug = skinFn.findPlug('weights') wlAttr = wlPlug.attribute() wAttr = wPlug.attribute() wInfIds = OpenMaya.MIntArray() # the weights are stored in dictionary, the key is the vertId, # the value is another dictionary whose key is the influence id and # value is the weight for that influence weights = {} for vId in xrange(wlPlug.numElements()): vWeights = {} # tell the weights attribute which vertex id it represents wPlug.selectAncestorLogicalIndex(vId, wlAttr) # get the indice of all non-zero weights for this vert wPlug.getExistingArrayAttributeIndices(wInfIds) # create a copy of the current wPlug infPlug = OpenMaya.MPlug(wPlug) for infId in wInfIds: # tell the infPlug it represents the current influence id infPlug.selectAncestorLogicalIndex(infId, wAttr) # add this influence and its weight to this verts weights try: vWeights[infIds[infId]] = infPlug.asDouble() except KeyError: # assumes a removed influence pass weights['weightList[' + str(vId) + '].weights'] = vWeights return weights