-
Notifications
You must be signed in to change notification settings - Fork 202
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
Improve rename logics #483
Changes from all commits
ae2a7e0
bb1da2e
c4f247a
a45779c
b207895
890372d
a305af9
610f2ce
80aa35e
3cf2acc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,36 +42,39 @@ namespace ufe { | |
|
||
UsdUndoRenameCommand::UsdUndoRenameCommand(const UsdSceneItem::Ptr& srcItem, const Ufe::PathComponent& newName) | ||
: Ufe::UndoableCommand() | ||
, _ufeSrcItem(srcItem) | ||
, _ufeDstItem(nullptr) | ||
, _stage(_ufeSrcItem->prim().GetStage()) | ||
, _newName(newName.string()) | ||
{ | ||
const UsdPrim& prim = srcItem->prim(); | ||
_stage = prim.GetStage(); | ||
_ufeSrcItem = srcItem; | ||
_usdSrcPath = prim.GetPath(); | ||
|
||
// Every call to rename() (through execute(), undo() or redo()) removes | ||
// a prim, which becomes expired. Since USD UFE scene items contain a | ||
// prim, we must recreate them after every call to rename. | ||
_usdDstPath = prim.GetParent().GetPath().AppendChild(TfToken(newName.string())); | ||
|
||
_layer = MayaUsdUtils::defPrimSpecLayer(prim); | ||
if (!_layer) { | ||
std::string err = TfStringPrintf("No prim found at %s", prim.GetPath().GetString().c_str()); | ||
throw std::runtime_error(err.c_str()); | ||
} | ||
const UsdPrim& prim = _stage->GetPrimAtPath(_ufeSrcItem->prim().GetPath()); | ||
|
||
// if the current layer doesn't have any opinions that affects selected prim | ||
if (!MayaUsdUtils::doesEditTargetLayerHavePrimSpec(prim)) { | ||
auto possibleTargetLayer = MayaUsdUtils::strongestLayerWithPrimSpec(prim); | ||
// if the current layer doesn't have any contributions | ||
if (!MayaUsdUtils::doesEditTargetLayerContribute(prim)) { | ||
auto strongestContributingLayer = MayaUsdUtils::strongestContributingLayer(prim); | ||
std::string err = TfStringPrintf("Cannot rename [%s] defined on another layer. " | ||
"Please set [%s] as the target layer to proceed", | ||
prim.GetName().GetString().c_str(), | ||
possibleTargetLayer->GetDisplayName().c_str()); | ||
strongestContributingLayer->GetDisplayName().c_str()); | ||
throw std::runtime_error(err.c_str()); | ||
} | ||
else | ||
{ | ||
auto layers = MayaUsdUtils::layersWithPrimSpec(prim); | ||
// account for internal vs external references | ||
// internal references (references without a file path specified) from the same file | ||
// should be renamable. | ||
if (prim.HasAuthoredReferences()) { | ||
auto primSpec = MayaUsdUtils::getPrimSpecAtEditTarget(_stage, prim); | ||
|
||
if(!MayaUsdUtils::isInternalReference(primSpec)) { | ||
std::string err = TfStringPrintf("Unable to rename referenced object [%s]", | ||
prim.GetName().GetString().c_str()); | ||
throw std::runtime_error(err.c_str()); | ||
} | ||
} | ||
|
||
ppt-adsk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
auto layers = MayaUsdUtils::layersWithContribution(prim); | ||
// if we have more than 2 layers that contributes to the final composed prim | ||
if (layers.size() > 1) { | ||
std::string layerDisplayNames; | ||
for (auto layer : layers) { | ||
|
@@ -101,79 +104,53 @@ UsdSceneItem::Ptr UsdUndoRenameCommand::renamedItem() const | |
|
||
bool UsdUndoRenameCommand::renameRedo() | ||
{ | ||
// Copy the source path using CopySpec, and remove the source. | ||
|
||
// We use the source layer as the destination. An alternate workflow | ||
// would be the edit target layer be the destination: | ||
// _layer = _stage->GetEditTarget().GetLayer() | ||
bool status = SdfCopySpec(_layer, _usdSrcPath, _layer, _usdDstPath); | ||
if (status) { | ||
// remove all scene description for the given path and | ||
// its subtree in the current UsdEditTarget | ||
{ | ||
UsdEditContext ctx(_stage, _layer); | ||
status = _stage->RemovePrim(_ufeSrcItem->prim().GetPath()); | ||
} | ||
|
||
if (status) { | ||
// The renamed scene item is a "sibling" of its original name. | ||
_ufeDstItem = createSiblingSceneItem(_ufeSrcItem->path(), _usdDstPath.GetElementString()); | ||
const UsdPrim& prim = _stage->GetPrimAtPath(_ufeSrcItem->prim().GetPath()); | ||
|
||
sendRenameNotification(_ufeDstItem, _ufeSrcItem->path()); | ||
} | ||
auto primSpec = MayaUsdUtils::getPrimSpecAtEditTarget(_stage, prim); | ||
if(!primSpec) { | ||
return false; | ||
} | ||
else { | ||
UFE_LOG(std::string("Warning: SdfCopySpec(") + | ||
_usdSrcPath.GetString() + std::string(") failed.")); | ||
|
||
// set prim's name | ||
// XXX: SetName successfuly returns true but when you examine the _prim.GetName() | ||
// after the rename, the prim name shows the original name HS, 6-May-2020. | ||
bool status = primSpec->SetName(_newName); | ||
if (!status) { | ||
return false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do an early check for primSpec and SetName result. @ppt-adsk there is something troubling happening here which I am trying to understand: On Redo, I get the primspec for _prim object and rename it's name to the _newName. This operation return successful BUT when I query the _prim's name right after, I still get the _prim's original name. Huh??? I then set _ufeDstItem and when I print it's USD name and it gives me the _newName which is expected. |
||
|
||
return status; | ||
// the renamed scene item is a "sibling" of its original name. | ||
_ufeDstItem = createSiblingSceneItem(_ufeSrcItem->path(), _newName); | ||
sendRenameNotification(_ufeDstItem, _ufeSrcItem->path()); | ||
|
||
return true; | ||
ppt-adsk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
bool UsdUndoRenameCommand::renameUndo() | ||
{ | ||
// Copy the source path using CopySpec, and remove the source. | ||
bool status = SdfCopySpec(_layer, _usdDstPath, _layer, _usdSrcPath); | ||
|
||
if (status) { | ||
// remove all scene description for the given path and | ||
// its subtree in the current UsdEditTarget | ||
{ | ||
UsdEditContext ctx(_stage, _layer); | ||
status = _stage->RemovePrim(_usdDstPath); | ||
} | ||
const UsdPrim& prim = _stage->GetPrimAtPath(_ufeDstItem->prim().GetPath()); | ||
|
||
if (status) { | ||
// create a new prim at _usdSrcPath | ||
auto newPrim = _stage->DefinePrim(_usdSrcPath); | ||
|
||
#ifdef UFE_V2_FEATURES_AVAILABLE | ||
UFE_ASSERT_MSG(newPrim, "Invalid prim cannot be inactivated."); | ||
#else | ||
assert(newPrim); | ||
#endif | ||
auto primSpec = MayaUsdUtils::getPrimSpecAtEditTarget(_stage, prim); | ||
if(!primSpec) { | ||
return false; | ||
} | ||
|
||
// I shouldn't have to again create a sibling sceneItem here since we already have a valid _ufeSrcItem | ||
// however, I get random crashes if I don't which needs furthur investigation. HS, 6-May-2020. | ||
_ufeSrcItem = createSiblingSceneItem(_ufeDstItem->path(), _usdSrcPath.GetElementString()); | ||
// set prim's name | ||
bool status = primSpec->SetName(_ufeSrcItem->prim().GetName()); | ||
if (!status) { | ||
return false; | ||
} | ||
|
||
sendRenameNotification(_ufeSrcItem, _ufeDstItem->path()); | ||
// shouldn't have to again create a sibling sceneItem here since we already have a valid _ufeSrcItem | ||
// however, I get random crashes if I don't which needs furthur investigation. HS, 6-May-2020. | ||
_ufeSrcItem = createSiblingSceneItem(_ufeDstItem->path(), _ufeSrcItem->prim().GetName()); | ||
sendRenameNotification(_ufeSrcItem, _ufeDstItem->path()); | ||
|
||
_ufeDstItem = nullptr; | ||
} | ||
} | ||
else { | ||
UFE_LOG(std::string("Warning: SdfCopySpec(") + | ||
_usdDstPath.GetString() + std::string(") failed.")); | ||
} | ||
_ufeDstItem = nullptr; | ||
|
||
return status; | ||
return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Undo: |
||
} | ||
|
||
//------------------------------------------------------------------------------ | ||
// UsdUndoRenameCommand overrides | ||
//------------------------------------------------------------------------------ | ||
|
||
void UsdUndoRenameCommand::undo() | ||
{ | ||
// MAYA-92264: Pixar bug prevents undo from working. Try again with USD | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,22 +48,17 @@ class MAYAUSD_CORE_PUBLIC UsdUndoRenameCommand : public Ufe::UndoableCommand | |
UsdSceneItem::Ptr renamedItem() const; | ||
|
||
private: | ||
|
||
// UsdUndoRenameCommand overrides | ||
void undo() override; | ||
void redo() override; | ||
|
||
bool renameRedo(); | ||
bool renameUndo(); | ||
|
||
UsdStageWeakPtr _stage; | ||
SdfLayerHandle _layer; | ||
void undo() override; | ||
void redo() override; | ||
|
||
UsdSceneItem::Ptr _ufeSrcItem; | ||
SdfPath _usdSrcPath; | ||
|
||
UsdSceneItem::Ptr _ufeDstItem; | ||
SdfPath _usdDstPath; | ||
|
||
UsdStageWeakPtr _stage; | ||
std::string _newName; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Simplified member variables. We no longer need _usdSrcPath, _usdDstPath, and _layer. |
||
}; // UsdUndoRenameCommand | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,17 +29,25 @@ namespace MayaUsdUtils { | |
MAYA_USD_UTILS_PUBLIC | ||
SdfLayerHandle defPrimSpecLayer(const UsdPrim&); | ||
|
||
//! Return a list of layers in strength order that have opinions on the argument prim. | ||
//! Return a list of layers in no strength order that can contribute to the argument prim. | ||
MAYA_USD_UTILS_PUBLIC | ||
std::vector<SdfLayerHandle> layersWithPrimSpec(const UsdPrim&); | ||
std::set<SdfLayerHandle> layersWithContribution(const UsdPrim&); | ||
|
||
//! Check if a layer has any opinions that affects on the argument prim. | ||
//! Check if a layer has any contributions towards the argument prim. | ||
MAYA_USD_UTILS_PUBLIC | ||
bool doesEditTargetLayerHavePrimSpec(const UsdPrim&); | ||
bool doesEditTargetLayerContribute(const UsdPrim&); | ||
|
||
//! Return the strongest layer that has an opinion on the argument prim. | ||
//! Return the strongest layer that can contribute to the argument prim. | ||
MAYA_USD_UTILS_PUBLIC | ||
SdfLayerHandle strongestLayerWithPrimSpec(const UsdPrim&); | ||
SdfLayerHandle strongestContributingLayer(const UsdPrim&); | ||
|
||
//! Return a PrimSpec for the argument prim in the layer containing the stage's current edit target. | ||
MAYA_USD_UTILS_PUBLIC | ||
SdfPrimSpecHandle getPrimSpecAtEditTarget(UsdStageWeakPtr, const UsdPrim&); | ||
|
||
//! Returns true if the prim spec has an internal reference. | ||
MAYA_USD_UTILS_PUBLIC | ||
bool isInternalReference(const SdfPrimSpecHandle&); | ||
|
||
} // namespace MayaUsdUtils | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added a utility function for getting a PrimSpec from a prim path in the layer containing the stage's current edit target. |
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using initializer list.