API enums

187 views
Skip to first unread message

Judah Baron

unread,
Jan 19, 2010, 1:21:59 PM1/19/10
to python_inside_maya
Has anyone experienced problems using Maya's enum values?

We have had to use integer values directly because the enum values we get through the class is not correct. It appears to me that the enums coming through the python class are all zero based and 'localized' to the assocaited class, whereas maya's enums are generally a lot larger and seem to be coming from a larger 'global' list of unique values.

thanks,
-Judah


Adam Mechtley

unread,
Jan 19, 2010, 1:42:31 PM1/19/10
to python_in...@googlegroups.com
Could you elaborate a little or provide a specific example? In general, I have not had problems using enumerated types—certainly not where the values are incorrect. An enum in the C++ class simply corresponds to an integer value as far as Python is concerned, so corresponding zero-based integers can be used interchangeably where an enum is required. There are, as always, some exceptions, including a couple of bugs I am aware of:
  • MTransformationMatrix.getRotation Error (when using a rotation order enum)
  • api enums passed as reference
  • Python cannot accept pointer to integer as reference to enum type (need to use short instead)


Judah Baron

unread,
Jan 19, 2010, 3:59:06 PM1/19/10
to python_in...@googlegroups.com
We're using some of the MMessage classes to register callbacks. For MNodeMessage callbacks, the first argument passed in by Maya is the messageID. If we check to see if the messageID == OpenMaya.MNodeMessage.kConnectionMade it's always false because the value of OpenMaya.MNodeMessage.kConnectionMade is 1. The actual messageID coming in to the callback is 18433. The other MMessage related IDs are also not what I expected.

Prior to 2008 I didn't have this problem. But prior to 2008 there were other issues. As I recall, the MMessage family of classes were not fully implemented back then. They seem to be fully implemented now, in that they can actually be used, but associating the IDs is a little strange, especially when working with multiple versions of Maya.



Adam Mechtley

unread,
Jan 19, 2010, 6:01:23 PM1/19/10
to python_in...@googlegroups.com
If you look at the C++ devkit examples (or for that matter the explanation up in the Public Types section for MNodeMessage) you can see the problem. Namely, the enum values correspond to hexadecimal numbers. If you run hex() on the number, you will see what's going on:

hex(18433) is 0x4801, which means:
  • kOtherPlugSet (0x4000)
  • kIncomingDirection(0x800)
  • kConnectionMade(0x01)
I'm guessing the reason for this paradigm is so you are not sending a separate message for each of these events—otherwise you would have two or three messages sent for each attribute. As you can see in the C++ examples (e.g. nodeMessageCmd.cpp), a simple if-statement does not suffice—you must instead use the bitwise operator:

if ( msg & MNodeMessage::kConnectionMade ) {
    cout << "Connection made ";
} else if ( msg & MNodeMessage::kConnectionBroken ) {
    cout << "Connection broken ";
} else {
    return;
}

Thus, the same goes for Python:

if messageId & OM.MNodeMessage.kConnectionMade:
    # Do cool stuff

If a particular message code is not included, the if-statement will return 0 (false). If it is included, it will return decimal representation of the hex number for that enum, and thus pass the test.


Chad Dombrova

unread,
Jan 20, 2010, 12:11:39 AM1/20/10
to python_in...@googlegroups.com
each of the enum values is a bit-mask that can be combined into a single integer that represents a collection of settings.  these three options were active in the bit-mask that was returned in adam's example:
  • kOtherPlugSet (0x4000)
  • kIncomingDirection(0x800)
  • kConnectionMade(0x01)
here's a little more python code to show what's going on:

we'll continue from adam's example, where the integer contained in messageID is 18433. 

get the string representation of the hexidecimal bitmask
>>> hex(18433)
'0x4801'

python, in it's all-knowingness, provides an easy shorthand for working with hexidecimal values. enter in the hex representation, and it gives you an int
>>> 0x4801
18433

use the "bitwise or" to combine values:
>>> 0x4000 | 0x0800 | 0x0001
18433

so, it follows that:
>>> (0x4000 | 0x0800 | 0x0001) == 0x4801
True

to determine if a given option is in play, use "bitwise and".  in our case, we'll test if kIncomingDirection is enabled:
>>> bool(0x4801 & 0x800)
True

now test if kConnectionMade is set:
>>> bool(0x4801 & 0x01)
True

finally, test for a bitmask that has not been set (kAttributeAdded = 0x40):
>>> bool(0x4801 & 0x40)
False

bitmasks are often used in C/C++. more "descriptive" data types are usually favored in python, but since the maya python API is derived from C++, you'll have to leg up on the concepts.  i'm no expert myself (i've basically just told you all i know about bitmasks) so if i'm missing something, hopefully someone else will jump in with a more thorough explanation.

-chad




Judah Baron

unread,
Jan 20, 2010, 3:34:16 PM1/20/10
to python_in...@googlegroups.com
Chad and Adam,
Thanks for the detailed explanation. I am familiar with hex and masking, just didn't realize that was required here.

thanks,
-Judah


Reply all
Reply to author
Forward
0 new messages