From 8f937052b803a0b357997cad69077574ada3f973 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 14 May 2026 11:30:10 +1000 Subject: [PATCH] Show ENH for first length pick Style hidden interface models with disabled text and move the first length-tool pick coordinates to the HUD as ENH in the global georeferenced frame. Generated with the assistance of an AI coding tool. --- src/ifcviewer-full/Measurement.cpp | 7 +++++++ src/ifcviewer/ViewportWindow.cpp | 22 ++++++++++++++++++++++ src/ifcviewer/ViewportWindow.h | 5 +++++ src/interface/modules/models/Panel.cpp | 10 ++++++++++ src/interface/modules/models/View.cpp | 4 ++++ 5 files changed, 48 insertions(+) diff --git a/src/ifcviewer-full/Measurement.cpp b/src/ifcviewer-full/Measurement.cpp index da333cd688..548a39756f 100644 --- a/src/ifcviewer-full/Measurement.cpp +++ b/src/ifcviewer-full/Measurement.cpp @@ -858,6 +858,13 @@ void LengthMeasurement::rebuildLaserOverlay(ViewportWindow& vp) { std::vector labels; QStringList hud_lines; hud_lines << QStringLiteral("Laser measure (click another point for distance)"); + double enh[3] = {0.0, 0.0, 0.0}; + if (vp.meshLocalToGlobal(first_pick_.object_id, first_pick_.mesh_local, enh)) { + hud_lines << QString("ENH: %1, %2, %3") + .arg(enh[0], 0, 'f', 3) + .arg(enh[1], 0, 'f', 3) + .arg(enh[2], 0, 'f', 3); + } // ---------- Coplanar-patch BFS for face extent ---------- // Read back the seed mesh, transform every vertex into world space, diff --git a/src/ifcviewer/ViewportWindow.cpp b/src/ifcviewer/ViewportWindow.cpp index 8e91d8dbe9..265dd88bf4 100644 --- a/src/ifcviewer/ViewportWindow.cpp +++ b/src/ifcviewer/ViewportWindow.cpp @@ -4156,6 +4156,28 @@ bool ViewportWindow::pickMeshLocalAt(int x, int y, MeshLocalPick& out) { return false; } +bool ViewportWindow::meshLocalToGlobal(uint32_t object_id, + const float mesh_local[3], + double global_out[3]) const { + InstanceLookup inst; + if (!findInstance(object_id, inst)) return false; + + auto model_it = models_gpu_.find(inst.model_id); + if (model_it == models_gpu_.end()) return false; + + using Mat4fCol = Eigen::Matrix; + const Eigen::Matrix4d placement = + Eigen::Map(inst.placement_transformation).cast(); + const Eigen::Vector4d local(mesh_local[0], mesh_local[1], mesh_local[2], 1.0); + const Eigen::Vector3d global = + (model_it->second.coordinate_operation_meters * placement * local).head<3>(); + + global_out[0] = global.x(); + global_out[1] = global.y(); + global_out[2] = global.z(); + return true; +} + void ViewportWindow::setToolMode(ToolMode mode) { if (tool_mode_ == mode) return; tool_mode_ = mode; diff --git a/src/ifcviewer/ViewportWindow.h b/src/ifcviewer/ViewportWindow.h index bfabc16bbf..c464a7abf3 100644 --- a/src/ifcviewer/ViewportWindow.h +++ b/src/ifcviewer/ViewportWindow.h @@ -233,6 +233,11 @@ public: float composed_transform[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; }; bool pickMeshLocalAt(int x, int y, MeshLocalPick& out); + // Resolve a mesh-local point to the IFC's own georeferenced global + // frame: CoordinateOperation · placement_transformation · mesh_local. + // Excludes FederatedFalseOrigin and ModelTransformation. + bool meshLocalToGlobal(uint32_t object_id, const float mesh_local[3], + double global_out[3]) const; // CPU raycast against the per-model BVHs. Walks the BVH for each // finalised model, transforms the world ray into mesh-local space diff --git a/src/interface/modules/models/Panel.cpp b/src/interface/modules/models/Panel.cpp index e7f992a9da..1aa9d1c6a4 100644 --- a/src/interface/modules/models/Panel.cpp +++ b/src/interface/modules/models/Panel.cpp @@ -20,9 +20,12 @@ #include "Panel.h" +#include "../../InterfaceSettings.h" #include "../../components/Section.h" #include "../../components/SvgIcon.h" +#include +#include #include #include #include @@ -429,6 +432,13 @@ void ModelsPanel::addNode(QTreeWidgetItem* parent, const TreeNode& node) { item->setIcon(1, components::icons::makeSvgIcon(node.visible ? ":/icons/eye-solid.svg" : ":/icons/eye-closed.svg")); } + if (!node.visible) { + const QBrush disabled_brush( + QColor(ifcinterface::InterfaceSettings::instance().color("disabled_text"))); + item->setForeground(0, disabled_brush); + item->setForeground(1, disabled_brush); + } + for (const auto& child : node.children) { addNode(item, child); } diff --git a/src/interface/modules/models/View.cpp b/src/interface/modules/models/View.cpp index e5154eca2b..992df7b273 100644 --- a/src/interface/modules/models/View.cpp +++ b/src/interface/modules/models/View.cpp @@ -22,6 +22,7 @@ #include "Panel.h" +#include "../../InterfaceSettings.h" #include "../../SessionState.h" #include "../../../ifcviewer/Federation.h" @@ -70,6 +71,9 @@ ModelsPanelView::ModelsPanelView(ModelsPanel* widget, this, [this]() { reload(); }); connect(session_state_, &ifcinterface::SessionState::projectOpened, this, [this](const QString&) { reload(); }); + connect(&ifcinterface::InterfaceSettings::instance(), + &ifcinterface::InterfaceSettings::themeChanged, + this, [this]() { reload(); }); reload(); }