Reading info from the MFnMessageAttribute

336 views
Skip to first unread message

MaxtorAG

unread,
Sep 25, 2008, 3:51:50 AM9/25/08
to python_inside_maya
Hi guys!

1. I need som good books/tutorials on Maya API! :(

2. I am setting up a node with 2 message input attributes (one for
connecting message from fluid and another from particle)

This is what I have in compute function def:

def compute(self, plug, dataBlock):

print "1. preparing"
result = "1. preparing"

connections = om.MPlugArray()
connection = om.MPlug()

plugParticleNode = om.MPlug()
plugParticleNode.setAttribute(self.particleNode) #this is the
connection to the message att
connectedToParticleNode = om.MObject()

plugFluidNode = om.MPlug()
plugFluidNode.setAttribute(self.fluidNode) #this is the
connection to the message att
connectedToFluidNode = om.MObject()

print "2.computed"
result = "2.computed"

# check if a particle is connected to the particleNode input
plugParticleNode.connectedTo(connections,1,0)
if (connections.length() > 0):
connection = connections[0]
connectedToParticleNode = connection.node()
try:
connectedParticleNode =
omFX.MFnParticleSystem(connectedToParticleNode) # I will be later
using function set to read particle atts
particleConnected = 1
except:
statusError("Not valid particle shape connected")
particleConnected = 0
else:
particleConnected = 0

print "3.particle checked with value %d" % particleConnected
result = "3.particle checked with value %d" %
particleConnected

# check if a fluid is connected to the fluidNode input
plugFluidNode.connectedTo(connections,1,0)
if (connections.length() > 0):
connection = connections[0]
connectedToFluidNode = connection.node()
try:
connectedFluidNode =
omFX.MFnFluid(connectedToFluidNode) # I will be later using function
set to read fluid atts
fluidConnected = 1
except:
statusError("Not valid fluid shape connected")
fluidConnected = 0
else:
fluidConnected = 0

print "4.fluid checked with value %d" % fluidConnected
result = "4.fluid checked with value %d" % fluidConnected

Problem:
1. I did not know how to construct the MPlug with function (MObject,
Attribute) (there is no thisObject() function in python API?) So I
just created it and then assigned

2. When I create the node, everything works. I get the correct integer
number for my debugging (0 for both). As soon as I connect anything to
those message atts, I get crash. Even without that, when I after
creation try to create new scene, I get crash. If I comment out the
connection checking functions, nothing crashes.

Btw...That's all I compute, nothing after this part of code except of
setting custom debugging attribute to the *result* value value.

Simon

unread,
Sep 25, 2008, 4:52:21 AM9/25/08
to python_in...@googlegroups.com
hi GUY :)

- 3DBUZZ.com offers A NEW mayaPython DVD ...
http://www.3dbuzz.com/xcart/product.php?productid=54&cat=16&page=1

( i ordered it last week / i can tell you , how it is , when the
shipping arrives - hope they will send it by "plane" - HAHA )

- there is one "Autodesk" DVD "Python for Maya" / it shows how to create
a simple-PYTHON-node ( really basic stuff , and you won't learn much
from it )
http://store.autodesk.com/DRHM/servlet/ControllerServlet?Action=DisplayProductDetailsPage&SiteID=adsk&Locale=en_US&productID=98208500

- i got the Digital-Tutors DVD somewhere , i think there is also a
"tiny" part about scripted-plugins on it . but i do not think , it is so
informative - as it is mainly about python-basics

API:
there are 2 Books
"Complete Maya Programming" by David Gould / you can find them on Amazon
... here you can learn a lot about API ( C++ )

... there is not much python-API-information on the internet yet / but
somehow , you can to try to "translate" the C++ API-tutorials into
Python / python_API is easier to learn than C++ , as you can "source"
the code directly in Maya without compiling it .

Information about maya-API :
http://www.robthebloke.org/mayaapi.html
http://comet-cartoons.com/3ddocs/mayaAPI/

hope that helps you a little , although i can't tell anything about
fluids ...

sim.On


MaxtorAG schrieb:

Mario Dubec

unread,
Sep 25, 2008, 4:57:22 AM9/25/08
to python_in...@googlegroups.com
Thanks ;)

I have seen the DT and Autodesk DVDs (somwhat useful, but...that I could figure just from examples in devkit ;)

I am thinking just exactly about that book...will see, but not everything is so easily translated

MaxtorAG

2008/9/25 Simon <sim.mn...@googlemail.com>

Dean Edmonds

unread,
Sep 25, 2008, 8:32:01 AM9/25/08
to python_in...@googlegroups.com
On Thu, Sep 25, 2008 at 12:51 AM, MaxtorAG <maxt...@gmail.com> wrote:
>
> Problem:
> 1. I did not know how to construct the MPlug with function (MObject,
> Attribute) (there is no thisObject() function in python API?)

Use MPxNode::thisMObject().

> 2. When I create the node, everything works. I get the correct integer
> number for my debugging (0 for both). As soon as I connect anything to
> those message atts, I get crash. Even without that, when I after
> creation try to create new scene, I get crash. If I comment out the
> connection checking functions, nothing crashes.

The purpose of a node's compute() method is to compute the value of a
requested output attribute using the values of one or more of the
node's input attributes. Maya will call your node's compute() whenever
it needs the value of one of your node's attributes which may have
changed since it was last retrieved. Note that this is true not just
for attributes which you have added to your node, but also for
standard attributes which Maya provides for every node.

In your compute() you are executing your code every time it is called,
regardless of the attribute whose value is being requested.
Furthermore, your code is not computing anything, by which I mean that
it never sets the datablock values for any output attributes. So Maya
is calling your compute() to get values for various attributes, but
you are not providing any. I'm guessing that that is what is causing
the crash, though there are other possibilities as well.

The code that you have in your compute() just seems to be checking to
be sure that the correct types of nodes are connected to the plugs.
The compute() is not the right place to do that. If you really want to
be sure that only the correct type of node is connected, then provide
an override for the MPxNode::legalConnection() method. Do the check
there and refuse the connection if it is to the wrong node type.

As for the compute() itself, the question you must ask yourself is:
what are the outputs and what are the inputs that you need to compute
each of those outputs?

--
-deane

Mario Dubec

unread,
Sep 25, 2008, 8:42:13 AM9/25/08
to python_in...@googlegroups.com
Thanks, Dean...but

I used this ccecking in compute while I was translating one C++ node from devkit (particleAttributeNode I think).

What I did not say in the script, but I have, is the final part of the computation:

outputHandle = dataBlock.outputValue(node.debugMe)
outputHandle.setString(result)
dataBlock.setClean(plug)

while I have set the attribute relationship as:
attributeAffects(node.enableDensity, node.debugMe) #enable density is always on

I am trying to construct this node in parts while constantly debugging (if I would just run the shole compute, which will be large, it would be hard to identify errors)

So basically the compute method goes thru itself and sets node's attribute debugMe to appropriate value based on the computation stage

so I was expecting, when nothing is connected, the value would be 0 and stage 4
when I connect appropriate nodes, value would be 1 and stage 4

but I get crash only :(

2008/9/25 Dean Edmonds <dean.e...@gmail.com>

Dean Edmonds

unread,
Sep 25, 2008, 10:03:37 AM9/25/08
to python_in...@googlegroups.com
On Thu, Sep 25, 2008 at 5:42 AM, Mario Dubec <maxt...@gmail.com> wrote:
>
> I used this ccecking in compute while I was translating one C++ node from
> devkit (particleAttributeNode I think).

I would still recommend moving that code out to either the
legalConnection/legalDisconnection methods or
connectionMade/connectionBroken. I doubt that will fix your crash, but
it's a good start to cleaning up the compute().

The particleAttributeNode sample node is doing it the way that it is
because, quite frankly, it's badly written. The author tried to cram
what should be two different nodes into one and ended up with some bad
code as a result.

> What I did not say in the script, but I have, is the final part of the
> computation:
>
> outputHandle = dataBlock.outputValue(node.debugMe)
> outputHandle.setString(result)
> dataBlock.setClean(plug)

In that case you should only be executing your code when the plug
passed to your compute() method is for 'debugMe'. For all others your
compute() method should immediately return
om.MStatus.kUnknownParameter.

> so I was expecting, when nothing is connected, the value would be 0 and
> stage 4
> when I connect appropriate nodes, value would be 1 and stage 4
>
> but I get crash only :(

At which stage does it crash?

--
-deane

Mario Dubec

unread,
Sep 25, 2008, 10:16:02 AM9/25/08
to python_in...@googlegroups.com
Ok, i will try that if statement at the beginning.

It crashes either:
1. when i plug anything into it, correct or incorrect does not matter
2. when I have plugin loaded and try to create new scene in current Maya session

If I comment out the checking part, nothing from above mentioned happens ;)

By moving it to connection methods, should I call them at the beginning of compute? Or return some status from them? (like unknown parameter) Never used those :( I am quite new to API :(

2008/9/25 Dean Edmonds <dean.e...@gmail.com>

Dean Edmonds

unread,
Sep 25, 2008, 11:09:08 AM9/25/08
to python_in...@googlegroups.com
On Thu, Sep 25, 2008 at 7:16 AM, Mario Dubec <maxt...@gmail.com> wrote:
> Ok, i will try that if statement at the beginning.
>
> It crashes either:
> 1. when i plug anything into it, correct or incorrect does not matter
> 2. when I have plugin loaded and try to create new scene in current Maya
> session

No, I meant at what point in your compute() method does it crash. You
have a print statement at each stage. What's the last one to be
displayed before it crashes?

> By moving it to connection methods, should I call them at the beginning of
> compute? Or return some status from them? (like unknown parameter) Never
> used those :( I am quite new to API :(

You don't need to call the connection methods at all. Maya will call
them whenever a connection is made to your node or broken. So you'd
want something like this:

import maya.OpenMaya as om
import maya.OpenMayaFX as omfx

class myNode(om.MPxNode):
particleNode = om.MObject() # to hold particleNode attr
fluidNode = om.MObject() # to hold fluidNode attr
debugMe = om.MObject() # to hold debugMe attr

def __init__(self):
self.particleNodeValid = False
self.fluidNodeValid = False
ompx.MPxNode.__init__(self)

def connectionMade(self, myPlug, otherPlug, iAmSrc):
if not iAmSrc:
if myPlug == myNode.particleNode:
otherNode = otherPlug.node()

# If the connection is to a particle node, mark it valid.
if otherNode.hasFn(om.MFn.kParticle):
self.particleNodeIsValid = True
self.particleNodeFn = omfx.MFnParticleSystem(otherNode)
else:
self.particleNodeIsValid = False
self.particleNodeFn = None

elif myPlug == myNode.fluidNode:
otherNode = otherPlug.node()

# If the connection is to a fluid node, mark it valid.
if otherNode.hasFn(om.MFn.kFluid):
self.fluidNodeIsValid = True
self.fluidNodeFn = omfx.MFnFluid(otherNode)
else:
self.fluidNodeIsValid = False
self.fluidNodeFn = None

def connectionBroken(self, myPlug, otherPlug, iWasSrc):
if not iWasSrc:
if myPlug == myNode.particleNode:
self.particleNodeIsValid = False
self.particleNodeFn = None
elif myPlug == myNode.fluidNode:
self.fluidNodeIsValid = False
self.fluidNodeFn = None

def compute(self, plug, block):
if plug == myNode.debugMe:
if self.particleNodeIsValid and self.fluidNodeIsValid:
result = "both connected"
elif self.particleNodeIsValid:
result = "particle connected"
elif self.fluidNodeIsValid:
result = "fluid connected"
else
result = "neither connected"

block.outputValue(myNode.debugMe).setString(result)
return om.MStatus.kSuccess

# This is not an attribute that I recognize, so let Maya know that
it should handle it.
return om.MStatus.kUnknownParameter

So you use connectionMade and connectionBroken to maintain a pair of
flags indicating which connections are currently valid. I've also got
them creating the corresponding function sets so that they'll be ready
for compute() to use when its needs them. If you find that it's still
crashing then try having compute() create the functionsets for itself.

The compute() simply checks the flags to see what's valid and takes
action based on that.

--
-deane

Mario Dubec

unread,
Sep 25, 2008, 11:16:43 AM9/25/08
to python_in...@googlegroups.com
Thanks a lot, dean!

Will try it later this evening.

Problem with crashing is that it does not print anyting (when I create node, it prints all the status messages one by one with correct values)
When I connect/create new scene, maya just crashes...I haven't really noticed any print statement in script editor. But I will try to incorporate more substep printing to see what part of the checking procedure does the crashing.

Will let you know about the progress.

Thanks for your help, again!

MaxtorAG

2008/9/25 Dean Edmonds <dean.e...@gmail.com>
Reply all
Reply to author
Forward
0 new messages