From 294869316189ac6e1115fed019fbdb6aeff9b786 Mon Sep 17 00:00:00 2001 From: Aram Azhari Date: Thu, 26 Jan 2023 11:13:57 -0500 Subject: [PATCH 1/3] Fixes an issue on layer editor when trying to save a root layer directly (by right clicking on the layer and Save As.), where an invalid extension could cause a crash. The fallback is .usd. It also blocks the path that will result in the crash for any other scenario where the file cannot be opened after it was exported. The user is then displayed a message dialog indicating the layer saving was not successful. --- lib/mayaUsd/utils/utilSerialization.cpp | 4 ++++ lib/usd/ui/layerEditor/layerTreeItem.cpp | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/mayaUsd/utils/utilSerialization.cpp b/lib/mayaUsd/utils/utilSerialization.cpp index edd035ab87..4af1ad2721 100644 --- a/lib/mayaUsd/utils/utilSerialization.cpp +++ b/lib/mayaUsd/utils/utilSerialization.cpp @@ -105,6 +105,10 @@ bool saveRootLayer(SdfLayerRefPtr layer, const std::string& proxy) void updateAllCachedStageWithLayer(SdfLayerRefPtr originalLayer, const std::string& newFilePath) { SdfLayerRefPtr newLayer = SdfLayer::FindOrOpen(newFilePath); + if (!newLayer) { + TF_WARN("The filename %s is an invalid file name for a layer.", newFilePath.c_str()); + return; + } for (UsdStageCache& cache : UsdMayaStageCache::GetAllCaches()) { UsdStageCacheContext ctx(cache); std::vector stages = cache.FindAllMatching(originalLayer); diff --git a/lib/usd/ui/layerEditor/layerTreeItem.cpp b/lib/usd/ui/layerEditor/layerTreeItem.cpp index c95174dc15..5d563e7526 100644 --- a/lib/usd/ui/layerEditor/layerTreeItem.cpp +++ b/lib/usd/ui/layerEditor/layerTreeItem.cpp @@ -10,6 +10,7 @@ #include "warningDialogs.h" #include +#include #include #include @@ -362,19 +363,30 @@ void LayerTreeItem::saveAnonymousLayer() std::string fileName; if (sessionState->saveLayerUI(nullptr, &fileName)) { + + std::string filePath(fileName); + const std::string& extension = SdfFileFormat::GetFileExtension(filePath); + const std::string defaultExt(UsdMayaTranslatorTokens->UsdFileExtensionDefault.GetText()); + const std::string usdCrateExt(UsdMayaTranslatorTokens->UsdFileExtensionCrate.GetText()); + const std::string usdASCIIExt(UsdMayaTranslatorTokens->UsdFileExtensionASCII.GetText()); + if (extension != defaultExt && extension != usdCrateExt && extension != usdASCIIExt) { + filePath.append("."); + filePath.append(defaultExt.c_str()); + } + // the path we has is an absolute path const QString dialogTitle = StringResources::getAsQString(StringResources::kSaveLayer); std::string formatTag = MayaUsd::utils::usdFormatArgOption(); - if (saveSubLayer(dialogTitle, parentLayerItem(), layer(), fileName, formatTag)) { - printf("USD Layer written to %s\n", fileName.c_str()); + if (saveSubLayer(dialogTitle, parentLayerItem(), layer(), filePath, formatTag)) { + printf("USD Layer written to %s\n", filePath.c_str()); // now replace the layer in the parent if (isRootLayer()) { - sessionState->rootLayerPathChanged(fileName); + sessionState->rootLayerPathChanged(filePath); } else { // now replace the layer in the parent auto parentItem = parentLayerItem(); - auto newLayer = SdfLayer::FindOrOpen(fileName); + auto newLayer = SdfLayer::FindOrOpen(filePath); if (newLayer) { bool setTarget = _isTargetLayer; auto model = parentModel(); From 499d11ea102073605ba23c667b515bfe185c3ae2 Mon Sep 17 00:00:00 2001 From: Aram Azhari Date: Thu, 26 Jan 2023 14:08:50 -0500 Subject: [PATCH 2/3] Created a function for common code that check USD file extension correction. --- lib/mayaUsd/utils/utilSerialization.cpp | 23 ++++++++++++++--------- lib/mayaUsd/utils/utilSerialization.h | 7 ++++++- lib/usd/ui/layerEditor/layerTreeItem.cpp | 23 +++++++---------------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/mayaUsd/utils/utilSerialization.cpp b/lib/mayaUsd/utils/utilSerialization.cpp index 0800cb8895..d41b1dbf1e 100644 --- a/lib/mayaUsd/utils/utilSerialization.cpp +++ b/lib/mayaUsd/utils/utilSerialization.cpp @@ -289,15 +289,8 @@ SdfLayerRefPtr saveAnonymousLayer( return nullptr; } - std::string filePath(path); - const std::string& extension = SdfFileFormat::GetFileExtension(filePath); - const std::string defaultExt(UsdMayaTranslatorTokens->UsdFileExtensionDefault.GetText()); - const std::string usdCrateExt(UsdMayaTranslatorTokens->UsdFileExtensionCrate.GetText()); - const std::string usdASCIIExt(UsdMayaTranslatorTokens->UsdFileExtensionASCII.GetText()); - if (extension != defaultExt && extension != usdCrateExt && extension != usdASCIIExt) { - filePath.append("."); - filePath.append(defaultExt.c_str()); - } + std::string filePath(path); + ensureUSDFileExtension(filePath); saveLayerWithFormat(anonLayer, filePath, formatArg); @@ -313,6 +306,18 @@ SdfLayerRefPtr saveAnonymousLayer( return newLayer; } +void ensureUSDFileExtension(std::string& filePath) +{ + const std::string& extension = SdfFileFormat::GetFileExtension(filePath); + const std::string defaultExt(UsdMayaTranslatorTokens->UsdFileExtensionDefault.GetText()); + const std::string usdCrateExt(UsdMayaTranslatorTokens->UsdFileExtensionCrate.GetText()); + const std::string usdASCIIExt(UsdMayaTranslatorTokens->UsdFileExtensionASCII.GetText()); + if (extension != defaultExt && extension != usdCrateExt && extension != usdASCIIExt) { + filePath.append("."); + filePath.append(defaultExt.c_str()); + } +} + void getLayersToSaveFromProxy(const std::string& proxyPath, stageLayersToSave& layersInfo) { auto stage = UsdMayaUtil::GetStageByProxyName(proxyPath); diff --git a/lib/mayaUsd/utils/utilSerialization.h b/lib/mayaUsd/utils/utilSerialization.h index 1d093cfabe..02930a7032 100644 --- a/lib/mayaUsd/utils/utilSerialization.h +++ b/lib/mayaUsd/utils/utilSerialization.h @@ -114,7 +114,12 @@ PXR_NS::SdfLayerRefPtr saveAnonymousLayer( LayerParent parent, std::string formatArg = ""); -/*! \brief Check the sublayer stack of the stage looking for any anonymnous +/*! \brief Ensures that the filepath contains a valid USD extension. + */ +MAYAUSD_CORE_PUBLIC +void ensureUSDFileExtension(std::string& filePath); + +/*! \brief Check the sublayer stack of the stage looking for any anonymous layers that will need to be saved. */ MAYAUSD_CORE_PUBLIC diff --git a/lib/usd/ui/layerEditor/layerTreeItem.cpp b/lib/usd/ui/layerEditor/layerTreeItem.cpp index efe7a975da..294aaaa725 100644 --- a/lib/usd/ui/layerEditor/layerTreeItem.cpp +++ b/lib/usd/ui/layerEditor/layerTreeItem.cpp @@ -365,33 +365,24 @@ void LayerTreeItem::saveAnonymousLayer() std::string fileName; if (sessionState->saveLayerUI(nullptr, &fileName)) { - std::string filePath(fileName); - const std::string& extension = SdfFileFormat::GetFileExtension(filePath); - const std::string defaultExt(UsdMayaTranslatorTokens->UsdFileExtensionDefault.GetText()); - const std::string usdCrateExt(UsdMayaTranslatorTokens->UsdFileExtensionCrate.GetText()); - const std::string usdASCIIExt(UsdMayaTranslatorTokens->UsdFileExtensionASCII.GetText()); - if (extension != defaultExt && extension != usdCrateExt && extension != usdASCIIExt) { - filePath.append("."); - filePath.append(defaultExt.c_str()); - } + MayaUsd::utils::ensureUSDFileExtension(fileName); - // the path we has is an absolute path + // the path we have is an absolute path const QString dialogTitle = StringResources::getAsQString(StringResources::kSaveLayer); std::string formatTag = MayaUsd::utils::usdFormatArgOption(); - if (saveSubLayer(dialogTitle, parentLayerItem(), layer(), filePath, formatTag)) { - printf("USD Layer written to %s\n", filePath.c_str()); + if (saveSubLayer(dialogTitle, parentLayerItem(), layer(), fileName, formatTag)) { + printf("USD Layer written to %s\n", fileName.c_str()); // now replace the layer in the parent if (isRootLayer()) { - sessionState->rootLayerPathChanged(filePath); sessionState->rootLayerPathChanged( UsdMayaUtilFileSystem::requireUsdPathsRelativeToMayaSceneFile() - ? UsdMayaUtilFileSystem::getPathRelativeToMayaSceneFile(filePath) - : filePath); + ? UsdMayaUtilFileSystem::getPathRelativeToMayaSceneFile(fileName) + : fileName); } else { // now replace the layer in the parent auto parentItem = parentLayerItem(); - auto newLayer = SdfLayer::FindOrOpen(filePath); + auto newLayer = SdfLayer::FindOrOpen(fileName); if (newLayer) { bool setTarget = _isTargetLayer; auto model = parentModel(); From 2592f5c028e1477a4ca2d32b0a2de7ea5e0c12f7 Mon Sep 17 00:00:00 2001 From: Aram Azhari Date: Thu, 26 Jan 2023 15:00:51 -0500 Subject: [PATCH 3/3] Removed the redundant hearder include. --- lib/usd/ui/layerEditor/layerTreeItem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/usd/ui/layerEditor/layerTreeItem.cpp b/lib/usd/ui/layerEditor/layerTreeItem.cpp index 294aaaa725..ecb7fb57d7 100644 --- a/lib/usd/ui/layerEditor/layerTreeItem.cpp +++ b/lib/usd/ui/layerEditor/layerTreeItem.cpp @@ -10,7 +10,6 @@ #include "warningDialogs.h" #include -#include #include #include