[Maya C++ API] Per vertex color update in MPxDeformerNode

Code snippet in C++ to be able to update the color of a mesh with Maya API on a per vertex basis.

To display per vertex color in Maya's viewport, select the mesh and enable "Color""Toggle Per Vertex Colors Attribute" in Maya's menu or call the MEL equivalent: toggleShadeMode();. Outside a node it's quite simple to update the mesh colors through the class MFnMesh of the Maya API: 

#define mayaCheck(code) do{ const g_status_(code); const int l = __LINE__;\
    if(g_status_ != MS::kSuccess) \
        throw My_exception(g_status_, __TO_STR(__FILE__), l); \
    }while(false)

    //--------------------
{  
    MObject mesh_shape;
    MFnMesh mesh_fn( mesh_shape, &status);
    mayaCheck(status);
    int num_verts = mesh_fn.numVertices(&status);
    mayaCheck(status);
    MColorArray colors;
    MIntArray vertex_idx_list;
    if( colors.length() != num_verts){
        mayaCheck(colors.setLength(num_verts));
        mayaCheck(vertex_idx_list.setLength(num_verts));
    }

    MGlobal::displayInfo(MString("num verts: ") + num_verts);
    for(int i = 0; i < num_verts; ++i)
    {
        colors.set(MColor(1.0f, 0.0f, 0.0f), i); // Set to red
        vertex_idx_list[i] = i;
    }

    mayaCheck( mesh_fn.setVertexColors(colors, vertex_idx_list) );
}

Next I show how to change vertex color with Maya API inside a MPxDeformerNode deformer node. The main trick is to not forget to call MPxDeformerNode::setDeformationDetails() note that setVertexColor() sometimes won't work for some strange reasons... Instead use setVertexColors() it's faster anyway.

MStatus Inherits_mpxdeformer::deform(MDataBlock& block,
                                     MItGeometry& geom_it,
                                     const MMatrix& object_matrix,
                                     unsigned int multi_index)
{
    
    try
    {
        MStatus status;
        MArrayDataHandle out_array = block.outputArrayValue(MPxDeformerNode::outputGeom, &status);
        mayaCheck(status);
        MDataHandle houtput = out_array.inputValue(&status);
        mayaCheck(status);
        MFnMesh mesh_fn ( houtput.asMesh(), &status);
        mayaCheck(status);
        MColorArray colors;
        MIntArray vertex_idx;
        for (geom_it.reset(); !geom_it.isDone(); geom_it.next()) {
            colors.append(1, 0, 0, 1);
            vertex_idx.append(geom_it.index());
        }

        mesh_fn.setVertexColors(colors, vertex_idx);
        houtput.setClean();
    }
    catch (std::exception& e)
    {
        maya_print_error( e );
        return MS::kFailure;
    }
    return MStatus::kSuccess;
    
}

// -----------------------------------------------------------------------------

void Inherits_mpxdeformer::postConstructor()
{
    mayaCheck( MPxDeformerNode::setDeformationDetails(MPxDeformerNode::kDeformsColors) );
}

Original post 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: