fix(clipboard): carry block definitions across drawings on paste

Copying an INSERT and pasting it into another drawing rendered nothing:
the clipboard snapshotted referenced layers/linetypes/styles but not the
block definition itself, so the pasted reference pointed at a block the
target drawing didn't have.

Capture every block an copied INSERT references — walking nested INSERTs
transitively, skipping model/paper space and xref blocks — and store the
definition's base point plus its owned entities. On paste, recreate any
of those blocks the target drawing lacks via a new define_block_raw
(entities kept in block-local coordinates), before adding the pasted
references. Same-document pastes are unaffected since the blocks already
exist.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-20 21:23:59 +03:00
1 parent 490c0f6cf9
commit e562738d9e
3 files changed
+138

No files matched your search

+45
View File
@@ -3820,6 +3820,51 @@ impl Scene {
Ok(())
}
/// Recreate a block definition verbatim — the entities are already in
/// block-local coordinates (unlike `define_block_from_owned_entities`,
/// which folds in a base offset). No-op if the block already exists.
/// Used when pasting an INSERT whose block this drawing lacks. (#135)
pub fn define_block_raw(
&mut self,
name: &str,
base_point: acadrust::types::Vector3,
entities: Vec<EntityType>,
) {
if name.is_empty() || self.document.block_records.get(name).is_some() {
return;
}
let next = self.document.next_handle();
let br_handle = Handle::new(next);
let block_handle = Handle::new(next + 1);
let end_handle = Handle::new(next + 2);
let mut block_record = acadrust::tables::BlockRecord::new(name);
block_record.handle = br_handle;
block_record.block_entity_handle = block_handle;
block_record.block_end_handle = end_handle;
if self.document.block_records.add(block_record).is_err() {
return;
}
let mut block = Block::new(name, base_point);
block.common.handle = block_handle;
block.common.owner_handle = br_handle;
let _ = self.document.add_entity(EntityType::Block(block));
let mut block_end = BlockEnd::new();
block_end.common.handle = end_handle;
block_end.common.owner_handle = br_handle;
let _ = self.document.add_entity(EntityType::BlockEnd(block_end));
for mut entity in entities {
Self::reset_clone_subhandles(&mut self.document, &mut entity);
entity.common_mut().handle = Handle::NULL;
entity.common_mut().owner_handle = br_handle;
let _ = self.document.add_entity(entity);
}
self.bump_geometry();
}
fn synced_hatch_models(&self) -> Vec<HatchModel> {
let layout_block = self.current_layout_block_handle();
let hatch_offset = if self.current_layout == "Model" {