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

Selection by kind #641

Merged
merged 2 commits into from
Jul 12, 2020
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
68 changes: 55 additions & 13 deletions lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include <pxr/base/tf/diagnostic.h>
#include <pxr/base/tf/stringUtils.h>
#include <pxr/usdImaging/usdImaging/delegate.h>
#include <pxr/usd/kind/registry.h>
#include <pxr/usd/usd/prim.h>
#include <pxr/usd/usd/modelAPI.h>
#include <pxr/imaging/hdx/renderTask.h>
#include <pxr/imaging/hdx/selectionTracker.h>
#include <pxr/imaging/hdx/taskController.h>
Expand Down Expand Up @@ -72,6 +75,7 @@ namespace
const HdReprSelector kSelectionReprSelector(HdVP2ReprTokens->selection);

#if defined(WANT_UFE_BUILD)
//! \brief Query the global selection list adjustment.
MGlobal::ListAdjustment GetListAdjustment()
{
// Keyboard modifiers can be queried from QApplication::keyboardModifiers()
Expand Down Expand Up @@ -101,6 +105,21 @@ namespace

return listAdjustment;
}

//! \brief Query the Kind to be selected from viewport.
//! \return A Kind token (https://graphics.pixar.com/usd/docs/api/kind_page_front.html). If the
//! token is empty or non-existing in the hierarchy, the exact prim that gets picked
//! in the viewport will be selected.
TfToken GetSelectionKind()
{
static const MString kOptionVarName("UsdSelectionKind");

if (MGlobal::optionVarExists(kOptionVarName)) {
MString optionVarValue = MGlobal::optionVarStringValue(kOptionVarName);
return TfToken(optionVarValue.asChar());
}
return TfToken();
}
#endif // defined(WANT_UFE_BUILD)

//! \brief Configure repr descriptions
Expand Down Expand Up @@ -489,8 +508,15 @@ void ProxyRenderDelegate::_Execute(const MHWRender::MFrameContext& frameContext)
const bool inPointSnapping = pointSnappingActive();

#if defined(WANT_UFE_BUILD)
// Query selection adjustment mode only if the update is triggered in a selection pass.
_globalListAdjustment = (inSelectionPass && !inPointSnapping) ? GetListAdjustment() : MGlobal::kReplaceList;
// Query selection adjustment and kind only if the update is triggered in a selection pass.
if (inSelectionPass && !inPointSnapping) {
_globalListAdjustment = GetListAdjustment();
_selectionKind = GetSelectionKind();
}
else {
_globalListAdjustment = MGlobal::kReplaceList;
_selectionKind = TfToken();
}
#endif // defined(WANT_UFE_BUILD)

#else // !defined(MAYA_ENABLE_UPDATE_FOR_SELECTION)
Expand Down Expand Up @@ -646,6 +672,31 @@ bool ProxyRenderDelegate::getInstancedSelectionPath(
}
#endif

// If update for selection is enabled, we can query Maya selection list adjustment and USD kind
// once per selection update to avoid cost of executing MEL command or searching optionVar for
// each intersection.
#if defined(MAYA_ENABLE_UPDATE_FOR_SELECTION)
const TfToken& selectionKind = _selectionKind;
const MGlobal::ListAdjustment& listAdjustment = _globalListAdjustment;
#else
const TfToken selectionKind = GetSelectionKind();
const MGlobal::ListAdjustment listAdjustment = GetListAdjustment();
#endif

// If selection kind is empty, the exact prim that gets picked from viewport should be selected
// thus no need to walk the scene hierarchy.
if (!selectionKind.IsEmpty()) {
UsdPrim prim = _proxyShapeData->UsdStage()->GetPrimAtPath(usdPath);
while (prim) {
TfToken kind;
if (UsdModelAPI(prim).GetKind(&kind) && KindRegistry::IsA(kind, selectionKind)) {
usdPath = prim.GetPath();
break;
}
prim = prim.GetParent();
}
}

const Ufe::PathSegment pathSegment(usdPath.GetText(), USD_UFE_RUNTIME_ID, USD_UFE_SEPARATOR);
const Ufe::SceneItem::Ptr& si = handler->createItem(_proxyShapeData->ProxyShape()->ufePath() + pathSegment);
if (!si) {
Expand All @@ -655,15 +706,7 @@ bool ProxyRenderDelegate::getInstancedSelectionPath(

auto globalSelection = Ufe::GlobalSelection::get();

// If update for selection is enabled, we can query selection list adjustment
// mode once per selection update to avoid any potential performance hit due
// to MEL command execution.
#if defined(MAYA_ENABLE_UPDATE_FOR_SELECTION)
switch (_globalListAdjustment)
#else
switch (GetListAdjustment())
#endif
{
switch (listAdjustment) {
case MGlobal::kReplaceList:
// The list has been cleared before viewport selection runs, so we
// can add the new hits directly. UFE selection list is a superset
Expand All @@ -678,8 +721,7 @@ bool ProxyRenderDelegate::getInstancedSelectionPath(
globalSelection->remove(si);
break;
case MGlobal::kXORWithList:
if (!globalSelection->remove(si))
{
if (!globalSelection->remove(si)) {
globalSelection->append(si);
}
break;
Expand Down
3 changes: 3 additions & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ class ProxyRenderDelegate : public MHWRender::MPxSubSceneOverride
#if defined(WANT_UFE_BUILD) && defined(MAYA_ENABLE_UPDATE_FOR_SELECTION)
//! Adjustment mode for global selection list: ADD, REMOVE, REPLACE, XOR
MGlobal::ListAdjustment _globalListAdjustment;

//! Token of the Kind to be selected from viewport. If it empty, select the exact prims.
TfToken _selectionKind;
#endif
};

Expand Down