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

HYDRA-1271 : Selection highlighting rework #240

Merged
merged 151 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
3b6b7c4
HYDRA-1132 : Handle missing cases of native instances picking
debloip-adsk Aug 29, 2024
d98f917
HYDRA-1132 : Begin refactoring UfePathToPrimSelections for native ins…
debloip-adsk Aug 30, 2024
985b816
Merge branch 'dev' into debloip/HYDRA-1132/pick-instanceable-prims
debloip-adsk Aug 30, 2024
c10e730
HYDRA-1132 : Initial implementation of UfePathToPrimSelections
debloip-adsk Sep 3, 2024
86bcef9
HYDRA-1132 : Cleanup UfePathToPrimSelections
debloip-adsk Sep 3, 2024
45dd420
HYDRA-1132 : Adjust selection data sources
debloip-adsk Sep 3, 2024
bac81da
HYDRA-1132 : Add prototypes test
debloip-adsk Sep 3, 2024
3284e78
Merge branch 'dev' into debloip/HYDRA-1132/pick-instanceable-prims
debloip-adsk Sep 3, 2024
f757027
HYDRA-1132 : Fix tests
debloip-adsk Sep 3, 2024
d3ed4a1
HYDRA-1132 : Adjust comment
debloip-adsk Sep 3, 2024
6e454f5
HYDRA-1132 : Fix tests
debloip-adsk Sep 3, 2024
712db34
HYDRA-1132 : Add comment
debloip-adsk Sep 3, 2024
9ca0976
HYDRA-1132 : Add missing changes to test file
debloip-adsk Sep 4, 2024
7824d8f
HYDRA-1132 : Adjust camera position to accomodate different viewport …
debloip-adsk Sep 4, 2024
658f061
HYDRA-1132 : Fix Linux error
debloip-adsk Sep 4, 2024
af87b9a
HYDRA-1132 : Add references to USD schemas
debloip-adsk Sep 4, 2024
6df39d1
HYDRA-1132 : Add ending newline
debloip-adsk Sep 4, 2024
8d59cfc
HYDRA-1161 : Rename variables
debloip-adsk Sep 5, 2024
f13b0ab
stash
debloip-adsk Sep 11, 2024
37fa378
Fix crashes
debloip-adsk Sep 11, 2024
b5ca1f9
wireframe appears
debloip-adsk Sep 12, 2024
8542461
fix deselection
debloip-adsk Sep 12, 2024
3f8ca4d
dirty notifications for lead/active color changes
debloip-adsk Sep 12, 2024
07150d2
add selection index
debloip-adsk Sep 12, 2024
8b9c95e
initial compile of point instancer highlight
debloip-adsk Sep 12, 2024
c4d2efb
functional point instancer highlight
debloip-adsk Sep 12, 2024
69ef39c
remove extra prototypes in selection highlight hierarchy for point in…
debloip-adsk Sep 13, 2024
0bdb635
edit native instance scene
debloip-adsk Sep 13, 2024
89594b7
indirect highlights for meshes
debloip-adsk Sep 13, 2024
6af8c4f
basic native instance prototype highlight structure
debloip-adsk Sep 13, 2024
85ba57e
set native instance prototype xform
debloip-adsk Sep 13, 2024
a9df612
implement per-selection wireframe colors
debloip-adsk Sep 13, 2024
ff7f3c5
native instance highlighting
debloip-adsk Sep 13, 2024
1b80e03
point instance prototype highlighting
debloip-adsk Sep 16, 2024
3cd70cd
add comment
debloip-adsk Sep 16, 2024
9507490
Merge branch 'dev' into debloip/HYDRA-1161/native-instance-highlighting
debloip-adsk Sep 24, 2024
48c3138
Merge branch 'dev' into debloip/HYDRA-1271/selection-highlight-refactor
debloip-adsk Nov 20, 2024
dafe523
HYDRA-1271 : Point Instancer highlight rework phase 1 - scene structure
debloip-adsk Nov 28, 2024
bf65405
HYDRA-1271 : Fix GetPrim for point instancers
debloip-adsk Nov 28, 2024
cc97839
HYDRA-1271 : Fix lead color dirtying
debloip-adsk Nov 29, 2024
b03f055
HYDRA-1271 : Delete commented code
debloip-adsk Dec 2, 2024
b0f091c
HYDRA-1271 : Start setting up base wireframe highlight scene index
debloip-adsk Dec 3, 2024
1900d66
HYDRA-1271 : Functional standalone point instancer highlight scene index
debloip-adsk Dec 4, 2024
2188d05
HYDRA-1271 : Remove dead code
debloip-adsk Dec 4, 2024
f4f4666
HYDRA-1271 : Change selection id to string
debloip-adsk Dec 4, 2024
05b37ca
HYDRA-1271 : Rename selectionId to highlightId
debloip-adsk Dec 4, 2024
649b364
HYDRA-1271 : Mesh highlighting
debloip-adsk Dec 4, 2024
b19b8ef
HYDRA-1271 :
debloip-adsk Dec 4, 2024
7a7598e
HYDRA-1271 : Add excluded path support
debloip-adsk Dec 4, 2024
8d1cea6
HYDRA-1271 : Use excluded paths
debloip-adsk Dec 4, 2024
3dd9504
HYDRA-1271 : Exclude prototype meshes from mesh highlighting
debloip-adsk Dec 4, 2024
15273fd
HYDRA-1271 : Add native instance highlighting
debloip-adsk Dec 11, 2024
521ae59
HYDRA-1271 : Dirtying of wireframe colors for native instances
debloip-adsk Dec 12, 2024
2b1149b
HYDRA-1271 : Native instance prototype highlighting
debloip-adsk Dec 13, 2024
89bfc35
HYDRA-1271 : GeomSubset highlighting
debloip-adsk Dec 19, 2024
50d0fae
HYDRA-1271 : Point instance instance highlighting
debloip-adsk Dec 19, 2024
a4ed6c1
HYDRA-1271 : Point instance prototype highlight files
debloip-adsk Jan 13, 2025
6675476
HYDRA-1271 : Point instance prototype highlight
debloip-adsk Jan 13, 2025
06f0b06
HYDRA-1271 : Remove unused method
debloip-adsk Jan 14, 2025
9a8c98a
HYDRA-1271 : Extract ForEachPrimInHierarchy and CollectInstancingPaths
debloip-adsk Jan 14, 2025
973e6d0
HYDRA-1271 : Extract ConvertHydraToFvpSelection
debloip-adsk Jan 14, 2025
238ba9c
HYDRA-1271 : Extract RepathingDataSource
debloip-adsk Jan 14, 2025
1109040
HYDRA-1271 : Partial cleanup
debloip-adsk Jan 15, 2025
8eb6776
HYDRA-1271 : Add comments
debloip-adsk Jan 15, 2025
153a769
HYDRA-1271 : Cleanup + bugfix geomsubset highlights
debloip-adsk Jan 15, 2025
bad9b8b
HYDRA-1271 : Mesh highlight bugfix
debloip-adsk Jan 15, 2025
99d894d
HYDRA-1271 : Mesh highlight cleanup
debloip-adsk Jan 15, 2025
225d34a
HYDRA-1271 : GeomSubset highlight cleanup
debloip-adsk Jan 15, 2025
9b4eb99
HYDRA-1271 : Fix crash with native instance prototype highlight
debloip-adsk Jan 15, 2025
3de7e25
HYDRA-1271 : Add guard clauses and rename parameters
debloip-adsk Jan 15, 2025
462d480
HYDRA-1271 : Fix mesh highlight colors
debloip-adsk Jan 16, 2025
1a4b039
HYDRA-1271 : Fix testPrimInstancing
debloip-adsk Jan 16, 2025
2e9f5c0
HYDRA-1271 : See previous commit
debloip-adsk Jan 16, 2025
e57bd1a
HYDRA-1271 : Update testDataProducerSelectionHighlight reference image
debloip-adsk Jan 16, 2025
f6a4910
HYDRA-1271 : Port point instancing and geom subset highlight tests to…
debloip-adsk Jan 16, 2025
7f0235c
HYDRA-1271 : Adjust reference image
debloip-adsk Jan 16, 2025
73f71cf
HYDRA-1271 : Add mechanism to simplify handling parent selection changes
debloip-adsk Jan 16, 2025
ebb8a5e
HYDRA-1271 : Remove redundant variables
debloip-adsk Jan 16, 2025
79c8532
HYDRA-1271 ; Handle parent selection for point instancers (WIP)
debloip-adsk Jan 16, 2025
afaef83
HYDRA-1271 : Bugfix for point instancer highlight
debloip-adsk Jan 16, 2025
250392e
HYDRA-1271 : Don't create highlight for prototype point instancers
debloip-adsk Jan 16, 2025
cae71df
HYDRA-1271 : Delete old test files
debloip-adsk Jan 16, 2025
f62710e
HYDRA-1271 : Update reference images for point instancing
debloip-adsk Jan 16, 2025
a0e859d
HYDRA-1271 : For previous commit
debloip-adsk Jan 16, 2025
28fe7ed
HYDRA-1271 : Update point instancing test for robustness
debloip-adsk Jan 16, 2025
20a5a81
HYDRA-1271 : Update test file
debloip-adsk Jan 17, 2025
4028b4f
HYDRA-1271 : Add native instance highlighting test
debloip-adsk Jan 17, 2025
ca38d16
HYDRA-1271 : Add mesh highlighting test
debloip-adsk Jan 17, 2025
4e48647
HYDRA-1271 : Handle GeomSubset point instance prototype highlights
debloip-adsk Jan 17, 2025
d9d5881
HYDRA-1271 : Dirty wireframe colors for geomsubset highlights
debloip-adsk Jan 17, 2025
f61c38f
HYDRA-1271 : Fix color updates on native instance prototype highlights
debloip-adsk Jan 17, 2025
370e905
HYDRA-1271 : Exclude highlights from notification processing
debloip-adsk Jan 17, 2025
1371ae4
HYDRA-1271 : Cleanup geomSubset highlights
debloip-adsk Jan 17, 2025
f365914
HYDRA-1271 : Add missing path exclusion handling
debloip-adsk Jan 17, 2025
6ac782b
HYDRA-1271 : Add guard clause
debloip-adsk Jan 17, 2025
7cee360
HYDRA-1271 : Exclude maya path from flow highlights
debloip-adsk Jan 17, 2025
eb0649a
HYDRA-1271 : Fix compilation errors
debloip-adsk Jan 17, 2025
3015430
HYDRA-1271 : Extend GeomSubset highlight test
debloip-adsk Jan 17, 2025
4019f92
HYDRA-1271 : GeomSubset wireframe color change test
debloip-adsk Jan 17, 2025
e1a8885
HYDRA-1271 : Mesh wireframe color change test
debloip-adsk Jan 17, 2025
77551aa
HYDRA-1271 : Native instancing wireframe color change test
debloip-adsk Jan 17, 2025
4e3551d
HYDRA-1271 : Point instancing wireframe color change test
debloip-adsk Jan 17, 2025
f86dd18
HYDRA-1271 : Remove old wireframe highlight test
debloip-adsk Jan 17, 2025
bf015bd
HYDRA-1271 : Fix crash due to iterating while modifying containers
debloip-adsk Jan 20, 2025
f596176
HYDRA-1271 : Remove old/dead code and fix picking exclude paths
debloip-adsk Jan 20, 2025
d169549
Merge branch 'dev' into debloip/HYDRA-1271/selection-highlight-refact…
debloip-adsk Jan 20, 2025
b5fa134
HYDRA-1271 : Fix merge and update footprint selection highlight test
debloip-adsk Jan 20, 2025
4e597a4
HYDRA-1271 : Update copyright years, compile GeomSubset code conditio…
debloip-adsk Jan 20, 2025
bb8355f
Merge branch 'dev' into debloip/HYDRA-1271/selection-highlight-refact…
debloip-adsk Jan 20, 2025
2a1797b
HYDRA-1271 : Conditionally add GeomSubset highlight SI
debloip-adsk Jan 20, 2025
c47c18b
HYDRA-1271 : Skip highlight tests on OSX
debloip-adsk Jan 20, 2025
b8c7e21
HYDRA-1271 : Remove unneeded include
debloip-adsk Jan 20, 2025
df19a17
HYDRA-1271 : Skip footprintnode highlight test on OSX
debloip-adsk Jan 20, 2025
95e2c69
HYDRA-1271 : Skip GeomSubset highlight test if USD version does not s…
debloip-adsk Jan 20, 2025
95cf48f
HYDRA-1271 : Commit for preflight test
debloip-adsk Jan 20, 2025
00f180d
HYDRA-1271 : Cleanup BaseWhSi
debloip-adsk Jan 20, 2025
f3cca52
Revert "HYDRA-1271 : Commit for preflight test"
debloip-adsk Jan 20, 2025
19229fe
HYDRA-1271 Headers cleanup
debloip-adsk Jan 20, 2025
0328bda
HYDRA-1271 : Remove unused struct
debloip-adsk Jan 20, 2025
1dbf292
HYDRA-1271 : Minor touchup
debloip-adsk Jan 20, 2025
7de89e4
HYDRA-1271 : Add short description of selection highlight scene indices
debloip-adsk Jan 20, 2025
7870757
HYDRA-1271 : Adjust point instancing wireframe test to test another s…
debloip-adsk Jan 20, 2025
edd3efd
HYDRA-1271 : Remove comment
debloip-adsk Jan 20, 2025
7ba3c26
HYDRA-1271 : Adjust mesh notifications for consistency
debloip-adsk Jan 20, 2025
942af33
HYDRA-1271 : Add visualizations for the selection highlight sub-hiera…
debloip-adsk Jan 20, 2025
affedf7
HYDRA-1271 : Commit to collect preflight results
debloip-adsk Jan 20, 2025
78e628a
HYDRA-1271 : Adjust lighting by USD version
debloip-adsk Jan 21, 2025
0f70824
Revert "HYDRA-1271 : Commit to collect preflight results"
debloip-adsk Jan 21, 2025
1a4e62b
HYDRA-1271 : Remove materials from test scenes
debloip-adsk Jan 21, 2025
0cfe298
HYDRA-1271 : Adjust thresholds
debloip-adsk Jan 21, 2025
402c4d8
HYDRA-1271 : Edit comments
debloip-adsk Jan 21, 2025
fe44259
HYDRA-1271 : Remove expected failure test
debloip-adsk Jan 21, 2025
ff22bf0
HYDRA-1271 : Adjust geomSubset ProcessRemovedPrims for consistency
debloip-adsk Jan 21, 2025
c72f302
HYDRA-1271 : Remove empty anonymous namespace
debloip-adsk Jan 23, 2025
22b9d2a
HYDRA-1271 : Slight tweak to mhWireframeColorInterface
debloip-adsk Jan 23, 2025
b96b8c5
HYDRA-1271 : Make PR comment into code comments
debloip-adsk Jan 23, 2025
aceaf64
HYDRA-1271 : Rename files for fvp nomenclature
debloip-adsk Jan 23, 2025
7f25515
HYDRA-1271 : Update existing selection highlight architecture doc
debloip-adsk Jan 23, 2025
4722c27
HYDRA-1271 : Fix BaseWhSi::HasFullySelectedAncestorInclusive
debloip-adsk Jan 23, 2025
9c0b69b
HYDRA-1271 : Re-implement previous intended behavior
debloip-adsk Jan 23, 2025
180db2e
HYDRA-1271 : Add PR description as README + re-add instancing explana…
debloip-adsk Jan 23, 2025
33b9728
HYDRA-1271 : Corrections to selection highlighting architecture doc
debloip-adsk Jan 23, 2025
6e541f8
HYDRA-1271 : Further corrections
debloip-adsk Jan 23, 2025
e2804e1
HYDRA-1271 : Extend HasFullySelectedAncestorInclusive to most uses of…
debloip-adsk Jan 24, 2025
fcd8887
HYDRA-1271 : Use utility method in HasFullySelectedAncestorInclusive
debloip-adsk Jan 24, 2025
a200ad8
HYDRA-1271 : Use utility in viewport filtering
debloip-adsk Jan 24, 2025
603f5c1
HYDRA-1271 : Simplify utiltiy method
debloip-adsk Jan 24, 2025
1f46a85
HYDRA-1271 : Edit doc
debloip-adsk Jan 24, 2025
93862d7
HYDRA-1271 : Fix 2025 builds
debloip-adsk Jan 24, 2025
ca939ed
HYDRA-1271 : Add requirements section
debloip-adsk Jan 24, 2025
0a63dcf
HYDRA-1271 : Update requirements
debloip-adsk Jan 24, 2025
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
259 changes: 21 additions & 238 deletions doc/selectionHighlightingArchitecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ supports Hydra rendering in this repository as the Flow Viewport Toolkit (name
subject to change).

This document will describe the state of Flow Viewport Toolkit selection
highlighting as of 5-Dec-2024.
highlighting as of 23-Jan-2025.

## Behavior

Expand All @@ -18,9 +18,8 @@ are shown differently in the viewport for ease of understanding.

An application will provide a way to select an object, or to select components
of an object. For example, for a mesh object, these components may be points,
edges, or faces. Currently, only object selection highlighting and point
instancing highlighting of meshes are supported. Selection highlighting of
components is unimplemented.
edges, or faces. Currently, highlighting is provided for object-level, point
instancing and native instancing selections of meshes and geomSubsets of faces.

## Selection: Application versus Hydra

Expand Down Expand Up @@ -95,12 +94,11 @@ path mapper and returns the Hydra scene index paths.

### Wireframe Selection Highlighting

This
[wireframe selection highlighting code](../lib/flowViewport/sceneIndex/fvpWireframeSelectionHighlightSceneIndex.cpp)
shows the use of the *Selection*, through the
*IsFullySelected()* method, called on the input selection.
The selection allows a selection highlighting filtering scene index to query
selected prims. It can also query the *selections* data source on a prim to determine selection status.
The [wireframe selection highlighting scene indices](../lib/flowViewport/sceneIndex/wireframeHighlights/)
use the selection data sources on Hydra prims to create corresponding wireframe highlights.
It does not matter to these scene indices where the selection data sources come from; what matters
is that these scene indices be positioned in the scene index chain after all necessary selection
data source providers have applied their selections.

## Design Option Discussion

Expand Down Expand Up @@ -171,8 +169,6 @@ graph BT;
ph1[Plugin highlighting 1]-->hm;
subgraph ph[Plugin highlighting]
ph2[Plugin highlighting 2]-->ph1;
roSn[/Read-only Selection/]-.->ph1;
roSn-.->ph2;
end
snSi[Selection scene index]-->ph2;
dpm[Data producer merge]-->snSi;
Expand All @@ -194,18 +190,17 @@ index is optional.
The object modeling is the following:
- **Selection**: builtin provided by the Flow Viewport Toolkit.
- Encapsulates the Hydra selection as scene index paths and selection data sources.
- Is shared by the selection scene index and all selection highlighting
scene indices.
- Is used by the selection scene index.
- **Selection scene index**: builtin provided by the Flow Viewport Toolkit.
- Has a pointer to read and write the Hydra selection.
- Translates the application selection to Hydra selection.
- **Plugin data scene index**: provided by plugin.
- Injects plugin data into Hydra
- **Plugin selection highlighting scene index**: provided by plugin.
- Has a pointer to a read-only view of the Hydra selection.
- Processes dirty selection notifications to dirty the appropriate prim(s)
in plugin data, including hierarchical selection highlighting
- Adds required geometry or data sources to implement selection
- **Plugin selection highlighting scene indices**: provided by plugin.
- Process dirty selection notifications to create corresponding
wireframe highlights for plugin data, including hierarchical
selection highlighting
- Add required geometry or data sources to implement selection
highlighting

### New Path Mapper Base Class
Expand All @@ -219,11 +214,11 @@ The Flow Viewport Toolkit has a new base class:

### Implementation Classes

- **Wireframe selection highlighting scene index**:
- Uses Hydra HdRepr to add wireframe representation to selected objects
- **Wireframe selection highlighting scene indices (classes suffixed by WhSi)**:
- Use Hydra HdRepr to create wireframe representations of selected objects
*and their descendants*.
- Requires selected ancestor query from selection.
- Dirties descendants on selection dirty.
- Use Hydra selection data sources to determine when & how to create wireframe highlights.
- Update wireframe highlights when selected prims are dirtied.
- **Render index proxy**:
- Provides encapsulated access to the data producer merging scene
index. This is a standard Hydra merging scene index to which Flow
Expand All @@ -244,7 +239,7 @@ class Selection{
}

class SelectionSceneIndex
class WireframeSelectionHighlightSceneIndex
class BaseWhSi

class RenderIndexProxy{
+HdMergingSceneIndex mergingSceneIndex
Expand All @@ -254,18 +249,16 @@ class RenderIndexProxy{

HdSingleInputFilteringSceneIndexBase <|-- SelectionSceneIndex

HdSingleInputFilteringSceneIndexBase <|-- WireframeSelectionHighlightSceneIndex
HdSingleInputFilteringSceneIndexBase <|-- BaseWhSi

RenderIndexProxy *-- HdMergingSceneIndex : Owns

SelectionSceneIndex o-- Selection : Read / Write

WireframeSelectionHighlightSceneIndex o-- Selection : Read
```

## Algorithmic Complexity

- At time of writing, for an n-element selection, membership lookup is O(log n)
- In the Flow Viewport Selection, for an n-element selection, membership lookup is O(log n)
(map of SdfPath). Ancestor membership lookup is O(n), as we loop through
each selected path and inspect the selected path prefix. This could be much
improved (to amortized O(k), for a k-element path) through the use of a
Expand All @@ -284,213 +277,3 @@ WireframeSelectionHighlightSceneIndex o-- Selection : Read
propagate across scene index inputs, so that if a Maya Dag ancestor is
selected, a USD descendant's appearance can change. This is the same
situation as global transformation and visibility.

## Mesh point instancing wireframe selection highlighting
ppt-adsk marked this conversation as resolved.
Show resolved Hide resolved

We currently support wireframe selection highlighting for point instancing of meshes
for the three different point instancing selection modes :

- Point Instancer

![Point instancer selection highlight](images/pointInstancerSelectionHighlight.png)

- Instance

![Instance selection highlight](images/instanceSelectionHighlight.png)

- Prototype

![Prototype selection highlight](images/prototypeSelectionHighlight.png)

Here is an overview of how point instancing works in Hydra, and how we implement
wireframe selection highlighting for it.

### Scene index structure

In Hydra, a point instancer is represented as a prim of type `instancer`,
with an `instancerTopology` data source.

![instancerTopology data source](images/instancerTopology.png)

This data source contains three relevant inner data sources :
- The `prototypes` data source, of type `VtArray<SdfPath>`, lists the paths
to each prototype this point instancer instances.
- The `instanceIndices` data source, a vector data source where each element
data source (`i0, i1, i2, etc.`) is of type `VtArray<int>` and contains
which instances correspond to which prototype. For example, if `i1` contains
`0, 3`, then the first and fourth instances will be using the second prototype.
- The `mask` data source, of type `VtArray<bool>`, which can optionally be used
to show/hide specific instances (e.g. if the 3rd element of the mask is `false`,
then the 3rd instance will be hidden). If this array is empty, all instances will be
shown.

---

Per-instance data is specified using primvar data sources, namely :
- hydra:instanceTranslations
- hydra:instanceRotations
- hydra:instanceScales
- hydra:instanceTransforms

![instanceTranslations primvar data source](images/instanceTranslations.png)

Where the corresponding primvarValue data source lists the instance-specific data.
Note that while the first three are 3-dimensional vectors and `hydra:instanceTransforms`
is a 4x4 matrix, they can all be used simultaneously (internally, they will all be
converted to 4x4 matrices, and then multiplied together).

---

On the other end of instancing, prototype prims have an `instancedBy` data source.

![instancedBy data source](images/instancedBy.png)

This data source contains up to two inner data sources :
- (required) : The `paths` data source, of type `VtArray<SdfPath>`, lists the paths
to each instancer that instances this prototype.
- (optional) : When a sub-hierarchy is prototyped, the `prototypeRoots`, of type
`VtArray<SdfPath>`, lists the paths to the roots of the sub-hierarchies that are being
prototyped. For example, if we are instancing an xform that has a child mesh,
then the prototype xform and mesh prims will each have the same `instancedBy` data source,
where the `paths` data source will point to the instancers that use this prototype, and
where the `prototypeRoots` will point to the xform prim.

---

Some notes about the behavioral impacts of the hierarchical location of prims :
- Prims that are rooted under an instancer will not be drawn unless instanced
- Prototypes that are instanced will still be drawn as if they were not instanced
(i.e. the instances will be drawn in addition to the base prim itself), unless as
mentioned they are rooted under an instancer.

### Nested/Composed instancers

It is possible for an instancer itself to be instanced by another, and thus have both the
`instancerTopology` and the `instancedBy` data sources. Note that this does not preclude
such a prototyped instancer from also drawing geometry itself. If the prototyped instancer
is a child of the instancing instancer, then yes, such a nested instancer will not draw by
itself, and will be instance-drawn through the parent instancer. However, if the prototyped
instancer has no parent instancer, but it is instanced by another instancer somewhere else
in the hierarchy, then both the prototyped instancer will draw as if it were by itself, but
also be instance-drawn by the other instancer.

This nesting and composition of instancers is what leads to most of the complexity of point
instancing selection highlighting. We can view such nesting and composition of instancers as
graphs, with the vertices being the instancer prims, and the edges being the paths contained
in the `instancerTopology/prototypes`, `instancedBy/paths` and `instancedBy/prototypeRoots`
data sources, as well as parent-child relationships.

For example, given the following scene structure :
```
Root
|__TopInstancer
| |__NestedInstancer
| | |__LeafInstancer
| | |__PrototypePrim
| | |__PrototypeSubPrim
|__AnotherPrototypePrim
|__ChildInstancer
```

```mermaid
graph LR
TopInstancer -->|instancerTopology/prototypes| NestedInstancer
NestedInstancer -->|instancerTopology/prototypes| LeafInstancer
LeafInstancer -->|instancedBy/paths| NestedInstancer
NestedInstancer -->|instancedBy/paths| TopInstancer
LeafInstancer -->|instancerTopology/prototypes| PrototypePrim
PrototypePrim -->|instancedBy/paths| LeafInstancer
PrototypeSubPrim -->|instancedBy/prototypeRoots| PrototypePrim

TopInstancer -->|instancerTopology/prototypes| AnotherPrototypePrim
AnotherPrototypePrim -->|parent-child relationship| ChildInstancer
ChildInstancer -->|instancedBy/prototypeRoots| AnotherPrototypePrim
ChildInstancer -->|instancedBy/paths| TopInstancer
```

### Implementation for point instancer and instance selection

This section will focus on selection highlighting when trying to highlight point instancers
as a whole or specific instances, as these require a more complicated workflow. Unlike standard
selection, we cannot simply override instanced meshes to use the `refinedWireOnSurf`/`wireOnSurf`
HdReprs, as that would lead to highlighting all instances of the prototype all the time. Instead,
we opt for the following approach : when an instancer is selected (entirely or only certain instances),
we will create a mirror of the instancing graph it is a part of, and make the mirror copies of the
instanced meshes draw with a wireframe representation. This mirror graph includes everything from
the most deeply buried prims to the topmost instancers; anything that this instancer affects or is
affected by, including itself. In practice, this means that each prototype and each instancer will
have a corresponding mirror prim for selection highlighting, that will be located alongside it as
a sibling. This way, any parent transforms affecting the original prim will also affect the selection
highlight mirror prim.

For example, given the following scene structure :
```
Root
|__TopInstancer
|__NestedInstancer
|__Prototype
```
the resulting scene structure with selection highlighting would become :
```
Root
|__TopInstancer
| |__NestedInstancer
| | |__Prototype
| | |__Prototype_SelectionHighlight
| |__NestedInstancer_SelectionHighlight
|__TopInstancer_SelectionHighlight
```
where `TopInstancer_SelectionHighlight` would instance `NestedInstancer_SelectionHighlight`, which would in turn instance `Prototype_SelectionHighlight`.

Note that in the case where a prototype is not a single prim but a sub-hierarchy, we only need to
create a single *explicit* selection highlight mirror prim for the whole prototype sub-hierarchy; the
child prims of the selection highlight mirror will simply be pulled from the corresponding original
prim, and thus implicitly be selection highlight mirrors as well.

Another thing to be aware of is that a nested/composed instancer is not necessarily directly selected,
as it is not necessarily a prototype root itself. If an instancer is a child prim of another prim
that is itself selected or instanced by another instancer, these instancers are still composed
together, but will not point to each other directly. Such cases are an example of when we need to
use the `instancedBy/prototypeRoots` data source to properly construct the mirror graph of instancers.

An example of this is the following :
```
Root
|__TopInstancer
|__Prototype
|__ChildInstancer
```
for which we end up with :
```
Root
|__TopInstancer
| |__Prototype
| | |__ChildInstancer
| |__Prototype_SelectionHighlight
| |__ChildInstancer
|__TopInstancer_SelectionHighlight
```
where `TopInstancer_SelectionHighlight` instances `Prototype_SelectionHighlight`, which implicitly draws the selection highlight version of `ChildInstancer`.

Of note are the following selection highlighting scenarios and their corresponding behaviors :
- Selecting a point instancer in its entirety
- If the instancer is a top-level instancer, all instances it draws WILL be highlighted.
- If the instancer is a prototype, instances of itself drawn by other instancers will NOT be highlighted.
This is an intentional workflow decision from the Hydra for Maya team.
- Selecting specific instances of point instancer
- If the instancer is a top-level instancer, the selected instances it draws WILL be highlighted.
- If the instancer is a prototype, the instances it would indirectly draw through instances of itself drawn by other instancers will NOT be highlighted.
This is an intentional workflow decision from the Hydra for Maya team.
- Selecting a parent prim of a point instancer
- (same as selecting a point instancer in its entirety)

### Implementation for prototype selection

We simply do as for a regular selection, and override the original prim's display style
to draw as a wireframe-on-surface representation.

### Current limitations

- The wireframe colors for point instancer & instance selections might not always be correct (with
respect to the lead/active selection colors). However, prototype selections should be using the
correct colors.
33 changes: 33 additions & 0 deletions lib/flowViewport/fvpUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,39 @@ class PrimvarDataSource final : public PXR_NS::HdContainerDataSource

PXR_NS::HdDataSourceBaseHandle createSelectionDataSource(const PrimSelection& selection);

template<typename PathContainer>
auto FindSelfOrFirstParent(const PXR_NS::SdfPath& path, const PathContainer& container) -> decltype(container.cend()) {
PXR_NS::SdfPath currPath = path;
while (!currPath.IsEmpty()) {
auto foundIt = container.find(currPath);
if (foundIt != container.cend()) {
return foundIt;
}
else {
currPath = currPath.GetParentPath();
}
}
return container.cend();
}

inline
auto FindSelfOrFirstChild(const PXR_NS::SdfPath& path, const std::set<PXR_NS::SdfPath>& pathSet) -> decltype(pathSet.cend()) {
auto itPath = pathSet.lower_bound(path);
if (itPath != pathSet.cend() && itPath->HasPrefix(path)) {
return itPath;
}
return pathSet.cend();
}

template<typename MapValueType>
auto FindSelfOrFirstChild(const PXR_NS::SdfPath& path, const std::map<PXR_NS::SdfPath, MapValueType>& pathMap) -> decltype(pathMap.cend()) {
auto itPath = pathMap.lower_bound(path);
if (itPath != pathMap.cend() && itPath->first.HasPrefix(path)) {
return itPath;
}
return pathMap.cend();
}

ppt-adsk marked this conversation as resolved.
Show resolved Hide resolved
} // namespace FVP_NS_DEF

#endif // FVP_UTILS_H
2 changes: 2 additions & 0 deletions lib/flowViewport/fvpWireframeColorInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

//Local headers
#include "flowViewport/api.h"
#include "flowViewport/selection/fvpSelectionTypes.h"

//Hydra headers
#include <pxr/usd/sdf/path.h>
Expand All @@ -33,6 +34,7 @@ class WireframeColorInterface
public:
//Get the wireframe color of a primitive for selection highlighting
virtual PXR_NS::GfVec4f getWireframeColor(const PXR_NS::SdfPath& primPath) const = 0;
virtual PXR_NS::GfVec4f getWireframeColor(const Fvp::PrimSelection& primSelection) const = 0;
ppt-adsk marked this conversation as resolved.
Show resolved Hide resolved
};

}//end of namespace FVP_NS_DEF
Expand Down
Loading