From 521931aabf544cb30b6df46fc18daa5143c43f68 Mon Sep 17 00:00:00 2001 From: Pierre Baillargeon Date: Fri, 3 Feb 2023 10:24:43 -0500 Subject: [PATCH] MAYA-127478 fix bulk save of root layer filename When doing a bulk-save of layers when saving a Maya scene for the first time, the multiple-parts of teh saving process could end-up using stale data. That is because there is a first batch-save delegate (customizable callback) that can do a partial save, then a fallback save is done for any layer that did not get saved. When a stage has just been created, it contains an anonymous root layer which gets replaced by a non-anonymous by the batch save delegate. When the root layer is swapped, the stage proxy shape is updated by setting its stage name attribute. Unfortunately, the USD stage object was being cached and the attribute chage was thus not use immediately. Thus the 2nd part fallback-save thought that the root layer was still anonymous. The fix is to refresh the cached USD stages by pulling again on the proxy stage node so that it updates itself when its attributes have been changed. --- lib/mayaUsd/nodes/layerManager.cpp | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/lib/mayaUsd/nodes/layerManager.cpp b/lib/mayaUsd/nodes/layerManager.cpp index f1c04e348a..a0afb7eea1 100644 --- a/lib/mayaUsd/nodes/layerManager.cpp +++ b/lib/mayaUsd/nodes/layerManager.cpp @@ -248,6 +248,7 @@ class LayerDatabase : public TfWeakBase void saveUsdLayerToMayaFile(SdfLayerRefPtr layer, bool asAnonymous); void clearProxies(); bool hasDirtyLayer() const; + void refreshProxiesToSave(); std::map _idToLayer; TfNotice::Key _onStageSetKey; @@ -520,6 +521,27 @@ bool LayerDatabase::getProxiesToSave(bool isExport) bool LayerDatabase::saveInteractionRequired() { return _proxiesToSave.size() > 0; } +static void refreshSavingInfo(StageSavingInfo& info) +{ + MFnDependencyNode fn; + MObject mobj = info.dagPath.node(); + fn.setObject(mobj); + if (!fn.isFromReferencedFile() && LayerDatabase::instance().supportedNodeType(fn.typeId())) { + MayaUsdProxyShapeBase* pShape = static_cast(fn.userNode()); + info.stage = pShape ? pShape->getUsdStage() : nullptr; + } +} + +void LayerDatabase::refreshProxiesToSave() +{ + for (StageSavingInfo& info : _proxiesToSave) { + refreshSavingInfo(info); + } + for (StageSavingInfo& info : _internalProxiesToSave) { + refreshSavingInfo(info); + } +} + bool LayerDatabase::saveUsd(bool isExport) { BatchSaveResult result = MayaUsd::kNotHandled; @@ -555,6 +577,12 @@ bool LayerDatabase::saveUsd(bool isExport) return true; } + // After the potentially partial save, we need to refresh the stages + // to be saved because the saving might have modified the proxy shape + // attributes and we need to re-evaluate these nodes so that the stages + // are re-created with the new attribute values if needed. + refreshProxiesToSave(); + if (MayaUsd::utils::kSaveToUSDFiles == opt) { result = saveUsdToUsdFiles(); } else { @@ -781,6 +809,9 @@ void LayerDatabase::convertAnonymousLayers( convertAnonymousLayersRecursive(root, proxyName, stage); + // Note: retrieve root again since it may have been changed by the call + // to convertAnonymousLayersRecursive + root = stage->GetRootLayer(); if (root->IsAnonymous()) { PXR_NS::SdfFileFormat::FileFormatArguments args; std::string newFileName = MayaUsd::utils::generateUniqueFileName(proxyName);