diff options
Diffstat (limited to 'mayaPlug/shaveBlindData.cpp')
| -rw-r--r-- | mayaPlug/shaveBlindData.cpp | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/mayaPlug/shaveBlindData.cpp b/mayaPlug/shaveBlindData.cpp new file mode 100644 index 0000000..deae943 --- /dev/null +++ b/mayaPlug/shaveBlindData.cpp @@ -0,0 +1,360 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +#include <maya/MGlobal.h> +#include <string.h> +#include "shaveSDK.h" +#include "shaveBlindData.h" +#include "shaveDebug.h" +#include "shaveUtil.h" + + +MTypeId blindShaveData::dataTypeId(0x83001); +const MString blindShaveData::dataTypeName("blindShaveData"); + + +/* + * Proxy data class implementation + */ + +void* blindShaveData::creator() +{ + + return new blindShaveData; +} + + +blindShaveData::blindShaveData() +{ + init_MEMFILE(&m, 0); +} + + +blindShaveData::~blindShaveData() +{ + free_MEMFILE(&m); +} + + +void blindShaveData::clear() +{ + free_MEMFILE(&m); +} + + +void blindShaveData::copy(const MPxData& other) +// +// Deescription: +// Perform a copy. +// +{ + if (other.typeId() == blindShaveData::dataTypeId) + { + const blindShaveData& otherData = (const blindShaveData&)other; + + copy_MEMFILE(&m, (MEMFILE*)&otherData.m); + } + + return; +} + + +void blindShaveData::resize(int newSize) +{ + if (newSize < 0) newSize = 0; + + if (m.size != newSize) + { + clear(); + + if (newSize > 0) + { + m.data = (char*)malloc(newSize); + m.size = newSize; + } + } +} + + +void blindShaveData::setValue(const void* newData, int newDataLen) +{ + resize(newDataLen); + memcpy(m.data, newData, m.size); +} + + +MTypeId blindShaveData::typeId() const +{ + return blindShaveData::dataTypeId; +} + + +MString blindShaveData::name() const +{ + return blindShaveData::dataTypeName; +} + + +MStatus blindShaveData::readASCII( + const MArgList& args, unsigned& lastParsedElement +) +{ + MStatus status; + MString s; + int datasize; + int argLength = args.length(); + + + if (argLength > 0) + { + datasize = args.asInt(lastParsedElement++, &status); + + resize(datasize); + + // + // Prior to shaveNode version 11, we stored each byte as a separate + // value. From version 11 onward we stored the data as 4-byte + // words, with any leftover bytes stored individually at the end. + // + // So we need to compare the number of remaining arguments against + // the overall datasize to see which format this is. + // + int i; + + if (argLength - (int)lastParsedElement >= datasize) + { + for(i = 0; i < datasize; i++) + m.data[i] = (char)args.asInt(lastParsedElement++, &status); + } + else + { + int intval; +#if defined(IRIX) || defined(__ppc__) + char* p = (char*)&intval; +#endif + int stop = datasize - 3; + + for (i = 0; i < stop; i += 4) + { + intval = args.asInt(lastParsedElement++, &status); +#if defined(IRIX) || defined(__ppc__) + // + // We save values to file in LSB-first order. IRIX and + // PowerPC use MSB_first ordering, so we need to swap the + // byte order. + // + m.data[i+3] = p[0]; + m.data[i+2] = p[1]; + m.data[i+1] = p[2]; + m.data[i] = p[3]; +#else + *(int *)&m.data[i] = intval; +#endif + } + + // + // Grab any leftover bytes one at a time. + // + for (; i < datasize; i++) + m.data[i] = (char)args.asInt(lastParsedElement++, &status); + } + + return MS::kSuccess; + } + + return MS::kFailure; +} + + +MStatus blindShaveData::writeASCII(ostream& out) +{ + int i; + int intval; +#if defined(IRIX) || defined(__ppc__) + char* p = (char*)&intval; +#endif + int stop = 0; + + out << m.size; + + if (m.size > 3) stop = m.size - 3; + + // + // We write the data out as 4-byte ints because that's a bit faster and + // makes the file a bit smaller. + // + for (i = 0; i < stop; i += 4) + { +#if defined(IRIX) || defined(__ppc__) + // + // We save values to file in LSB-first order. IRIX and PowerPC use + // MSB-first ordering, so we need to swap the byte order. + // + p[0] = m.data[i+3]; + p[1] = m.data[i+2]; + p[2] = m.data[i+1]; + p[3] = m.data[i]; +#else + intval = *(int*)&m.data[i]; +#endif + out << ' ' << intval; + + // + // Start a new line after every 10 longwords, just to make viewing + // and editing the .ma files a bit easier. + // + if (i % 40 == 36) out << endl; + } + + // + // If the number of bytes was not divisible by 4, we'll have a few left + // over, so just write them out one byte at a time. + // + for (; i < m.size; i++) + out << ' ' << (int)m.data[i]; + + return out.fail() ? MS::kFailure : MS::kSuccess; +} + + +#ifdef JOETEST +MStatus blindShaveData::writeASCII(ostream& out) +{ + char intdata[10000]; + int position=0; + int start,stop; + + out << m.size; + out << " "; + +// for(int i = 0; i < m.size; i++) +while (position<m.size) +{ + int ii=0; + intdata[0]=0; + start=position; + stop=position+1000; + if (stop>m.size) stop=m.size; + + for(int i = start; i < stop; i++) + { + + sprintf(intdata, "%d ",m.data[i]); + ii++; + + } + out << intdata; + position+=ii; + intdata[0]=0; +} + + return out.fail() ? MS::kFailure : MS::kSuccess; + +} +#endif + + +// +// NOTE: You might have noticed that we read and write the MEMFILE's +// 'pos' member when doing binary I/O but not when doing ASCII +// I/O. Clearly Shave manages to get along fine without it, but +// this was how I inherited the code, and to change it now would +// break a lot of existing scene files, so we let the dichotomy +// stand. +// + + +MStatus blindShaveData::readBinary(istream& in, unsigned length) +{ + ENTER(); + + int expectedSize = length - 2 * sizeof(int); + int storedSize; + bool LSBfirst = false; + + in.read ((char*) &storedSize, sizeof(int)); + +#if defined(IRIX) || defined(__ppc__) + storedSize = shaveUtil::reorderInt(storedSize); +#endif + + if (storedSize != expectedSize) + { + // + // Prior to version 8 of the shaveNode, little-endian systems such + // as IRIX and OSX incorrectly wrote their sizes to the scene file + // in little-endian form, which made the files unreadable on other + // platforms. + // + // From version 8 onward that was corrected so that little-endian + // systems reorder the bytes before writing them to the file. + // + // However, it is possible that the current scene file is an old + // one from a little-endian system, in which case the sizes will + // still be in little-endian format. + // + // So let's flip the ordering and see if we get a match. + // + storedSize = shaveUtil::reorderInt(storedSize); + + if (storedSize != expectedSize) + { + // + // We must have a corrupt file. Just return without an error + // code because the license check later on will fail on the + // empty blind data and display an appropriate message. + // + RETURN(MS::kSuccess); + } + + LSBfirst = true; + } + + resize(storedSize); + + in.read((char*) &(m.pos), sizeof(int)); + +#if defined(IRIX) || defined(__ppc__) + m.pos = shaveUtil::reorderInt(m.pos); +#endif + + if (LSBfirst) m.pos = shaveUtil::reorderInt(m.pos); + +#ifdef DEBUG + char msg[200]; + sprintf(msg, "reading %d bytes of blind data", storedSize); + MGlobal::displayInfo(msg); +#endif + + in.read((char*) m.data, storedSize); + + RETURN(in.fail() ? MS::kFailure : MS::kSuccess); + +} + + +MStatus blindShaveData::writeBinary(ostream& out) +{ + ENTER(); + +#if defined(IRIX) || defined(__ppc__) + int pos = shaveUtil::reorderInt(m.pos); + int size = shaveUtil::reorderInt(m.size); +#else + int pos = m.pos; + int size = m.size; +#endif + + out.write ((char*) &(size), sizeof(int)); + out.write ((char*) &(pos), sizeof(int)); + out.write ((char*) m.data, m.size); + +#ifdef DEBUG + char msg[200]; + sprintf(msg, "wrote %d bytes of blind data", m.size); + MGlobal::displayInfo(msg); +#endif + + RETURN(out.fail() ? MS::kFailure : MS::kSuccess); +} |