Cargo: codec e023bc3 (acadrust sync), kernel abca4e8, graph c63556f

The codec now holds wide EntityType variants boxed (MText, Helix,
Dimension, Hatch, Viewport, MultiLeader, Surface, Table, Ole2Frame,
Light, Extended). Constructors box their entity; nested patterns reach
a dimension through entities::dimension::as_dimension(_mut). Also
follows BlockAction::action_ids, LineTypeComplexData::source_flags and
the decimal tab stop with an explicit character.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-16 09:17:01 +03:00
1 parent 218150c76a
commit e4d04ef132
87 files changed
+380 -269

No files matched your search

+7 -7
View File
@@ -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.
+1 -1
View File
@@ -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;
+14 -8
View File
@@ -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<f64>,
) -> 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;
+6 -10
View File
@@ -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
+1 -1
View File
@@ -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();
}
+1 -1
View File
@@ -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);
+3 -2
View File
@@ -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]
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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();
+2 -2
View File
@@ -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());
+5 -2
View File
@@ -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
+2 -2
View File
@@ -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(_))
)
}
+6 -4
View File
@@ -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<WireModel> = 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());
}
}
}
+1 -1
View File
@@ -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.);
+4 -4
View File
@@ -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 {
+37 -33
View File
@@ -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<Handle> {
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(_)
+2 -2
View File
@@ -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()
}
+13 -6
View File
@@ -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;
}
+1 -1
View File
@@ -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()
+5 -5
View File
@@ -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,
+24 -5
View File
@@ -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,
}
}
+3 -3
View File
@@ -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,
+3 -1
View File
@@ -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,
+10
View File
@@ -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<T: TextContent + ?Sized> TextContent for Box<T> {
fn text_content(&self) -> Option<String> {
(**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.
+2 -2
View File
@@ -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(
+2
View File
@@ -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)],
},
};
+8 -5
View File
@@ -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");
+1 -1
View File
@@ -168,7 +168,7 @@ pub fn add_embedded_image(
) -> Result<codec::Handle, String> {
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())
}
+1 -1
View File
@@ -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"))
+1 -1
View File
@@ -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 {
+3 -3
View File
@@ -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 {
+1 -1
View File
@@ -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,
+2 -2
View File
@@ -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 {
+3 -3
View File
@@ -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<Vec<DimensionPreview>> {
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,
}]
})
+3 -3
View File
@@ -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<Vec<DimensionPreview>> {
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,
}]
})
+7 -3
View File
@@ -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;
}
+8 -5
View File
@@ -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(),
+1 -1
View File
@@ -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 {
+3 -1
View File
@@ -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,
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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))))
}
}
+5 -5
View File
@@ -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<WireModel> {
return Vec::new();
};
let mut lines: Vec<Vec<[f64; 3]>> = Vec::new();
match dimension {
match &**dimension {
Dimension::Linear(value) => {
let first = d3(value.first_point);
let second = d3(value.second_point);
+2 -2
View File
@@ -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
+4 -3
View File
@@ -222,7 +222,7 @@ fn separate(p: &Piece, doc: &CadDocument) -> Vec<EntityType> {
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<EntityType> {
.collect::<Vec<_>>()
.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))],
})
}
+1 -1
View File
@@ -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 {
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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)))
}
}
}
+13 -13
View File
@@ -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);
+1 -1
View File
@@ -262,7 +262,7 @@ fn mtext(lines: &[DgnGeom], style: String, node: bool) -> Option<EntityType> {
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.
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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,
}
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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)
{
+26 -22
View File
@@ -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");
};
+1 -1
View File
@@ -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());
+3 -3
View File
@@ -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);
+5 -5
View File
@@ -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());
+2 -2
View File
@@ -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),
+15 -11
View File
@@ -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(_)
);
+2 -2
View File
@@ -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,
})
+1 -1
View File
@@ -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)))
}
}
}