- Main Page
- Related Pages
- Modules
- Classes
- Examples

# weightListNode.cpp

    //
    //-
    // ==========================================================================
    // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
    //
    // Use of this software is subject to the terms of the Autodesk
    // license agreement provided at the time of installation or download,
    // or which otherwise accompanies this software in either electronic
    // or hard copy form.
    // ==========================================================================
    //+
    //

    //
    //  File: weightListNode.cpp
    //
    //  Description:
    //      Example implementation of a node which read and write a
    //              multi of multi of float attibute in the compute() method. The
    //              definition of this multi of multi of float attibute is
    //              the same as the weightList attribute for deformer.
    //
    //              To test the node, use the following MEL commands
    /*
                    loadPlugin weightListNode;
                    createNode weightList;
                    setAttr weightList1.bias 1;
                    getAttr -type weightList1.weightsList;
    */

    #include <string.h>
    #include <maya/MIOStream.h>
    #include <math.h>

    #include <maya/MPxNode.h>
    #include <maya/MFnNumericAttribute.h>
    #include <maya/MFnCompoundAttribute.h>
    #include <maya/MFnPlugin.h>
    #include <maya/MFnDependencyNode.h>
    #include <maya/MTypeId.h>
    #include <maya/MPlug.h>
    #include <maya/MDataBlock.h>
    #include <maya/MDataHandle.h>
    #include <maya/MArrayDataHandle.h>

    #define McheckErr(stat,msg)     \
        if ( MS::kSuccess != stat ) {   \
            cerr << msg;        \
            return MS::kFailure;    \
        }

    class weightList : public MPxNode
    {
    public:
                    weightList();
        virtual         ~weightList();

        static  void*       creator();
        static  MStatus     initialize();

        // deformation function
        //
            virtual MStatus         compute( const MPlug&, MDataBlock&);

    public:
        // local node attributes

        static  MObject         aWeightsList;
        static  MObject         aWeights;
        static  MObject         aBias;
        static  MTypeId     id;

    private:
    };

    MTypeId weightList::id( 0x81035 );

    // local attributes
    //
    MObject weightList::aWeightsList;
    MObject weightList::aWeights;
    MObject weightList::aBias;

    weightList::weightList() {}
    weightList::~weightList() {}

    void* weightList::creator()
    {
        return new weightList();
    }

    MStatus weightList::initialize()
    {
            MStatus status;
        MFnNumericAttribute numAtt;

        aBias = numAtt.create( "bias", "b", MFnNumericData::kFloat);
        addAttribute(aBias);

        aWeights = numAtt.create("weights", "w", MFnNumericData::kFloat, -1000.0, &status);
        numAtt.setKeyable(true);
        numAtt.setArray(true);
        numAtt.setReadable(true);
        numAtt.setUsesArrayDataBuilder(true);
        // setIndexMatters() will only affect array attributes with setReadable set to false,
        // i.e. destination attributes. We have set the default value to an unlikely value
        // to guarantee an entry is created regardless of its value.
        // numAtt.setIndexMatters(true);
        addAttribute(aWeights);

        MFnCompoundAttribute cmpAttr;
        aWeightsList = cmpAttr.create("weightsList", "wl", &status);
        cmpAttr.setArray(true);
        cmpAttr.addChild(aWeights);
        cmpAttr.setReadable(true);
        cmpAttr.setUsesArrayDataBuilder(true);
        // cmpAttr.setIndexMatters(true);
        addAttribute(aWeightsList);

        attributeAffects(aBias, aWeightsList);

        return MStatus::kSuccess;
    }

    MStatus weightList::compute( const MPlug& plug, MDataBlock& block)
    {
            MStatus status = MS::kSuccess;

        unsigned i, j;
        MObject thisNode = thisMObject();
        MPlug wPlug(thisNode, aWeights);

        // Write into aWeightList
        for( i = 0; i < 3; i++) {
            status = wPlug.selectAncestorLogicalIndex( i, aWeightsList );
            MDataHandle wHandle = wPlug.constructHandle(block);
            MArrayDataHandle arrayHandle(wHandle, &status);
            McheckErr(status, "arrayHandle construction failed\n");
            MArrayDataBuilder arrayBuilder = arrayHandle.builder(&status);
            McheckErr(status, "arrayBuilder accessing/construction failed\n");
            for( j = 0; j < i+2; j++) {
                MDataHandle handle = arrayBuilder.addElement(j,&status);
            McheckErr(status, "addElement to arrayBuilder failed\n");
            float val = 1.0f*(i+j);
            handle.set(val);
            }
            status = arrayHandle.set(arrayBuilder);
            McheckErr(status, "set arrayBuilder failed\n");
            wPlug.setValue(wHandle);
            wPlug.destructHandle(wHandle);
        }

        // Read from aWeightList and print out result
        MArrayDataHandle arrayHandle = block.inputArrayValue(aWeightsList, &status);
        McheckErr(status, "arrayHandle construction for aWeightsList failed\n");
        unsigned count = arrayHandle.elementCount();
        for( i = 0; i < count; i++) {
            arrayHandle.jumpToElement(i);
            MDataHandle eHandle = arrayHandle.inputValue(&status).child(aWeights);
            McheckErr(status, "handle evaluation failed\n");
            MArrayDataHandle eArrayHandle(eHandle, &status);
            McheckErr(status, "arrayHandle construction for aWeights failed\n");
            unsigned eCount = eArrayHandle.elementCount();
            for( j = 0; j < eCount; j++) {
                eArrayHandle.jumpToElement(j);
            float weight = eArrayHandle.inputValue(&status).asFloat();
            McheckErr(status, "weight evaluation error\n");
            fprintf(stderr, "weightList[%u][%u] = %g\n",i,j,weight);
            }
        }

        // Read from aWeightList and print out result using the more
        // efficient jumpToArrayElement() call
        arrayHandle = block.inputArrayValue(aWeightsList, &status);
        McheckErr(status, "arrayHandle construction for aWeightsList failed\n");
        count = arrayHandle.elementCount();
        for( i = 0; i < count; i++) {
            arrayHandle.jumpToArrayElement(i);
            MDataHandle eHandle = arrayHandle.inputValue(&status).child(aWeights);
            McheckErr(status, "handle evaluation failed\n");
            MArrayDataHandle eArrayHandle(eHandle, &status);
            McheckErr(status, "arrayHandle construction for aWeights failed\n");
            unsigned eCount = eArrayHandle.elementCount();
            for( j = 0; j < eCount; j++) {
                eArrayHandle.jumpToArrayElement(j);
            float weight = eArrayHandle.inputValue(&status).asFloat();
            McheckErr(status, "weight evaluation error\n");
            fprintf(stderr, "weightList[%d][%d] = %g\n",i,j,weight);
            }
        }

        return status;
    }

    // standard initialization procedures
    //

    MStatus initializePlugin( MObject obj )
    {
        MStatus result;
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
        result = plugin.registerNode( "weightList",
                          weightList::id,
                          weightList::creator,
                          weightList::initialize);

        return result;
    }

    MStatus uninitializePlugin( MObject obj)
    {
        MStatus result;
        MFnPlugin plugin( obj );
        result = plugin.deregisterNode( weightList::id );
        return result;
    }