If you don’t have any specific goals, then make your life easier by using maya.api.OpenMaya
instead of maya.OpenMaya
.
A simple way to work with selected vertices:
import maya.api.OpenMaya as om2
# Get the current selection of elements in the scene.
selection = om2.MGlobal.getActiveSelectionList()
# We get the shape and the components selected on it.
node, component = selection.getComponent(0)
# We will use an iterator specifically designed to effectively work with vertices.
it = om2.MItMeshVertex(node, component)
# We will place the results (vertex positions) in a special array designed to store the positions of points (vertices).
# Essentially, the array value contains a tuple of four float values (x, y, z, w).
vertices_pos_array = om2.MFloatPointArray()
# Loop through the selected vertices for a given shape until we have iterated through them all:
while not it.isDone():
# Get the vertex position in the space we need, for example in World Space.
position = it.position(om2.MSpace.kWorld) # or it.position(4)
# Add the result to the array:
vertices_pos_array.append(position)
# For clarity, let's print the name of the shape with the index of the current vertex and its position:
print('{}.vtx[{}]: {}'.format(node.fullPathName(), it.index(), position)) # or node.partialPathName()
# move to the next vertex in the current iteration:
it.next()
BUT! This will work correctly if you have only vertices selected and only on one shape!
If the selection contains different components, or non-DAG nodes, or components are selected on different shapes, then you will get strange, incorrect and incomplete results.
Or you will even get errors.
That is, this only works for the first element in the list.
We specify this ourselves explicitly using index ‘0’:
getComponent(0)
Let’s try a more reasonable approach.
import maya.api.OpenMaya as om2
selection = om2.MGlobal.getActiveSelectionList()
# Let's find out the number of elements in the select list and process them all:
for i in range(selection.length()):
# If the element is not a DAG node, then when we try to request a node with components for the current selection element, we will receive an error.
# Handle the error using the `try/except` construct
node, component = None, None
try:
node, component = selection.getComponent(i)
except:
pass
# If the node contains the selected components, then process the result
if component:
# Check that the selected components are vertices:
if component.apiTypeStr == 'kMeshVertComponent':
# Use an iterator as in the previous example:
it = om2.MItMeshVertex(node, component)
vertices_pos_array = om2.MFloatPointArray()
while not it.isDone():
position = it.position(om2.MSpace.kWorld) # or it.position(4)
vertices_pos_array.append(position)
print('{}.vtx[{}]: {}'.format(node.fullPathName(), it.index(), position)) # or node.partialPathName()
it.next()
BUT! The method proposed above is not effective and is a clumsy crutch.
There is a special iterator to work effectively with Selection List
!
import maya.api.OpenMaya as om2
selection = om2.MGlobal.getActiveSelectionList()
# Create an iterator to process the `Selection List`:
it_sel = om2.MItSelectionList(selection)
while not it_sel.isDone():
# Check that the current element is a DAG node:
if not it_sel.itemType(): # int kDagSelectionItem = 0
# Check that the selection contains the components of the current element:
if(it_sel.hasComponents()):
# Now we can get a DAG node with the components selected on it:
node, component = it_sel.getComponent()
# Check that the selected components are vertices:
if component.apiTypeStr == 'kMeshVertComponent': # or component.apiType() == 554
# Use an iterator as in the previous example:
it = om2.MItMeshVertex(node, component)
vertices_pos_array = om2.MFloatPointArray()
while not it.isDone():
position = it.position(om2.MSpace.kWorld) # or it.position(4)
vertices_pos_array.append(position)
print('{}.vtx[{}]: {}'.format(node.fullPathName(), it.index(), position)) # or node.partialPathName()
it.next()
it_sel.next()
OpenMaya.MItMeshVertex Class Reference
OpenMaya.MItSelectionList Class Reference
OpenMaya.MFloatPointArray Class Reference