whisperwing
02-01-2011, 11:10 PM
Basically I have a customized node with an array attribute (of type int) that is an internal attribute. I want to be able to save the values of this attribute to file.
When I compiled this plug with the macro "INTERNAL" not defined, data in inputArray will be saved to file, and numOfElement() is correct. If the plugin is compiled with "INTERNAL" defined, numOfElement() = 0 even although getAttr and setAttr works.
To try this plugin, use the following commands:
file -f -new;
unloadPlugin "testArrayAttrSave.so";
loadPlugin "testArrayAttrSave.so";
createNode testNode;
getAttr testNode1.inputArray[0];
getAttr testNode1.inputArray[10];
setAttr testNode1.inputArray[10] 0;
file -type "mayaAscii";
file->Save Scene As "....ma"
really appreciate it if someone could tell me if I did something obviously wrong here, thanks !
#include <vector>
#include <iostream>
#include <maya/MPxNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MVector.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#define INTERNAL
class testNode : public MPxNode
{
public:
testNode();
virtual ~testNode();
virtual MStatus compute( const MPlug& plug, MDataBlock& data );
static void* creator();
static MStatus initialize();
MStatus shouldSave(const MPlug &, bool & result){ result = true; return MS::kSuccess; }
#ifdef INTERNAL
virtual bool getInternalValueInContext(const MPlug&, MDataHandle&, MDGContext&);
virtual bool setInternalValueInContext(const MPlug&, const MDataHandle&, MDGContext&);
#endif
static MTypeId id;
private:
static MObject mInputArrayAttr;
std::vector< int > mInputs;
};
MTypeId testNode::id( 0x81019 );
MObject testNode::mInputArrayAttr;
testNode::testNode() {}
testNode::~testNode() {}
MStatus testNode::compute( const MPlug& plug, MDataBlock& data )
{
return( MS::kSuccess );
}
#ifdef INTERNAL
bool testNode::getInternalValueInContext(const MPlug& plug, MDataHandle& handle, MDGContext& context)
{
if (plug == mInputArrayAttr)
{
if (plug.isElement())
{
int val = -1;
unsigned int index = plug.logicalIndex();
if (mInputs.size() > index)
val = mInputs[index];
handle.set(val);
}
return true;
}
return true;
}
bool testNode::setInternalValueInContext(const MPlug& plug, const MDataHandle& handle, MDGContext& context)
{
if (plug == mInputArrayAttr)
{
if (plug.isElement())
{
unsigned int index = plug.logicalIndex();
if (mInputs.size() <= index)
mInputs.resize(index+1, -1);
mInputs[index] = handle.asInt();
}
return true;
}
return true;
}
#endif
void* testNode::creator()
{
return( new testNode() );
}
MStatus testNode::initialize()
{
MStatus status = MS::kSuccess;
MFnNumericAttribute nAttr;
mInputArrayAttr = nAttr.create("inputArray", "inputArray", MFnNumericData::kInt, -1, &status);
status = nAttr.setArray(true);
status = nAttr.setUsesArrayDataBuilder(true);
#ifdef INTERNAL
status = nAttr.setInternal(true);
#endif
status = addAttribute(mInputArrayAttr);
return status;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY , "Any", "Any");
status = plugin.registerNode( "testNode", testNode::id, testNode::creator, testNode::initialize );
if (!status)
status.perror("registerNode");
return status;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status;
MFnPlugin plugin( obj );
status = plugin.deregisterNode( testNode::id );
if (!status)
status.perror("deregisterNode");
return( status );
}
When I compiled this plug with the macro "INTERNAL" not defined, data in inputArray will be saved to file, and numOfElement() is correct. If the plugin is compiled with "INTERNAL" defined, numOfElement() = 0 even although getAttr and setAttr works.
To try this plugin, use the following commands:
file -f -new;
unloadPlugin "testArrayAttrSave.so";
loadPlugin "testArrayAttrSave.so";
createNode testNode;
getAttr testNode1.inputArray[0];
getAttr testNode1.inputArray[10];
setAttr testNode1.inputArray[10] 0;
file -type "mayaAscii";
file->Save Scene As "....ma"
really appreciate it if someone could tell me if I did something obviously wrong here, thanks !
#include <vector>
#include <iostream>
#include <maya/MPxNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MPlugArray.h>
#include <maya/MVector.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#define INTERNAL
class testNode : public MPxNode
{
public:
testNode();
virtual ~testNode();
virtual MStatus compute( const MPlug& plug, MDataBlock& data );
static void* creator();
static MStatus initialize();
MStatus shouldSave(const MPlug &, bool & result){ result = true; return MS::kSuccess; }
#ifdef INTERNAL
virtual bool getInternalValueInContext(const MPlug&, MDataHandle&, MDGContext&);
virtual bool setInternalValueInContext(const MPlug&, const MDataHandle&, MDGContext&);
#endif
static MTypeId id;
private:
static MObject mInputArrayAttr;
std::vector< int > mInputs;
};
MTypeId testNode::id( 0x81019 );
MObject testNode::mInputArrayAttr;
testNode::testNode() {}
testNode::~testNode() {}
MStatus testNode::compute( const MPlug& plug, MDataBlock& data )
{
return( MS::kSuccess );
}
#ifdef INTERNAL
bool testNode::getInternalValueInContext(const MPlug& plug, MDataHandle& handle, MDGContext& context)
{
if (plug == mInputArrayAttr)
{
if (plug.isElement())
{
int val = -1;
unsigned int index = plug.logicalIndex();
if (mInputs.size() > index)
val = mInputs[index];
handle.set(val);
}
return true;
}
return true;
}
bool testNode::setInternalValueInContext(const MPlug& plug, const MDataHandle& handle, MDGContext& context)
{
if (plug == mInputArrayAttr)
{
if (plug.isElement())
{
unsigned int index = plug.logicalIndex();
if (mInputs.size() <= index)
mInputs.resize(index+1, -1);
mInputs[index] = handle.asInt();
}
return true;
}
return true;
}
#endif
void* testNode::creator()
{
return( new testNode() );
}
MStatus testNode::initialize()
{
MStatus status = MS::kSuccess;
MFnNumericAttribute nAttr;
mInputArrayAttr = nAttr.create("inputArray", "inputArray", MFnNumericData::kInt, -1, &status);
status = nAttr.setArray(true);
status = nAttr.setUsesArrayDataBuilder(true);
#ifdef INTERNAL
status = nAttr.setInternal(true);
#endif
status = addAttribute(mInputArrayAttr);
return status;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY , "Any", "Any");
status = plugin.registerNode( "testNode", testNode::id, testNode::creator, testNode::initialize );
if (!status)
status.perror("registerNode");
return status;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status;
MFnPlugin plugin( obj );
status = plugin.deregisterNode( testNode::id );
if (!status)
status.perror("deregisterNode");
return( status );
}
