Yet again, I'm attempting to reimplement this approach
(http://www.alecjacobson.com/weblog/?p=2104#comments) to skinning, but
using the SoUP toolset as a base. SoUP's "point" node is basically an
expression node for mesh geometry, so I thought I'd use it to try to figure
out the skin method that paper proposes. It's not as fast as a deformer
node, but at least I didn't have to figure out how to setup/access weights
and influences for it. What I did was:
-I created a point node and connect the outputGeometry attribute of the
skinCluster to it, then connect the point's output to the original
destination mesh the skinCluster was using
-I also connected the intermediate geometry to the point node to negate the
deformation that the skinCluster makes (I could also have set the
skinCluster envelope to 0, I guess)
-I created two script nodes: one to execute the other when the scene opens.
The first script node executes the "before" attribute of the second
scriptNode through the "python" mel command. The second script is the
actual attempt at the STBS deformer function which I wrote as this:
*import maya.OpenMaya as OM*
*import maya.cmds as cmds*
*import maya.mel as mel*
*import math*
*def stbs(shape,idx,x,y,z):*
* #return(x,y,z)*
* inVec = OM.MVector(x,y,z)*
* outVec = OM.MVector()*
* skinNode = mel.eval("findRelatedSkinCluster(\""+shape+"\")")*
* skinJoints =
cmds.skinPercent(skinNode,(shape+".vtx["+`idx`+"]"),q=True,transform=None)*
* for i in range(len(skinJoints)):*
* skinWt = cmds.getAttr(skinNode+".weightList["+`idx`+"].weights["+`i`+"]")*
* prevMat = cmds.getAttr(skinNode + ".bindPreMatrix["+`i`+"]")*
* baseXfPos = OM.MVector(prevMat[12],prevMat[13],prevMat[14])*
* rx = math.radians(cmds.xform(skinJoints[i],q=True,ws=True,ro=True)[0])*
* ry = math.radians(cmds.xform(skinJoints[i],q=True,ws=True,ro=True)[0])*
* rz = math.radians(cmds.xform(skinJoints[i],q=True,ws=True,ro=True)[0])*
* jRot = [rx,ry,rz]*
* jPos = cmds.xform(skinJoints[i],q=True,ws=True,t=True)*
* euler = OM.MEulerRotation(jRot[0],jRot[1],jRot[2])*
* translate = OM.MVector(jPos[0],jPos[1],jPos[2])*
* translate = (translate*skinWt)+(baseXfPos*skinWt)*
* euler = euler*skinWt*
* outVec += (inVec*skinWt-translate).rotateBy(euler)*
* outVec += translate*
* return (outVec.x,outVec.y,outVec.z)*
-Finally, in the points "Position" attribute (the actual expression string
attribute, which already has built-in variables for point
positions,normals,indices,etc), I put this:
*// POINT POSITION*
*$px=$TX2;*
*$py=$TY2;*
*$pz=$TZ2;*
*float $newPos[] =
`python("stbs(\"polySurfaceShape1\","+$ID+","+$px+","+$py+","+$pz+")")`;*
*$X = $newPos[0];*
*$Y = $newPos[1];*
*$Z = $newPos[2];*
Well, the approach didn't work for the most part. I didn't need to cancel
out rotations because I just tested this with a capsule-like mesh and all
the joints are aligned on the x-axis. However some points have popped to
the origin, and only the rotateX attribute for each of the joints appear to
be influencing anything, but it isn't twisting properly. Could somebody
please help me figure out this issue?
--
view archives: http://groups.google.com/group/python_inside_maya
change your subscription settings:
http://groups.google.com/group/python_inside_maya/subscribe