MFnSkinCluster.setWeights doesn't work from multiple weights at once.

1,018 views
Skip to first unread message

meljunky

unread,
Oct 11, 2009, 6:06:24 PM10/11/09
to python_inside_maya
I am using the setWeights method from the MFnSkinCluster class and
there are 2 types:

Single weight to a list of components (single influence object)
setWeights(MDagPath const &,MObject const &,unsigned
int,double,bool,MDoubleArray *)
setWeights(MDagPath const &,MObject const &,unsigned
int,float,bool,MFloatArray *)

Multiple weights to a list of components at once (multiple influence
objects)
setWeights(MDagPath const &,MObject const &,MIntArray &,MDoubleArray
&,bool,MDoubleArray *)
setWeights(MDagPath const &,MObject const &,MIntArray &,MFloatArray
&,bool,MFloatArray *)

I am trying to call the multiple weights my arguments as:
MDagPath: The shape Node
MObject: Derived from currentItem() from the MItGeometry class
MIntArray: Tried both a python list and MIntArray. The same size as
the influence objects
MDoubleArray/MFloatArray: A tuple of the new values. The same size as
the influence objects
bool: Tried both True and 1
MDoubleArray/MFloatArray: A list of the old values. The same size as
the influence objects

I am getting the following error:
# TypeError: in method 'MFnSkinCluster_setWeights', argument 4 of type
'unsigned int' # ('self' from the class is the first argument)

Which means its trying to execute the single weight method. I am
trying to avoid having to use the single weight method since it will
increase the loop dramatically or having to use skinPercent MEL
command.

Not sure if this is something I am doing wrong or if the Python API is
incapable of the multiple weight method.

Thanks for the help,
-brian
www.meljunky.com

Paul Molodowitch

unread,
Oct 11, 2009, 6:39:57 PM10/11/09
to python_in...@googlegroups.com
Hmm... I wish I could help, as I could swear I got an error similar to
this at one point. I have a fuzzy memory that the message was a
little misleading - one of the other arguments was actually of the
incorrect type, or somesuch (I'm guessing it complains about the 4th
arg not being an int because it just tries all the different
call-signatures in some arbitrary order - if it doesn't match any, it
just gives the error message for whatever the last call-signature it
happened to try was...?).

Anyway, when I made that call, i used:

mfnSkin.setWeights(an_MDagPath,
a_component_MObject,
an_MIntArray,
an_MDoubleArray,
False,
another_MDoubleArray)

(If you're curious, you can take a look at some code that makes such a
call at: http://github.com/elrond79/pmHeatWeight)

Definitely worth using this version of the call if you can get it to
work, as the time savings are VERY big over the single-influence
version.

- Paul

br...@meljunky.com

unread,
Oct 11, 2009, 9:34:29 PM10/11/09
to python_in...@googlegroups.com
Thanks paul, I realize two difference with my call and your call with heat wave.

Mistake 1:
MDoubleArray/MFloatArray: A list of the old values. The same size as the influence objects
Solution:
This return the old value to be used for undo. I'm not suppose to past it the old values. I thought it was an undo support by passing the old values, so the undo could work. Now that I read the help docs again, I see that I just simply missed it. Suppose, it would of overwritten my values is I passed it a MDoubleArray/MFloatArray... but didn't check it since its not important.

Mistake 2:
MIntArray: Tried both a python list and MIntArray. The same size as the influence objects
MDoubleArray/MFloatArray: A tuple of the new values. The same size as the influence objects
Solution:
I thought it was good enough sending lists/tuples as arguments. Maya really wants a MIntArray and a MDoubleArray/MFloatArray as arguments. I have seen it before where it have worked with lists/tuples. But, not with this. Once I passed it the correct type for both it worked fine.

Thanks,
-brian

Brandon Harris

unread,
Nov 5, 2009, 5:36:40 PM11/5/09
to python_inside_maya
OK. I felt it was appropriate to post my issue here because it falls
inline with this issue.

j=0
while not compItr.isDone():
self.tmpOldSkinWeights = []
self.skinCluster.setWeights(self.relatedShape,compItr.currentItem
(),self.infIndices,self.newWeightsArray,True,self.throwAwayWeights)
for i in xrange(self.throwAwayWeights.length()):
self.tmpOldSkinWeights.append(self.throwAwayWeights[i])
self.oldSkinWeights.insert(j, self.tmpOldSkinWeights)
j = j+1
compItr.next()

OK. so first off, this works exactly the way that I want it to. It
takes the new weights and applies them to the proper components. Now
because I'm iterating over the components and the old weights that are
returned are overwritten with each pass, I have elected to catch the
values and put them into a list of lists so I can use them for Undos.
So when I undo I want this to happen.

compItr = openMaya.MItGeometry(self.objectPath, self.objectComps)
i = 0
while not compItr.isDone():
self.skinCluster.setWeights(self.relatedShape,compItr.currentItem
(),self.infIndices,self.oldSkinWeights[i],True,self.throwAwayWeights)
print self.oldSkinWeights[i]
i = i+1
compItr.next()

Now this is basically an exact mirror of the first part that works
correctly (as far as I know) but when used during the Undo it throw
this error.

// Error: line 1: in method 'MFnSkinCluster_setWeights', argument 4 of
type 'unsigned int'
# Traceback (most recent call last):
# File "/data/film/apps/reelfx/maya/plug-ins/linux/2009-x64/
TestCommand.py", line 189, in undoIt
# self.skinCluster.setWeights(self.relatedShape,compItr.currentItem
(),self.infIndices,self.oldSkinWeights[i],True,self.throwAwayWeights)
# TypeError: in method 'MFnSkinCluster_setWeights', argument 4 of type
'unsigned int' //


Also, for my self.infIndices I am doing this.

self.infIndices = openMaya.MIntArray()
for i in xrange(self.skinInfluences.length()):
self.infIndices.append(i)

Hopefully my tabbing hasn't gotten too bad with copying it over here,
but hopefully you get an idea for what I'm doing. It's the same error
meljunky was having, but it works fine unless I'm undoing. thanks in
advance!

Brandon L. Harris

br...@meljunky.com

unread,
Nov 5, 2009, 8:33:38 PM11/5/09
to python_in...@googlegroups.com
I am assuming that you set:
self.throwAwayWeights to a OpenMaya.MDoubleArray() to capture the skinCluster weights at some point.

Since each time you capture the old weights it over write the weights so they will all point to the weight (The last weight)
If you create a new OpenMaya.MDoubleArray() on each iteration that it will prevent a list of the same weights.

Here is the exert of my code for the undo creation array only:

while not toNode.MItGeometry.isDone():
 oldWeight = OpenMaya.MDoubleArray()
 ...
 toNode.skinCluster.setWeights (toNode.MDagPath, toNode.MItGeometry.currentItem(), iIndices, newWeights, True, oldWeight )
 toNode.oldWeights.append(oldWeight)

Since I recreated oldWeight on each iteration, toNode.oldWeights kept from pointing to the same MDoubleArray.

When I set the skinCluster back to its orginal weights with undo, I omitted the last argument, oldWeight.

As for you indicies problem.. here is an exact exert of my code:
iIndices = OpenMaya.MIntArray()
for i in range( toNode.influenceObjects.length() ):
 iIndices.append(i)

Don't see the probem with your version. How ever I was able to recreate the problem without touch the iIndices.

I changed:
oldWeight = OpenMaya.MDoubleArray()
to:
oldWeight = []

I got the following error:
# TypeError: in method 'MFnSkinCluster_setWeights', argument 4 of type 'unsigned int' #

So, the problem with yours is somewhere else. Make sure that each argument is created correctly.

Hope that helps,
-brian

-------- Original Message --------
Subject: [Maya-Python] Re: MFnSkinCluster.setWeights doesn't work from
multiple weights at once.

Brandon Harris

unread,
Nov 6, 2009, 2:19:23 PM11/6/09
to python_inside_maya
Absolutely perfect. Fixed my issue. I didn't think about recreating
oldWeights every iter. Originally I just appended it after each pass,
but because I was appending an instance it always changed all of the
values down the line so this way is very nice. Thanks!!

Brandon L. Harris
Reply all
Reply to author
Forward
0 new messages