refactor(scene): reference-only designation becomes a scene-scoped set (API v9)

Per the upstream review of the XDATA-based storage: the host no longer writes
its own state into the saved file. The marker record under the host-owned OCS
APPID, the on-first-use APPID registration and the verbatim-EED rewrite
handling are removed; the single source of truth is a scene-scoped in-memory
set of entity handles (Scene::reference_only) that dies with the drawing tab,
so a reopened file starts undesignated and the owning plugin re-marks on the
document-opened notification.

All behaviour sites are unchanged, driven by the set: the wire stamp moves
from an XDATA read to a set lookup threaded through the tessellation
pipelines (tessellate_entity and the dimension text path take the handle set
as a plain parameter), and the pick filters, selection retains and
update/erase refusals read Scene::is_reference_only.

Undo keeps the entity-write contract: set mutations are recorded as explicit
first-touch before/after values on each history delta (the parametric-
constraints channel pattern). A designation inside a plugin push_undo scope
joins it, a scope-less change is one step of its own, an idempotent re-mark
records nothing, erasing a designated entity drops the set entry with the
entity, and undo/redo restores entity and designation together.

The round-trip test is inverted: reference_only_designation_is_not_written_
to_dwg_or_dxf now asserts the marker appears in neither format's bytes, that
no OCS APPID or marker record survives a reload, and that the designation
stays live in memory.
This commit is contained in:
Sebastian committed 2026-10-14 21:12:17 +02:00
1 parent 06ee0798a8
commit 50db12b169
17 files changed
+623 -232

No files matched your search

+14
View File
@@ -3598,6 +3598,7 @@ fn apply_dimension_jog(
}
pub trait DimensionTess {
#[allow(clippy::too_many_arguments)]
fn tessellate(
&self,
document: &CadDocument,
@@ -3611,10 +3612,12 @@ pub trait DimensionTess {
bg_color: [f32; 4],
view_aabb: Option<[f32; 4]>,
world_per_pixel: Option<f32>,
reference_only: &rustc_hash::FxHashSet<codec::Handle>,
) -> Vec<WireModel>;
}
impl DimensionTess for Dimension {
#[allow(clippy::too_many_arguments)]
fn tessellate(
&self,
document: &CadDocument,
@@ -3628,6 +3631,7 @@ impl DimensionTess for Dimension {
bg_color: [f32; 4],
view_aabb: Option<[f32; 4]>,
world_per_pixel: Option<f32>,
reference_only: &rustc_hash::FxHashSet<codec::Handle>,
) -> Vec<WireModel> {
tessellate_dimension_inner(
document,
@@ -3642,10 +3646,12 @@ impl DimensionTess for Dimension {
bg_color,
view_aabb,
world_per_pixel,
reference_only,
)
}
}
#[allow(clippy::too_many_arguments)]
fn tessellate_dimension_inner(
document: &CadDocument,
handle: Handle,
@@ -3662,6 +3668,7 @@ fn tessellate_dimension_inner(
bg_color: [f32; 4],
view_aabb: Option<[f32; 4]>,
world_per_pixel: Option<f32>,
reference_only: &rustc_hash::FxHashSet<codec::Handle>,
) -> Vec<WireModel> {
if let Dimension::Arc(arc) = dim {
if let Some((local_arc, normal)) = arc_dimension_in_ocs(arc) {
@@ -3678,6 +3685,7 @@ fn tessellate_dimension_inner(
bg_color,
None,
world_per_pixel,
reference_only,
);
for wire in &mut wires {
map_wire_ocs_to_wcs(wire, normal);
@@ -3700,6 +3708,7 @@ fn tessellate_dimension_inner(
bg_color,
None,
world_per_pixel,
reference_only,
);
for wire in &mut wires {
map_wire_ocs_to_wcs(wire, normal);
@@ -3721,6 +3730,7 @@ fn tessellate_dimension_inner(
bg_color,
None,
world_per_pixel,
reference_only,
);
for wire in &mut wires {
map_wire_ocs_to_wcs(wire, normal);
@@ -4420,6 +4430,7 @@ fn tessellate_dimension_inner(
view_aabb,
world_per_pixel,
text_color,
reference_only,
);
for mut w in text_wires {
w.name = name.clone();
@@ -4437,6 +4448,7 @@ fn tessellate_dimension_inner(
view_aabb,
world_per_pixel,
text_color,
reference_only,
);
for mut w in tol_wires {
w.name = name.clone();
@@ -8890,6 +8902,7 @@ mod linear_transform_tests {
[0.0, 0.0, 0.0, 1.0],
None,
None,
&rustc_hash::FxHashSet::default(),
);
let mut points = Vec::new();
for wire in &wires {
@@ -9221,6 +9234,7 @@ mod layout_parity_tests {
[0.0, 0.0, 0.0, 1.0],
None,
None,
&rustc_hash::FxHashSet::default(),
);
let mut points = Vec::new();
let mut fills = 0;