#include <maya/MIOStream.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MArgList.h>
#include <maya/MPxCommand.h>
#include <maya/MGlobal.h>
#include <maya/MItSelectionList.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MPxData.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MFnPluginData.h>
#include <maya/MFnNurbsCurve.h>
#include <assert.h>
struct CVData {
MStatus readASCII( const MArgList&, unsigned& );
MStatus writeASCII( ostream& );
MStatus readBinary( istream& in );
MStatus writeBinary( ostream& out );
double _doubleData;
int _intData;
static CVData empty;
};
CVData CVData::empty;
class blindComplexData : public MPxData
{
public:
blindComplexData();
blindComplexData( const unsigned int );
virtual ~blindComplexData();
virtual MStatus readASCII( const MArgList&, unsigned& lastElement );
virtual MStatus readBinary( istream& in, unsigned length );
virtual MStatus writeASCII( ostream& out );
virtual MStatus writeBinary( ostream& out );
virtual void copy( const MPxData& );
MTypeId typeId() const;
MString name() const;
bool setLength( const unsigned int numCVs,
const bool copyOldData = false );
const CVData &operator [] ( const unsigned int index ) const;
CVData &operator [] ( const unsigned int index );
unsigned int length() const;
static const MString typeName;
static const MTypeId id;
static void* creator();
private:
bool indexOk( const unsigned int ) const;
CVData* _CVDataArrayPtr;
unsigned int _length;
};
const MTypeId blindComplexData::id( 0x80002 );
const MString blindComplexData::typeName( "blindComplexData" );
class blindComplexDataCmd : public MPxCommand
{
public:
blindComplexDataCmd();
virtual ~blindComplexDataCmd();
MStatus doIt( const MArgList& args );
MStatus redoIt();
MStatus undoIt();
bool isUndoable() const;
public:
static void* creator();
MItSelectionList* iter;
};
void* blindComplexData::creator()
{
return new blindComplexData;
}
blindComplexData::blindComplexData()
:_CVDataArrayPtr( NULL ),
_length(0)
{
}
blindComplexData::~blindComplexData()
{
delete [] _CVDataArrayPtr;
_length = 0;
}
blindComplexData::blindComplexData( const unsigned int cvNum )
: _length(0),
_CVDataArrayPtr( NULL )
{
setLength( cvNum );
}
bool blindComplexData::setLength ( const unsigned int cvNum,
const bool copyOldData )
{
bool ret = true;
if ( _length != cvNum || _CVDataArrayPtr == NULL ) {
CVData* ptr;
if ( _length != 0 && ! copyOldData ) {
cerr << "warning: might be erasing previous data." << endl;
}
ptr = new CVData[cvNum];
if ( ptr == NULL ) {
cerr << "out of memory, setLength() failed" << endl;
ret = false;
} else {
if ( copyOldData ) {
if ( cvNum < _length ) {
cerr << "warning: new size not big enough for old data."
<< endl;
}
for ( unsigned int i = 0; i < cvNum; i++ ) {
ptr[i] = _CVDataArrayPtr[i];
}
}
delete [] _CVDataArrayPtr;
_CVDataArrayPtr = ptr;
_length = cvNum;
}
} else {
cerr << "warning: setLength() o.k., same length, no change." << endl;
}
return ret;
}
unsigned int blindComplexData::length ( ) const
{
return _length;
}
inline
bool blindComplexData::indexOk( const unsigned int index ) const {
return ( index < _length );
}
const CVData& blindComplexData::operator [] ( const unsigned int index ) const
{
if ( indexOk( index ) ) {
return _CVDataArrayPtr[index];
} else {
cerr << "indexing error. operator [] failed, returning invalid object"
<< endl;
return CVData::empty;
}
}
CVData &blindComplexData::operator [] ( const unsigned int index )
{
if ( indexOk( index ) ) {
return _CVDataArrayPtr[index];
} else {
cerr << "indexing error. operator [] failed, returning invalid object"
<< endl;
return CVData::empty;
}
}
void blindComplexData::copy( const MPxData& other )
{
if( other.typeId() == blindComplexData::id ) {
const blindComplexData* otherData =
(const blindComplexData*)&other;
if ( _length != otherData->_length ) {
if ( ! setLength( otherData->_length ) ) {
return;
}
}
for ( unsigned int i = 0; i < _length; i++ ) {
_CVDataArrayPtr[i] = (*otherData)[i];
}
} else {
cerr << "wrong data format!" << endl;
}
return;
}
MTypeId blindComplexData::typeId() const
{
return blindComplexData::id;
}
MString blindComplexData::name() const
{
return blindComplexData::typeName;
}
MStatus blindComplexData::readASCII( const MArgList& args,
unsigned& lastParsedElement )
{
MStatus status;
int argLength = args.length();
if( argLength > 0 ) {
int numDataRecord = (argLength - lastParsedElement);
if ( numDataRecord % 2 != 0 ) {
cerr << "warning: corrupted data for blindComplexData" << endl;
}
numDataRecord /= 2;
setLength(numDataRecord);
for ( unsigned int i=0; i < _length; i++ ) {
status = _CVDataArrayPtr[i].readASCII(args, lastParsedElement);
if ( status != MS::kSuccess ) {
return status;
}
}
return MS::kSuccess;
}
return MS::kFailure;
}
MStatus CVData::readASCII ( const MArgList& args,
unsigned& lastParsedElement )
{
MStatus status;
_intData = args.asInt( lastParsedElement++, &status );
if ( status == MS::kSuccess ) {
_doubleData = args.asDouble( lastParsedElement++, &status );
}
return status;
}
MStatus CVData::writeASCII ( ostream& out )
{
out << _intData << " " << _doubleData << " ";
return out.fail() ? MS::kFailure : MS::kSuccess;
}
MStatus blindComplexData::writeASCII( ostream& out )
{
MStatus status;
for ( unsigned int i=0; i < _length; i++ ) {
status = _CVDataArrayPtr[i].writeASCII(out);
if ( status != MS::kSuccess ) {
return MS::kFailure;
}
}
return MS::kSuccess;
}
MStatus blindComplexData::readBinary( istream& in, unsigned length )
{
MStatus status;
if ( length > 0 ) {
unsigned int recNum;
in.read( (char*) &recNum, sizeof(recNum) );
if ( ! in.fail() && recNum > 0 ) {
setLength(recNum);
for ( unsigned int i=0; i < _length; i++ ) {
status = _CVDataArrayPtr[i].readBinary(in);
if ( status != MS::kSuccess ) {
return status;
}
}
}
} else {
return MS::kFailure;
}
return MS::kSuccess;
}
MStatus blindComplexData::writeBinary( ostream& out )
{
MStatus status;
out.write( (char*) &_length, sizeof(_length) );
if ( ! out.fail() ) {
for ( unsigned int i=0; i < _length; i++ ) {
status = _CVDataArrayPtr[i].writeBinary(out);
if ( status != MS::kSuccess ) {
return status;
}
}
} else {
return MS::kFailure;
}
return MS::kSuccess;
}
MStatus CVData::readBinary ( istream& in )
{
in.read( (char*) &_intData, sizeof(_intData) );
if ( !in.fail() ) {
in.read( (char*) &_doubleData, sizeof(_doubleData) );
} else {
return MS::kFailure;
}
return in.fail() ? MS::kFailure : MS::kSuccess;
}
MStatus CVData::writeBinary ( ostream& out )
{
out.write( (char*) &_intData, sizeof(_intData) );
if ( !out.fail() ) {
out.write( (char*) &_doubleData, sizeof(_doubleData) );
} else {
return MS::kFailure;
}
return out.fail() ? MS::kFailure : MS::kSuccess;
}
void* blindComplexDataCmd::creator()
{
return new blindComplexDataCmd;
}
blindComplexDataCmd::~blindComplexDataCmd()
{
}
blindComplexDataCmd::blindComplexDataCmd()
: MPxCommand()
{
}
MStatus blindComplexDataCmd::doIt( const MArgList& )
{
MStatus stat;
MSelectionList list;
MGlobal::getActiveSelectionList( list );
iter = new MItSelectionList( list, MFn::kInvalid, &stat );
if ( MS::kSuccess == stat )
stat = redoIt();
return stat;
}
MStatus blindComplexDataCmd::redoIt()
{
MStatus stat;
MObject dependNode;
for ( ; !iter->isDone(); iter->next() )
{
if ( MS::kSuccess != iter->getDependNode( dependNode ) ) {
cerr << "Error getting the dependency node" << endl;
continue;
}
MFnDependencyNode fnDN( dependNode, &stat );
if ( MS::kSuccess != stat ) {
cerr << "Error creating MFnDependencyNode" << endl;
continue;
}
MFnTypedAttribute fnAttr;
const MString fullName( "blindComplexData" );
const MString briefName( "BCD" );
MObject newAttr = fnAttr.create( fullName, briefName,
blindComplexData::id );
fnDN.addAttribute( newAttr, MFnDependencyNode::kLocalDynamicAttr );
MPlug plug( dependNode, newAttr );
blindComplexData * newData = new blindComplexData( 5 );
unsigned int i;
for ( i= 0; i < newData->length(); i++ ) {
(*newData)[i]._intData = 10 + i;
(*newData)[i]._doubleData = 20.02 + i;
}
stat = plug.setValue( newData );
MObject sData;
stat = plug.getValue( sData );
if ( stat != MS::kSuccess ) {
cerr << "error getting value off plug" << endl;
continue;
}
MFnPluginData pdFn( sData );
blindComplexData* data =
( blindComplexData* ) pdFn.constData( &stat );
clearResult();
if ( NULL != data ) {
for ( i = 0; i < data->length(); i++ ) {
appendToResult((double) ((*data)[i]._intData));
appendToResult((*data)[i]._doubleData);
}
} else {
}
}
return MS::kSuccess;
}
MStatus blindComplexDataCmd::undoIt()
{
return MS::kSuccess;
}
bool blindComplexDataCmd::isUndoable() const
{
return true;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any" );
status = plugin.registerData( "blindComplexData",
blindComplexData::id,
blindComplexData::creator );
if (!status) {
status.perror("registerData");
return status;
}
status = plugin.registerCommand( "blindComplexData",
blindComplexDataCmd::creator );
if (!status) {
plugin.deregisterData( blindComplexData::id );
status.perror("registerCommand");
return status;
}
return status;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status1, status2;
MFnPlugin plugin( obj );
status1 = plugin.deregisterCommand( "blindComplexData" );
if (!status1) {
status1.perror("deregisterCommand");
}
status2 = plugin.deregisterData( blindComplexData::id );
if (!status2) {
status2.perror("deregisterData");
}
if ( !status1 )
return status1;
return status2;
}