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

EMSUSD-193 - Reintroduce legacy smart signaling in 2024 #3177

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
54 changes: 54 additions & 0 deletions lib/mayaUsd/nodes/proxyShapeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ MObject MayaUsdProxyShapeBase::drawGuidePurposeAttr;
MObject MayaUsdProxyShapeBase::sessionLayerNameAttr;
MObject MayaUsdProxyShapeBase::rootLayerNameAttr;
MObject MayaUsdProxyShapeBase::mutedLayersAttr;
#if MAYA_API_VERSION >= 20240000 && MAYA_API_VERSION <= 20249999
// Change counter attributes
MObject MayaUsdProxyShapeBase::updateCounterAttr;
MObject MayaUsdProxyShapeBase::resyncCounterAttr;
#endif
// Output attributes
MObject MayaUsdProxyShapeBase::outTimeAttr;
MObject MayaUsdProxyShapeBase::outStageDataAttr;
Expand Down Expand Up @@ -402,6 +407,28 @@ MStatus MayaUsdProxyShapeBase::initialize()
retValue = addAttribute(outStageDataAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);

#if MAYA_API_VERSION >= 20240000 && MAYA_API_VERSION <= 20249999
updateCounterAttr
= numericAttrFn.create("updateId", "upid", MFnNumericData::kInt64, -1, &retValue);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
numericAttrFn.setStorable(false);
numericAttrFn.setWritable(false);
numericAttrFn.setHidden(true);
numericAttrFn.setInternal(true);
retValue = addAttribute(updateCounterAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);

resyncCounterAttr
= numericAttrFn.create("resyncId", "rsid", MFnNumericData::kInt64, -1, &retValue);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
numericAttrFn.setStorable(false);
numericAttrFn.setWritable(false);
numericAttrFn.setHidden(true);
numericAttrFn.setInternal(true);
retValue = addAttribute(resyncCounterAttr);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
#endif

outStageCacheIdAttr
= numericAttrFn.create("outStageCacheId", "ostcid", MFnNumericData::kInt, -1, &retValue);
CHECK_MSTATUS_AND_RETURN_IT(retValue);
Expand Down Expand Up @@ -568,6 +595,24 @@ void MayaUsdProxyShapeBase::postConstructor()
}
}

#if MAYA_API_VERSION >= 20240000 && MAYA_API_VERSION <= 20249999
/* virtual */
bool MayaUsdProxyShapeBase::getInternalValue(const MPlug& plug, MDataHandle& handle)
{
bool retVal = true;

if (plug == updateCounterAttr) {
handle.set(_UsdStageUpdateCounter);
} else if (plug == resyncCounterAttr) {
handle.set(_UsdStageResyncCounter);
} else {
retVal = MPxSurfaceShape::getInternalValue(plug, handle);
}

return retVal;
}
#endif

/* virtual */
MStatus MayaUsdProxyShapeBase::compute(const MPlug& plug, MDataBlock& dataBlock)
{
Expand Down Expand Up @@ -1998,10 +2043,19 @@ void MayaUsdProxyShapeBase::_OnStageObjectsChanged(const UsdNotice::ObjectsChang
MProfilingScope profilingScope(
_shapeBaseProfilerCategory, MProfiler::kColorB_L1, "Process USD objects changed");

#if MAYA_API_VERSION >= 20240000 && MAYA_API_VERSION <= 20249999
switch (UsdMayaStageNoticeListener::ClassifyObjectsChanged(notice)) {
case UsdMayaStageNoticeListener::ChangeType::kIgnored: return;
case UsdMayaStageNoticeListener::ChangeType::kResync: ++_UsdStageResyncCounter;
// [[fallthrough]]; // We want that fallthrough to have the update always triggered.
case UsdMayaStageNoticeListener::ChangeType::kUpdate: ++_UsdStageUpdateCounter; break;
}
#else
if (UsdMayaStageNoticeListener::ClassifyObjectsChanged(notice)
== UsdMayaStageNoticeListener::ChangeType::kIgnored) {
return;
}
#endif

// This will definitely force a BBox recomputation on "Frame All" or when framing a selected
// stage. Computing bounds in USD is expensive, so if it pops up in other frequently used
Expand Down
18 changes: 18 additions & 0 deletions lib/mayaUsd/nodes/proxyShapeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ class MayaUsdProxyShapeBase
MAYAUSD_CORE_PUBLIC
static MObject mutedLayersAttr;

#if MAYA_API_VERSION >= 20240000 && MAYA_API_VERSION <= 20249999
// Change counter attributes
MAYAUSD_CORE_PUBLIC
static MObject updateCounterAttr;
MAYAUSD_CORE_PUBLIC
static MObject resyncCounterAttr;
#endif

// Output attributes
MAYAUSD_CORE_PUBLIC
static MObject outTimeAttr;
Expand Down Expand Up @@ -171,6 +179,10 @@ class MayaUsdProxyShapeBase

MAYAUSD_CORE_PUBLIC
void postConstructor() override;
#if MAYA_API_VERSION >= 20240000 && MAYA_API_VERSION <= 20249999
MAYAUSD_CORE_PUBLIC
bool getInternalValue(const MPlug&, MDataHandle&) override;
#endif
MAYAUSD_CORE_PUBLIC
MStatus compute(const MPlug& plug, MDataBlock& dataBlock) override;
MAYAUSD_CORE_PUBLIC
Expand Down Expand Up @@ -406,6 +418,12 @@ class MayaUsdProxyShapeBase
size_t _excludePrimPathsVersion { 1 };
size_t _UsdStageVersion { 1 };

#if MAYA_API_VERSION >= 20240000 && MAYA_API_VERSION <= 20249999
// Notification counters:
MInt64 _UsdStageUpdateCounter { 1 };
MInt64 _UsdStageResyncCounter { 1 };
#endif

MayaUsd::ProxyAccessor::Owner _usdAccessor;

static ClosestPointDelegate _sharedClosestPointDelegate;
Expand Down
41 changes: 41 additions & 0 deletions test/lib/ufe/testContextOps.py
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,27 @@ def testGeomCoponentAssignment(self):
self.assertEqual(topSubset.GetFamilyNameAttr().Get(), "componentTag")
self.assertFalse(topSubset.GetPrim().HasAPI(UsdShade.MaterialBindingAPI))

if mayaUtils.mayaMajorVersion() == 2024:
# We also can check the old sync counters:
counters= { "resync": cmds.getAttr(psPathStr + '.resyncId'),
"update" : cmds.getAttr(psPathStr + '.upid')}

def assertIsOnlyUpdate(self, counters, shapePathStr):
resyncCounter = cmds.getAttr(shapePathStr + '.resyncId')
updateCounter = cmds.getAttr(shapePathStr + '.updateId')
self.assertEqual(resyncCounter, counters["resync"])
self.assertGreater(updateCounter, counters["update"])
counters["resync"] = resyncCounter
counters["update"] = updateCounter

def assertIsResync(self, counters, shapePathStr):
resyncCounter = cmds.getAttr(shapePathStr + '.resyncId')
updateCounter = cmds.getAttr(shapePathStr + '.updateId')
self.assertGreater(resyncCounter, counters["resync"])
self.assertGreater(updateCounter, counters["update"])
counters["resync"] = resyncCounter
counters["update"] = updateCounter

messageHandler = mayaUtils.TestProxyShapeUpdateHandler(psPathStr)
messageHandler.snapshot()

Expand All @@ -1508,47 +1529,66 @@ def testGeomCoponentAssignment(self):

# We expect a resync after this assignment:
self.assertTrue(messageHandler.isResync())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsResync(self, counters, psPathStr)

# setting a value the first time is a resync due to the creation of the attribute:
attrs = ufe.Attributes.attributes(shaderItem)
metallicAttr = attrs.attribute("inputs:metallic")
ufeCmd.execute(metallicAttr.setCmd(0.5))
self.assertTrue(messageHandler.isResync())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsResync(self, counters, psPathStr)

# Subsequent changes are updates:
ufeCmd.execute(metallicAttr.setCmd(0.7))
self.assertTrue(messageHandler.isUpdate())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsOnlyUpdate(self, counters, psPathStr)

# First undo is an update:
cmds.undo()
self.assertTrue(messageHandler.isUpdate())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsOnlyUpdate(self, counters, psPathStr)

# Second undo is a resync:
cmds.undo()
self.assertTrue(messageHandler.isResync())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsResync(self, counters, psPathStr)

# Third undo is also resync:
cmds.undo()
self.assertTrue(messageHandler.isResync())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsResync(self, counters, psPathStr)

# First redo is resync:
cmds.redo()
self.assertTrue(messageHandler.isResync())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsResync(self, counters, psPathStr)

# Second redo is resync:
cmds.redo()
self.assertTrue(messageHandler.isResync())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsResync(self, counters, psPathStr)

# Third redo is update:
cmds.redo()
self.assertTrue(messageHandler.isUpdate())
if mayaUtils.mayaMajorVersion() == 2024:
assertIsOnlyUpdate(self, counters, psPathStr)
currentCacheId = messageHandler.getStageCacheId()

# Changing the whole stage is a resync:
testFile = testUtils.getTestScene("MaterialX", "MtlxValueTypes.usda")
cmds.setAttr('{}.filePath'.format(psPathStr), testFile, type='string')

self.assertTrue(messageHandler.isResync())
# The old smart signaling for Maya 2024 will not catch that.

# But that will be the last resync:
testFile = testUtils.getTestScene("MaterialX", "sin_compound.usda")
Expand All @@ -1564,6 +1604,7 @@ def testGeomCoponentAssignment(self):
cmds.setAttr('{}.filePath'.format(psPathStr), testFile, type='string')

self.assertTrue(messageHandler.isResync())
# The old smart signaling for Maya 2024 will not catch that.

messageHandler.terminate()

Expand Down