diff --git a/Cargo.lock b/Cargo.lock index bf8d59d12..dbea93f19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2397,7 +2397,7 @@ dependencies = [ "hayro-syntax", "kurbo 0.13.1", "moxcms", - "phf", + "phf 0.13.1", "rustc-hash 2.1.3", "siphasher", "skrifa 0.42.1", @@ -4348,6 +4348,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "oem_cp" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7959d3349f484aec36462f98226983578bf7d33f9b034c32967489c7000e1f" +dependencies = [ + "phf 0.11.3", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -4373,7 +4382,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.6.0" -source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=102f04c#102f04c8ecda1cd409f7ecc4b6eab2dc895c9095" +source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=e023bc3#e023bc37235dddecf9b3e79c522d8936d15e21e6" dependencies = [ "anyhow", "bitflags 2.13.1", @@ -4385,6 +4394,7 @@ dependencies = [ "itoa", "memmap2", "nom 7.1.3", + "oem_cp", "once_cell", "rayon", "ryu", @@ -4396,7 +4406,7 @@ dependencies = [ [[package]] name = "opencadgraph" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=88cdae0#88cdae06858f6811f5058a5686bc1edb5ff39910" +source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=c63556f#c63556f9f7a3cf658fd003a2e47fe67283b6afa7" dependencies = [ "opencadkernel", "serde_json", @@ -4405,7 +4415,7 @@ dependencies = [ [[package]] name = "opencadkernel" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=5811296#5811296a6c98ea9b12defa977f08d74cfc739014" +source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=abca4e8#abca4e81b089114a776ad6fe72a40c51a35646cb" dependencies = [ "cavalier_contours", "opencadcodec", @@ -4416,7 +4426,7 @@ dependencies = [ [[package]] name = "opencadkernel-constraints" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=5811296#5811296a6c98ea9b12defa977f08d74cfc739014" +source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=abca4e8#abca4e81b089114a776ad6fe72a40c51a35646cb" dependencies = [ "nalgebra", ] @@ -4595,6 +4605,15 @@ dependencies = [ "indexmap", ] +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_shared 0.11.3", +] + [[package]] name = "phf" version = "0.13.1" @@ -4602,7 +4621,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ "phf_macros", - "phf_shared", + "phf_shared 0.13.1", ] [[package]] @@ -4612,7 +4631,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ "fastrand", - "phf_shared", + "phf_shared 0.13.1", ] [[package]] @@ -4622,12 +4641,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ "phf_generator", - "phf_shared", + "phf_shared 0.13.1", "proc-macro2", "quote", "syn 2.0.119", ] +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + [[package]] name = "phf_shared" version = "0.13.1" diff --git a/Cargo.toml b/Cargo.toml index a3cbad80c..76f14f916 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,10 +37,10 @@ rfd = "0.17" clap = { version = "4", features = ["derive", "string"] } env_logger = "0.11" log = "0.4" -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] } -kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "5811296", features = ["acis", "offset"] } -kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "5811296" } -graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "88cdae0" } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "e023bc3", features = ["serde"] } +kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "abca4e8", features = ["acis", "offset"] } +kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "abca4e8" } +graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "c63556f" } dwg-thumbnailer = { path = "crates/dwg-thumbnailer" } # Shared SAVE serialization dispatch + web-worker wire format: one # implementation for the inline (fallback/native) path and the worker path. diff --git a/benches/command_benchmarks.rs b/benches/command_benchmarks.rs index c65439c4a..8e90a5c00 100644 --- a/benches/command_benchmarks.rs +++ b/benches/command_benchmarks.rs @@ -101,7 +101,7 @@ fn push_fixture_entities(doc: &mut CadDocument, quick: bool) -> Vec { d.definition_point = Vector3::new(x + 5.0, y + 3.0, 0.0); d.base.text_middle_point = Vector3::new(x + 5.0, y + 4.0, 0.0); handles.push( - doc.add_entity(EntityType::Dimension(Dimension::Linear(d))) + doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(), ); } diff --git a/crates/ocs_plugin_api/Cargo.toml b/crates/ocs_plugin_api/Cargo.toml index 6a528cac8..f5f538245 100644 --- a/crates/ocs_plugin_api/Cargo.toml +++ b/crates/ocs_plugin_api/Cargo.toml @@ -15,7 +15,7 @@ serde_json = { version = "1", optional = true } # Pulled in only by the `host` feature, which adds the `opencadcodec`-typed # `HostApi` runtime surface. The default crate stays dependency-free so engine # crates and external tooling can depend on the manifest/ribbon contract cheaply. -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", optional = true, features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "e023bc3", optional = true, features = ["serde"] } # Runtime IPC and serialization (host feature only). interprocess = { version = "2", optional = true } @@ -39,7 +39,7 @@ serde_json = "1" serde = { version = "1", features = ["derive"] } cargo-lock = "11" # opencadcodec is scanned at build time to generate the embedded type registry. -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "e023bc3", features = ["serde"] } [dev-dependencies] serde_json = "1" diff --git a/crates/ocs_plugin_api/src/entity_coverage.rs b/crates/ocs_plugin_api/src/entity_coverage.rs index aa2901297..c723c1266 100644 --- a/crates/ocs_plugin_api/src/entity_coverage.rs +++ b/crates/ocs_plugin_api/src/entity_coverage.rs @@ -3583,7 +3583,7 @@ mod tests { #[test] fn unsupported_canvas_kind_has_typed_snapshot_fields() { use crate::host::codec; - let hatch = codec::EntityType::Hatch(codec::entities::Hatch::default()); + let hatch = codec::EntityType::Hatch(Box::new(codec::entities::Hatch::default())); let snapshot = entity_snapshot(&hatch).unwrap(); let fields = snapshot .get("Hatch") @@ -3713,7 +3713,7 @@ mod tests { #[test] fn canvas_layer_patch_preserves_unmapped_hatch_fields() { use crate::host::codec; - let hatch = codec::EntityType::Hatch(codec::entities::Hatch::default()); + let hatch = codec::EntityType::Hatch(Box::new(codec::entities::Hatch::default())); let patched = patch_canvas_layer(&hatch, "HATCHES").unwrap(); assert_eq!(patched.common().layer, "HATCHES"); assert_eq!(hatch.common().layer, "0"); @@ -3809,13 +3809,13 @@ mod tests { })); } hatch.paths.push(path); - let entity = codec::EntityType::Hatch(hatch.clone()); + let entity = codec::EntityType::Hatch(Box::new(hatch.clone())); validate_new_canvas_entity(&entity).unwrap(); let mut invalid = hatch.clone(); invalid.paths.clear(); assert!( - validate_new_canvas_entity(&codec::EntityType::Hatch(invalid)) + validate_new_canvas_entity(&codec::EntityType::Hatch(Box::new(invalid))) .unwrap_err() .contains("at least one boundary path") ); @@ -3824,7 +3824,7 @@ mod tests { invalid.is_solid = false; invalid.pattern_scale = 0.0; assert!( - validate_new_canvas_entity(&codec::EntityType::Hatch(invalid)) + validate_new_canvas_entity(&codec::EntityType::Hatch(Box::new(invalid))) .unwrap_err() .contains("greater than zero") ); @@ -3841,13 +3841,13 @@ mod tests { associative.paths[0].boundary_handles.push(boundary); validate_canvas_entity_references( &document, - &codec::EntityType::Hatch(associative.clone()), + &codec::EntityType::Hatch(Box::new(associative.clone())), ) .unwrap(); associative.paths[0].boundary_handles[0] = codec::Handle::new(u64::MAX); assert!(validate_canvas_entity_references( &document, - &codec::EntityType::Hatch(associative), + &codec::EntityType::Hatch(Box::new(associative)), ) .unwrap_err() .contains("does not exist")); diff --git a/crates/ocs_save/Cargo.toml b/crates/ocs_save/Cargo.toml index 687cbe234..150de8021 100644 --- a/crates/ocs_save/Cargo.toml +++ b/crates/ocs_save/Cargo.toml @@ -10,6 +10,6 @@ publish = false # exactly one implementation. No UI/app dependencies — only the codec + serde. [dependencies] -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "e023bc3", features = ["serde"] } bincode = "1.3" serde = { version = "1", features = ["derive"] } diff --git a/crates/ocs_web_worker/Cargo.toml b/crates/ocs_web_worker/Cargo.toml index 656935b3c..42aabfcd1 100644 --- a/crates/ocs_web_worker/Cargo.toml +++ b/crates/ocs_web_worker/Cargo.toml @@ -8,7 +8,7 @@ publish = false crate-type = ["cdylib"] [dependencies] -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c", features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "e023bc3", features = ["serde"] } bincode = "1.3" serde = { version = "1", features = ["derive"] } console_error_panic_hook = "0.1" diff --git a/docs/plugin-template-v2/Cargo.toml b/docs/plugin-template-v2/Cargo.toml index 484fad237..d0a847190 100644 --- a/docs/plugin-template-v2/Cargo.toml +++ b/docs/plugin-template-v2/Cargo.toml @@ -16,4 +16,4 @@ ocs_plugin_api = { path = "../../crates/ocs_plugin_api", features = ["host"] } # entry): the plugin's entities and the host's re-exports are the same types # only when both resolve the same revision. The registration `rustc` / # `acadrust_source` gates enforce this at load time too. -acadrust = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "102f04c" } +acadrust = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "e023bc3" } diff --git a/plugins/opencad-python/Cargo.lock b/plugins/opencad-python/Cargo.lock index b4227ff83..d5afa7615 100644 --- a/plugins/opencad-python/Cargo.lock +++ b/plugins/opencad-python/Cargo.lock @@ -1245,6 +1245,15 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "oem_cp" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7959d3349f484aec36462f98226983578bf7d33f9b034c32967489c7000e1f" +dependencies = [ + "phf 0.11.3", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -1264,7 +1273,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.6.0" -source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=102f04c#102f04c8ecda1cd409f7ecc4b6eab2dc895c9095" +source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=e023bc3#e023bc37235dddecf9b3e79c522d8936d15e21e6" dependencies = [ "anyhow", "bitflags", @@ -1276,6 +1285,7 @@ dependencies = [ "itoa", "memmap2", "nom", + "oem_cp", "once_cell", "rayon", "ryu", diff --git a/plugins/opencad-python/examples/create_layout_fixture.rs b/plugins/opencad-python/examples/create_layout_fixture.rs index b76e2158b..5cff8d471 100644 --- a/plugins/opencad-python/examples/create_layout_fixture.rs +++ b/plugins/opencad-python/examples/create_layout_fixture.rs @@ -41,7 +41,7 @@ fn main() -> Result<(), Box> { viewport.twist_angle = std::f64::consts::FRAC_PI_2; viewport.view_target = Vector3::new(5.0, 10.0, 0.0); } - document.add_entity_to_layout(EntityType::Viewport(viewport), "Sheet")?; + document.add_entity_to_layout(EntityType::Viewport(Box::new(viewport)), "Sheet")?; let mut file = std::fs::OpenOptions::new() .write(true) diff --git a/plugins/opencad-python/src/ocs_module.rs b/plugins/opencad-python/src/ocs_module.rs index 929268656..04f70baef 100644 --- a/plugins/opencad-python/src/ocs_module.rs +++ b/plugins/opencad-python/src/ocs_module.rs @@ -406,7 +406,7 @@ mod ocs { text.rotation = rotation; host_ctx::with_host(|host| { host_ctx::ensure_undo_started(host); - host.add_entity(EntityType::MText(text)).value() + host.add_entity(EntityType::MText(Box::new(text))).value() }) .ok_or_else(|| vm.new_runtime_error("ocs: not running inside a PY_ command".to_owned())) } diff --git a/src/app/automation.rs b/src/app/automation.rs index 20ed24436..74b95ce18 100644 --- a/src/app/automation.rs +++ b/src/app/automation.rs @@ -2129,7 +2129,7 @@ mod tests { dimension.definition_point = Vector3::new(0.0, 5.0, 0.0); dimension.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0); document - .add_entity(EntityType::Dimension(Dimension::Linear(dimension))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension)))) .unwrap(); crate::modules::draw::modify::explode::bake_dimension_blocks(&mut document); @@ -2152,7 +2152,7 @@ mod tests { dimension.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0); app.tabs[app.active_tab] .scene - .add_entity(EntityType::Dimension(Dimension::Linear(dimension))); + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension)))); let path = std::env::temp_dir().join(format!( "ocs_verified_dimension_{}_{}.dwg", std::process::id(), @@ -2190,7 +2190,7 @@ mod tests { let i = app.active_tab; app.tabs[i] .scene - .add_entity(EntityType::Dimension(Dimension::Linear(dimension))); + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension)))); let path = std::env::temp_dir().join(format!( "ocs_verified_dimension_follow_up_{}_{}.dwg", std::process::id(), @@ -2240,7 +2240,7 @@ mod tests { app.tabs[i] .scene .document - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); let path = std::env::temp_dir().join(format!( "ocs_verified_dim_{}_{}.dwg", @@ -2330,7 +2330,7 @@ mod tests { viewport.width = 100.0; viewport.height = 50.0; viewport.turn_on(); - scene.add_entity(codec::EntityType::Viewport(viewport)); + scene.add_entity(codec::EntityType::Viewport(Box::new(viewport))); for entity in scene.document.entities_mut() { if let codec::EntityType::Viewport(viewport) = entity { viewport.status.grid_on = true; @@ -2774,7 +2774,7 @@ mod tests { codec::MText::with_value("\\A1;10.5000", codec::types::Vector3::new(10.0, 20.0, 0.0)); app.tabs[i] .scene - .add_entity(codec::EntityType::MText(mtext)); + .add_entity(codec::EntityType::MText(Box::new(mtext))); let q = app.automation_op( r#"{"op":"query","type":"MTEXT","detail":"full","fields":["value","text","height","bounds"]}"#, @@ -3642,7 +3642,7 @@ mod tests { let mut dst_mtext = MText::new(); dst_mtext.value = "DSTM".into(); dst_mtext.height = 2.0; - let dst_mtext_h = app.tabs[i].scene.add_entity(EntityType::MText(dst_mtext)); + let dst_mtext_h = app.tabs[i].scene.add_entity(EntityType::MText(Box::new(dst_mtext))); // Drive the interactive command exactly as the viewport does: // phase 1 source pick, phase 2 destination selection. diff --git a/src/app/command_driver/clipboard.rs b/src/app/command_driver/clipboard.rs index 64827cad8..8e9d687ab 100644 --- a/src/app/command_driver/clipboard.rs +++ b/src/app/command_driver/clipboard.rs @@ -1405,7 +1405,7 @@ mod paste_entities_kernel_tests { fn remaps_leader_annotation_link_to_pasted_handles() { let mut seed = codec::CadDocument::new(); let note = seed - .add_entity(codec::EntityType::MText(codec::entities::MText::new())) + .add_entity(codec::EntityType::MText(Box::new(codec::entities::MText::new()))) .unwrap(); let mut leader = codec::entities::Leader::default(); leader.annotation_handle = note; diff --git a/src/app/command_driver/dim_edit.rs b/src/app/command_driver/dim_edit.rs index 906b4c636..e845bfe9a 100644 --- a/src/app/command_driver/dim_edit.rs +++ b/src/app/command_driver/dim_edit.rs @@ -36,10 +36,12 @@ impl OpenCADStudio { ) { let i = self.active_tab; let valid = matches!( - self.tabs[i].scene.document.get_entity(dimension), - Some(codec::EntityType::Dimension( - codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_) - )) + self.tabs[i] + .scene + .document + .get_entity(dimension) + .and_then(crate::entities::dimension::as_dimension), + Some(codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_)) ); if !valid { self.command_line.push_error( @@ -415,8 +417,12 @@ fn apply_dimspace( requested_spacing: Option, ) -> bool { use codec::entities::Dimension; - let (axis, normal, definition, auto_spacing) = match scene.document.get_entity(base_h) { - Some(codec::EntityType::Dimension(dimension @ Dimension::Linear(d))) => { + let base = scene + .document + .get_entity(base_h) + .and_then(crate::entities::dimension::as_dimension); + let (axis, normal, definition, auto_spacing) = match base { + Some(dimension @ Dimension::Linear(d)) => { let spacing = dimension_auto_spacing( &scene.document, dimension, @@ -433,7 +439,7 @@ fn apply_dimspace( spacing, ) } - Some(codec::EntityType::Dimension(dimension @ Dimension::Aligned(d))) => { + Some(dimension @ Dimension::Aligned(d)) => { let spacing = dimension_auto_spacing( &scene.document, dimension, @@ -471,7 +477,7 @@ fn apply_dimspace( kernel::space::move_to_dimension_spacing([p.x, p.y, p.z], frame, target); *p = codec::types::Vector3::new(point[0], point[1], point[2]); }; - match dim { + match &mut **dim { Dimension::Linear(d) => { slide(&mut d.definition_point); d.base.definition_point = d.definition_point; diff --git a/src/app/command_driver/entity_commit.rs b/src/app/command_driver/entity_commit.rs index 559961a35..b4ca6eac0 100644 --- a/src/app/command_driver/entity_commit.rs +++ b/src/app/command_driver/entity_commit.rs @@ -39,10 +39,8 @@ impl OpenCADStudio { let delta_safe = self.delta_add_safe(i, &entity); let pending = self.begin_undo(i, label, 1, delta_safe); let is_associative_dimension = matches!( - entity, - codec::EntityType::Dimension( - codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_) - ) + crate::entities::dimension::as_dimension(&entity), + Some(codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_)) ); let association_enabled = self.tabs[i].scene.document.header.dimension_associativity == 2; let committed = if preserve_commit_layer { @@ -257,10 +255,8 @@ impl OpenCADStudio { }; let pending = self.begin_undo(i, label, 1, delta_safe); let is_associative_dimension = matches!( - entity, - codec::EntityType::Dimension( - codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_) - ) + crate::entities::dimension::as_dimension(&entity), + Some(codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_)) ); let association_enabled = self.tabs[i].scene.document.header.dimension_associativity == 2; let committed = if preserve_commit_layer { @@ -324,8 +320,8 @@ impl OpenCADStudio { let label = self.history_label_from_active_cmd(i, "DIMENSION"); let association_mode = self.tabs[i].scene.document.header.dimension_associativity; let single_source_dimension = matches!( - &entity, - codec::EntityType::Dimension(codec::entities::Dimension::Ordinate(_)) + crate::entities::dimension::as_dimension(&entity), + Some(codec::entities::Dimension::Ordinate(_)) ); // A dimension placed on the sheet but measuring model geometry // through a viewport carries the compensation as a negative diff --git a/src/app/command_driver/text_edit.rs b/src/app/command_driver/text_edit.rs index 86cb2b713..3cf316d42 100644 --- a/src/app/command_driver/text_edit.rs +++ b/src/app/command_driver/text_edit.rs @@ -160,7 +160,7 @@ impl OpenCADStudio { Operation::Rotate(degrees) => { dimension.base_mut().text_rotation = degrees.to_radians(); } - Operation::Oblique(degrees) => match dimension { + Operation::Oblique(degrees) => match &mut **dimension { codec::entities::Dimension::Linear(value) => { value.ext_line_rotation = degrees.to_radians(); } diff --git a/src/app/command_driver/transform.rs b/src/app/command_driver/transform.rs index 421cdc274..dc4f070e3 100644 --- a/src/app/command_driver/transform.rs +++ b/src/app/command_driver/transform.rs @@ -463,7 +463,7 @@ impl OpenCADStudio { false } }; - match dim { + match &mut **dim { Dimension::Linear(d) => { stretched |= mv(&mut d.first_point); stretched |= mv(&mut d.second_point); diff --git a/src/app/command_driver/viewport.rs b/src/app/command_driver/viewport.rs index 05c5bfb5c..3208a1ca6 100644 --- a/src/app/command_driver/viewport.rs +++ b/src/app/command_driver/viewport.rs @@ -21,7 +21,7 @@ impl OpenCADStudio { }); let label = self.history_label_from_active_cmd(i, "MVIEW"); let pending = self.begin_undo(i, label, 1, true); - let handle = self.commit_entity_handle(codec::EntityType::Viewport(viewport)); + let handle = self.commit_entity_handle(codec::EntityType::Viewport(Box::new(viewport))); if let (Some(handle), Some(saved)) = (handle, saved_view) { if let Some(codec::EntityType::Viewport(viewport)) = self.tabs[i].scene.document.get_entity_mut(handle) @@ -244,7 +244,8 @@ impl OpenCADStudio { viewport.id = 2; viewport.clip_boundary_handle = clip_handle; viewport.status.non_rectangular_clipping = !clip_handle.is_null(); - let viewport_handle = self.commit_entity_handle(codec::EntityType::Viewport(viewport)); + let viewport_handle = + self.commit_entity_handle(codec::EntityType::Viewport(Box::new(viewport))); if let Some(viewport_handle) = viewport_handle { if !created_boundary { let before = self.tabs[i] diff --git a/src/app/commands/pdf_shx_text.rs b/src/app/commands/pdf_shx_text.rs index 3f500d98e..182448672 100644 --- a/src/app/commands/pdf_shx_text.rs +++ b/src/app/commands/pdf_shx_text.rs @@ -294,7 +294,7 @@ impl OpenCADStudio { } else { line.layer }; - scene.add_entity(codec::EntityType::MText(mtext)); + scene.add_entity(codec::EntityType::MText(Box::new(mtext))); erase.extend(line.handles); } erase.sort(); diff --git a/src/app/commands/sheet_set.rs b/src/app/commands/sheet_set.rs index 3da99868d..c62a06dce 100644 --- a/src/app/commands/sheet_set.rs +++ b/src/app/commands/sheet_set.rs @@ -2389,7 +2389,7 @@ impl OpenCADStudio { Vector3::new(mv.center.x - mv.target.x, mv.center.y - mv.target.y, 0.0); vp.view_height = mv.height; vp.custom_scale = scale; - scene.add_entity(codec::EntityType::Viewport(vp)); + scene.add_entity(codec::EntityType::Viewport(Box::new(vp))); // A paper-space named view of the same name frames it. let mut named = codec::tables::View::new(title.as_str()); named.handle = scene.document.allocate_handle(); diff --git a/src/app/commands/ucsfollow.rs b/src/app/commands/ucsfollow.rs index 77213208c..f76c4075c 100644 --- a/src/app/commands/ucsfollow.rs +++ b/src/app/commands/ucsfollow.rs @@ -126,10 +126,10 @@ mod tests { let i = app.active_tab; let first = app.tabs[i] .scene - .add_entity(codec::EntityType::Viewport(codec::entities::Viewport::new())); + .add_entity(codec::EntityType::Viewport(Box::new(codec::entities::Viewport::new()))); let second = app.tabs[i] .scene - .add_entity(codec::EntityType::Viewport(codec::entities::Viewport::new())); + .add_entity(codec::EntityType::Viewport(Box::new(codec::entities::Viewport::new()))); app.tabs[i].scene.active_viewport = Some(first); let _ = app.run_command_line("UCSFOLLOW 1"); assert!(app.tabs[i].scene.ucs_follow()); diff --git a/src/app/commands/view.rs b/src/app/commands/view.rs index 87e312163..5e7a7dfa7 100644 --- a/src/app/commands/view.rs +++ b/src/app/commands/view.rs @@ -1000,7 +1000,10 @@ impl OpenCADStudio { match self.tabs[i] .scene .document - .add_entity_to_layout(codec::EntityType::Viewport(vp), &layout_name) + .add_entity_to_layout( + codec::EntityType::Viewport(Box::new(vp)), + &layout_name, + ) { Ok(handle) => { self.tabs[i].scene.auto_fit_viewport(handle); @@ -2207,7 +2210,7 @@ mod tests { locked_hatch.common.layer = "LOCKED_LAYER".into(); let h_locked_hatch = app.tabs[i] .scene - .add_entity_clone(EntityType::Hatch(locked_hatch)); + .add_entity_clone(EntityType::Hatch(Box::new(locked_hatch))); let h_line = app.tabs[i] .scene diff --git a/src/app/dim_viewport.rs b/src/app/dim_viewport.rs index db3fc9322..49ffaded8 100644 --- a/src/app/dim_viewport.rs +++ b/src/app/dim_viewport.rs @@ -352,7 +352,7 @@ impl OpenCADStudio { fn is_angular_dimension(entity: &EntityType) -> bool { matches!( - entity, - EntityType::Dimension(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) + crate::entities::dimension::as_dimension(entity), + Some(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) ) } diff --git a/src/app/mtext_editor.rs b/src/app/mtext_editor.rs index 2f67342d1..24aa40da0 100644 --- a/src/app/mtext_editor.rs +++ b/src/app/mtext_editor.rs @@ -841,7 +841,7 @@ impl super::OpenCADStudio { // catastrophic cancellation. Insertion is a pure translation, so zeroing // it keeps the layout's shape, wrapping and alignment identical. mt.insertion_point = Vector3::new(0.0, 0.0, 0.0); - let entity = EntityType::MText(mt.clone()); + let entity = EntityType::MText(Box::new(mt.clone())); let anno = 1.0; let bg = self.tabs[i].scene.bg_color; let wires: Vec = tessellate::tessellate( @@ -1753,7 +1753,8 @@ impl super::OpenCADStudio { )); mt.insertion_point = codec::types::Vector3::new(position.x, position.y, position.z); self.push_undo_snapshot(i, "MTEXT"); - let handle = self.commit_entity_handle(plane.place_entity(EntityType::MText(mt))); + let handle = + self.commit_entity_handle(plane.place_entity(EntityType::MText(Box::new(mt)))); if annotative { let scale = self.tabs[i].scene.creation_annotation_scale_handle(); if let (Some(handle), Some(scale)) = (handle, scale) { @@ -1869,7 +1870,8 @@ impl super::OpenCADStudio { )); mt.insertion_point = codec::types::Vector3::new(position.x, position.y, position.z); self.push_undo_snapshot(i, "MTEXT"); - let handle = self.commit_entity_handle(plane.place_entity(EntityType::MText(mt))); + let handle = + self.commit_entity_handle(plane.place_entity(EntityType::MText(Box::new(mt)))); self.tabs[i].dirty = true; if annotative { let scale = self.tabs[i].scene.creation_annotation_scale_handle(); @@ -1885,7 +1887,7 @@ impl super::OpenCADStudio { if let (Some(h), Some(ed)) = (handle, self.mtext_editor.as_mut()) { ed.editing = Some(h); if let Some(EntityType::MText(mtext)) = self.tabs[i].scene.document.get_entity(h) { - ed.original = Some(mtext.clone()); + ed.original = Some((**mtext).clone()); } } } diff --git a/src/app/navigation.rs b/src/app/navigation.rs index 5a7267692..54c8c4e92 100644 --- a/src/app/navigation.rs +++ b/src/app/navigation.rs @@ -497,7 +497,7 @@ mod tests { vp.width = 200.; vp.height = 100.; vp.view_height = 50.; - let handle = scene.add_entity(codec::EntityType::Viewport(vp)); + let handle = scene.add_entity(codec::EntityType::Viewport(Box::new(vp))); scene.active_viewport = Some(handle); let mut camera = scene.navigation_camera(); camera.target = DVec3::new(120., 30., 8.); diff --git a/src/app/plugin_host.rs b/src/app/plugin_host.rs index 3088a9e07..e023cdb31 100644 --- a/src/app/plugin_host.rs +++ b/src/app/plugin_host.rs @@ -943,7 +943,7 @@ impl<'a> HostSession<'a> { frame.common.layer = layer; } self.push_undo("Embed picture"); - let handle = self.add_entity(EntityType::Ole2Frame(frame)); + let handle = self.add_entity(EntityType::Ole2Frame(Box::new(frame))); if handle.is_null() { return Err("the picture frame could not be added".into()); } @@ -6708,7 +6708,7 @@ mod tests { let EntityType::Dimension(dimension) = &mut after else { unreachable!() }; - if let codec::entities::Dimension::Linear(value) = dimension { + if let codec::entities::Dimension::Linear(value) = &mut **dimension { value.second_point.x = 30.0; } ocs_plugin_api::entity_coverage::validate_entity_mutation(&before, &after).unwrap(); @@ -7414,7 +7414,7 @@ mod tests { .unwrap(); let mut viewport = codec::entities::Viewport::new(); viewport.common.owner_handle = owner; - let viewport_handle = host.add_entity(EntityType::Viewport(viewport)); + let viewport_handle = host.add_entity(EntityType::Viewport(Box::new(viewport))); let scale_handle = host.document_mut().allocate_handle(); let mut scale = codec::objects::Scale::new("1:1", 1.0, 1.0); scale.handle = scale_handle; @@ -10861,7 +10861,7 @@ mod tests { bare.height = 30.0; let bare = host .document_mut() - .add_entity(EntityType::Viewport(bare)) + .add_entity(EntityType::Viewport(Box::new(bare))) .unwrap(); assert_eq!( host.document().get_entity(bare).map(|e| match e { diff --git a/src/app/properties.rs b/src/app/properties.rs index e376a84e9..1b88ad023 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -1489,12 +1489,14 @@ impl OpenCADStudio { if let Some((anno_field, insert_after)) = anno { let is_anno = crate::scene::annotative::is_annotative(doc, entity) || match entity { - codec::EntityType::Dimension(codec::entities::Dimension::Arc( - dimension, - )) => crate::scene::annotative::dim_style_is_annotative( - doc, - &dimension.base.style_name, - ), + codec::EntityType::Dimension(dimension) + if matches!(**dimension, codec::entities::Dimension::Arc(_)) => + { + crate::scene::annotative::dim_style_is_annotative( + doc, + &dimension.base().style_name, + ) + } codec::EntityType::Tolerance(_) => { crate::scene::annotative::annotation_style_is_annotative(doc, entity) } @@ -1530,7 +1532,9 @@ impl OpenCADStudio { "annotative", yes_no_choice(t.is_annotative || is_anno), ), - codec::EntityType::Dimension(codec::entities::Dimension::Arc(_)) => { + codec::EntityType::Dimension(dimension) + if matches!(**dimension, codec::entities::Dimension::Arc(_)) => + { set_row( &mut sections, "annotative", @@ -1683,10 +1687,14 @@ impl OpenCADStudio { format!("{} ({})", t!("Surface"), t!("Extrusion")) } // The reference names an angular dimension by its kind. - codec::EntityType::Dimension(codec::entities::Dimension::Angular2Ln(_)) => { + codec::EntityType::Dimension(dimension) + if matches!(**dimension, codec::entities::Dimension::Angular2Ln(_)) => + { t!("Angular Dimension").into_owned() } - codec::EntityType::Dimension(codec::entities::Dimension::Angular3Pt(_)) => { + codec::EntityType::Dimension(dimension) + if matches!(**dimension, codec::entities::Dimension::Angular3Pt(_)) => + { t!("3 Point Angular Dimension").into_owned() } codec::EntityType::Underlay(underlay) => match underlay.underlay_type { @@ -1719,22 +1727,14 @@ impl OpenCADStudio { title } else { use codec::entities::Dimension; - match entity { - codec::EntityType::Dimension(Dimension::Aligned(_)) => { - t!("Aligned Dimensional Constraint") - } - codec::EntityType::Dimension(Dimension::Angular2Ln(_)) => { - t!("Angular Dimension (Dynamic)") - } - codec::EntityType::Dimension(Dimension::Angular3Pt(_)) => { + match crate::entities::dimension::as_dimension(entity) { + Some(Dimension::Aligned(_)) => t!("Aligned Dimensional Constraint"), + Some(Dimension::Angular2Ln(_)) => t!("Angular Dimension (Dynamic)"), + Some(Dimension::Angular3Pt(_)) => { t!("3 Point Angular Dimension (Dynamic)") } - codec::EntityType::Dimension(Dimension::Radius(_)) => { - t!("Radius Dimensional Constraint") - } - codec::EntityType::Dimension(Dimension::Diameter(_)) => { - t!("Diameter Dimensional Constraint") - } + Some(Dimension::Radius(_)) => t!("Radius Dimensional Constraint"), + Some(Dimension::Diameter(_)) => t!("Diameter Dimensional Constraint"), _ => t!("Linear Dimensional Constraint"), } .into_owned() @@ -2743,7 +2743,7 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={} // scale are available. if let codec::EntityType::Dimension(dim) = contextual.as_ref() { if matches!( - dim, + &**dim, codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_) ) && !dim.base().text_user_positioned @@ -2780,13 +2780,17 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={} } } } - let dynamic_angle = match contextual.as_ref() { - codec::EntityType::Dimension( - dim @ (codec::entities::Dimension::Angular2Ln(_) - | codec::entities::Dimension::Angular3Pt(_)), - ) if self.tabs[i].scene.is_dynamic_dimension(handle) => Some(dim), - _ => None, - }; + let contextual_dimension = + crate::entities::dimension::as_dimension(contextual.as_ref()); + let dynamic_angle = contextual_dimension + .filter(|dim| { + matches!( + dim, + codec::entities::Dimension::Angular2Ln(_) + | codec::entities::Dimension::Angular3Pt(_) + ) + }) + .filter(|_| self.tabs[i].scene.is_dynamic_dimension(handle)); if let Some(dim) = dynamic_angle { // A dynamic angle shows a triangle at each end of its arc // pointing away from it, and squares at the arc point and @@ -3060,8 +3064,8 @@ handles={handles_ms:.1} panel={:.1} ribbon={ribbon_ms:.1} tail={:.1} selected={} ) -> Option { let i = self.active_tab; let tracks_dimension_chain = matches!( - &entity, - codec::EntityType::Dimension( + crate::entities::dimension::as_dimension(&entity), + Some( codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_) | codec::entities::Dimension::Angular2Ln(_) diff --git a/src/app/update/block_ops_tests.rs b/src/app/update/block_ops_tests.rs index 8afcf5910..5d3c49121 100644 --- a/src/app/update/block_ops_tests.rs +++ b/src/app/update/block_ops_tests.rs @@ -224,7 +224,7 @@ fn fixture_dimension_reference(app: &mut OpenCADStudio) -> String { dimension.base.style_name = "BO_ARROWSTYLE".to_string(); app.tabs[i] .scene - .add_entity(EntityType::Dimension(Dimension::Aligned(dimension))); + .add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension)))); name.to_string() } @@ -244,7 +244,7 @@ fn fixture_dimension_name_reference(app: &mut OpenCADStudio) -> String { dimension.base.style_name = "BO_ARROWNAMESTYLE".to_string(); app.tabs[i] .scene - .add_entity(EntityType::Dimension(Dimension::Aligned(dimension))); + .add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension)))); name.to_string() } diff --git a/src/app/update/command.rs b/src/app/update/command.rs index 2d2a8ca8e..83e6fbc47 100644 --- a/src/app/update/command.rs +++ b/src/app/update/command.rs @@ -2913,9 +2913,12 @@ impl OpenCADStudio { &value, ); if applied && field == "dim_text_inside" { - if let Some(codec::EntityType::Dimension( - codec::entities::Dimension::LargeRadial(dimension), - )) = app.tabs[i].scene.document.get_entity_mut(handle) + let radial = app.tabs[i] + .scene + .document + .get_entity_mut(handle) + .and_then(crate::entities::dimension::as_dimension_mut); + if let Some(codec::entities::Dimension::LargeRadial(dimension)) = radial { dimension.base.text_user_positioned = false; } @@ -4182,9 +4185,13 @@ impl OpenCADStudio { &val, ); if applied && field == "dim_text_inside" { - if let Some(codec::EntityType::Dimension( - codec::entities::Dimension::LargeRadial(dimension), - )) = self.tabs[i].scene.document.get_entity_mut(handle) + if let Some(codec::entities::Dimension::LargeRadial( + dimension, + )) = self.tabs[i] + .scene + .document + .get_entity_mut(handle) + .and_then(crate::entities::dimension::as_dimension_mut) { dimension.base.text_user_positioned = false; } diff --git a/src/app/update/graphic_attributes.rs b/src/app/update/graphic_attributes.rs index 3157cd1bc..d34314779 100644 --- a/src/app/update/graphic_attributes.rs +++ b/src/app/update/graphic_attributes.rs @@ -1084,7 +1084,7 @@ mod tests { .document .entities() .filter_map(|entity| match entity { - EntityType::Hatch(hatch) => Some(hatch), + EntityType::Hatch(hatch) => Some(&**hatch), _ => None, }) .collect() diff --git a/src/app/viewport_dimension_tests.rs b/src/app/viewport_dimension_tests.rs index 0866e4f8d..94f0bd326 100644 --- a/src/app/viewport_dimension_tests.rs +++ b/src/app/viewport_dimension_tests.rs @@ -28,7 +28,7 @@ fn fixture() -> (OpenCADStudio, Handle, ViewportFrame) { viewport.custom_scale = 0.1; viewport.view_direction = Vector3::UNIT_Z; viewport.turn_on(); - let viewport = scene.add_entity(EntityType::Viewport(viewport)); + let viewport = scene.add_entity(EntityType::Viewport(Box::new(viewport))); let frame = scene.viewport_frame(viewport).unwrap(); scene.document.header.dimension_associativity = 2; let i = app.active_tab; @@ -323,7 +323,7 @@ fn viewport_dimension_linear_aligned_and_radial_object_picks() { assert_eq!( preview_text( &app, - &EntityType::Dimension(dimension(&app.tabs[i].scene.document).clone()) + &EntityType::Dimension(Box::new(dimension(&app.tabs[i].scene.document).clone())) ), value, "{name}" @@ -361,7 +361,7 @@ fn viewport_dimension_angular_preserves_angle_without_length_factor() { let _ = app.feed_command(StepInput::Point(place)); let doc = &app.tabs[app.active_tab].scene.document; assert_eq!( - preview_text(&app, &EntityType::Dimension(dimension(doc).clone())), + preview_text(&app, &EntityType::Dimension(Box::new(dimension(doc).clone()))), value ); assert!((dimension(doc).measurement() - 90.0).abs() < 1e-5); @@ -1461,9 +1461,9 @@ fn viewport_dimension_invalid_paths_leave_no_partial_association() { Vector3::new(55.0, 60.0, 0.0), ))); for (source, path) in [(model, vec![Handle::new(u64::MAX)]), (leaf, vec![root])] { - let dim = scene.add_entity(EntityType::Dimension(Dimension::Aligned( + let dim = scene.add_entity(EntityType::Dimension(Box::new(Dimension::Aligned( DimensionAligned::new(Vector3::new(50.0, 50.0, 0.0), Vector3::new(55.0, 50.0, 0.0)), - ))); + )))); let invalid = AcceptedSnap { paper_point: DVec3::new(50.0, 50.0, 0.0), model_point: DVec3::ZERO, diff --git a/src/entities/dimension.rs b/src/entities/dimension.rs index 9b3eb9129..7c2bc8d6d 100644 --- a/src/entities/dimension.rs +++ b/src/entities/dimension.rs @@ -3248,7 +3248,7 @@ pub(crate) fn materialize_large_radial_text_position( let Some(EntityType::Dimension(dimension)) = document.get_entity(handle) else { return; }; - if !matches!(dimension, Dimension::LargeRadial(_)) || dimension.base().text_user_positioned { + if !matches!(&**dimension, Dimension::LargeRadial(_)) || dimension.base().text_user_positioned { return; } let source = document.dim_styles.iter().find(|style| { @@ -3262,8 +3262,8 @@ pub(crate) fn materialize_large_radial_text_position( .map(|style| resolved_dimension_style(style, dimension, document)) .map(|style| styled_dimension_text_position(dimension, &style, 1.0)) .unwrap_or_else(|| dimension_text_pos_f64(dimension, None, 2.5, 1.0)); - if let Some(EntityType::Dimension(Dimension::LargeRadial(radial))) = - document.get_entity_mut(handle) + if let Some(Dimension::LargeRadial(radial)) = + document.get_entity_mut(handle).and_then(as_dimension_mut) { radial.base.text_middle_point = position; } @@ -6491,7 +6491,7 @@ fn dimension_text_entity( } mtext.normal = base.normal; mtext.common = base.common.clone(); - return Some(EntityType::MText(mtext)); + return Some(EntityType::MText(Box::new(mtext))); } let value = if style.is_some_and(|style| style.dimtxtdirection) { @@ -7150,7 +7150,7 @@ fn dimension_tolerance_entity( mtext.style = primary_style; mtext.attachment_point = codec::entities::AttachmentPoint::MiddleCenter; mtext.common = primary_common; - return Some(EntityType::MText(mtext)); + return Some(EntityType::MText(Box::new(mtext))); } let mut t = Text::with_value(tol, pos) @@ -9559,3 +9559,22 @@ mod layout_parity_tests { ); } } + +/// The dimension an entity is, if it is one. The variant holds it boxed, so +/// a pattern cannot reach into it; match on this instead. +pub(crate) fn as_dimension(entity: &codec::EntityType) -> Option<&codec::entities::Dimension> { + match entity { + codec::EntityType::Dimension(dimension) => Some(dimension), + _ => None, + } +} + +/// [`as_dimension`], mutably. +pub(crate) fn as_dimension_mut( + entity: &mut codec::EntityType, +) -> Option<&mut codec::entities::Dimension> { + match entity { + codec::EntityType::Dimension(dimension) => Some(dimension), + _ => None, + } +} diff --git a/src/entities/object_data.rs b/src/entities/object_data.rs index d55d2cf86..71f9116bd 100644 --- a/src/entities/object_data.rs +++ b/src/entities/object_data.rs @@ -620,7 +620,7 @@ fn dynamic_data_text(data: &DynamicBlockData) -> String { "{}; dependencies {}; parameters {}; distance multiplier {:.6}; angle {:.6}", value.action.element.name, value.action.dependencies.len(), - value.action.parameter_ids.len(), + value.action.action_ids.len(), value.offsets.distance_multiplier, value.offsets.angle_offset ), @@ -628,14 +628,14 @@ fn dynamic_data_text(data: &DynamicBlockData) -> String { "{}; dependencies {}; parameters {}; connections {}", value.action.element.name, value.action.dependencies.len(), - value.action.parameter_ids.len(), + value.action.action_ids.len(), value.connections.len() ), DynamicBlockData::RotateAction(value) | DynamicBlockData::ScaleAction(value) => format!( "{}; dependencies {}; parameters {}; base {:.6},{:.6},{:.6}; dependent {}", value.action.action.element.name, value.action.action.dependencies.len(), - value.action.action.parameter_ids.len(), + value.action.action.action_ids.len(), value.action.base_point.x, value.action.base_point.y, value.action.base_point.z, diff --git a/src/entities/text_support.rs b/src/entities/text_support.rs index 16e827685..6d8b9d361 100644 --- a/src/entities/text_support.rs +++ b/src/entities/text_support.rs @@ -676,7 +676,9 @@ pub fn adapt_mtext_paragraphs( ATab::Left(_) => TabKind::Left, ATab::Center(_) => TabKind::Center, ATab::Right(_) => TabKind::Right, - ATab::Decimal(..) => TabKind::Decimal, + ATab::Decimal(..) | ATab::DecimalWithCharacter { .. } => { + TabKind::Decimal + } }; TabStop { position: ts.position() as f32 * entity_height, diff --git a/src/entities/traits.rs b/src/entities/traits.rs index 4fc27b30a..9a95575b7 100644 --- a/src/entities/traits.rs +++ b/src/entities/traits.rs @@ -158,6 +158,16 @@ pub trait TextContent { fn replace_text(&mut self, search: &str, rep: &str); } +/// Entity variants holding their entity boxed (MTEXT) dispatch through here. +impl TextContent for Box { + fn text_content(&self) -> Option { + (**self).text_content() + } + fn replace_text(&mut self, search: &str, rep: &str) { + (**self).replace_text(search, rep) + } +} + /// Human-readable variant name used by Quick Select / Select Similar /// filtering. Stable across releases — the strings here are the canonical /// type identifiers throughout the UI. diff --git a/src/entity_creation.rs b/src/entity_creation.rs index f07bfa678..96e5c29c4 100644 --- a/src/entity_creation.rs +++ b/src/entity_creation.rs @@ -638,7 +638,7 @@ pub(crate) fn build_entity( if let Some(style) = text_style_field(spec, document)? { mtext.style = style; } - EntityType::MText(mtext) + EntityType::MText(Box::new(mtext)) } "INSERT" => { let block = spec["block"].as_str().unwrap_or(""); @@ -724,7 +724,7 @@ pub(crate) fn build_entity( let mut path = BoundaryPath::external(); path.add_edge(BoundaryEdge::Polyline(PolylineEdge::new(vertices, true))); hatch.paths.push(path); - EntityType::Hatch(hatch) + EntityType::Hatch(Box::new(hatch)) } other => { return Err(failure( diff --git a/src/io/linetypes.rs b/src/io/linetypes.rs index f029496e5..7afc4b8ba 100644 --- a/src/io/linetypes.rs +++ b/src/io/linetypes.rs @@ -472,6 +472,7 @@ fn complex_elements( scale: decimal(*scale), rotation: decimal(*rot_deg).to_radians(), absolute_rotation: false, + source_flags: 0, offset: [decimal(*x), decimal(*y)], } } @@ -492,6 +493,7 @@ fn complex_elements( scale: decimal(*scale), rotation: decimal(*rot_deg).to_radians(), absolute_rotation: false, + source_flags: 0, offset: [decimal(*x), decimal(*y)], }, }; diff --git a/src/io/mod.rs b/src/io/mod.rs index 11392d93f..a0e639614 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -2969,7 +2969,7 @@ mod dimension_arrow_save_tests { dimension.definition_point = Vector3::new(0.0, 20.0, 0.0); dimension.base.definition_point = dimension.definition_point; dimension.base.text_middle_point = Vector3::new(50.0, 20.0, 0.0); - doc.add_entity(EntityType::Dimension(Dimension::Linear(dimension))) + doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension)))) .unwrap(); doc } @@ -3545,11 +3545,12 @@ mod prepare_save_tests { dim.base.definition_point = Vector3::ZERO; dim.base.common.handle = doc.allocate_handle(); let handle = dim.base.common.handle; - doc.add_entity(EntityType::Dimension(Dimension::Linear(dim))) + doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dim)))) .unwrap(); let prepared = prepare_document_for_save(doc.clone(), doc.version); - let EntityType::Dimension(Dimension::Linear(linear)) = prepared.get_entity(handle).unwrap() + let Some(Dimension::Linear(linear)) = + crate::entities::dimension::as_dimension(prepared.get_entity(handle).unwrap()) else { panic!("dimension missing from prepared clone"); }; @@ -3565,7 +3566,9 @@ mod prepare_save_tests { assert_eq!(linear.base.definition_point, linear.definition_point); // The live document is untouched: no block name, stale group-10. - let EntityType::Dimension(Dimension::Linear(live)) = doc.get_entity(handle).unwrap() else { + let Some(Dimension::Linear(live)) = + crate::entities::dimension::as_dimension(doc.get_entity(handle).unwrap()) + else { panic!("dimension missing from live document"); }; assert!(live.base.block_name.is_empty()); @@ -3582,7 +3585,7 @@ mod prepare_save_tests { let mut dim = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0)); dim.base.common.handle = doc.allocate_handle(); - doc.add_entity(EntityType::Dimension(Dimension::Linear(dim))) + doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dim)))) .unwrap(); for ext in ["dwg", "dxf"] { let inline = save_to_bytes(&doc, ext, codec::DxfVersion::AC1032).expect("inline"); diff --git a/src/io/ole_embed.rs b/src/io/ole_embed.rs index c82e93cdc..29a87cec3 100644 --- a/src/io/ole_embed.rs +++ b/src/io/ole_embed.rs @@ -168,7 +168,7 @@ pub fn add_embedded_image( ) -> Result { let (upper_left, lower_right) = corners_from_placement(origin, width, image.aspect()); let ole = build_embedded_ole(image, upper_left, lower_right); - doc.add_entity(codec::EntityType::Ole2Frame(ole)) + doc.add_entity(codec::EntityType::Ole2Frame(Box::new(ole))) .map_err(|e| e.to_string()) } diff --git a/src/io/xref.rs b/src/io/xref.rs index 541362102..13c34f34f 100644 --- a/src/io/xref.rs +++ b/src/io/xref.rs @@ -3336,7 +3336,7 @@ mod tests { // Hatch (pattern names have no table — preserved verbatim). let mut hatch = codec::entities::Hatch::new(); hatch.pattern.name = "ANSI31".to_string(); - doc.add_entity(codec::EntityType::Hatch(hatch)).unwrap(); + doc.add_entity(codec::EntityType::Hatch(Box::new(hatch))).unwrap(); // Dim-style reference via a tolerance entity. doc.dim_styles .add(codec::tables::DimStyle::new("ARCH")) diff --git a/src/modules/annotate/aligned_dim.rs b/src/modules/annotate/aligned_dim.rs index ea0e326d6..5d62c941e 100644 --- a/src/modules/annotate/aligned_dim.rs +++ b/src/modules/annotate/aligned_dim.rs @@ -95,7 +95,7 @@ pub(crate) fn aligned_dimension_entity( crate::entities::dimension::reset_automatic_text_position(&mut dim.base); dim.base.actual_measurement = dim.measurement(); crate::entities::dimension::set_dimension_text_override(&mut dim.base, text_override); - EntityType::Dimension(Dimension::Aligned(dim)) + EntityType::Dimension(Box::new(Dimension::Aligned(dim))) } impl CadCommand for AlignedDimensionCommand { diff --git a/src/modules/annotate/angular_dim.rs b/src/modules/annotate/angular_dim.rs index e101214fd..309d379e0 100644 --- a/src/modules/annotate/angular_dim.rs +++ b/src/modules/annotate/angular_dim.rs @@ -232,7 +232,7 @@ impl AngularDimensionCommand { } fn commit(&self, dimension: Dimension) -> CmdResult { - let entity = self.plane.place_entity(EntityType::Dimension(dimension)); + let entity = self.plane.place_entity(EntityType::Dimension(Box::new(dimension))); CmdResult::CommitDimension { entity, association: DimensionAssociationInput::Explicit(self.source_refs.clone()), @@ -1242,7 +1242,7 @@ pub(crate) fn angular_two_line_entity( dim.base.insertion_point = dim.dimension_arc; dim.base.actual_measurement = dim.measurement_degrees(); crate::entities::dimension::set_dimension_text_override(&mut dim.base, text); - Some(EntityType::Dimension(Dimension::Angular2Ln(dim))) + Some(EntityType::Dimension(Box::new(Dimension::Angular2Ln(dim)))) } /// A three-point angular dimension (vertex, two points, arc point), for a @@ -1261,7 +1261,7 @@ pub(crate) fn angular_three_point_entity( dim.base.insertion_point = dim.definition_point; dim.base.actual_measurement = dim.measurement_degrees(); crate::entities::dimension::set_dimension_text_override(&mut dim.base, text); - Some(EntityType::Dimension(Dimension::Angular3Pt(dim))) + Some(EntityType::Dimension(Box::new(Dimension::Angular3Pt(dim)))) } fn v3(point: DVec3) -> Vector3 { diff --git a/src/modules/annotate/arc_length_dim.rs b/src/modules/annotate/arc_length_dim.rs index 7dcfc758e..bd2476b9a 100644 --- a/src/modules/annotate/arc_length_dim.rs +++ b/src/modules/annotate/arc_length_dim.rs @@ -258,7 +258,7 @@ impl ArcLengthDimensionCommand { |handle| DimensionAssociationInput::Explicit(selection.association_sources(handle)), ); CmdResult::CommitDimension { - entity: plane.place_entity(EntityType::Dimension(Dimension::Arc(dimension))), + entity: plane.place_entity(EntityType::Dimension(Box::new(Dimension::Arc(dimension)))), association, preserve_base_style: false, continue_command: false, diff --git a/src/modules/annotate/diameter_dim.rs b/src/modules/annotate/diameter_dim.rs index 800370674..1dad74115 100644 --- a/src/modules/annotate/diameter_dim.rs +++ b/src/modules/annotate/diameter_dim.rs @@ -83,7 +83,7 @@ impl DiameterDimensionCommand { if let Some(angle) = self.text_angle { dim.base.text_rotation = angle; } - plane.place_entity(EntityType::Dimension(Dimension::Diameter(dim))) + plane.place_entity(EntityType::Dimension(Box::new(Dimension::Diameter(dim)))) } } @@ -103,7 +103,7 @@ pub(crate) fn diameter_constraint_entity( dim.leader_length = chord.distance(location).max(radius * 0.5); dim.base.actual_measurement = dim.measurement(); crate::entities::dimension::set_dimension_text_override(&mut dim.base, text); - Some(EntityType::Dimension(Dimension::Diameter(dim))) + Some(EntityType::Dimension(Box::new(Dimension::Diameter(dim)))) } impl CadCommand for DiameterDimensionCommand { diff --git a/src/modules/annotate/dim_baseline.rs b/src/modules/annotate/dim_baseline.rs index 23612384c..4d2e862e8 100644 --- a/src/modules/annotate/dim_baseline.rs +++ b/src/modules/annotate/dim_baseline.rs @@ -151,7 +151,7 @@ impl DimBaselineCommand { let increment = self.effective_increment(&style.style_name); let plane = plane_from_normal(dimension.base().definition_point, style.normal); let pick = pick.and_then(|point| plane.project(point.to_array()).map(Vec2::from)); - let kind = match dimension { + let kind = match &**dimension { Dimension::Linear(source) => { let first = project(&plane, source.first_point); let second = project(&plane, source.second_point); @@ -441,7 +441,7 @@ impl CadCommand for DimBaselineCommand { self.committed += 1; self.advance(1.0); CmdResult::CommitDimension { - entity: EntityType::Dimension(dimension), + entity: EntityType::Dimension(Box::new(dimension)), association: DimensionAssociationInput::Infer(None), preserve_base_style: self.preserve_base_style, continue_command: true, @@ -489,7 +489,7 @@ impl CadCommand for DimBaselineCommand { fn dimension_preview(&self, cursor: DVec3) -> Option> { self.build_dimension(cursor).map(|dimension| { vec![DimensionPreview { - entity: EntityType::Dimension(dimension), + entity: EntityType::Dimension(Box::new(dimension)), preserve_base_style: self.preserve_base_style, }] }) diff --git a/src/modules/annotate/dim_continue.rs b/src/modules/annotate/dim_continue.rs index 8922e019b..1496f956d 100644 --- a/src/modules/annotate/dim_continue.rs +++ b/src/modules/annotate/dim_continue.rs @@ -117,7 +117,7 @@ impl DimContinueCommand { let style = SourceStyle::from_base(dimension.base()); let plane = plane_from_normal(dimension.base().definition_point, style.normal); let pick = pick_world.and_then(|point| plane.project(point.to_array()).map(Vec2::from)); - let kind = match dimension { + let kind = match &**dimension { Dimension::Linear(source) => { let rotation = source.rotation; let perpendicular = Vec2::new(-rotation.sin(), rotation.cos()); @@ -383,7 +383,7 @@ impl CadCommand for DimContinueCommand { } self.advance(point); CmdResult::CommitDimension { - entity: EntityType::Dimension(dimension), + entity: EntityType::Dimension(Box::new(dimension)), association: DimensionAssociationInput::Infer(None), preserve_base_style: self.preserve_base_style, continue_command: true, @@ -433,7 +433,7 @@ impl CadCommand for DimContinueCommand { fn dimension_preview(&self, cursor: DVec3) -> Option> { self.build_dimension(cursor).map(|dimension| { vec![DimensionPreview { - entity: EntityType::Dimension(dimension), + entity: EntityType::Dimension(Box::new(dimension)), preserve_base_style: self.preserve_base_style, }] }) diff --git a/src/modules/annotate/dimjogline.rs b/src/modules/annotate/dimjogline.rs index a80260e16..b63527637 100644 --- a/src/modules/annotate/dimjogline.rs +++ b/src/modules/annotate/dimjogline.rs @@ -145,13 +145,17 @@ impl CadCommand for DimJogLineCommand { } fn on_entity_pick(&mut self, handle: Handle, _point: DVec3) -> CmdResult { - let Some(EntityType::Dimension(dimension @ (Dimension::Linear(_) | Dimension::Aligned(_)))) = - self.picked_entity.take() - else { + let Some(EntityType::Dimension(dimension)) = self.picked_entity.take() else { return CmdResult::ReportError( t!("DIMJOGLINE: select a linear or aligned dimension.").into_owned(), ); }; + let dimension = *dimension; + if !matches!(dimension, Dimension::Linear(_) | Dimension::Aligned(_)) { + return CmdResult::ReportError( + t!("DIMJOGLINE: select a linear or aligned dimension.").into_owned(), + ); + } if handle.is_null() { return CmdResult::NeedPoint; } diff --git a/src/modules/annotate/dimspace.rs b/src/modules/annotate/dimspace.rs index ef0ef9e64..8c5959ff8 100644 --- a/src/modules/annotate/dimspace.rs +++ b/src/modules/annotate/dimspace.rs @@ -104,8 +104,8 @@ impl CadCommand for DimSpaceCommand { for selected in entities { if selected.handle != *base && matches!( - selected.entity, - EntityType::Dimension( + crate::entities::dimension::as_dimension(&selected.entity), + Some( codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_) ) @@ -124,11 +124,14 @@ impl CadCommand for DimSpaceCommand { match &mut self.step { Step::PickBase => { if !matches!( - self.picked_entity.take(), - Some(EntityType::Dimension( + self.picked_entity + .take() + .as_ref() + .and_then(crate::entities::dimension::as_dimension), + Some( codec::entities::Dimension::Linear(_) | codec::entities::Dimension::Aligned(_) - )) + ) ) { return CmdResult::ReportError( t!("DIMSPACE: select a linear or aligned dimension.").into_owned(), diff --git a/src/modules/annotate/field_cmd.rs b/src/modules/annotate/field_cmd.rs index 7ab6a2920..6d24ae657 100644 --- a/src/modules/annotate/field_cmd.rs +++ b/src/modules/annotate/field_cmd.rs @@ -158,7 +158,7 @@ impl CadCommand for FieldPlaceCommand { mtext.attachment_point = self.attachment; // No defined width: the field text never wraps. mtext.rectangle_width = 0.0; - CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(mtext))) + CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(Box::new(mtext)))) } fn on_enter(&mut self) -> CmdResult { diff --git a/src/modules/annotate/jogged_radius_dim.rs b/src/modules/annotate/jogged_radius_dim.rs index f566d5bf8..fe43b88bb 100644 --- a/src/modules/annotate/jogged_radius_dim.rs +++ b/src/modules/annotate/jogged_radius_dim.rs @@ -138,7 +138,9 @@ impl JoggedRadiusDimensionCommand { ); CmdResult::CommitDimension { - entity: plane.place_entity(EntityType::Dimension(Dimension::LargeRadial(dimension))), + entity: plane.place_entity(EntityType::Dimension(Box::new(Dimension::LargeRadial( + dimension, + )))), association, preserve_base_style: false, continue_command: false, diff --git a/src/modules/annotate/leader_cmd.rs b/src/modules/annotate/leader_cmd.rs index 654c7c281..6f03e83f1 100644 --- a/src/modules/annotate/leader_cmd.rs +++ b/src/modules/annotate/leader_cmd.rs @@ -151,7 +151,7 @@ impl LeaderCommand { CmdResult::CommitManyAndEditText { entities: vec![ self.plane.place_entity(EntityType::Leader(leader)), - self.plane.place_entity(EntityType::MText(mtext)), + self.plane.place_entity(EntityType::MText(Box::new(mtext))), ], edit_index: 1, open_editor, diff --git a/src/modules/annotate/linear_dim.rs b/src/modules/annotate/linear_dim.rs index c997067cd..ee365950e 100644 --- a/src/modules/annotate/linear_dim.rs +++ b/src/modules/annotate/linear_dim.rs @@ -141,7 +141,7 @@ pub(crate) fn linear_dimension_entity( crate::entities::dimension::reset_automatic_text_position(&mut dim.base); dim.base.actual_measurement = dim.measurement(); crate::entities::dimension::set_dimension_text_override(&mut dim.base, text_override); - EntityType::Dimension(Dimension::Linear(dim)) + EntityType::Dimension(Box::new(Dimension::Linear(dim))) } impl CadCommand for LinearDimensionCommand { diff --git a/src/modules/annotate/mleader_cmd.rs b/src/modules/annotate/mleader_cmd.rs index 81eef14ea..c1cc4cab8 100644 --- a/src/modules/annotate/mleader_cmd.rs +++ b/src/modules/annotate/mleader_cmd.rs @@ -648,7 +648,7 @@ impl CadCommand for MLeaderCommand { text.insertion_point.z, )); self.text = text.value.clone(); - self.selected_mtext = Some(text); + self.selected_mtext = Some(*text); self.content_type = LeaderContentType::MText; self.order = CreationOrder::ContentFirst; self.step = Step::PickPoints; diff --git a/src/modules/annotate/ordinate_dim.rs b/src/modules/annotate/ordinate_dim.rs index 0aa9ddb48..b8dff08b5 100644 --- a/src/modules/annotate/ordinate_dim.rs +++ b/src/modules/annotate/ordinate_dim.rs @@ -80,7 +80,7 @@ impl OrdinateDimCommand { } dim.refresh_measurement(); self.plane - .place_entity(EntityType::Dimension(Dimension::Ordinate(dim))) + .place_entity(EntityType::Dimension(Box::new(Dimension::Ordinate(dim)))) } } diff --git a/src/modules/annotate/qdim.rs b/src/modules/annotate/qdim.rs index 3f1f2357a..e60029e5c 100644 --- a/src/modules/annotate/qdim.rs +++ b/src/modules/annotate/qdim.rs @@ -341,7 +341,7 @@ impl QdimCommand { ]); ( self.plane - .place_entity(EntityType::Dimension(Dimension::Linear(dimension))), + .place_entity(EntityType::Dimension(Box::new(Dimension::Linear(dimension)))), association, ) } @@ -366,7 +366,7 @@ impl QdimCommand { dimension.refresh_measurement(); ( self.plane - .place_entity(EntityType::Dimension(Dimension::Ordinate(dimension))), + .place_entity(EntityType::Dimension(Box::new(Dimension::Ordinate(dimension)))), DimensionAssociationInput::Explicit(vec![point.sources.first().copied()]), ) } @@ -405,7 +405,7 @@ impl QdimCommand { dimension.base.text_user_positioned = true; dimension.leader_length = chord.distance(text); dimension.base.actual_measurement = dimension.measurement(); - EntityType::Dimension(Dimension::Radius(dimension)) + EntityType::Dimension(Box::new(Dimension::Radius(dimension))) } else { let opposite = center - direction * radius; let mut dimension = DimensionDiameter::new(v3(chord), v3(opposite)); @@ -415,7 +415,7 @@ impl QdimCommand { dimension.base.text_user_positioned = true; dimension.leader_length = chord.distance(text); dimension.base.actual_measurement = dimension.measurement(); - EntityType::Dimension(Dimension::Diameter(dimension)) + EntityType::Dimension(Box::new(Dimension::Diameter(dimension))) }; (self.plane.place_entity(entity), association) }) @@ -680,7 +680,7 @@ fn preview_entity(index: usize, entity: &EntityType) -> Vec { return Vec::new(); }; let mut lines: Vec> = Vec::new(); - match dimension { + match &**dimension { Dimension::Linear(value) => { let first = d3(value.first_point); let second = d3(value.second_point); diff --git a/src/modules/annotate/radius_dim.rs b/src/modules/annotate/radius_dim.rs index 435ae9277..7a8d79f93 100644 --- a/src/modules/annotate/radius_dim.rs +++ b/src/modules/annotate/radius_dim.rs @@ -93,7 +93,7 @@ pub(crate) fn radial_dimension_entity( if let Some(angle) = text_angle { dim.base.text_rotation = angle; } - plane.place_entity(EntityType::Dimension(Dimension::Radius(dim))) + plane.place_entity(EntityType::Dimension(Box::new(Dimension::Radius(dim)))) } /// A radius dimension for a dimensional constraint: the leader leaves the @@ -111,7 +111,7 @@ pub(crate) fn radius_constraint_entity( dim.leader_length = chord.distance(location).max(radius * 0.5); dim.base.actual_measurement = dim.measurement(); crate::entities::dimension::set_dimension_text_override(&mut dim.base, text); - Some(EntityType::Dimension(Dimension::Radius(dim))) + Some(EntityType::Dimension(Box::new(Dimension::Radius(dim)))) } /// The unit direction a radial constraint's dimension points in, from the diff --git a/src/modules/annotate/txt2mtxt.rs b/src/modules/annotate/txt2mtxt.rs index c0970a8aa..bd55200be 100644 --- a/src/modules/annotate/txt2mtxt.rs +++ b/src/modules/annotate/txt2mtxt.rs @@ -222,7 +222,7 @@ fn separate(p: &Piece, doc: &CadDocument) -> Vec { let at = p.point(p.rect[0] + x * (p.rect[1] - p.rect[0]), p.rect[3]); let mut m = mtext_from(p.entity, p.content.clone(), at, p.height, p.rotation); m.attachment_point = attachment; - vec![EntityType::MText(m)] + vec![EntityType::MText(Box::new(m))] } EntityType::MText(m) => { // The drawn words, grouped into lines by their baseline. @@ -261,7 +261,8 @@ fn separate(p: &Piece, doc: &CadDocument) -> Vec { .collect::>() .join(" "); let at = p.point(line[0].0 - origin_along, p.rect[3] - k as f64 * step); - EntityType::MText(mtext_from(p.entity, value, at, line[0].1.height, m.rotation)) + let height = line[0].1.height; + EntityType::MText(Box::new(mtext_from(p.entity, value, at, height, m.rotation))) }) .collect() } @@ -352,7 +353,7 @@ pub fn plan( } Some(Txt2MtxtPlan { erase: pieces.iter().map(|p| p.handle).collect(), - add: vec![EntityType::MText(m)], + add: vec![EntityType::MText(Box::new(m))], }) } diff --git a/src/modules/draw/clipboard/pastespec.rs b/src/modules/draw/clipboard/pastespec.rs index cbbefc93f..cc770ed7b 100644 --- a/src/modules/draw/clipboard/pastespec.rs +++ b/src/modules/draw/clipboard/pastespec.rs @@ -113,7 +113,7 @@ impl CadCommand for PasteSpecCommand { mtext.style = self.style.clone(); mtext.attachment_point = AttachmentPoint::TopLeft; mtext.rectangle_width = 0.0; - CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(mtext))) + CmdResult::CommitAndExit(self.plane.place_entity(EntityType::MText(Box::new(mtext)))) } fn on_enter(&mut self) -> CmdResult { diff --git a/src/modules/draw/draw/hatchedit.rs b/src/modules/draw/draw/hatchedit.rs index e05a26400..8acb6989d 100644 --- a/src/modules/draw/draw/hatchedit.rs +++ b/src/modules/draw/draw/hatchedit.rs @@ -925,7 +925,7 @@ mod tests { })); } hatch.paths.push(path); - let entity = EntityType::Hatch(hatch); + let entity = EntityType::Hatch(Box::new(hatch)); HatcheditCommand::with_handle(Handle::new(7), "ANSI31".into(), 1.0, 0.0, false) .with_appearance(Some(&entity), Color::Index(6), Transparency::T_40) .with_origin([9.0, 8.0]) @@ -1096,7 +1096,7 @@ mod tests { counter_clockwise: true, })); hatch.paths.push(path); - let entity = EntityType::Hatch(hatch); + let entity = EntityType::Hatch(Box::new(hatch)); let mut command = HatcheditCommand::with_handle(Handle::new(7), "ANSI31".into(), 1.0, 0.0, false) .with_appearance(Some(&entity), Color::ByLayer, Transparency::ByLayer); diff --git a/src/modules/draw/draw/raster_image.rs b/src/modules/draw/draw/raster_image.rs index 27b10c863..da1015837 100644 --- a/src/modules/draw/draw/raster_image.rs +++ b/src/modules/draw/draw/raster_image.rs @@ -104,7 +104,7 @@ impl ImageCommand { let (upper_left, lower_right) = corners_from_placement(ins, world_width, self.aspect()); let ole = build_embedded_ole(image, upper_left, lower_right); - self.plane.place_entity(EntityType::Ole2Frame(ole)) + self.plane.place_entity(EntityType::Ole2Frame(Box::new(ole))) } } } diff --git a/src/modules/draw/modify/explode.rs b/src/modules/draw/modify/explode.rs index 441909933..9e3c7c158 100644 --- a/src/modules/draw/modify/explode.rs +++ b/src/modules/draw/modify/explode.rs @@ -1439,7 +1439,7 @@ fn sync_dimension_base_points_and_collect_pending(doc: &mut CadDocument) -> Vec< let EntityType::Dimension(dimension) = entity else { return None; }; - let definition_point = match dimension { + let definition_point = match &**dimension { Dimension::Linear(value) => Some(value.definition_point), Dimension::Aligned(value) => Some(value.definition_point), Dimension::Radius(value) => Some(value.definition_point), @@ -1493,7 +1493,7 @@ pub fn bake_dimension_blocks(doc: &mut CadDocument) { let dimensions: Vec<(Handle, Dimension)> = pending .into_iter() .filter_map(|handle| match doc.get_entity(handle) { - Some(EntityType::Dimension(d)) => Some((handle, d.clone())), + Some(EntityType::Dimension(d)) => Some((handle, (**d).clone())), _ => None, }) .collect(); @@ -1654,7 +1654,7 @@ mod tests { d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0); // block_name is left empty — exactly what OCS-created dimensions carry. let handle = doc - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); bake_dimension_blocks(&mut doc); @@ -1693,7 +1693,7 @@ mod tests { // Exactly what OCS-created dimensions carry: insertion == text anchor. d.base.insertion_point = d.base.text_middle_point; let handle = doc - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); bake_dimension_blocks(&mut doc); @@ -1720,7 +1720,7 @@ mod tests { d.definition_point = Vector3::new(0.0, 5.0, 0.0); d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0); let handle = doc - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); bake_dimension_blocks(&mut doc); @@ -1798,7 +1798,7 @@ mod tests { d.rotation = 0.0; d.definition_point = Vector3::new(0.0, 8.0, 0.0); let handle = doc - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); bake_dimension_blocks(&mut doc); let name = match doc.get_entity(handle) { @@ -1827,7 +1827,7 @@ mod tests { let mut d = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0)); d.definition_point = Vector3::new(0.0, 5.0, 0.0); let handle = doc - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); bake_dimension_blocks(&mut doc); let name = match doc.get_entity(handle) { @@ -1875,7 +1875,7 @@ mod tests { .collect(); assert!(!expected.is_empty(), "the dimension explodes into no lines"); - let mut turned = EntityType::Dimension(flat); + let mut turned = EntityType::Dimension(Box::new(flat)); crate::scene::view::dispatch::apply_transform( &mut turned, &EntityTransform::Rotate { @@ -1911,7 +1911,7 @@ mod tests { ); d.definition_point = Vector3::new(5.0, 5.0, 0.0); // arc location let handle = doc - .add_entity(EntityType::Dimension(Dimension::Angular3Pt(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Angular3Pt(d)))) .unwrap(); bake_dimension_blocks(&mut doc); let name = match doc.get_entity(handle) { @@ -1940,7 +1940,7 @@ mod tests { let mut d = DimensionDiameter::new(edge, far); d.base.text_middle_point = Vector3::new(3.0, 9.0, 0.0); let handle = doc - .add_entity(EntityType::Dimension(Dimension::Diameter(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Diameter(d)))) .unwrap(); bake_dimension_blocks(&mut doc); let name = match doc.get_entity(handle) { @@ -1971,7 +1971,7 @@ mod tests { d.rotation = std::f64::consts::FRAC_PI_2; // 90°, vertical dimension line d.definition_point = Vector3::new(8.0, 0.0, 0.0); let handle = doc - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); bake_dimension_blocks(&mut doc); let name = match doc.get_entity(handle) { @@ -2064,7 +2064,7 @@ mod tests { DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0)); d.definition_point = Vector3::new(0.0, 5.0, 0.0); d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0); - doc.add_entity(EntityType::Dimension(Dimension::Linear(d))) + doc.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); let path = @@ -2171,7 +2171,7 @@ mod tests { d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0); d.base.common.xdictionary_handle = Some(dict_handle); let dim_handle = doc - .add_entity(EntityType::Dimension(Dimension::Linear(d))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Linear(d)))) .unwrap(); bake_dimension_blocks(&mut doc); diff --git a/src/modules/insert/dgn_import.rs b/src/modules/insert/dgn_import.rs index 41b22f575..4b15efb03 100644 --- a/src/modules/insert/dgn_import.rs +++ b/src/modules/insert/dgn_import.rs @@ -262,7 +262,7 @@ fn mtext(lines: &[DgnGeom], style: String, node: bool) -> Option { m.rotation = *rotation; m.rectangle_width = 0.0; m.style = style; - Some(EntityType::MText(m)) + Some(EntityType::MText(Box::new(m))) } /// The object(s) one element converts to. diff --git a/src/modules/insert/pdf_import.rs b/src/modules/insert/pdf_import.rs index b8eb3c2bd..2c82251a5 100644 --- a/src/modules/insert/pdf_import.rs +++ b/src/modules/insert/pdf_import.rs @@ -1482,7 +1482,7 @@ pub fn convert( let layer = naming.layer(pdf_layer, Kind::Text); mtext.common.color = color_on(&layer, color_of(text.color)); mtext.common.layer = layer; - result.entities.push(EntityType::MText(mtext)); + result.entities.push(EntityType::MText(Box::new(mtext))); } } @@ -1712,7 +1712,7 @@ fn fill_entities( return Vec::new(); } hatch.elevation = z; - vec![EntityType::Hatch(hatch)] + vec![EntityType::Hatch(Box::new(hatch))] } inventory::submit!(crate::command::CommandRegistration { diff --git a/src/modules/layout/mvsetup.rs b/src/modules/layout/mvsetup.rs index 40b858ff1..50de2d2fb 100644 --- a/src/modules/layout/mvsetup.rs +++ b/src/modules/layout/mvsetup.rs @@ -144,7 +144,7 @@ impl MvsetupCommand { if self.arrangement == Arrangement::Engineering { viewport.view_direction = directions[(row * 2 + column) as usize].clone(); } - viewports.push(EntityType::Viewport(viewport)); + viewports.push(EntityType::Viewport(Box::new(viewport))); } } CmdResult::CommitEntitiesAndExit(viewports) diff --git a/src/scene/annotative.rs b/src/scene/annotative.rs index 9d1decb69..c7b287b29 100644 --- a/src/scene/annotative.rs +++ b/src/scene/annotative.rs @@ -322,7 +322,7 @@ pub fn supports_annotation_context(entity: &EntityType) -> bool { | EntityType::Tolerance(_) | EntityType::Hatch(_) => true, EntityType::Dimension(dimension) => { - !matches!(dimension, codec::entities::Dimension::Arc(_)) + !matches!(&**dimension, codec::entities::Dimension::Arc(_)) } _ => false, } diff --git a/src/scene/block_service.rs b/src/scene/block_service.rs index 5b20152d2..541321358 100644 --- a/src/scene/block_service.rs +++ b/src/scene/block_service.rs @@ -788,7 +788,7 @@ mod tests { dimension.base.block_name = "SVC_TARGET".to_string(); scene .document - .add_entity(EntityType::Dimension(Dimension::Aligned(dimension))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension)))) .unwrap(); // A table's picture block and a block-valued cell, by handle. @@ -894,7 +894,7 @@ mod tests { dimension.base.block_name = "SVC_RENAMED".to_string(); scene .document - .add_entity(EntityType::Dimension(Dimension::Aligned(dimension))) + .add_entity(EntityType::Dimension(Box::new(Dimension::Aligned(dimension)))) .unwrap(); let mut style = DimStyle::new("SVC_STYLE"); style.dimblk = target; diff --git a/src/scene/camera_ops.rs b/src/scene/camera_ops.rs index 62d728ded..179e4261b 100644 --- a/src/scene/camera_ops.rs +++ b/src/scene/camera_ops.rs @@ -479,7 +479,7 @@ impl Scene { self.previous_view = Some(ViewSnapshot::Floating { layout, handle, - viewport: Box::new(viewport.clone()), + viewport: viewport.clone(), }); return; } @@ -538,7 +538,7 @@ impl Scene { }); return false; } - let current = Box::new(current.clone()); + let current = current.clone(); if let Some(EntityType::Viewport(destination)) = self.document.get_entity_mut(handle) { diff --git a/src/scene/dimension_assoc.rs b/src/scene/dimension_assoc.rs index bbb40ae90..f6394d49e 100644 --- a/src/scene/dimension_assoc.rs +++ b/src/scene/dimension_assoc.rs @@ -869,7 +869,7 @@ pub(crate) fn constraint_from_associative_dimension( Some(ParametricRef::whole(*reference.xrefs.first()?)) }; let measurement = DrivingValue::Literal(dimension.measurement()); - match dimension { + match &**dimension { Dimension::Aligned(_) => Some(( ConstraintKind::Distance, vec![point(0)?, point(1)?], @@ -921,7 +921,7 @@ pub(crate) fn radial_extension_points( let EntityType::Dimension(dimension_entity) = document.get_entity(dimension)? else { return None; }; - let target_point = match dimension_entity { + let target_point = match &**dimension_entity { Dimension::Radius(radius) => radius.definition_point, Dimension::Diameter(diameter) => diameter.angle_vertex, Dimension::LargeRadial(radial) => radial.chord_point, @@ -1009,7 +1009,7 @@ impl Scene { else { return; }; - let radial_data = match dimension_entity { + let radial_data = match &**dimension_entity { Dimension::Radius(radius) => Some(( radius.angle_vertex, radius.measurement(), @@ -1223,7 +1223,7 @@ impl Scene { }; // Radial references identify a circle/arc and angle, rather than a vertex. let radial_dimension = matches!( - dimension_entity, + &**dimension_entity, Dimension::Radius(_) | Dimension::Diameter(_) | Dimension::LargeRadial(_) ); if radial_dimension { @@ -1383,7 +1383,7 @@ impl Scene { let Some(EntityType::Dimension(entity)) = self.document.get_entity(dimension) else { return Vec::new(); }; - match entity { + match &**entity { // A radial dimension's single reference describes the point where // the leader meets the circle. Dimension::Radius(radius) => vec![radius.definition_point], @@ -1458,17 +1458,15 @@ impl Scene { let measurement_supported = !association.trans_space || self.document.get_entity(dimension).is_some_and(|entity| { matches!( - entity, - EntityType::Dimension(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) + crate::entities::dimension::as_dimension(entity), + Some(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) ) || persisted_measurement_scale(&self.document, entity).is_some() }); let measurement_supported = measurement_supported && self.document.get_entity(dimension).is_some_and(|entity| { if !matches!( - entity, - EntityType::Dimension( - Dimension::Radius(_) | Dimension::Diameter(_) | Dimension::LargeRadial(_) - ) + crate::entities::dimension::as_dimension(entity), + Some(Dimension::Radius(_) | Dimension::Diameter(_) | Dimension::LargeRadial(_)) ) { return true; } @@ -1652,7 +1650,7 @@ impl Scene { let Some(EntityType::Dimension(entity)) = self.document.get_entity(dimension) else { return Vec::new(); }; - let radial_data = match entity { + let radial_data = match &**entity { Dimension::Radius(radius) => Some(( radius.angle_vertex, radius.measurement(), @@ -1850,8 +1848,8 @@ impl Scene { continue; }; let angular = matches!( - &before, - EntityType::Dimension(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) + crate::entities::dimension::as_dimension(&before), + Some(Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_)) ); let measurement_scale = if let Some(frame) = map.frame.filter(|_| !angular) { let Some(mut scale) = persisted_measurement_scale(&self.document, &before) else { @@ -1874,7 +1872,7 @@ impl Scene { else { continue; }; - match dimension { + match &mut **dimension { Dimension::Linear(linear) => { // The sheet annotation the user placed — the dimension // line's standoff and, when they dragged it, the text — is @@ -2104,7 +2102,7 @@ impl Scene { arc.base.actual_measurement = arc.measurement(); } } - let measurement = match &*dimension { + let measurement = match &**dimension { Dimension::Linear(linear) => linear_measurement(linear), _ => dimension.measurement(), }; @@ -2155,8 +2153,12 @@ impl Scene { refreshed } pub(crate) fn sync_diameter_association_angle(&mut self, dimension: Handle) { - let chord = match self.document.get_entity(dimension) { - Some(EntityType::Dimension(Dimension::Diameter(diameter))) => diameter.angle_vertex, + let chord = match self + .document + .get_entity(dimension) + .and_then(crate::entities::dimension::as_dimension) + { + Some(Dimension::Diameter(diameter)) => diameter.angle_vertex, _ => return, }; @@ -2247,9 +2249,9 @@ mod tests { Vector3::ZERO, 5.0, ))); - let dimension = scene.add_entity(EntityType::Dimension(Dimension::Diameter( + let dimension = scene.add_entity(EntityType::Dimension(Box::new(Dimension::Diameter( DimensionDiameter::new(Vector3::new(5.0, 0.0, 0.0), Vector3::new(-5.0, 0.0, 0.0)), - ))); + )))); scene.attach_dimension_association(dimension, vec![Some(circle)]); let association = scene .document @@ -2270,8 +2272,10 @@ mod tests { .expect("diameter association"); scene.begin_undo_recording(); - let Some(EntityType::Dimension(Dimension::Diameter(diameter))) = - scene.document.get_entity_mut(dimension) + let Some(Dimension::Diameter(diameter)) = scene + .document + .get_entity_mut(dimension) + .and_then(crate::entities::dimension::as_dimension_mut) else { panic!("diameter dimension"); }; diff --git a/src/scene/entity.rs b/src/scene/entity.rs index 2b6c14419..ac89c65c6 100644 --- a/src/scene/entity.rs +++ b/src/scene/entity.rs @@ -3206,7 +3206,7 @@ impl Scene { if let Some(origin) = model.pattern_origin { dxf.record_pattern_origin(Vector2::new(origin[0], origin[1])); } - let mut entity = EntityType::Hatch(dxf); + let mut entity = EntityType::Hatch(Box::new(dxf)); if let Some(layer) = layer { entity.as_entity_mut().set_layer(layer.to_string()); diff --git a/src/scene/layout.rs b/src/scene/layout.rs index a727d8fe7..d10d5d461 100644 --- a/src/scene/layout.rs +++ b/src/scene/layout.rs @@ -64,10 +64,10 @@ impl Scene { if let Some(EntityType::Viewport(sheet)) = self.document.get_entity(from.viewport).cloned() { if let Some(EntityType::Viewport(target)) = self.document.get_entity_mut(to.viewport) { - *target = codec::entities::Viewport { + *target = Box::new(codec::entities::Viewport { common: target.common.clone(), - ..sheet - }; + ..*sheet + }); } } self.unopened_layouts.remove(name); diff --git a/src/scene/mod.rs b/src/scene/mod.rs index d90117db5..a81d2f444 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -4956,7 +4956,7 @@ impl Scene { fit_sheet_viewport(&mut vp, min_lim, max_lim); if let Ok(handle) = self .document - .add_entity_to_layout(EntityType::Viewport(vp), layout_name) + .add_entity_to_layout(EntityType::Viewport(Box::new(vp)), layout_name) { if let Some(ObjectType::Layout(l)) = self.document.objects.get_mut(&layout_handle) { l.viewports.retain(|candidate| *candidate != handle); @@ -5027,7 +5027,7 @@ impl Scene { viewport.status = codec::entities::ViewportStatusFlags::default_on(); if let Ok(handle) = self .document - .add_entity_to_layout(EntityType::Viewport(viewport), layout_name) + .add_entity_to_layout(EntityType::Viewport(Box::new(viewport)), layout_name) { // The reference zooms the new viewport to the model's extents // with a margin of under one percent. @@ -13802,7 +13802,7 @@ mod journal_tests { let mut annotative = MText::new(); annotative.value = "annotative".to_string(); annotative.is_annotative = true; - let annotative = s.add_entity(EntityType::MText(annotative)); + let annotative = s.add_entity(EntityType::MText(Box::new(annotative))); let before_points = s.geometry_epoch; s.invalidate_point_dependencies(); @@ -14117,7 +14117,7 @@ mod journal_tests { scene.document.layers.add_or_replace(Layer::new("Shadows")); let mut hatch = Hatch::new(); hatch.common.layer = "Shadows".to_string(); - let handle = scene.add_entity(EntityType::Hatch(hatch)); + let handle = scene.add_entity(EntityType::Hatch(Box::new(hatch))); let model = scene.model_space_block_handle(); assert_eq!( scene @@ -15447,7 +15447,7 @@ mod layout_cache_tests { vp.height = 100.0; let handle = scene .document - .add_entity_to_layout(codec::EntityType::Viewport(vp), "P1") + .add_entity_to_layout(codec::EntityType::Viewport(Box::new(vp)), "P1") .unwrap(); assert!(scene.set_viewport_scale_named_for(handle, "1:50").is_some()); assert!(scene.active_viewport.is_none()); diff --git a/src/scene/mspace.rs b/src/scene/mspace.rs index 688376cca..d1c01595d 100644 --- a/src/scene/mspace.rs +++ b/src/scene/mspace.rs @@ -285,7 +285,7 @@ mod viewport_zoom_tests { viewport.width = 100.0; viewport.height = 100.0; viewport.view_height = 200.0; - let handle = scene.add_entity(EntityType::Viewport(viewport)); + let handle = scene.add_entity(EntityType::Viewport(Box::new(viewport))); scene.active_viewport = Some(handle); let view_height = |scene: &Scene| match scene.document.get_entity(handle) { @@ -337,7 +337,7 @@ mod clip_tests { viewport.height = 20.0; viewport.clip_boundary_handle = clip; viewport.status.non_rectangular_clipping = true; - let viewport = scene.add_entity(EntityType::Viewport(viewport)); + let viewport = scene.add_entity(EntityType::Viewport(Box::new(viewport))); for (x, y, inside) in [ (2.0, 2.0, true), (8.0, 2.0, true), diff --git a/src/scene/parametric_constraints.rs b/src/scene/parametric_constraints.rs index 4accc1dfe..5ac4bc6f4 100644 --- a/src/scene/parametric_constraints.rs +++ b/src/scene/parametric_constraints.rs @@ -696,7 +696,7 @@ fn dynamic_dimension_follow_points( target.attachment_point = base.attachment_point; target.line_spacing_style = base.line_spacing_style; target.line_spacing_factor = base.line_spacing_factor; - *dimension = rebuilt; + *dimension = *rebuilt; true } @@ -794,7 +794,7 @@ fn dynamic_dimension_follow_radial( let Some(codec::EntityType::Dimension(mut rebuilt)) = rebuilt else { return false; }; - let unchanged = match (&*dimension, &rebuilt) { + let unchanged = match (&*dimension, &*rebuilt) { (Dimension::Radius(old), Dimension::Radius(new)) => { same(old.angle_vertex, new.angle_vertex) && same(old.definition_point, new.definition_point) @@ -808,7 +808,7 @@ fn dynamic_dimension_follow_radial( if unchanged { return false; } - match &mut rebuilt { + match &mut *rebuilt { Dimension::Radius(new) => new.leader_length = leader, Dimension::Diameter(new) => new.leader_length = leader, _ => {} @@ -821,7 +821,7 @@ fn dynamic_dimension_follow_radial( target.attachment_point = base.attachment_point; target.line_spacing_style = base.line_spacing_style; target.line_spacing_factor = base.line_spacing_factor; - *dimension = rebuilt; + *dimension = *rebuilt; true } @@ -881,7 +881,7 @@ fn dynamic_dimension_follow_angle( target.attachment_point = base.attachment_point; target.line_spacing_style = base.line_spacing_style; target.line_spacing_factor = base.line_spacing_factor; - *dimension = rebuilt; + *dimension = *rebuilt; true } @@ -2264,10 +2264,14 @@ impl super::Scene { }); let measured = points.filter(|_| !angular).map(|(first, second)| { let delta = second - first; - let axis = match self.document.get_entity(*dimension) { - Some(codec::EntityType::Dimension(codec::entities::Dimension::Linear( - linear, - ))) => Some((linear.rotation.cos(), linear.rotation.sin())), + let axis = match self + .document + .get_entity(*dimension) + .and_then(crate::entities::dimension::as_dimension) + { + Some(codec::entities::Dimension::Linear(linear)) => { + Some((linear.rotation.cos(), linear.rotation.sin())) + } _ => None, }; match (constraint.kind, axis) { @@ -2605,7 +2609,7 @@ impl super::Scene { // line, which breaks around the text, so the text is centred on // it rather than lifted above it. let radial = matches!( - dimension, + &**dimension, codec::entities::Dimension::Radius(_) | codec::entities::Dimension::Diameter(_) ); let centred = !radial || ov::int(xdata, ov::DIMTAD) == Some(0); @@ -2615,7 +2619,7 @@ impl super::Scene { // The reference draws dynamic distance text horizontally; an // angle's text keeps its style's alignment. let angular = matches!( - dimension, + &**dimension, codec::entities::Dimension::Angular2Ln(_) | codec::entities::Dimension::Angular3Pt(_) ); diff --git a/src/scene/project.rs b/src/scene/project.rs index a2433eadf..711d371a6 100644 --- a/src/scene/project.rs +++ b/src/scene/project.rs @@ -16,7 +16,7 @@ impl Scene { let viewports: Vec<&Viewport> = viewport_handles .iter() .filter_map(|handle| match self.document.get_entity(*handle) { - Some(EntityType::Viewport(vp)) => Some(vp), + Some(EntityType::Viewport(vp)) => Some(&**vp), _ => None, }) .filter(|vp| { @@ -446,7 +446,7 @@ impl Scene { Some(EntityType::Viewport(viewport)) if viewport.common.owner_handle == paper_block && viewport.is_on() => { - Some(viewport) + Some(&**viewport) } _ => None, }) diff --git a/src/ui/node_graph.rs b/src/ui/node_graph.rs index c7ff9ded5..cdcbbc439 100644 --- a/src/ui/node_graph.rs +++ b/src/ui/node_graph.rs @@ -152,7 +152,7 @@ impl ObjectKind { EntityType::Text(e::Text::with_value("Text", origin).with_height(2.5)) } ObjectKind::MText => { - EntityType::MText(e::MText::with_value("MText", origin).with_height(2.5)) + EntityType::MText(Box::new(e::MText::with_value("MText", origin).with_height(2.5))) } } } diff --git a/tests/active_space_roundtrip.rs b/tests/active_space_roundtrip.rs index 85739c387..15530c41a 100644 --- a/tests/active_space_roundtrip.rs +++ b/tests/active_space_roundtrip.rs @@ -90,13 +90,13 @@ fn entered_viewport_survives_a_save_and_reload() { sheet.id = 1; sheet.width = 420.0; sheet.height = 297.0; - let sheet = scene.add_entity(EntityType::Viewport(sheet)); + let sheet = scene.add_entity(EntityType::Viewport(Box::new(sheet))); let mut model = Viewport::new(); model.id = 2; model.width = 100.0; model.height = 80.0; model.view_height = 80.0; - let model = scene.add_entity(EntityType::Viewport(model)); + let model = scene.add_entity(EntityType::Viewport(Box::new(model))); assert_ne!(sheet, model); for entered in [Some(model), None] { diff --git a/tests/annotative_context_synthesis.rs b/tests/annotative_context_synthesis.rs index 1f52ce560..4de593b2e 100644 --- a/tests/annotative_context_synthesis.rs +++ b/tests/annotative_context_synthesis.rs @@ -20,7 +20,7 @@ fn empty_annotation_scales_is_not_annotative() { let mut doc = CadDocument::with_version(DxfVersion::AC1032); let mut m = MText::new(); m.is_annotative = false; // no native flag, no annotative style - let ent = doc.add_entity(EntityType::MText(m)).unwrap(); + let ent = doc.add_entity(EntityType::MText(Box::new(m))).unwrap(); // Build xdict -> "AcDbContextDataManager" -> "ACDB_ANNOTATIONSCALES" (empty). let mk = |doc: &mut CadDocument, owner: Handle| -> Handle { @@ -92,7 +92,7 @@ fn ocs_synthesized_mtext_context_survives_dwg_roundtrip() { m.insertion_point = Vector3::new(100.0, 200.0, 0.0); m.rectangle_width = 50.0; m.is_annotative = true; - let ent = doc.add_entity(EntityType::MText(m)).expect("add mtext"); + let ent = doc.add_entity(EntityType::MText(Box::new(m))).expect("add mtext"); let sh = doc.allocate_handle(); let mut scale = Scale::new("1:50", 1.0, 50.0); @@ -174,7 +174,7 @@ fn object_scale_membership_add_remove_roundtrips() { let mut doc = CadDocument::with_version(DxfVersion::AC1032); let mut m = MText::new(); m.insertion_point = Vector3::new(1.0, 2.0, 0.0); - let ent = doc.add_entity(EntityType::MText(m)).unwrap(); + let ent = doc.add_entity(EntityType::MText(Box::new(m))).unwrap(); let mk_scale = |doc: &mut CadDocument, name: &str, d: f64| { let h = doc.allocate_handle(); diff --git a/tests/block_hatch_export.rs b/tests/block_hatch_export.rs index b65381871..574d2c98f 100644 --- a/tests/block_hatch_export.rs +++ b/tests/block_hatch_export.rs @@ -75,7 +75,7 @@ fn block_internal_hatch_reaches_export() { // A blue hatch, wrapped into a block and inserted in model space — the // minimal shape of "coloured fill nested in a block". - let h = scene.add_entity(EntityType::Hatch(square_hatch(5))); + let h = scene.add_entity(EntityType::Hatch(Box::new(square_hatch(5)))); let identity = codec::types::Transform::identity(); scene .create_block_from_entities(&[h], "LOGO", &identity, &identity) @@ -100,7 +100,7 @@ fn block_internal_hatch_reaches_export() { fn pattern_hatch_uses_stored_line_spacing() { let mut scene = Scene::new(); // Spacing 0.5; a big pattern_scale (10) that the catalog path would apply. - scene.add_entity(EntityType::Hatch(ansi31_stored(0.5, 10.0))); + scene.add_entity(EntityType::Hatch(Box::new(ansi31_stored(0.5, 10.0)))); scene.populate_hatches_from_document(); let hatches = scene.paper_plot_hatches(); @@ -143,7 +143,7 @@ fn far_from_origin_pattern_hatch_still_fills() { // the perpendicular index is |k| ≈ 4000·sin45°/0.3 ≈ 9400, well past the // 4096 clamp on both ends; the old absolute-index clamp inverts the range // (k_lo > k_hi) there and emits nothing. - scene.add_entity(EntityType::Hatch(ansi31_stored_at(0.3, 1.0, 4000.0, 0.0))); + scene.add_entity(EntityType::Hatch(Box::new(ansi31_stored_at(0.3, 1.0, 4000.0, 0.0)))); scene.populate_hatches_from_document(); let hatches = scene.paper_plot_hatches(); @@ -188,7 +188,7 @@ fn textbox_boundary_path_is_not_filled() { let mut tb = rect_path(0.0, 0.0, 200.0, 50.0); tb.flags = BoundaryPathFlags::from_bits(8 | 1); // TEXTBOX + EXTERNAL hatch.paths.push(tb); - scene.add_entity(EntityType::Hatch(hatch)); + scene.add_entity(EntityType::Hatch(Box::new(hatch))); scene.populate_hatches_from_document(); let hatches = scene.paper_plot_hatches(); diff --git a/tests/dim_copy_check.rs b/tests/dim_copy_check.rs index 0eb46f9cb..03388833c 100644 --- a/tests/dim_copy_check.rs +++ b/tests/dim_copy_check.rs @@ -28,7 +28,7 @@ fn copy_dimension_duplicates_its_block() { // A linear dimension whose drawn geometry is that baked block. let mut dim = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0)); dim.base.block_name = "*D0".to_string(); - let dim_h = scene.add_entity(EntityType::Dimension(Dimension::Linear(dim))); + let dim_h = scene.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dim)))); // Copy the dimension by (0, 50). let copies = scene.copy_entities( diff --git a/tests/dim_leader_render_check.rs b/tests/dim_leader_render_check.rs index 2484b52ef..7c48bf7d4 100644 --- a/tests/dim_leader_render_check.rs +++ b/tests/dim_leader_render_check.rs @@ -38,7 +38,7 @@ fn dim_leader_extends_only_when_requested() { base.insertion_point = base.text_middle_point; base.text_user_positioned = true; base.style_name = "Standard".into(); - let handle = scene.add_entity(EntityType::Dimension(dim)); + let handle = scene.add_entity(EntityType::Dimension(Box::new(dim))); for (code, value) in [ (ov::DIMTMOVE, XDataValue::Integer16(movement)), (ov::DIMTXT, XDataValue::Real(3.5)), diff --git a/tests/dim_line_color_roundtrip.rs b/tests/dim_line_color_roundtrip.rs index 1f800be11..e67d9a687 100644 --- a/tests/dim_line_color_roundtrip.rs +++ b/tests/dim_line_color_roundtrip.rs @@ -70,7 +70,7 @@ fn dimension_scene(aci: i16) -> Scene { let mut dim = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0)); dim.base.block_name = "*D0".to_string(); - let h = scene.add_entity(EntityType::Dimension(Dimension::Linear(dim))); + let h = scene.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dim)))); dov::set( &mut scene.document, h, diff --git a/tests/explode_regression.rs b/tests/explode_regression.rs index 1b277e15d..9ec6bbc95 100644 --- a/tests/explode_regression.rs +++ b/tests/explode_regression.rs @@ -130,7 +130,7 @@ fn explode_dimension_linear_golden_segments() { let mut d = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(10.0, 0.0, 0.0)); d.definition_point = Vector3::new(5.0, 3.0, 0.0); d.base.text_middle_point = Vector3::new(5.0, 5.0, 0.0); - let pieces = explode_entity(&EntityType::Dimension(Dimension::Linear(d)), &doc); + let pieces = explode_entity(&EntityType::Dimension(Box::new(Dimension::Linear(d))), &doc); // A baked linear dimension explodes to exactly 2 extension lines + 1 // dimension line. The arrowheads bake as SOLIDs (see the unit test // `linear_dim_bakes_filled_arrowheads`), which is why the Lines count is diff --git a/tests/pdf_export_images_check.rs b/tests/pdf_export_images_check.rs index 6859e6a1c..5e552458c 100644 --- a/tests/pdf_export_images_check.rs +++ b/tests/pdf_export_images_check.rs @@ -331,7 +331,7 @@ fn viewport_projection_clips_images_and_respects_frozen_and_nonplot_layers() { viewport.view_center = Vector3::new(20.0, 10.0, 0.0); viewport.id = 2; viewport.status.is_on = true; - let handle = scene.add_entity(EntityType::Viewport(viewport)); + let handle = scene.add_entity(EntityType::Viewport(Box::new(viewport))); let (_, _, _, images) = scene.viewport_plot_fills(); assert_eq!(images.len(), 1); let raster = Raster::from_pdf(&export(&[page(images)]), 0); diff --git a/tests/pdf_export_text_check.rs b/tests/pdf_export_text_check.rs index 8ad8037b3..947f6092e 100644 --- a/tests/pdf_export_text_check.rs +++ b/tests/pdf_export_text_check.rs @@ -26,7 +26,7 @@ fn text_and_dim_reach_pdf_export() { // A linear dimension — its measurement value is synthesized as SDF text too, // and dimension text is what #385 was actually filed about. let dim = DimensionLinear::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(40.0, 0.0, 0.0)); - let dim_h = scene.add_entity(EntityType::Dimension(Dimension::Linear(dim))); + let dim_h = scene.add_entity(EntityType::Dimension(Box::new(Dimension::Linear(dim)))); let wires = scene.entity_wires(); diff --git a/tests/text_font_rendering.rs b/tests/text_font_rendering.rs index 805988e6a..66ba96bf0 100644 --- a/tests/text_font_rendering.rs +++ b/tests/text_font_rendering.rs @@ -43,7 +43,7 @@ fn expand_block_mtext( mtext.style = "SHOP".to_string(); mtext.height = 20.0; mtext.rectangle_width = 0.0; - let mut sub = EntityType::MText(mtext); + let mut sub = EntityType::MText(Box::new(mtext)); sub.common_mut().owner_handle = br_h; doc.add_entity(sub).unwrap(); diff --git a/tests/viewport_wide_polyline_plot_width.rs b/tests/viewport_wide_polyline_plot_width.rs index 8ccf6851c..d898b5b43 100644 --- a/tests/viewport_wide_polyline_plot_width.rs +++ b/tests/viewport_wide_polyline_plot_width.rs @@ -43,7 +43,7 @@ fn viewport_projection_scales_wide_polyline_band_width() { viewport.view_center = Vector3::new(50.0, 0.0, 0.0); viewport.id = 2; viewport.status.is_on = true; - scene.add_entity(EntityType::Viewport(viewport)); + scene.add_entity(EntityType::Viewport(Box::new(viewport))); let (_paper, model) = scene.plot_wire_groups(None); let band = model diff --git a/tests/zoom_extents_coverage.rs b/tests/zoom_extents_coverage.rs index 455349760..c8fbb518d 100644 --- a/tests/zoom_extents_coverage.rs +++ b/tests/zoom_extents_coverage.rs @@ -75,7 +75,7 @@ fn fit_all_reaches_an_entity_parked_far_from_the_rest() { #[test] fn fit_all_frames_a_hatch_only_drawing() { let mut scene = Scene::new(); - scene.add_entity(EntityType::Hatch(square_hatch(100.0, 200.0, 40.0))); + scene.add_entity(EntityType::Hatch(Box::new(square_hatch(100.0, 200.0, 40.0)))); scene.fit_all(); @@ -103,7 +103,7 @@ fn fit_all_keeps_a_hatch_outside_the_wires_in_view() { } // The fill is the outermost thing in the drawing; the wires alone would // frame a 12 x 10 strip and leave it off screen. - scene.add_entity(EntityType::Hatch(square_hatch(500.0, 500.0, 50.0))); + scene.add_entity(EntityType::Hatch(Box::new(square_hatch(500.0, 500.0, 50.0)))); scene.fit_all();