forked from 1b-agent/opencadstudio-upstream
fix(render): halve polyline width — wide bands drew twice as wide
DXF codes 43 / 40 / 41 store a polyline band's full width, and `polyline_segment_fill` offsets ±hw about the centreline, so the stored value has to be halved. Both `wide_fills` passed it in whole and drew every wide polyline at double width. The codebase was writing the spec value and reading it as something else: `make_donut` stores `outer_r - inner_r`, a full width, which `wide_fills` then treated as a half-width. So OCS mis-drew even its own donuts. Seen on budweiser2018.dwg handle 2579, a donut of width 2.2 on a 1.1 centreline radius: it should fill out to radius 2.2 and instead reached 3.3 — a disc 1.5× its real size, overflowing the square it sits in. Affects every wide polyline, so TRACE and PEDIT-widened runs come back to true size too. The writers already stored full width and are left alone, as is the property panel, which shows the file's own value. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
3f060a570a
commit
07d7888b94
2 files changed
+13
-9
No files matched your search
@@ -662,9 +662,12 @@ impl crate::entities::traits::Transformable for LwPolyline {
|
||||
/// UTM-scale coordinates — building them in absolute f32 collapsed the band into
|
||||
/// a string of squares far from the origin.
|
||||
pub(crate) fn wide_fills(pl: &acadrust::entities::LwPolyline) -> ([f64; 2], Vec<Vec<[f32; 2]>>) {
|
||||
// The stored width is applied to EACH side of the centreline (not halved),
|
||||
// so `polyline_segment_fill`'s ±offset spans the full width on either side.
|
||||
let hw_const = pl.constant_width as f32;
|
||||
// Codes 43 / 40 / 41 store the band's FULL width, and
|
||||
// `polyline_segment_fill` offsets ±hw about the centreline — so halve it.
|
||||
// Feeding the stored width in whole draws every wide polyline twice as wide
|
||||
// as the file asks for, which on a donut (a closed 2-vertex bulge-1 polyline)
|
||||
// shows up as a disc 1.5× its real radius.
|
||||
let hw_const = pl.constant_width as f32 * 0.5;
|
||||
let verts = &pl.vertices;
|
||||
let n = verts.len();
|
||||
if n < 2 {
|
||||
@@ -677,12 +680,12 @@ pub(crate) fn wide_fills(pl: &acadrust::entities::LwPolyline) -> ([f64; 2], Vec<
|
||||
let v0 = &verts[i];
|
||||
let v1 = &verts[(i + 1) % n];
|
||||
let hw0 = if v0.start_width > 1e-9 {
|
||||
v0.start_width as f32
|
||||
v0.start_width as f32 * 0.5
|
||||
} else {
|
||||
hw_const
|
||||
};
|
||||
let hw1 = if v0.end_width > 1e-9 {
|
||||
v0.end_width as f32
|
||||
v0.end_width as f32 * 0.5
|
||||
} else {
|
||||
hw_const
|
||||
};
|
||||
|
||||
@@ -770,8 +770,9 @@ impl Transformable for Polyline3D {
|
||||
/// relative to (the first vertex). See `lwpolyline::wide_fills` — offsets are
|
||||
/// f32 from `origin` so the band stays precise at UTM-scale coordinates.
|
||||
pub(crate) fn wide_fills(pl: &acadrust::entities::Polyline2D) -> ([f64; 2], Vec<Vec<[f32; 2]>>) {
|
||||
// Width is applied full to each side of the centreline (not halved).
|
||||
let hw_default = pl.start_width.max(pl.end_width) as f32;
|
||||
// The stored widths are the band's FULL width and `polyline_segment_fill`
|
||||
// offsets ±hw about the centreline — halve them. See `lwpolyline::wide_fills`.
|
||||
let hw_default = pl.start_width.max(pl.end_width) as f32 * 0.5;
|
||||
let verts = &pl.vertices;
|
||||
let n = verts.len();
|
||||
if n < 2 {
|
||||
@@ -784,12 +785,12 @@ pub(crate) fn wide_fills(pl: &acadrust::entities::Polyline2D) -> ([f64; 2], Vec<
|
||||
let v0 = &verts[i];
|
||||
let v1 = &verts[(i + 1) % n];
|
||||
let hw0 = if v0.start_width > 1e-9 {
|
||||
v0.start_width as f32
|
||||
v0.start_width as f32 * 0.5
|
||||
} else {
|
||||
hw_default
|
||||
};
|
||||
let hw1 = if v0.end_width > 1e-9 {
|
||||
v0.end_width as f32
|
||||
v0.end_width as f32 * 0.5
|
||||
} else {
|
||||
hw_default
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user