From 7246c4379efc483c7d37f4f021f17b8ed5233469 Mon Sep 17 00:00:00 2001 From: Sean Donnelly <23455376+seando-adsk@users.noreply.github.com> Date: Thu, 22 Apr 2021 09:54:02 -0400 Subject: [PATCH 1/3] MAYA-110489 - Prim AE template: categories persist their expand/collapse state * Set new forceRebuild flag true to keep our prim template always destroy/recreate itself. This is needed because we are dynmaically changing the transform section and we do not know the attributes to show and their order. * Fixed bug with xformOpOrder change where copied AE tabs were not freshing to show/remove updated transforms. * Fixed a bug in UsdAttribute where setting a value (that had no previous value) would throw error. MAYA-110215 - On AE template I'd like to see some categories collapsed * Simple logic to collapse (by default) certain categories. --- .../resources/ae/usdschemabase/ae_template.py | 30 ++++++++++---- lib/mayaUsd/ufe/UsdAttribute.cpp | 39 +++++++------------ 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py b/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py index e2480ec3f1..712dad0e52 100644 --- a/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py +++ b/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py @@ -20,7 +20,6 @@ import mayaUsd.ufe as mayaUsdUfe import mayaUsd.lib as mayaUsdLib import maya.internal.common.ufe_ae.template as ufeAeTemplate -import maya.internal.common.ae.custom as aecustom from maya.common.ui import LayoutManager from maya.common.ui import setClipboardData @@ -62,7 +61,7 @@ def __del__(self): def __call__(self, notification): if isinstance(notification, ufe.AttributeValueChanged): if notification.name() == UsdGeom.Tokens.xformOpOrder: - mel.eval("evalDeferred(\"AEbuildControls\");") + mel.eval("evalDeferred -low \"refreshEditorTemplates\";") def onCreate(self, *args): ufe.Attributes.addObserver(self._item, self) @@ -70,17 +69,16 @@ def onCreate(self, *args): def onReplace(self, *args): pass -class MetaDataCustomControl(aecustom.CustomControl): +class MetaDataCustomControl(object): # Custom control for all prim metadata we want to display. - def __init__(self, prim, *args, **kwargs): + def __init__(self, prim): self.prim = prim - super(MetaDataCustomControl, self).__init__(args, kwargs) # There are four metadata that we always show: primPath, kind, active, instanceable # We use a dictionary to store the various other metadata that this prim contains. self.extraMetadata = dict() - def buildControlUI(self): + def onCreate(self, *args): # Should we display nice names in AE? useNiceName = True if cmds.optionVar(exists='attrEditorIsLongName'): @@ -148,6 +146,9 @@ def buildControlUI(self): # Update all metadata values. self.refresh() + def onReplace(self, *args): + pass + def refresh(self): # PrimPath cmds.textFieldGrp(self.primPath, edit=True, text=str(self.prim.GetPath())) @@ -276,6 +277,16 @@ def __init__(self, ufeSceneItem): self.createMetadataSection() cmds.editorTemplate(endScrollLayout=True) + if int(cmds.about(majorVersion=True)) > 2022: + # Because of how we dynamically build the Transform attribute section, + # we need this template to rebuild each time it is needed. This will + # also restore the collapse/expand state of the sections. + # Note: in Maya 2022 all UFE templates were forcefully rebuilt, but + # no restore of section states. + try: + cmds.editorTemplate(forceRebuild=True) + except: + pass def addControls(self, controls): for c in controls: @@ -473,7 +484,10 @@ def buildUI(self): if schemaTypeName == 'UsdGeomXformable': self.createTransformAttributesSection(sectionName, attrsToAdd) else: - self.createSection(sectionName, attrsToAdd) + sectionsToCollapse = ['Curves', 'Point Based', 'Geometric Prim', 'Boundable', + 'Imageable', 'Field Asset', 'Light'] + collapse = sectionName in sectionsToCollapse + self.createSection(sectionName, attrsToAdd, collapse) def suppressArrayAttribute(self): # Suppress all array attributes except UsdGeom.Tokens.xformOpOrder @@ -487,4 +501,4 @@ def isArrayAttribute(self, attrName): attr = self.prim.GetAttribute(attrName) typeName = attr.GetTypeName() return typeName.isArray - return False \ No newline at end of file + return False diff --git a/lib/mayaUsd/ufe/UsdAttribute.cpp b/lib/mayaUsd/ufe/UsdAttribute.cpp index ed9494ecf2..9300f528e1 100644 --- a/lib/mayaUsd/ufe/UsdAttribute.cpp +++ b/lib/mayaUsd/ufe/UsdAttribute.cpp @@ -47,7 +47,6 @@ static constexpr char kErrorMsgFailedConvertToString[] = "Could not convert the attribute to a string"; static constexpr char kErrorMsgInvalidType[] = "USD attribute does not match created attribute class type"; -static constexpr char kErrorMsgEnumNoValue[] = "Enum string attribute has no value"; //------------------------------------------------------------------------------ // Helper functions @@ -118,7 +117,11 @@ getUsdAttributeValueAsString(const PXR_NS::UsdAttribute& attr, const PXR_NS::Usd return os.str(); } - UFE_ASSERT_MSG(false, kErrorMsgFailedConvertToString); + try { + UFE_ASSERT_MSG(false, kErrorMsgFailedConvertToString); + } catch (const std::exception&) { + // noop + } return std::string(); } @@ -135,7 +138,6 @@ U getUsdAttributeVectorAsUfe(const PXR_NS::UsdAttribute& attr, const PXR_NS::Usd return ret; } - UFE_ASSERT_MSG(false, kErrorMsgInvalidType); return U(); } @@ -146,7 +148,6 @@ void setUsdAttributeVectorFromUfe( const PXR_NS::UsdTimeCode& time) { T vec; - UFE_ASSERT_MSG(attr.Get(&vec, time), kErrorMsgInvalidType); vec.Set(value.x(), value.y(), value.z()); setUsdAttr(attr, vec); } @@ -263,22 +264,17 @@ UsdAttributeEnumString::create(const UsdSceneItem::Ptr& item, const PXR_NS::UsdA std::string UsdAttributeEnumString::get() const { - UFE_ASSERT_MSG(hasValue(), kErrorMsgEnumNoValue); PXR_NS::VtValue vt; if (fUsdAttr.Get(&vt, getCurrentTime(sceneItem())) && vt.IsHolding()) { TfToken tok = vt.UncheckedGet(); return tok.GetString(); } - UFE_ASSERT_MSG(false, kErrorMsgInvalidType); return std::string(); } void UsdAttributeEnumString::set(const std::string& value) { - PXR_NS::TfToken dummy; - UFE_ASSERT_MSG( - fUsdAttr.Get(&dummy, getCurrentTime(sceneItem())), kErrorMsgInvalidType); PXR_NS::TfToken tok(value); setUsdAttr(fUsdAttr, tok); } @@ -286,7 +282,11 @@ void UsdAttributeEnumString::set(const std::string& value) Ufe::UndoableCommand::Ptr UsdAttributeEnumString::setCmd(const std::string& value) { auto self = std::dynamic_pointer_cast(shared_from_this()); - UFE_ASSERT_MSG(self, kErrorMsgInvalidType); + try { + UFE_ASSERT_MSG(self, kErrorMsgInvalidType); + } catch (const std::exception&) { + // noop + } return std::make_shared>(self, value); } @@ -349,7 +349,6 @@ template <> std::string TypedUsdAttribute::get() const } } - UFE_ASSERT_MSG(false, kErrorMsgInvalidType); return std::string(); } @@ -358,23 +357,20 @@ template <> void TypedUsdAttribute::set(const std::string& value) // We need to figure out if the USDAttribute is holding a TfToken or string. const PXR_NS::SdfValueTypeName typeName = fUsdAttr.GetTypeName(); if (typeName.GetHash() == SdfValueTypeNames->String.GetHash()) { - std::string dummy; - UFE_ASSERT_MSG( - fUsdAttr.Get(&dummy, getCurrentTime(sceneItem())), kErrorMsgInvalidType); setUsdAttr(fUsdAttr, value); return; } else if (typeName.GetHash() == SdfValueTypeNames->Token.GetHash()) { - PXR_NS::TfToken dummy; - UFE_ASSERT_MSG( - fUsdAttr.Get(&dummy, getCurrentTime(sceneItem())), - kErrorMsgInvalidType); PXR_NS::TfToken tok(value); setUsdAttr(fUsdAttr, tok); return; } // If we get here it means the USDAttribute type wasn't TfToken or string. - UFE_ASSERT_MSG(false, kErrorMsgInvalidType); + try { + UFE_ASSERT_MSG(false, kErrorMsgInvalidType); + } catch (const std::exception&) { + // noop + } } template <> Ufe::Color3f TypedUsdAttribute::get() const @@ -386,7 +382,6 @@ template <> Ufe::Color3f TypedUsdAttribute::get() const template <> void TypedUsdAttribute::set(const Ufe::Color3f& value) { GfVec3f vec; - UFE_ASSERT_MSG(fUsdAttr.Get(&vec, getCurrentTime(sceneItem())), kErrorMsgInvalidType); vec.Set(value.r(), value.g(), value.b()); setUsdAttr(fUsdAttr, vec); } @@ -437,15 +432,11 @@ template T TypedUsdAttribute::get() const return vt.UncheckedGet(); } - UFE_ASSERT_MSG(false, kErrorMsgInvalidType); return T(); } template void TypedUsdAttribute::set(const T& value) { - T dummy; - UFE_ASSERT_MSG( - fUsdAttr.Get(&dummy, getCurrentTime(Ufe::Attribute::sceneItem())), kErrorMsgInvalidType); setUsdAttr(fUsdAttr, value); } From 394ef984927362b66a7c1b8ae04c4ea4bac41b34 Mon Sep 17 00:00:00 2001 From: Sean Donnelly <23455376+seando-adsk@users.noreply.github.com> Date: Thu, 29 Apr 2021 08:37:49 -0400 Subject: [PATCH 2/3] MAYA-110489 - Prim AE template: categories persist their expand/collapse state * Code review feedback. --- .../resources/ae/usdschemabase/ae_template.py | 5 ++++ lib/mayaUsd/ufe/UsdAttribute.cpp | 26 ++++--------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py b/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py index 712dad0e52..2070f4ab3e 100644 --- a/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py +++ b/lib/mayaUsd/resources/ae/usdschemabase/ae_template.py @@ -67,6 +67,7 @@ def onCreate(self, *args): ufe.Attributes.addObserver(self._item, self) def onReplace(self, *args): + # Nothing needed here since we don't create any UI. pass class MetaDataCustomControl(object): @@ -147,6 +148,9 @@ def onCreate(self, *args): self.refresh() def onReplace(self, *args): + # Nothing needed here since USD data is not time varying. Normally this template + # is force rebuilt all the time, except in response to time change from Maya. In + # that case we don't need to update our controls since none will change. pass def refresh(self): @@ -233,6 +237,7 @@ def onCreate(self, *args): cmds.scriptJob(uiDeleted=[pname, self.onClose], runOnce=True) def onReplace(self, *args): + # Nothing needed here since we don't create any UI. pass def onClose(self): diff --git a/lib/mayaUsd/ufe/UsdAttribute.cpp b/lib/mayaUsd/ufe/UsdAttribute.cpp index 9300f528e1..75dc759ba2 100644 --- a/lib/mayaUsd/ufe/UsdAttribute.cpp +++ b/lib/mayaUsd/ufe/UsdAttribute.cpp @@ -26,18 +26,13 @@ #include #include -#include +#include #include #include -// We unconditionally want the UFE asserts here (even in release builds). -// The UFE_ASSERT_MSG has a built-in throw which we want to use for error handling. -#define UFE_ENABLE_ASSERTS #include #include -#include - // Note: normally we would use this using directive, but here we cannot because // our class is called UsdAttribute which is exactly the same as the one // in USD. @@ -117,11 +112,7 @@ getUsdAttributeValueAsString(const PXR_NS::UsdAttribute& attr, const PXR_NS::Usd return os.str(); } - try { - UFE_ASSERT_MSG(false, kErrorMsgFailedConvertToString); - } catch (const std::exception&) { - // noop - } + TF_CODING_ERROR(kErrorMsgFailedConvertToString); return std::string(); } @@ -282,11 +273,8 @@ void UsdAttributeEnumString::set(const std::string& value) Ufe::UndoableCommand::Ptr UsdAttributeEnumString::setCmd(const std::string& value) { auto self = std::dynamic_pointer_cast(shared_from_this()); - try { - UFE_ASSERT_MSG(self, kErrorMsgInvalidType); - } catch (const std::exception&) { - // noop - } + if (!TF_VERIFY(self, kErrorMsgInvalidType)) + return nullptr; return std::make_shared>(self, value); } @@ -366,11 +354,7 @@ template <> void TypedUsdAttribute::set(const std::string& value) } // If we get here it means the USDAttribute type wasn't TfToken or string. - try { - UFE_ASSERT_MSG(false, kErrorMsgInvalidType); - } catch (const std::exception&) { - // noop - } + TF_CODING_ERROR(kErrorMsgInvalidType); } template <> Ufe::Color3f TypedUsdAttribute::get() const From f9780e2dfd3e292bf24d3ea25a6cb169fa8cb621 Mon Sep 17 00:00:00 2001 From: Sean Donnelly <23455376+seando-adsk@users.noreply.github.com> Date: Thu, 29 Apr 2021 10:02:06 -0400 Subject: [PATCH 3/3] MAYA-110489 - Prim AE template: categories persist their expand/collapse state * Fix clang-format error. --- lib/mayaUsd/ufe/UsdAttribute.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/mayaUsd/ufe/UsdAttribute.cpp b/lib/mayaUsd/ufe/UsdAttribute.cpp index 75dc759ba2..668b0370e8 100644 --- a/lib/mayaUsd/ufe/UsdAttribute.cpp +++ b/lib/mayaUsd/ufe/UsdAttribute.cpp @@ -17,6 +17,8 @@ #include "private/Utils.h" +#include +#include #include #include @@ -30,9 +32,6 @@ #include #include -#include -#include - // Note: normally we would use this using directive, but here we cannot because // our class is called UsdAttribute which is exactly the same as the one // in USD.