Skip to content

Commit

Permalink
Merge pull request #865 from Autodesk/t_gamaj/MAYA-107167/handle_usdz
Browse files Browse the repository at this point in the history
MAYA-107167 - Keep USDZ texture paths relative
  • Loading branch information
Krystian Ligenza authored Oct 26, 2020
2 parents 505d4f5 + ab3dc41 commit 10834d8
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 12 deletions.
20 changes: 13 additions & 7 deletions lib/usd/translators/shading/usdFileTextureWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <pxr/base/gf/vec3f.h>
#include <pxr/base/gf/vec4f.h>
#include <pxr/base/tf/diagnostic.h>
#include <pxr/base/tf/pathUtils.h>
#include <pxr/base/tf/staticTokens.h>
#include <pxr/base/tf/stringUtils.h>
#include <pxr/base/tf/token.h>
Expand Down Expand Up @@ -226,13 +227,18 @@ PxrUsdTranslators_FileTextureWriter::Write(const UsdTimeCode& usdTime)
// WARNING: This extremely minimal attempt at making the file path relative
// to the USD stage is a stopgap measure intended to provide
// minimal interop. It will be replaced by proper use of Maya and
// USD asset resolvers.
boost::filesystem::path usdDir(GetUsdStage()->GetRootLayer()->GetRealPath());
usdDir = usdDir.parent_path();
boost::system::error_code ec;
boost::filesystem::path relativePath = boost::filesystem::relative(fileTextureName, usdDir, ec);
if (!ec && !relativePath.empty()) {
fileTextureName = relativePath.generic_string();
// USD asset resolvers. For package files, the exporter needs full
// paths.
const std::string& fileName = GetUsdStage()->GetRootLayer()->GetRealPath();
TfToken fileExt(TfGetExtension(fileName));
if (fileExt != UsdMayaTranslatorTokens->UsdFileExtensionPackage) {
boost::filesystem::path usdDir(fileName);
usdDir = usdDir.parent_path();
boost::system::error_code ec;
boost::filesystem::path relativePath = boost::filesystem::relative(fileTextureName, usdDir, ec);
if (!ec && !relativePath.empty()) {
fileTextureName = relativePath.generic_string();
}
}

UsdShadeInput fileInput = shaderSchema.CreateInput(_tokens->file, SdfValueTypeNames->Asset);
Expand Down
6 changes: 4 additions & 2 deletions lib/usd/translators/shading/usdUVTextureReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <pxr/base/tf/staticTokens.h>
#include <pxr/base/tf/token.h>
#include <pxr/base/vt/value.h>
#include <pxr/usd/ar/packageUtils.h>
#include <pxr/usd/sdf/path.h>
#include <pxr/usd/sdf/types.h>
#include <pxr/usd/sdf/valueTypeName.h>
Expand Down Expand Up @@ -179,12 +180,13 @@ bool PxrMayaUsdUVTexture_Reader::Read(UsdMayaPrimReaderContext* context)
UsdShadeInput usdInput = shaderSchema.GetInput(_tokens->file);
if (usdInput && usdInput.Get(&val) && val.IsHolding<SdfAssetPath>()) {
std::string filePath = val.UncheckedGet<SdfAssetPath>().GetResolvedPath();
if (!filePath.empty()) {
if (!filePath.empty() && !ArIsPackageRelativePath(filePath)) {
// Maya has issues with relative paths, especially if deep inside a
// nesting of referenced assets. Use absolute path instead if USD was
// able to resolve. A better fix will require providing an asset
// resolver to Maya that can resolve the file correctly using the
// MPxFileResolver API.
// MPxFileResolver API. We also make sure the path is not expressed
// as a relationship like texture paths inside USDZ assets.
val = SdfAssetPath(filePath);
}
mayaAttr = depFn.findPlug(_tokens->fileTextureName.GetText(), true, &status);
Expand Down
11 changes: 10 additions & 1 deletion plugin/pxr/maya/lib/usdMaya/usdTranslatorExport.mel
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ global proc string usdTranslatorExport_AppendFromPopup(string $currentOptions, s
return $currentOptions + ";" + $arg + "=" + $annotation;
}

global proc string usdTranslatorExport_AppendFromShadingModePopup(string $currentOptions, string $arg, string $widget) {
int $index = `optionMenuGrp -q -select $widget` - 1;
string $allItems[] = `optionMenuGrp -q -itemListLong $widget`;
string $item = $allItems[$index];
string $annotation = `menuItem -q -ann $item`;
string $options = `usdListShadingModes -eo $annotation`;
return $currentOptions + ";" + $options;
}

global proc string usdTranslatorExport_AppendFromIntField(string $currentOptions, string $arg, string $widget) {
string $value = `intFieldGrp -q -value1 $widget`;
return $currentOptions + ";" + $arg + "=" + $value;
Expand Down Expand Up @@ -276,7 +285,7 @@ global proc int usdTranslatorExport (string $parent,

} else if ($action == "query") {

$currentOptions = usdTranslatorExport_AppendFromPopup($currentOptions, "shadingMode", "shadingModePopup");
$currentOptions = usdTranslatorExport_AppendFromShadingModePopup($currentOptions, "shadingMode", "shadingModePopup");
$currentOptions = usdTranslatorExport_AppendFromTextField($currentOptions, "materialsScopeName", "materialsScopeNameField");
$currentOptions = usdTranslatorExport_AppendFromCheckbox($currentOptions, "exportDisplayColor", "exportDisplayColorCheckBox");
$currentOptions = usdTranslatorExport_AppendFromCheckbox($currentOptions, "exportRefsAsInstanceable", "exportRefsAsInstanceableCheckBox");
Expand Down
14 changes: 12 additions & 2 deletions plugin/pxr/maya/lib/usdMaya/usdTranslatorImport.mel
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ global proc string usdTranslatorImport_AppendFromPopup(string $currentOptions, s
return $currentOptions + ";" + $arg + "=" + $annotation;
}

global proc string usdTranslatorImport_AppendFromShadingModePopup(string $currentOptions, string $arg, string $widget) {
int $index = `optionMenuGrp -q -select $widget` - 1;
string $allItems[] = `optionMenuGrp -q -itemListLong $widget`;
string $item = $allItems[$index];
string $annotation = `menuItem -q -ann $item`;
string $options[] = `usdListShadingModes -io $annotation`;
return $currentOptions + ";" + $arg + "=[[" + stringArrayToString($options, ",") + "]]";
}


global proc string usdTranslatorImport_AppendFromBoolPopup(string $currentOptions, string $arg, string $widget) {
int $index = `optionMenuGrp -q -select $widget` - 1;
return $currentOptions + ";" + $arg + "=" + $index;
Expand Down Expand Up @@ -150,7 +160,7 @@ global proc int usdTranslatorImport (string $parent,
for ($index = 0; $index < size($optionList); $index++) {
tokenize($optionList[$index], "=", $optionBreakDown);
if ($optionBreakDown[0] == "shadingMode") {
usdTranslatorImport_SetOptionMenuByAnnotation($optionBreakDown[1], "shadingModePopup");
usdTranslatorImport_SetShadingOptionMenuByAnnotation($optionBreakDown[1], "shadingModePopup");
} else if ($optionBreakDown[0] == "readAnimData") {
usdTranslatorImport_SetCheckbox($optionBreakDown[1], "readAnimDataCheckBox");
} else if ($optionBreakDown[0] == "useAsAnimationCache") {
Expand All @@ -175,7 +185,7 @@ global proc int usdTranslatorImport (string $parent,

} else if ($action == "query") {

$currentOptions = usdTranslatorImport_AppendFromPopup($currentOptions, "shadingMode", "shadingModePopup");
$currentOptions = usdTranslatorImport_AppendFromShadingModePopup($currentOptions, "shadingMode", "shadingModePopup");
$currentOptions = usdTranslatorImport_AppendFromCheckbox($currentOptions, "readAnimData", "readAnimDataCheckBox");
$currentOptions = usdTranslatorImport_AppendFromCheckbox($currentOptions, "useAsAnimationCache", "useAsAnimationCacheCheckBox");
$currentOptions = usdTranslatorImport_AppendFromPopup($currentOptions, "assemblyRep", "assemblyRepPopup");
Expand Down
Binary file not shown.
21 changes: 21 additions & 0 deletions test/lib/usd/translators/testUsdImportPreviewSurface.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,26 @@ def testImportReferenceWithRelativeFilePath(self):

self.assertEqual(len(cmds.ls(typ="lambert")), lambert_before + 8)

def testImportUSDZWithUnresolvableRelativeFilePath(self):
"""
Tests that a USDZ texture path does not resolve as
usdz_file[path_in_archive]
"""
cmds.file(f=True, new=True)

usd_path = os.path.join(self.test_dir, "Tiny.usdz")
options = ["shadingMode=[[useRegistry,UsdPreviewSurface]]",
"primPath=/",
"preferredMaterial=none"]
cmds.file(usd_path, i=True, type="USD Import",
ignoreVersion=True, ra=True, mergeNamespacesOnClash=False,
namespace="Test", pr=True, importTimeRange="combine",
options=";".join(options))

# Check that the texture path stayed relative:
filename = cmds.getAttr("file1.fileTextureName")
self.assertEqual(filename.replace("\\", "/"), "0/Tiny.png")


if __name__ == '__main__':
unittest.main(verbosity=2)

0 comments on commit 10834d8

Please sign in to comment.