[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