HYDRA-1058/HYDRA-970 : GeomSubsets picking filter + Fix multi-selection when single-picking#143
Conversation
…, and reconstruct it if MayaUSD is reloaded
…pport GeomSubset prims
|
|
||
| // Clear any registered callbacks | ||
| MGlobal::executeCommand("callbacks -cc mayaHydra;"); | ||
| MGlobal::executeCommand("callbacks -cc -owner mayaHydra;"); |
There was a problem hiding this comment.
Fixes the following error that was raised when trying to unload mayaHydra : When clearing callbacks, the owner must be specified. Note that mayaHydra still doesn't unload properly (and already didn't before this PR, even with this fix), but at least that's one issue down.
|
|
||
| const HdxPickHit& pickHit; | ||
| const MHWRender::MSelectionInfo& pickInfo; | ||
| const bool isSolePickHit; |
There was a problem hiding this comment.
Used to differentiate/handle the following behaviors from HYDRA-1058 :
- Marquee select only selects GeomSubsets, never the parent prims
- A single pick selects either a GeomSubset, or if the picked object is not a GeomSubset, the parent prim is selected
| UsdPickHandler(MtohRenderOverride& renderOverride) : | ||
| PickHandlerBase(renderOverride) {} | ||
|
|
||
| #if PXR_VERSION >= 2403 |
There was a problem hiding this comment.
GeomSubset Hydra prims were only added in USD 24.03
| // numeric path components are not allowed by SdfPath. Do so | ||
| // here with Ufe::Path, which has no such restriction. | ||
| return pickedMayaPath + std::to_string(instanceNdx); | ||
| std::vector<HitPath> hitPaths; |
There was a problem hiding this comment.
We now handle multiple paths, since a given component (e.g. face) of a mesh can be in more than one GeomSubset.
| pickParams.pickTarget = HdxPickTokens->pickPrimsAndInstances; | ||
| pickParams.resolveMode = singlePick ? HdxPickTokens->resolveNearestToCenter : HdxPickTokens->resolveUnique; | ||
| pickParams.doUnpickablesOcclude = false; | ||
| pickParams.viewMatrix.Set(viewMatrix.matrix); | ||
| pickParams.projectionMatrix.Set(adjustedProjMatrix.matrix); | ||
| pickParams.resolveMode = HdxPickTokens->resolveUnique; | ||
| pickParams.collection = _renderCollection; | ||
| pickParams.outHits = &outHits; |
There was a problem hiding this comment.
- Reorganized the params configuration to explicitly set the default values first, and then override them based on special behaviors afterwards.
- The
resolveModeis now different ifsinglePickis true : theresolveNearestToCentermode will only return the prim that is closest to the center of the selection. This fixes HYDRA-970. - Explicitly set
doUnpickablesOccludetofalse, as it was the default value and our existing behavior, to avoid unforeseen surprises if the default value ever changes.
| } else if (db.isFlagSet(_buildDate)) { | ||
| setResult(MhBuildInfo::buildDate()); | ||
| } else if (db.isFlagSet(_usdVersion)) { | ||
| setResult(PXR_VERSION); |
There was a problem hiding this comment.
We use PXR_VERSION to conditionally compile the GeomSubsets pick resolution code; since the feature can't be made available when building with earlier USD versions, we also need to not show the GeomSubsets pick filter UI in such cases. However, we had no way of determining what USD version the plugin was built with from MEL/Python; this added flag to the mayaHydra command does just that.
| // object is returned. Therefore test that the expected selected path is | ||
| // in the selection. | ||
| ASSERT_GE(sn->size(), 1u); | ||
| ASSERT_EQ(sn->size(), 1u); |
There was a problem hiding this comment.
Adjusted since we should no longer have more than one prim selected when single-clicking.
| cmds.setAttr('persp.translate', 15, 15, 10, type='float3') | ||
| cmds.setAttr('persp.rotate', -40, 60, 0, type='float3') |
There was a problem hiding this comment.
One of the tests previously clicked on the boundary between two prims, but was closer to the wrong prim than the correct one, and with the fix for HYDRA-970, this made the test fail. Adjusted the camera angle slightly so that the mouse click is on the correct prim.
| def Xform "CubeUpperHalfMarker" | ||
| { | ||
| double3 xformOp:translate = (-2, 0.5, 0) | ||
| uniform token[] xformOpOrder = ["xformOp:translate"] | ||
| } | ||
|
|
||
| def Xform "CubeLowerHalfMarker" | ||
| { | ||
| double3 xformOp:translate = (-2, -0.5, 0) | ||
| uniform token[] xformOpOrder = ["xformOp:translate"] | ||
| } | ||
|
|
||
| def Xform "SphereInstanceUpperHalfMarker" | ||
| { | ||
| double3 xformOp:translate = (2, 0.5, 0) | ||
| uniform token[] xformOpOrder = ["xformOp:translate"] | ||
| } | ||
|
|
||
| def Xform "SphereInstanceLowerHalfMarker" | ||
| { | ||
| double3 xformOp:translate = (2, -0.5, 0) | ||
| uniform token[] xformOpOrder = ["xformOp:translate"] | ||
| } |
There was a problem hiding this comment.
Markers are used for pointing the test mouse clicks at the right spots, as by default just using a prim's transform will point to its center, but we want to click at slightly different offsets from the center, and we can't use screen-space offsets, since viewport sizes can differ.
This PR adds GeomSubsets picking functionality, and extends the "USD Selection Mode" menu with a GeomSubsets section. Bundled with it is a fix for the HYDRA-970 issue where doing a single click could select more than one prim (the fix was required to properly implement the following behavior from HYDRA-1058 : "A single pick selects either a GeomSubset, or if the picked object is not a GeomSubset, the parent prim is selected").