[Maya C++ API] Get selected vertices of a mesh
How to access the mesh's selected vertices with Maya api - 03/2017 - #Maya

Iterate over every objects of the scene and get their selected vertices:
MSelectionList selection_list;
MGlobal::getActiveSelectionList(selection_list);
MItSelectionList iter(selection_list);
for ( ; !iter.isDone(); iter.next()) // For each selected object
{
MObject component;
MDagPath item;
mayaCheck( iter.getDagPath(item, component) );
MGlobal::displayInfo( item.fullPathName() );
if( component.isNull() )
continue; // No vertices selected.
if( component.apiType() != MFn::kMeshVertComponent )
continue; // the component is not a vertex (perhaps face, edge etc.)
MStatus status;
MItMeshVertex vert_it(item, component, &status);
mayaCheck(status);
for ( ; !vert_it.isDone() ; vert_it.next() ) // For each selected vertex
{
int af = vert_it.index(&status);
mayaCheck(status);
MGlobal::displayInfo(MString("Vertex index\n") + af );
}
}
Note that you can get selected faces, edges and so one through other iterators such as MItMeshEdge (MFn::kMeshEdgeComponent) or MItMeshPolygon (MFn::kMeshPolygonComponent) etc. To get selected vertices of a specific shape here some cleaner code:
MDagPath get_MDagPath(const MObject& obj)
{
MStatus status;
mayaAssertMsg(obj.hasFn(MFn::kDagNode), "This is not a dag node");
MFnDagNode dag_node(obj, &status);
mayaCheck(status);
MDagPath dag_path;
mayaCheck( dag_node.getPath( dag_path ) );
return dag_path;
}
/// Returns true if the object designated by 'path' is selected and has vertices selected
/// if true 'component' will contain the selected vertices
bool check_selected_vertex_of(const MDagPath& path, MObject& component)
{
MStatus status;
MSelectionList selection_list;
mayaCheck( MGlobal::getActiveSelectionList(selection_list) );
MItSelectionList iter(selection_list, MFn::kInvalid, &status);
mayaCheck(status);
for ( ; !iter.isDone(); iter.next())
{
MDagPath curr_selection;
if( !iter.getDagPath( curr_selection, component ) )
continue;
if( curr_selection == path &&
!component.isNull() &&
component.apiType() == MFn::kMeshVertComponent)
{
return true;
}
}
return false;
}
int get_nb_vertices(MObject mesh_shape)
{
MStatus status;
MItMeshVertex mesh_it(mesh_shape, &status);
mayaCheck(status);
int nb_verts = mesh_it.count(&status);
mayaCheck(status);
return nb_verts;
}
/// returns the list of selected vertices of 'mesh_shape'
std::vector<int> get_selected_vertices(MObject mesh_shape)
{
MStatus status;
std::vector<int> vertex_list;
MObject component;
MDagPath path = get_MDagPath(mesh_shape);
if( check_selected_vertex_of(path, component) )
{
vertex_list.reserve( get_nb_vertices(mesh_shape) );
MItMeshVertex vert_it(path, component, &status);
mayaCheck( status );
int i = 0;
for ( ; !vert_it.isDone() ; vert_it.next() ){
int vidx = vert_it.index(&status);
mayaCheck(status);
vertex_list.push_back( vidx );
++i;
}
}
return vertex_list;
}
Inside a deformer (MPxDeformerNode) I found using MItMeshVertex would trigger warnings. My advice is to rely on MItGeometry:
MStatus MPxDeformerNode_custom::deform(
MDataBlock& block,
MItGeometry& geom_it,
const MMatrix& object_matrix,
unsigned int multi_index)
{
MObject component;
MArrayDataHandle input_array = block.inputArrayValue(MPxDeformerNode_custom::input);
input_array.jumpToElement(multi_index);
MDataHandle input_data = input_array.inputValue();
MDataHandle input_geom_data_h = input_data.child(MPxDeformerNode_custom::inputGeom);
// _out_mesh_shape is a pointer we saved at the creation of the deformer
// I did not find a nice way to get the dag path of the output mesh inside
// the deform method. You could perhaps look up the graph with MItDependencyGraph...
if( check_selected_vertex_of(get_MDagPath(_out_mesh_shape), component) )
{
MItGeometry vert_it(input_geom_data_h, component, true, &status);
mayaCheck( status );
for ( ; !vert_it.isDone() ; vert_it.next() )
{
int vidx = vert_it.index(&status);
mayaCheck(status);
process(vidx);
}
}
return MStatus::kSuccess;
}
No comments