Skip to content

Commit 5bc1a66

Browse files
committed
Merge branch 'dev' into fix_preview_surface_opacity_threshold
2 parents 02c65c1 + 0668bf5 commit 5bc1a66

File tree

20 files changed

+681
-77
lines changed

20 files changed

+681
-77
lines changed

lib/mayaUsd/commands/Readme.md

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Each base command class is documented in the following sections.
5454
| `-importUSDZTexturesFilePath` | `-itf` | string | none | Specifies an explicit directory to write imported textures to from a USDZ archive. Has no effect if `-importUSDZTextures` is not specified. |
5555
| `-importRelativeTextures` | `-rtx` | string | none | Selects how textures filenames are generated: absolute, relative, automatic or none. When automatic, the filename is relative if the source filename of the texture being imported is relative. When none, the file path is left alone, for backward compatible behavior. |
5656
| `-upAxis` | `-upa` | bool | true | Enable changing axis on import. |
57+
| `-unit` | `-unt` | bool | true | Enable changing units on import. |
5758
| `-axisAndUnitMethod` | `-aum` | string | rotateScale | Selects how the unit and axis are handled during import. |
5859

5960
### Return Value

lib/mayaUsd/commands/baseImportCommand.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ MSyntax MayaUSDImportCommand::createSyntax()
7070
MSyntax::kString);
7171
syntax.addFlag(
7272
kImportUpAxisFlag, UsdMayaJobImportArgsTokens->upAxis.GetText(), MSyntax::kBoolean);
73+
syntax.addFlag(kImportUnitFlag, UsdMayaJobImportArgsTokens->unit.GetText(), MSyntax::kBoolean);
7374
syntax.addFlag(
7475
kImportAxisAndUnitMethodFlag,
7576
UsdMayaJobImportArgsTokens->axisAndUnitMethod.GetText(),

lib/mayaUsd/commands/baseImportCommand.h

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class MAYAUSD_CORE_PUBLIC MayaUSDImportCommand : public MPxCommand
4747
static constexpr auto kImportUSDZTexturesFilePathFlag = "itf";
4848
static constexpr auto kImportRelativeTexturesFlag = "rtx";
4949
static constexpr auto kImportUpAxisFlag = "upa";
50+
static constexpr auto kImportUnitFlag = "unt";
5051
static constexpr auto kImportAxisAndUnitMethodFlag = "aum";
5152
static constexpr auto kMetadataFlag = "md";
5253
static constexpr auto kApiSchemaFlag = "api";

lib/mayaUsd/fileio/jobs/jobArgs.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,7 @@ UsdMayaJobImportArgs::UsdMayaJobImportArgs(
13821382
UsdMayaJobImportArgsTokens->addTransform,
13831383
UsdMayaJobImportArgsTokens->overwritePrefs }))
13841384
, upAxis(extractBoolean(userArgs, UsdMayaJobImportArgsTokens->upAxis))
1385+
, unit(extractBoolean(userArgs, UsdMayaJobImportArgsTokens->unit))
13851386
, importInstances(extractBoolean(userArgs, UsdMayaJobImportArgsTokens->importInstances))
13861387
, useAsAnimationCache(extractBoolean(userArgs, UsdMayaJobImportArgsTokens->useAsAnimationCache))
13871388
, importWithProxyShapes(importWithProxyShapes)
@@ -1473,6 +1474,7 @@ const VtDictionary& UsdMayaJobImportArgs::GetDefaultDictionary()
14731474
d[UsdMayaJobImportArgsTokens->axisAndUnitMethod]
14741475
= UsdMayaJobImportArgsTokens->rotateScale.GetString();
14751476
d[UsdMayaJobImportArgsTokens->upAxis] = true;
1477+
d[UsdMayaJobImportArgsTokens->unit] = true;
14761478
d[UsdMayaJobImportArgsTokens->pullImportStage] = UsdStageRefPtr();
14771479
d[UsdMayaJobImportArgsTokens->useAsAnimationCache] = false;
14781480
d[UsdMayaJobImportArgsTokens->preserveTimeline] = false;
@@ -1557,6 +1559,7 @@ const VtDictionary& UsdMayaJobImportArgs::GetGuideDictionary()
15571559
d[UsdMayaJobImportArgsTokens->importRelativeTextures] = _string;
15581560
d[UsdMayaJobImportArgsTokens->axisAndUnitMethod] = _string;
15591561
d[UsdMayaJobImportArgsTokens->upAxis] = _boolean;
1562+
d[UsdMayaJobImportArgsTokens->unit] = _boolean;
15601563
d[UsdMayaJobImportArgsTokens->pullImportStage] = _usdStageRefPtr;
15611564
d[UsdMayaJobImportArgsTokens->useAsAnimationCache] = _boolean;
15621565
d[UsdMayaJobImportArgsTokens->preserveTimeline] = _boolean;
@@ -1649,6 +1652,7 @@ std::ostream& operator<<(std::ostream& out, const UsdMayaJobImportArgs& importAr
16491652
<< "importRelativeTextures: " << TfStringify(importArgs.importRelativeTextures) << std::endl
16501653
<< "axisAndUnitMethod: " << TfStringify(importArgs.axisAndUnitMethod) << std::endl
16511654
<< "upAxis: " << TfStringify(importArgs.upAxis) << std::endl
1655+
<< "unit: " << TfStringify(importArgs.unit) << std::endl
16521656
<< "pullImportStage: " << TfStringify(importArgs.pullImportStage) << std::endl
16531657
<< std::endl
16541658
<< "timeInterval: " << importArgs.timeInterval << std::endl

lib/mayaUsd/fileio/jobs/jobArgs.h

+2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ TF_DECLARE_PUBLIC_TOKENS(
197197
(preserveTimeline) \
198198
(remapUVSetsTo) \
199199
(upAxis) \
200+
(unit) \
200201
(axisAndUnitMethod) \
201202
/* values for axis and unit method */ \
202203
(rotateScale) \
@@ -436,6 +437,7 @@ struct UsdMayaJobImportArgs
436437
const std::string importRelativeTextures;
437438
const std::string axisAndUnitMethod;
438439
const bool upAxis;
440+
const bool unit;
439441
const bool importInstances;
440442
const bool useAsAnimationCache;
441443
const bool importWithProxyShapes;

lib/mayaUsd/fileio/jobs/readJob.cpp

+112-66
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ bool UsdMaya_ReadJob::Read(std::vector<MDagPath>* addedDagPaths)
199199
// When we are called from PrimUpdaterManager we should already have
200200
// a computation scope. If we are called from elsewhere don't show any
201201
// progress bar here.
202-
MayaUsd::ProgressBarScope progressBar(17);
202+
MayaUsd::ProgressBarScope progressBar(16);
203203

204204
// Do not use the global undo info recording system.
205205
// The read job Undo() / redo() functions will handle all operations.
@@ -259,22 +259,6 @@ bool UsdMaya_ReadJob::Read(std::vector<MDagPath>* addedDagPaths)
259259
_setTimeSampleMultiplierFrom(stage->GetTimeCodesPerSecond());
260260
progressBar.advance();
261261

262-
// XXX Currently all distance values are set directly from USD and will be
263-
// interpreted as centimeters (Maya's internal distance unit). Future work
264-
// could include converting distance values based on the specified meters-
265-
// per-unit in the USD stage metadata. For now, simply warn.
266-
if (UsdGeomStageHasAuthoredMetersPerUnit(stage)) {
267-
MDistance::Unit mdistanceUnit = UsdMayaUtil::ConvertUsdGeomLinearUnitToMDistanceUnit(
268-
UsdGeomGetStageMetersPerUnit(stage));
269-
270-
if (mdistanceUnit != MDistance::internalUnit()) {
271-
TF_WARN("Distance unit conversion is not yet supported. "
272-
"All distance values will be imported in Maya's internal "
273-
"distance unit.");
274-
}
275-
}
276-
progressBar.advance();
277-
278262
// If the import time interval isn't empty, we expand the Min/Max time
279263
// sliders to include the stage's range if necessary.
280264
AutoTimelineRestore timelineRestore(mArgs.preserveTimeline);
@@ -483,7 +467,7 @@ bool UsdMaya_ReadJob::Read(std::vector<MDagPath>* addedDagPaths)
483467
}
484468
progressBar.advance();
485469

486-
_ConvertUpAxis(stage);
470+
_ConvertUpAxisAndUnits(stage);
487471
progressBar.advance();
488472

489473
UsdMayaReadUtil::mapFileHashes.clear();
@@ -498,37 +482,39 @@ static bool getUSDUpAxisZ(const UsdStageRefPtr& stage)
498482
return UsdGeomGetStageUpAxis(stage) == UsdGeomTokens->z;
499483
}
500484

501-
void UsdMaya_ReadJob::_ConvertUpAxis(const UsdStageRefPtr& stage)
485+
void UsdMaya_ReadJob::_ConvertUpAxisAndUnits(const UsdStageRefPtr& stage)
502486
{
503-
// If up-axis fixing is turned off, do nothing.
504-
if (!mArgs.upAxis)
505-
return;
506-
507-
// If up axis are the same in Maya and USD, do nothing.
508-
const bool isMayaUpAxisZ = getMayaUpAxisZ();
509-
const bool isUSDUpAxisUZ = getUSDUpAxisZ(stage);
510-
511-
if (isMayaUpAxisZ == isUSDUpAxisUZ)
487+
ConversionInfo conversion;
488+
489+
// Convert up-axis based if required and different between Maya and USD.
490+
const bool convertUpAxis = mArgs.upAxis;
491+
conversion.isMayaUpAxisZ = getMayaUpAxisZ();
492+
conversion.isUSDUpAxisUZ = getUSDUpAxisZ(stage);
493+
conversion.needUpAxisConversion
494+
= (convertUpAxis && (conversion.isMayaUpAxisZ != conversion.isUSDUpAxisUZ));
495+
496+
// Convert units if required and different between Maya and USD.
497+
const bool convertUnits = mArgs.unit;
498+
conversion.mayaMetersPerUnit
499+
= UsdMayaUtil::ConvertMDistanceUnitToUsdGeomLinearUnit(MDistance::internalUnit());
500+
conversion.usdMetersPerUnit = UsdGeomGetStageMetersPerUnit(stage);
501+
conversion.needUnitsConversion
502+
= (convertUnits && (conversion.mayaMetersPerUnit != conversion.usdMetersPerUnit));
503+
504+
// If neither up-axis nor units need to change, do nothing.
505+
if (!conversion.needUpAxisConversion && !conversion.needUnitsConversion)
512506
return;
513507

514-
// Convert axis based on desired method.
515-
const bool convertYtoZ = isMayaUpAxisZ;
516-
517-
bool success = false;
518-
519508
if (mArgs.axisAndUnitMethod == UsdMayaJobImportArgsTokens->rotateScale)
520-
success = _ConvertUpAxisWithRotation(stage, convertYtoZ, false);
509+
_ConvertUpAxisAndUnitsByModifyingData(stage, conversion, false);
521510
else if (mArgs.axisAndUnitMethod == UsdMayaJobImportArgsTokens->addTransform)
522-
success = _ConvertUpAxisWithRotation(stage, convertYtoZ, true);
511+
_ConvertUpAxisAndUnitsByModifyingData(stage, conversion, true);
523512
else if (mArgs.axisAndUnitMethod == UsdMayaJobImportArgsTokens->overwritePrefs)
524-
success = _ConvertUpAxisByChangingMayPrefs(convertYtoZ);
513+
_ConvertUpAxisAndUnitsByChangingMayaPrefs(stage, conversion);
525514
else
526515
TF_WARN(
527-
"Unknown method of converting the USD up axis to Maya: %s",
516+
"Unknown method of converting the USD up axis and units to Maya: %s",
528517
mArgs.axisAndUnitMethod.c_str());
529-
530-
if (success)
531-
MGlobal::displayInfo("Mismatching axis have been converted for accurate orientation.");
532518
}
533519

534520
// Construct list of top level DAG nodes.
@@ -583,27 +569,37 @@ static std::string _cleanMayaNodeName(const std::string& name)
583569
return cleaned;
584570
}
585571

586-
static void
587-
_addOrignalUpAxisAttribute(const std::vector<MDagPath>& dagNodePaths, bool convertUsdYtoMayaZ)
572+
static void _addOrignalUpAxisAttribute(const std::vector<MDagPath>& dagNodePaths, bool isUSDUpAxisZ)
588573
{
589-
// Note: if we're converting from Y to Z, then the original up axis was Y, otherwise Z.
590-
const MString originalUpAxis = convertUsdYtoMayaZ ? "Y" : "Z";
574+
const MString originalUpAxis = isUSDUpAxisZ ? "Z" : "Y";
591575
const MString attrName = "OriginalUSDUpAxis";
592576
for (const MDagPath& dagPath : dagNodePaths) {
593577
MFnDependencyNode depNode(dagPath.node());
594578
MayaUsd::setDynamicAttribute(depNode, attrName, originalUpAxis);
595579
}
596580
}
597581

598-
bool UsdMaya_ReadJob::_ConvertUpAxisWithRotation(
582+
static void
583+
_addOrignalUnitsAttribute(const std::vector<MDagPath>& dagNodePaths, double usdMetersPerUnit)
584+
{
585+
MString originalUnits;
586+
originalUnits.set(usdMetersPerUnit);
587+
const MString attrName = "OriginalUSDMetersPerUnit";
588+
for (const MDagPath& dagPath : dagNodePaths) {
589+
MFnDependencyNode depNode(dagPath.node());
590+
MayaUsd::setDynamicAttribute(depNode, attrName, originalUnits);
591+
}
592+
}
593+
594+
void UsdMaya_ReadJob::_ConvertUpAxisAndUnitsByModifyingData(
599595
const UsdStageRefPtr& stage,
600-
bool convertUsdYtoMayaZ,
596+
const ConversionInfo& conversion,
601597
bool keepParentGroup)
602598
{
603599
std::vector<MDagPath> dagNodePaths
604600
= _findAllRootDagNodePaths(mNewNodeRegistry, mMayaRootDagPath);
605601
if (dagNodePaths.size() <= 0)
606-
return true;
602+
return;
607603

608604
std::vector<std::string> dagNodeNames = _convertDagPathToNames(dagNodePaths);
609605

@@ -648,7 +644,7 @@ bool UsdMaya_ReadJob::_ConvertUpAxisWithRotation(
648644

649645
if (mMayaRootDagPath.node() != MObject::kNullObj) {
650646
static const char groupUnderParentCmdFormat[]
651-
= "string $groupName = `group -name \"%s\" -absolute -parent \"%s\" \"%s\"`;";
647+
= "string $groupName = `group -name \"%s\" -absolute -parent \"%s\" \"%s\"`;\n";
652648
std::string rootName = mMayaRootDagPath.fullPathName().asChar();
653649
groupCmd = TfStringPrintf(
654650
groupUnderParentCmdFormat,
@@ -657,7 +653,7 @@ bool UsdMaya_ReadJob::_ConvertUpAxisWithRotation(
657653
rootName.c_str());
658654
} else {
659655
static const char groupUnderWorldCmdFormat[]
660-
= "string $groupName = `group -name \"%s\" -absolute -world \"%s\"`;";
656+
= "string $groupName = `group -name \"%s\" -absolute -world \"%s\"`;\n";
661657
groupCmd = TfStringPrintf(
662658
groupUnderWorldCmdFormat, groupName.c_str(), joinedDAGNodeNames.c_str());
663659
}
@@ -673,26 +669,35 @@ bool UsdMaya_ReadJob::_ConvertUpAxisWithRotation(
673669
// - Use -pivot to make sure we are rotating relative to the origin
674670
// (The group is positioned at the center of all sub-object, so we need to specify the
675671
// pivot)
676-
{
672+
if (conversion.needUpAxisConversion) {
677673
static const char rotationCmdFormat[]
678-
= "rotate -relative -euler -pivot 0 0 0 -forceOrderXYZ %d 0 0 $groupName;";
674+
= "rotate -relative -euler -pivot 0 0 0 -forceOrderXYZ %d 0 0 $groupName;\n";
679675
const int angleYtoZ = 90;
680676
const int angleZtoY = -90;
681677
std::string rotationCmd
682-
= TfStringPrintf(rotationCmdFormat, convertUsdYtoMayaZ ? angleYtoZ : angleZtoY);
678+
= TfStringPrintf(rotationCmdFormat, conversion.isMayaUpAxisZ ? angleYtoZ : angleZtoY);
683679
fullScript += rotationCmd;
684680
}
685681

682+
if (conversion.needUnitsConversion) {
683+
static const char scalingCmdFormat[]
684+
= "scale -relative -pivot 0 0 0 -scaleXYZ %f %f %f $groupName;\n";
685+
const double usdToMayaScaling = conversion.usdMetersPerUnit / conversion.mayaMetersPerUnit;
686+
std::string scalingCmd = TfStringPrintf(
687+
scalingCmdFormat, usdToMayaScaling, usdToMayaScaling, usdToMayaScaling);
688+
fullScript += scalingCmd;
689+
}
690+
686691
if (!keepParentGroup) {
687-
static const char ungroupCmdFormat[] = "ungroup -absolute \"%s\";";
692+
static const char ungroupCmdFormat[] = "ungroup -absolute \"%s\";\n";
688693
std::string ungroupCmd = TfStringPrintf(ungroupCmdFormat, groupName.c_str());
689694
fullScript += ungroupCmd;
690695
}
691696

692697
if (!MGlobal::executeCommand(fullScript.c_str())) {
693698
MGlobal::displayWarning("Failed to add a transform to convert the up-axis to align "
694699
"the USD data with Maya up-axis.");
695-
return false;
700+
return;
696701
}
697702

698703
if (keepParentGroup) {
@@ -702,26 +707,67 @@ bool UsdMaya_ReadJob::_ConvertUpAxisWithRotation(
702707
sel.add(groupName.c_str());
703708
sel.getDagPath(0, groupDagPath);
704709
}
705-
_addOrignalUpAxisAttribute({ groupDagPath }, convertUsdYtoMayaZ);
710+
if (conversion.needUpAxisConversion)
711+
_addOrignalUpAxisAttribute({ groupDagPath }, conversion.isUSDUpAxisUZ);
712+
if (conversion.needUnitsConversion)
713+
_addOrignalUnitsAttribute({ groupDagPath }, conversion.usdMetersPerUnit);
706714
} else {
707-
_addOrignalUpAxisAttribute(dagNodePaths, convertUsdYtoMayaZ);
715+
if (conversion.needUpAxisConversion)
716+
_addOrignalUpAxisAttribute(dagNodePaths, conversion.isUSDUpAxisUZ);
717+
if (conversion.needUnitsConversion)
718+
_addOrignalUnitsAttribute(dagNodePaths, conversion.usdMetersPerUnit);
708719
}
709720

710-
return true;
721+
MGlobal::displayInfo(
722+
"Mismatching axis and units have been converted for accurate orientation and scale.");
711723
}
712724

713-
bool UsdMaya_ReadJob::_ConvertUpAxisByChangingMayPrefs(const bool convertUsdYtoMayaZ)
725+
void UsdMaya_ReadJob::_ConvertUpAxisAndUnitsByChangingMayaPrefs(
726+
const UsdStageRefPtr& stage,
727+
const ConversionInfo& conversion)
714728
{
715-
const bool rotateView = true;
716-
const MStatus status
717-
= convertUsdYtoMayaZ ? MGlobal::setYAxisUp(rotateView) : MGlobal::setZAxisUp(rotateView);
718-
if (!status) {
719-
MGlobal::displayWarning(
720-
"Failed to change the Maya up-axis preferences to match USD data up-axis.");
721-
return false;
729+
bool success = true;
730+
731+
// Set up-axis preferences if needed.
732+
if (conversion.needUpAxisConversion) {
733+
const bool rotateView = true;
734+
const MStatus status = conversion.isUSDUpAxisUZ ? MGlobal::setZAxisUp(rotateView)
735+
: MGlobal::setYAxisUp(rotateView);
736+
if (!status) {
737+
MGlobal::displayWarning(
738+
"Failed to change the Maya up-axis preferences to match USD data up-axis.");
739+
success = false;
740+
}
722741
}
723742

724-
return true;
743+
// Set units preferences if needed.
744+
if (conversion.needUnitsConversion) {
745+
const MDistance::Unit mayaUnit
746+
= UsdMayaUtil::ConvertUsdGeomLinearUnitToMDistanceUnit(conversion.usdMetersPerUnit);
747+
if (mayaUnit == MDistance::kInvalid) {
748+
MGlobal::displayWarning(
749+
"Unable to convert <unit> to a Maya unit. Supported units include millimeters, "
750+
"centimeters, meters, kilometers, inches, feet, yards and miles.");
751+
success = false;
752+
} else {
753+
const MString mayaUnitText = UsdMayaUtil::ConvertMDistanceUnitToText(mayaUnit);
754+
MString changeUnitsCmd;
755+
changeUnitsCmd.format("currentUnit -linear ^1s;", mayaUnitText);
756+
757+
// Note: we *must* execute the units change on-idle because the import process
758+
// saves and restores all units! If we change it now, the change would be lost.
759+
if (!MGlobal::executeCommandOnIdle(changeUnitsCmd)) {
760+
MGlobal::displayWarning(
761+
"Failed to change the Maya units preferences to match USD data "
762+
"because the units are not supported by Maya.");
763+
success = false;
764+
}
765+
}
766+
}
767+
768+
if (success)
769+
MGlobal::displayInfo(
770+
"Changed Maya preferences to match up-axis and units from the imported USD scene.");
725771
}
726772

727773
bool UsdMaya_ReadJob::DoImport(UsdPrimRange& rootRange, const UsdPrim& usdRootPrim)

lib/mayaUsd/fileio/jobs/readJob.h

+17-4
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,25 @@ class UsdMaya_ReadJob
141141

142142
double _setTimeSampleMultiplierFrom(const double layerFPS);
143143

144-
void _ConvertUpAxis(const UsdStageRefPtr& stage);
145-
bool _ConvertUpAxisWithRotation(
144+
struct ConversionInfo
145+
{
146+
bool isMayaUpAxisZ { false };
147+
bool isUSDUpAxisUZ { false };
148+
bool needUpAxisConversion { false };
149+
150+
double mayaMetersPerUnit = { 0.01 };
151+
double usdMetersPerUnit = { 0.01 };
152+
bool needUnitsConversion = { false };
153+
};
154+
155+
void _ConvertUpAxisAndUnits(const UsdStageRefPtr& stage);
156+
void _ConvertUpAxisAndUnitsByModifyingData(
146157
const UsdStageRefPtr& stage,
147-
bool convertUsdYtoMayaZ,
158+
const ConversionInfo& conversion,
148159
bool keepParentGroup);
149-
bool _ConvertUpAxisByChangingMayPrefs(const bool convertUsdYtoMayaZ);
160+
void _ConvertUpAxisAndUnitsByChangingMayaPrefs(
161+
const UsdStageRefPtr& stage,
162+
const ConversionInfo& conversion);
150163

151164
// Data
152165
MDagModifier mDagModifierUndo;

lib/mayaUsd/fileio/jobs/writeJob.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -493,8 +493,6 @@ bool UsdMaya_WriteJob::_BeginWriting(const std::string& fileName, bool append)
493493
_autoAxisAndUnitsChanger = std::make_unique<AutoUpAxisAndUnitsChanger>(
494494
mJobCtx.mStage, mJobCtx.mArgs.upAxis, mJobCtx.mArgs.unit);
495495

496-
// TODO: handle mJobCtx.mArgs.unit
497-
498496
// Set the customLayerData on the layer
499497
if (!mJobCtx.mArgs.customLayerData.empty()) {
500498
mJobCtx.mStage->GetRootLayer()->SetCustomLayerData(mJobCtx.mArgs.customLayerData);

0 commit comments

Comments
 (0)