Skip to content
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

EMSUSD-280 import relative textures #3259

Merged
merged 9 commits into from
Aug 9, 2023
3 changes: 2 additions & 1 deletion lib/mayaUsd/commands/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ Each base command class is documented in the following sections.
| `-verbose` | `-v` | noarg | false | Make the command output more verbose. |
| `-variant` | `-var` | string[2] | none | Set variant key value pairs |
| `-importUSDZTextures` | `-itx` | bool | false | Imports textures from USDZ archives during import to disk. Can be used in conjuction with `-importUSDZTexturesFilePath` to specify an explicit directory to write imported textures to. If not specified, requires a Maya project to be set in the current context. |
| `-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.
| `-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. |
| `-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. |

### Return Value

Expand Down
4 changes: 4 additions & 0 deletions lib/mayaUsd/commands/baseImportCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ MSyntax MayaUSDImportCommand::createSyntax()
kImportUSDZTexturesFilePathFlag,
UsdMayaJobImportArgsTokens->importUSDZTexturesFilePath.GetText(),
MSyntax::kString);
syntax.addFlag(
kImportRelativeTexturesFlag,
UsdMayaJobImportArgsTokens->importRelativeTextures.GetText(),
MSyntax::kString);
syntax.addFlag(kMetadataFlag, UsdMayaJobImportArgsTokens->metadata.GetText(), MSyntax::kString);
syntax.makeFlagMultiUse(kMetadataFlag);
syntax.addFlag(
Expand Down
1 change: 1 addition & 0 deletions lib/mayaUsd/commands/baseImportCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class MAYAUSD_CORE_PUBLIC MayaUSDImportCommand : public MPxCommand
static constexpr auto kImportInstancesFlag = "ii";
static constexpr auto kImportUSDZTexturesFlag = "itx";
static constexpr auto kImportUSDZTexturesFilePathFlag = "itf";
static constexpr auto kImportRelativeTexturesFlag = "rtx";
static constexpr auto kMetadataFlag = "md";
static constexpr auto kApiSchemaFlag = "api";
static constexpr auto kJobContextFlag = "jc";
Expand Down
12 changes: 12 additions & 0 deletions lib/mayaUsd/fileio/jobs/jobArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,14 @@ UsdMayaJobImportArgs::UsdMayaJobImportArgs(
UsdMayaPreferredMaterialTokens->allTokens))
, importUSDZTexturesFilePath(UsdMayaJobImportArgs::GetImportUSDZTexturesFilePath(userArgs))
, importUSDZTextures(extractBoolean(userArgs, UsdMayaJobImportArgsTokens->importUSDZTextures))
, importRelativeTextures(extractToken(
userArgs,
UsdMayaJobImportArgsTokens->importRelativeTextures,
UsdMayaJobImportArgsTokens->none,
{ UsdMayaJobImportArgsTokens->automatic,
UsdMayaJobImportArgsTokens->absolute,
UsdMayaJobImportArgsTokens->relative,
UsdMayaJobImportArgsTokens->none }))
, importInstances(extractBoolean(userArgs, UsdMayaJobImportArgsTokens->importInstances))
, useAsAnimationCache(extractBoolean(userArgs, UsdMayaJobImportArgsTokens->useAsAnimationCache))
, importWithProxyShapes(importWithProxyShapes)
Expand Down Expand Up @@ -1209,6 +1217,8 @@ const VtDictionary& UsdMayaJobImportArgs::GetDefaultDictionary()
d[UsdMayaJobImportArgsTokens->importInstances] = true;
d[UsdMayaJobImportArgsTokens->importUSDZTextures] = false;
d[UsdMayaJobImportArgsTokens->importUSDZTexturesFilePath] = "";
d[UsdMayaJobImportArgsTokens->importRelativeTextures]
= UsdMayaJobImportArgsTokens->none.GetString();
d[UsdMayaJobImportArgsTokens->pullImportStage] = UsdStageRefPtr();
d[UsdMayaJobImportArgsTokens->useAsAnimationCache] = false;
d[UsdMayaJobImportArgsTokens->preserveTimeline] = false;
Expand Down Expand Up @@ -1289,6 +1299,7 @@ const VtDictionary& UsdMayaJobImportArgs::GetGuideDictionary()
d[UsdMayaJobImportArgsTokens->importInstances] = _boolean;
d[UsdMayaJobImportArgsTokens->importUSDZTextures] = _boolean;
d[UsdMayaJobImportArgsTokens->importUSDZTexturesFilePath] = _string;
d[UsdMayaJobImportArgsTokens->importRelativeTextures] = _string;
d[UsdMayaJobImportArgsTokens->pullImportStage] = _usdStageRefPtr;
d[UsdMayaJobImportArgsTokens->useAsAnimationCache] = _boolean;
d[UsdMayaJobImportArgsTokens->preserveTimeline] = _boolean;
Expand Down Expand Up @@ -1377,6 +1388,7 @@ std::ostream& operator<<(std::ostream& out, const UsdMayaJobImportArgs& importAr
<< "importInstances: " << TfStringify(importArgs.importInstances) << std::endl
<< "importUSDZTextures: " << TfStringify(importArgs.importUSDZTextures) << std::endl
<< "importUSDZTexturesFilePath: " << TfStringify(importArgs.importUSDZTexturesFilePath)
<< "importRelativeTextures: " << TfStringify(importArgs.importRelativeTextures) << std::endl
<< "pullImportStage: " << TfStringify(importArgs.pullImportStage) << std::endl
<< std::endl
<< "timeInterval: " << importArgs.timeInterval << std::endl
Expand Down
7 changes: 7 additions & 0 deletions lib/mayaUsd/fileio/jobs/jobArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,14 @@ TF_DECLARE_PUBLIC_TOKENS(
(importInstances) \
(importUSDZTextures) \
(importUSDZTexturesFilePath) \
(importRelativeTextures) \
(pullImportStage) \
(preserveTimeline) \
/* values for import relative textures */ \
(automatic) \
(absolute) \
(relative) \
(none) \
/* assemblyRep values */ \
(Collapsed) \
(Full) \
Expand Down Expand Up @@ -348,6 +354,7 @@ struct UsdMayaJobImportArgs
const TfToken preferredMaterial;
const std::string importUSDZTexturesFilePath;
const bool importUSDZTextures;
const std::string importRelativeTextures;
const bool importInstances;
const bool useAsAnimationCache;
const bool importWithProxyShapes;
Expand Down
1 change: 1 addition & 0 deletions lib/mayaUsd/python/wrapPrimReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ void wrapJobImportArgs()
.def_readonly("importUSDZTextures", &UsdMayaJobImportArgs::importUSDZTextures)
.def_readonly(
"importUSDZTexturesFilePath", &UsdMayaJobImportArgs::importUSDZTexturesFilePath)
.def_readonly("importRelativeTextures", &UsdMayaJobImportArgs::importRelativeTextures)
.def_readonly("importWithProxyShapes", &UsdMayaJobImportArgs::importWithProxyShapes)
.add_property(
"includeAPINames",
Expand Down
24 changes: 21 additions & 3 deletions lib/mayaUsd/utils/utilFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ std::string UsdMayaUtilFileSystem::getPathRelativeToProject(const std::string& f
if (fileName.empty())
return {};

MString projectPath = MGlobal::executeCommandStringResult("workspace -q -rd");
// Note: don't use isEmpty() because it is not available in Maya 2022 and earlier.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would have been nice if you removed this comment as its not relevant anymore since we are using std::string instead of MString.

if (projectPath.length() == 0)
const MString projectPath = UsdMayaUtil::GetCurrentMayaWorkspacePath();
if (projectPath.isEmpty())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment right above says you cannot use MString::isEmpty().

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my bad. I missed that comment..

return {};

// Note: we do *not* use filesystem function to attempt to make the
Expand All @@ -191,7 +191,7 @@ std::string UsdMayaUtilFileSystem::getPathRelativeToProject(const std::string& f
// preserve paths entered manually with relative folder ("..")
// by keping an absolute path with ".." embedded in them,
// so this works even in this situation.
const auto pos = fileName.find(projectPath.asChar());
const auto pos = fileName.rfind(projectPath.asChar(), 0);
if (pos != 0)
return {};

Expand All @@ -203,6 +203,24 @@ std::string UsdMayaUtilFileSystem::getPathRelativeToProject(const std::string& f
return relativePathAndSuccess.first;
}

std::string UsdMayaUtilFileSystem::makeProjectRelatedPath(const std::string& fileName)
{
const MString projectPath = UsdMayaUtil::GetCurrentMayaWorkspacePath();
if (projectPath.isEmpty())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, no isEmpty here. Since you need it as a char for both cases below I would just convert it to std::string here.

Suggested change
const MString projectPath = UsdMayaUtil::GetCurrentMayaWorkspacePath();
if (projectPath.isEmpty())
const std::string projectPath(UsdMayaUtil::GetCurrentMayaWorkspacePath().asChar());
if (projectPath.empty())

return {};

// Attempt to create a relative path relative to the project folder.
// If that fails, we cannot create the project-relative path.
const auto pathAndSuccess
= UsdMayaUtilFileSystem::makePathRelativeTo(fileName, projectPath.asChar());
if (!pathAndSuccess.second)
return {};

// Make the path absolute but relative to the project folder. That is an absolute
// path that starts with the project path.
return UsdMayaUtilFileSystem::appendPaths(projectPath.asChar(), pathAndSuccess.first);
}

std::string UsdMayaUtilFileSystem::getPathRelativeToDirectory(
const std::string& fileName,
const std::string& relativeToDir)
Expand Down
6 changes: 6 additions & 0 deletions lib/mayaUsd/utils/utilFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ getPathRelativeToDirectory(const std::string& fileName, const std::string& relat
MAYAUSD_CORE_PUBLIC
std::string getPathRelativeToProject(const std::string& fileName);

/*! \brief returns the absolute path of a file but relative to the Maya scene project folder.
Returns an empty string if the path cannot be made relative to the project.
*/
MAYAUSD_CORE_PUBLIC
std::string makeProjectRelatedPath(const std::string& fileName);

/*! \brief returns parent directory of a maya scene file opened by reference
*/
MAYAUSD_CORE_PUBLIC
Expand Down
1 change: 1 addition & 0 deletions lib/usd/translators/shading/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# -----------------------------------------------------------------------------
target_sources(${TARGET_NAME}
PRIVATE
shadingAsset.cpp
shadingTokens.cpp
usdBlinnReader.cpp
usdBlinnWriter.cpp
Expand Down
36 changes: 6 additions & 30 deletions lib/usd/translators/shading/mtlxImageReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.
//
#include "mtlxBaseReader.h"
#include "shadingAsset.h"
#include "shadingTokens.h"

#include <mayaUsd/fileio/shaderReader.h>
Expand Down Expand Up @@ -118,34 +119,8 @@ bool MtlxUsd_ImageReader::Read(UsdMayaPrimReaderContext& context)
}

// File
VtValue val;
MPlug mayaAttr = depFn.findPlug(TrMayaTokens->fileTextureName.GetText(), true, &status);

UsdShadeInput usdInput = shaderSchema.GetInput(TrMtlxTokens->file);
if (status == MS::kSuccess && usdInput && usdInput.Get(&val) && val.IsHolding<SdfAssetPath>()) {
std::string filePath = val.UncheckedGet<SdfAssetPath>().GetResolvedPath();
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. We also make sure the path is not expressed
// as a relationship like texture paths inside USDZ assets.
val = SdfAssetPath(filePath);
}

// NOTE: Will need UDIM support and potentially USDZ support. When that happens, consider
// refactoring existing code from usdUVTextureReader.cpp as shared utilities.
UsdMayaReadUtil::SetMayaAttr(mayaAttr, val);

// colorSpace:
if (usdInput.GetAttr().HasColorSpace()) {
MString colorSpace = usdInput.GetAttr().GetColorSpace().GetText();
mayaAttr = depFn.findPlug(TrMayaTokens->colorSpace.GetText(), true, &status);
if (status == MS::kSuccess) {
mayaAttr.setString(colorSpace);
}
}
if (!ResolveTextureAssetPath(prim, shaderSchema, depFn, _GetArgs().GetJobArguments())) {
return false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That error is not fatal. Please continue loading the other USD attributes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDK what is best here and the other place that uses that function. I'll do what you suggest, we can revisit the best practice in the future. Note that in the original usdUVTextureReader, many error were considered fatal, so I'm just keeping the existing behavior.

}

// Default color
Expand All @@ -158,8 +133,9 @@ bool MtlxUsd_ImageReader::Read(UsdMayaPrimReaderContext& context)
}

// Filter type:
mayaAttr = depFn.findPlug(TrMayaTokens->filterType.GetText(), true, &status);
usdInput = shaderSchema.GetInput(TrMtlxTokens->filtertype);
MPlug mayaAttr = depFn.findPlug(TrMayaTokens->filterType.GetText(), true, &status);
UsdShadeInput usdInput = shaderSchema.GetInput(TrMtlxTokens->filtertype);
VtValue val;
if (status == MS::kSuccess && usdInput && usdInput.Get(&val) && val.IsHolding<std::string>()) {
std::string filterType = val.UncheckedGet<std::string>();
if (filterType == TrMtlxTokens->closest.GetString()) {
Expand Down
Loading
Loading