Skip to content

Commit

Permalink
NEW: Maya namespaces are removed from glTF names. To keep them, pass …
Browse files Browse the repository at this point in the history
…the -kon flag
  • Loading branch information
ziriax committed Nov 18, 2020
1 parent 34aa09e commit 03f669e
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 64 deletions.
91 changes: 58 additions & 33 deletions src/Arguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ const auto constantRotationThreshold = "crt";
const auto constantScalingThreshold = "cst";
const auto constantWeightsThreshold = "cwt";

const auto keepObjectNamespace = "kon";

} // namespace flag

inline const char *getArgTypeName(const MSyntax::MArgType argType) {
Expand Down Expand Up @@ -182,7 +184,7 @@ SyntaxFactory::SyntaxFactory() {
registerFlag(ss, flag::forceRootNode, "forceRootNode", kNoArg);
registerFlag(ss, flag::forceAnimationChannels, "forceAnimationChannels", kNoArg);
registerFlag(ss, flag::forceAnimationSampling, "forceAnimationSampling", kNoArg);

registerFlag(ss, flag::hashBufferURIs, "hashBufferUri", kNoArg);
registerFlag(ss, flag::niceBufferURIs, "niceBufferNames", kNoArg);

Expand All @@ -197,6 +199,8 @@ SyntaxFactory::SyntaxFactory() {
registerFlag(ss, flag::constantScalingThreshold, "constantScalingThreshold", kDouble);
registerFlag(ss, flag::constantWeightsThreshold, "constantWeightsThreshold", kDouble);

registerFlag(ss, flag::keepObjectNamespace, "keepMayaNamespaces", kNoArg);

m_usage = ss.str();
}

Expand All @@ -212,13 +216,11 @@ MSyntax SyntaxFactory::createSyntax() {
return s;
}

void SyntaxFactory::registerFlag(std::stringstream &ss, const char *shortName, const char *longName,
const MArgType argType1) {
void SyntaxFactory::registerFlag(std::stringstream &ss, const char *shortName, const char *longName, const MArgType argType1) {
registerFlag(ss, shortName, longName, false, argType1);
}

void SyntaxFactory::registerFlag(std::stringstream &ss, const char *shortName, const char *longName,
const bool isMultiUse, const MArgType argType1) {
void SyntaxFactory::registerFlag(std::stringstream &ss, const char *shortName, const char *longName, const bool isMultiUse, const MArgType argType1) {
// short-name should be unique
assert(m_argNames.find(shortName) == m_argNames.end());

Expand Down Expand Up @@ -297,8 +299,7 @@ class ArgChecker {

int flagUsageCount(const char *shortName) const { return adb.numberOfFlagUses(shortName); }

template <typename T>
void required(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
template <typename T> void required(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
MStatus status;

if (!isFlagSet(shortName))
Expand All @@ -310,16 +311,13 @@ class ArgChecker {
} else {
MArgList args;
status = adb.getFlagArgumentList(shortName, flagIndex, args);
throwOnArgument(status, shortName,
formatted("Failed to get required multi-flag #%d argument", flagIndex).c_str());
throwOnArgument(status, shortName, formatted("Failed to get required multi-flag #%d argument", flagIndex).c_str());
status = args.get(componentIndex, value);
throwOnArgument(status, shortName,
formatted("Failed to get required multi-flag #%d argument value", flagIndex).c_str());
throwOnArgument(status, shortName, formatted("Failed to get required multi-flag #%d argument value", flagIndex).c_str());
}
}

template <typename T>
bool optional(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
template <typename T> bool optional(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
if (!adb.isFlagSet(shortName))
return false;

Expand All @@ -331,11 +329,9 @@ class ArgChecker {
} else {
MArgList args;
status = adb.getFlagArgumentList(shortName, flagIndex, args);
throwOnArgument(status, shortName,
formatted("Failed to get optional multi-flag #%d argument", flagIndex).c_str());
throwOnArgument(status, shortName, formatted("Failed to get optional multi-flag #%d argument", flagIndex).c_str());
status = args.get(componentIndex, value);
throwOnArgument(status, shortName,
formatted("Failed to get optional multi-flag #%d argument value", flagIndex).c_str());
throwOnArgument(status, shortName, formatted("Failed to get optional multi-flag #%d argument value", flagIndex).c_str());
}

return true;
Expand All @@ -357,8 +353,7 @@ class ArgChecker {
return true;
}

std::unique_ptr<IndentableStream> getOutputStream(const char *arg, const char *outputName,
const fs::path &outputFolder,
std::unique_ptr<IndentableStream> getOutputStream(const char *arg, const char *outputName, const fs::path &outputFolder,
std::ofstream &fileOutputStream) const {
std::ostream *out = nullptr;

Expand Down Expand Up @@ -401,19 +396,16 @@ class ArgChecker {
const auto longArgName = SyntaxFactory::get().longArgName(shortArgName);
const auto statusStr = status.errorString().asChar();
const auto usageStr = SyntaxFactory::get().usage();
throw MayaException(
status, message ? formatted("-%s (-%s): %s\nUsage:\n%s", shortArgName, longArgName, statusStr, usageStr)
: formatted("-%s (-%s): %s %s\nUsage:\n%s", shortArgName, longArgName, message,
statusStr, usageStr));
throw MayaException(status, message ? formatted("-%s (-%s): %s\nUsage:\n%s", shortArgName, longArgName, statusStr, usageStr)
: formatted("-%s (-%s): %s %s\nUsage:\n%s", shortArgName, longArgName, message, statusStr, usageStr));
}
}

static void throwInvalid(const char *shortArgName, const char *message = "Invalid parameter") {
const auto longArgName = SyntaxFactory::get().longArgName(shortArgName);
const auto usageStr = SyntaxFactory::get().usage();

throw MayaException(MStatus::kInvalidParameter,
formatted("%s -%s (%s)\nUsage:\n%s", message, shortArgName, longArgName, usageStr));
throw MayaException(MStatus::kInvalidParameter, formatted("%s -%s (%s)\nUsage:\n%s", message, shortArgName, longArgName, usageStr));
}

private:
Expand Down Expand Up @@ -479,6 +471,7 @@ Arguments::Arguments(const MArgList &args, const MSyntax &syntax) {

force32bitIndices = adb.isFlagSet(flag::force32bitIndices);
disableNameAssignment = adb.isFlagSet(flag::disableNameAssignment);
keepObjectNamespace = adb.isFlagSet(flag::keepObjectNamespace);
skipSkinClusters = adb.isFlagSet(flag::skipSkinClusters);
skipBlendShapes = adb.isFlagSet(flag::skipBlendShapes);
redrawViewport = adb.isFlagSet(flag::redrawViewport);
Expand Down Expand Up @@ -573,8 +566,7 @@ Arguments::Arguments(const MArgList &args, const MSyntax &syntax) {
// Print the animation clips
for (const auto &clip : animationClips) {
cout << prefix << "Exporting clip " << clip.name << ", start:" << clip.startTime << ", end: " << clip.endTime
<< ", duration:" << clip.duration() << ", frames: " << clip.frameCount()
<< ", rate: " << clip.framesPerSecond << "fps" << endl;
<< ", duration:" << clip.duration() << ", frames: " << clip.frameCount() << ", rate: " << clip.framesPerSecond << "fps" << endl;
}

// Get extra cameras to export
Expand Down Expand Up @@ -607,8 +599,7 @@ Arguments::Arguments(const MArgList &args, const MSyntax &syntax) {
unsigned shapeCount;
status = dagPath.numberOfShapesDirectlyBelow(shapeCount);
if (!status) {
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no shapes attached to it"
<< endl;
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no shapes attached to it" << endl;
continue;
}

Expand All @@ -629,8 +620,7 @@ Arguments::Arguments(const MArgList &args, const MSyntax &syntax) {
}

if (!foundCameraShape) {
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no cameras attached to it"
<< endl;
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no cameras attached to it" << endl;
continue;
}
}
Expand Down Expand Up @@ -670,8 +660,43 @@ Arguments::~Arguments() {
}
}

void Arguments::select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath,
const bool includeDescendants, const bool includeInvisibleNodes) {
std::string Arguments::assignName(GLTF::Object &glObj, const MDagPath &dagPath, const MString &suffix) const {
MStatus status;
auto obj = dagPath.node(&status);
THROW_ON_FAILURE(status)

const MFnDependencyNode node(obj, &status);
THROW_ON_FAILURE(status)

return assignName(glObj, node, suffix);
}

std::string Arguments::assignName(GLTF::Object &glObj, const MFnDependencyNode &node, const MString &suffix) const {
MStatus status;

auto name = node.name(&status);
THROW_ON_FAILURE(status)

if (!keepObjectNamespace) {
const auto ns = node.parentNamespace(&status);
if (status && ns.length() > 0) {
name.substitute(ns + ":", "");
}
}

name += suffix;

std::string result(name.asChar());

if (!disableNameAssignment) {
glObj.name = result;
}

return result;
}

void Arguments::select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath, const bool includeDescendants,
const bool includeInvisibleNodes) {
MStatus status;

std::string debugName{dagPath.partialPathName().asChar()};
Expand Down
21 changes: 9 additions & 12 deletions src/Arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ class SyntaxFactory : MSyntax {
std::map<const char *, const char *> m_argNames;
std::string m_usage;

void registerFlag(std::stringstream &ss, const char *shortName, const char *longName, bool isMultiUse,
MArgType argType1 = kNoArg);
void registerFlag(std::stringstream &ss, const char *shortName, const char *longName, bool isMultiUse, MArgType argType1 = kNoArg);
void registerFlag(std::stringstream &ss, const char *shortName, const char *longName, MArgType argType1 = kNoArg);
};

Expand All @@ -48,9 +47,7 @@ struct AnimClipArg {
};

struct MDagPathComparer {
bool operator()(const MDagPath &a, const MDagPath &b) const {
return strcmp(a.fullPathName().asChar(), b.fullPathName().asChar()) < 0;
}
bool operator()(const MDagPath &a, const MDagPath &b) const { return strcmp(a.fullPathName().asChar(), b.fullPathName().asChar()) < 0; }
};

typedef std::set<MDagPath, MDagPathComparer> Selection;
Expand Down Expand Up @@ -141,6 +138,9 @@ class Arguments {
/** By default the Maya node names are assigned to the GLTF node names */
bool disableNameAssignment = false;

/** By default we remove the Maya object namespace from GLTF node names */
bool keepObjectNamespace = false;

/** Generate debug tangent vector lines? */
bool debugTangentVectors = false;

Expand Down Expand Up @@ -251,11 +251,8 @@ class Arguments {
/** Copyright text of the exported file */
MString copyright;

void assignName(GLTF::Object &glObj, const std::string &name) const {
if (!disableNameAssignment) {
glObj.name = name;
}
}
std::string assignName(GLTF::Object &glObj, const MDagPath &dagPath, const MString &suffix) const;
std::string assignName(GLTF::Object &glObj, const MFnDependencyNode &node, const MString &suffix) const;

std::string makeName(const std::string &name) const { return disableNameAssignment ? "" : name; }

Expand All @@ -265,8 +262,8 @@ class Arguments {
private:
DISALLOW_COPY_MOVE_ASSIGN(Arguments);

static void select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath,
bool includeDescendants, bool visibleNodesOnly);
static void select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath, bool includeDescendants,
bool visibleNodesOnly);

std::ofstream m_mayaOutputFileStream;
std::ofstream m_gltfOutputFileStream;
Expand Down
3 changes: 1 addition & 2 deletions src/ExportableCamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ ExportableCamera::ExportableCamera(ExportableScene &scene, ExportableNode &node,
glCamera = move(perspectiveCamera);
}

const std::string cameraName{shapeDagPath.partialPathName(&status).asChar()};
args.assignName(*glCamera, cameraName);
args.assignName(*glCamera, shapeDagPath, "");

glCamera->znear = float(camera.nearClippingPlane(&status)) * args.globalScaleFactor;
THROW_ON_FAILURE(status);
Expand Down
6 changes: 3 additions & 3 deletions src/ExportableMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void ExportableMaterialPBR::convert(ExportableResources &resources, const MObjec
THROW_ON_FAILURE(status);

auto &args = resources.arguments();
args.assignName(m_glMaterial, shader.name().asChar());
args.assignName(m_glMaterial, shader, "");

m_glMetallicRoughness.roughnessFactor = 1;
m_glMetallicRoughness.metallicFactor = 0;
Expand Down Expand Up @@ -165,7 +165,7 @@ void ExportableMaterialPBR::loadPBR(ExportableResources &resources, const MFnDep
THROW_ON_FAILURE(status);

auto &args = resources.arguments();
args.assignName(m_glMaterial, shaderNode.name().asChar());
args.assignName(m_glMaterial, shaderNode, "");

// Base color. For some reason Maya splits this attribute into separate RGB
// and A attributes
Expand Down Expand Up @@ -365,7 +365,7 @@ void ExportableMaterialPBR::loadAiStandard(
THROW_ON_FAILURE(status);

auto &args = resources.arguments();
args.assignName(m_glMaterial, shaderNode.name().asChar());
args.assignName(m_glMaterial, shaderNode, "");

float opacityFactor = 1.f;

Expand Down
6 changes: 2 additions & 4 deletions src/ExportableMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ ExportableMesh::ExportableMesh(ExportableScene &scene, ExportableNode &node, con
: ExportableObject(shapeDagPath.node()) {
MStatus status;

const std::string shapeName{shapeDagPath.partialPathName(&status).asChar()};

auto &resources = scene.resources();
auto &args = resources.arguments();

Expand All @@ -29,7 +27,7 @@ ExportableMesh::ExportableMesh(ExportableScene &scene, ExportableNode &node, con
}

if (!mayaMesh->isEmpty()) {
args.assignName(glMesh, shapeName);
auto shapeName = args.assignName(glMesh, shapeDagPath, "");

auto &mainShape = mayaMesh->shape();

Expand Down Expand Up @@ -133,7 +131,7 @@ ExportableMesh::ExportableMesh(ExportableScene &scene, ExportableNode &node, con
// Generate skin
auto &skeleton = mainShape.skeleton();
if (!skeleton.isEmpty()) {
args.assignName(glSkin, shapeName);
args.assignName(glSkin, shapeDagPath, "");

auto &joints = skeleton.joints();

Expand Down
20 changes: 10 additions & 10 deletions src/ExportableNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ void ExportableNode::load(ExportableScene &scene, NodeTransformCache &transformC
// Remember scale factor
scaleFactor = args.getBakeScaleFactor();

// Get name
const auto name = dagPath.partialPathName(&status);
THROW_ON_FAILURE(status);

// // Get name
// const auto name = dagPath.partialPathName(&status);
// THROW_ON_FAILURE(status);
//
// Get parent
parentNode = scene.getParent(this);

Expand Down Expand Up @@ -77,17 +77,17 @@ void ExportableNode::load(ExportableScene &scene, NodeTransformCache &transformC

switch (transformKind) {
case TransformKind::ComplexJoint:
args.assignName(sNode, (name + ":SSC").asChar());
args.assignName(pNode, name.asChar());
args.assignName(sNode, dagPath, ":SSC");
args.assignName(pNode, dagPath, "");
sNode.children.emplace_back(&pNode);
break;
case TransformKind::ComplexTransform:
args.assignName(pNode, (name + ":PIV").asChar());
args.assignName(sNode, name.asChar());
args.assignName(pNode, dagPath, ":PIV");
args.assignName(sNode, dagPath, "");
sNode.children.emplace_back(&pNode);
break;
default:;
args.assignName(pNode, name.asChar());
args.assignName(pNode, dagPath, "");
break;
}

Expand All @@ -110,7 +110,7 @@ void ExportableNode::load(ExportableScene &scene, NodeTransformCache &transformC
if (initialTransformState.maxNonOrthogonality > MAX_NON_ORTHOGONALITY) {
// TODO: Use SVG to decompose the 3x3 matrix into a product of rotation
// and scale matrices.
cerr << prefix << "WARNING: node '" << name
cerr << prefix << "WARNING: node '" << name()
<< "' has initial transforms that are not representable by glTF! "
"Skewing is not supported, use 3 nodes to simulate this. "
"Deviation = "
Expand Down

0 comments on commit 03f669e

Please sign in to comment.