-
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
MAYA-127483 - Deleting a connection does not delete source and destination properties. #2852
Changes from 1 commit
ebcdb64
d83a905
9f6cbdc
cd6dbdd
373c3db
a27a9bc
d8dd340
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 |
---|---|---|
|
@@ -284,6 +284,139 @@ UsdUndoDeleteConnectionCommand::Ptr UsdUndoDeleteConnectionCommand::create( | |
return std::make_shared<UsdUndoDeleteConnectionCommand>(srcAttr, dstAttr); | ||
} | ||
|
||
bool canRemoveSrcProperty(const PXR_NS::UsdAttribute& srcAttr) | ||
{ | ||
|
||
// Do not remove if it has a value. | ||
if (srcAttr.HasValue()) { | ||
return false; | ||
} | ||
|
||
PXR_NS::SdfPathVector connectedAttrs; | ||
srcAttr.GetConnections(&connectedAttrs); | ||
|
||
// Do not remove if it has connections. | ||
if (!connectedAttrs.empty()) { | ||
return false; | ||
} | ||
|
||
const auto prim = srcAttr.GetPrim(); | ||
|
||
if (!prim) { | ||
return false; | ||
} | ||
|
||
const auto primParent = prim.GetParent(); | ||
|
||
if (!primParent) { | ||
return false; | ||
} | ||
|
||
// Do not remove if there is a connection with a prim. | ||
for (const auto& childPrim : primParent.GetChildren()) { | ||
if (childPrim != prim) { | ||
for (const auto& attribute : childPrim.GetAttributes()) { | ||
const PXR_NS::UsdAttribute dstUsdAttr = attribute.As<PXR_NS::UsdAttribute>(); | ||
if (isConnected(srcAttr, dstUsdAttr)) { | ||
return false; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Do not remove if there is a connection with the parent prim. | ||
for (const auto& attribute : primParent.GetAttributes()) { | ||
const PXR_NS::UsdAttribute dstUsdAttr = attribute.As<PXR_NS::UsdAttribute>(); | ||
if (isConnected(srcAttr, dstUsdAttr)) { | ||
return false; | ||
} | ||
} | ||
|
||
PXR_NS::UsdShadeNodeGraph ngPrim(prim); | ||
|
||
if (!ngPrim) { | ||
return true; | ||
} | ||
|
||
// Do not remove if there is a connection with a child prim. | ||
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. There is a very useful workflow where you drag the first port of the type you want on the boundary, and connect it to the input node as many times as desired, then delete the connections. 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. Thank you. I didn't know about this workflow. I've also reintroduced the condition for the |
||
for (const auto& childPrim : prim.GetChildren()) { | ||
for (const auto& attribute : childPrim.GetAttributes()) { | ||
const PXR_NS::UsdAttribute dstUsdAttr = attribute.As<PXR_NS::UsdAttribute>(); | ||
if (isConnected(srcAttr, dstUsdAttr)) { | ||
return false; | ||
} | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool canRemoveDstProperty(const PXR_NS::UsdAttribute& srcAttr) | ||
{ | ||
// Do not remove if it has a value. | ||
if (srcAttr.HasValue()) { | ||
return false; | ||
} | ||
|
||
PXR_NS::SdfPathVector connectedAttrs; | ||
srcAttr.GetConnections(&connectedAttrs); | ||
|
||
// Do not remove if it has connections. | ||
if (!connectedAttrs.empty()) { | ||
return false; | ||
} | ||
|
||
const auto prim = srcAttr.GetPrim(); | ||
|
||
if (!prim) { | ||
return false; | ||
} | ||
|
||
PXR_NS::UsdShadeNodeGraph ngPrim(prim); | ||
|
||
if (!ngPrim) { | ||
return true; | ||
} | ||
|
||
// Do not remove if there is a connection with a child prim. | ||
for (const auto& childPrim : prim.GetChildren()) { | ||
for (const auto& attribute : childPrim.GetAttributes()) { | ||
const PXR_NS::UsdAttribute dstUsdAttr = attribute.As<PXR_NS::UsdAttribute>(); | ||
if (isConnected(srcAttr, dstUsdAttr)) { | ||
return false; | ||
} | ||
} | ||
} | ||
|
||
const auto primParent = prim.GetParent(); | ||
|
||
if (!primParent) { | ||
return false; | ||
} | ||
|
||
// Do not remove if there is a connection with the parent prim. | ||
for (const auto& attribute : primParent.GetAttributes()) { | ||
const PXR_NS::UsdAttribute dstUsdAttr = attribute.As<PXR_NS::UsdAttribute>(); | ||
if (isConnected(srcAttr, dstUsdAttr)) { | ||
return false; | ||
} | ||
} | ||
|
||
// Do not remove if there is a connection with a prim. | ||
for (const auto& childPrim : primParent.GetChildren()) { | ||
if (childPrim != prim) { | ||
for (const auto& attribute : childPrim.GetAttributes()) { | ||
const PXR_NS::UsdAttribute dstUsdAttr = attribute.As<PXR_NS::UsdAttribute>(); | ||
if (isConnected(srcAttr, dstUsdAttr)) { | ||
return false; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
void UsdUndoDeleteConnectionCommand::execute() | ||
{ | ||
UsdUndoBlock undoBlock(&_undoableItem); | ||
|
@@ -312,19 +445,12 @@ void UsdUndoDeleteConnectionCommand::execute() | |
// Remove attribute if it does not have a value, default value, or time samples. We do this | ||
// on Shader nodes and on the Material outputs since they are re-created automatically. | ||
// Other NodeGraph inputs and outputs require explicit removal. | ||
if (!dstUsdAttr->usdAttribute().HasValue()) { | ||
UsdShadeShader asShader(dstUsdAttr->usdPrim()); | ||
if (asShader) { | ||
dstUsdAttr->usdPrim().RemoveProperty(dstUsdAttr->usdAttribute().GetName()); | ||
} | ||
UsdShadeMaterial asMaterial(dstUsdAttr->usdPrim()); | ||
if (asMaterial) { | ||
const TfToken baseName = dstUsdAttr->usdAttribute().GetBaseName(); | ||
if (baseName == UsdShadeTokens->surface || baseName == UsdShadeTokens->volume | ||
|| baseName == UsdShadeTokens->displacement) { | ||
dstUsdAttr->usdPrim().RemoveProperty(dstUsdAttr->usdAttribute().GetName()); | ||
} | ||
} | ||
if (canRemoveDstProperty(dstUsdAttr->usdAttribute())) { | ||
dstUsdAttr->usdPrim().RemoveProperty(dstUsdAttr->usdAttribute().GetName()); | ||
} | ||
|
||
if (canRemoveSrcProperty(srcUsdAttr->usdAttribute())) { | ||
srcUsdAttr->usdPrim().RemoveProperty(srcUsdAttr->usdAttribute().GetName()); | ||
} | ||
} | ||
|
||
|
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.
I think this helper function (and the one below) should be in the unnamed namespace near the top of this file (with the other helper functions).
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.
Could I move them to
mayaUsd/ufe/Utils.h
? I need them also for other issues I'm working on.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.
Yes that is a good idea.
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.
I moved also the
isConnected
function since it is used bycanRemoveSrcProperty
andcanRemoveDstProperty
, I also need it for the issues I'm working on.