我最终为此做的是实现this,它似乎与maya的复制皮肤权重相应地工作。我确实有它检查多边形是否是凸的,如果是,它只会在最近的三角形上使用常规的重心坐标。
这里是根据@Paul 的要求进行的更新。我搜集了这个,希望它有所帮助。我认为这是我做的一个非常早的测试。
import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
if __name__ == '__main__':
pnts = []
p1 = OpenMaya.MVector(*cmds.xform("p0",
query=True,
worldSpace=True,
translation=True))
p2 = OpenMaya.MVector(*cmds.xform("p1",
query=True,
worldSpace=True,
translation=True))
p3 = OpenMaya.MVector(*cmds.xform("p2",
query=True,
worldSpace=True,
translation=True))
p4 = OpenMaya.MVector(*cmds.xform("p3",
query=True,
worldSpace=True,
translation=True))
p5 = OpenMaya.MVector(*cmds.xform("p4",
query=True,
worldSpace=True,
translation=True))
pnts.append(p1)
pnts.append(p2)
pnts.append(p3)
pnts.append(p4)
pnts.append(p5)
p = OpenMaya.MVector(*cmds.xform("p",
query=True,
worldSpace=True,
translation=True))
vertCount = len(pnts)
weights = []
si = []
for i, pnt in enumerate(pnts):
si.append(pnts[i] - p)
Ri = []
Ai = []
Di = []
for i, pnt in enumerate(pnts):
iPlus = (i+1) % vertCount
ri = si[i].length()
ai = (si[i] ^ si[iPlus]).length()/2.0
di = si[i] * si[iPlus]
if round(ri, 7) == 0.0:
print("%s : 1.0." % i)
Ri = []
Ai = []
Di = []
break
elif round(ai, 7) == 0.0 and round(di, 7) < 0.0:
riPlus = si[iPlus].length()
print("%s : %s" % (i, ri/(ri+riPlus)))
print("%s : %s" % (iPlus, riPlus/(ri+riPlus)))
Ri = []
Ai = []
Di = []
break
else:
Ri.append(ri)
Ai.append(ai)
Di.append(di)
if not len(Ri) == 0 or not len(Ai) == 0 or not len(Di) == 0:
for i, pnt in enumerate(pnts):
iPlus = (i+1) % vertCount
iMinus = (i-1) % vertCount
w = 0.0
if not Ai[iMinus] == 0.0:
w += (Ri[iMinus] - Di[iMinus] / Ri[i]) / Ai[iMinus]
if not Ai[i] == 0.0:
w += (Ri[iPlus] - Di[i] / Ri[i]) / Ai[i]
weights.append(w)
weightSum = sum(weights)
finalWeights = [weight/weightSum for weight in weights]
print("Weights: ", finalWeights)