PDA

View Full Version : unable to save an internal array attribute to file


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 );
}

whisperwing
02-02-2011, 04:26 AM
ok, I kinda solved this. I need to also override

int MPxNode::internalArrayCount (const MPlug & plug, const MDGContext & ctx) const;

Even doing so numElements() will not return the correct value, but at least it will write to file as I expected. Also, beware that for internal attributes, there's no difference between physical index and logical index ( read the doc on ::internalArrayCount() )

CGTalk Moderation
02-02-2011, 04:26 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.