Skip to main content

viewport_lib/interaction/
pick_mask.rs

1//! Pick mask for controlling which item types and sub-element levels are
2//! included in a pick call.
3
4// The bitflags! macro generates associated constants without doc comments
5// for some internal items (e.g. the implicit ALL/NONE sentinels).
6#![allow(missing_docs)]
7
8bitflags::bitflags! {
9    /// Controls what [`ViewportRenderer::pick`] and [`ViewportRenderer::pick_rect`]
10    /// return.
11    ///
12    /// Set one or more bits to include the corresponding item types and
13    /// sub-element levels. The convenience groups (`OBJECT`, `POINT_LIKE`,
14    /// `EDGE_LIKE`, `FACE_LIKE`) cover the common cases.
15    ///
16    /// Bits are grouped by geometric dimension:
17    /// - Bit 0: object level (whole item, any type).
18    /// - Bits 1-39: point-like sub-elements (0D discrete elements).
19    /// - Bits 40-79: edge-like sub-elements (1D segments).
20    /// - Bits 80-119: face-like sub-elements (2D patches or curve strips).
21    /// - Bits 120-127: reserved for future use.
22    ///
23    /// Combining bits from different dimensions (e.g. `FACE | VERTEX`) is legal
24    /// but the resulting set contains elements that cannot be acted on uniformly.
25    /// Use one dimension at a time in normal selection workflows.
26    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
27    pub struct PickMask: u128 {
28        // Object level -- whole item, any type.
29        // Bits 0-0.
30        const OBJECT        = 1 << 0;
31
32        // Point-like sub-types (0D discrete elements).
33        // Bits 1-39 reserved for point-like types.
34        const VERTEX        = 1 << 1;   // mesh vertex
35        const CLOUD_POINT   = 1 << 2;   // point cloud point
36        const CELL          = 1 << 3;   // volume mesh cell (boundary or interior)
37        const VOXEL         = 1 << 4;   // ray-marched volume voxel
38        const SPLAT         = 1 << 5;   // gaussian splat
39        const INSTANCE      = 1 << 6;   // glyph / tensor glyph / sprite instance
40        const POLY_NODE     = 1 << 7;   // polyline node
41        // bits 8-39: reserved for future point-like types
42
43        // Edge-like sub-types (1D elements).
44        // Bits 40-79 reserved for edge-like types.
45        const EDGE          = 1 << 40;  // mesh edge
46        const SEGMENT       = 1 << 41;  // polyline / tube / ribbon segment
47        // bits 42-79: reserved for future edge-like types
48
49        // Face-like sub-types (2D elements and curve strips).
50        // Bits 80-119 reserved for face-like types.
51        const FACE          = 1 << 80;  // mesh face
52        const STRIP         = 1 << 81;  // one connected curve within a multi-strip item
53        // bits 82-119: reserved for future face-like types
54
55        // bits 120-127: reserved for future use
56
57        // Convenience groups.
58
59        /// All point-like sub-elements: mesh vertices, cloud points, volume mesh
60        /// cells, volume voxels, gaussian splats, glyph instances, and polyline
61        /// nodes.
62        const POINT_LIKE    = Self::VERTEX.bits()
63                            | Self::CLOUD_POINT.bits()
64                            | Self::CELL.bits()
65                            | Self::VOXEL.bits()
66                            | Self::SPLAT.bits()
67                            | Self::INSTANCE.bits()
68                            | Self::POLY_NODE.bits();
69
70        /// All edge-like sub-elements: mesh edges and polyline / tube / ribbon
71        /// segments.
72        const EDGE_LIKE     = Self::EDGE.bits() | Self::SEGMENT.bits();
73
74        /// All face-like sub-elements: mesh faces and connected curve strips.
75        const FACE_LIKE     = Self::FACE.bits() | Self::STRIP.bits();
76    }
77}