Skip to content

Commit

Permalink
Adding unit test for AETemplate.
Browse files Browse the repository at this point in the history
  • Loading branch information
seando-adsk committed Aug 24, 2023
1 parent 50a1883 commit 52a4474
Show file tree
Hide file tree
Showing 2 changed files with 256 additions and 0 deletions.
1 change: 1 addition & 0 deletions test/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set(TEST_SCRIPT_FILES

# Interactive Unit test scripts.
set(INTERACTIVE_TEST_SCRIPT_FILES
testAttributeEditorTemplate.py
testMayaUsdInteractiveLayerEditorCommands.py
)

Expand Down
255 changes: 255 additions & 0 deletions test/lib/testAttributeEditorTemplate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
#!/usr/bin/env python

#
# Copyright 2023 Autodesk
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import unittest

import mayaUtils
import ufeUtils
import fixturesUtils
import testUtils

import mayaUsd.lib

from maya import cmds
from maya import standalone

from mayaUsdLibRegisterStrings import getMayaUsdLibString

from pxr import Usd

import ufe

class AttributeEditorTemplateTestCase(unittest.TestCase):

@classmethod
def setUpClass(cls):
fixturesUtils.readOnlySetUpClass(__file__, initializeStandalone=False)

def setUp(self):
cmds.file(new=True, force=True)
cmds.select(clear=True)

def searchForMayaControl(self, controlOrLayout, mayaControlCmd, labelToFind):
'''Helper function to search for a Maya control or layout with the label
matching the input string <p labelToFind>. The type of the control being
searched for is also given as input <p mayaControlCmd>.
'''
if mayaControlCmd(controlOrLayout, exists=True):
if mayaControlCmd(controlOrLayout, q=True, label=True) == labelToFind:
return controlOrLayout

if controlOrLayout:
childrenOfLayout = cmds.layout(controlOrLayout, q=True, ca=True)
if childrenOfLayout:
for child in childrenOfLayout:
child = controlOrLayout + '|' + child
if cmds.layout(child, exists=True):
foundControl = self.searchForMayaControl(child, mayaControlCmd, labelToFind)
if foundControl:
return foundControl
elif mayaControlCmd(child, exists=True):
if mayaControlCmd(child, q=True, label=True) == labelToFind:
return child
return None

def testAETemplate(self):
'''Simple test to check the Attribute Editor template has no scripting errors
which prevent it from being used. When that happens there is no layout in AE
for USD prims. All attributes are just listed one after another.'''

# Create a simple USD scene with a single prim.
cmds.file(new=True, force=True)

import mayaUsd_createStageWithNewLayer
proxyShape = mayaUsd_createStageWithNewLayer.createStageWithNewLayer()
proxyShapePath = ufe.PathString.path(proxyShape)
proxyShapeItem = ufe.Hierarchy.createItem(proxyShapePath)

# Create a Capsule via contextOps menu. The capsule is automatically
# selected by the 'Add New Prim', so the AE will be showing it.
proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem)
proxyShapeContextOps.doOp(['Add New Prim', 'Capsule'])

# Enable the display of Array Attributes.
cmds.optionVar(intValue=('mayaUSD_AEShowArrayAttributes', 1))

# Make sure the AE is visible.
import maya.mel
maya.mel.eval('openAEWindow')

# --------------------------------------------------------------------------------
# Test the 'buildUI' method of template.
# --------------------------------------------------------------------------------

# In the AE there is a formLayout for each USD prim type. We start
# by making sure we can find the one for capsule.
capsuleFormLayout = 'AttrEdUSDCapsuleFormLayout'
self.assertTrue(cmds.formLayout(capsuleFormLayout, exists=True))
startLayout = cmds.formLayout(capsuleFormLayout, query=True, fullPathName=True)
self.assertIsNotNone(startLayout, 'Could not get full path for Capsule formLayout')

# We should have a frameLayout called 'Capsule' in the template.
# If there is a scripting error in the template, this layout will be missing.
frameLayout = self.searchForMayaControl(startLayout, cmds.frameLayout, 'Capsule')
self.assertIsNotNone(frameLayout, 'Could not find Capsule frameLayout')

# We should also have float slider controls for 'Height' & 'Radius'.
heightControl = self.searchForMayaControl(frameLayout, cmds.floatSliderGrp, 'Height')
self.assertIsNotNone(heightControl, 'Could not find Capsule Height control')
radiusControl = self.searchForMayaControl(frameLayout, cmds.floatSliderGrp, 'Radius')
self.assertIsNotNone(radiusControl, 'Could not find Capsule Radius control')

# Since we enabled array attributes we should have an 'Extent' attribute.
extentControl = self.searchForMayaControl(frameLayout, cmds.text, 'Extent')
self.assertIsNotNone(extentControl, 'Could not find Capsule Extent control')

# --------------------------------------------------------------------------------
# Test the 'createMetadataSection' method of template.
# --------------------------------------------------------------------------------

# We should have a frameLayout called 'Metadata' in the template.
# If there is a scripting error in the template, this layout will be missing.
frameLayout = self.searchForMayaControl(startLayout, cmds.frameLayout, getMayaUsdLibString('kLabelMetadata'))
self.assertIsNotNone(frameLayout, 'Could not find Metadata frameLayout')

# Create a SphereLight via contextOps menu.
# This prim type has applied schemas and extra attributes.
proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem)
proxyShapeContextOps.doOp(['Add New Prim', 'SphereLight'])
maya.mel.eval('openAEWindow')

# Make sure we can find formLayout for the SphereLight.
lightFormLayout = 'AttrEdUSDSphereLightFormLayout'
self.assertTrue(cmds.formLayout(lightFormLayout, exists=True))
startLayout = cmds.formLayout(lightFormLayout, query=True, fullPathName=True)
self.assertIsNotNone(startLayout, 'Could not get full path for SphereLight formLayout')

# --------------------------------------------------------------------------------
# Test the 'createAppliedSchemasSection' method of template.
# Requires USD 0.21.2
# --------------------------------------------------------------------------------
if Usd.GetVersion() >= (0, 21, 2):
# We should have a frameLayout called 'Applied Schemas' in the template.
# If there is a scripting error in the template, this layout will be missing.
frameLayout = self.searchForMayaControl(startLayout, cmds.frameLayout, getMayaUsdLibString('kLabelAppliedSchemas'))
self.assertIsNotNone(frameLayout, 'Could not find Applied Schemas frameLayout')

# --------------------------------------------------------------------------------
# Test the 'createCustomExtraAttrs' method of template.
# --------------------------------------------------------------------------------
sectionName = maya.mel.eval("uiRes(\"s_TPStemplateStrings.rExtraAttributes\");")
frameLayout = self.searchForMayaControl(startLayout, cmds.frameLayout, sectionName)
self.assertIsNotNone(frameLayout, 'Could not find Extra Attributes frameLayout')

def testAECustomImageControl(self):
'''Simple test for the customImageControlCreator in AE template.'''
cmds.file(new=True, force=True)
testFile = testUtils.getTestScene("MaterialX", "MtlxValueTypes.usda")
shapeNode,shapeStage = mayaUtils.createProxyFromFile(testFile)

# Select this prim which has a custom image control attribute.
cmds.select('|stage|stageShape,/TypeSampler/MaterialX/D_filename', r=True)


# Make sure the AE is visible.
import maya.mel
maya.mel.eval('openAEWindow')

# In the AE there is a formLayout for each USD prim type. We start
# by making sure we can find the one for shader.
shaderFormLayout = 'AttrEdUSDShaderFormLayout'
self.assertTrue(cmds.formLayout(shaderFormLayout, exists=True))
startLayout = cmds.formLayout(shaderFormLayout, query=True, fullPathName=True)
self.assertIsNotNone(startLayout, 'Could not get full path for Shader formLayout')

# We should have a frameLayout called 'Shader: Dot' in the template.
# If there is a scripting error in the template, this layout will be missing.
frameLayout = self.searchForMayaControl(startLayout, cmds.frameLayout, 'Shader: Dot')
self.assertIsNotNone(frameLayout, 'Could not find "Shader: Dot" frameLayout')

# We should also have custom image control for 'Inputs In'.
InputsInControl = self.searchForMayaControl(frameLayout, cmds.text, 'Inputs In')
self.assertIsNotNone(InputsInControl, 'Could not find D_filename "Inputs In" control')

def testAECustomEnumControl(self):
'''Simple test for the customEnumControlCreator in AE template.'''

from ufe_ae.usd.nodes.usdschemabase import AETemplate
from ufe_ae.usd.nodes.usdschemabase.custom_enum_control import customEnumControlCreator
if customEnumControlCreator not in AETemplate._controlCreators:
self.skipTest('Test only available if AE template has customEnumControlCreator.')

cmds.file(new=True, force=True)
testFile = testUtils.getTestScene("MaterialX", "int_enum.usda")
shapeNode,shapeStage = mayaUtils.createProxyFromFile(testFile)

# Select this prim which has a custom image control attribute.
cmds.select('|stage|stageShape,/Material1/gltf_pbr1', r=True)

# Make sure the AE is visible.
import maya.mel
maya.mel.eval('openAEWindow')

# In the AE there is a formLayout for each USD prim type. We start
# by making sure we can find the one for Shader.
shaderFormLayout = 'AttrEdUSDShaderFormLayout'
self.assertTrue(cmds.formLayout(shaderFormLayout, exists=True))
startLayout = cmds.formLayout(shaderFormLayout, query=True, fullPathName=True)
self.assertIsNotNone(startLayout, 'Could not get full path for Shader formLayout')

# We should have a frameLayout called 'Alpha' in the template.
# If there is a scripting error in the template, this layout will be missing.
frameLayout = self.searchForMayaControl(startLayout, cmds.frameLayout, 'Alpha')
self.assertIsNotNone(frameLayout, 'Could not find "Alpha" frameLayout')

# We should also have custom enum control for 'Inputs Alpha Mode'.
InputsAlphaModeControl = self.searchForMayaControl(frameLayout, cmds.text, 'Inputs Alpha Mode')
self.assertIsNotNone(InputsAlphaModeControl, 'Could not find gltf_pbr1 "Inputs Alpha Mode" control')

def testAEConnectionsCustomControl(self):
'''Simple test for the connectionsCustomControlCreator in AE template.'''

cmds.file(new=True, force=True)
testFile = testUtils.getTestScene('MaterialX', 'multiple_connections.usda')
testPath,shapeStage = mayaUtils.createProxyFromFile(testFile)

# Select this prim which has an attribute with a connection.
cmds.select('|stage|stageShape,/Material1/fractal3d1', r=True)

# Make sure the AE is visible.
import maya.mel
maya.mel.eval('openAEWindow')

# In the AE there is a formLayout for each USD prim type. We start
# by making sure we can find the one for Shader.
shaderFormLayout = 'AttrEdUSDShaderFormLayout'
self.assertTrue(cmds.formLayout(shaderFormLayout, exists=True))
startLayout = cmds.formLayout(shaderFormLayout, query=True, fullPathName=True)
self.assertIsNotNone(startLayout, 'Could not get full path for Shader formLayout')

# We should have a frameLayout called 'Shader: Fractal3d' in the template.
# If there is a scripting error in the template, this layout will be missing.
frameLayout = self.searchForMayaControl(startLayout, cmds.frameLayout, 'Shader: Fractal3d')
self.assertIsNotNone(frameLayout, 'Could not find "Shader: Fractal3d" frameLayout')

# We should also have an attribute called 'Amplitude' which has a connection.
AmplitudeControl = self.searchForMayaControl(frameLayout, cmds.text, 'Amplitude')
self.assertIsNotNone(AmplitudeControl, 'Could not find fractal3d1 "Amplitude" control')

if __name__ == '__main__':
fixturesUtils.runTests(globals())

0 comments on commit 52a4474

Please sign in to comment.