Skip to content

Commit

Permalink
MAYA-127484 - Delete src and dst properties when deleting compound at…
Browse files Browse the repository at this point in the history
…tribute.
  • Loading branch information
alicedegirolamo committed Feb 22, 2023
1 parent 3850545 commit 2193047
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 29 deletions.
53 changes: 25 additions & 28 deletions lib/mayaUsd/ufe/UsdAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,36 +455,33 @@ bool UsdAttributes::canRemoveAttribute(const UsdSceneItem::Ptr& item, const std:
}
return false;
}

static void removeConnections(const PXR_NS::UsdPrim& prim, const PXR_NS::SdfPath& srcPropertyPath)
static void removeConnections(PXR_NS::UsdPrim& prim, const PXR_NS::UsdAttribute& srcUsdAttr)
{
// Remove the connections with source srcPropertyPath.
// Remove the connections with source srcUsdAttr.
for (const auto& attribute : prim.GetAttributes()) {
PXR_NS::UsdAttribute attr = attribute.As<PXR_NS::UsdAttribute>();
PXR_NS::SdfPathVector sources;
attr.GetConnections(&sources);
PXR_NS::UsdAttribute dstUsdAttr = attribute.As<PXR_NS::UsdAttribute>();

for (size_t i = 0; i < sources.size(); ++i) {
if (sources[i] == srcPropertyPath) {
attr.RemoveConnection(srcPropertyPath);
// Check if we can remove also the property.
if (MayaUsd::ufe::isConnected(srcUsdAttr, dstUsdAttr)) {
UsdShadeConnectableAPI::DisconnectSource(dstUsdAttr, srcUsdAttr);
// Check if we can remove the property.
if (MayaUsd::ufe::canRemoveDstProperty(dstUsdAttr)) {
// Remove the property.
break;
prim.RemoveProperty(dstUsdAttr.GetName());
}
}
}
}

static void
removeAllChildrenConnections(const PXR_NS::UsdPrim& prim, const PXR_NS::SdfPath& srcPropertyPath)
removeAllChildrenConnections(const PXR_NS::UsdPrim& prim, const PXR_NS::UsdAttribute& srcUsdAttr)
{
// Remove the connections with source srcPropertyPath for all the children.
for (const auto& childPrim : prim.GetChildren()) {
removeConnections(childPrim, srcPropertyPath);
// Remove the connections with source srcUsdAttr for all the children.
for (auto&& usdChild : prim.GetChildren()) {
removeConnections(usdChild, srcUsdAttr);
}
}

static void removeShadeNodeGraphConnections(const PXR_NS::UsdAttribute& attr)
static void removeNodeGraphConnections(const PXR_NS::UsdAttribute& attr)
{
const auto prim = attr.GetPrim();

Expand All @@ -499,7 +496,7 @@ static void removeShadeNodeGraphConnections(const PXR_NS::UsdAttribute& attr)
return;
}

const auto primParent = prim.GetParent();
auto primParent = prim.GetParent();

if (!primParent) {
return;
Expand All @@ -517,7 +514,7 @@ static void removeShadeNodeGraphConnections(const PXR_NS::UsdAttribute& attr)

if (!sourcesInfo.empty()) {
// The attribute is the connection destination.
const PXR_NS::UsdPrim connectedPrim = sourcesInfo[0].source.GetPrim();
PXR_NS::UsdPrim connectedPrim = sourcesInfo[0].source.GetPrim();

if (connectedPrim) {
const std::string prefix = connectedPrim == primParent
Expand All @@ -532,22 +529,22 @@ static void removeShadeNodeGraphConnections(const PXR_NS::UsdAttribute& attr)

if (srcAttr) {
UsdShadeConnectableAPI::DisconnectSource(attr, srcAttr);
// Check if we can remove also the property.
// Remove the property.
// Check if we can remove the property.
if (MayaUsd::ufe::canRemoveSrcProperty(srcAttr)) {
// Remove the property.
connectedPrim.RemoveProperty(srcAttr.GetName());
}
}
}
}

const SdfPath kPrimPath = prim.GetPath();
const SdfPath kPropertyPath = kPrimPath.AppendProperty(attr.GetName());

if (baseNameAndType.second == PXR_NS::UsdShadeAttributeType::Output) {
removeAllChildrenConnections(primParent, kPropertyPath);
removeConnections(primParent, kPropertyPath);
removeAllChildrenConnections(primParent, attr);
removeConnections(primParent, attr);
}

if (baseNameAndType.second == PXR_NS::UsdShadeAttributeType::Input) {
removeAllChildrenConnections(prim, kPropertyPath);
removeAllChildrenConnections(prim, attr);
}
}

Expand All @@ -569,14 +566,14 @@ bool UsdAttributes::doRemoveAttribute(const UsdSceneItem::Ptr& item, const std::
if (baseNameAndType.second == PXR_NS::UsdShadeAttributeType::Output) {
auto output = connectApi.GetOutput(baseNameAndType.first);
if (output) {
removeShadeNodeGraphConnections(attribute);
removeNodeGraphConnections(attribute);
connectApi.ClearSources(output);
return prim.RemoveProperty(nameAsToken);
}
} else if (baseNameAndType.second == PXR_NS::UsdShadeAttributeType::Input) {
auto input = connectApi.GetInput(baseNameAndType.first);
if (input) {
removeShadeNodeGraphConnections(attribute);
removeNodeGraphConnections(attribute);
connectApi.ClearSources(input);
return prim.RemoveProperty(nameAsToken);
}
Expand Down
30 changes: 29 additions & 1 deletion test/lib/ufe/testAttributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ def testRemoveCompoundAttribute(self):
# 1. Remove an output compound attribute.

# 1.1 Remove an output compound attribute connected to prim and child prim.

cmd = compound1Attrs.removeAttributeCmd("outputs:baseColor")
self.assertIsNotNone(cmd)

Expand All @@ -241,7 +242,16 @@ def testRemoveCompoundAttribute(self):
conns = connections.allConnections()
self.assertEqual(len(conns), 1)

# Test we removed the properties.
mayaSwizzlePrim = usdUtils.getPrimFromSceneItem(ufeItemMayaSwizzle)
self.assertIsNotNone(mayaSwizzlePrim)
self.assertFalse(mayaSwizzlePrim.HasProperty('outputs:out'))
standardSurface2Prim = usdUtils.getPrimFromSceneItem(ufeItemStandardSurface2)
self.assertIsNotNone(standardSurface2Prim)
self.assertFalse(standardSurface2Prim.HasProperty('inputs:base_color'))

# 1.2 Remove an output compound attribute connected to parent prim.

cmd = compound2Attrs.removeAttributeCmd("outputs:out")
self.assertIsNotNone(cmd)

Expand All @@ -253,13 +263,26 @@ def testRemoveCompoundAttribute(self):
ufeItemParent = ufeUtils.createUfeSceneItem(shapeNode,
"/pCube2/Looks/standardSurface2SG")
self.assertIsNotNone(ufeItemParent)
ufeItemSurface = ufeUtils.createUfeSceneItem(shapeNode,
"/pCube2/Looks/standardSurface2SG/NodeGraph1/surface1")
self.assertIsNotNone(ufeItemSurface)

connections = connectionHandler.sourceConnections(ufeItemParent)
conns = connections.allConnections()
self.assertEqual(len(conns), 1)

# Test we removed the properties.
surfacePrim = usdUtils.getPrimFromSceneItem(ufeItemSurface)
self.assertIsNotNone(surfacePrim)
self.assertFalse(surfacePrim.HasProperty('outputs:out'))
parentPrim = usdUtils.getPrimFromSceneItem(ufeItemParent)
self.assertIsNotNone(parentPrim)
self.assertTrue(parentPrim.HasProperty('outputs:out'))

# 2. Remove an input compound attribute.

# 2.1 Remove an input compound attribute connected to parent and child prim.

cmd = compound1Attrs.removeAttributeCmd("inputs:file2:varnameStr")
self.assertIsNotNone(cmd)

Expand All @@ -268,7 +291,6 @@ def testRemoveCompoundAttribute(self):
self.assertNotIn("inputs:file2:varnameStr", compound1Attrs.attributeNames)

# Test we removed the connection.

ufeItemTexture = ufeUtils.createUfeSceneItem(shapeNode,
"/pCube2/Looks/standardSurface2SG/MayaNG_standardSurface2SG/place2dTexture2")
self.assertIsNotNone(ufeItemTexture)
Expand All @@ -281,6 +303,12 @@ def testRemoveCompoundAttribute(self):
conns = connections.allConnections()
self.assertEqual(len(conns), 1)

# Test we removed the properties.
texturePrim = usdUtils.getPrimFromSceneItem(ufeItemTexture)
self.assertIsNotNone(texturePrim)
self.assertFalse(texturePrim.HasProperty('inputs:geomprop'))
self.assertTrue(parentPrim.HasProperty('inputs:file2:varnameStr'))

@unittest.skipIf(os.getenv('UFE_PREVIEW_VERSION_NUM', '0000') < '4024', 'Test for UFE preview version 0.4.24 and later')
def testUniqueNameAttribute(self):
'''Test unique name attribute'''
Expand Down

0 comments on commit 2193047

Please sign in to comment.