Skip to content

Commit 03f669e

Browse files
committed
NEW: Maya namespaces are removed from glTF names. To keep them, pass the -kon flag
1 parent 34aa09e commit 03f669e

6 files changed

Lines changed: 83 additions & 64 deletions

File tree

src/Arguments.cpp

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ const auto constantRotationThreshold = "crt";
9090
const auto constantScalingThreshold = "cst";
9191
const auto constantWeightsThreshold = "cwt";
9292

93+
const auto keepObjectNamespace = "kon";
94+
9395
} // namespace flag
9496

9597
inline const char *getArgTypeName(const MSyntax::MArgType argType) {
@@ -182,7 +184,7 @@ SyntaxFactory::SyntaxFactory() {
182184
registerFlag(ss, flag::forceRootNode, "forceRootNode", kNoArg);
183185
registerFlag(ss, flag::forceAnimationChannels, "forceAnimationChannels", kNoArg);
184186
registerFlag(ss, flag::forceAnimationSampling, "forceAnimationSampling", kNoArg);
185-
187+
186188
registerFlag(ss, flag::hashBufferURIs, "hashBufferUri", kNoArg);
187189
registerFlag(ss, flag::niceBufferURIs, "niceBufferNames", kNoArg);
188190

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

202+
registerFlag(ss, flag::keepObjectNamespace, "keepMayaNamespaces", kNoArg);
203+
200204
m_usage = ss.str();
201205
}
202206

@@ -212,13 +216,11 @@ MSyntax SyntaxFactory::createSyntax() {
212216
return s;
213217
}
214218

215-
void SyntaxFactory::registerFlag(std::stringstream &ss, const char *shortName, const char *longName,
216-
const MArgType argType1) {
219+
void SyntaxFactory::registerFlag(std::stringstream &ss, const char *shortName, const char *longName, const MArgType argType1) {
217220
registerFlag(ss, shortName, longName, false, argType1);
218221
}
219222

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

@@ -297,8 +299,7 @@ class ArgChecker {
297299

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

300-
template <typename T>
301-
void required(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
302+
template <typename T> void required(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
302303
MStatus status;
303304

304305
if (!isFlagSet(shortName))
@@ -310,16 +311,13 @@ class ArgChecker {
310311
} else {
311312
MArgList args;
312313
status = adb.getFlagArgumentList(shortName, flagIndex, args);
313-
throwOnArgument(status, shortName,
314-
formatted("Failed to get required multi-flag #%d argument", flagIndex).c_str());
314+
throwOnArgument(status, shortName, formatted("Failed to get required multi-flag #%d argument", flagIndex).c_str());
315315
status = args.get(componentIndex, value);
316-
throwOnArgument(status, shortName,
317-
formatted("Failed to get required multi-flag #%d argument value", flagIndex).c_str());
316+
throwOnArgument(status, shortName, formatted("Failed to get required multi-flag #%d argument value", flagIndex).c_str());
318317
}
319318
}
320319

321-
template <typename T>
322-
bool optional(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
320+
template <typename T> bool optional(const char *shortName, T &value, const int flagIndex = 0, const int componentIndex = 0) const {
323321
if (!adb.isFlagSet(shortName))
324322
return false;
325323

@@ -331,11 +329,9 @@ class ArgChecker {
331329
} else {
332330
MArgList args;
333331
status = adb.getFlagArgumentList(shortName, flagIndex, args);
334-
throwOnArgument(status, shortName,
335-
formatted("Failed to get optional multi-flag #%d argument", flagIndex).c_str());
332+
throwOnArgument(status, shortName, formatted("Failed to get optional multi-flag #%d argument", flagIndex).c_str());
336333
status = args.get(componentIndex, value);
337-
throwOnArgument(status, shortName,
338-
formatted("Failed to get optional multi-flag #%d argument value", flagIndex).c_str());
334+
throwOnArgument(status, shortName, formatted("Failed to get optional multi-flag #%d argument value", flagIndex).c_str());
339335
}
340336

341337
return true;
@@ -357,8 +353,7 @@ class ArgChecker {
357353
return true;
358354
}
359355

360-
std::unique_ptr<IndentableStream> getOutputStream(const char *arg, const char *outputName,
361-
const fs::path &outputFolder,
356+
std::unique_ptr<IndentableStream> getOutputStream(const char *arg, const char *outputName, const fs::path &outputFolder,
362357
std::ofstream &fileOutputStream) const {
363358
std::ostream *out = nullptr;
364359

@@ -401,19 +396,16 @@ class ArgChecker {
401396
const auto longArgName = SyntaxFactory::get().longArgName(shortArgName);
402397
const auto statusStr = status.errorString().asChar();
403398
const auto usageStr = SyntaxFactory::get().usage();
404-
throw MayaException(
405-
status, message ? formatted("-%s (-%s): %s\nUsage:\n%s", shortArgName, longArgName, statusStr, usageStr)
406-
: formatted("-%s (-%s): %s %s\nUsage:\n%s", shortArgName, longArgName, message,
407-
statusStr, usageStr));
399+
throw MayaException(status, message ? formatted("-%s (-%s): %s\nUsage:\n%s", shortArgName, longArgName, statusStr, usageStr)
400+
: formatted("-%s (-%s): %s %s\nUsage:\n%s", shortArgName, longArgName, message, statusStr, usageStr));
408401
}
409402
}
410403

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

415-
throw MayaException(MStatus::kInvalidParameter,
416-
formatted("%s -%s (%s)\nUsage:\n%s", message, shortArgName, longArgName, usageStr));
408+
throw MayaException(MStatus::kInvalidParameter, formatted("%s -%s (%s)\nUsage:\n%s", message, shortArgName, longArgName, usageStr));
417409
}
418410

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

480472
force32bitIndices = adb.isFlagSet(flag::force32bitIndices);
481473
disableNameAssignment = adb.isFlagSet(flag::disableNameAssignment);
474+
keepObjectNamespace = adb.isFlagSet(flag::keepObjectNamespace);
482475
skipSkinClusters = adb.isFlagSet(flag::skipSkinClusters);
483476
skipBlendShapes = adb.isFlagSet(flag::skipBlendShapes);
484477
redrawViewport = adb.isFlagSet(flag::redrawViewport);
@@ -573,8 +566,7 @@ Arguments::Arguments(const MArgList &args, const MSyntax &syntax) {
573566
// Print the animation clips
574567
for (const auto &clip : animationClips) {
575568
cout << prefix << "Exporting clip " << clip.name << ", start:" << clip.startTime << ", end: " << clip.endTime
576-
<< ", duration:" << clip.duration() << ", frames: " << clip.frameCount()
577-
<< ", rate: " << clip.framesPerSecond << "fps" << endl;
569+
<< ", duration:" << clip.duration() << ", frames: " << clip.frameCount() << ", rate: " << clip.framesPerSecond << "fps" << endl;
578570
}
579571

580572
// Get extra cameras to export
@@ -607,8 +599,7 @@ Arguments::Arguments(const MArgList &args, const MSyntax &syntax) {
607599
unsigned shapeCount;
608600
status = dagPath.numberOfShapesDirectlyBelow(shapeCount);
609601
if (!status) {
610-
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no shapes attached to it"
611-
<< endl;
602+
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no shapes attached to it" << endl;
612603
continue;
613604
}
614605

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

631622
if (!foundCameraShape) {
632-
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no cameras attached to it"
633-
<< endl;
623+
cerr << prefix << "Skipping " << dagPath.partialPathName() << ", it has no cameras attached to it" << endl;
634624
continue;
635625
}
636626
}
@@ -670,8 +660,43 @@ Arguments::~Arguments() {
670660
}
671661
}
672662

673-
void Arguments::select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath,
674-
const bool includeDescendants, const bool includeInvisibleNodes) {
663+
std::string Arguments::assignName(GLTF::Object &glObj, const MDagPath &dagPath, const MString &suffix) const {
664+
MStatus status;
665+
auto obj = dagPath.node(&status);
666+
THROW_ON_FAILURE(status)
667+
668+
const MFnDependencyNode node(obj, &status);
669+
THROW_ON_FAILURE(status)
670+
671+
return assignName(glObj, node, suffix);
672+
}
673+
674+
std::string Arguments::assignName(GLTF::Object &glObj, const MFnDependencyNode &node, const MString &suffix) const {
675+
MStatus status;
676+
677+
auto name = node.name(&status);
678+
THROW_ON_FAILURE(status)
679+
680+
if (!keepObjectNamespace) {
681+
const auto ns = node.parentNamespace(&status);
682+
if (status && ns.length() > 0) {
683+
name.substitute(ns + ":", "");
684+
}
685+
}
686+
687+
name += suffix;
688+
689+
std::string result(name.asChar());
690+
691+
if (!disableNameAssignment) {
692+
glObj.name = result;
693+
}
694+
695+
return result;
696+
}
697+
698+
void Arguments::select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath, const bool includeDescendants,
699+
const bool includeInvisibleNodes) {
675700
MStatus status;
676701

677702
std::string debugName{dagPath.partialPathName().asChar()};

src/Arguments.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ class SyntaxFactory : MSyntax {
2727
std::map<const char *, const char *> m_argNames;
2828
std::string m_usage;
2929

30-
void registerFlag(std::stringstream &ss, const char *shortName, const char *longName, bool isMultiUse,
31-
MArgType argType1 = kNoArg);
30+
void registerFlag(std::stringstream &ss, const char *shortName, const char *longName, bool isMultiUse, MArgType argType1 = kNoArg);
3231
void registerFlag(std::stringstream &ss, const char *shortName, const char *longName, MArgType argType1 = kNoArg);
3332
};
3433

@@ -48,9 +47,7 @@ struct AnimClipArg {
4847
};
4948

5049
struct MDagPathComparer {
51-
bool operator()(const MDagPath &a, const MDagPath &b) const {
52-
return strcmp(a.fullPathName().asChar(), b.fullPathName().asChar()) < 0;
53-
}
50+
bool operator()(const MDagPath &a, const MDagPath &b) const { return strcmp(a.fullPathName().asChar(), b.fullPathName().asChar()) < 0; }
5451
};
5552

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

141+
/** By default we remove the Maya object namespace from GLTF node names */
142+
bool keepObjectNamespace = false;
143+
144144
/** Generate debug tangent vector lines? */
145145
bool debugTangentVectors = false;
146146

@@ -251,11 +251,8 @@ class Arguments {
251251
/** Copyright text of the exported file */
252252
MString copyright;
253253

254-
void assignName(GLTF::Object &glObj, const std::string &name) const {
255-
if (!disableNameAssignment) {
256-
glObj.name = name;
257-
}
258-
}
254+
std::string assignName(GLTF::Object &glObj, const MDagPath &dagPath, const MString &suffix) const;
255+
std::string assignName(GLTF::Object &glObj, const MFnDependencyNode &node, const MString &suffix) const;
259256

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

@@ -265,8 +262,8 @@ class Arguments {
265262
private:
266263
DISALLOW_COPY_MOVE_ASSIGN(Arguments);
267264

268-
static void select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath,
269-
bool includeDescendants, bool visibleNodesOnly);
265+
static void select(Selection &shapeSelection, Selection &cameraSelection, const MDagPath &dagPath, bool includeDescendants,
266+
bool visibleNodesOnly);
270267

271268
std::ofstream m_mayaOutputFileStream;
272269
std::ofstream m_gltfOutputFileStream;

src/ExportableCamera.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ ExportableCamera::ExportableCamera(ExportableScene &scene, ExportableNode &node,
9595
glCamera = move(perspectiveCamera);
9696
}
9797

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

101100
glCamera->znear = float(camera.nearClippingPlane(&status)) * args.globalScaleFactor;
102101
THROW_ON_FAILURE(status);

src/ExportableMaterial.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void ExportableMaterialPBR::convert(ExportableResources &resources, const MObjec
111111
THROW_ON_FAILURE(status);
112112

113113
auto &args = resources.arguments();
114-
args.assignName(m_glMaterial, shader.name().asChar());
114+
args.assignName(m_glMaterial, shader, "");
115115

116116
m_glMetallicRoughness.roughnessFactor = 1;
117117
m_glMetallicRoughness.metallicFactor = 0;
@@ -165,7 +165,7 @@ void ExportableMaterialPBR::loadPBR(ExportableResources &resources, const MFnDep
165165
THROW_ON_FAILURE(status);
166166

167167
auto &args = resources.arguments();
168-
args.assignName(m_glMaterial, shaderNode.name().asChar());
168+
args.assignName(m_glMaterial, shaderNode, "");
169169

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

367367
auto &args = resources.arguments();
368-
args.assignName(m_glMaterial, shaderNode.name().asChar());
368+
args.assignName(m_glMaterial, shaderNode, "");
369369

370370
float opacityFactor = 1.f;
371371

src/ExportableMesh.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ ExportableMesh::ExportableMesh(ExportableScene &scene, ExportableNode &node, con
1717
: ExportableObject(shapeDagPath.node()) {
1818
MStatus status;
1919

20-
const std::string shapeName{shapeDagPath.partialPathName(&status).asChar()};
21-
2220
auto &resources = scene.resources();
2321
auto &args = resources.arguments();
2422

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

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

3432
auto &mainShape = mayaMesh->shape();
3533

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

138136
auto &joints = skeleton.joints();
139137

src/ExportableNode.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ void ExportableNode::load(ExportableScene &scene, NodeTransformCache &transformC
2424
// Remember scale factor
2525
scaleFactor = args.getBakeScaleFactor();
2626

27-
// Get name
28-
const auto name = dagPath.partialPathName(&status);
29-
THROW_ON_FAILURE(status);
30-
27+
// // Get name
28+
// const auto name = dagPath.partialPathName(&status);
29+
// THROW_ON_FAILURE(status);
30+
//
3131
// Get parent
3232
parentNode = scene.getParent(this);
3333

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

7878
switch (transformKind) {
7979
case TransformKind::ComplexJoint:
80-
args.assignName(sNode, (name + ":SSC").asChar());
81-
args.assignName(pNode, name.asChar());
80+
args.assignName(sNode, dagPath, ":SSC");
81+
args.assignName(pNode, dagPath, "");
8282
sNode.children.emplace_back(&pNode);
8383
break;
8484
case TransformKind::ComplexTransform:
85-
args.assignName(pNode, (name + ":PIV").asChar());
86-
args.assignName(sNode, name.asChar());
85+
args.assignName(pNode, dagPath, ":PIV");
86+
args.assignName(sNode, dagPath, "");
8787
sNode.children.emplace_back(&pNode);
8888
break;
8989
default:;
90-
args.assignName(pNode, name.asChar());
90+
args.assignName(pNode, dagPath, "");
9191
break;
9292
}
9393

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

0 commit comments

Comments
 (0)