Maya Python API: Reading data from API classes

Hey guys, I’m trying to grasp the Python API in Maya, but I really struggle with the fact that everything is objects. Even though I manage to retrieve (I think) the data I want, I don’t know how to work with the data.

Example:

#Create a MRichSelection object
softSelection = OpenMaya.MRichSelection()
#Get the current softselection (output data to the "softSelection" variable)
OpenMaya.MGlobal.getRichSelection(softSelection)

Now if I want to get the elements in the softselection, the first thing I tried was to dir(softSelection), but it doesn’t return anything useful. And if I try to print I just get this:

<maya.OpenMaya.MRichSelection; proxy of <Swig Object of type 'MRichSelection *' at 0x397adcb0> >

Here’s another example:

vec = OpenMaya.MFloatVector(1,2,3)

So how do you know how to fetch the data from each object you create?

1 Like

Grab yourself a copy of this book.

@cgjedi: That’s the C++ API though

Look up the class documentation based on the name of the object you’re getting back. For the example you posted the docs would be in

http://download.autodesk.com/us/maya/2011help/api/class_m_rich_selection.html

(or other year as appropriate). The doc page will show you the fields and methods of the objects you’re working with. It’s C++ docs but it will give you the names to call and the expected return types

@cgjedi: That’s the C++ API though

Yes, but your message make me think you don’t quite understand the similarities/differences between the C++ API and how the Python API makes use of it. The answer you require takes more than can be written here. That book is the beginning of your answer.

Translating the C++ docs into Python is no small feat, especially when your throw MScriptUtils into the mix. Start by looking at the examples provided by Autodesk in the devkit folder - read over the API documentation.

Maya Python for Games and Film has a good chapter on how to understand C++ documentation and make use of it in Python.

ctypes cast?

The process for me has been a combination of looking at existing code (including C++ examples that ship with maya), and looking at the documentation. Eventually you’ll be able to figure out how to extract the values you want just by looking at the docs (for most cases at least).

This may be overly detailed and known to you, but I’m just going to break down how I look at the docs to decide what I need to use to get the data I want, and how to access it.

Looking at the docs for MRichSelection, under Public Member Functions you will find:

MStatus getSelection (MSelectionList &selection) const
Returns a copy of the non-symmetry component of the rich selection.

In this case it says it returns the component(s) of the selection, which sounds like what we want.
The “MStatus” on the left is the return value. MStatus just means it returns an indication of whether the function succeeded or not. This is not used in the python API at all, and can be ignored. For me, seeing MStatus means that the function returns nothing meaningful, and instead it operates on objects that you pass into the function (often by changing the data in the passed object).
The (MSelectionList &selection) tells us that it takes a reference to an MSelectionList. MSelectionLists store objects and components, which would make sense for storing the affected components of a soft select.

From that I know that I need to create an empty MSelectionList and pass that to MRichSelection.getSelection:

mSelList = om.MSelectionList()
mRichSel = om.MRichSelection()
om.MGlobal.getRichSelection(mRichSel)
mRichSel.getSelection(mSelList)

Now we have an MSelectionList containing the data we want. Extracting it takes more work. We need to get the MDagPath to the selected object, and an MObject of the selection components. If we look at the docs for MSelectionList, we find:

MStatus getDagPath (unsigned int index, MDagPath &dagPath, MObject &component=MObject::kNullObj) const
Get the dag path and component (may be NULL) of the given element of the selection list.

This is a pretty standard pattern for getting selected data:

mDagPath = om.MDagPath()
mObject = om.MObject()
mSelList.getDagPath(0, mDagPath, mObject)

mObject now stores the components we want. In order to access the actual component IDs and their soft-select weight, we need to use MFnSingleIndexedComponent (vertices are single-indexed components, ie mesh.vtx[4], whereas double-indexed would be nurbsSpline.cv[0][1])

Figuring out what to do with the MFnSingleIndexedComponent is a little more complicated. In the docs we see:

int element (int index, MStatus *ReturnStatus=NULL) const
Returns the specified element from the component.

The return type is “int”, so we know the element method returns the component ID of the given index in the component array.
MFnSingleIndexedComponent inherits from MFnComponent, and if we look at the docs for MFnComponent we see:

int elementCount (MStatus *ReturnStatus=NULL) const
Returns the number of elements that this component contains.

We can use this to determine how many elements are in this component list. We will loop through that range and pass each index to the “element()” call to get the component IDs in this array.
We also see:

MWeight weight (int index, MStatus *ReturnStatus=NULL) const
Return the weight data for a given element within this component.

This will return the (in our case) soft selection weight percentage for the given component.

All in all:
Loop through each element index and extract the ID and weight.

# Create an MFnSingleIndexedComponent using the components extracted in the previous step
mFnCmpt = om.MFnSingleIndexedComponent(mObject)
weights = {}
# For each element in the component array, get the ID of that component and the soft-select weight of that component.
for i in range(mFnCmpt.elementCount()):
    weights[mFnCmpt.element(i)] = mFnCmpt.weight(i).influence()

That was a fairly complex and nested example of extracting data, but shows the process I would go through. Here’s a more complete example that accounts for potential errors: http://www.charactersetup.com/tutorial_softSelect.html

1 Like