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
+11 -2
View File
@@ -210,11 +210,20 @@ void MainWindow::setupUi() {
[this](int x, int y, int modifiers) {
const bool alt = (modifiers & Qt::AltModifier) != 0;
area_measurement_.onPick(*viewport_, x, y, alt);
viewport_->setHudText(QString("Area: %1 m² (%2 tris)")
.arg(area_measurement_.totalArea(), 0, 'f', 4)
.arg(area_measurement_.triangleCount()));
});
connect(viewport_, &ViewportWindow::areaToolToggled, this,
[this](bool active) {
area_measurement_.clear();
qInfo("Area tool %s", active ? "on (LMB to add patch, Alt+LMB single tri, click again to remove, Esc exits)" : "off");
area_measurement_.clear(*viewport_);
if (active) {
viewport_->setHudText("Area: 0.0000 m² (0 tris)");
status_label_->setText("Area tool: LMB add, Alt+LMB single tri, click again to remove, Esc exits");
} else {
viewport_->setHudText(QString());
status_label_->setText("Ready");
}
});
auto* tree_dock = new QDockWidget("Elements", this);