Skip to content

Commit

Permalink
Merge pull request #3353 from Autodesk/vlasovi/EMSUSD-622
Browse files Browse the repository at this point in the history
EMSUSD-622 - As a user, I'd like to add a relative sublayer on a anonymous layer
  • Loading branch information
seando-adsk authored Oct 2, 2023
2 parents 4c3c857 + b6c081a commit bee6786
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 13 deletions.
66 changes: 66 additions & 0 deletions lib/mayaUsd/utils/utilFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ std::string generateUniqueName()
}
return uniqueName;
}

using PostponedRelativePaths = std::map<PXR_NS::SdfLayerHandle, std::set<ghc::filesystem::path>>;

static PostponedRelativePaths& getPostponedRelativePaths()
{
static PostponedRelativePaths sPaths;
return sPaths;
}

} // namespace

PXR_NAMESPACE_USING_DIRECTIVE
Expand Down Expand Up @@ -283,6 +292,63 @@ std::string UsdMayaUtilFileSystem::getPathRelativeToLayerFile(
return relativePathAndSuccess.first;
}

void UsdMayaUtilFileSystem::markPathAsPostponedRelative(
const PXR_NS::SdfLayerHandle& layer,
const std::string& contentPath)
{
ghc::filesystem::path filePath(contentPath);
auto& postponedRelativePaths = getPostponedRelativePaths();
postponedRelativePaths[layer].insert(filePath.lexically_normal());
}

void UsdMayaUtilFileSystem::unmarkPathAsPostponedRelative(
const PXR_NS::SdfLayerHandle& layer,
const std::string& contentPath)
{
auto& postponedRelativePaths = getPostponedRelativePaths();
auto layerEntry = postponedRelativePaths.find(layer);
if (layerEntry != postponedRelativePaths.end()) {
ghc::filesystem::path filePath(contentPath);
layerEntry->second.erase(filePath.lexically_normal());
}
}

void UsdMayaUtilFileSystem::updatePostponedRelativePaths(
const PXR_NS::SdfLayerHandle& layer,
const std::string& layerFileName)
{
// Find the layer entry
auto& postponedRelativePaths = getPostponedRelativePaths();
auto layerEntry = postponedRelativePaths.find(layer);
if (layerEntry == postponedRelativePaths.end()) {
return;
}

// Update sublayer paths
auto subLayerPaths = layer->GetSubLayerPaths();
for (size_t j = 0; j < subLayerPaths.size(); ++j) {
const auto subLayer = SdfLayer::FindRelativeToLayer(layer, subLayerPaths[j]);
if (!subLayer) {
continue;
}

ghc::filesystem::path filePath(subLayer->GetRealPath());
filePath = filePath.lexically_normal();

auto it = layerEntry->second.find(filePath);
if (it == layerEntry->second.end()) {
continue;
}

auto anchorDir = ghc::filesystem::path(layerFileName).lexically_normal().remove_filename();
subLayerPaths[j]
= getPathRelativeToDirectory(filePath.generic_string(), anchorDir.generic_string());
}

// Erase the layer entry
postponedRelativePaths.erase(layerEntry);
}

bool UsdMayaUtilFileSystem::prepareLayerSaveUILayer(
const PXR_NS::SdfLayerHandle& layer,
bool useSceneFileForRoot)
Expand Down
22 changes: 22 additions & 0 deletions lib/mayaUsd/utils/utilFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,28 @@ MAYAUSD_CORE_PUBLIC
std::string
getPathRelativeToLayerFile(const std::string& fileName, const PXR_NS::SdfLayerHandle& layer);

/*! \brief Marks a certain file path inside the layer to be made relative in a postponed fashion.
The marked file paths will be turned into relative paths upon calling updatePostponedRelativePaths.
*/
MAYAUSD_CORE_PUBLIC
void markPathAsPostponedRelative(
const PXR_NS::SdfLayerHandle& layer,
const std::string& contentPath);

/*! \brief Unmarks file path which was marked through the call to markPathAsPostponedRelative.
*/
MAYAUSD_CORE_PUBLIC
void unmarkPathAsPostponedRelative(
const PXR_NS::SdfLayerHandle& layer,
const std::string& contentPath);

/*! \brief Turns the file paths marked through the call 'markPathAsPostponedRelative' to relative.
*/
MAYAUSD_CORE_PUBLIC
void updatePostponedRelativePaths(
const PXR_NS::SdfLayerHandle& layer,
const std::string& layerFileName);

/*! \brief returns the flag specifying whether USD file paths should be saved as relative to Maya
* scene file
*/
Expand Down
2 changes: 2 additions & 0 deletions lib/mayaUsd/utils/utilSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ bool saveLayerWithFormat(
const std::string& formatArg
= requestedFormatArg.empty() ? usdFormatArgOption() : requestedFormatArg;

UsdMayaUtilFileSystem::updatePostponedRelativePaths(layer, filePath);

if (isCompatibleWithSave(layer, filePath, formatArg)) {
if (!layer->Save()) {
return false;
Expand Down
30 changes: 22 additions & 8 deletions lib/usd/ui/layerEditor/layerTreeItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,13 +395,19 @@ void LayerTreeItem::saveAnonymousLayer()
sessionState->rootLayerPathChanged(fileName);
} else {
auto parentItem = parentLayerItem();

std::string relativePathAnchor;
if (parentItem && UsdMayaUtilFileSystem::requireUsdPathsRelativeToParentLayer()) {
fileName = UsdMayaUtilFileSystem::getPathRelativeToLayerFile(
fileName, parentItem->layer());
relativePathAnchor
= UsdMayaUtilFileSystem::getLayerFileDir(parentItem->layer());
auto parentLayer = parentItem ? parentItem->layer() : nullptr;
if (parentLayer) {
if (UsdMayaUtilFileSystem::requireUsdPathsRelativeToParentLayer()) {
if (!parentLayer->IsAnonymous()) {
fileName = UsdMayaUtilFileSystem::getPathRelativeToLayerFile(
fileName, parentLayer);
} else {
UsdMayaUtilFileSystem::markPathAsPostponedRelative(
parentLayer, fileName);
}
} else {
UsdMayaUtilFileSystem::unmarkPathAsPostponedRelative(parentLayer, fileName);
}
}

// Note: we need to open the layer with the absolute path. The relative path is only
Expand Down Expand Up @@ -478,8 +484,16 @@ void LayerTreeItem::loadSubLayers(QWidget* in_parent)
if (dlg.pathsToLoad().size() > 0) {
const int index = 0;
UndoContext context(commandHook(), "Load Layers");
for (auto path : dlg.pathsToLoad()) {
for (const auto& path : dlg.pathsToLoad()) {
context.hook()->insertSubLayerPath(layer(), path, index);

if (UsdMayaUtilFileSystem::requireUsdPathsRelativeToParentLayer()) {
if (layer()->IsAnonymous()) {
UsdMayaUtilFileSystem::markPathAsPostponedRelative(layer(), path);
}
} else {
UsdMayaUtilFileSystem::unmarkPathAsPostponedRelative(layer(), path);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/usd/ui/layerEditor/loadLayersDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ void LoadLayersDialog::onOpenBrowser()
return;

// Replace selected filenames with relative ones if enabled.
if (requireUsdPathsRelativeToParentLayer()) {
if (requireUsdPathsRelativeToParentLayer() && parentLayer && !parentLayer->IsAnonymous()) {
for (std::string& fileName : files) {
fileName = getPathRelativeToLayerFile(fileName, parentLayer);
}
Expand Down
2 changes: 1 addition & 1 deletion plugin/adsk/scripts/mayaUSDRegisterStrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def mayaUSDRegisterStrings():
register("kMakePathRelativeToImageEditTargetLayer", "Make Path Relative to Edit Target Layer Directory")
register("kMakePathRelativeToImageEditTargetLayerAnn", "Enable to activate relative pathing to your current edit target layer's directory.\nIf this option is disabled, verify that your target layer is not anonymous and save it to disk.")
register("kMakePathRelativeToParentLayer", "Make Path Relative to Parent Layer Directory")
register("kMakePathRelativeToParentLayerAnn", "Enable to activate relative pathing to your current parent layer's directory.\nIf this option is disabled, verify that your parent layer is not anonymous and save it to disk.")
register("kMakePathRelativeToParentLayerAnn", "Enable to activate relative pathing to your current parent layer's directory.")
register("kUnresolvedPath", "Path Preview:")
register("kUnresolvedPathAnn", "This field indicates the path with the file name currently chosen in your text input. Note: This is the string that will be written out to the file in the chosen directory in order to enable portability.")
register("kCompositionArcOptions", "Composition Arc Options")
Expand Down
7 changes: 5 additions & 2 deletions plugin/adsk/scripts/mayaUsd_USDRootFileRelative.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ def uiInit(cls, parentLayout):
showPreviewFields = True
if cls.kRelativeToWhat == 'SceneFile':
showPreviewFields = cmds.file(q=True, exists=True)
elif cls.kRelativeToWhat == 'ParentLayer':
showPreviewFields = bool(cls._relativeToDir)

cmds.textFieldGrp(cls.kUnresolvedPathTextField, edit=True, visible=showPreviewFields)

Expand Down Expand Up @@ -330,8 +332,9 @@ def uiInit(cls, parentLayout, filterType, parentLayerPath):
'''
cls.setRelativeFilePathRoot(parentLayerPath)
cls._relativeToDir = parentLayerPath
# If the parent layer is not saved, then the checkbox and label should be disabled.
cls._canBeRelative = bool(cls._relativeToDir)
# Even if the parent layer is not saved, the file can still be marked as relative.
# In that case we use a technique to set the path to relative in a postponed fashion.
cls._canBeRelative = True
super(usdSubLayerFileRelative, cls).uiInit(parentLayout)

@classmethod
Expand Down
3 changes: 2 additions & 1 deletion plugin/adsk/scripts/mayaUsd_layerEditorFileDialogs.mel
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,9 @@ global proc UsdLayerEditor_LoadLayersFileDialogOptions_FileTypeChanged(string $p

global proc string[] UsdLayerEditor_LoadLayersFileDialog(string $title, string $folder)
{
// Always set parent path to empty to hide the file preview
global string $gLayerParentPathUsdLayerEditorSaveFileDialog;
$gLayerParentPathUsdLayerEditorSaveFileDialog = $folder;
$gLayerParentPathUsdLayerEditorSaveFileDialog = "";

string $fileFilter = python("from mayaUsdUtils import getUSDDialogFileFilters; getUSDDialogFileFilters(False)");
$okCaption = getMayaUsdString("kLoad");
Expand Down

0 comments on commit bee6786

Please sign in to comment.