forked from 1b-agent/opencadstudio-upstream
fix(export): keep plot coordinates in f64 until they cancel
A UTM drawing plotted deformed — both geometry and text — while the same drawing near the origin came out clean. Every pass of the exporter narrowed an absolute world coordinate to f32 before the offset had a chance to cancel it, and f32 resolution at UTM is ~0.03 m on easting and ~0.5 m on northing, so the whole plot snapped onto that grid. Four places did it, all now folding in f64 and narrowing only once the result is a single-digit sheet-mm value: - The wire pass never read `points_low` at all — the word did not appear in the file — so it plotted the double-single "high" half alone and dropped every residual. - emit_hatch cast the f64 `world_origin` to f32, re-introducing at the last step exactly the quantisation the boundary-relative encoding exists to avoid. - pattern_segments rasterised entirely in absolute f32. The pattern is anchored at world (0,0), so a hatch at UTM runs a line index k of ~1e7: `origin + k · step` and the `edge − line` intersections both fall apart there. k also becomes i64 — `as i32` saturates silently, which would collapse the range to a bogus run from i32::MIN rather than drop the fill. - emit_text folded `pos + pos_low` in f32, which rounds straight back to `pos`: the residual the pair exists to carry was discarded at precisely the coordinates it was carried for. The offsets themselves were also narrowed by the callers, so the value meant to cancel a UTM coordinate was quantised before it could. Widen ox/oy to f64 through export_pdf, build_pdf, print_wires and the two plot-param builders; printing shared the same path and the same bug. Pre-existing, not from #390 — that change only routed text through the same faulty pipe the wires were already in. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
5018963d3d
commit
f452ae9211
4 files changed
+120
-75
No files matched your search
+16
-12
@@ -1243,8 +1243,8 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
wipeouts.as_slice(),
|
||||
eff_w,
|
||||
eff_h,
|
||||
draw_ox as f32,
|
||||
draw_oy as f32,
|
||||
draw_ox,
|
||||
draw_oy,
|
||||
rotation_deg,
|
||||
1.0,
|
||||
None,
|
||||
@@ -1313,8 +1313,8 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
// scale (rotation_deg == 0 adds no further CTM translation).
|
||||
// window_to_sheet's (ox, oy) is the sheet-mm target for the window's
|
||||
// min corner, so: scale * (x0 + offset_x) = ox => offset_x = ox/scale - x0.
|
||||
let offset_x = ((ox / scale) - x0) as f32;
|
||||
let offset_y = ((oy / scale) - y0) as f32;
|
||||
let offset_x = (ox / scale) - x0;
|
||||
let offset_y = (oy / scale) - y0;
|
||||
// Clip rect in pre-scale space (build_pdf's CTM applies `scale` to it,
|
||||
// same as the wires) so the final sheet-mm rect lands at (ox, oy).
|
||||
let clip = Some(((ox / scale) as f32, (oy / scale) as f32, win_w as f32, win_h as f32));
|
||||
@@ -1359,8 +1359,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
Vec<crate::scene::model::hatch_model::HatchModel>,
|
||||
f64,
|
||||
f64,
|
||||
f32,
|
||||
f32,
|
||||
// Draw offsets stay f64: they cancel an absolute world coordinate that
|
||||
// an f32 cannot hold at UTM scale.
|
||||
f64,
|
||||
f64,
|
||||
i32,
|
||||
) {
|
||||
let i = self.active_tab;
|
||||
@@ -1411,8 +1413,8 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
wipeouts,
|
||||
eff_w,
|
||||
eff_h,
|
||||
draw_ox as f32,
|
||||
draw_oy as f32,
|
||||
draw_ox,
|
||||
draw_oy,
|
||||
rotation_deg,
|
||||
)
|
||||
}
|
||||
@@ -2076,8 +2078,10 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
Vec<crate::scene::model::hatch_model::HatchModel>,
|
||||
f64,
|
||||
f64,
|
||||
f32,
|
||||
f32,
|
||||
// Offsets stay f64 (they cancel a UTM-scale world coordinate); the plot
|
||||
// scale is a small ratio and stays f32.
|
||||
f64,
|
||||
f64,
|
||||
f32,
|
||||
Option<(f32, f32, f32, f32)>,
|
||||
)> {
|
||||
@@ -2113,8 +2117,8 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
.collect();
|
||||
let hatches: Vec<_> = scene.paper_canvas_hatches().as_ref().clone();
|
||||
let wipeouts: Vec<_> = scene.paper_canvas_wipeouts().as_ref().clone();
|
||||
let offset_x = ((ox / scale) - x0) as f32;
|
||||
let offset_y = ((oy / scale) - y0) as f32;
|
||||
let offset_x = (ox / scale) - x0;
|
||||
let offset_y = (oy / scale) - y0;
|
||||
let clip = Some((
|
||||
(ox / scale) as f32,
|
||||
(oy / scale) as f32,
|
||||
|
||||
Reference in new issue
Block a user