Skip to content

Commit

Permalink
Fix issue discovered while testing.
Browse files Browse the repository at this point in the history
Geometries that had their own material scope, when duplicated, would lose
their shading because connections deep in the hierarchy were considered
external. Fixed the external check.
  • Loading branch information
JGamache-autodesk committed Nov 4, 2022
1 parent b524492 commit 0cc1d0b
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 61 deletions.
3 changes: 2 additions & 1 deletion lib/mayaUsd/ufe/UsdUndoDuplicateSelectionCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ bool UsdUndoDuplicateSelectionCommand::updateSdfPathVector(
for (; itPath != endPath; ++itPath) {
if (*itPath == duplicatePair) {
// That one was correctly processed by USD when duplicating.
isExternalPath = !finalPath.HasPrefix(itPath->first);
isExternalPath
= !finalPath.HasPrefix(itPath->first) && !finalPath.HasPrefix(itPath->second);
continue;
}
finalPath = finalPath.ReplacePrefix(itPath->first, itPath->second);
Expand Down
37 changes: 37 additions & 0 deletions test/lib/ufe/testBatchOpsHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,43 @@ def checkState2(self, expectedF3t):

checkState2(self, expectedF3t)

def testMeshWithEncapsulatedMaterial(self):
"""Duplicate is a complex operation. Test an issue that was found out while debugging:
Connections on shaders deep in the hierarchy were losing their connections."""
# Load a scene.
testFile = testUtils.getTestScene('MaterialX', 'BatchOpsTestScene.usda')
shapeNode,shapeStage = mayaUtils.createProxyFromFile(testFile)

geomItem = ufeUtils.createUfeSceneItem(shapeNode, '/pPlane2')
self.assertIsNotNone(geomItem)

batchOpsHandler = ufe.RunTimeMgr.instance().batchOpsHandler(geomItem.runTimeId())
self.assertIsNotNone(batchOpsHandler)

sel = ufe.Selection()
sel.append(geomItem)

cmd = batchOpsHandler.duplicateSelection(sel, {"inputConnections": False})
cmd.execute()

def checkStatus(self, cmd, feomItem):
stage = usdUtils.getPrimFromSceneItem(geomItem).GetStage()
ss2 = UsdShade.Shader(stage.GetPrimAtPath(Sdf.Path("/pPlane7/mtl/ss2SG/ss2")))
self.assertTrue(ss2.GetPrim().IsValid())
base_color = ss2.GetInput("base_color")
self.assertEqual(base_color.GetAttr().GetPath(), Sdf.Path("/pPlane7/mtl/ss2SG/ss2.inputs:base_color"))
self.assertTrue(base_color.HasConnectedSource())
connection = base_color.GetConnectedSources()[0][0]
self.assertEqual(connection.sourceName, "baseColor")
self.assertEqual(connection.source.GetPath(), Sdf.Path("/pPlane7/mtl/ss2SG/MayaNG_ss2SG"))

checkStatus(self, cmd, geomItem)

cmd.undo()
cmd.redo()

checkStatus(self, cmd, geomItem)


if __name__ == '__main__':
unittest.main(verbosity=2)
122 changes: 62 additions & 60 deletions test/testSamples/MaterialX/BatchOpsTestScene.usda
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def Mesh "pPlane2" (
float3[] extent = [(-0.5, 0, -0.5), (0.5, 0, 0.5)]
int[] faceVertexCounts = [4]
int[] faceVertexIndices = [0, 1, 3, 2]
rel material:binding = </mtl/ss2SG>
rel material:binding = </pPlane2/mtl/ss2SG>
normal3f[] normals = [(0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0)] (
interpolation = "faceVarying"
)
Expand All @@ -71,6 +71,66 @@ def Mesh "pPlane2" (
uniform token subdivisionScheme = "none"
double3 xformOp:translate = (-1.5, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate"]

def Scope "mtl" {
def Material "ss2SG" (
kind = "assembly"
)
{
string inputs:file2:varname = "st"
token outputs:mtlx:surface.connect = </pPlane2/mtl/ss2SG/ss2.outputs:out>

def Shader "ss2"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
float inputs:base = 1
color3f inputs:base_color.connect = </pPlane2/mtl/ss2SG/MayaNG_ss2SG.outputs:baseColor>
float inputs:specular = 1
float inputs:specular_roughness = 0.2
token outputs:out
}

def NodeGraph "MayaNG_ss2SG"
{
string inputs:file2:varname.connect = </pPlane2/mtl/ss2SG.inputs:file2:varname>
color3f outputs:baseColor.connect = </pPlane2/mtl/ss2SG/MayaNG_ss2SG/MayaConvert_file2_MayafileTexture.outputs:out>

def Shader "file2"
{
uniform token info:id = "ND_image_color4"
asset inputs:file = @textures/normalSpiralA.png@
string inputs:filtertype = "cubic"
float2 inputs:texcoord.connect = </pPlane2/mtl/ss2SG/MayaNG_ss2SG/place2dTexture2.outputs:out>
string inputs:uaddressmode = "periodic"
string inputs:vaddressmode = "periodic"
color4f outputs:out
}

def Shader "file2_MayafileTexture"
{
uniform token info:id = "MayaND_fileTexture_color4"
color4f inputs:defaultColor = (0.5, 0.5, 0.5, 1)
color4f inputs:inColor.connect = </pPlane2/mtl/ss2SG/MayaNG_ss2SG/file2.outputs:out>
color4f inputs:uvCoord.connect = </pPlane2/mtl/ss2SG/MayaNG_ss2SG/place2dTexture2.outputs:out>
color4f outputs:outColor
}

def Shader "MayaConvert_file2_MayafileTexture"
{
uniform token info:id = "ND_convert_color4_color3"
color4f inputs:in.connect = </pPlane2/mtl/ss2SG/MayaNG_ss2SG/file2_MayafileTexture.outputs:outColor>
color3f outputs:out
}

def Shader "place2dTexture2"
{
uniform token info:id = "ND_geompropvalue_vector2"
string inputs:geomprop.connect = </pPlane2/mtl/ss2SG/MayaNG_ss2SG.inputs:file2:varname>
float2 outputs:out
}
}
}
}
}

def Mesh "pPlane3" (
Expand Down Expand Up @@ -117,7 +177,7 @@ def Mesh "pPlane4" (
float3[] extent = [(-0.5, 0, -0.5), (0.5, 0, 0.5)]
int[] faceVertexCounts = [4]
int[] faceVertexIndices = [0, 1, 3, 2]
rel material:binding = </mtl/ss2SG>
rel material:binding = </pPlane2/mtl/ss2SG>
normal3f[] normals = [(0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0)] (
interpolation = "faceVarying"
)
Expand Down Expand Up @@ -214,64 +274,6 @@ def Mesh "pPlane6" (
}

def Scope "mtl" {
def Material "ss2SG" (
kind = "assembly"
)
{
string inputs:file2:varname = "st"
token outputs:mtlx:surface.connect = </mtl/ss2SG/ss2.outputs:out>

def Shader "ss2"
{
uniform token info:id = "ND_standard_surface_surfaceshader"
float inputs:base = 1
color3f inputs:base_color.connect = </mtl/ss2SG/MayaNG_ss2SG.outputs:baseColor>
float inputs:specular = 1
float inputs:specular_roughness = 0.2
token outputs:out
}

def NodeGraph "MayaNG_ss2SG"
{
string inputs:file2:varname.connect = </mtl/ss2SG.inputs:file2:varname>
color3f outputs:baseColor.connect = </mtl/ss2SG/MayaNG_ss2SG/MayaConvert_file2_MayafileTexture.outputs:out>

def Shader "file2"
{
uniform token info:id = "ND_image_color4"
asset inputs:file = @textures/normalSpiralA.png@
string inputs:filtertype = "cubic"
float2 inputs:texcoord.connect = </mtl/ss2SG/MayaNG_ss2SG/place2dTexture2.outputs:out>
string inputs:uaddressmode = "periodic"
string inputs:vaddressmode = "periodic"
color4f outputs:out
}

def Shader "file2_MayafileTexture"
{
uniform token info:id = "MayaND_fileTexture_color4"
color4f inputs:defaultColor = (0.5, 0.5, 0.5, 1)
color4f inputs:inColor.connect = </mtl/ss2SG/MayaNG_ss2SG/file2.outputs:out>
color4f inputs:uvCoord.connect = </mtl/ss2SG/MayaNG_ss2SG/place2dTexture2.outputs:out>
color4f outputs:outColor
}

def Shader "MayaConvert_file2_MayafileTexture"
{
uniform token info:id = "ND_convert_color4_color3"
color4f inputs:in.connect = </mtl/ss2SG/MayaNG_ss2SG/file2_MayafileTexture.outputs:outColor>
color3f outputs:out
}

def Shader "place2dTexture2"
{
uniform token info:id = "ND_geompropvalue_vector2"
string inputs:geomprop.connect = </mtl/ss2SG/MayaNG_ss2SG.inputs:file2:varname>
float2 outputs:out
}
}
}

def Material "ss3SG" (
kind = "assembly"
)
Expand Down

0 comments on commit 0cc1d0b

Please sign in to comment.