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

MAYA-110489 - Prim AE template: categories persist their expand/colla… #1372

Merged
merged 3 commits into from
Apr 29, 2021
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
35 changes: 27 additions & 8 deletions lib/mayaUsd/resources/ae/usdschemabase/ae_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -62,25 +61,25 @@ 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\";")
seando-adsk marked this conversation as resolved.
Show resolved Hide resolved

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(aecustom.CustomControl):
class MetaDataCustomControl(object):
seando-adsk marked this conversation as resolved.
Show resolved Hide resolved
# 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'):
Expand Down Expand Up @@ -148,6 +147,12 @@ def buildControlUI(self):
# Update all metadata values.
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
seando-adsk marked this conversation as resolved.
Show resolved Hide resolved

def refresh(self):
# PrimPath
cmds.textFieldGrp(self.primPath, edit=True, text=str(self.prim.GetPath()))
Expand Down Expand Up @@ -232,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):
Expand Down Expand Up @@ -276,6 +282,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:
Expand Down Expand Up @@ -473,7 +489,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)
Comment on lines +492 to +495
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a simple fix for another JIRA item (to collapse certain sections by default).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the hard-coded list is O.K. because it won't change much?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right it was a list given to me in the JIRA item. It would only change if Nat wants a change.


def suppressArrayAttribute(self):
# Suppress all array attributes except UsdGeom.Tokens.xformOpOrder
Expand All @@ -487,4 +506,4 @@ def isArrayAttribute(self, attrName):
attr = self.prim.GetAttribute(attrName)
typeName = attr.GetTypeName()
return typeName.isArray
return False
return False
40 changes: 7 additions & 33 deletions lib/mayaUsd/ufe/UsdAttribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "private/Utils.h"

#include <mayaUsd/ufe/StagesSubject.h>
#include <mayaUsd/ufe/Utils.h>
#include <mayaUsd/undo/UsdUndoBlock.h>
#include <mayaUsd/undo/UsdUndoableItem.h>

Expand All @@ -26,18 +28,10 @@
#include <pxr/usd/sdf/attributeSpec.h>
#include <pxr/usd/usd/schemaRegistry.h>

#include <iostream>
#include <sstream>
#include <unordered_map>
#include <unordered_set>

// 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 <mayaUsd/ufe/StagesSubject.h>
#include <mayaUsd/ufe/Utils.h>

#include <ufe/ufeAssert.h>

// 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.
Expand All @@ -47,7 +41,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
Expand Down Expand Up @@ -118,7 +111,7 @@ getUsdAttributeValueAsString(const PXR_NS::UsdAttribute& attr, const PXR_NS::Usd
return os.str();
}

UFE_ASSERT_MSG(false, kErrorMsgFailedConvertToString);
TF_CODING_ERROR(kErrorMsgFailedConvertToString);
return std::string();
}

Expand All @@ -135,7 +128,6 @@ U getUsdAttributeVectorAsUfe(const PXR_NS::UsdAttribute& attr, const PXR_NS::Usd
return ret;
}

UFE_ASSERT_MSG(false, kErrorMsgInvalidType);
return U();
}

Expand All @@ -146,7 +138,6 @@ void setUsdAttributeVectorFromUfe(
const PXR_NS::UsdTimeCode& time)
{
T vec;
UFE_ASSERT_MSG(attr.Get<T>(&vec, time), kErrorMsgInvalidType);
vec.Set(value.x(), value.y(), value.z());
setUsdAttr<T>(attr, vec);
}
Expand Down Expand Up @@ -263,30 +254,26 @@ 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>()) {
TfToken tok = vt.UncheckedGet<TfToken>();
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<PXR_NS::TfToken>(&dummy, getCurrentTime(sceneItem())), kErrorMsgInvalidType);
PXR_NS::TfToken tok(value);
setUsdAttr<PXR_NS::TfToken>(fUsdAttr, tok);
}

Ufe::UndoableCommand::Ptr UsdAttributeEnumString::setCmd(const std::string& value)
{
auto self = std::dynamic_pointer_cast<UsdAttributeEnumString>(shared_from_this());
UFE_ASSERT_MSG(self, kErrorMsgInvalidType);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If self is false just return a nullptr.

if (!TF_VERIFY(self, kErrorMsgInvalidType))
return nullptr;
return std::make_shared<SetUndoableCommand<std::string, UsdAttributeEnumString>>(self, value);
}

Expand Down Expand Up @@ -349,7 +336,6 @@ template <> std::string TypedUsdAttribute<std::string>::get() const
}
}

UFE_ASSERT_MSG(false, kErrorMsgInvalidType);
return std::string();
}

Expand All @@ -358,23 +344,16 @@ template <> void TypedUsdAttribute<std::string>::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<std::string>(&dummy, getCurrentTime(sceneItem())), kErrorMsgInvalidType);
setUsdAttr<std::string>(fUsdAttr, value);
return;
} else if (typeName.GetHash() == SdfValueTypeNames->Token.GetHash()) {
PXR_NS::TfToken dummy;
UFE_ASSERT_MSG(
fUsdAttr.Get<PXR_NS::TfToken>(&dummy, getCurrentTime(sceneItem())),
kErrorMsgInvalidType);
PXR_NS::TfToken tok(value);
setUsdAttr<PXR_NS::TfToken>(fUsdAttr, tok);
return;
}

// If we get here it means the USDAttribute type wasn't TfToken or string.
UFE_ASSERT_MSG(false, kErrorMsgInvalidType);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove the line.

TF_CODING_ERROR(kErrorMsgInvalidType);
}

template <> Ufe::Color3f TypedUsdAttribute<Ufe::Color3f>::get() const
Expand All @@ -386,7 +365,6 @@ template <> Ufe::Color3f TypedUsdAttribute<Ufe::Color3f>::get() const
template <> void TypedUsdAttribute<Ufe::Color3f>::set(const Ufe::Color3f& value)
{
GfVec3f vec;
UFE_ASSERT_MSG(fUsdAttr.Get<GfVec3f>(&vec, getCurrentTime(sceneItem())), kErrorMsgInvalidType);
vec.Set(value.r(), value.g(), value.b());
setUsdAttr<GfVec3f>(fUsdAttr, vec);
}
Expand Down Expand Up @@ -437,15 +415,11 @@ template <typename T> T TypedUsdAttribute<T>::get() const
return vt.UncheckedGet<T>();
}

UFE_ASSERT_MSG(false, kErrorMsgInvalidType);
return T();
}

template <typename T> void TypedUsdAttribute<T>::set(const T& value)
{
T dummy;
UFE_ASSERT_MSG(
fUsdAttr.Get<T>(&dummy, getCurrentTime(Ufe::Attribute::sceneItem())), kErrorMsgInvalidType);
setUsdAttr<T>(fUsdAttr, value);
}

Expand Down