//- // ========================================================================== // 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: blindComplexDataCmd.cpp $ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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; /////////////////////////////////////// // // Proxy data class declaration // /////////////////////////////////////// class blindComplexData : public MPxData { public: blindComplexData(); blindComplexData( const unsigned int ); virtual ~blindComplexData(); // // Override methods in MPxData. virtual MStatus readASCII( const MArgList&, unsigned& lastElement ); virtual MStatus readBinary( istream& in, unsigned length ); virtual MStatus writeASCII( ostream& out ); virtual MStatus writeBinary( ostream& out ); // // Custom methods. 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 methods and data. static const MString typeName; static const MTypeId id; static void* creator(); private: bool indexOk( const unsigned int ) const; // // any customized data can be declared here, in this case, an array of // CVData that is associated with the CVs. 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; }; ////////////////////////////////////////////////////////////////////////////// // // Proxy data class implementation // ////////////////////////////////////////////////////////////////////////////// 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 ); } // // Set the length of the array 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; // // to get away a compiler warning. return CVData::empty; } } void blindComplexData::copy( const MPxData& other ) // // Deescription: // Perform a copy or a conversion // { 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 { // we need to convert to the other type based on its iff Tag 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); // // Note: a better solution to determine the number of records is to // write out the number of records in the writeASCII() routine. // if ( numDataRecord % 2 != 0 ) { cerr << "warning: corrupted data for blindComplexData" << endl; } // // 2 numbers per record. 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; } ////////////////////////////////////////////////////////////////////////////// // // Command class implementation // ////////////////////////////////////////////////////////////////////////////// void* blindComplexDataCmd::creator() { return new blindComplexDataCmd; } blindComplexDataCmd::~blindComplexDataCmd() { } blindComplexDataCmd::blindComplexDataCmd() : MPxCommand() { } MStatus blindComplexDataCmd::doIt( const MArgList& ) { MStatus stat; // Create a selection list iterator // 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; // Status code MObject dependNode; // Selected dependency node // Iterate over all selected dependency nodes // for ( ; !iter->isDone(); iter->next() ) { // Get the selected dependency node and create // a function set for it // 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; } // Create a new attribute for our blind data // // cout << "Creating attr..." << endl; MFnTypedAttribute fnAttr; const MString fullName( "blindComplexData" ); const MString briefName( "BCD" ); MObject newAttr = fnAttr.create( fullName, briefName, blindComplexData::id ); // Now add the new attribute to the current dependency node // // cout << "Adding attr..." << endl; fnDN.addAttribute( newAttr, MFnDependencyNode::kLocalDynamicAttr ); // // now we will demonstrate setting the value by using a plug. MPlug plug( dependNode, newAttr ); // // create an instance of the blind data with an initial array size of // 5. blindComplexData * newData = new blindComplexData( 5 ); // // initialized // cout << "setting data values..." << endl; unsigned int i; for ( i= 0; i < newData->length(); i++ ) { (*newData)[i]._intData = 10 + i; (*newData)[i]._doubleData = 20.02 + i; } // // setting the value for the plug. stat = plug.setValue( newData ); // // The following code demonstrates the retrieving of data from the // plug. MObject sData; stat = plug.getValue( sData ); if ( stat != MS::kSuccess ) { cerr << "error getting value off plug" << endl; continue; } // // Convert the data from an MObject back to a pointer to MPxData, then // cast it back to a pointer to blindComplexData. MFnPluginData pdFn( sData ); blindComplexData* data = ( blindComplexData* ) pdFn.constData( &stat ); // // read the data, and set the result to the values set. clearResult(); if ( NULL != data ) { // cout << "retrieving data values..." << endl; for ( i = 0; i < data->length(); i++ ) { // cout << "rec #" << i << ": " << (*data)[i]._intData << ", "; // cout << (*data)[i]._doubleData << endl; appendToResult((double) ((*data)[i]._intData)); appendToResult((*data)[i]._doubleData); } } else { // cout << "Null data" << endl; } } return MS::kSuccess; } MStatus blindComplexDataCmd::undoIt() { return MS::kSuccess; } bool blindComplexDataCmd::isUndoable() const { return true; } ////////////////////////////////////////////////////////////////////////////// // // The following routines are used to register/unregister // the command we are creating within Maya // ////////////////////////////////////////////////////////////////////////////// MStatus initializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj, "Alias", "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; }