fix(refedit): objects created during the session join the block
REFCLOSE only wrote the temp copies made at REFEDIT entry back into the block, so anything drawn (or pasted / offset) during the session stayed behind in model space (#423). The session now captures a handle watermark at entry; on close, every current-space entity allocated at or above it joins the working set — Save folds it into the block through the same inverse transform, Discard removes it. Covers every creation path with no per-command hooks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
f03288f120
commit
554921c66f
2 changed files with 54 additions and 5 deletions
|
|
@ -583,6 +583,13 @@ impl OpenCADStudio {
|
||||||
temp_handles: vec![],
|
temp_handles: vec![],
|
||||||
forward,
|
forward,
|
||||||
inverse,
|
inverse,
|
||||||
|
// Everything allocated from here on is part of the session.
|
||||||
|
handle_watermark: self
|
||||||
|
.tabs[i]
|
||||||
|
.scene
|
||||||
|
.document
|
||||||
|
.next_handle()
|
||||||
|
.max(self.tabs[i].scene.document.header.handle_seed),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.push_undo_snapshot(i, "REFEDIT");
|
self.push_undo_snapshot(i, "REFEDIT");
|
||||||
|
|
@ -649,15 +656,35 @@ impl OpenCADStudio {
|
||||||
|
|
||||||
self.push_undo_snapshot(i, "REFCLOSE");
|
self.push_undo_snapshot(i, "REFCLOSE");
|
||||||
|
|
||||||
// Collect the edited temp entities.
|
// The working set: the temp copies PLUS everything the user
|
||||||
let new_entities: Vec<acadrust::EntityType> = session
|
// created in this space during the session (drawn / pasted /
|
||||||
|
// offset entities carry handles at or above the watermark) —
|
||||||
|
// those must fold into the block too, not stay behind in
|
||||||
|
// model space (#423).
|
||||||
|
let working: Vec<acadrust::Handle> = {
|
||||||
|
let space = self.tabs[i].scene.current_layout_block_handle_pub();
|
||||||
|
let drawn = self.tabs[i].scene.document.entities().filter(|e| {
|
||||||
|
let c = e.common();
|
||||||
|
c.owner_handle == space
|
||||||
|
&& c.handle.value() >= session.handle_watermark
|
||||||
|
&& !session.temp_handles.contains(&c.handle)
|
||||||
|
});
|
||||||
|
session
|
||||||
.temp_handles
|
.temp_handles
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.chain(drawn.map(|e| e.common().handle))
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Collect the edited temp entities.
|
||||||
|
let new_entities: Vec<acadrust::EntityType> = working
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|h| self.tabs[i].scene.document.get_entity(*h).cloned())
|
.filter_map(|h| self.tabs[i].scene.document.get_entity(*h).cloned())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Remove temp entities from model space.
|
// Remove temp entities from model space.
|
||||||
self.tabs[i].scene.erase_entities(&session.temp_handles);
|
self.tabs[i].scene.erase_entities(&working);
|
||||||
|
|
||||||
// Apply inverse INSERT transform → block-local coordinates.
|
// Apply inverse INSERT transform → block-local coordinates.
|
||||||
let new_entities: Vec<_> = new_entities
|
let new_entities: Vec<_> = new_entities
|
||||||
|
|
@ -720,8 +747,24 @@ impl OpenCADStudio {
|
||||||
return Some(Task::none());
|
return Some(Task::none());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Remove temp entities without modifying the block.
|
// Remove the working set without modifying the block — the
|
||||||
self.tabs[i].scene.erase_entities(&session.temp_handles);
|
// temp copies plus anything created during the session (#423).
|
||||||
|
let working: Vec<acadrust::Handle> = {
|
||||||
|
let space = self.tabs[i].scene.current_layout_block_handle_pub();
|
||||||
|
let drawn = self.tabs[i].scene.document.entities().filter(|e| {
|
||||||
|
let c = e.common();
|
||||||
|
c.owner_handle == space
|
||||||
|
&& c.handle.value() >= session.handle_watermark
|
||||||
|
&& !session.temp_handles.contains(&c.handle)
|
||||||
|
});
|
||||||
|
session
|
||||||
|
.temp_handles
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.chain(drawn.map(|e| e.common().handle))
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
self.tabs[i].scene.erase_entities(&working);
|
||||||
self.tabs[i].scene.deselect_all();
|
self.tabs[i].scene.deselect_all();
|
||||||
// End the edit fade — restore the drawing to full brightness.
|
// End the edit fade — restore the drawing to full brightness.
|
||||||
self.tabs[i].scene.set_refedit_keep(None);
|
self.tabs[i].scene.set_refedit_keep(None);
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,12 @@ pub struct RefEditSession {
|
||||||
pub forward: acadrust::types::Transform,
|
pub forward: acadrust::types::Transform,
|
||||||
/// World → block-local, applied on SAVE to bring edits back.
|
/// World → block-local, applied on SAVE to bring edits back.
|
||||||
pub inverse: acadrust::types::Transform,
|
pub inverse: acadrust::types::Transform,
|
||||||
|
/// Handle watermark captured before the temp copies were created: every
|
||||||
|
/// entity allocated at or above it during the session (drawn, pasted,
|
||||||
|
/// offset, …) belongs to the working set, so Save folds it into the block
|
||||||
|
/// and Discard removes it (#423). Catches every creation path without
|
||||||
|
/// per-command hooks.
|
||||||
|
pub handle_watermark: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── REFEDIT pick command ───────────────────────────────────────────────────
|
// ── REFEDIT pick command ───────────────────────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue