Skip to content

Instantly share code, notes, and snippets.

@Onefabis
Created June 3, 2019 14:22
Show Gist options
  • Save Onefabis/81bdba26c5cf85f05e5b5b52b20b8851 to your computer and use it in GitHub Desktop.
Save Onefabis/81bdba26c5cf85f05e5b5b52b20b8851 to your computer and use it in GitHub Desktop.
Grow Skin Weights from selected vertices to adjacent vertices
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