aboutsummaryrefslogtreecommitdiff
path: root/mayaPlug/shaveBlindData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mayaPlug/shaveBlindData.cpp')
-rw-r--r--mayaPlug/shaveBlindData.cpp360
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);
+}