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

MAYA-110196 - Multiple ProxyShapes with Same Stage (InStageData) Bug #1228

Merged
merged 4 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/usd/ui/layerEditor/layerTreeModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void LayerTreeModel::setSessionState(SessionState* in_sessionState)
in_sessionState,
&SessionState::autoHideSessionLayerSignal,
this,
&LayerTreeModel::sessionStageChanged);
&LayerTreeModel::autoHideSessionLayerChanged);
}

void LayerTreeModel::rebuildModelOnIdle()
Expand Down
11 changes: 5 additions & 6 deletions lib/usd/ui/layerEditor/mayaLayerEditorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class LayerEditorWindowCreator : public AbstractLayerEditorCreator
{
public:
LayerEditorWindowCreator() { ; };
virtual ~LayerEditorWindowCreator() { }
virtual ~LayerEditorWindowCreator() {}

AbstractLayerEditorWindow* createWindow(const char* panelName) override;
AbstractLayerEditorWindow* getWindow(const char* panelName) const override;
Expand Down Expand Up @@ -232,11 +232,10 @@ void MayaLayerEditorWindow::selectPrimsWithSpec()

void MayaLayerEditorWindow::selectProxyShape(const char* shapePath)
{
auto prim = UsdMayaQuery::GetPrim(shapePath);
if (prim) {
auto stage = prim.GetStage();
if (stage != nullptr) {
_sessionState.setStage(stage);
SessionState::StageEntry entry;
if (_sessionState.getStageEntry(&entry, shapePath)) {
if (entry._stage != nullptr) {
_sessionState.setStageEntry(entry);
}
}
}
Expand Down
81 changes: 46 additions & 35 deletions lib/usd/ui/layerEditor/mayaSessionState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@
#include "saveLayersDialog.h"
#include "stringResources.h"

#include <mayaUsd/utils/query.h>
#include <mayaUsd/nodes/usdPrimProvider.h>
#include <mayaUsd/utils/util.h>

#include <maya/MDGMessage.h>
#include <maya/MDagPath.h>
#include <maya/MFnDagNode.h>
#include <maya/MGlobal.h>
#include <maya/MNodeMessage.h>
#include <maya/MPxNode.h>
#include <maya/MSceneMessage.h>
#include <maya/MUuid.h>

#include <QtCore/QTimer>
#include <QtWidgets/QMenu>
Expand Down Expand Up @@ -59,25 +61,29 @@ MayaSessionState::~MayaSessionState()
//
}

void MayaSessionState::setStage(PXR_NS::UsdStageRefPtr const& in_stage)
void MayaSessionState::setStageEntry(StageEntry const& inEntry)
{
PARENT_CLASS::setStage(in_stage);
if (in_stage) {
auto stageList = allStages();
for (auto const& entry : stageList) {
if (entry._stage == in_stage) {
_currentProxyShapePath = entry._proxyShapePath;
break;
}
}
} else {
_currentProxyShapePath.clear();
PARENT_CLASS::setStageEntry(inEntry);
if (!inEntry._stage) {
_currentStageEntry.clear();
}
}

bool MayaSessionState::getStageEntry(StageEntry* out_stageEntry, const MString& shapePath)
{
auto prim = UsdMayaQuery::GetPrim(shapePath.asChar());
pxr::UsdPrim prim;

MObject shapeObj;
MStatus status = UsdMayaUtil::GetMObjectByName(shapePath.asChar(), shapeObj);
CHECK_MSTATUS_AND_RETURN(status, false);
MFnDagNode dagNode(shapeObj, &status);
CHECK_MSTATUS_AND_RETURN(status, false);

if (const UsdMayaUsdPrimProvider* usdPrimProvider
= dynamic_cast<const UsdMayaUsdPrimProvider*>(dagNode.userNode())) {
prim = usdPrimProvider->usdPrim();
}

if (prim) {
auto stage = prim.GetStage();
// debatable, but we remove the path|to|shape
Expand All @@ -89,6 +95,7 @@ bool MayaSessionState::getStageEntry(StageEntry* out_stageEntry, const MString&
} else {
niceName = tokenList[0];
}
out_stageEntry->_id = dagNode.uuid().asString().asChar();
out_stageEntry->_stage = stage;
out_stageEntry->_displayName = niceName.toStdString();
out_stageEntry->_proxyShapePath = shapePath.asChar();
Expand Down Expand Up @@ -155,25 +162,23 @@ void MayaSessionState::unregisterNotifications()

void MayaSessionState::mayaUsdStageReset(const MayaUsdProxyStageSetNotice& notice)
{
auto shapePath = notice.GetShapePath();
auto stage = notice.GetStage();
if (shapePath == _currentProxyShapePath) {
QTimer::singleShot(0, this, [this, stage]() { setStage(stage); });
} else {
auto shapePath = notice.GetShapePath();
QTimer::singleShot(
0, this, [this, shapePath, stage]() { mayaUsdStageResetCBOnIdle(shapePath, stage); });
auto shapePath = notice.GetShapePath();
StageEntry entry;
if (getStageEntry(&entry, shapePath.c_str())) {
if (entry._proxyShapePath == _currentStageEntry._proxyShapePath) {
QTimer::singleShot(0, this, [this, entry]() {
mayaUsdStageResetCBOnIdle(entry);
setStageEntry(entry);
});
} else {
QTimer::singleShot(0, this, [this, entry]() { mayaUsdStageResetCBOnIdle(entry); });
}
}
}

void MayaSessionState::mayaUsdStageResetCBOnIdle(
const std::string& shapePath,
PXR_NS::UsdStageRefPtr const& stage)
void MayaSessionState::mayaUsdStageResetCBOnIdle(StageEntry const& entry)
{
StageEntry entry;
if (getStageEntry(&entry, shapePath.c_str())) {
Q_EMIT stageResetSignal(entry._proxyShapePath, stage);
}
Q_EMIT stageResetSignal(entry);
}

/* static */
Expand All @@ -195,7 +200,7 @@ void MayaSessionState::proxyShapeAddedCBOnIdle(const MObject& obj)
auto shapePath = dagPath.fullPathName();
StageEntry entry;
if (getStageEntry(&entry, shapePath)) {
Q_EMIT stageListChangedSignal(entry._stage);
Q_EMIT stageListChangedSignal(entry);
}
}

Expand All @@ -213,11 +218,12 @@ void MayaSessionState::nodeRenamedCB(MObject& obj, const MString& oldName, void*
auto THIS = static_cast<MayaSessionState*>(clientData);

// doing it on idle give time to the Load Stage to set a file name
QTimer::singleShot(0, [THIS, obj]() { THIS->nodeRenamedCBOnIdle(obj); });
QTimer::singleShot(
0, [THIS, obj, oldName]() { THIS->nodeRenamedCBOnIdle(oldName.asChar(), obj); });
}
}

void MayaSessionState::nodeRenamedCBOnIdle(const MObject& obj)
void MayaSessionState::nodeRenamedCBOnIdle(std::string const& oldName, const MObject& obj)
{
// this does not work:
// if OpenMaya.MFnDependencyNode(obj).typeName == PROXY_NODE_TYPE
Expand All @@ -228,7 +234,12 @@ void MayaSessionState::nodeRenamedCBOnIdle(const MObject& obj)

StageEntry entry;
if (getStageEntry(&entry, shapePath)) {
Q_EMIT stageRenamedSignal(entry._displayName, entry._stage);
// Need to update the current Entry also
if (_currentStageEntry._id == entry._id) {
_currentStageEntry = entry;
}

Q_EMIT stageRenamedSignal(entry);
}
}
}
Expand Down Expand Up @@ -325,10 +336,10 @@ std::string MayaSessionState::defaultLoadPath() const
// in this case, the stage needs to be re-created on the new file
void MayaSessionState::rootLayerPathChanged(std::string const& in_path)
{
if (!_currentProxyShapePath.empty()) {
if (!_currentStageEntry._proxyShapePath.empty()) {

MString script;
MString proxyShape(_currentProxyShapePath.c_str());
MString proxyShape(_currentStageEntry._proxyShapePath.c_str());
MString newValue(in_path.c_str());
script.format("setAttr -type \"string\" ^1s.filePath \"^2s\"", proxyShape, newValue);
MGlobal::executeCommand(
Expand Down
11 changes: 5 additions & 6 deletions lib/usd/ui/layerEditor/mayaSessionState.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class MayaSessionState
~MayaSessionState();

// API implementation
void setStage(PXR_NS::UsdStageRefPtr const& in_stage) override;
void setStageEntry(StageEntry const& in_entry) override;
void setAutoHideSessionLayer(bool hide) override;
AbstractCommandHook* commandHook() override;
std::vector<StageEntry> allStages() const override;
Expand All @@ -69,7 +69,7 @@ class MayaSessionState
// in this case, the stage needs to be re-created on the new file
void rootLayerPathChanged(std::string const& in_path) override;

std::string proxyShapePath() { return _currentProxyShapePath; }
std::string proxyShapePath() { return _currentStageEntry._proxyShapePath; }

Q_SIGNALS:
void clearUIOnSceneResetSignal();
Expand All @@ -78,26 +78,25 @@ class MayaSessionState
void registerNotifications();
void unregisterNotifications();

protected:
// get the stage and proxy name for a path
static bool getStageEntry(StageEntry* out_stageEntry, const MString& shapePath);

protected:
// maya callback handers
static void proxyShapeAddedCB(MObject& node, void* clientData);
static void proxyShapeRemovedCB(MObject& node, void* clientData);
static void nodeRenamedCB(MObject& node, const MString& oldName, void* clientData);
static void sceneClosingCB(void* clientData);

void proxyShapeAddedCBOnIdle(const MObject& node);
void nodeRenamedCBOnIdle(const MObject& obj);
void nodeRenamedCBOnIdle(std::string const& oldName, const MObject& obj);

// Notice listener method for proxy stage set
void mayaUsdStageReset(const MayaUsdProxyStageSetNotice& notice);
void mayaUsdStageResetCBOnIdle(const std::string& shapePath, UsdStageRefPtr const& stage);
void mayaUsdStageResetCBOnIdle(StageEntry const& entry);

std::vector<MCallbackId> _callbackIds;
TfNotice::Key _stageResetNoticeKey;
std::string _currentProxyShapePath;
MayaCommandHook _mayaCommandHook;
};

Expand Down
18 changes: 5 additions & 13 deletions lib/usd/ui/layerEditor/saveLayersDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,19 +275,11 @@ SaveLayersDialog::SaveLayersDialog(SessionState* in_sessionState, QWidget* in_pa
MString msg;
QString dialogTitle = StringResources::getAsQString(StringResources::kSaveStage);
if (TF_VERIFY(nullptr != _sessionState)) {
auto stage = _sessionState->stage();

auto stageList = _sessionState->allStages();
for (auto const& entry : stageList) {
if (entry._stage == stage) {
std::string stageName = entry._displayName;
msg.format(
StringResources::getAsMString(StringResources::kSaveName), stageName.c_str());
dialogTitle = MQtUtil::toQString(msg);
getLayersToSave(stage, stageName);
break;
}
}
auto stageEntry = _sessionState->stageEntry();
std::string stageName = stageEntry._displayName;
msg.format(StringResources::getAsMString(StringResources::kSaveName), stageName.c_str());
dialogTitle = MQtUtil::toQString(msg);
getLayersToSave(stageEntry._stage, stageName);
}
setWindowTitle(dialogTitle);

Expand Down
11 changes: 6 additions & 5 deletions lib/usd/ui/layerEditor/sessionState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@ void SessionState::setAutoHideSessionLayer(bool hideIt)
Q_EMIT autoHideSessionLayerSignal(_autoHideSessionLayer);
}

void SessionState::setStage(PXR_NS::UsdStageRefPtr const& in_stage)
void SessionState::setStageEntry(StageEntry const& in_entry)
{
if (in_stage != _stage) {
_stage = in_stage;
if (_currentStageEntry != in_entry) {
auto oldEntry = _currentStageEntry;
_currentStageEntry = in_entry;
Q_EMIT currentStageChangedSignal();
}
}

PXR_NS::SdfLayerRefPtr SessionState::targetLayer() const
{
if (_stage != nullptr) {
const auto& target = _stage->GetEditTarget();
if (_currentStageEntry._stage != nullptr) {
const auto& target = _currentStageEntry._stage->GetEditTarget();
return target.GetLayer();
} else {
return nullptr;
Expand Down
47 changes: 38 additions & 9 deletions lib/usd/ui/layerEditor/sessionState.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,47 @@ class SessionState : public QObject
{
Q_OBJECT
public:
virtual ~SessionState() { }
virtual ~SessionState() {}

struct StageEntry
{
std::string _id;
PXR_NS::UsdStageRefPtr _stage;
std::string _displayName;
std::string _proxyShapePath;

StageEntry()
{
_id = "";
_stage = PXR_NS::UsdStageRefPtr();
_displayName = "";
_proxyShapePath = "";
}

bool operator==(const StageEntry& entry) const
{
return (
_id == entry._id && _stage == entry._stage && _displayName == entry._displayName
&& _proxyShapePath == entry._proxyShapePath);
}

bool operator!=(const StageEntry& entry) const { return !(*this == entry); }

void clear()
{
_stage = PXR_NS::UsdStageRefPtr();
_displayName = "";
_proxyShapePath = "";
}
};

// properties
virtual bool autoHideSessionLayer() const { return _autoHideSessionLayer; }
virtual void setAutoHideSessionLayer(bool hide);
PXR_NS::UsdStageRefPtr const& stage() const { return _stage; }
PXR_NS::UsdStageRefPtr const& stage() const { return _currentStageEntry._stage; }
StageEntry const& stageEntry() const { return _currentStageEntry; }
PXR_NS::SdfLayerRefPtr targetLayer() const;
virtual void setStage(PXR_NS::UsdStageRefPtr const& in_stage);
virtual void setStageEntry(StageEntry const& in_entry);
virtual AbstractCommandHook* commandHook() = 0;
virtual std::vector<StageEntry> allStages() const = 0;
// path to default load layer dialogs to
Expand All @@ -73,18 +99,21 @@ class SessionState : public QObject
// in this case, the stage needs to be re-created on the new file
virtual void rootLayerPathChanged(std::string const& in_path) = 0;

bool isValid() { return _stage && _stage->GetRootLayer(); }
bool isValid()
{
return _currentStageEntry._stage && _currentStageEntry._stage->GetRootLayer();
}

Q_SIGNALS:
void currentStageChangedSignal();
void stageListChangedSignal(PXR_NS::UsdStageRefPtr const& toSelect = PXR_NS::UsdStageRefPtr());
void stageRenamedSignal(std::string const& name, PXR_NS::UsdStageRefPtr const& stage);
void stageListChangedSignal(StageEntry const& toSelect = StageEntry());
void stageRenamedSignal(StageEntry const& renamedEntry);
void autoHideSessionLayerSignal(bool hideIt);
void stageResetSignal(const std::string& proxyPath, PXR_NS::UsdStageRefPtr const& stage);
void stageResetSignal(StageEntry const& entry);

protected:
PXR_NS::UsdStageRefPtr _stage;
bool _autoHideSessionLayer = true;
StageEntry _currentStageEntry;
bool _autoHideSessionLayer = true;
};

} // namespace UsdLayerEditor
Expand Down
Loading