Python API: Read outputValue in a custom deformer

218 views
Skip to first unread message

Arturo Alcibia

unread,
Apr 10, 2018, 7:07:07 PM4/10/18
to Python Programming for Autodesk Maya
Hi guys, I'm still fiddling with the python API, I'm unclear about what is the correct way to do some things.

I have two meshes, one as an input and one as an output. I'm inheriting from MPxDeformerNode.
This deformer will read its input and output and evaluate once what vertices are in the same worldspace of the both meshes, it will create a dict and in the deform method will iterate through the vertices and move the matched output vertices from how the input move. 

Basically I'm trying to implement a control-less rig as shown here: https://vimeo.com/207167769

I have already solved how to iterate through the vertices and get the matched ones, but I don't know how to access the output geometry and the verts position from the compute method, and if I should, 

Also how to get the matching vertices only once per connection. I guess using attributeAffects will only evaluate once, but I'm unsure if I should store them as a list in python or use sets in Maya or something like that, I'm pretty lost at that part.

Thank you!

justin hidair

unread,
Apr 11, 2018, 10:45:55 PM4/11/18
to Python Programming for Autodesk Maya
I don't really understand your concerns , you mean you want to set the output mesh ?

Arturo Alcibia

unread,
Apr 12, 2018, 6:55:40 PM4/12/18
to Python Programming for Autodesk Maya
Hi! I want to read the points' position of the output mesh

Marcus Ottosson

unread,
Apr 12, 2018, 6:57:26 PM4/12/18
to python_in...@googlegroups.com
Would it be possible to share an example of what you've got so far?​

Arturo Alcibia

unread,
Apr 12, 2018, 7:11:01 PM4/12/18
to Python Programming for Autodesk Maya
Hi! Sure, this is the complete code:

import maya.OpenMayaMPx as OpenMayaMPx
import maya.OpenMaya as OpenMaya
 
class BlendNode(OpenMayaMPx.MPxDeformerNode):
kPluginNodeId = OpenMaya.MTypeId(0x00000002)
 
aBlendMesh = OpenMaya.MObject()
aBlendWeight = OpenMaya.MObject()
 
def __init__(self):
OpenMayaMPx.MPxDeformerNode.__init__(self)

self.matchedVertices = {}


def compute(self, pPlug, data):

if pPlug == self.outputGeom:

iBlendMesh = data.inputValue(BlendNode.aBlendMesh).asMesh()
fnBlendMesh = OpenMaya.MFnMesh(iBlendMesh)

blendPoints = OpenMaya.MPointArray()
fnBlendMesh.getPoints(blendPoints)

outputMeshHandle = data.outputValue( self.outputGeom ).asMesh()
fnOutputMesh = OpenMaya.MFnMesh(outputMeshHandle)
outputPoints = OpenMaya.MPointArray()
fnOutputMesh.getPoints(outputPoints)
print outputPoints.length()

 
def deform(self, data, itGeo, localToWorldMatrix, mIndex):
pass

def creator():
return OpenMayaMPx.asMPxPtr(BlendNode())
 
def initialize():
tAttr = OpenMaya.MFnTypedAttribute()
nAttr = OpenMaya.MFnNumericAttribute()
 
BlendNode.aBlendMesh = tAttr.create('blendMesh', 'bm', OpenMaya.MFnData.kMesh)
BlendNode.addAttribute( BlendNode.aBlendMesh )
 
outputGeom = OpenMayaMPx.cvar.MPxDeformerNode_outputGeom
BlendNode.attributeAffects(BlendNode.aBlendMesh, outputGeom)
 
BlendNode.aBlendWeight = nAttr.create('blendWeight', 'bw', OpenMaya.MFnNumericData.kFloat)
nAttr.setKeyable(True)
BlendNode.addAttribute(BlendNode.aBlendWeight)
BlendNode.attributeAffects(BlendNode.aBlendWeight, outputGeom)
 
# Make deformer weights paintable
cmds.makePaintable('blendNode', 'weights', attrType='multiFloat', shapeMode='deformer')
 
def initializePlugin(obj):
plugin = OpenMayaMPx.MFnPlugin(obj, 'Chad Vernon', '1.0', 'Any')
try:
plugin.registerNode('blendNode', BlendNode.kPluginNodeId, creator, initialize, OpenMayaMPx.MPxNode.kDeformerNode)
except:
raise RuntimeError, 'Failed to register node'
 
def uninitializePlugin(obj):
plugin = OpenMayaMPx.MFnPlugin(obj)
try:
plugin.deregisterNode(BlendNode.kPluginNodeId)
except:
raise RuntimeError, 'Failed to deregister node'





Basically what I want to do is to compare the vertices of the input mesh and the output mesh and check which ones are in the same worldSpace, store them in a list, and perform the desired operations in the deform method, I want to move the matched output vertices to the input vertices as shown in the video I shared,

I'm stuck at reading the points from the output Mesh.

justin hidair

unread,
Apr 12, 2018, 8:24:21 PM4/12/18
to Python Programming for Autodesk Maya
Lol , you're gonna have to be clearer than that, still don't understand what you're trying to do friend ,maybe compare the vtx positions of the input and output ? cache the output and do it then ? I feel like you want to access the output node itself , and I don't think it's recommended to be that savage bro, just sayin' , your example code seem like a basic template for deformer implementation , it doesn't say alot idk ;

Michael Boon

unread,
Apr 15, 2018, 6:16:21 PM4/15/18
to Python Programming for Autodesk Maya
You're trying to do the point snapper, from around 10:20 in that video? It sounds to me like you need two input meshes - a "source" and a "target"  - and you want to store a list of verts that are the same in those two, then when verts move in the source, you want to move verts in a copy of the target, and then output that to an output mesh plug.

"Source" I think is what you're currently calling "input". It's the small control mesh.
"Target" is part of what you're currently calling "output". It will be the same visible mesh as the output, but it's an input plug on your deformer and (I think) would be connected to the outmesh plugin of an "intermediate object" in the construction history of that mesh.

I think if it was me, I'd start by trying to convert polyModifierCmd example in the docs to Python (or do it in C++...this looks like it will be slow in Python), then add a "source" mesh input to that. (You could maybe skip the part where it tries to make a tweak node, for now at least.)

Arturo Alcibia

unread,
Apr 16, 2018, 12:34:19 PM4/16/18
to Python Programming for Autodesk Maya
Thanks Michael for the answer, there are still tons of things I don't understand about the API but you've helped me to start in the correct path, I will do a lot of research and start with the devkit example you told me. I will come back to post (hopefully) the answer.

I guess by intermediate object you mean somehing like "ShapeOrig" node that gets created when a deformer, skincluster, etc is applied and contains the mesh before the deformer was applied.

Michael Boon

unread,
Apr 16, 2018, 7:21:22 PM4/16/18
to Python Programming for Autodesk Maya

I guess by intermediate object you mean somehing like "ShapeOrig" node that gets created when a deformer, skincluster, etc is applied and contains the mesh before the deformer was applied.

Yes, that's it.

I haven't written a node like this either, but it looks like you need to write a "geometry filter" node (aka a "deformer"), which is the sort of node that moves verts, like a skincluster or a lattice deformer. Check out "Writing a Deformer Node" here:
http://help.autodesk.com/view/MAYAUL/2018/ENU/?guid=__files_Writing_a_Deformer_Node_htm
Reply all
Reply to author
Forward
0 new messages