wgpu backend: per-element visibility + H/Shift+H/I hotkeys

Closes the interactive selection loop. After this commit you can:
  - LMB-click an object  → highlight (selection)
  - Press H              → hide all selected
  - Press Shift+H        → show all (clear hidden set)
  - Press I              → isolate selected (hide everything else)

WgpuVisibilityState (new header) is a plain unordered_set<uint32_t> of
hidden object_ids — mirrors src/ifcviewer/Visibility.h's shape but
stays Qt-free for the ifcviewer-core extract later.

cullModelCpuCompute consults visibility_.isHidden(inst.object_id)
before the frustum test — hidden instances cost nothing on every axis
(no draw, no depth contribution, no pick hit). The CPU vector is
read concurrently by the parallel cull workers, which is safe because
mutations only happen between renders (handlers requestUpdate after
mutating; render reads).

Hiding deselects (matches GL behaviour: H clears the now-invisible
selection rather than leaving phantom selected-but-invisible ids).

Stage 5's last piece — clip planes — is deferred. Adding the uniform
array + WGSL discard is mechanical, but the section-tool UI that
drives them isn't ported yet (minimal viewer has no way to place a
clip plane), so it'd ship as empty plumbing. Will land alongside the
section-tool port.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-27 20:28:07 +10:00
parent 54fa7d8379
commit 4dfe27e251
3 changed files with 119 additions and 0 deletions
+9
View File
@@ -35,6 +35,7 @@
#include "SidecarCache.h"
#include "WgpuModelGpuData.h"
#include "WgpuSelectionState.h"
#include "WgpuVisibilityState.h"
// Stage-2 wgpu viewport: opens a native QWindow, brings up a wgpu instance/
// adapter/device, configures a surface against the platform-native window
@@ -106,6 +107,7 @@ protected:
void mouseReleaseEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
private:
bool initWgpu();
@@ -232,6 +234,13 @@ private:
WgpuSelectionState selection_;
std::vector<uint32_t> selection_flags_scratch_;
// Per-element visibility. Consulted in cullModelCpuCompute to drop
// hidden instances before they're added to visible_draws — keeps
// hidden geometry out of cost on every axis (no draw, no depth, no
// pick). Mutated on the main thread between renders; cull workers
// read concurrently which is safe as long as no concurrent writes.
WgpuVisibilityState visibility_;
// Depth attachment (4× MSAA), recreated on surface resize.
WGPUTexture depth_texture_ = nullptr;
WGPUTextureView depth_view_ = nullptr;