Pick Items¶
Map a pointer location to a rendered item or scene value.
Use picking when the user points at rendered geometry and the application needs the item, instance, face, or primitive that was drawn there. Use probing when the user needs a sampled field value at a data coordinate.
At a glance
- Status: Supported GPU-backed queries; promoted picking examples run natively and in WebGPU.
- Languages: C-first asynchronous workflow; Python exposes exact query descriptors and polling calls.
- Prerequisites: A query-capable visual, rendered frames, and outer-panel-local pointer coordinates.
- Result: A later poll returns the frontmost rendered target and its visual-local or linked id.
Task workflow¶
Use picking when the target is a rendered item, instance, or primitive. Use probing when the target is a sampled field value at a data coordinate.

Minimal workflow¶
- Enable query support on the visual with
dvz_visual_set_query_capabilities(). - Convert pointer input to outer-panel-local logical pixel coordinates.
- Queue a panel query with
dvz_panel_query_px(). - Poll resolved results with
dvz_scene_poll_query()after subsequent frames. - Map
resolved_idorlink_keyback to application data. - Update hover, selection, or readout state from the query result.
Keep the visual's item order stable if the pick result is used as an index into application data.
The code below is an asynchronous C excerpt. Check every mutator/queue result, render subsequent frames, and keep polling rather than waiting synchronously in the input callback.
dvz_visual_set_query_capabilities(visual, DVZ_QUERY_CAPABILITY_ITEM);
DvzQueryRequest request = dvz_query_request();
request.request_id = 1;
request.target = DVZ_SCENE_TARGET_ITEM;
request.hit_policy = DVZ_QUERY_HIT_FRONTMOST;
dvz_panel_query_px(panel, panel_x, panel_y, &request);
DvzQueryResult result = {0};
while (dvz_scene_poll_query(scene, &result))
{
if (result.request_id != 1)
continue;
if (result.status == DVZ_QUERY_STATUS_HIT && result.hit &&
result.resolved_target == DVZ_SCENE_TARGET_ITEM)
{
uint64_t item_id = result.resolved_id;
/* Map item_id to application data, selection state, or a readout. */
}
}
Pointer coordinates¶
Queries use DVZ_PANEL_COORD_PANEL_PX coordinates: logical pixels local to the outer panel
rectangle, not raw window coordinates. When the pointer event comes from the scenario runner, use
the scenario helper shown in examples/c/features/picking.c. In a direct app or hosted
integration, first translate host-window coordinates to figure coordinates with
dvz_figure_window_to_layout() when needed, then convert figure to panel pixels with
dvz_panel_transform_point() before calling dvz_panel_query_px().
When the application already has a data-coordinate point, use dvz_panel_query_data() or convert it
with dvz_panel_data_to_position().
Result handling¶
| Field | Use |
|---|---|
status and hit |
Check whether the query resolved to a rendered target. |
visual_family and visual_id |
Confirm the hit came from the expected visual family or visual. |
resolved_target |
Confirm whether the answer is an item, primitive, face, texel, or other target. |
resolved_id |
Use as the visual-local item or primitive id when item order is stable. |
link_key |
Use for application ids when the visual has explicit link keys. |
has_data_position and data_position |
Use for readouts when the visual can report data-space position. |
Use request_id to distinguish hover queries from click queries when both are active. The examples
use one request id for hover and another for click selection.
Hover and selection¶
For retained hover or selection styling, apply successful query results to the retained interaction objects instead of rewriting visual attributes manually:
DvzHover* hover = dvz_hover(scene, NULL);
DvzSelection* selection = dvz_selection(scene, NULL);
dvz_hover_apply_query(hover, &result);
dvz_selection_apply_query(selection, &result);
Use Select and highlight data for selection modes, styles, and clearing rules.
Important details¶
Picking is tied to what is rendered. Hidden, clipped, transparent, or depth-tested items may not behave like a CPU-side nearest-neighbor search.
Panel queries are GPU-backed and normally resolve after rendering work has advanced. Queue the request from input or frame code, then consume results from the scene polling path.
Query result storage is caller-owned. Hover and selection objects retain their own state after
dvz_hover_apply_query() or dvz_selection_apply_query(); destroy those objects before destroying
their scene if you remove them early.
Common mistakes¶
- Using picking to read image scalar values; use field probing.
- Reordering visual data without updating the application-side id mapping.
- Expecting identical results from native and WebGPU paths without checking feature status.
- Forgetting to enable query capabilities on the visual before issuing item queries.
- Treating query results as immediate return values instead of polling resolved results.
- Using raw window coordinates instead of outer-panel-local logical pixels.
See also¶
Complete and related examples
- Canonical complete example: Picking - Source:
examples/c/features/picking.c - Pixel Selection - Source:
examples/c/features/selection_pixel.c - Label Probe - Source:
examples/c/features/probe_labels.c