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

Prim metadata editRouting #3790

Merged
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ab31d89
Prepare for primMetadata editRouting.
jufrantz May 28, 2024
8f53231
ToggleInstanceable command can be editRouted
jufrantz May 28, 2024
f033c96
ToggleActive command can be editRouted
jufrantz May 28, 2024
9e04811
SetKind command can be editRouted
jufrantz May 28, 2024
d07abbc
Operations on references/payload can be editRouted
jufrantz May 28, 2024
1da6452
SceneItemMetadata commands can be editRouted
jufrantz May 28, 2024
191c3ec
SetVariantSelection command can be editRouted
jufrantz May 28, 2024
62956c9
Merge branch 'dev' into issue3778/prim_metadata_edit_routing
jufrantz Sep 17, 2024
388a63c
Python bindings for usdUfe SetKindCommand
jufrantz Sep 23, 2024
5e60622
Setting kind metadata from prim AE template is now edit routed
jufrantz Sep 23, 2024
9fd66f1
Faster metadata per-stage layer routing
jufrantz Sep 23, 2024
85bcb08
Python overload to construct PrimMetadataEditRouterContext omitting m…
jufrantz Sep 23, 2024
fd1e2ed
Output errors raised when setting kind from AE such as editRouting pr…
jufrantz Sep 23, 2024
91199ad
Add test case for primMetadata editRouting
jufrantz Sep 23, 2024
5d0718d
Setting/clearing UFE metadata in "SessionLayer-*" groups can be editR…
jufrantz Sep 23, 2024
0c783b4
Add documentation about primMetadata editRouting
jufrantz Sep 23, 2024
a2171ac
clang-format
jufrantz Sep 23, 2024
c0f8a94
Fix primMetadataEditRouting test for USD<23.11.
jufrantz Sep 24, 2024
b317f57
SetKind command enforces edit restrictions
jufrantz Sep 24, 2024
ca1ebb7
SetSceneItemMetadata command enforces edit restrictions
jufrantz Sep 24, 2024
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
22 changes: 15 additions & 7 deletions lib/mayaUsd/resources/ae/usdschemabase/ae_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,7 @@ def onReplace(self, *args):
# that case we don't need to update our controls since none will change.
pass

def refresh(self):
# PrimPath
cmds.textFieldGrp(self.primPath, edit=True, text=str(self.prim.GetPath()))

# Kind
def _refreshKind(self):
model = Usd.ModelAPI(self.prim)
primKind = model.GetKind()
if not primKind:
Expand All @@ -233,6 +229,13 @@ def refresh(self):
else:
cmds.optionMenuGrp(self.kind, edit=True, value=primKind)

def refresh(self):
# PrimPath
cmds.textFieldGrp(self.primPath, edit=True, text=str(self.prim.GetPath()))

# Kind
self._refreshKind()

# Active
cmds.checkBoxGrp(self.active, edit=True, value1=self.prim.IsActive())

Expand All @@ -246,8 +249,13 @@ def refresh(self):

def _onKindChanged(self, value):
with mayaUsdLib.UsdUndoBlock():
model = Usd.ModelAPI(self.prim)
model.SetKind(value)
try:
usdUfe.SetKindCommand(self.prim, value).execute()
except Exception as ex:
# Note: the command might not work because there is a stronger
# opinion or an editRouting prevention so update the option menu
self._refreshKind()


def _onActiveChanged(self, value):
with mayaUsdLib.UsdUndoBlock():
Expand Down
3 changes: 3 additions & 0 deletions lib/usdUfe/base/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,16 @@ namespace USDUFE_NS_DEF {
/* Stage received in the context of some router */ \
((Stage, "stage")) \
((EditTarget, "editTarget")) \
/* Metadata key path received in the context */ \
((KeyPath, "keyPath")) \
jufrantz marked this conversation as resolved.
Show resolved Hide resolved
\
/* Routing operations */ \
\
((RouteParent, "parent")) \
((RouteDuplicate, "duplicate")) \
((RouteVisibility, "visibility")) \
((RouteAttribute, "attribute")) \
((RoutePrimMetadata, "primMetadata")) \
((RouteDelete, "delete")) \
((RouteTransform, "transform")) \
\
Expand Down
15 changes: 15 additions & 0 deletions lib/usdUfe/python/wrapCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <usdUfe/ufe/UsdUndoPayloadCommand.h>
#include <usdUfe/ufe/UsdUndoReloadRefCommand.h>
#include <usdUfe/ufe/UsdUndoSetDefaultPrimCommand.h>
#include <usdUfe/ufe/UsdUndoSetKindCommand.h>
#include <usdUfe/ufe/UsdUndoToggleActiveCommand.h>
#include <usdUfe/ufe/UsdUndoToggleInstanceableCommand.h>

Expand Down Expand Up @@ -67,6 +68,12 @@ UsdUfe::UsdUndoToggleInstanceableCommand* ToggleInstanceableCommandInit(const PX
return new UsdUfe::UsdUndoToggleInstanceableCommand(prim);
}

UsdUfe::UsdUndoSetKindCommand*
SetKindCommandInit(const PXR_NS::UsdPrim& prim, const PXR_NS::TfToken& kind)
{
return new UsdUfe::UsdUndoSetKindCommand(prim, kind);
}

UsdUfe::UsdUndoLoadPayloadCommand*
LoadPayloadCommandInit(const PXR_NS::UsdPrim& prim, PXR_NS::UsdLoadPolicy policy)
{
Expand Down Expand Up @@ -165,6 +172,14 @@ void wrapCommands()
.def("undo", &UsdUfe::UsdUndoToggleInstanceableCommand::undo)
.def("redo", &UsdUfe::UsdUndoToggleInstanceableCommand::redo);
}
{
using This = UsdUfe::UsdUndoSetKindCommand;
class_<This, boost::noncopyable>("SetKindCommand", no_init)
.def("__init__", make_constructor(SetKindCommandInit))
.def("execute", &UsdUfe::UsdUndoSetKindCommand::execute)
.def("undo", &UsdUfe::UsdUndoSetKindCommand::undo)
.def("redo", &UsdUfe::UsdUndoSetKindCommand::redo);
}
{
using This = UsdUfe::UsdUndoLoadPayloadCommand;
class_<This, boost::noncopyable>("LoadPayloadCommand", no_init)
Expand Down
5 changes: 5 additions & 0 deletions lib/usdUfe/python/wrapEditRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,9 @@ void wrapEditRouter()
using AttrThis = UsdUfe::AttributeEditRouterContext;
class_<AttrThis, boost::noncopyable>("AttributeEditRouterContext", no_init)
.def("__init__", make_constructor(AttributeEditRouterContextInit));

using PrimMdThis = UsdUfe::PrimMetadataEditRouterContext;
class_<PrimMdThis, boost::noncopyable>("PrimMetadataEditRouterContext", no_init)
.def(init<const PXR_NS::UsdPrim&, const PXR_NS::TfToken&>())
.def(init<const PXR_NS::UsdPrim&, const PXR_NS::TfToken&, const PXR_NS::TfToken&>());
}
16 changes: 12 additions & 4 deletions lib/usdUfe/ufe/SetVariantSelectionCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "SetVariantSelectionCommand.h"

#include <usdUfe/ufe/Utils.h>
#include <usdUfe/utils/editRouterContext.h>

#include <pxr/usd/usd/variantSets.h>

Expand Down Expand Up @@ -50,15 +51,20 @@ SetVariantSelectionCommand::SetVariantSelectionCommand(

void SetVariantSelectionCommand::redo()
{
const PXR_NS::TfToken metadataKeyPath(_varSet.GetName());

PrimMetadataEditRouterContext ctx(
_prim, PXR_NS::SdfFieldKeys->VariantSelection, metadataKeyPath);

std::string errMsg;
if (!UsdUfe::isPrimMetadataEditAllowed(
_prim,
PXR_NS::SdfFieldKeys->VariantSelection,
PXR_NS::TfToken(_varSet.GetName()),
&errMsg)) {
_prim, PXR_NS::SdfFieldKeys->VariantSelection, metadataKeyPath, &errMsg)) {
throw std::runtime_error(errMsg.c_str());
}

// Backup the destination layer for consistent undo.
_dstLayer = _prim.GetStage()->GetEditTarget().GetLayer();

// Make a copy of the global selection, to restore it on undo.
auto globalSn = Ufe::GlobalSelection::get();
_savedSn.replaceWith(*globalSn);
Expand All @@ -69,6 +75,8 @@ void SetVariantSelectionCommand::redo()

void SetVariantSelectionCommand::undo()
{
PrimMetadataEditRouterContext ctx(_prim.GetStage(), _dstLayer);

std::string errMsg;
if (!UsdUfe::isPrimMetadataEditAllowed(
_prim,
Expand Down
13 changes: 7 additions & 6 deletions lib/usdUfe/ufe/SetVariantSelectionCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ class USDUFE_PUBLIC SetVariantSelectionCommand : public Ufe::UndoableCommand
void undo() override;

private:
const Ufe::Path _path;
PXR_NS::UsdPrim _prim;
PXR_NS::UsdVariantSet _varSet;
const std::string _oldSelection;
const std::string _newSelection;
Ufe::Selection _savedSn; // For global selection save and restore.
const Ufe::Path _path;
PXR_NS::UsdPrim _prim;
PXR_NS::UsdVariantSet _varSet;
const std::string _oldSelection;
const std::string _newSelection;
Ufe::Selection _savedSn; // For global selection save and restore.
PXR_NS::SdfLayerHandle _dstLayer; // To ensure consistent editTarget at undo.
};

} // namespace USDUFE_NS_DEF
Expand Down
8 changes: 8 additions & 0 deletions lib/usdUfe/ufe/UsdUndoAddRefOrPayloadCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
//
#include "UsdUndoAddRefOrPayloadCommand.h"

#include <usdUfe/utils/editRouterContext.h>

#include <pxr/base/tf/stringUtils.h>
#include <pxr/usd/sdf/layer.h>
#include <pxr/usd/sdf/path.h>
Expand Down Expand Up @@ -94,10 +96,16 @@ void UsdUndoAddRefOrPayloadCommand::executeImplementation()
if (_isPayload) {
SdfPayload payload(_filePath, primPath);
UsdPayloads primPayloads = _prim.GetPayloads();

PrimMetadataEditRouterContext ctx(_prim, SdfFieldKeys->Payload);

primPayloads.AddPayload(payload, _listPos);
} else {
SdfReference ref(_filePath, primPath);
UsdReferences primRefs = _prim.GetReferences();

PrimMetadataEditRouterContext ctx(_prim, SdfFieldKeys->References);

primRefs.AddReference(ref, _listPos);
}
}
Expand Down
4 changes: 4 additions & 0 deletions lib/usdUfe/ufe/UsdUndoClearPayloadsCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#include "UsdUndoClearPayloadsCommand.h"

#include <usdUfe/utils/editRouterContext.h>

#include <pxr/usd/usd/payloads.h>

namespace USDUFE_NS_DEF {
Expand All @@ -32,6 +34,8 @@ void UsdUndoClearPayloadsCommand::executeImplementation()
if (!_prim.IsValid())
return;

PrimMetadataEditRouterContext ctx(_prim, SdfFieldKeys->Payload);

_prim.GetPayloads().ClearPayloads();
}

Expand Down
4 changes: 4 additions & 0 deletions lib/usdUfe/ufe/UsdUndoClearReferencesCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

#include "UsdUndoClearReferencesCommand.h"

#include <usdUfe/utils/editRouterContext.h>

#include <pxr/usd/usd/references.h>

namespace USDUFE_NS_DEF {
Expand All @@ -32,6 +34,8 @@ void UsdUndoClearReferencesCommand::executeImplementation()
if (!_prim.IsValid())
return;

PrimMetadataEditRouterContext ctx(_prim, SdfFieldKeys->References);

_prim.GetReferences().ClearReferences();
}

Expand Down
9 changes: 7 additions & 2 deletions lib/usdUfe/ufe/UsdUndoClearSceneItemMetadataCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include <usdUfe/base/tokens.h>
#include <usdUfe/ufe/Utils.h>
#include <usdUfe/utils/editRouter.h>
#include <usdUfe/utils/editRouterContext.h>

#include <pxr/base/tf/diagnostic.h>
#include <pxr/base/tf/token.h>
Expand Down Expand Up @@ -52,7 +54,9 @@ void ClearSceneItemMetadataCommand::executeImplementation()
const PXR_NS::UsdPrim prim = _stage->GetPrimAtPath(_primPath);
if (_group.empty()) {
// If this is not a grouped meta data, remove the key
prim.ClearCustomDataByKey(TfToken(_key));
PXR_NS::TfToken key(_key);
PrimMetadataEditRouterContext ctx(prim, SdfFieldKeys->CustomData, key);
prim.ClearCustomDataByKey(key);
} else {
// When the group name starts with "SessionLayer-", remove that prefix
// and clear in the session layer.
Expand All @@ -62,7 +66,8 @@ void ClearSceneItemMetadataCommand::executeImplementation()
PXR_NS::TfToken fullKey(prefixlessGroupName + std::string(":") + _key);
prim.ClearCustomDataByKey(fullKey);
} else {
PXR_NS::TfToken fullKey(_group + std::string(":") + _key);
PXR_NS::TfToken fullKey(_group + std::string(":") + _key);
PrimMetadataEditRouterContext ctx(prim, SdfFieldKeys->CustomData, fullKey);
prim.ClearCustomDataByKey(fullKey);
}
}
Expand Down
4 changes: 4 additions & 0 deletions lib/usdUfe/ufe/UsdUndoSetKindCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include <usdUfe/undo/UsdUndoBlock.h>

#include <usdUfe/utils/editRouterContext.h>

#include <pxr/base/tf/token.h>
#include <pxr/usd/usd/modelAPI.h>
#include <pxr/usd/usd/prim.h>
Expand Down Expand Up @@ -52,6 +54,8 @@ void UsdUndoSetKindCommand::execute()
{
UsdUndoBlock undoBlock(&_undoableItem);

PrimMetadataEditRouterContext ctx(_prim, PXR_NS::SdfFieldKeys->Kind);

PXR_NS::UsdModelAPI(_prim).SetKind(_kind);
}

Expand Down
9 changes: 7 additions & 2 deletions lib/usdUfe/ufe/UsdUndoSetSceneItemMetadataCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include <usdUfe/base/tokens.h>
#include <usdUfe/ufe/Utils.h>
#include <usdUfe/utils/editRouter.h>
#include <usdUfe/utils/editRouterContext.h>

#include <pxr/base/tf/token.h>
#include <pxr/base/vt/value.h>
Expand Down Expand Up @@ -63,9 +65,11 @@ SetSceneItemMetadataCommand::SetSceneItemMetadataCommand(
void SetSceneItemMetadataCommand::setKeyMetadata()
{
const PXR_NS::UsdPrim prim = _stage->GetPrimAtPath(_primPath);
const PXR_NS::TfToken key(_key);

// If this is not a grouped metadata, set the _value directly on the _key
prim.SetCustomDataByKey(TfToken(_key), ufeValueToVtValue(_value));
PrimMetadataEditRouterContext ctx(prim, PXR_NS::SdfFieldKeys->CustomData, key);
prim.SetCustomDataByKey(key, ufeValueToVtValue(_value));
}

void SetSceneItemMetadataCommand::setGroupMetadata()
Expand All @@ -80,7 +84,8 @@ void SetSceneItemMetadataCommand::setGroupMetadata()
PXR_NS::TfToken fullKey(prefixlessGroupName + std::string(":") + _key);
jufrantz marked this conversation as resolved.
Show resolved Hide resolved
prim.SetCustomDataByKey(fullKey, ufeValueToVtValue(_value));
} else {
PXR_NS::TfToken fullKey(_group + std::string(":") + _key);
PXR_NS::TfToken fullKey(_group + std::string(":") + _key);
PrimMetadataEditRouterContext ctx(prim, PXR_NS::SdfFieldKeys->CustomData, fullKey);
prim.SetCustomDataByKey(fullKey, ufeValueToVtValue(_value));
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/usdUfe/ufe/UsdUndoToggleActiveCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <usdUfe/ufe/UfeNotifGuard.h>
#include <usdUfe/ufe/Utils.h>
#include <usdUfe/utils/editRouterContext.h>

namespace USDUFE_NS_DEF {

Expand All @@ -38,6 +39,8 @@ void UsdUndoToggleActiveCommand::executeImplementation()
if (!prim.IsValid())
return;

PrimMetadataEditRouterContext ctx(prim, PXR_NS::SdfFieldKeys->Active);

std::string errMsg;
if (!UsdUfe::isPrimMetadataEditAllowed(
prim, PXR_NS::SdfFieldKeys->Active, PXR_NS::TfToken(), &errMsg)) {
Expand Down
3 changes: 3 additions & 0 deletions lib/usdUfe/ufe/UsdUndoToggleInstanceableCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "UsdUndoToggleInstanceableCommand.h"

#include <usdUfe/ufe/Utils.h>
#include <usdUfe/utils/editRouterContext.h>

namespace USDUFE_NS_DEF {

Expand All @@ -39,6 +40,8 @@ void UsdUndoToggleInstanceableCommand::executeImplementation()
if (!prim.IsValid())
return;

PrimMetadataEditRouterContext ctx(prim, PXR_NS::SdfFieldKeys->Instanceable);

std::string errMsg;
if (!UsdUfe::isPrimMetadataEditAllowed(
prim, PXR_NS::SdfFieldKeys->Instanceable, PXR_NS::TfToken(), &errMsg)) {
Expand Down
32 changes: 32 additions & 0 deletions lib/usdUfe/utils/editRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,38 @@ getAttrEditRouterLayer(const PXR_NS::UsdPrim& prim, const PXR_NS::TfToken& attrN
return _extractLayer(found->second);
}

PXR_NS::SdfLayerHandle getPrimMetadataEditRouterLayer(
const PXR_NS::UsdPrim& prim,
const PXR_NS::TfToken& metadataName,
const PXR_NS::TfToken& metadataKeyPath)
{
static const PXR_NS::TfToken metadataOp(EditRoutingTokens->RoutePrimMetadata);

const EditRouter::Ptr dstEditRouter = getEditRouter(metadataOp);
if (!dstEditRouter)
return nullptr;

// Optimize the case where we have a per-stage layer routing.
// This avoid creating dictionaries just to pass and receive a value.
if (auto layerRouter = std::dynamic_pointer_cast<LayerPerStageEditRouter>(dstEditRouter))
return layerRouter->getLayerForStage(prim.GetStage());

PXR_NS::VtDictionary context;
PXR_NS::VtDictionary routingData;
context[EditRoutingTokens->Prim] = PXR_NS::VtValue(prim);
context[EditRoutingTokens->Operation] = metadataOp;
context[EditRoutingTokens->KeyPath] = PXR_NS::VtValue(metadataKeyPath);
context[metadataOp] = PXR_NS::VtValue(metadataName);
(*dstEditRouter)(context, routingData);

// Try to retrieve the layer from the routing data.
const auto found = routingData.find(EditRoutingTokens->Layer);
if (found == routingData.end())
return nullptr;

return _extractLayer(found->second);
}

PXR_NS::UsdEditTarget
getEditRouterEditTarget(const PXR_NS::TfToken& operation, const PXR_NS::UsdPrim& prim)
{
Expand Down
8 changes: 8 additions & 0 deletions lib/usdUfe/utils/editRouter.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ USDUFE_PUBLIC
PXR_NS::SdfLayerHandle
getAttrEditRouterLayer(const PXR_NS::UsdPrim& prim, const PXR_NS::TfToken& attrName);

// Retrieve the layer for the prim metadata operation. If no edit router for the
// "primMetadata" operation is found, a nullptr is returned.
USDUFE_PUBLIC
PXR_NS::SdfLayerHandle getPrimMetadataEditRouterLayer(
const PXR_NS::UsdPrim& prim,
const PXR_NS::TfToken& metadataName,
const PXR_NS::TfToken& metadataKeyPath);

// Utility function that returns a UsdEditTarget for the argument operation.
// If no edit router exists for that operation, a null UsdEditTarget is returned.
// The edit router is given the prim in the context with key "prim", and is
Expand Down
Loading