forked from 1b-agent/opencadstudio-upstream
fix(precision): keep typed coordinates exact in f64 (#311)
Typed values were quantized to the f32 grid before reaching the entity (e.g. a length of 2000.8 committed as 2000.8020), worsening with magnitude. The interaction point layer was all glam::Vec3 (f32). Two-layer fix: 1. Coordinate backbone -> f64. last_point, last_cursor_world, dyn_anchor, dyn_ref become DVec3; UcsXform transforms, parse_coord, the ucs helper fns, dyn_resolve_point, the OTRACK typed-distance paths, command-line coordinate entry and the coordinate readout all compute in f64. Screen/GPU/alignment stays f32 (snap engine, render geometry, projection, UCS-icon/viewcube drawing) with casts only at those boundaries. 2. Per-command committed storage -> DVec3. on_point already received a DVec3, but many command impls narrowed it back to f32 (let pt = pt.as_vec3(); Vec<Vec3> fields) and re-widened at build, quantizing the committed coordinate. Migrated PLINE, SPLINE, MLINE, LENGTHEN, INSERT, 3D primitives, every dimension/leader/mleader, ray, revcloud, wipeout, attdef, table, tolerance, array center, mview, plot_window, plus the QDIM_PLACE handler and qdim_collect_points. Preview, hit-test and rubber-band paths keep f32 at the boundary. Hatch manual boundaries are left for a follow-up: HatchModel.boundary is structurally Arc<Vec<[f32;2]>> and needs a model-level widen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
8ed10ceb2a
commit
57710eec2b
47 files changed
+699
-606
No files matched your search
@@ -159,11 +159,16 @@ pub fn lengthen_entity(entity: &EntityType, pick_pt: Vec3, mode: &LenMode) -> Op
|
||||
}
|
||||
|
||||
fn lengthen_line(line: &LineEnt, pick_pt: Vec3, mode: &LenMode) -> Option<EntityType> {
|
||||
let s = Vec3::new(line.start.x as f32, line.start.y as f32, 0.0);
|
||||
let e = Vec3::new(line.end.x as f32, line.end.y as f32, 0.0);
|
||||
let p = Vec3::new(pick_pt.x, pick_pt.y, 0.0);
|
||||
// Keep the line's own coordinates on the f64 grid; only pick_pt (screen-only,
|
||||
// nearest-end selection) widens for the distance compare.
|
||||
let sx = line.start.x;
|
||||
let sy = line.start.y;
|
||||
let ex = line.end.x;
|
||||
let ey = line.end.y;
|
||||
|
||||
let current_len = (e - s).length() as f64;
|
||||
let dx = ex - sx;
|
||||
let dy = ey - sy;
|
||||
let current_len = (dx * dx + dy * dy).sqrt();
|
||||
if current_len < 1e-10 {
|
||||
return None;
|
||||
}
|
||||
@@ -173,23 +178,28 @@ fn lengthen_line(line: &LineEnt, pick_pt: Vec3, mode: &LenMode) -> Option<Entity
|
||||
return None;
|
||||
}
|
||||
|
||||
let dir = (e - s) / current_len as f32;
|
||||
let ux = dx / current_len;
|
||||
let uy = dy / current_len;
|
||||
|
||||
// Which end is closer to pick?
|
||||
let dist_to_start = (p - s).length();
|
||||
let dist_to_end = (p - e).length();
|
||||
let px = pick_pt.x as f64;
|
||||
let py = pick_pt.y as f64;
|
||||
let dist_to_start = (px - sx).hypot(py - sy);
|
||||
let dist_to_end = (px - ex).hypot(py - ey);
|
||||
|
||||
let mut result = line.clone();
|
||||
result.common.handle = Handle::NULL;
|
||||
|
||||
if dist_to_end <= dist_to_start {
|
||||
// Extend/trim the end
|
||||
let new_end = s + dir * new_len as f32;
|
||||
result.end = xz_to_v3(new_end, line.end.z);
|
||||
let new_x = sx + ux * new_len;
|
||||
let new_y = sy + uy * new_len;
|
||||
result.end = Vector3::new(new_x, new_y, line.end.z);
|
||||
} else {
|
||||
// Extend/trim the start (move start backward along dir)
|
||||
let new_start = e - dir * new_len as f32;
|
||||
result.start = xz_to_v3(new_start, line.start.z);
|
||||
let new_x = ex - ux * new_len;
|
||||
let new_y = ey - uy * new_len;
|
||||
result.start = Vector3::new(new_x, new_y, line.start.z);
|
||||
}
|
||||
Some(EntityType::Line(result))
|
||||
}
|
||||
@@ -335,11 +345,6 @@ fn arc_span_rad(start: f64, end: f64) -> f64 {
|
||||
}
|
||||
}
|
||||
|
||||
fn xz_to_v3(v: Vec3, z: f64) -> Vector3 {
|
||||
// v is (world_x, world_z, 0) → DXF (x, world_z, z)
|
||||
Vector3::new(v.x as f64, v.y as f64, z)
|
||||
}
|
||||
|
||||
fn lengthen_lwpoly(poly: &LwPolyline, pick_pt: Vec3, mode: &LenMode) -> Option<EntityType> {
|
||||
let n = poly.vertices.len();
|
||||
if n < 2 {
|
||||
|
||||
Reference in new issue
Block a user