// ========================================================================== // Copyright (C) 1995 - 2005 Alias Systems Corp. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files are provided by Alias // Systems Corp. ("Alias") and/or its licensors for the exclusive use of the // Customer (as defined in the Alias Software License Agreement that // accompanies this Alias software). Such Customer has the right to use, // modify, and incorporate the Data into other products and to distribute such // products for use by end-users. // // THE DATA IS PROVIDED "AS IS". ALIAS HEREBY DISCLAIMS ALL WARRANTIES // RELATING TO THE DATA, INCLUDING, WITHOUT LIMITATION, ANY AND ALL EXPRESS OR // IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. IN NO EVENT SHALL ALIAS BE LIABLE FOR ANY DAMAGES // WHATSOEVER, WHETHER DIRECT, INDIRECT, SPECIAL, OR PUNITIVE, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, OR IN EQUITY, // ARISING OUT OF ACCESS TO, USE OF, OR RELIANCE UPON THE DATA. // ========================================================================== // $RCSfile: weightListNode.cpp $ $Revision: /main/6 $ // // 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 #include #include #include #include #include #include #include #include #include #include #include #include #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( 0x81020 ); // 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[%d][%d] = %g\n",i,j,weight); } } return status; } // standard initialization procedures // MStatus initializePlugin( MObject obj ) { MStatus result; MFnPlugin plugin( obj, "Alias|Wavefront - Example", "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; }