ifcviewer: viewport overlay subsystem (highlight tris + HUD text)

New OverlayRenderer module owns every client-supplied overlay primitive
drawn after the main pass: tinted, depth-aware highlight triangles via
its own GL shader, and top-left HUD text via QPainter on a
QOpenGLPaintDevice.  Public surface on ViewportWindow is just two
forwarders (setHighlightTriangles, setHudText).

ViewportWindow's MeshLocalPick now exposes the instance's composed
transform so consumers can map mesh-local geometry back to world
space without re-querying.  AreaMeasurement uses both: its selection
key is now (object_id, tri) so per-instance highlighting works for
two distinct walls sharing a mesh, and on every pick it rebuilds the
world-space tri list and the HUD readout.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-07 16:43:38 +10:00
parent d565dc3ff3
commit ad62dd6d91
7 changed files with 414 additions and 21 deletions
+27
View File
@@ -670,6 +670,7 @@ ViewportWindow::~ViewportWindow() {
if (hiz_resolve_depth_tex_) gl_->glDeleteTextures(1, &hiz_resolve_depth_tex_);
if (hiz_downsample_program_) gl_->glDeleteProgram(hiz_downsample_program_);
if (hiz_downsample_vao_) gl_->glDeleteVertexArrays(1, &hiz_downsample_vao_);
overlay_renderer_.release();
}
context_->doneCurrent();
}
@@ -690,6 +691,7 @@ void ViewportWindow::initGL() {
buildAxisGizmo();
buildPivotIndicator();
buildSectionPlaneGizmo();
overlay_renderer_.initialize(gl_);
gl_->glEnable(GL_DEPTH_TEST);
gl_->glEnable(GL_MULTISAMPLE);
@@ -2726,6 +2728,16 @@ void ViewportWindow::render() {
renderEdgePass();
renderPivotIndicator();
renderSectionPlanes();
// Overlay handles highlight tris + HUD text; renderAxisGizmo() must
// come after because it shrinks glViewport to the corner badge and
// does not restore.
{
const qreal dpr = devicePixelRatio();
overlay_renderer_.render(vp.constData(),
int(width() * dpr),
int(height() * dpr),
dpr);
}
renderAxisGizmo();
// Build HiZ from this frame's resolved depth for next frame's cull.
@@ -3848,6 +3860,8 @@ bool ViewportWindow::pickMeshLocalAt(int x, int y, MeshLocalPick& out) {
out.world_normal[0] = world_normal.x();
out.world_normal[1] = world_normal.y();
out.world_normal[2] = world_normal.z();
std::memcpy(out.composed_transform, inst.transform,
sizeof(out.composed_transform));
return true;
}
}
@@ -3858,3 +3872,16 @@ void ViewportWindow::toggleAreaTool() {
area_tool_active_ = !area_tool_active_;
emit areaToolToggled(area_tool_active_);
}
void ViewportWindow::setHighlightTriangles(const std::vector<float>& world_xyz,
float r, float g, float b, float a) {
if (!gl_initialized_) return;
context_->makeCurrent(this);
overlay_renderer_.setHighlightTriangles(world_xyz, r, g, b, a);
requestUpdate();
}
void ViewportWindow::setHudText(const QString& text) {
overlay_renderer_.setHudText(text);
requestUpdate();
}