diff --git a/Cargo.lock b/Cargo.lock index a98de6d6c..6074183f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4205,7 +4205,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.5.5" -source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=5ef9376#5ef9376e02996097ff649cd9268c343327413787" +source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=d28fd71#d28fd710268e7301798703d3ca9c5698a1af91ed" dependencies = [ "ahash 0.8.12", "anyhow", @@ -4228,7 +4228,7 @@ dependencies = [ [[package]] name = "opencadgraph" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=5384cbe#5384cbe499e97aac800f348659317b502a72da52" +source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=79bdc4b#79bdc4b0586b227edad722d220227caa7f06b32f" dependencies = [ "opencadkernel", "serde_json", @@ -4237,7 +4237,7 @@ dependencies = [ [[package]] name = "opencadkernel" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=8b4980b#8b4980bad0b40f49fc6b85310c0b1b699dc8b05c" +source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=a03e4f0#a03e4f094331949c8b27fb659e6891b84eeaa813" dependencies = [ "cavalier_contours", "opencadcodec", @@ -4248,7 +4248,7 @@ dependencies = [ [[package]] name = "opencadkernel-constraints" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=8b4980b#8b4980bad0b40f49fc6b85310c0b1b699dc8b05c" +source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=a03e4f0#a03e4f094331949c8b27fb659e6891b84eeaa813" dependencies = [ "nalgebra", ] diff --git a/Cargo.toml b/Cargo.toml index fd7f865bd..56e6a7dac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,10 +34,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 = "5ef9376", features = ["serde"] } -kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "8b4980b", features = ["acis", "offset"] } -kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "8b4980b" } -graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "5384cbe" } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "d28fd71", features = ["serde"] } +kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "a03e4f0", features = ["acis", "offset"] } +kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "a03e4f0" } +graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "79bdc4b" } dwg-thumbnailer = { path = "crates/dwg-thumbnailer" } flate2 = "1" image = { version = "0.25", default-features = false, features = ["png", "jpeg", "bmp", "tiff"] } diff --git a/crates/ocs_plugin_api/Cargo.toml b/crates/ocs_plugin_api/Cargo.toml index 09a21c5ea..408368990 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 = "5ef9376", optional = true, features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "d28fd71", 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 = "5ef9376", features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "d28fd71", 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 4d0a0f810..b04b14ace 100644 --- a/crates/ocs_plugin_api/src/entity_coverage.rs +++ b/crates/ocs_plugin_api/src/entity_coverage.rs @@ -1958,7 +1958,7 @@ pub fn validate_entity_mutation( if old.is_mpolygon != new.is_mpolygon || old.mpolygon_hatch_color != new.mpolygon_hatch_color || old.mpolygon_x_direction != new.mpolygon_x_direction - || old.mpolygon_boundary_handle_count != new.mpolygon_boundary_handle_count + || old.mpolygon_invalid_loops != new.mpolygon_invalid_loops { return Err("Hatch MPOLYGON fields are unmapped and read-only".into()); } diff --git a/crates/ocs_web_worker/Cargo.toml b/crates/ocs_web_worker/Cargo.toml index eb764d0d1..168bb51ab 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 = "5ef9376", features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "d28fd71", features = ["serde"] } bincode = "1.3" serde = { version = "1", features = ["derive"] } console_error_panic_hook = "0.1" diff --git a/plugins/opencad-python/Cargo.lock b/plugins/opencad-python/Cargo.lock index 44bcdd907..6dacfa72d 100644 --- a/plugins/opencad-python/Cargo.lock +++ b/plugins/opencad-python/Cargo.lock @@ -1265,7 +1265,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.5.5" -source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=5ef9376#5ef9376e02996097ff649cd9268c343327413787" +source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=d28fd71#d28fd710268e7301798703d3ca9c5698a1af91ed" dependencies = [ "ahash 0.8.12", "anyhow", diff --git a/plugins/opencad-python/build/generate.rs b/plugins/opencad-python/build/generate.rs index 226e7db29..e5a093028 100644 --- a/plugins/opencad-python/build/generate.rs +++ b/plugins/opencad-python/build/generate.rs @@ -925,7 +925,7 @@ fn gen_dict_to_entity(manifest: &Manifest, registry: &TypeRegistry) -> String { } if manifest.manual_kinds.contains(kind) { arms.push_str(&format!( - " \"{kind}\" => codec::EntityType::{kind}({}_from_dict(dict, vm)?),\n", + " \"{kind}\" => codec::EntityType::{kind}({}_from_dict(dict, vm)?.into()),\n", snake_case(kind) )); continue; @@ -962,7 +962,7 @@ fn gen_dict_to_entity(manifest: &Manifest, registry: &TypeRegistry) -> String { for f in &fields { body.push_str(&format!(" {}\n", f.setter)); } - body.push_str(&format!(" codec::EntityType::{kind}({var})\n")); + body.push_str(&format!(" codec::EntityType::{kind}({var}.into())\n")); arms.push_str(&format!(" \"{kind}\" => {{\n{body} }}\n")); } format!( @@ -990,7 +990,7 @@ fn gen_apply_dict_to_entity(manifest: &Manifest, registry: &TypeRegistry) -> Str for kind in &manifest.type_filter { if manifest.manual_kinds.contains(kind) { arms.push_str(&format!( - " codec::EntityType::{kind}(existing_value) => codec::EntityType::{kind}({}_apply(existing_value, dict, vm)?),\n", + " codec::EntityType::{kind}(existing_value) => codec::EntityType::{kind}({}_apply(existing_value, dict, vm)?.into()),\n", snake_case(kind) )); continue; @@ -1032,7 +1032,7 @@ fn gen_apply_dict_to_entity(manifest: &Manifest, registry: &TypeRegistry) -> Str for f in &fields { body.push_str(&format!(" {}\n", f.setter)); } - body.push_str(&format!(" codec::EntityType::{kind}({var})\n")); + body.push_str(&format!(" codec::EntityType::{kind}({var}.into())\n")); arms.push_str(&format!( " codec::EntityType::{kind}(existing_value) => {{\n{body} }}\n" )); diff --git a/plugins/opencad-python/src/ocs_module.rs b/plugins/opencad-python/src/ocs_module.rs index 954cad93c..929268656 100644 --- a/plugins/opencad-python/src/ocs_module.rs +++ b/plugins/opencad-python/src/ocs_module.rs @@ -3699,7 +3699,7 @@ mod ocs { } host_ctx::with_host(|host| { host_ctx::ensure_undo_started(host); - host.add_entity(EntityType::Table(builder.build())).value() + host.add_entity(EntityType::Table(Box::new(builder.build()))).value() }) .ok_or_else(|| vm.new_runtime_error("ocs: not running inside a PY_ command".to_owned())) } diff --git a/src/app/command_driver/tests.rs b/src/app/command_driver/tests.rs index 8cf929474..be67ee374 100644 --- a/src/app/command_driver/tests.rs +++ b/src/app/command_driver/tests.rs @@ -965,16 +965,16 @@ mod thicken_tests { ) .unwrap(); let source = app.add_surface_model( - codec::EntityType::Surface(Surface::new(SurfaceKind::Plane)), + codec::EntityType::Surface(Box::new(Surface::new(SurfaceKind::Plane))), body, ); assert!(!source.is_null()); let i = app.active_tab; let invalid = app.tabs[i] .scene - .add_entity(codec::EntityType::Surface(Surface::new( + .add_entity(codec::EntityType::Surface(Box::new(Surface::new( SurfaceKind::Generic, - ))); + )))); let original = serde_json::to_value(app.tabs[i].scene.document.get_entity(source).unwrap()).unwrap(); let before = app.tabs[i].history.undo_stack.len(); @@ -1060,7 +1060,7 @@ mod thicken_tests { kernel::brep::extrude_surface(Plane::XY, &[Curve::Nurbs(profile)], [0.0, 0.0, 2.0]) .unwrap(); let source = app.add_surface_model( - codec::EntityType::Surface(Surface::new(SurfaceKind::Generic)), + codec::EntityType::Surface(Box::new(Surface::new(SurfaceKind::Generic))), body, ); let i = app.active_tab; diff --git a/src/app/commands/pdf_underlay.rs b/src/app/commands/pdf_underlay.rs index 5d1a98bd6..a45753708 100644 --- a/src/app/commands/pdf_underlay.rs +++ b/src/app/commands/pdf_underlay.rs @@ -322,7 +322,7 @@ impl OpenCADStudio { "_PCCROPCIRC" => "C", _ => "", }; - let command = crate::modules::insert::pc_crop::PointCloudCropCommand::for_cloud(handle, cloud, option); + let command = crate::modules::insert::pc_crop::PointCloudCropCommand::for_cloud(handle, *cloud, option); self.command_line.push_info(&command.prompt()); self.tabs[i].active_cmd = Some(Box::new(command)); } diff --git a/src/app/commands/point_cloud.rs b/src/app/commands/point_cloud.rs index 6f1ef62a0..0c302da32 100644 --- a/src/app/commands/point_cloud.rs +++ b/src/app/commands/point_cloud.rs @@ -163,10 +163,10 @@ impl OpenCADStudio { elevation_as_gradient: false, croppings: Vec::new(), }; - let entity = codec::EntityType::Extended(codec::entities::ExtendedEntity { + let entity = codec::EntityType::Extended(Box::new(codec::entities::ExtendedEntity { common: codec::entities::EntityCommon::new(), data: codec::entities::ExtendedEntityData::PointCloudEx(data), - }); + })); if let Some(cloud) = self.commit_entity_handle(entity) { // The reactor, owned by the cloud, tells the definition who uses it. let document = &mut self.tabs[i].scene.document; diff --git a/src/app/history.rs b/src/app/history.rs index 7133694c7..4ea0a0e99 100644 --- a/src/app/history.rs +++ b/src/app/history.rs @@ -685,15 +685,15 @@ impl OpenCADStudio { /// Add is delta-safe when its layer and XData application IDs already exist /// and it creates no block records. pub(super) fn delta_add_safe(&self, i: usize, entity: &EntityType) -> bool { - if matches!( - entity, - EntityType::Block(_) - | EntityType::BlockEnd(_) - | EntityType::Extended(codec::entities::ExtendedEntity { - data: codec::entities::ExtendedEntityData::SectionObject(_), - .. - }) - ) { + if matches!(entity, EntityType::Block(_) | EntityType::BlockEnd(_)) + || matches!( + entity, + EntityType::Extended(extended) if matches!( + extended.data, + codec::entities::ExtendedEntityData::SectionObject(_) + ) + ) + { return false; } let layer = entity.common().layer.clone(); diff --git a/src/app/model_ops.rs b/src/app/model_ops.rs index d4bf15247..0d522ada2 100644 --- a/src/app/model_ops.rs +++ b/src/app/model_ops.rs @@ -1354,7 +1354,7 @@ impl super::OpenCADStudio { let mut entity = Surface::new(SurfaceKind::Generic); entity.common = group.common; self.add_surface_model_preserving_style( - EntityType::Surface(entity), + EntityType::Surface(Box::new(entity)), group.body, ) } @@ -2316,7 +2316,7 @@ impl super::OpenCADStudio { } let n = surfaces.len(); for surf in surfaces { - self.tabs[i].scene.add_entity(EntityType::Surface(surf)); + self.tabs[i].scene.add_entity(EntityType::Surface(Box::new(surf))); } self.tabs[i].dirty = true; self.refresh_properties(); diff --git a/src/app/plugin_host.rs b/src/app/plugin_host.rs index b8d7acce9..edf47fe0c 100644 --- a/src/app/plugin_host.rs +++ b/src/app/plugin_host.rs @@ -198,14 +198,14 @@ impl<'a> HostSession<'a> { } if let EntityType::Helix(new) = entity { let old = match old { - Some(EntityType::Helix(old)) => Some(old), + Some(EntityType::Helix(old)) => Some(&**old), _ => None, }; crate::entities::helix::normalize_scripted_helix(old, new)?; } if let EntityType::Table(new) = entity { let old = match old { - Some(EntityType::Table(old)) => Some(old), + Some(EntityType::Table(old)) => Some(&**old), _ => None, }; crate::entities::table::normalize_scripted_table(old, new); @@ -758,7 +758,7 @@ impl<'a> HostSession<'a> { surface.wires = model::edge_wires(&body); surface.acis_data = codec::entities::AcisData::from_sat(&sat.to_sat_string()); surface.common.layer = layer; - self.commit_profile_result(EntityType::Surface(surface), source, delete_source, "Create surface") + self.commit_profile_result(EntityType::Surface(Box::new(surface)), source, delete_source, "Create surface") } SolidOperation::Extrude { source, direction, layer, delete_source } => { if direction.iter().any(|v| !v.is_finite()) { @@ -788,7 +788,7 @@ impl<'a> HostSession<'a> { surface.wires = model::edge_wires(&body); surface.acis_data = codec::entities::AcisData::from_sat(&sat.to_sat_string()); surface.common.layer = layer; - EntityType::Surface(surface) + EntityType::Surface(Box::new(surface)) }; self.commit_profile_result(result, source, delete_source, "Extrude profile") } @@ -7201,7 +7201,7 @@ mod tests { let unliftable = host.add_entity(EntityType::Solid3D(codec::entities::Solid3D::new())); let mut plane = codec::entities::Surface::new(codec::entities::SurfaceKind::Plane); plane.acis_data = codec::entities::AcisData::new(); - let surface = host.add_entity(EntityType::Surface(plane)); + let surface = host.add_entity(EntityType::Surface(Box::new(plane))); let far = { dispatch(&mut host, "PY_EVAL ocs.active_document.solids.box(center=(500, 500, 500), size=(1, 1, 1)).handle"); *solids_in(host.document()).last().unwrap() }; let counts = (host.document().entities().count(), host.app.tabs[0].history.undo_stack.len()); diff --git a/src/app/presspull_ops.rs b/src/app/presspull_ops.rs index a93d183d7..18eacfe20 100644 --- a/src/app/presspull_ops.rs +++ b/src/app/presspull_ops.rs @@ -140,7 +140,7 @@ impl super::OpenCADStudio { surface.surface_data = solid_history::extrusion_surface_data(record) .ok_or("PRESSPULL: the surface parameters could not be retained.")?; } - EntityType::Surface(surface) + EntityType::Surface(Box::new(surface)) }; (body, history, entity) } diff --git a/src/app/update/mod.rs b/src/app/update/mod.rs index ce1d7ccd3..ba26c5e29 100644 --- a/src/app/update/mod.rs +++ b/src/app/update/mod.rs @@ -10922,7 +10922,7 @@ mod free_text_entry_tests { let handle = app.tabs[0] .scene .document - .add_entity(EntityType::Table(table.clone())) + .add_entity(EntityType::Table(Box::new(table.clone()))) .unwrap(); app.set_active_command(0, Box::new(TableCellEditCommand::new(handle, &table, 0, 0))); (app, handle) diff --git a/src/entities/multileader.rs b/src/entities/multileader.rs index 74de8d97a..bf27cff68 100644 --- a/src/entities/multileader.rs +++ b/src/entities/multileader.rs @@ -2108,7 +2108,7 @@ impl MultiLeaderTess for MultiLeader { fill_tris_low: Vec::new(), }); - let host = codec::EntityType::MultiLeader(ml.clone()); + let host = codec::EntityType::MultiLeader(Box::new(ml.clone())); for block_use in crate::scene::render_graph::entity_render_block_uses(document, &host, 1.0) .into_iter() .filter(|block_use| { diff --git a/src/entities/traits.rs b/src/entities/traits.rs index 93b2f0dea..fbb797baa 100644 --- a/src/entities/traits.rs +++ b/src/entities/traits.rs @@ -81,6 +81,63 @@ pub trait Transformable { fn apply_transform(&mut self, t: &EntityTransform); } +// The codec boxes its rare wide entity kinds (Surface, Table, MultiLeader, +// Helix, Extended) so every other entity is stored narrow; the boxed ones +// answer through their contents. +impl RenderConvertible for Box { + fn to_render(&self, document: &CadDocument) -> Option { + (**self).to_render(document) + } +} + +impl Grippable for Box { + fn grips(&self) -> Vec { + (**self).grips() + } + fn apply_grip(&mut self, grip_id: usize, apply: GripApply) { + (**self).apply_grip(grip_id, apply) + } + fn grip_menu(&self, grip_id: usize) -> Vec { + (**self).grip_menu(grip_id) + } + fn apply_grip_menu(&mut self, grip_id: usize, action: GripMenuAction) { + (**self).apply_grip_menu(grip_id, action) + } + fn apply_grip_menu_value(&mut self, grip_id: usize, action: GripMenuAction, value: f64) { + (**self).apply_grip_menu_value(grip_id, action, value) + } + fn grip_menu_value_prompt( + &self, + grip_id: usize, + action: GripMenuAction, + ) -> Option<&'static str> { + (**self).grip_menu_value_prompt(grip_id, action) + } + fn grip_menu_point_value( + &self, + grip_id: usize, + action: GripMenuAction, + point: glam::DVec3, + ) -> Option { + (**self).grip_menu_point_value(grip_id, action, point) + } +} + +impl PropertyEditable for Box { + fn geometry_properties(&self, text_style_names: &[String]) -> Vec { + (**self).geometry_properties(text_style_names) + } + fn apply_geom_prop(&mut self, field: &str, value: &str) { + (**self).apply_geom_prop(field, value) + } +} + +impl Transformable for Box { + fn apply_transform(&mut self, t: &EntityTransform) { + (**self).apply_transform(t) + } +} + /// Inquiry-time mass / area / perimeter properties for entities whose /// 2D footprint has a meaningful area or perimeter (Circle, Arc, Line, /// LwPolyline, Ellipse). Entities outside this set get `None` via the diff --git a/src/modules/annotate/data_link.rs b/src/modules/annotate/data_link.rs index 00472d3bd..cbc7baf6f 100644 --- a/src/modules/annotate/data_link.rs +++ b/src/modules/annotate/data_link.rs @@ -160,7 +160,7 @@ impl CadCommand for DataLinkPlaceCommand { self.table.insertion_point = codec::types::Vector3::new(point.x, point.y, point.z); CmdResult::CommitAndExit( self.plane - .place_entity(EntityType::Table(self.table.clone())), + .place_entity(EntityType::Table(Box::new(self.table.clone()))), ) } diff --git a/src/modules/annotate/mleader_cmd.rs b/src/modules/annotate/mleader_cmd.rs index 262010a0d..fbb9c9add 100644 --- a/src/modules/annotate/mleader_cmd.rs +++ b/src/modules/annotate/mleader_cmd.rs @@ -269,7 +269,7 @@ impl MLeaderCommand { ml.text_style_handle = style_handle; ml.context.text_style_handle = style_handle; } - let entity = self.plane.place_entity(EntityType::MultiLeader(ml)); + let entity = self.plane.place_entity(EntityType::MultiLeader(Box::new(ml))); if self.content_type == LeaderContentType::MText && self.text.is_empty() { CmdResult::CommitAndEditText(entity) } else { diff --git a/src/modules/annotate/table_cmd.rs b/src/modules/annotate/table_cmd.rs index 7193b5397..2d5bfacf4 100644 --- a/src/modules/annotate/table_cmd.rs +++ b/src/modules/annotate/table_cmd.rs @@ -271,7 +271,7 @@ impl TableCommand { row.style = Some(styles[row_index.min(2)].clone()); } } - self.plane.place_entity(EntityType::Table(table)) + self.plane.place_entity(EntityType::Table(Box::new(table))) } fn preview_grid( @@ -795,7 +795,7 @@ impl CadCommand for TableCellEditCommand { cell.set_text(&formatted); self.table.block_record_handle = None; Some(CmdResult::ReplaceMany( - vec![(self.handle, vec![EntityType::Table(self.table.clone())])], + vec![(self.handle, vec![EntityType::Table(Box::new(self.table.clone()))])], Vec::new(), )) } diff --git a/src/modules/draw/draw/helix.rs b/src/modules/draw/draw/helix.rs index eafb53c97..6ae3b42fc 100644 --- a/src/modules/draw/draw/helix.rs +++ b/src/modules/draw/draw/helix.rs @@ -139,7 +139,7 @@ impl HelixCommand { helix.turn_height = if curve.turns == 0.0 { 0.0 } else { height / curve.turns }; helix.handedness = self.counter_clockwise; helix.constraint = self.constraint; - Some(EntityType::Helix(helix)) + Some(EntityType::Helix(Box::new(helix))) } fn commit(&mut self, height: f64, axis: DVec3) -> CmdResult { diff --git a/src/modules/draw/modify/reverse.rs b/src/modules/draw/modify/reverse.rs index cf4460c34..5d190774f 100644 --- a/src/modules/draw/modify/reverse.rs +++ b/src/modules/draw/modify/reverse.rs @@ -75,7 +75,8 @@ impl ReverseCommand { } EntityType::Spline(sp) => Some(EntityType::Spline(reverse_spline(sp))), EntityType::Helix(helix) => { - crate::entities::helix::reversed(helix).map(EntityType::Helix) + crate::entities::helix::reversed(helix) + .map(|helix| EntityType::Helix(Box::new(helix))) } _ => None, } diff --git a/src/modules/insert/pc_crop.rs b/src/modules/insert/pc_crop.rs index d9ca86f68..a5ca8e8dd 100644 --- a/src/modules/insert/pc_crop.rs +++ b/src/modules/insert/pc_crop.rs @@ -117,7 +117,10 @@ impl PointCloudCropCommand { if let ExtendedEntityData::PointCloudEx(data) = &mut cloud.data { change(data); } - CmdResult::UpdateEntityAndFinish { handle: self.handle, entity: EntityType::Extended(cloud) } + CmdResult::UpdateEntityAndFinish { + handle: self.handle, + entity: EntityType::Extended(Box::new(cloud)), + } } fn axes(data: &PointCloudExData) -> glam::DMat3 { @@ -296,7 +299,7 @@ impl CadCommand for PointCloudCropCommand { match self.picked.take() { Some(EntityType::Extended(cloud)) if matches!(cloud.data, ExtendedEntityData::PointCloudEx(_)) => { self.handle = handle; - self.cloud = Some(cloud); + self.cloud = Some(*cloud); if self.uncrop { return self.finish(|data| data.croppings.clear()); } diff --git a/src/modules/insert/solid3d_cmds.rs b/src/modules/insert/solid3d_cmds.rs index 8caddb981..934fbc432 100644 --- a/src/modules/insert/solid3d_cmds.rs +++ b/src/modules/insert/solid3d_cmds.rs @@ -2793,7 +2793,7 @@ pub fn empty_extruded_surface(direction: DVec3, taper_angle: f64) -> EntityType options.is_solid = false; *sweep_vector = Vector3::new(direction.x, direction.y, direction.z); } - EntityType::Surface(surface) + EntityType::Surface(Box::new(surface)) } pub fn empty_revolved_surface( @@ -2832,7 +2832,7 @@ pub fn empty_revolved_surface( *stored_start = start_angle; *solid = false; } - EntityType::Surface(surface) + EntityType::Surface(Box::new(surface)) } // ── Autocomplete registry ───────────────────────────────── @@ -2909,7 +2909,7 @@ mod thicken_command_tests { let handle = Handle::new(42); let mut command = ThickenCommand::new(vec![ (Handle::new(1), EntityType::Line(codec::entities::Line::default())), - (handle, EntityType::Surface(codec::entities::Surface::new(codec::entities::SurfaceKind::Plane))), + (handle, EntityType::Surface(Box::new(codec::entities::Surface::new(codec::entities::SurfaceKind::Plane)))), ]); assert!(!command.is_selection_gathering()); assert_eq!(command.handles, vec![handle]); diff --git a/src/modules/model/sectionplane_cmd.rs b/src/modules/model/sectionplane_cmd.rs index b75d4b1ef..13c85c39a 100644 --- a/src/modules/model/sectionplane_cmd.rs +++ b/src/modules/model/sectionplane_cmd.rs @@ -172,7 +172,7 @@ impl SectionPlaneCommand { self.kind == SectionKind::Slice, depth, ); - EntityType::Extended(entity) + EntityType::Extended(Box::new(entity)) } fn line_at(&self, point: DVec3, viewing: DVec3, vertical_hint: DVec3) -> (Vec, DVec3) { diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 151a808bf..dff34ff69 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -3052,10 +3052,10 @@ impl Scene { let is_insert = matches!(entity, EntityType::Insert(_)); let is_section = matches!( entity, - EntityType::Extended(codec::entities::ExtendedEntity { - data: codec::entities::ExtendedEntityData::SectionObject(_), - .. - }) + EntityType::Extended(extended) if matches!( + extended.data, + codec::entities::ExtendedEntityData::SectionObject(_) + ) ); if self.meshes.contains_key(&handle) || self.block_meshes.contains_key(&handle) @@ -7691,16 +7691,14 @@ impl Scene { CACHE_CATEGORY_MESH, |h| { self.meshes.contains_key(&h) - || matches!( - self.document.get_entity(h), - Some(EntityType::Insert(_)) - | Some(EntityType::Extended( - codec::entities::ExtendedEntity { - data: codec::entities::ExtendedEntityData::SectionObject(_), - .. - } - )) - ) + || match self.document.get_entity(h) { + Some(EntityType::Insert(_)) => true, + Some(EntityType::Extended(extended)) => matches!( + extended.data, + codec::entities::ExtendedEntityData::SectionObject(_) + ), + _ => false, + } }, ) => { @@ -12153,15 +12151,15 @@ mod section_tests { #[test] fn adding_and_erasing_a_section_keeps_its_object_graph_consistent() { let mut scene = Scene::new(); - let handle = scene.add_entity(EntityType::Extended(ExtendedEntity { + let handle = scene.add_entity(EntityType::Extended(Box::new(ExtendedEntity { common: EntityCommon::new(), data: ExtendedEntityData::SectionObject(section(1, 0.0)), - })); + }))); let settings_handle = match scene.document.get_entity(handle).unwrap() { - EntityType::Extended(ExtendedEntity { - data: ExtendedEntityData::SectionObject(data), - .. - }) => data.settings_handle, + EntityType::Extended(extended) => match &extended.data { + ExtendedEntityData::SectionObject(data) => data.settings_handle, + _ => unreachable!(), + }, _ => unreachable!(), }; assert!(matches!( diff --git a/src/scene/model/loft_command_model.rs b/src/scene/model/loft_command_model.rs index 9055c2e51..aa671e172 100644 --- a/src/scene/model/loft_command_model.rs +++ b/src/scene/model/loft_command_model.rs @@ -91,5 +91,5 @@ pub fn surface_entity(record: &SolidHistoryLoft) -> EntityType { ruled_surface: settings.normals == 0, virtual_guide: false, cross_sections: Vec::new(), guide_curves: Vec::new(), path_curve: None, }; - EntityType::Surface(surface) + EntityType::Surface(Box::new(surface)) } diff --git a/src/scene/model/sweep_command_model.rs b/src/scene/model/sweep_command_model.rs index 1d40b0efc..da2310700 100644 --- a/src/scene/model/sweep_command_model.rs +++ b/src/scene/model/sweep_command_model.rs @@ -109,5 +109,5 @@ pub fn swept_surface_entity(record: &SolidHistorySweep) -> EntityType { ..SurfaceSweepOptions::default() }, }; - EntityType::Surface(surface) + EntityType::Surface(Box::new(surface)) } diff --git a/src/scene/selection.rs b/src/scene/selection.rs index 8a536fa01..019803e51 100644 --- a/src/scene/selection.rs +++ b/src/scene/selection.rs @@ -1002,10 +1002,14 @@ impl Scene { continue; } let settings_handle = self.document.get_entity(h).and_then(|entity| match entity { - EntityType::Extended(codec::entities::ExtendedEntity { - data: codec::entities::ExtendedEntityData::SectionObject(data), - .. - }) if !data.settings_handle.is_null() => Some(data.settings_handle), + EntityType::Extended(extended) => match &extended.data { + codec::entities::ExtendedEntityData::SectionObject(data) + if !data.settings_handle.is_null() => + { + Some(data.settings_handle) + } + _ => None, + }, _ => None, }); let section_managers: Vec = managers_by_section diff --git a/tests/section_plane_roundtrip.rs b/tests/section_plane_roundtrip.rs index afa7f3395..da08c1c61 100644 --- a/tests/section_plane_roundtrip.rs +++ b/tests/section_plane_roundtrip.rs @@ -14,7 +14,7 @@ fn add_slice(scene: &mut Scene) -> Handle { thickness.values = vec![XDataValue::Real(0.75)]; common.extended_data.add_record(thickness); - scene.add_entity(EntityType::Extended(ExtendedEntity { + scene.add_entity(EntityType::Extended(Box::new(ExtendedEntity { common, data: ExtendedEntityData::SectionObject(SectionObjectData { state: 1, @@ -29,7 +29,7 @@ fn add_slice(scene: &mut Scene) -> Handle { back_line_vertices: Vec::new(), settings_handle: Handle::NULL, }), - })) + }))) } fn assert_section_graph(document: &codec::CadDocument, extension: &str) {