feat(python): block contents (create_entity(..., block=))

BlockEntityAdd adds a validated entity to a block definition (owner set by the
host, same validation as a model-space entity, self-nesting inserts refused),
reusing the scene's block-editor routing. Deleting a block member now also
drops its handle from the block record. Real-IPC audit with an attribute
definition inside a block, DWG/DXF persistence and undo; IPC and Python unit
tests; docs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Felix RiestraandClaude Sonnet 5 committed 2026-09-21 16:54:30 +02:00
1 parent 8d20d280fe
commit b1edc9f578
8 files changed
+251 -7

No files matched your search

+5
View File
@@ -142,6 +142,11 @@ pub enum TableOperation {
BlockRename { from: String, to: String },
/// Delete an unreferenced block definition and its contents.
BlockDelete { name: String },
/// Add a new entity to a block definition, validated exactly as a new
/// model-space entity is. The entity's owner is set by the host. Returns the
/// new entity's handle. Edit and delete members with the ordinary entity
/// operations.
BlockEntityAdd { block: String, entity: EntityType },
}
/// The style tables `TableOperation` can rename, delete or make current.
@@ -141,6 +141,10 @@ mod tests {
TableOperation::BlockModify { name: "B".into(), description: None, explodable: Some(false), scale_uniformly: Some(true) },
TableOperation::BlockRename { from: "B".into(), to: "C".into() },
TableOperation::BlockDelete { name: "C".into() },
TableOperation::BlockEntityAdd {
block: "C".into(),
entity: acadrust::EntityType::Line(acadrust::entities::Line::new()),
},
] {
let bytes = bincode::serialize(&PluginRequest::TableOperation { operation: operation.clone() }).unwrap();
assert!(matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),