Created
June 3, 2019 14:22
-
-
Save Onefabis/c0d2b7f63aa28df5665a5c39879ac9be to your computer and use it in GitHub Desktop.
Grow Skin Weights from selected vertices to adjacent vertices
This file contains hidden or 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
import maya.api.OpenMaya as om2 | |
import maya.api.OpenMayaAnim as oma2 | |
import maya.cmds as mc | |
class growSkinWeights(object): | |
def __init__(self): | |
self.cIds = None | |
def growSkinDo(self, mode): | |
selVerts = om2.MGlobal.getActiveSelectionList() | |
# Get selected verts indices | |
if selVerts.length() == 0: | |
mc.warning('Please, select any vertex') | |
return | |
dp, comp = selVerts.getComponent(0) | |
compFn = om2.MFnSingleIndexedComponent(comp) | |
if comp.isNull(): | |
mc.warning('Please, select any vertex') | |
return | |
ids = compFn.getElements() | |
if mode == 'copy': | |
self.cIds = ids | |
else: | |
# Get all mesh vertices and edges count | |
numVertices = om2.MFnMesh( dp ).numVertices | |
numEdges = om2.MFnMesh( dp ).numEdges | |
# Get skinCluster from the mesh | |
self.skinCl = mc.ls( mc.listHistory( dp, pdo=1, il=2 ), typ='skinCluster' ) | |
if self.skinCl and self.cIds is not None: | |
# Convert skinCluster to MFnSkinCluster to be able extract influences and weights from it | |
self.skinFn = oma2.MFnSkinCluster( om2.MSelectionList().add( self.skinCl[0] ).getDependNode(0) ) | |
# get the MDagPath for all influence | |
infDags = self.skinFn.influenceObjects() | |
self.allInfs = infDags | |
self.infIds = {} | |
for x in xrange(infDags.__len__()): | |
infPath = infDags[x].fullPathName() | |
infId = int(self.skinFn.indexForInfluenceObject(infDags[x])) | |
self.infIds[x] = infId | |
# unlock influences used by skincluster | |
mc.setAttr('%s.liw' % infPath) | |
# get the MPlug for the weightList and weights attributes | |
self.wlPlug = self.skinFn.findPlug( 'weightList',0 ) | |
self.wPlug = self.skinFn.findPlug( 'weights',0 ) | |
self.wlAttr = self.wlPlug.attribute() | |
self.wAttr = self.wPlug.attribute() | |
# Get selected and unselected vertices that share the same edge | |
idsShareEdge = {} | |
meshEdgeIt = om2.MItMeshEdge( dp ) | |
for e in xrange(numEdges): | |
meshEdgeIt.setIndex(e) | |
vertEdgeId = ( meshEdgeIt.vertexId(0), meshEdgeIt.vertexId(1) ) | |
if vertEdgeId[0] in self.cIds and vertEdgeId[1] in ids: | |
#print vertEdgeId[0], vertEdgeId[1] | |
self.setGrowSkinWeights( vertEdgeId[0], vertEdgeId[1] ) | |
elif vertEdgeId[1] in self.cIds and vertEdgeId[0] in ids: | |
#print vertEdgeId[1], vertEdgeId[0] | |
self.setGrowSkinWeights( vertEdgeId[1], vertEdgeId[0] ) | |
else: | |
mc.warning( 'Something went wrong, please copy skin weights again' ) | |
def setGrowSkinWeights( self, origVert, affectVert ): | |
vWeights = {} | |
# tell the weights attribute which vertex id it represents | |
self.wPlug.selectAncestorLogicalIndex(origVert, self.wlAttr) | |
# get the indice of all non-zero weights for this vert | |
wInfIds = self.wPlug.getExistingArrayAttributeIndices() | |
# create a copy of the current wPlug | |
infPlug = om2.MPlug(self.wPlug) | |
for infId in xrange(len(self.allInfs)): | |
# tell the infPlug it represents the current influence id | |
infPlug.selectAncestorLogicalIndex(self.infIds[infId], self.wAttr) | |
# add this influence and its weight to this verts weights | |
if infId in self.infIds.keys(): | |
mc.setAttr( '%s.weightList[%s].weights[%s]' %( self.skinCl[0], affectVert, self.infIds[infId] ), infPlug.asDouble() ) | |
else: | |
infNum = int(self.skinFn.indexForInfluenceObject(self.allInfs[infId])) | |
mc.setAttr( '%s.weightList[%s].weights[%s]' %( self.skinCl[0], affectVert, infNum ), 0 ) | |
gr = growSkinWeights() | |
gr.growSkinDo('copy') | |
#gr.growSkinDo('paste') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment