Behnam Hasani

Get Barycentric weights using Maya Api


import maya.cmds as mc
import maya.OpenMaya as OpenMaya
mesh = "pSphereShape1"
source = "locatorShape1"
deformer = "deltaMush1"

# get object and attach it to the MFnDependencyNode
# we can access mesh data with Dependency node function set
selection = OpenMaya.MSelectionList()
selection.add(mesh)
selection.add(source)
selection.add(deformer)
meshDag = OpenMaya.MDagPath()
sourceDag = OpenMaya.MDagPath()
defObj = OpenMaya.MObject()
selection.getDagPath(0, meshDag)
selection.getDagPath(1, sourceDag)
selection.getDependNode(2, defObj)
defFn = OpenMaya.MFnDependencyNode(defObj)

# accessing weightList and query the values
weightsPlug = defFn.findPlug("weightList")
for i in range(weightsPlug.numElements()):
    weightIdxPlug = weightsPlug.elementByPhysicalIndex(i) 
for j in range(weightIdxPlug.numChildren()):
    weights = weightIdxPlug.child(j) # "cluster1.weightList[0].weights"
weightList = {} 
for i in range(weights.numElements()):
    val = weights.elementByPhysicalIndex(i).asFloat()
    weightList[i] = val

#get the source object position
mMatrix = sourceDag.exclusiveMatrix()
locMatrix = OpenMaya.MTransformationMatrix( mMatrix )
locPoint = OpenMaya.MPoint( locMatrix.getTranslation( OpenMaya.MSpace.kWorld ))

#find the closest point on mesh from our source
meshIntersector = OpenMaya.MMeshIntersector()
pointInfo = OpenMaya.MPointOnMesh()
meshIntersector.create(meshDag.node(), meshDag.exclusiveMatrix())
meshIntersector.getClosestPoint(locPoint, pointInfo)

#create the list pointer
uUtil = OpenMaya.MScriptUtil(0.0)
uPtr = uUtil.asFloatPtr()
vUtil = OpenMaya.MScriptUtil(0.0)
vPtr = vUtil.asFloatPtr()
pointerList = OpenMaya.MScriptUtil()
ListIntPtr = pointerList.asIntPtr()

#get BarycentricCoords weights
pointInfo.getBarycentricCoords(uPtr,vPtr)
u = uUtil.getFloat(uPtr)
v = vUtil.getFloat(vPtr)
w = 1-u-v
faceId = pointInfo.faceIndex()
triId = pointInfo.triangleIndex()

#find the current face from pointed vertices
currentFace = OpenMaya.MItMeshPolygon(meshDag)
pointArray = OpenMaya.MPointArray()
vertIdList = OpenMaya.MIntArray()
currentFace.setIndex(faceId, ListIntPtr)
currentFace.getTriangle(triId, pointArray, vertIdList, OpenMaya.MSpace.kWorld )

#get the weights & multipy them by barycentric weights
P0 = weightList[vertIdList[0]]
P1 = weightList[vertIdList[1]]
P2 = weightList[vertIdList[2]]

# final weight for the source
source_weight = u*P0 + v*P1 + w*P2