maya.api.openMaya setWeight 没有调用正确版本的函数
maya.api.openMaya setWeight not calling right version of function
我没有包括我用来跟踪 Maya 节点的补充文件,所以如果你看到 attr,就知道这是一种跟踪 dags/MObjects 以及传递变量和查找路径的方法来自那些被跟踪节点的属性。 Polygon 和 PolygonShape 类似 类,它们继承了该节点跟踪方法,但特定于那些类型的节点。他们的代码在这个文件中更靠前,但我排除了这些代码,以免使它的长度超过需要的时间。可以说,他们只是跟踪多边形 dag 和 polygonShape MObj。
这是我的问题。
# Error: line 1: TypeError: file D:/Libraries/My Documents/maya/scripts\toolbox\Shapes.py line 332: an integer is required #
332行是最下面的setWeight行
使用这段代码,我可以获得权重并通过它们的顶点将它们分开似乎很好,但是当我尝试设置权重时,它说它需要一个 int 变量。该 int 变量引用 setWeight 方法的逐个版本。出于某种原因,它不接受我提交的变量并恢复到错误的方法。我已经检查了进入该方法的所有类型。他们是正确的。我检查了影响的长度和权重的长度是否正确。因为它们是正确的类型和正确的长度,所以我只能假设它与 self.vertexComp 有关,但是 MObject 对于 get 工作正常,而且我已经看到这个 setWeights 的版本使用完全相同的方法。
任何人都可以看看这个,看看是什么导致 setWeight 出现该错误:
import maya.cmds as cmds
import Attributor as attr #custom package to interact with nodes
import maya.api.OpenMaya as om
import maya.api.OpenMayaAnim as omAnim
class skinCluster(attr.node):
outputGeometry = attr.connection("outputGeometry")
def getInfl_IDs(self,dagObj=False,pathFirst=False):
infDags = self.skinFn.influenceObjects()
infIds = {}
for x in xrange(len(infDags)):
infPath = attr.joint(nodeName=infDags[x].fullPathName()) if dagObj else infDags[x].fullPathName()
infId = int(self.skinFn.indexForInfluenceObject(infDags[x]))
if pathFirst:
infIds[infPath] = infId
else:
infIds[infId] = infPath
return dict(infIds)
# Returns something like {0:"joint1",1:"joint2"}
# useful for figuring out what list indexes to edit with weight tools
def __init__(self, nodeName=None, tracker=None, vertices=None, shapeNode=None):
if not nodeName and vertices:
nodeName = polygonShape(nodeName=vertices[0]).inMesh["in"][0]
self.initialize(nodeName=nodeName, tracker=tracker)
self.polygon = polygon(nodeName=self.outputGeometry["out"][0])
self.shapeNode = shapeNode if shapeNode else polygonShape(nodeName=self.polygon.shapeNodes[0].path)
self.skinFn = omAnim.MFnSkinCluster(self.tracker.obj)
self.vertexComp = om.MFnSingleIndexedComponent().create(om.MFn.kMeshVertComponent)
def getWeights(self, vertices=None):
vertWeights = self.skinFn.getWeights(self.polygon.tracker.dag, self.vertexComp)
weights = list(vertWeights[-2])
infCount = vertWeights[-1]
weights = [weights[x:x+infCount] for x in range(0,len(weights),infCount)]
dicty = {}
for i, weight in enumerate(weights):
if not vertices or i in vertices:
dicty.update({i:weight})
return dicty
# returns a vert weight list
# {0:[0.1, 0.2, 0.3, 0.4], 1:[etc..]}
def setWeights(self,values=None,normalize=True):
vertices = values.keys() #gets all the verts that are going to be edited
oldWeights = self.getWeights(vertices) #gets vert weights for undo
oldValues = []
newValues = []
influences = self.getInfl_IDs().keys() # gets the influence indices
for vert in vertices:
oldValues += oldWeights[vert] # combine weights into a list
newValues += values[vert] # combines the new weights to a list
self.skinFn.setWeights(self.polygon.tracker.dag, self.vertexComp,
om.MIntArray(influences), om.MDoubleArray(newValues),
normalize=normalize, oldValues=om.MDoubleArray(oldValues))
在打印以仔细检查类型时,这是输出:
<type 'OpenMaya.MDagPath'>
<type 'OpenMaya.MObject'>
<type 'OpenMaya.MIntArray'>
<type 'OpenMaya.MDoubleArray'>
<type 'bool'>
<type 'OpenMaya.MDoubleArray'>
来源材料:
https://gist.github.com/utatsuya/a95afe3c5523ab61e61b
http://download.autodesk.com/us/maya/2010help/api/class_m_fn_skin_cluster.html#52071d6c77ca374a4c8723f0c63e90e5
找到了一个具有类似问题的 post,但它似乎没有帮助。也许其他人会注意到他们的解决方案为何有效以及我遗漏了什么。
这与其说是一种解决方案,不如说是一种解决方法。我发现如果我从 setWeight 中取出 oldValues 它突然起作用了。
def setWeights(self,values=None,normalize=True):
vertices = values.keys()
oldWeights = self.getWeights()
newWeights = dict(oldWeights)
for key, value in values.iteritems():
newWeights[key] = value
oldValues = []
newValues = []
influences = self.getInfl_IDs().keys()
intArray = om.MIntArray()
intArray.copy(influences)
for vert in oldWeights.keys():
oldValues += oldWeights[vert]
newValues += newWeights[vert]
oldValues = om.MDoubleArray(oldValues)
newValues = om.MDoubleArray(newValues)
self.skinFn.setWeights(self.polygon.tracker.dag, self.vertexComp, intArray, newValues, normalize=normalize)
因此,如果有人知道旧值导致它调用错误方法的原因,请告诉我。
我发现 maya.api.OpenMayaAnim setWeight 函数是不可撤销的。您必须执行额外的步骤才能将其撤消,这很痛苦。所以我创建了一些东西来获取 getWeight 值并使用 skinPercent 命令来设置它们。
@property
def weights(self):
vertWeights = self.skinFn.getWeights(self.polygon.tracker.dag, self.vertexComp)
weights = list(vertWeights[-2])
infCount = vertWeights[-1]
weights = [weights[x:x + infCount] for x in range(0, len(weights), infCount)]
dicty = {}
for i, weight in enumerate(weights):
dicty.update({i: weight})
# returns {vert1:[weightValue0,weightValue1,weightValue2..],vert2:[etc..]}
# weight list index corresponds to influences from self.getInfl_IDs(), so it's easy to iterate weights using the index.
return dicty
@weights.setter
def weights(self, values):
#Will only set verts sent to it. Uses same data structure as get
influences = self.getInfl_IDs()
for vert, weights in values.iteritems():
tempy = []
for i, value in enumerate(weights):
tempy += [(influences[i],value)]
cmds.skinPercent(self.path, self.shapeNode.getVertName(vert), transformValue=tempy)
我没有包括我用来跟踪 Maya 节点的补充文件,所以如果你看到 attr,就知道这是一种跟踪 dags/MObjects 以及传递变量和查找路径的方法来自那些被跟踪节点的属性。 Polygon 和 PolygonShape 类似 类,它们继承了该节点跟踪方法,但特定于那些类型的节点。他们的代码在这个文件中更靠前,但我排除了这些代码,以免使它的长度超过需要的时间。可以说,他们只是跟踪多边形 dag 和 polygonShape MObj。
这是我的问题。
# Error: line 1: TypeError: file D:/Libraries/My Documents/maya/scripts\toolbox\Shapes.py line 332: an integer is required #
332行是最下面的setWeight行
使用这段代码,我可以获得权重并通过它们的顶点将它们分开似乎很好,但是当我尝试设置权重时,它说它需要一个 int 变量。该 int 变量引用 setWeight 方法的逐个版本。出于某种原因,它不接受我提交的变量并恢复到错误的方法。我已经检查了进入该方法的所有类型。他们是正确的。我检查了影响的长度和权重的长度是否正确。因为它们是正确的类型和正确的长度,所以我只能假设它与 self.vertexComp 有关,但是 MObject 对于 get 工作正常,而且我已经看到这个 setWeights 的版本使用完全相同的方法。
任何人都可以看看这个,看看是什么导致 setWeight 出现该错误:
import maya.cmds as cmds
import Attributor as attr #custom package to interact with nodes
import maya.api.OpenMaya as om
import maya.api.OpenMayaAnim as omAnim
class skinCluster(attr.node):
outputGeometry = attr.connection("outputGeometry")
def getInfl_IDs(self,dagObj=False,pathFirst=False):
infDags = self.skinFn.influenceObjects()
infIds = {}
for x in xrange(len(infDags)):
infPath = attr.joint(nodeName=infDags[x].fullPathName()) if dagObj else infDags[x].fullPathName()
infId = int(self.skinFn.indexForInfluenceObject(infDags[x]))
if pathFirst:
infIds[infPath] = infId
else:
infIds[infId] = infPath
return dict(infIds)
# Returns something like {0:"joint1",1:"joint2"}
# useful for figuring out what list indexes to edit with weight tools
def __init__(self, nodeName=None, tracker=None, vertices=None, shapeNode=None):
if not nodeName and vertices:
nodeName = polygonShape(nodeName=vertices[0]).inMesh["in"][0]
self.initialize(nodeName=nodeName, tracker=tracker)
self.polygon = polygon(nodeName=self.outputGeometry["out"][0])
self.shapeNode = shapeNode if shapeNode else polygonShape(nodeName=self.polygon.shapeNodes[0].path)
self.skinFn = omAnim.MFnSkinCluster(self.tracker.obj)
self.vertexComp = om.MFnSingleIndexedComponent().create(om.MFn.kMeshVertComponent)
def getWeights(self, vertices=None):
vertWeights = self.skinFn.getWeights(self.polygon.tracker.dag, self.vertexComp)
weights = list(vertWeights[-2])
infCount = vertWeights[-1]
weights = [weights[x:x+infCount] for x in range(0,len(weights),infCount)]
dicty = {}
for i, weight in enumerate(weights):
if not vertices or i in vertices:
dicty.update({i:weight})
return dicty
# returns a vert weight list
# {0:[0.1, 0.2, 0.3, 0.4], 1:[etc..]}
def setWeights(self,values=None,normalize=True):
vertices = values.keys() #gets all the verts that are going to be edited
oldWeights = self.getWeights(vertices) #gets vert weights for undo
oldValues = []
newValues = []
influences = self.getInfl_IDs().keys() # gets the influence indices
for vert in vertices:
oldValues += oldWeights[vert] # combine weights into a list
newValues += values[vert] # combines the new weights to a list
self.skinFn.setWeights(self.polygon.tracker.dag, self.vertexComp,
om.MIntArray(influences), om.MDoubleArray(newValues),
normalize=normalize, oldValues=om.MDoubleArray(oldValues))
在打印以仔细检查类型时,这是输出:
<type 'OpenMaya.MDagPath'>
<type 'OpenMaya.MObject'>
<type 'OpenMaya.MIntArray'>
<type 'OpenMaya.MDoubleArray'>
<type 'bool'>
<type 'OpenMaya.MDoubleArray'>
来源材料:
https://gist.github.com/utatsuya/a95afe3c5523ab61e61b
http://download.autodesk.com/us/maya/2010help/api/class_m_fn_skin_cluster.html#52071d6c77ca374a4c8723f0c63e90e5
找到了一个具有类似问题的 post,但它似乎没有帮助。也许其他人会注意到他们的解决方案为何有效以及我遗漏了什么。
这与其说是一种解决方案,不如说是一种解决方法。我发现如果我从 setWeight 中取出 oldValues 它突然起作用了。
def setWeights(self,values=None,normalize=True):
vertices = values.keys()
oldWeights = self.getWeights()
newWeights = dict(oldWeights)
for key, value in values.iteritems():
newWeights[key] = value
oldValues = []
newValues = []
influences = self.getInfl_IDs().keys()
intArray = om.MIntArray()
intArray.copy(influences)
for vert in oldWeights.keys():
oldValues += oldWeights[vert]
newValues += newWeights[vert]
oldValues = om.MDoubleArray(oldValues)
newValues = om.MDoubleArray(newValues)
self.skinFn.setWeights(self.polygon.tracker.dag, self.vertexComp, intArray, newValues, normalize=normalize)
因此,如果有人知道旧值导致它调用错误方法的原因,请告诉我。
我发现 maya.api.OpenMayaAnim setWeight 函数是不可撤销的。您必须执行额外的步骤才能将其撤消,这很痛苦。所以我创建了一些东西来获取 getWeight 值并使用 skinPercent 命令来设置它们。
@property
def weights(self):
vertWeights = self.skinFn.getWeights(self.polygon.tracker.dag, self.vertexComp)
weights = list(vertWeights[-2])
infCount = vertWeights[-1]
weights = [weights[x:x + infCount] for x in range(0, len(weights), infCount)]
dicty = {}
for i, weight in enumerate(weights):
dicty.update({i: weight})
# returns {vert1:[weightValue0,weightValue1,weightValue2..],vert2:[etc..]}
# weight list index corresponds to influences from self.getInfl_IDs(), so it's easy to iterate weights using the index.
return dicty
@weights.setter
def weights(self, values):
#Will only set verts sent to it. Uses same data structure as get
influences = self.getInfl_IDs()
for vert, weights in values.iteritems():
tempy = []
for i, value in enumerate(weights):
tempy += [(influences[i],value)]
cmds.skinPercent(self.path, self.shapeNode.getVertName(vert), transformValue=tempy)