mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-01 17:36:27 +00:00
wgpu: volume measurement tool (V hotkey, selection-driven HUD + per-object labels)
Ports Bonsai's volumeOfObjects + volumesPerObject onto WgpuViewportWindow. Mesh-local volumes are precomputed at applyCachedModel via signed- tetrahedra-from-origin (dequantising positions from the 12 B/vertex GPU layout); per-instance volume is just the cached local × |det(placement)|. No GPU readback — measurement is O(K) in the selection size. Streaming path computes volumes per-chunk as they arrive — fills any mesh whose chunk just delivered, then re-runs updateVolumeReadout if the user is staring at a Volume readout while the geometry pages in. UX matches GL: V toggles, Esc exits, selection-driven (LMB pick / marquee / Shift/Ctrl set ops all funnel into updateVolumeReadout). HUD shows total + count; one overlay label per object at its AABB centre, capped at 200 to keep the label-texture cache bounded on large marquees. Side fixes layered on the label overlay: - O(1) AABB lookup via object_id_to_instance instead of linear-scanning every model's instance list per selected object. - Label texture cache evicts entries not touched this frame, so churning through "X.XXXX m³" strings doesn't pin GPU memory. - DrawRec stores the WGPUBindGroup handle by value rather than a LabelTexture* pointer into the QHash — getOrCreateLabelTexture can rehash the table and invalidate every captured pointer, which crashed large marquee selections with BindGroup-no-longer-alive. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -295,6 +295,27 @@ private:
|
||||
void setOverlayLabels(const std::vector<WgpuOverlayRenderer::Label>& labels);
|
||||
void setHudText(const QString& text);
|
||||
|
||||
// Measurement tools. Mirrors GL ViewportWindow::ToolMode. Volume is
|
||||
// the first ported tool — selection-driven (LMB pick / marquee /
|
||||
// Shift/Ctrl set ops drive the readout), no clicks-to-place. V
|
||||
// toggles, Esc exits.
|
||||
// NoTool (not None) because X11/X.h #define's None as 0L; including
|
||||
// it transitively via Qt's xcb back-end breaks any enum named None.
|
||||
enum class ToolMode { NoTool, Volume };
|
||||
ToolMode toolMode() const { return tool_mode_; }
|
||||
void setToolMode(ToolMode m);
|
||||
|
||||
// Sum of mesh-local volumes (m³) of every instance whose object_id
|
||||
// is in `object_ids`. Each instance is scaled by |det(placement_3x3)|
|
||||
// to pick up mapped-item scale/mirror; signed-tetrahedra absolute
|
||||
// value means winding is ignored. Volumes are precomputed at
|
||||
// applyCachedModel — this call is just lookups + multiplies.
|
||||
double volumeOfObjects(const std::vector<uint32_t>& object_ids) const;
|
||||
// Per-object variant. Used by the Volume tool to drive both the
|
||||
// total HUD and the per-object overlay labels at AABB centres.
|
||||
std::vector<std::pair<uint32_t, double>>
|
||||
volumesPerObject(const std::vector<uint32_t>& object_ids) const;
|
||||
|
||||
void ensureHizTextures(int viewport_w, int viewport_h);
|
||||
void releaseHizResources();
|
||||
// Resolves the just-rendered MSAA depth into the small single-sample
|
||||
@@ -469,6 +490,15 @@ private:
|
||||
// encode each overlay; see WgpuOverlayRenderer.h.
|
||||
WgpuOverlayRenderer overlays_;
|
||||
|
||||
// Active measurement tool. setToolMode() / setSelection mutations
|
||||
// both funnel into updateVolumeReadout() which pushes the HUD +
|
||||
// per-object labels into overlays_.
|
||||
ToolMode tool_mode_ = ToolMode::NoTool;
|
||||
// Recompute the volume HUD + per-object labels from the current
|
||||
// selection. No-op unless tool_mode_ == Volume; on the first call
|
||||
// after entering Volume mode this primes the overlay.
|
||||
void updateVolumeReadout();
|
||||
|
||||
// Pick pass (stage 4). Single-sample R32UInt target + depth, vertex-
|
||||
// pulled from the same visible_draws / instances buffers as the main
|
||||
// pass — pick fragment outputs the instance's object_id. The pick
|
||||
|
||||
Reference in New Issue
Block a user