feat(statusbar): isolate / hide objects with status pill

Add a hidden-entity set to the scene that the tessellation visibility
test skips, so hidden objects neither render nor hit-test. New commands
ISOLATEOBJECTS (show only the selection), HIDEOBJECTS (hide the
selection) and UNISOLATEOBJECTS (restore). An ISO status pill lights up
while anything is hidden and restores everything on click.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-04 22:51:23 +03:00
1 parent 243a0bc923
commit e0e7897952
5 files changed
+106

No files matched your search

+51
View File
@@ -549,6 +549,10 @@ pub struct Scene {
pub document: CadDocument,
/// Currently selected entity handles.
pub selected: HashSet<Handle>,
/// Entity handles hidden by Isolate / Hide. Empty = nothing hidden.
/// `tessellate_block`'s visibility test skips these, so they neither
/// render nor hit-test until isolation ends.
pub hidden: HashSet<Handle>,
/// In-progress preview wires while a command is active (rubber-band + object ghosts).
pub preview_wires: Vec<WireModel>,
/// Committed-segment wire drawn during multi-point commands (normal colour).
@@ -693,6 +697,7 @@ impl Scene {
selection: Rc::new(RefCell::new(SelectionState::default())),
document: CadDocument::new(),
selected: HashSet::new(),
hidden: HashSet::new(),
preview_wires: vec![],
interim_wire: None,
camera_generation: 0,
@@ -1316,6 +1321,48 @@ impl Scene {
.count()
}
/// True when any entities are hidden by Isolate / Hide.
pub fn is_isolation_active(&self) -> bool {
!self.hidden.is_empty()
}
/// Hide every drawable entity except the current selection (Isolate).
pub fn isolate_selected(&mut self) {
if self.selected.is_empty() {
return;
}
let keep = self.selected.clone();
self.hidden = self
.document
.entities()
.map(|e| e.common().handle)
.filter(|h| !h.is_null() && !keep.contains(h))
.collect();
self.selected.clear();
self.bump_geometry();
}
/// Hide the current selection (Hide Objects).
pub fn hide_selected(&mut self) {
if self.selected.is_empty() {
return;
}
for h in self.selected.iter().copied() {
self.hidden.insert(h);
}
self.selected.clear();
self.bump_geometry();
}
/// Clear isolation — bring every hidden entity back (End Isolation).
pub fn end_isolation(&mut self) {
if self.hidden.is_empty() {
return;
}
self.hidden.clear();
self.bump_geometry();
}
/// True if any currently selected entity is a Viewport.
/// Used to enable the scale picker when a viewport is selected in paper space.
pub fn has_selected_viewport(&self) -> bool {
@@ -1869,6 +1916,10 @@ impl Scene {
if c.invisible {
return false;
}
// Isolate / Hide: skip entities the user has hidden.
if !self.hidden.is_empty() && self.hidden.contains(&c.handle) {
return false;
}
// Block/BlockEnd are block-defn sentinels, not drawable geometry.
// Without this skip they fall through to fallback_geometry's `_`
// arm and emit a 1-unit phantom segment at world_offset that