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-123143 - As a user, I'd like my prims to be templated in a Display Layer #2508

Merged
merged 11 commits into from
Jul 28, 2022
Merged
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 @@ -1451,12 +1451,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 @@ -1717,7 +1721,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 @@ -1744,7 +1748,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 @@ -1945,12 +1949,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 @@ -1970,14 +1978,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 @@ -1991,26 +2003,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