forked from 1b-agent/opencadstudio-upstream
fix(edit): STRETCH moves dimension definition points (#372)
The STRETCH apply loop had no Dimension arm, so dimensions fell into the generic skip — points never moved, and a reopened file's stale baked *D block made the result snap back visually. Move every definition point inside the window (grip-equivalent set plus pinned text, sparing the zero auto-placement sentinel), refresh the stored measurement, and drop the stale *D block so the stretch survives render and save. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
3205f7a2b9
commit
5383c64d5d
1 file changed
+81
@@ -1423,6 +1423,9 @@ impl OpenCADStudio {
|
||||
let dy = delta.y as f64; // drawing plane is world XY
|
||||
let dz = delta.z as f64;
|
||||
|
||||
// Dimensions whose points moved — their baked *D block is
|
||||
// stale afterwards and must be dropped (see #398 / #372).
|
||||
let mut stretched_dims: Vec<acadrust::Handle> = Vec::new();
|
||||
for handle in &handles {
|
||||
let Some(entity) = self.tabs[i].scene.document.get_entity_mut(*handle) else {
|
||||
continue;
|
||||
@@ -1520,6 +1523,75 @@ impl OpenCADStudio {
|
||||
stretched = true;
|
||||
}
|
||||
}
|
||||
acadrust::EntityType::Dimension(dim) => {
|
||||
use acadrust::entities::Dimension;
|
||||
// Move every definition point that falls inside the
|
||||
// window — the same points the grips expose — then
|
||||
// refresh the stored measurement so the value tracks
|
||||
// the stretched geometry.
|
||||
let mut mv = |p: &mut acadrust::types::Vector3| {
|
||||
if in_win(p.x, p.y) {
|
||||
p.x += dx;
|
||||
p.y += dy;
|
||||
p.z += dz;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
match dim {
|
||||
Dimension::Linear(d) => {
|
||||
stretched |= mv(&mut d.first_point);
|
||||
stretched |= mv(&mut d.second_point);
|
||||
stretched |= mv(&mut d.definition_point);
|
||||
}
|
||||
Dimension::Aligned(d) => {
|
||||
stretched |= mv(&mut d.first_point);
|
||||
stretched |= mv(&mut d.second_point);
|
||||
stretched |= mv(&mut d.definition_point);
|
||||
}
|
||||
Dimension::Radius(d) => {
|
||||
stretched |= mv(&mut d.angle_vertex);
|
||||
stretched |= mv(&mut d.definition_point);
|
||||
}
|
||||
Dimension::Diameter(d) => {
|
||||
stretched |= mv(&mut d.angle_vertex);
|
||||
stretched |= mv(&mut d.definition_point);
|
||||
}
|
||||
Dimension::Angular2Ln(d) => {
|
||||
stretched |= mv(&mut d.angle_vertex);
|
||||
stretched |= mv(&mut d.first_point);
|
||||
stretched |= mv(&mut d.second_point);
|
||||
stretched |= mv(&mut d.definition_point);
|
||||
}
|
||||
Dimension::Angular3Pt(d) => {
|
||||
stretched |= mv(&mut d.angle_vertex);
|
||||
stretched |= mv(&mut d.first_point);
|
||||
stretched |= mv(&mut d.second_point);
|
||||
stretched |= mv(&mut d.definition_point);
|
||||
}
|
||||
Dimension::Ordinate(d) => {
|
||||
stretched |= mv(&mut d.definition_point);
|
||||
stretched |= mv(&mut d.feature_location);
|
||||
stretched |= mv(&mut d.leader_endpoint);
|
||||
}
|
||||
}
|
||||
// Pinned text follows too; the zero sentinel means
|
||||
// "auto placement" and must not be captured by a
|
||||
// window that happens to cover the origin.
|
||||
let t = dim.base().text_middle_point;
|
||||
if t.x * t.x + t.y * t.y + t.z * t.z > 1e-16 {
|
||||
let mut t = t;
|
||||
if mv(&mut t) {
|
||||
dim.base_mut().text_middle_point = t;
|
||||
stretched = true;
|
||||
}
|
||||
}
|
||||
if stretched {
|
||||
dim.base_mut().actual_measurement = dim.measurement();
|
||||
stretched_dims.push(*handle);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Generic: move entire entity (treat as block-level)
|
||||
stretched = false; // skip generic types
|
||||
@@ -1530,6 +1602,15 @@ impl OpenCADStudio {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
// A stretched dimension renders through its baked *D block when
|
||||
// one exists (file roundtrip) — drop it so tessellation falls
|
||||
// back to the live points and the next save re-bakes. (#372)
|
||||
for h in stretched_dims {
|
||||
crate::modules::draw::modify::explode::invalidate_dim_block(
|
||||
&mut self.tabs[i].scene.document,
|
||||
h,
|
||||
);
|
||||
}
|
||||
|
||||
// Geometry was edited in place via get_entity_mut, which the
|
||||
// scene's tessellation cache doesn't observe. Re-tessellate the
|
||||
|
||||
Reference in new issue
Block a user