Skip to content

Commit

Permalink
Merge branch 'dev' into minnins/assign-new-material-to-multiple-objects
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanminning-autodesk authored Nov 17, 2022
2 parents d50fa23 + f7997b1 commit 7f3ddcd
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 54 deletions.
6 changes: 0 additions & 6 deletions lib/mayaUsd/ufe/UsdUndoAddNewPrimCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ UsdUndoAddNewPrimCommand::UsdUndoAddNewPrimCommand(
_newUfePath = appendToPath(ufePath, newPrimName);
}

const bool allowStronger = true;
ufe::applyCommandRestriction(
usdSceneItem->prim(),
"add new [" + _newUfePath.back().string() + "] under ",
allowStronger);

// Build (and store) the usd path for the new prim with the unique name.
PXR_NS::SdfPath usdItemPath = usdSceneItem->prim().GetPath();
_primPath = usdItemPath.AppendChild(PXR_NS::TfToken(newPrimName));
Expand Down
4 changes: 4 additions & 0 deletions lib/mayaUsd/ufe/UsdUndoAddNewPrimCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ namespace MAYAUSD_NS_DEF {
namespace ufe {

//! \brief Undoable command for add new prim
//
// This command is not restricted: it is always possible to create a new
// prim even in weaker layer since the new prim, by the fact that it is new
// cannot have an already-existing opinon that would shadow it.
class MAYAUSD_CORE_PUBLIC UsdUndoAddNewPrimCommand : public Ufe::UndoableCommand
{
public:
Expand Down
26 changes: 18 additions & 8 deletions lib/mayaUsd/ufe/UsdUndoVisibleCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
namespace MAYAUSD_NS_DEF {
namespace ufe {

UsdUndoVisibleCommand::UsdUndoVisibleCommand(const UsdPrim& prim, bool vis)
UsdUndoVisibleCommand::UsdUndoVisibleCommand(
const UsdPrim& prim,
bool vis,
const PXR_NS::SdfLayerHandle& layer)
: Ufe::UndoableCommand()
, _prim(prim)
, _visible(vis)
, _layer(getEditRouterLayer(PXR_NS::TfToken("visibility"), prim))
, _layer(layer)
{
}

Expand All @@ -39,19 +42,26 @@ UsdUndoVisibleCommand::Ptr UsdUndoVisibleCommand::create(const UsdPrim& prim, bo
if (!prim) {
return nullptr;
}
return std::make_shared<UsdUndoVisibleCommand>(prim, vis);
}

void UsdUndoVisibleCommand::execute()
{
UsdGeomImageable primImageable(_prim);
auto layer = getEditRouterLayer(PXR_NS::TfToken("visibility"), prim);

UsdGeomImageable primImageable(prim);

EditTargetGuard guard(prim, layer);

std::string errMsg;
if (!MayaUsd::ufe::isAttributeEditAllowed(primImageable.GetVisibilityAttr(), &errMsg)) {
MGlobal::displayError(errMsg.c_str());
return;
return nullptr;
}

return std::make_shared<UsdUndoVisibleCommand>(prim, vis, layer);
}

void UsdUndoVisibleCommand::execute()
{
UsdGeomImageable primImageable(_prim);

UsdUndoBlock undoBlock(&_undoableItem);

EditTargetGuard guard(_prim, _layer);
Expand Down
6 changes: 5 additions & 1 deletion lib/mayaUsd/ufe/UsdUndoVisibleCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ class MAYAUSD_CORE_PUBLIC UsdUndoVisibleCommand : public Ufe::UndoableCommand
public:
typedef std::shared_ptr<UsdUndoVisibleCommand> Ptr;

UsdUndoVisibleCommand(const PXR_NS::UsdPrim& prim, bool vis);
// Public for std::make_shared() access, use create() instead.
UsdUndoVisibleCommand(
const PXR_NS::UsdPrim& prim,
bool vis,
const PXR_NS::SdfLayerHandle& layer);
~UsdUndoVisibleCommand() override;

// Delete the copy/move constructors assignment operators.
Expand Down
4 changes: 4 additions & 0 deletions plugin/al/lib/AL_USDMaya/AL/usdmaya/nodes/ProxyShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,10 @@ MStatus ProxyShape::computeOutStageData(const MPlug& plug, MDataBlock& dataBlock
return MS::kFailure;
}

// Sending MayaUsdProxyStageInvalidateNotice will trigger a callback in StagesSubject
// to clear out stage listeners before adding new stage listeners by the callback triggered by
// MayaUsdProxyStageSetNotice.
MayaUsdProxyStageInvalidateNotice(*this).Send();
MayaUsdProxyStageSetNotice(*this).Send();

return status;
Expand Down
12 changes: 10 additions & 2 deletions test/lib/ufe/testConnections.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import testUtils

from maya import cmds
from pxr import Sdr

import os
import ufe
Expand Down Expand Up @@ -493,6 +494,13 @@ def testCreateStandardSurface(self):

shaderAttr = shaderAttrs.attribute("info:id")
shaderAttr.set("ND_standard_surface_surfaceshader")

# The native type of the output has changed in recent versions of USD, so we need to
# check with Sdr to see what native type we are going to get.
ssNodeDef = Sdr.Registry().GetShaderNodeByIdentifier("ND_standard_surface_surfaceshader")
ssOutput = ssNodeDef.GetShaderOutput("out")
ssOutputType = ssOutput.GetType()

#
#
# Then switch to connection code to connect the shader. Since we never created the
Expand All @@ -503,7 +511,7 @@ def testCreateStandardSurface(self):
materialOutput = materialAttrs.attribute("outputs:surface")

self.assertEqual(shaderOutput.type, "Generic")
self.assertEqual(shaderOutput.nativeType(), "surfaceshader")
self.assertEqual(shaderOutput.nativeType(), ssOutputType)
self.assertEqual(materialOutput.type, "Generic")
self.assertEqual(materialOutput.nativeType(), "TfToken")

Expand Down Expand Up @@ -557,7 +565,7 @@ def testCreateStandardSurface(self):
shaderAttrs = ufe.Attributes.attributes(shaderItem)
shaderOutput = shaderAttrs.attribute("outputs:out")
self.assertEqual(shaderOutput.type, "Generic")
self.assertEqual(shaderOutput.nativeType(), "surfaceshader")
self.assertEqual(shaderOutput.nativeType(), ssOutputType)

# TODO: Test the undoable versions of these commands. They MUST restore the prims as they
# were before connecting, which might require deleting authored attributes.
Expand Down
97 changes: 97 additions & 0 deletions test/lib/ufe/testContextOps.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import usdUtils
import ufeUtils
import testUtils
import mayaUsd

from pxr import UsdGeom
from pxr import UsdShade
Expand Down Expand Up @@ -403,6 +404,102 @@ def testAddNewPrim(self):
self.assertEqual(ufeObs.nbAddNotif(), 2)
self.assertEqual(ufeObs.nbDeleteNotif(), 2)

def testAddNewPrimInWeakerLayer(self):
cmds.file(new=True, force=True)

# Create a proxy shape with empty stage to start with.
import mayaUsd_createStageWithNewLayer
proxyShape = mayaUsd_createStageWithNewLayer.createStageWithNewLayer()

# Create our UFE notification observer
ufeObs = TestAddPrimObserver()
ufe.Scene.addObserver(ufeObs)

# Create a ContextOps interface for the proxy shape.
proxyShapePath = ufe.Path([mayaUtils.createUfePathSegment(proxyShape)])
proxyShapeItem = ufe.Hierarchy.createItem(proxyShapePath)
contextOps = ufe.ContextOps.contextOps(proxyShapeItem)

# Create a sub-layers SubLayerA.
stage = mayaUsd.lib.GetPrim(proxyShape).GetStage()
rootLayer = stage.GetRootLayer()
subLayerA = cmds.mayaUsdLayerEditor(rootLayer.identifier, edit=False, addAnonymous="SubLayerA")[0]

# Add a new prim.
cmd = contextOps.doOpCmd(['Add New Prim', 'Xform'])
self.assertIsNotNone(cmd)
ufeObs.reset()
ufeCmd.execute(cmd)

# Ensure we got the correct UFE notifs.
self.assertEqual(ufeObs.nbAddNotif(), 1)
self.assertEqual(ufeObs.nbDeleteNotif(), 0)

# The proxy shape should now have a single UFE child item.
proxyShapehier = ufe.Hierarchy.hierarchy(proxyShapeItem)
self.assertTrue(proxyShapehier.hasChildren())
self.assertEqual(len(proxyShapehier.children()), 1)

# Add a new prim to the prim we just added.
cmds.pickWalk(d='down')

# Get the scene item from the UFE selection.
snIter = iter(ufe.GlobalSelection.get())
xformItem = next(snIter)

# Create a ContextOps interface for it.
contextOps = ufe.ContextOps.contextOps(xformItem)

# Add a new prim.
cmd = contextOps.doOpCmd(['Add New Prim', 'Xform'])
self.assertIsNotNone(cmd)
ufeObs.reset()
ufeCmd.execute(cmd)

# Ensure we got the correct UFE notifs.
self.assertEqual(ufeObs.nbAddNotif(), 1)
self.assertEqual(ufeObs.nbDeleteNotif(), 0)

# The xform prim should now have a single UFE child item.
xformHier = ufe.Hierarchy.hierarchy(xformItem)
self.assertTrue(xformHier.hasChildren())
self.assertEqual(len(xformHier.children()), 1)

# Set target to the weaker sub-layer.
cmds.mayaUsdEditTarget(proxyShape, edit=True, editTarget=subLayerA)

# Add another prim
cmd = contextOps.doOpCmd(['Add New Prim', 'Capsule'])
self.assertIsNotNone(cmd)
ufeObs.reset()
ufeCmd.execute(cmd)

# Ensure we got the correct UFE notifs.
self.assertEqual(ufeObs.nbAddNotif(), 1)
self.assertEqual(ufeObs.nbDeleteNotif(), 0)

# The xform prim should now have two UFE child items.
self.assertTrue(xformHier.hasChildren())
self.assertEqual(len(xformHier.children()), 2)

# Undo will remove the new prim, meaning one less child.
ufeObs.reset()
cmds.undo()
self.assertTrue(xformHier.hasChildren())
self.assertEqual(len(xformHier.children()), 1)

# Ensure we got the correct UFE notifs.
self.assertEqual(ufeObs.nbAddNotif(), 0)
self.assertEqual(ufeObs.nbDeleteNotif(), 1)

cmds.redo()
self.assertTrue(xformHier.hasChildren())
self.assertEqual(len(xformHier.children()), 2)

# Ensure we got the correct UFE notifs.
self.assertEqual(ufeObs.nbAddNotif(), 1)
self.assertEqual(ufeObs.nbDeleteNotif(), 1)

@unittest.skipUnless(Usd.GetVersion() >= (0, 21, 8), 'Requires CanApplySchema from USD')
def testMaterialBinding(self):
"""This test builds a material using only Ufe pre-4.10 capabilities."""
Expand Down
Loading

0 comments on commit 7f3ddcd

Please sign in to comment.