Skip to content

Commit

Permalink
Merge pull request #3984 from Autodesk/bailp/EMSUSD-1722/fix-node-ori…
Browse files Browse the repository at this point in the history
…gin-detection

EMSUSD-1722 fix node origin detection
  • Loading branch information
seando-adsk authored Nov 5, 2024
2 parents 9ddc95c + f17afcc commit a20c419
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 120 deletions.
96 changes: 61 additions & 35 deletions lib/mayaUsd/nodes/layerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,23 @@ MStatus disconnectCompoundArrayPlug(MPlug arrayPlug)
return dgmod.doIt();
}

/// @brief Verify if the given node is either from the given reference, if that is not null,
/// or from the main Maya scene if the reference is null.
/// @brief Verify if the given node is from a reference.
static bool
isNodeFromDesiredOrigin(const MFnReference* fromReference, const MFnDependencyNode& node)
isNodeFromDesiredOrigin(const MFnDependencyNode& node, MayaUsdProxyShapeBase* forProxyShape)
{
if (fromReference) {
return fromReference->containsNodeExactly(node.object());
} else {
return !node.isFromReferencedFile();
}
const bool proxyIsFromReference
= (forProxyShape && MFnDependencyNode(forProxyShape->thisMObject()).isFromReferencedFile());
return node.isFromReferencedFile() == proxyIsFromReference;
}

MayaUsd::LayerManager* findNode(const MFnReference* fromReference = nullptr)
MayaUsd::LayerManager* findNode(MayaUsdProxyShapeBase* forProxyShape)
{
if (forProxyShape) {
if (MayaUsd::LayerManager* layerManager = forProxyShape->getLayerManager()) {
return layerManager;
}
}

// Check for cached layer manager before searching
MFnDependencyNode fn;
if (layerManagerHandle.isValid() && layerManagerHandle.isAlive()) {
Expand All @@ -143,7 +146,7 @@ MayaUsd::LayerManager* findNode(const MFnReference* fromReference = nullptr)
MObject mobj = iter.item();
fn.setObject(mobj);
if (fn.typeId() == MayaUsd::LayerManager::typeId) {
if (isNodeFromDesiredOrigin(fromReference, fn)) {
if (isNodeFromDesiredOrigin(fn, forProxyShape)) {
layerManagerHandle = mobj;
return static_cast<MayaUsd::LayerManager*>(fn.userNode());
}
Expand All @@ -152,9 +155,9 @@ MayaUsd::LayerManager* findNode(const MFnReference* fromReference = nullptr)
return nullptr;
}

MayaUsd::LayerManager* findOrCreateNode(const MFnReference* fromReference = nullptr)
MayaUsd::LayerManager* findOrCreateNode(MayaUsdProxyShapeBase* forProxyShape)
{
MayaUsd::LayerManager* lm = findNode(fromReference);
MayaUsd::LayerManager* lm = findNode(forProxyShape);
if (!lm) {
MDGModifier& modifier = MayaUsd::MDGModifierUndoItem::create("Node find or creation");
MObject manager = modifier.createNode(MayaUsd::LayerManager::typeId);
Expand Down Expand Up @@ -230,10 +233,12 @@ class LayerDatabase : public TfWeakBase
static void prepareForExportCheck(bool*, void*);
static void prepareForWriteCheck(bool*, bool);
static void cleanupForWrite();
static void loadLayersPostRead(const MFnReference* fromReference = nullptr);
static void loadLayersPostRead(MayaUsdProxyShapeBase* forProxyShape);
static void cleanUpNewScene(void*);
static void clearManagerNode(MayaUsd::LayerManager* lm);
static void removeManagerNode(MayaUsd::LayerManager* lm = nullptr);
static void removeManagerNode(
MayaUsd::LayerManager* lm = nullptr,
MayaUsdProxyShapeBase* forProxyShape = nullptr);

bool getProxiesToSave(bool isExport, bool* hasAnyProxy);
bool saveInteractionRequired();
Expand All @@ -249,7 +254,7 @@ class LayerDatabase : public TfWeakBase
std::string getSelectedStage() const;

bool saveLayerManagerSelectedStage();
bool loadLayerManagerSelectedStage();
bool loadLayerManagerSelectedStage(MayaUsdProxyShapeBase* forProxyShape);

SdfLayerHandle findLayer(std::string identifier) const;

Expand Down Expand Up @@ -506,8 +511,11 @@ void LayerDatabase::prepareForWriteCheck(bool* retCode, bool isExport)
*retCode = true;
}

// Note: for now we only save USD change made in stage in the main
// Maya scene. We don't save changes made to stages in Maya
// references.
if (!hasAnyProxy)
removeManagerNode(nullptr);
removeManagerNode(nullptr, nullptr);
}

void LayerDatabase::cleanupForWrite()
Expand Down Expand Up @@ -666,7 +674,10 @@ std::string LayerDatabase::getSelectedStage() const { return _selectedStage; }

bool LayerDatabase::saveLayerManagerSelectedStage()
{
MayaUsd::LayerManager* lm = findOrCreateNode();
// Note: for now we only save USD change made in stage in the main
// Maya scene. We don't save changes made to stages in Maya
// references.
MayaUsd::LayerManager* lm = findOrCreateNode(nullptr);
if (!lm)
return false;

Expand All @@ -691,9 +702,9 @@ bool LayerDatabase::saveLayerManagerSelectedStage()
return true;
}

bool LayerDatabase::loadLayerManagerSelectedStage()
bool LayerDatabase::loadLayerManagerSelectedStage(MayaUsdProxyShapeBase* forProxyShape)
{
MayaUsd::LayerManager* lm = findNode();
MayaUsd::LayerManager* lm = findNode(forProxyShape);
if (!lm)
return false;

Expand Down Expand Up @@ -852,6 +863,8 @@ SaveStageToMayaResult saveStageToMayaFile(
if (!pShape)
return result;

pShape->setLayerManager(nullptr);

std::unordered_set<std::string> localLayerIds;

// Save session layer and its sublayers
Expand Down Expand Up @@ -902,14 +915,19 @@ SaveStageToMayaResult saveStageToMayaFile(
stage->GetRootLayer()->GetIdentifier());
}

pShape->setLayerManager(lm);

result._saveSuceeded = true;
return result;
}

SaveStageToMayaResult saveStageToMayaFile(const MObject& proxyNode, UsdStageRefPtr stage)
{
// Note: for now we only save USD change made in stage in the main
// Maya scene. We don't save changes made to stages in Maya
// references.
SaveStageToMayaResult result;
MayaUsd::LayerManager* lm = findOrCreateNode();
MayaUsd::LayerManager* lm = findOrCreateNode(nullptr);
if (!lm)
return result;

Expand All @@ -930,7 +948,10 @@ SaveStageToMayaResult saveStageToMayaFile(const MObject& proxyNode, UsdStageRefP

BatchSaveResult LayerDatabase::saveUsdToMayaFile()
{
MayaUsd::LayerManager* lm = findOrCreateNode();
// Note: for now we only save USD change made in stage in the main
// Maya scene. We don't save changes made to stages in Maya
// references.
MayaUsd::LayerManager* lm = findOrCreateNode(nullptr);
if (!lm) {
return MayaUsd::kNotHandled;
}
Expand Down Expand Up @@ -1077,7 +1098,10 @@ void LayerDatabase::convertAnonymousLayers(

void LayerDatabase::saveUsdLayerToMayaFile(SdfLayerRefPtr layer, bool asAnonymous)
{
MayaUsd::LayerManager* lm = findOrCreateNode();
// Note: for now we only save USD change made in stage in the main
// Maya scene. We don't save changes made to stages in Maya
// references.
MayaUsd::LayerManager* lm = findOrCreateNode(nullptr);
if (!lm)
return;

Expand All @@ -1094,9 +1118,9 @@ void LayerDatabase::saveUsdLayerToMayaFile(SdfLayerRefPtr layer, bool asAnonymou
dataBlock.setClean(lm->layers);
}

void LayerDatabase::loadLayersPostRead(const MFnReference* fromReference)
void LayerDatabase::loadLayersPostRead(MayaUsdProxyShapeBase* forProxyShape)
{
MayaUsd::LayerManager* lm = findNode(fromReference);
MayaUsd::LayerManager* lm = findNode(forProxyShape);
if (!lm)
return;

Expand Down Expand Up @@ -1127,7 +1151,7 @@ void LayerDatabase::loadLayersPostRead(const MFnReference* fromReference)
identifierVal = idPlug.asString(MDGContext::fsNormal, &status).asChar();
if (identifierVal.empty()) {
MGlobal::displayError(
MString("Error - plug ") + idPlug.partialName(true) + "had empty identifier");
MString("Error - plug ") + idPlug.partialName(true) + " had empty identifier");
continue;
}

Expand Down Expand Up @@ -1209,10 +1233,10 @@ void LayerDatabase::loadLayersPostRead(const MFnReference* fromReference)
}
}

LayerDatabase::instance().loadLayerManagerSelectedStage();
LayerDatabase::instance().loadLayerManagerSelectedStage(forProxyShape);

if (!_isSavingMayaFile)
removeManagerNode(lm);
removeManagerNode(lm, forProxyShape);

for (auto it = createdLayers.begin(); it != createdLayers.end(); ++it) {
SdfLayerHandle lh = (*it);
Expand Down Expand Up @@ -1332,10 +1356,12 @@ void LayerDatabase::clearManagerNode(MayaUsd::LayerManager* lm)
dataBlock.setClean(lm->layers);
}

void LayerDatabase::removeManagerNode(MayaUsd::LayerManager* lm)
void LayerDatabase::removeManagerNode(
MayaUsd::LayerManager* lm,
MayaUsdProxyShapeBase* forProxyShape)
{
if (!lm) {
lm = findNode();
lm = findNode(forProxyShape);
}
if (!lm) {
return;
Expand Down Expand Up @@ -1485,21 +1511,21 @@ LayerManager::LayerManager()
LayerManager::~LayerManager() { }

/* static */
SdfLayerHandle LayerManager::findLayer(std::string identifier, const MFnReference* fromReference)
SdfLayerHandle LayerManager::findLayer(std::string identifier, MayaUsdProxyShapeBase* forProxyShape)
{
std::lock_guard<std::recursive_mutex> lock(findNodeMutex);

LayerDatabase::loadLayersPostRead(fromReference);
LayerDatabase::loadLayersPostRead(forProxyShape);

return LayerDatabase::instance().findLayer(identifier);
}

/* static */
LayerManager::LayerNameMap LayerManager::getLayerNameMap(const MFnReference* fromReference)
LayerManager::LayerNameMap LayerManager::getLayerNameMap(MayaUsdProxyShapeBase* forProxyShape)
{
std::lock_guard<std::recursive_mutex> lock(findNodeMutex);

LayerDatabase::loadLayersPostRead(fromReference);
LayerDatabase::loadLayersPostRead(forProxyShape);

return LayerDatabase::instance().getLayerNameMap();
}
Expand Down Expand Up @@ -1528,9 +1554,9 @@ void LayerManager::setSelectedStage(const std::string& stage)
}

/* static */
std::string LayerManager::getSelectedStage()
std::string LayerManager::getSelectedStage(MayaUsdProxyShapeBase* forProxyShape)
{
LayerDatabase::loadLayersPostRead();
LayerDatabase::loadLayersPostRead(forProxyShape);
return LayerDatabase::instance().getSelectedStage();
}

Expand Down
7 changes: 4 additions & 3 deletions lib/mayaUsd/nodes/layerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define MAYA_USD_LAYER_MANAGER

#include <mayaUsd/base/api.h>
#include <mayaUsd/nodes/proxyShapeBase.h>

#include <pxr/base/tf/notice.h>
#include <pxr/pxr.h>
Expand Down Expand Up @@ -122,18 +123,18 @@ class MAYAUSD_CORE_PUBLIC LayerManager : public MPxNode
//! \brief set the stage that is currently selected in the layer manager.
static void setSelectedStage(const std::string& stage);
//! \brief get the stage that should be selected in the layer manager.
static std::string getSelectedStage();
static std::string getSelectedStage(PXR_NS::MayaUsdProxyShapeBase* forProxyShape);

/*! \brief Supported Proxy Shapes should call this to possibly retrieve their Root and Session
layers before calling Sdf::FindOrOpen. If a handle is found and returned then it will be the
recreated layer, and all sublayers, with edits from a previous Maya session and should be
used to initialize the Proxy Shape in a call to UsdStage::Open().
*/
static SdfLayerHandle
findLayer(std::string identifier, const MFnReference* fromReference = nullptr);
findLayer(std::string identifier, PXR_NS::MayaUsdProxyShapeBase* forProxyShape);

using LayerNameMap = std::map<std::string, std::string>;
static LayerNameMap getLayerNameMap(const MFnReference* fromReference = nullptr);
static LayerNameMap getLayerNameMap(PXR_NS::MayaUsdProxyShapeBase* forProxyShape);

//! \brief returns true if the layer manager is currently saving files.
static bool isSaving();
Expand Down
Loading

0 comments on commit a20c419

Please sign in to comment.