#include "AbcBullet.h"
#include "AbcWriteJob.h"
#include "MayaUtility.h"
#include "AbcBulletStringTable.h"
#include <maya/MFnPlugin.h>
#include <maya/MFileObject.h>
#include <maya/MItDependencyNodes.h>
#include <fstream>
#include <maya/MItDependencyNodes.h>
#include <maya/MTimer.h>
namespace AbcA = Alembic::AbcCoreAbstract;
AbcBullet::AbcBullet()
{
}
AbcBullet::~AbcBullet()
{
}
{
return syntax;
}
void* AbcBullet::creator()
{
return new AbcBullet();
}
{
try
{
if (argData.isFlagSet("help"))
{
return MS::kSuccess;
}
bool verbose = argData.isFlagSet("verbose");
bool skipFrame = true;
if (argData.isFlagSet("dontSkipUnwrittenFrames"))
skipFrame = false;
double startEvaluationTime = DBL_MAX;
if (argData.isFlagSet("preRollStartFrame"))
{
double startAt = 0.0;
argData.getFlagArgument("preRollStartFrame", 0, startAt);
startEvaluationTime = startAt;
}
unsigned int jobSize = argData.numberOfFlagUses("jobArg");
if (jobSize == 0)
return status;
std::set<double> allFrameRange;
std::list < AbcWriteJobPtr > jobList;
for (unsigned int jobIndex = 0; jobIndex < jobSize; jobIndex++)
{
JobArgs jobArgs;
argData.getFlagArgumentList("jobArg", jobIndex, jobArgList);
jobArgs.verbose = verbose;
{
enum State {
kArgument,
kDoubleQuotedString,
kSingleQuotedString,
};
State state = kArgument;
for (
unsigned int charIdx = 0; charIdx < jobArgsStr.
numChars();
charIdx++)
{
switch (state)
{
case kArgument:
if (ch == " ")
{
if (stringBuffer.
length() > 0) {
jobArgsArray.
append(stringBuffer);
}
state = kArgument;
}
else if (ch == "\"")
{
if (stringBuffer.
length() > 0)
{
stringBuffer += ch;
}
else
{
state = kDoubleQuotedString;
}
}
else if (ch == "'")
{
if (stringBuffer.
length() > 0)
{
stringBuffer += ch;
}
else
{
state = kSingleQuotedString;
}
}
else
{
stringBuffer += ch;
}
break;
case kDoubleQuotedString:
if (ch == "\"")
{
jobArgsArray.
append(stringBuffer);
state = kArgument;
}
else if (ch == "\\")
{
if (nextCh == "n") stringBuffer += "\n";
else if (nextCh == "t") stringBuffer += "\t";
else if (nextCh == "r") stringBuffer += "\r";
else if (nextCh == "\\") stringBuffer += "\\";
else if (nextCh == "'") stringBuffer += "'";
else if (nextCh == "\"") stringBuffer += "\"";
else stringBuffer += nextCh;
}
else
{
stringBuffer += ch;
}
break;
case kSingleQuotedString:
if (ch == "'")
{
jobArgsArray.
append(stringBuffer);
state = kArgument;
}
else if (ch == "\\")
{
if (nextCh == "n") stringBuffer += "\n";
else if (nextCh == "t") stringBuffer += "\t";
else if (nextCh == "r") stringBuffer += "\r";
else if (nextCh == "\\") stringBuffer += "\\";
else if (nextCh == "'") stringBuffer += "'";
else if (nextCh == "\"") stringBuffer += "\"";
else stringBuffer += nextCh;
}
else
{
stringBuffer += ch;
}
break;
}
}
if (stringBuffer.
length() > 0)
{
jobArgsArray.
append(stringBuffer);
}
}
double startTime = oldCurTime.
value();
double endTime = oldCurTime.
value();
double strideTime = 1.0;
bool hasRange = false;
bool hasRoot = false;
std::set <double> shutterSamples;
std::string fileName;
unsigned int numJobArgs = jobArgsArray.
length();
for (unsigned int i = 0; i < numJobArgs; ++i)
{
if (arg == "-f" || arg == "-file")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
fileName = jobArgsArray[++i].asChar();
}
else if (arg == "-fr" || arg == "-framerange")
{
if (i+2 >= numJobArgs || !jobArgsArray[i+1].isDouble() ||
!jobArgsArray[i+2].isDouble())
{
return MS::kFailure;
}
hasRange = true;
startTime = jobArgsArray[++i].asDouble();
endTime = jobArgsArray[++i].asDouble();
if (startTime > endTime)
{
double temp = startTime;
startTime = endTime;
endTime = temp;
}
}
else if (arg == "-frs" || arg == "-framerelativesample")
{
if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble())
{
return MS::kFailure;
}
shutterSamples.insert(jobArgsArray[++i].asDouble());
}
else if (arg == "-nn" || arg == "-nonormals")
{
jobArgs.noNormals = true;
}
else if (arg == "-ro" || arg == "-renderableonly")
{
jobArgs.excludeInvisible = true;
}
else if (arg == "-s" || arg == "-step")
{
if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble())
{
return MS::kFailure;
}
strideTime = jobArgsArray[++i].asDouble();
}
else if (arg == "-sl" || arg == "-selection")
{
jobArgs.useSelectionList = true;
}
else if (arg == "-sn" || arg == "-stripnamespaces")
{
if (i+1 >= numJobArgs || !jobArgsArray[i+1].isUnsigned())
{
jobArgs.stripNamespace = 0xffffffff;
}
else
{
jobArgs.stripNamespace = jobArgsArray[++i].asUnsigned();
}
}
else if (arg == "-uv" || arg == "-uvwrite")
{
jobArgs.writeUVs = true;
}
else if (arg == "-wcs" || arg == "-writecolorsets")
{
jobArgs.writeColorSets = true;
}
else if (arg == "-wfs" || arg == "-writefacesets")
{
jobArgs.writeFaceSets = true;
}
else if (arg == "-ws" || arg == "-worldspace")
{
jobArgs.worldSpace = true;
}
else if (arg == "-wv" || arg == "-writevisibility")
{
jobArgs.writeVisibility = true;
}
else if (arg == "-mfc" || arg == "-melperframecallback")
{
if (i+1 >= numJobArgs)
{
"melPerFrameCallback incorrectly specified.");
return MS::kFailure;
}
jobArgs.melPerFrameCallback = jobArgsArray[++i].asChar();
}
else if (arg == "-pfc" || arg == "-pythonperframecallback")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
jobArgs.pythonPerFrameCallback = jobArgsArray[++i].asChar();
}
else if (arg == "-mpc" || arg == "-melpostjobcallback")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
jobArgs.melPostCallback = jobArgsArray[++i].asChar();
}
else if (arg == "-ppc" || arg == "-pythonpostjobcallback")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
jobArgs.pythonPostCallback = jobArgsArray[++i].asChar();
}
else if (arg == "-atp" || arg == "-attrprefix")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
jobArgs.prefixFilters.push_back(jobArgsArray[++i].asChar());
}
else if (arg == "-a" || arg == "-attr")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
jobArgs.attribs.insert(jobArgsArray[++i].asChar());
}
else if (arg == "-uatp" || arg == "-userattrprefix")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
jobArgs.userPrefixFilters.push_back(jobArgsArray[++i].asChar());
}
else if (arg == "-u" || arg == "-userattr")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
jobArgs.userAttribs.insert(jobArgsArray[++i].asChar());
}
else if (arg == "-rt" || arg == "-root")
{
if (i+1 >= numJobArgs)
{
return MS::kFailure;
}
hasRoot = true;
if (sel.
add(root) != MS::kSuccess)
{
warn += " could not be select, skipping.";
continue;
}
unsigned int numRoots = sel.
length();
for (unsigned int j = 0; j < numRoots; ++j)
{
{
warn += " (part of ";
warn += root;
warn += " ) not a DAG Node, skipping.";
continue;
}
jobArgs.dagPaths.insert(path);
}
}
else if (arg == "-ef" || arg == "-eulerfilter")
{
jobArgs.filterEulerRotations = true;
}
else
{
MString warn =
"Ignoring unsupported flag: ";
warn += jobArgsArray[i];
}
}
if (fileName == "")
{
MString error =
"-file not specified.";
return MS::kFailure;
}
{
MString alembicFileRule =
"alembicCache";
MString alembicFilePath =
"cache/alembic";
queryFileRuleCmd.
format(
"workspace -q -fre \"^1s\"",
alembicFileRule);
queryFolderCmd.
format(
"workspace -en `workspace -q -fre \"^1s\"`",
alembicFileRule);
{
}
else
{
addFileRuleCmd.
format(
"workspace -fr \"^1s\" \"^2s\"",
alembicFileRule, alembicFilePath);
}
{
expandName = alembicFilePath;
}
{
createFolderCmd.
format(
"sysFile -md \"^1s\"", directoryName);
}
#if MAYA_API_VERSION < 201300
{
#else
#endif
MString absoluteFileName = directoryName +
"/" +
fileName.c_str();
}
else
{
}
if (!absoluteFilePath.
exists()) {
return MS::kFailure;
}
for (; !dgIter.isDone(); dgIter.next()) {
if (alembicNode.typeName() != "AlembicNode") {
continue;
}
MPlug abcFilePlug = alembicNode.findPlug(
"abc_File",
true);
continue;
}
continue;
}
MString error =
"Can't export to an Alembic file which is in use.";
return MS::kFailure;
}
}
std::ofstream ofs(fileName.c_str());
if (!ofs.is_open()) {
return MS::kFailure;
}
ofs.close();
}
if (shutterSamples.empty())
{
shutterSamples.insert(0.0);
}
if (jobArgs.prefixFilters.empty())
{
jobArgs.prefixFilters.push_back("ABC_");
}
std::set<double> transSamples;
std::set <double>::const_iterator shutter;
std::set <double>::const_iterator shutterStart = shutterSamples.begin();
std::set <double>::const_iterator shutterEnd = shutterSamples.end();
for (double frame = startTime; frame <= endTime; frame += strideTime)
{
for (shutter = shutterStart; shutter != shutterEnd; ++shutter)
{
double curFrame = *shutter + frame;
transSamples.insert(curFrame);
}
}
if (transSamples.empty())
{
transSamples.insert(startTime);
}
if (jobArgs.dagPaths.size() > 1)
{
util::ShapeSet::const_iterator m, n;
util::ShapeSet::const_iterator end = jobArgs.dagPaths.end();
for (m = jobArgs.dagPaths.begin(); m != end; )
{
m++;
for (n = m; n != end; n++)
{
if (util::isAncestorDescendentRelationship(path1,path2))
{
errorMsg += " and ";
errorMsg += " have an ancestor relationship.";
return MS::kFailure;
}
}
}
}
else if (!hasRoot && !jobArgs.useSelectionList)
{
#if MAYA_API_VERSION >= 201100
#else
#endif
unsigned int numRoots = sel.
length();
for (unsigned int i = 0; i < numRoots; ++i)
{
jobArgs.dagPaths.insert(path);
}
}
else if (hasRoot && jobArgs.dagPaths.empty())
{
MString errorMsg =
"No valid root nodes were specified.";
return MS::kFailure;
}
else if (jobArgs.useSelectionList)
{
{
"-selection specified but nothing is actively selected.";
return MS::kFailure;
}
}
AbcA::TimeSamplingPtr transTime;
std::vector<double> samples;
for (shutter = shutterStart; shutter != shutterEnd; ++shutter)
{
samples.push_back((startTime + *shutter) * util::spf());
}
if (hasRange)
{
transTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType(
static_cast<Alembic::Util::uint32_t>(samples.size()),
strideTime * util::spf()), samples));
}
else
{
transTime.reset(new AbcA::TimeSampling());
}
AbcWriteJobPtr job(new AbcWriteJob(fileName.c_str(),
transSamples, transTime, jobArgs));
jobList.push_front(job);
if (!skipFrame && !allFrameRange.empty())
{
double localMin = *(transSamples.begin());
std::set<double>::iterator last = transSamples.end();
last--;
double localMax = *last;
double globalMin = *(allFrameRange.begin());
last = allFrameRange.end();
last--;
double globalMax = *last;
if (localMin > globalMax)
{
for (double f = globalMax; f < localMin; f++)
{
allFrameRange.insert(f);
}
}
if (localMax < globalMin)
{
for (double f = localMax; f < globalMin; f++)
{
allFrameRange.insert(f);
}
}
}
allFrameRange.insert(transSamples.begin(), transSamples.end());
}
if (startEvaluationTime != DBL_MAX && !allFrameRange.empty())
{
double firstFrame = *allFrameRange.begin();
for (double f = startEvaluationTime; f < firstFrame; ++f)
{
allFrameRange.insert(f);
}
}
std::set<double>::iterator it = allFrameRange.begin();
std::set<double>::iterator itEnd = allFrameRange.end();
for (; it != itEnd; it++)
{
std::list< AbcWriteJobPtr >::iterator j = jobList.begin();
std::list< AbcWriteJobPtr >::iterator jend = jobList.end();
while (j != jend)
{
return MS::kFailure;
bool lastFrame = (*j)->eval(*it);
if (lastFrame)
{
j = jobList.erase(j);
}
else
j++;
}
if (verbose)
{
double frame = *it;
info.
format(
"processed frame: ^1s in ^2s seconds", arg1, arg2 );
}
}
return MS::kSuccess;
}
catch (Alembic::Util::Exception & e)
{
MString theError(
"Alembic Exception encountered: ");
theError += e.what();
return MS::kFailure;
}
catch (std::exception & e)
{
MString theError(
"std::exception encountered: ");
theError += e.what();
return MS::kFailure;
}
}
{
MFnPlugin plugin(obj,
"AbcBullet", ABCBULLET_VERSION,
"Any");
status = plugin.registerCommand(
"AbcBulletExport", AbcBullet::creator,
AbcBullet::createSyntax );
if (!status)
{
status.
perror(
"registerCommand");
}
info += ABCBULLET_VERSION;
info += " using ";
info += Alembic::Abc::GetLibraryVersion().c_str();
return status;
}
{
status = plugin.deregisterCommand("AbcBulletExport");
if (!status)
{
status.
perror(
"deregisterCommand");
}
return status;
}