New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redpawfx #21

Open
wants to merge 470 commits into
base: master
from
Commits
Jump to file or symbol
Failed to load files and symbols.
+73 −22
Diff settings

Always

Just for now

Viewing a subset of changes. View all

Export arbitrary time mappings.

  • Loading branch information...
sirpalee committed Jun 6, 2017
commit 5d7ef24d4ea1b1602f3ff81511e236b01be38538
@@ -1,6 +1,7 @@
#include <pxr/pxr.h>
#include <pxr/base/tf/fileUtils.h>
#include <pxr/usd/usd/clipsAPI.h>
#include <pxr/usd/usdGeom/points.h>
#include <usdMaya/primWriterRegistry.h>
@@ -16,13 +17,15 @@ namespace {
constexpr auto _cacheDir = "cacheDir";
constexpr auto _cachePrefix = "cachePrefix";
const std::array<std::string, 3> _extensionList = {"usd", "usda", "usdc"};
boost::regex _frameAndExtensionRe;
boost::regex _frameRe;
auto createFileName = [](const std::string& dir, const std::string& prefix, const std::string& suffix, const std::string& ext) -> std::string {
auto _createFileName = [](const std::string& dir, const std::string& prefix, const std::string& suffix, const std::string& ext) -> std::string {
std::stringstream ss; ss << dir << prefix << "result.topology" << suffix << ext;
return ss.str();
};
auto clearRegex = [](const std::string& in) -> std::string {
auto _clearRegex = [](const std::string& in) -> std::string {
std::string ret = in;
size_t pos = -2;
while ((pos = ret.find('.', pos + 2)) != std::string::npos) {
@@ -32,9 +35,10 @@ namespace {
};
template <size_t N>
std::string searchFile(const std::string& dir, const std::string& prefix, const std::string& suffix, const std::array<std::string, N>& extensions) {
std::string _searchFile(const std::string& dir, const std::string& prefix, const std::string& suffix,
const std::array<std::string, N>& extensions) {
for (const auto& ext : extensions) {
const auto ret = createFileName(dir, prefix, suffix, ext);
const auto ret = _createFileName(dir, prefix, suffix, ext);
if (TfIsFile(ret)) {
return ret;
}
@@ -47,10 +51,9 @@ namespace {
public:
partioVisualizerWriter(const MDagPath & iDag, const SdfPath& uPath, bool instanceSource, usdWriteJobCtx& jobCtx) :
MayaTransformWriter(iDag, uPath, instanceSource, jobCtx) {
mUsdPrim = getUsdStage()->DefinePrim(getUsdPath());
mUsdPrim = UsdGeomPoints::Define(getUsdStage(), getUsdPath()).GetPrim();
TF_AXIOM(mUsdPrim);
static boost::regex re;
static std::once_flag once_flag;
std::call_once(once_flag, []() {
std::stringstream ss;
@@ -63,51 +66,99 @@ namespace {
ss << "|" << *formatIt;
}
ss << ")$";
re = boost::regex(ss.str().c_str());
_frameAndExtensionRe = boost::regex(ss.str().c_str());
_frameRe = boost::regex("(.+[\\.|_])([0-9]+)([\\.|_].+)");
});
MFnDagNode dgNode(iDag);
std::string cacheDir = dgNode.findPlug(_cacheDir).asString().asChar();
if (cacheDir.size() > 0 && cacheDir.back() != '/') { cacheDir += "/"; }
const std::string cachePrefix = dgNode.findPlug(_cachePrefix).asString().asChar();
boost::cmatch match;
if (boost::regex_search(cachePrefix.c_str(), match, re)) {
if (boost::regex_search(cachePrefix.c_str(), match, _frameAndExtensionRe)) {
const auto match_1 = match[1].str();
const auto match_3 = match[3].str();
const auto match_4 = match[4].str();
auto manifestPath = searchFile(cacheDir, match_1, match_3, _extensionList);
auto manifestPath = _searchFile(cacheDir, match_1, match_3, _extensionList);
if (manifestPath.empty()) {
// We will try to stitch the file together using partusdtopology.
manifestPath = createFileName(cacheDir, match_1, match_3, _extensionList.front());
manifestPath = _createFileName(cacheDir, match_1, match_3, _extensionList.front());
std::stringstream ss;
ss << "partusdtopology " << "\"" << cacheDir << clearRegex(match_1) << "[0-9]+"
<< clearRegex(match_3) << match_4 << "\" \"" << manifestPath << "\"";
ss << "partusdtopology " << "\"" << cacheDir << _clearRegex(match_1) << "[0-9]+"
<< _clearRegex(match_3) << match_4 << "\" \"" << manifestPath << "\"";
std::cerr << "Runing command : " << ss.str() << std::endl;
const auto ret = system(ss.str().c_str());
if (ret != 0 || !TfIsFile(manifestPath)) {
TF_WARN("Manifest file does not exists and/or can't be created. %s", manifestPath.c_str());
return;
}
}
if (!boost::regex_search(cachePrefix.c_str(), match, _frameRe)) { return; }
std::stringstream ss; ss << cacheDir
<< match[1].str()
<< "%0"
<< match[2].str().length()
<< "d"
<< match[3].str();
mFormatString = ss.str();
mIsValid = true;
mUsdPrim.GetReferences().AppendReference(SdfReference(manifestPath));
UsdClipsAPI clips(mUsdPrim);
clips.SetClipManifestAssetPath(SdfAssetPath(manifestPath));
clips.SetClipPrimPath("/points");
std::stringstream ss;
ss << cacheDir << match_1;
const auto numDigits = match[2].str().length();
for (auto i = decltype(numDigits){0}; i < numDigits; ++i) { ss << "#"; }
ss << match_3 << match_4;
clips.SetClipTemplateAssetPath(ss.str());
clips.SetClipTemplateStartTime(getArgs().startTime);
clips.SetClipTemplateEndTime(getArgs().endTime);
clips.SetClipTemplateStride(1);
mPathBuffer.resize(mFormatString.length() + 1, '\0');
const auto numberOfFrames = std::max(1ul, static_cast<size_t>(getArgs().endTime - getArgs().startTime));
mClipTimes.reserve(numberOfFrames);
mClipAssetPaths.reserve(numberOfFrames);
mClipActive.reserve(numberOfFrames);
} else {
const auto cacheFile = cacheDir + cachePrefix;
TF_WARN("%s is not a valid path to a PartIO cache.", cacheFile.c_str());
}
}
~partioVisualizerWriter() { };
void write(const UsdTimeCode& usdTime) override {
if (usdTime.IsDefault()) { return; }
UsdGeomPoints points(mUsdPrim);
writeTransformAttrs(usdTime, points);
MFnDagNode dagNode(getDagPath());
const auto frame = dagNode.findPlug("time").asInt();
sprintf(mPathBuffer.data(), mFormatString.c_str(), frame);
SdfAssetPath assetPath(mPathBuffer.data());
if (!TfIsFile(assetPath.GetAssetPath())) { return; }
// We are taking the simplest route here to handle all the cases.
// Honestly, I can't be bothered to optimize this, since this is such a miniscule operation
// compared to the path validity checks and other calls we are making.
const auto timeValue = usdTime.GetValue();
mClipTimes.push_back(GfVec2d(timeValue, timeValue));
const auto it = std::find(mClipAssetPaths.begin(), mClipAssetPaths.end(), assetPath);
if (it == mClipAssetPaths.end()) {
mClipActive.push_back(GfVec2d(timeValue, static_cast<double>(mClipAssetPaths.size())));
mClipAssetPaths.push_back(assetPath);
} else {
mClipActive.push_back(GfVec2d(timeValue, static_cast<double>(std::distance(mClipAssetPaths.begin(), it))));
}
}
~partioVisualizerWriter() {
if (mIsValid) {
UsdClipsAPI clips(mUsdPrim);
clips.SetClipTimes(mClipTimes);
clips.SetClipActive(mClipActive);
clips.SetClipAssetPaths(mClipAssetPaths);
}
};
VtVec2dArray mClipTimes;
VtVec2dArray mClipActive;
VtArray<SdfAssetPath> mClipAssetPaths;
std::string mFormatString;
std::vector<char> mPathBuffer;
bool mIsValid;
};
using partioVisualizerWriterPtr = std::shared_ptr<partioVisualizerWriter>;
ProTip! Use n and p to navigate between commits in a pull request.