Skip to content
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

EMSUSD-1856 make the collection widget support all collections #4017

Merged
merged 1 commit into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 21 additions & 24 deletions lib/mayaUsd/resources/ae/usdschemabase/ae_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ def __init__(self, ufeSceneItem):
pass

_controlCreators = [ConnectionsCustomControl.creator, ArrayCustomControl.creator, ImageCustomControl.creator, defaultControlCreator]
if lightLinkingSupported:
_controlCreators.insert(0, LightLinkingCustomControl.creator)

@staticmethod
def prependControlCreator(controlCreator):
Expand Down Expand Up @@ -319,21 +321,25 @@ def addSchemas(desiredOrder, availableSchemas):

def addControls(self, attrNames):
for attrName in attrNames:
if attrName not in self.suppressedAttrs:
for controlCreator in AETemplate._controlCreators:
try:
createdControl = controlCreator(self, attrName)
if createdControl:
self.defineCustom(createdControl, attrName)
break
except Exception as ex:
# Do not let one custom control failure affect others.
print('Failed to create control %s: %s' % (attrName, ex))
self.addedAttrs.add(attrName)

def suppress(self, control):
cmds.editorTemplate(suppress=control)
self.suppressedAttrs.append(control)
for controlCreator in AETemplate._controlCreators:
# Control can suppress attributes in the creator function
# so we check for supression at each loop
if attrName in self.suppressedAttrs:
break

try:
createdControl = controlCreator(self, attrName)
if createdControl:
self.defineCustom(createdControl, attrName)
self.addedAttrs.add(attrName)
break
except Exception as ex:
# Do not let one custom control failure affect others.
print('Failed to create control %s: %s' % (attrName, ex))

def suppress(self, attrName):
cmds.editorTemplate(suppress=attrName)
self.suppressedAttrs.append(attrName)

@staticmethod
def defineCustom(customObj, attrs=[]):
Expand Down Expand Up @@ -476,12 +482,6 @@ def createMetadataSection(self, sectionName, attrs, collapse):
self.defineCustom(metaDataControl)
self.defineCustom(usdNoticeControl)

def createLightLinkingSection(self, sectionName, attrs, collapse):
# We don't use createSection() because these are metadata (not attributes).
with ufeAeTemplate.Layout(self, 'Light Linking', collapse):
lightLinkingControl = LightLinkingCustomControl(self.item, self.prim, self.useNiceName)
self.defineCustom(lightLinkingControl)

def createCustomExtraAttrs(self, sectionName, attrs, collapse):
# We are not using the maya default "Extra Attributes" section
# because we are using custom widget for array type and it's not
Expand Down Expand Up @@ -660,9 +660,6 @@ def isSectionOpen(sectionName):
'metadata': self.createMetadataSection,
'customCallbacks': self.createCustomCallbackSection,
}
# only support lightLinking custom attribute for Maya 2023+
if lightLinkingSupported:
customAttributes['lightLinkCollectionAPI'] = self.createLightLinkingSection
sectionCreators = collections.defaultdict(
lambda : self.createSection, customAttributes)

Expand Down
76 changes: 54 additions & 22 deletions lib/mayaUsd/resources/ae/usdschemabase/lightCustomControl.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,72 @@

class LightLinkingCustomControl(object):
'''Custom control for the light linking data we want to display.'''
def __init__(self, item, prim, useNiceName):

@staticmethod
def isCollectionAttribute(aeTemplate, attrName):
'''
Verify if the given attribute name is a collection attribute.
'''
attrNameParts = attrName.split(':')
if len(attrNameParts) <= 1:
return False

instanceName = attrNameParts[1]
if not aeTemplate.prim.HasAPI(Usd.CollectionAPI, instanceName):
return False

if len(attrNameParts) > 2:
pierrebai-adsk marked this conversation as resolved.
Show resolved Hide resolved
aeTemplate.suppress(attrName)
return False

return True

@staticmethod
def creator(aeTemplate, attrName):
'''
If the attribute is a collection attribute then create a section to edit it.
'''
if LightLinkingCustomControl.isCollectionAttribute(aeTemplate, attrName):
attrName, instanceName = attrName.split(':')
return LightLinkingCustomControl(aeTemplate.item, aeTemplate.prim, attrName, instanceName, aeTemplate.useNiceName)
else:
return None

def __init__(self, item, prim, attrName, instanceName, useNiceName):
# In Maya 2022.1 we need to hold onto the Ufe SceneItem to make
# sure it doesn't go stale. This is not needed in latest Maya.
super(LightLinkingCustomControl, self).__init__()
mayaVer = '%s.%s' % (cmds.about(majorVersion=True), cmds.about(minorVersion=True))
self.item = item if mayaVer == '2022.1' else None
self.attrName = attrName
self.instanceName = instanceName
self.prim = prim
self.useNiceName = useNiceName

def onCreate(self, *args):
if self.prim.IsValid() == True and self.prim.HasAPI(Usd.CollectionAPI, 'lightLink'):
try:
try:
pierrebai-adsk marked this conversation as resolved.
Show resolved Hide resolved
try:
from shiboken6 import wrapInstance
from PySide6.QtWidgets import QWidget
except:
from shiboken2 import wrapInstance # type: ignore
from PySide2.QtWidgets import QWidget # type: ignore

from maya.OpenMayaUI import MQtUtil

self.parent = cmds.setParent(q=True)
ptr = MQtUtil.findControl(self.parent)
parentWidget = wrapInstance(int(ptr), QWidget)

from usd_shared_components.collection.widget import CollectionWidget # type: ignore

self.widget = CollectionWidget(Usd.CollectionAPI.Get(self.prim, 'lightLink'))
parentWidget.layout().addWidget(self.widget)
from shiboken6 import wrapInstance
from PySide6.QtWidgets import QWidget
except:
from shiboken2 import wrapInstance # type: ignore
from PySide2.QtWidgets import QWidget # type: ignore

except Exception as ex:
print('Failed to create Light custom control: %s' % (ex))
from maya.OpenMayaUI import MQtUtil

self.parent = cmds.setParent(q=True)
ptr = MQtUtil.findControl(self.parent)
parentWidget = wrapInstance(int(ptr), QWidget)

from usd_shared_components.collection.widget import CollectionWidget # type: ignore

self.widget = CollectionWidget(Usd.CollectionAPI.Get(self.prim, self.instanceName))
parentWidget.layout().addWidget(self.widget)

except Exception as ex:
print('Failed to create collection custom control: %s' % (ex))

self.refresh()
self.refresh()

def onReplace(self, *args):
# Nothing needed here since USD data is not time varying. Normally this template
Expand Down
38 changes: 10 additions & 28 deletions test/lib/testAttributeEditorTemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,38 +501,20 @@ def testAEForLight(self):

# Note: different version of USD can have different schemas,
# so we only compare the ones we are interested in verifying.
expectedInitialSectionLabels = []
if mayaUtils.mayaMajorMinorVersions() >= (2023, 0):
expectedInitialSectionLabels = [
'Light ',
'Cylinder Light',
'Light Linking',
'Shadow Link Collection ']
else:
expectedInitialSectionLabels = [
'Light ',
'Cylinder Light',
'Light Link Collection ',
'Shadow Link Collection ']
expectedInitialSectionLabels = [
'Light ',
'Cylinder Light',
'Light Link Collection ',
'Shadow Link Collection ']
self.assertListEqual(
actualSectionLabels[0:len(expectedInitialSectionLabels)],
expectedInitialSectionLabels)

# Note: there are no extra attributes in Maya 2022.
if mayaUtils.mayaMajorMinorVersions() >= (2023, 0):
expectedFinalSectionLabels = [
'Transforms',
'Display',
'Extra Attributes',
'Metadata']
else:
expectedFinalSectionLabels = [
'Transforms',
'Display',
'Metadata']
self.assertListEqual(
actualSectionLabels[-len(expectedFinalSectionLabels):],
expectedFinalSectionLabels)
# Note: the extra attributes sometimes show up, especially
pierrebai-adsk marked this conversation as resolved.
Show resolved Hide resolved
# in older versions of Maya, so we don't compare an exact list.
self.assertIn('Transforms', actualSectionLabels[-4:])
self.assertIn('Display', actualSectionLabels[-4:])
self.assertIn('Metadata', actualSectionLabels[-4:])

def testAECustomAttributeCallback(self):
'''Test that the custm atribute callbacks work.'''
Expand Down