Skip to content

Commit

Permalink
Merge pull request #2508 from Autodesk/vlasovi/MAYA-123143
Browse files Browse the repository at this point in the history
MAYA-123143 - As a user, I'd like my prims to be templated in a Display Layer
  • Loading branch information
seando-adsk authored Jul 28, 2022
2 parents c83dc45 + b42af18 commit f24795c
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 93 deletions.
53 changes: 34 additions & 19 deletions lib/mayaUsd/render/vp2RenderDelegate/basisCurves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ void HdVP2BasisCurves::Sync(
const TfToken& renderTag = delegate->GetRenderTag(id);
#endif

_SyncSharedData(_sharedData, delegate, dirtyBits, reprToken, id, _reprs, renderTag);
_SyncSharedData(_sharedData, delegate, dirtyBits, reprToken, *this, _reprs, renderTag);

*dirtyBits = HdChangeTracker::Clean;

Expand Down Expand Up @@ -566,6 +566,8 @@ void HdVP2BasisCurves::_UpdateDrawItem(
// doesn't need to extract index data from topology. Points use non-indexed
// draw.
const bool isBoundingBoxItem = (drawMode == MHWRender::MGeometry::kBoundingBox);
const bool isHighlightItem = drawItem->ContainsUsage(HdVP2DrawItem::kSelectionHighlight);
const bool inTemplateMode = _displayType == MayaUsdRPrim::kTemplate;

#ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT
constexpr bool isPointSnappingItem = false;
Expand Down Expand Up @@ -699,8 +701,8 @@ void HdVP2BasisCurves::_UpdateDrawItem(

if (material) {
MHWRender::MShaderInstance* shader = material->GetSurfaceShader();
if (shader != nullptr
&& (shader != drawItemData._shader || shader != stateToCommit._shader)) {
drawItemData._shaderIsFallback = (shader == nullptr);
if (shader != nullptr && shader != drawItemData._shader) {
drawItemData._shader = shader;
stateToCommit._shader = shader;
stateToCommit._isTransparent = shader->isTransparent();
Expand All @@ -718,6 +720,8 @@ void HdVP2BasisCurves::_UpdateDrawItem(
drawItemData._primitiveStride = primitiveStride;
stateToCommit._primitiveStride = &drawItemData._primitiveStride;
}
} else {
drawItemData._shaderIsFallback = true;
}
}

Expand Down Expand Up @@ -776,7 +780,7 @@ void HdVP2BasisCurves::_UpdateDrawItem(

// Use fallback shader if there is no material binding or we failed to create a shader
// instance from the material.
if (!stateToCommit._shader) {
if (drawItemData._shaderIsFallback) {
MHWRender::MShaderInstance* shader = nullptr;
MHWRender::MGeometry::Primitive primitiveType = MHWRender::MGeometry::kLines;
int primitiveStride = 0;
Expand Down Expand Up @@ -934,7 +938,7 @@ void HdVP2BasisCurves::_UpdateDrawItem(
// If the item is used for both regular draw and selection highlight,
// it needs to display both wireframe color and selection highlight
// with one color vertex buffer.
if (drawItem->ContainsUsage(HdVP2DrawItem::kSelectionHighlight)) {
if (isHighlightItem) {
const MColor colors[]
= { drawScene.GetWireframeColor(),
drawScene.GetSelectionHighlightColor(HdPrimTypeTokens->basisCurves),
Expand Down Expand Up @@ -986,21 +990,25 @@ void HdVP2BasisCurves::_UpdateDrawItem(
} else {
// Non-instanced Rprims.
if (itemDirtyBits & (DirtySelectionHighlight | HdChangeTracker::DirtyDisplayStyle)) {
if (drawItem->ContainsUsage(HdVP2DrawItem::kRegular)
&& drawItem->ContainsUsage(HdVP2DrawItem::kSelectionHighlight)) {
if (drawItem->ContainsUsage(HdVP2DrawItem::kRegular) && isHighlightItem) {
MHWRender::MShaderInstance* shader = nullptr;

auto primitiveType = MHWRender::MGeometry::kLines;
int primitiveStride = 0;

const MColor& color
= (_selectionStatus != kUnselected ? drawScene.GetSelectionHighlightColor(
_selectionStatus == kFullyLead ? TfToken()
: HdPrimTypeTokens->basisCurves)
: drawScene.GetWireframeColor());
MColor color;
if (inTemplateMode) {
color = drawScene.GetTemplateColor(_selectionStatus != kUnselected);
} else {
color
= (_selectionStatus != kUnselected ? drawScene.GetSelectionHighlightColor(
_selectionStatus == kFullyLead ? TfToken()
: HdPrimTypeTokens->basisCurves)
: drawScene.GetWireframeColor());
}

if (desc.geomStyle == HdBasisCurvesGeomStylePatch) {
if (_selectionStatus != kUnselected) {
if (_selectionStatus != kUnselected || inTemplateMode) {
if (refineLevel <= 0) {
shader = _delegate->Get3dSolidShader(color);
} else {
Expand Down Expand Up @@ -1060,19 +1068,26 @@ void HdVP2BasisCurves::_UpdateDrawItem(
| HdChangeTracker::DirtyPrimvar | HdChangeTracker::DirtyTopology
| DirtySelectionHighlight));

#ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT
if ((itemDirtyBits & DirtySelectionHighlight) && !isBoundingBoxItem) {
// update selection mask if dirty
if (itemDirtyBits & DirtySelectionHighlight) {
MSelectionMask selectionMask(MSelectionMask::kSelectNurbsCurves);

// Only unselected Rprims can be used for point snapping.
if (_selectionStatus == kUnselected) {
selectionMask.addMask(MSelectionMask::kSelectPointsForGravity);
#ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT
if (!isBoundingBoxItem) {
// Only unselected Rprims can be used for point snapping.
if (_selectionStatus == kUnselected) {
selectionMask.addMask(MSelectionMask::kSelectPointsForGravity);
}
}
#endif
// In template mode, items should have no selection
if (inTemplateMode) {
selectionMask = MSelectionMask();
}

// The function is thread-safe, thus called in place to keep simple.
renderItem->setSelectionMask(selectionMask);
}
#endif

// Reset dirty bits because we've prepared commit state for this draw item.
drawItem->ResetDirtyBits();
Expand Down
52 changes: 31 additions & 21 deletions lib/mayaUsd/render/vp2RenderDelegate/mayaPrimCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,10 +563,12 @@ void MayaUsdRPrim::_SyncSharedData(
HdSceneDelegate* delegate,
HdDirtyBits const* dirtyBits,
TfToken const& reprToken,
SdfPath const& id,
HdRprim const& refThis,
ReprVector const& reprs,
TfToken const& renderTag)
{
const SdfPath& id = refThis.GetId();

if (HdChangeTracker::IsExtentDirty(*dirtyBits, id)) {
sharedData.bounds.SetRange(delegate->GetExtent(id));
}
Expand All @@ -588,32 +590,40 @@ void MayaUsdRPrim::_SyncSharedData(
bool displayLayerVisibility = true; // objects in the default display layer are visible
#ifdef MAYA_HAS_DISPLAY_LAYER_API
bool hideOnPlayback = false;
_displayType = kNormal;
// Maya Display Layers do not have a representation in USD, so a prim can be
// visible from USD's point of view, but hidden from Maya's point of view.
// In Maya Display Layer visibility really hides the render items vs. using
// render item filtering (like for example the "Show" menu). So we want to
// set the "enabled" state of the MRenderItem.

// Get all the display layers the object is affected by. If any of those layers
// are invisible, the object is invisible.
MFnDisplayLayerManager displayLayerManager(
MFnDisplayLayerManager::currentDisplayLayerManager());
MStatus status;
auto* const param = static_cast<HdVP2RenderParam*>(_delegate->GetRenderParam());
ProxyRenderDelegate& drawScene = param->GetDrawScene();
MDagPath proxyDagPath = drawScene.GetProxyShapeDagPath();
MString pathString = proxyDagPath.fullPathName()
+ Ufe::PathString::pathSegmentSeparator().c_str() + _PrimSegmentString[0];
MObjectArray ancestorDisplayLayers
= displayLayerManager.getAncestorLayersInclusive(pathString, &status);
for (unsigned int i = 0; i < ancestorDisplayLayers.length() && displayLayerVisibility;
i++) {
MFnDependencyNode displayLayerNodeFn(ancestorDisplayLayers[i]);
MPlug layerEnabled = displayLayerNodeFn.findPlug("enabled");
MPlug layerVisible = displayLayerNodeFn.findPlug("visibility");
MPlug layerHidesOnPlayback = displayLayerNodeFn.findPlug("hideOnPlayback");
displayLayerVisibility &= layerEnabled.asBool() ? layerVisible.asBool() : true;
hideOnPlayback |= layerHidesOnPlayback.asBool();
// Display layer features are currently implemented only for non-instanced geometry
if (refThis.GetInstancerId().IsEmpty()) {
// Get all the display layers the object is affected by. If any of those layers
// are invisible, the object is invisible.
MFnDisplayLayerManager displayLayerManager(
MFnDisplayLayerManager::currentDisplayLayerManager());
MStatus status;
auto* const param = static_cast<HdVP2RenderParam*>(_delegate->GetRenderParam());
ProxyRenderDelegate& drawScene = param->GetDrawScene();
MDagPath proxyDagPath = drawScene.GetProxyShapeDagPath();
MString pathString = proxyDagPath.fullPathName()
+ Ufe::PathString::pathSegmentSeparator().c_str() + _PrimSegmentString[0];
MObjectArray ancestorDisplayLayers
= displayLayerManager.getAncestorLayersInclusive(pathString, &status);
for (unsigned int i = 0; i < ancestorDisplayLayers.length() && displayLayerVisibility;
i++) {
MFnDependencyNode displayLayerNodeFn(ancestorDisplayLayers[i]);
MPlug layerEnabled = displayLayerNodeFn.findPlug("enabled");
MPlug layerVisible = displayLayerNodeFn.findPlug("visibility");
MPlug layerHidesOnPlayback = displayLayerNodeFn.findPlug("hideOnPlayback");
MPlug layerDisplayType = displayLayerNodeFn.findPlug("displayType");
displayLayerVisibility &= layerEnabled.asBool() ? layerVisible.asBool() : true;
hideOnPlayback |= layerHidesOnPlayback.asBool();
if (_displayType == kNormal) {
_displayType = (DisplayType)layerDisplayType.asShort();
}
}
}

// Update "hide on playback" status
Expand Down
12 changes: 11 additions & 1 deletion lib/mayaUsd/render/vp2RenderDelegate/mayaPrimCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ class MayaUsdRPrim
void(const TfToken& name, const VtValue& value, const HdInterpolation interpolation)>;
using ErasePrimvarInfoFunc = std::function<void(const TfToken& name)>;

enum DisplayType
{
kNormal = 0,
kTemplate = 1,
kReference = 2
};

void _CommitMVertexBuffer(MHWRender::MVertexBuffer* const, void*) const;

void _UpdateTransform(
Expand Down Expand Up @@ -201,7 +208,7 @@ class MayaUsdRPrim
HdSceneDelegate* delegate,
HdDirtyBits const* dirtyBits,
TfToken const& reprToken,
SdfPath const& id,
HdRprim const& refThis,
ReprVector const& reprs,
TfToken const& renderTag);

Expand Down Expand Up @@ -259,6 +266,9 @@ class MayaUsdRPrim
//! HideOnPlayback status of the Rprim
bool _hideOnPlayback { false };

//! Display type of the Rprim
DisplayType _displayType { kNormal };

//! The string representation of the runtime only path to this object
MStringArray _PrimSegmentString;
};
Expand Down
82 changes: 54 additions & 28 deletions lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ void HdVP2Mesh::Sync(
const TfToken& renderTag = delegate->GetRenderTag(id);
#endif

_SyncSharedData(_sharedData, delegate, dirtyBits, reprToken, id, _reprs, renderTag);
_SyncSharedData(_sharedData, delegate, dirtyBits, reprToken, *this, _reprs, renderTag);

*dirtyBits = HdChangeTracker::Clean;

Expand Down Expand Up @@ -1456,12 +1456,16 @@ void HdVP2Mesh::_UpdateDrawItem(
const bool usingShadedSelectedInstanceItem = false;
#endif

// We don't need to update the dedicated selection highlight item when there
// is no selection highlight change and the mesh is not selected. Draw item
// has its own dirty bits, so update will be done when it shows in viewport.
const bool isDedicatedSelectionHighlightItem
const bool isDedicatedHighlightItem
= drawItem->MatchesUsage(HdVP2DrawItem::kSelectionHighlight);
if (isDedicatedSelectionHighlightItem && ((itemDirtyBits & DirtySelectionHighlight) == 0)
const bool isHighlightItem = drawItem->ContainsUsage(HdVP2DrawItem::kSelectionHighlight);
const bool inTemplateMode = _displayType == MayaUsdRPrim::kTemplate;
const bool inPureSelectionHighlightMode = isDedicatedHighlightItem && !inTemplateMode;

// We don't need to update the selection-highlight-only item when there is no selection
// highlight change and the mesh is not selected. Render item stores its own
// dirty bits, so the proper update will be done when it shows in the viewport.
if (inPureSelectionHighlightMode && ((itemDirtyBits & DirtySelectionHighlight) == 0)
&& (_selectionStatus == kUnselected)) {
return;
}
Expand Down Expand Up @@ -1722,7 +1726,7 @@ void HdVP2Mesh::_UpdateDrawItem(
unsigned char modeActive = invalid;
unsigned char modeLead = invalid;

if (!drawItem->ContainsUsage(HdVP2DrawItem::kSelectionHighlight)) {
if (!isHighlightItem) {
stateToCommit._instanceColorParam = kDiffuseColorStr;
if (!usingShadedSelectedInstanceItem) {
if (isShadedSelectedInstanceItem) {
Expand All @@ -1749,7 +1753,7 @@ void HdVP2Mesh::_UpdateDrawItem(
modeDormant = _selectionStatus == kFullyLead ? lead : active;
stateToCommit._instanceColorParam = kSolidColorStr;
} else {
modeDormant = isDedicatedSelectionHighlightItem ? invalid : dormant;
modeDormant = inPureSelectionHighlightMode ? invalid : dormant;
modeActive = active;
modeLead = lead;
stateToCommit._instanceColorParam = kSolidColorStr;
Expand Down Expand Up @@ -1950,12 +1954,16 @@ void HdVP2Mesh::_UpdateDrawItem(

} else {
// Non-instanced Rprims.
if ((itemDirtyBits & DirtySelectionHighlight)
&& drawItem->ContainsUsage(HdVP2DrawItem::kSelectionHighlight)) {
const MColor& color
= (_selectionStatus != kUnselected ? drawScene.GetSelectionHighlightColor(
_selectionStatus == kFullyLead ? TfToken() : HdPrimTypeTokens->mesh)
: drawScene.GetWireframeColor());
if ((itemDirtyBits & DirtySelectionHighlight) && isHighlightItem) {
MColor color;
if (inTemplateMode) {
color = drawScene.GetTemplateColor(_selectionStatus != kUnselected);
} else {
color
= (_selectionStatus != kUnselected ? drawScene.GetSelectionHighlightColor(
_selectionStatus == kFullyLead ? TfToken() : HdPrimTypeTokens->mesh)
: drawScene.GetWireframeColor());
}

MHWRender::MShaderInstance* shader = _delegate->Get3dSolidShader(color);
if (shader != nullptr && shader != drawItemData._shader) {
Expand All @@ -1975,14 +1983,18 @@ void HdVP2Mesh::_UpdateDrawItem(
bool enable = drawItem->GetVisible() && !_points(_meshSharedData->_primvarInfo).empty()
&& !instancerWithNoInstances;

if (isDedicatedSelectionHighlightItem) {
if (inPureSelectionHighlightMode) {
enable = enable && (_selectionStatus != kUnselected);
} else if (isPointSnappingItem) {
enable = enable && (_selectionStatus == kUnselected);
} else if (isBBoxItem) {
enable = enable && !range.IsEmpty();
}

if (inTemplateMode) {
enable = enable && isHighlightItem;
}

enable = enable && drawScene.DrawRenderTag(_meshSharedData->_renderTag);

if (drawItemData._enabled != enable) {
Expand All @@ -1996,26 +2008,40 @@ void HdVP2Mesh::_UpdateDrawItem(
& (HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyNormals
| HdChangeTracker::DirtyPrimvar | HdChangeTracker::DirtyTopology));

#ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT
if (!isBBoxItem && !isDedicatedSelectionHighlightItem
// Some items may require selection mask overrides
if (!isDedicatedHighlightItem && !isPointSnappingItem
&& (itemDirtyBits & (DirtySelectionHighlight | DirtySelectionMode))) {
bool dynamicSelectionMaskItem = false;
MSelectionMask selectionMask(MSelectionMask::kSelectMeshes);

bool shadedUnselectedInstances = !isShadedSelectedInstanceItem
&& !isDedicatedSelectionHighlightItem && !GetInstancerId().IsEmpty();
if (_selectionStatus == kUnselected || drawScene.SnapToSelectedObjects()
|| shadedUnselectedInstances) {
selectionMask.addMask(MSelectionMask::kSelectPointsForGravity);
#ifdef MAYA_NEW_POINT_SNAPPING_SUPPORT
if (!isBBoxItem) {
dynamicSelectionMaskItem = true;
bool shadedUnselectedInstances
= !isShadedSelectedInstanceItem && !GetInstancerId().IsEmpty();
if (_selectionStatus == kUnselected || drawScene.SnapToSelectedObjects()
|| shadedUnselectedInstances) {
selectionMask.addMask(MSelectionMask::kSelectPointsForGravity);
}
// Only unselected Rprims can be used for point snapping.
if (_selectionStatus == kUnselected && !shadedUnselectedInstances) {
selectionMask.addMask(MSelectionMask::kSelectPointsForGravity);
}
}
// Only unselected Rprims can be used for point snapping.
if (_selectionStatus == kUnselected && !shadedUnselectedInstances) {
selectionMask.addMask(MSelectionMask::kSelectPointsForGravity);
#endif
if (isHighlightItem) {
dynamicSelectionMaskItem = true;
// In template mode, items should have no selection
if (inTemplateMode) {
selectionMask = MSelectionMask();
}
}

// The function is thread-safe, thus called in place to keep simple.
renderItem->setSelectionMask(selectionMask);
if (dynamicSelectionMaskItem) {
// The function is thread-safe, thus called in place to keep simple.
renderItem->setSelectionMask(selectionMask);
}
}
#endif

// Capture buffers we need
MHWRender::MIndexBuffer* indexBuffer = drawItemData._indexBuffer.get();
Expand Down
Loading

0 comments on commit f24795c

Please sign in to comment.