mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 11:24:19 +00:00
ifcviewer: multi-selection + box-select with active highlight
SelectionState (new) owns the multi-set, the "active" id (last single- clicked), and a per-object_id flags SSBO bound at binding=3. Main shader reads sel_flags[v_object_id] for the in-set tint and a separate u_active_id uniform for a stronger tint on the active. Click semantics: plain replaces, Shift/Ctrl toggles. LMB-drag past 5px boxes the rect through a pick-pass readback — plain replaces, Shift adds, Ctrl removes; box-select preserves the active. Drag promotes regardless of start point so a press on geometry doesn't disqualify it. Sidecar fast-path bulk-loads instances, so noteObjectId is also called from the apply path — without it the flags buffer was sized to 1 slot while object_ids were in the 100k+ range and the in-set bit was lost. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -911,20 +911,32 @@ void MainWindow::onAllLoadsFinished() {
|
||||
}
|
||||
|
||||
void MainWindow::onObjectPicked(uint32_t object_id) {
|
||||
viewport_->setSelectedObjectId(object_id);
|
||||
|
||||
// Signal originates from the viewport's SelectionState — viewport
|
||||
// selection is already authoritative. Pushing setSelectedObjectId
|
||||
// back here would clobber a multi-select set with {object_id}.
|
||||
auto it = tree_items_.find(object_id);
|
||||
if (it != tree_items_.end()) {
|
||||
element_tree_->blockSignals(true);
|
||||
element_tree_->setCurrentItem(it->second);
|
||||
element_tree_->blockSignals(false);
|
||||
} else {
|
||||
// No active (e.g. selection cleared, or active id is in a model
|
||||
// whose tree node hasn't materialised) — drop the tree highlight
|
||||
// so the panel doesn't lie about what's active.
|
||||
element_tree_->blockSignals(true);
|
||||
element_tree_->setCurrentItem(nullptr);
|
||||
element_tree_->blockSignals(false);
|
||||
}
|
||||
|
||||
populateProperties(object_id);
|
||||
|
||||
if (object_id != 0) {
|
||||
const double v = volumeOfObjects(*viewport_, {object_id});
|
||||
qInfo("Volume of object %u: %.6f m^3", object_id, v);
|
||||
// Volume readout: report for the full selection so multi-select
|
||||
// matches the highlighted set.
|
||||
const auto& selection = viewport_->selection().selectionIds();
|
||||
if (!selection.empty()) {
|
||||
std::vector<uint32_t> ids(selection.begin(), selection.end());
|
||||
const double v = volumeOfObjects(*viewport_, ids);
|
||||
qInfo("Volume of %zu selected object(s): %.6f m^3", ids.size(), v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -933,6 +945,8 @@ void MainWindow::onTreeSelectionChanged() {
|
||||
if (items.isEmpty()) return;
|
||||
|
||||
uint32_t object_id = items.first()->data(0, Qt::UserRole).toUInt();
|
||||
// Tree stays single-select per UX choice — clicking a tree item
|
||||
// replaces the viewport's multi-set with just that item.
|
||||
viewport_->setSelectedObjectId(object_id);
|
||||
populateProperties(object_id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user