-
Notifications
You must be signed in to change notification settings - Fork 4
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 highlighting, picking of MhFootPrint node, with test. #228
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,14 @@ | |
#include <maya/MGlobal.h> | ||
#include <maya/MFnDagNode.h> | ||
#include <maya/MModelMessage.h> | ||
#include <maya/MDagPath.h> | ||
#include <maya/MSelectionList.h> | ||
#include <maya/MPointArray.h> | ||
|
||
// MayaHydra headers. | ||
#include <mayaHydraLib/pick/mhPickHandler.h> | ||
#include <mayaHydraLib/pick/mhPickHandlerRegistry.h> | ||
#include <ufeExtensions/Global.h> | ||
|
||
//Flow viewport headers | ||
#include <flowViewport/API/fvpVersionInterface.h> | ||
|
@@ -50,6 +58,7 @@ | |
//Hydra headers | ||
#include <pxr/base/vt/array.h> | ||
#include <pxr/base/gf/vec3f.h> | ||
#include <pxr/imaging/hdx/pickTask.h> | ||
#include <pxr/imaging/hd/tokens.h> | ||
#include <pxr/imaging/hd/retainedSceneIndex.h> | ||
#include <pxr/imaging/hd/retainedDataSource.h> | ||
|
@@ -63,6 +72,40 @@ PXR_NAMESPACE_USING_DIRECTIVE | |
namespace { | ||
void nodeAddedToModel(MObject& node, void* clientData); | ||
void nodeRemovedFromModel(MObject& node, void* clientData); | ||
|
||
// Pick handler for the footprint node. | ||
|
||
class FootPrintPickHandler : public MayaHydra::PickHandler { | ||
public: | ||
|
||
FootPrintPickHandler(MObject& footPrintObj) : _footPrintObj(footPrintObj) {} | ||
|
||
bool handlePickHit( | ||
const Input& pickInput, Output& pickOutput | ||
) const override | ||
{ | ||
// Foot print parts are not selectable individually: only the complete | ||
// Maya shape object is selectable. | ||
// | ||
// Conceptually we could append a picked Maya object either to the | ||
// classic Maya MSelectionList selection or to the "MayaSelectTool" | ||
// named UFE selection (which provides input for the global selection). | ||
// However, the Maya select context filters out Maya items added to the | ||
// "MayaSelectTool" named UFE selection, so add to the MSelectionList. | ||
MDagPath dagPath; | ||
TF_AXIOM(MDagPath::getAPathTo(_footPrintObj, dagPath) == MS::kSuccess); | ||
pickOutput.mayaSelection.add(dagPath); | ||
const auto& wsPt = pickInput.pickHit.worldSpaceHitPoint; | ||
pickOutput.mayaWorldSpaceHitPts.append(wsPt[0], wsPt[1], wsPt[2]); | ||
|
||
return true; | ||
} | ||
|
||
private: | ||
|
||
MObject _footPrintObj; | ||
}; | ||
|
||
} | ||
|
||
//--------------------------------------------------------------------------- | ||
|
@@ -131,6 +174,8 @@ class MhFootPrint : public MPxLocatorNode | |
|
||
MCallbackId _nodeAddedToModelCbId{0}; | ||
MCallbackId _nodeRemovedFromModelCbId{0}; | ||
|
||
SdfPath _pathPrefix; | ||
}; | ||
|
||
namespace | ||
|
@@ -409,7 +454,8 @@ namespace { | |
//Trigger a call to compute so that everything is initialized | ||
MhFootPrint* footPrintInstance = reinterpret_cast<MhFootPrint*>(clientData); | ||
footPrintInstance->updateFootPrintPrims(); | ||
footPrintInstance->addedToModelCb(); | ||
// No need to call footPrintInstance->addedToModelCb(), as reading the | ||
// file will add the node to the model. | ||
} | ||
} | ||
|
||
|
@@ -552,19 +598,30 @@ void* MhFootPrint::creator() | |
|
||
void MhFootPrint::addedToModelCb() | ||
{ | ||
static const SdfPath noPrefix = SdfPath::AbsoluteRootPath(); | ||
_pathPrefix = SdfPath(TfStringPrintf("/MhFootPrint_%p", this)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lack of path prefix meant that the prefix was the Hydra scene index root. Thus, when foot print node was selected, the Hydra scene index root was selected, and all its children received selection highlighting, which is the normal and correct way to highlight children of a selected prim. Unfortunately, this meant that the whole scene was selection highlighted... Fixed with a proper Hydra scene index prefix. |
||
|
||
//Add the callback when an attribute of this node changes | ||
MObject obj = thisMObject(); | ||
_cbAttributeChangedId = MNodeMessage::addAttributeChangedCallback(obj, attributeChangedCallback, ((void*)this)); | ||
|
||
//Data producer scene index interface is used to add the retained scene index to all viewports with all render delegates | ||
auto& dataProducerSceneIndexInterface = Fvp::DataProducerSceneIndexInterface::get(); | ||
dataProducerSceneIndexInterface.addDataProducerSceneIndex(_retainedSceneIndex, noPrefix, (void*)&obj, FvpViewportAPITokens->allViewports,FvpViewportAPITokens->allRenderers); | ||
dataProducerSceneIndexInterface.addDataProducerSceneIndex(_retainedSceneIndex, _pathPrefix, (void*)&obj); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed default arguments. |
||
|
||
// Register a pick handler for our prefix with the pick handler registry. | ||
auto pickHandler = std::make_shared<FootPrintPickHandler>(obj); | ||
TF_AXIOM(MayaHydra::PickHandlerRegistry::Instance().Register(_pathPrefix, pickHandler)); | ||
|
||
// No need for a path mapper: the parts of the footprint are not selectable | ||
// individually, only the Maya shape, so the built-in Maya path mapper does | ||
// the job of path mapping for the footprint node. | ||
} | ||
|
||
void MhFootPrint::removedFromModelCb() | ||
{ | ||
// Unregister our pick handler. | ||
TF_AXIOM(MayaHydra::PickHandlerRegistry::Instance().Unregister(_pathPrefix)); | ||
|
||
//Remove the callback | ||
if (_cbAttributeChangedId){ | ||
CHECK_MSTATUS(MMessage::removeCallback(_cbAttributeChangedId)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,12 @@ | |
#include <ufe/path.h> | ||
#include <ufe/pathString.h> | ||
|
||
#include <pxr/imaging/hd/sceneIndexPrimView.h> | ||
|
||
#include <gtest/gtest.h> | ||
|
||
#include <regex> | ||
|
||
PXR_NAMESPACE_USING_DIRECTIVE | ||
|
||
using namespace MayaHydra; | ||
|
@@ -108,3 +112,29 @@ TEST(TestHydraPrim, translation) | |
constexpr double epsilon{1e-7}; | ||
ASSERT_TRUE(GfIsClose(primTranslation, expectedTranslation, epsilon)); | ||
} | ||
|
||
TEST(TestHydraPrim, countPrims) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New utility to count Hydra scene index prims, given a regular expression. |
||
{ | ||
const auto& sceneIndices = GetTerminalSceneIndices(); | ||
auto siRoot = sceneIndices.front(); | ||
|
||
auto [argc, argv] = getTestingArgs(); | ||
ASSERT_EQ(argc, 2); | ||
|
||
const std::regex r{argv[0]}; | ||
std::smatch m; | ||
const int expectedNbMatches{std::stoi(argv[1])}; | ||
int nbMatches{0}; | ||
|
||
for (const auto& primPath : | ||
HdSceneIndexPrimView(siRoot, SdfPath::AbsoluteRootPath())) { | ||
// Can't match temporary string, see | ||
// https://stackoverflow.com/questions/27391016 | ||
const std::string element = primPath.GetElementString(); | ||
if (std::regex_search(element, m, r)) { | ||
++nbMatches; | ||
} | ||
} | ||
|
||
ASSERT_EQ(nbMatches, expectedNbMatches); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,8 @@ class TestFootPrintNode(mtohUtils.MayaHydraBaseTestCase): #Subclassing mtohUtils | |
IMAGE_DIFF_FAIL_PERCENT = 0.1 | ||
imageVersion = None | ||
|
||
_requiredPlugins = ['mayaHydraCppTests'] | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
super(TestFootPrintNode, cls).setUpClass() | ||
|
@@ -257,5 +259,38 @@ def test_Load(self): | |
#using imageVersion as the color is different for this image under usd 24.11+ | ||
self.assertSnapshotClose("loadingFootPrintScene.png", self.IMAGE_DIFF_FAIL_THRESHOLD, self.IMAGE_DIFF_FAIL_PERCENT, self.imageVersion) | ||
|
||
# Test selection highlighting. When the footprint node is selected, only | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without the fixes for picking and selection highlighting, these two tests fail. With the fixes, these two tests pass. |
||
# its two Hydra scene index prims (heel and sole) should have a | ||
# _SelectionHighlight mirror hierarchy, and no other prim. | ||
def test_selectionHighlight(self): | ||
with PluginLoaded('mayaHydraFootPrintNode'): | ||
# Create a cube. | ||
cmds.polyCube() | ||
|
||
cmds.refresh() | ||
|
||
# Create a footprint node. It will be selected. | ||
cmds.createNode('MhFootPrint') | ||
|
||
cmds.refresh() | ||
|
||
# Traverse the scene starting at the root, and count the number | ||
# of _SelectionHighlight mirror hierarchies. There should be 2, | ||
# one for the heel and one for the sole of the footprint node. | ||
cmds.mayaHydraCppTest('.*_SelectionHighlight', 2, f="TestHydraPrim.countPrims") | ||
|
||
# Test picking. Once picked, the footprint node must appear in the global | ||
# selection. | ||
def test_picking(self): | ||
with PluginLoaded('mayaHydraFootPrintNode'): | ||
|
||
cmds.createNode('MhFootPrint') | ||
|
||
cmds.refresh() | ||
|
||
cmds.mayaHydraCppTest('|transform1|MhFootPrint1', f="TestUsdPicking.pickPrim") | ||
|
||
self.assertEqual(['MhFootPrint1'], cmds.ls(sl=True)) | ||
|
||
if __name__ == '__main__': | ||
fixturesUtils.runTests(globals()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Foot print node had no pick handler, picking did not work.