[Maya C++ API] Get selected vertices of a mesh

 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;
}

more here

No comments

All html tags except <b> and <i> will be removed from your comment. You can make links by just typing the url or mail-address.
Spam bot question: