Skip to content

Commit

Permalink
Merge branch 'dev' into minnins/assign-new-material-to-multiple-objects
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanminning-autodesk committed Nov 16, 2022
2 parents dbb7315 + f8f82ab commit d50fa23
Show file tree
Hide file tree
Showing 10 changed files with 355 additions and 7 deletions.
130 changes: 127 additions & 3 deletions lib/mayaUsd/ufe/StagesSubject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,21 @@ enum class AttributeChangeType
kAdded,
kValueChanged,
kConnectionChanged,
kRemoved
kRemoved,
kMetadataChanged
};

struct AttributeNotification
{
AttributeNotification(const Ufe::Path& path, const TfToken& token, AttributeChangeType type)
: _path(path)
, _token(token)
, _type(type)
{
}

virtual ~AttributeNotification() { }

Ufe::Path _path;
TfToken _token;
AttributeChangeType _type;
Expand All @@ -108,6 +118,31 @@ struct AttributeNotification
}
};

struct AttributeMetadataNotification : public AttributeNotification
{
AttributeMetadataNotification(
const Ufe::Path& path,
const TfToken& token,
AttributeChangeType type,
const std::set<std::string>& metadataKeys)
: AttributeNotification(path, token, type)
, _metadataKeys(metadataKeys)
{
}

~AttributeMetadataNotification() override { }

std::set<std::string> _metadataKeys;

bool operator==(const AttributeMetadataNotification& other)
{
// Only collapse multiple value changes. Collapsing added/removed notifications needs to be
// done safely so the observer ends up in the right state.
return other._type == _type && other._token == _token && other._path == _path
&& _type == AttributeChangeType::kMetadataChanged;
}
};

// Keep an array of the pending attribute notifications. Using a vector
// for two main reasons:
// 1) Order of notifs must be maintained.
Expand Down Expand Up @@ -153,6 +188,9 @@ void sendAttributeChanged(
notifyWithoutExceptions<Ufe::Attributes>(
Ufe::AttributeConnectionChanged(ufePath, changedToken.GetString()));
} break;
case AttributeChangeType::kMetadataChanged: {
// Do nothing (needed to fix build error)
} break;
}
#else
notifyWithoutExceptions<Ufe::Attributes>(
Expand All @@ -164,6 +202,20 @@ void sendAttributeChanged(
#endif
}

#if (UFE_PREVIEW_VERSION_NUM >= 4037)
void sendAttributeMetadataChanged(
const Ufe::Path& ufePath,
const TfToken& changedToken,
AttributeChangeType UFE_V4_24(changeType),
const std::set<std::string>& metadataKeys)
{
if (changeType == AttributeChangeType::kMetadataChanged) {
notifyWithoutExceptions<Ufe::Attributes>(
Ufe::AttributeMetadataChanged(ufePath, changedToken.GetString(), metadataKeys));
}
}
#endif

void valueChanged(const Ufe::Path& ufePath, const TfToken& changedToken)
{
if (inAttributeChangedNotificationGuard()) {
Expand Down Expand Up @@ -204,6 +256,36 @@ void attributeChanged(
}
#endif

#if (UFE_PREVIEW_VERSION_NUM >= 4037)
void attributeMetadataChanged(
const Ufe::Path& ufePath,
const TfToken& changedToken,
AttributeChangeType changeType,
const std::set<std::string>& metadataKeys)
{
if (inAttributeChangedNotificationGuard()) {
// Don't add pending notif if one already exists with same path/token.
auto p = AttributeMetadataNotification(ufePath, changedToken, changeType, metadataKeys);
auto p2 = std::find(
pendingAttributeChangedNotifications.begin(),
pendingAttributeChangedNotifications.end(),
p);
if (p2 == pendingAttributeChangedNotifications.end()) {
pendingAttributeChangedNotifications.emplace_back(p);
} else {
auto p2AttributeMetadataNotification
= dynamic_cast<AttributeMetadataNotification*>(&(*p2));
if (p2AttributeMetadataNotification) {
p2AttributeMetadataNotification->_metadataKeys.insert(
metadataKeys.begin(), metadataKeys.end());
}
}
} else {
sendAttributeMetadataChanged(ufePath, changedToken, changeType, metadataKeys);
}
}
#endif

void processAttributeChanges(
const Ufe::Path& ufePath,
const SdfPath& changedPath,
Expand All @@ -214,6 +296,10 @@ void processAttributeChanges(
bool sendAdded = false;
bool sendRemoved = false;
bool sendConnectionChanged = false;
#if (UFE_PREVIEW_VERSION_NUM >= 4037)
bool sendMetadataChanged = false;
std::set<std::string> metadataKeys;
#endif
for (const auto& entry : entries) {
// We can have multiple flags merged into a single entry:
if (entry->flags.didAddProperty || entry->flags.didAddPropertyWithOnlyRequiredFields) {
Expand All @@ -229,6 +315,22 @@ void processAttributeChanges(
sendConnectionChanged = true;
sendValueChanged = false;
}
#if (UFE_PREVIEW_VERSION_NUM >= 4037)
for (const auto& infoChanged : entry->infoChanged) {
if (infoChanged.first == UsdShadeTokens->sdrMetadata) {
sendMetadataChanged = true;
std::stringstream newMetadataStream;
newMetadataStream << infoChanged.second.second;
std::string newMetadataKey = newMetadataStream.str();
if (!newMetadataKey.empty()) {
// Find the modified key which is between a pair of single quotes.
newMetadataKey = newMetadataKey.substr(
newMetadataKey.find('\'') + 1, newMetadataKey.rfind('\'') - 2);
metadataKeys.insert(newMetadataKey);
}
}
}
#endif
}
if (sendAdded) {
attributeChanged(ufePath, changedPath.GetNameToken(), AttributeChangeType::kAdded);
Expand All @@ -243,6 +345,15 @@ void processAttributeChanges(
if (sendRemoved) {
attributeChanged(ufePath, changedPath.GetNameToken(), AttributeChangeType::kRemoved);
}
#if (UFE_PREVIEW_VERSION_NUM >= 4037)
if (sendMetadataChanged) {
attributeMetadataChanged(
ufePath,
changedPath.GetNameToken(),
AttributeChangeType::kMetadataChanged,
metadataKeys);
}
#endif
#else
valueChanged(ufePath, changedPath.GetNameToken());
#endif
Expand Down Expand Up @@ -768,8 +879,21 @@ AttributeChangedNotificationGuard::~AttributeChangedNotificationGuard()
}

for (const auto& notificationInfo : pendingAttributeChangedNotifications) {
sendAttributeChanged(
notificationInfo._path, notificationInfo._token, notificationInfo._type);
if (notificationInfo._type == AttributeChangeType::kMetadataChanged) {
#if (UFE_PREVIEW_VERSION_NUM >= 4037)
if (const auto metadataNotificationInfo
= dynamic_cast<const AttributeMetadataNotification*>(&notificationInfo)) {
sendAttributeMetadataChanged(
metadataNotificationInfo->_path,
metadataNotificationInfo->_token,
metadataNotificationInfo->_type,
metadataNotificationInfo->_metadataKeys);
}
#endif
} else {
sendAttributeChanged(
notificationInfo._path, notificationInfo._token, notificationInfo._type);
}
}

pendingAttributeChangedNotifications.clear();
Expand Down
24 changes: 24 additions & 0 deletions lib/mayaUsd/ufe/UsdAttributeHolder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ bool setUsdAttrMetadata(
throw std::runtime_error(errMsg);
}

PXR_NS::TfToken tok(key);
if (PXR_NS::UsdShadeNodeGraph(attr.GetPrim())) {
if (PXR_NS::UsdShadeInput::IsInput(attr)) {
PXR_NS::UsdShadeInput input(attr);
input.SetSdrMetadataByKey(tok, value.get<std::string>());
return true;
} else if (PXR_NS::UsdShadeOutput::IsOutput(attr)) {
PXR_NS::UsdShadeOutput output(attr);
output.SetSdrMetadataByKey(tok, value.get<std::string>());
return true;
}
}

// We must convert the Ufe::Value to VtValue for storage in Usd.
// Figure out the type of the input Ufe Value and create proper Usd VtValue.
PXR_NS::VtValue usdValue;
Expand Down Expand Up @@ -172,6 +185,17 @@ Ufe::Value UsdAttributeHolder::getMetadata(const std::string& key) const
return Ufe::Value();
}
PXR_NS::TfToken tok(key);
if (PXR_NS::UsdShadeNodeGraph(usdPrim())) {
if (PXR_NS::UsdShadeInput::IsInput(_usdAttr)) {
const PXR_NS::UsdShadeInput input(_usdAttr);
const std::string metadata = input.GetSdrMetadataByKey(tok);
return Ufe::Value(metadata);
} else if (PXR_NS::UsdShadeOutput::IsOutput(_usdAttr)) {
const PXR_NS::UsdShadeOutput output(_usdAttr);
const std::string metadata = output.GetSdrMetadataByKey(tok);
return Ufe::Value(metadata);
}
}
PXR_NS::VtValue v;
if (_usdAttr.GetMetadata(tok, &v)) {
if (v.IsHolding<bool>())
Expand Down
2 changes: 1 addition & 1 deletion lib/usd/translators/meshWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ bool PxrUsdTranslators_MeshWriter::writeMeshAttrs(

if (sdScheme == UsdGeomTokens->none) {
// Polygonal mesh - export normals.
bool emitNormals = true; // Default to emitting normals if no tagging.
bool emitNormals = false; // Skip writing normals if no tagging.
UsdMayaMeshReadUtils::getEmitNormalsTag(finalMesh, &emitNormals);
if (emitNormals) {
UsdMayaMeshWriteUtils::writeNormalsData(
Expand Down
79 changes: 78 additions & 1 deletion lib/usd/ui/layerEditor/layerTreeView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ LayerTreeView::LayerTreeView(SessionState* in_sessionState, QWidget* in_parent)
setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);

// updates
connect(
_model,
&QAbstractItemModel::modelAboutToBeReset,
this,
&LayerTreeView::onModelAboutToBeReset);
connect(_model, &QAbstractItemModel::modelReset, this, &LayerTreeView::onModelReset);

// signals
Expand Down Expand Up @@ -131,7 +136,79 @@ void LayerTreeView::onItemDoubleClicked(const QModelIndex& index)
}
}

void LayerTreeView::onModelReset() { expandAll(); }
LayerViewMemento::LayerViewMemento(const LayerTreeView& view, const LayerTreeModel& model)
{
preserve(view, model);
}

void LayerViewMemento::preserve(const LayerTreeView& view, const LayerTreeModel& model)
{
const LayerItemVector items = model.getAllItems();
if (items.size() == 0)
return;

for (const LayerTreeItem* item : items) {
if (!item)
continue;

PXR_NS::SdfLayerRefPtr layer = item->layer();
if (!layer)
continue;

const ItemId id = layer->GetIdentifier();
const ItemState state = { view.isExpanded(item->index()) };

_itemsState[id] = state;
}
}

void LayerViewMemento::restore(LayerTreeView& view, LayerTreeModel& model)
{
const LayerItemVector items = model.getAllItems();

QtDisableRepaintUpdates disableUpdates(view);

for (const LayerTreeItem* item : items) {
if (!item)
continue;

bool expanded = true;

PXR_NS::SdfLayerRefPtr layer = item->layer();
if (layer) {
const ItemId id = layer->GetIdentifier();
const auto state = _itemsState.find(id);
if (state != _itemsState.end()) {
expanded = state->second._expanded;
}
}

view.setExpanded(item->index(), expanded);
}
}

void LayerTreeView::onModelAboutToBeReset()
{
if (!_model)
return;

LayerViewMemento memento(*this, *_model);
if (memento.empty())
return;

_cachedModelState = std::make_unique<LayerViewMemento>(std::move(memento));
}

void LayerTreeView::onModelReset()
{
if (!_model)
return;

if (_cachedModelState)
_cachedModelState->restore(*this, *_model);
else
expandAll();
}

LayerItemVector LayerTreeView::getSelectedLayerItems() const
{
Expand Down
29 changes: 29 additions & 0 deletions lib/usd/ui/layerEditor/layerTreeView.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,37 @@ namespace UsdLayerEditor {
class LayerTreeItem;
class LayerTreeItemDelegate;
class LayerTreeModel;
class LayerTreeView;
class SessionState;

typedef std::vector<LayerTreeItem*> LayerItemVector;
typedef void (LayerTreeItem::*simpleLayerMethod)();

/**
* @brief State of the layer tree view and layer model.
* Used to save and restore the state when the model is rebuilt.
*
*/
class LayerViewMemento
{
public:
LayerViewMemento(const LayerTreeView&, const LayerTreeModel&);

void preserve(const LayerTreeView&, const LayerTreeModel&);
void restore(LayerTreeView&, LayerTreeModel&);

bool empty() const { return _itemsState.empty(); }

private:
using ItemId = std::string;
struct ItemState
{
bool _expanded = false;
};

std::map<ItemId, ItemState> _itemsState;
};

/**
* @brief Implements the Qt TreeView for USD layers. This widget is owned by the LayerEditorWidget.
*
Expand Down Expand Up @@ -82,6 +108,7 @@ class LayerTreeView : public QTreeView

protected:
// slot:
void onModelAboutToBeReset();
void onModelReset();
void onItemDoubleClicked(const QModelIndex& index);
void onMuteLayerButtonPushed();
Expand All @@ -93,6 +120,8 @@ class LayerTreeView : public QTreeView
QPointer<LayerTreeModel> _model;
LayerTreeItemDelegate* _delegate;

std::unique_ptr<LayerViewMemento> _cachedModelState;

void handleTooltips(QHelpEvent* event);

// the mute button area has a different implementation than
Expand Down
Loading

0 comments on commit d50fa23

Please sign in to comment.