Python API 2.0 Reference
Working with M*Array Classes

Most of Maya's array classes provide a common interface with the only difference being the type of the underlying array elements: integer, float, MPoint, etc. This page describes that common interface.

The array classes which use this common interface implement their Python type objects using the MPyMArray_Type template class, which takes the following template parameters:

  • The type of the Maya array class (e.g. MIntArray, MPointArray). We refer to this as ArrayType throughout this document.
  • The C++ type of the array elements (e.g. int, MPoint). We refer to this as ElementType throughout this document.
  • A boolean indicating whether reference semantics should be used.

Reference Semantics

Reference semantics mean that indexing into the array returns a reference to an array element rather than a copy of its value. For example, let's say that you do the following:

1 import maya.api.OpenMaya as om
2 array = om.MPointArray()
3 array.append(om.MPoint(1, 2, 3))
4 p = array[0]
5 p.x = -5

Under value semantics 'p' would contain a copy of the value in 'array[0]'. Changing one would have no effect on the other, so we would end up with 'p' containing (-5, 2, 3) and 'array[0]' containing (1, 2, 3).

Under reference semantics 'p' and 'array[0]' would refer to the same element so they would both end up with the point (-5, 2, 3).

In the Maya Python 2.0 API, arrays of simple types like int and float use value semantics, while arrays of class types like MPoint and MColor use reference semantics.

This is in keeping with the way that Python handles function parameters: parameters of simple type are passed by value while parameters of class types are passed by reference. More importantly, passing class type objects by reference can hugely improve performance. For example, imagine that you need to increment the X coordinate of all the points in an array. Using value semantics you'd have to copy the data twice:

1 for i in range(len(array)):
2  p = array[i]
3  p.x += 1
4  array[i] = p

Using reference semantics you can avoid the copies altogether:

1 for p in array;
2  p.x += 1

Without reference semantics those extra copies could easily double or triple the amount of CPU time required to process the array, which could prove crippling when dealing with complex geometries involving arrays of hundreds of thousands of points.

Unfortunately, there is a significant price to be paid for using reference semantics. Maya's array types do not provide reference counting for individual elements. This means that a Python script which holds a reference to an array element may suddenly find that reference invalid if the corresponding array element is destroyed. For example, the following could cause Maya to crash or otherwise become unstable because it is attempting to increment the 'x' member of an MPoint instance which no longer exists:

1 p = array[0]
2 array.clear()
3 p.x += 1

It is up to the API user to ensure that the array is not destroyed, resized or overwritten while zie holds references to one or ore of its elements.

Note that the same caveats apply to the C++ API and the Python 1.0 API as they also use reference semantics for arrays of class-type objects, so at least the danger is a familiar one for developers.

Constructors

Signature Parameters Description
ArrayType()  

Default constructor. Returns a new, empty ArrayType object.

ArrayType(src) src - ArrayType

Copy constructor. Returns a new ArrayType object containing copies of of the elements from src.

ArrayType(size, value) size - Int
value - ElementType

Returns a new ArrayType object with size elements, all set to value.

ArrayType(seq) seq - sequence whose elements are convertible to ElementType

Returns a new ArrayType object containing copies of the elements from seq. Raises a TypeError exception if any of the elements of seq cannot be converted to ElementType.

Object Methods

Signature Parameters Returns Description
append(value) value - ElementType New reference to self.

Appends value to the end of the array as a new element.

copy(src) src - ArrayType or sequence of items convertible to ElementType New reference to self.

Removes all existing elements and adds copies of the elements from src.

clear()   New reference to self.

Removes all existing elements.

insert(value, index) value - ElementType
index - Int
New reference to self.

Inserts value into the array element at index, after first shifting that and any elements which follow it down the array to make room. Raises a ValueError if there are not at least index elements in the array before insertion, or if index is negative.

remove(index) index - Int New reference to self.

Removes the array element at index then shifts any elements which follow it up to close the gap. Raises a ValueError if index is out of range.

setLength(newSize) newSize - Int New reference to self.

Sets the length of the array to newSize elements. If the new size is less than the old then the elements from newSize onward will be destroyed. If the new size is greater than the old then new elements will have undefined values which should not be used without first being initialized. Raises a ValueError if newSize is negative.

Sequence Support

All sequence operations are supported, including slices.

For arrays using reference semantics indexing returns what is effectively a borrowed reference to the array element rather than a copy of its value. See the discussion of Reference Semantics above for more details.