PDA

View Full Version : extract dagPath from inMesh (python)


mfg
06-11-2012, 02:58 PM
Hi,
As a api learning exercise i am trying to write a node that takes a kMesh input and has a kVectorArray as output.
Everything seems to work but i only get the local position.My guess is to get worldspace i just have to add om.MSpace.kWorld when using .getPoints (MFnMesh).

However as far as i understand i need to get the dagpath from the inMesh in order for kWorld to work. I have searched the forums, devkit and google'd but could not find an example on how to get the dagpath in the compute part of a node.

Can someone show me how to do this?, i am puzzled...


this is the main part of the node so far:



# Node definition
class myVtxPosNode(ommpx.MPxNode):
# input attributes
inputAttr = om.MDagPath

# output attributes
outputAttr = om.MObject

def __init__(self):
ommpx.MPxNode.__init__(self)

def compute(self, plug, dataBlock):

# if these attributes are requested, recompute their values
if (plug == myVtxPosNode.outputAttr):

# get the incoming data
input_dataHandle = om.MDataHandle(dataBlock.inputValue(myVtxPosNode.inputAttr))
inMesh = input_dataHandle.asMesh()
inMeshFn=om.MFnMesh(inMesh)

#do somthing
outMeshMPointArray = om.MPointArray()
inMeshFn.getPoints(outMeshMPointArray,om.MSpace.kWorld)

myVectorArray = om.MVectorArray()
myVectorArray.setLength(outMeshMPointArray.length())

for i in range(outMeshMPointArray.length()):
result=om.MVector(outMeshMPointArray[i][0],outMeshMPointArray[i][1],outMeshMPointArray[i][2])
myVectorArray.set(result,i)

# set the output
output_dataHandle= om.MDataHandle(dataBlock.outputValue(myVtxPosNode.outputAttr))
out_vectorArrayFn=om.MFnVectorArrayData()
out_vectorArray=out_vectorArrayFn.create(myVectorArray)
output_dataHandle.setMObject(out_vectorArray)

# set the plug clean so maya knows it can update
dataBlock.setClean(plug)

Azrail
06-11-2012, 03:06 PM
You don't need the DAG path to do that. Here are two ways to do that without the DAG path:
1. Use
dataBlock.inputValue(attribute).asMeshTransformed()
this way if you connect the source mesh .worldMesh[0] attribute to your node's inMesh you will get the mesh points in worldspace.
2. Get the matrix of the input with :
dataBlock.inputValue(attribute).geometryTransformMatrix()

then just multiply each point with that matrix ( I assume you're already looping trough the points, since you calculate vectors).

mfg
06-11-2012, 03:29 PM
Thx a lot, now i feel silly, the answer was so simple...

This node works:



import maya.cmds as mc
import maya.OpenMaya as om

import maya.OpenMayaMPx as ommpx



kPluginNodeName = "myVtxPosNode"

#kcompUtilNodeClassify = "utility/general"

kPluginNodeId = om.MTypeId(0x00392)



# Node definition

class myVtxPosNode(ommpx.MPxNode):



# input attributes

inputAttr = om.MObject



# output attributes

outputAttr = om.MObject





def __init__(self):

ommpx.MPxNode.__init__(self)



def compute(self, plug, dataBlock):



# if these attributes are requested, recompute their values

if (plug == myVtxPosNode.outputAttr):



# get the incoming data

input_dataHandle = om.MDataHandle(dataBlock.inputValue(myVtxPosNode.inputAttr))

inMesh = input_dataHandle.asMeshTransformed()

inMeshFn=om.MFnMesh(inMesh)



#do somthing

outMeshMPointArray = om.MPointArray()

inMeshFn.getPoints(outMeshMPointArray)



myVectorArray = om.MVectorArray()

myVectorArray.setLength(outMeshMPointArray.length())



for i in range(outMeshMPointArray.length()):

result=om.MVector(outMeshMPointArray[i][0],outMeshMPointArray[i][1],outMeshMPointArray[i][2])

myVectorArray.set(result,i)



# set the output

output_dataHandle= om.MDataHandle(dataBlock.outputValue(myVtxPosNode.outputAttr))

out_vectorArrayFn=om.MFnVectorArrayData()

out_vectorArray=out_vectorArrayFn.create(myVectorArray)

output_dataHandle.setMObject(out_vectorArray)



# set the plug clean so maya knows it can update

dataBlock.setClean(plug)



# creator

def nodeCreator():

return ommpx.asMPxPtr(myVtxPosNode())



# initializer

def nodeInitializer():



tAttr = om.MFnTypedAttribute()



# input attributes

myVtxPosNode.inputAttr = tAttr.create("Input","In", om.MFnData.kMesh)



# ouput attributes

myVtxPosNode.outputAttr = tAttr.create("Output","Out",om.MFnData.kVectorArray)

tAttr.setWritable(False)

tAttr.setStorable(False)




# add the attributes

myVtxPosNode.addAttribute(myVtxPosNode.inputAttr)

myVtxPosNode.addAttribute(myVtxPosNode.outputAttr)



# Setup which attributes affect each other

myVtxPosNode.attributeAffects(myVtxPosNode.inputAttr, myVtxPosNode.outputAttr)



# initialize the script plug-in

def initializePlugin(mobject):

mplugin = ommpx.MFnPlugin(mobject, "Martin", "1.0", "Any")

try:

mplugin.registerNode( kPluginNodeName, kPluginNodeId, nodeCreator, nodeInitializer )

except:

sys.stderr.write( "Failed to register command: %s\n" % kPluginNodeName )

raise



# uninitialize the script plug-in

def uninitializePlugin(mobject):

mplugin = ommpx.MFnPlugin(mobject)

try:

mplugin.deregisterNode( kPluginNodeId )

except:

sys.stderr.write( "Failed to unregister node: %s\n" % kPluginNodeName )

raise

tontonsuspect
06-12-2012, 05:00 PM
hello mfg, just a quick note on your code:

tAttr.setUsesArrayDataBuilder(True) is used when you have a network type of attribute: weight[0], weight[1], weight[n] etc it is used hand to hand with tAttr.setArray(True)


MFnData.kVectorArray --> is a single piece of data traveling through only 1 attribute( does your original intention was to connect several vectorArray to your node?)

mfg
06-13-2012, 10:15 AM
Thx tontonsuspect,
i think its a leftover line from some other node attempt i tried :) ill take it out

CGTalk Moderation
06-13-2012, 10:15 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.