forked from 1b-agent/opencadstudio-upstream
fix(plot): correct hatch rendering in PDF / plot export
Hatched content — especially fills nested inside a block INSERT, such as a title-block logo — plotted incorrectly: missing, mis-spaced, or with phantom bars. Five related fixes make the PDF/plot output match AutoCAD. 1. Export block-internal hatch fills. The export collected only hatches owned directly by the layout block, so a hatch nested in a block INSERT was dropped and printed as bare monochrome outlines. The insert-explosion the viewport already does is extracted into a shared `exploded_insert_hatch_models()` and called from both the viewport (`synced_hatch_models`) and the export (`paper_canvas_hatches`), so a plot draws block-internal hatches identically to the screen. 2. Honour the hatch's own stored pattern-line spacing. `hatch_model_from_dxf` re-derived pattern spacing from the name-matched catalog entry x pattern_scale, ignoring the resolved line geometry the DWG stores on the hatch. When a drawing was authored against a different base spacing (imperial 0.125 vs the catalog's metric 3.175 for ANSI31), lines came out up to ~25x too coarse and a dense fill collapsed to a few stray lines. When the hatch carries its own line geometry it is now used directly (identity scale/angle); the catalog path remains the fallback. 3. Fill far-from-origin pattern hatches. `pattern_segments` clamped the ABSOLUTE scan-line index to +/-MAX_LINES_PER_FAMILY. A fine-spaced hatch far from the pattern origin has large-magnitude indices at both ends but a small span, so the clamp inverted the range and emitted nothing — silently dropping the fill. Cap the line count (span) instead of the absolute index. 4. Skip TEXTBOX boundary paths. TEXTBOX boundary paths (flag bit 3) are text bounding-boxes AutoCAD derives for island detection; they are never drawn or filled. Treating one as a fill boundary painted its rectangle solid — a phantom bar. It is now skipped when building the fill boundary. 5. Print white/ACI-7 hatch fills black on paper. Hatch fills arrive adapted to the dark screen background, so a white/ACI-7 fill would vanish white-on-white on the sheet. Mirror the wire pass: near-white/near-yellow -> black, near-cyan -> dark blue, matching AutoCAD's colour-7-on-white plotting. Wipeouts keep their paper-white mask. Adds `tests/block_hatch_export.rs` covering: block-internal hatch reaches the export set, stored-line spacing is honoured, far-from-origin fills are not dropped, and TEXTBOX paths are not filled.
This commit is contained in:
1 parent
b50921923f
commit
1a45f6bd97
5 files changed
+393
-55
No files matched your search
+20
-1
@@ -381,10 +381,29 @@ fn emit_hatch(ops: &mut Vec<Op>, hatch: &HatchModel, ox: f32, oy: f32) {
|
||||
if hatch.boundary.is_empty() {
|
||||
return;
|
||||
}
|
||||
let [r, g, b, a] = hatch.color;
|
||||
let [mut r, mut g, mut b, a] = hatch.color;
|
||||
if a < 0.01 {
|
||||
return;
|
||||
}
|
||||
// Adapt hatch fills to the white sheet, mirroring the wire pass: colours
|
||||
// arrive adapted to the (dark) screen background, so a white/ACI-7 fill
|
||||
// would vanish white-on-white on paper. Force near-white/near-yellow → black
|
||||
// and near-cyan → dark blue, matching AutoCAD's colour-7-on-white plotting.
|
||||
// Genuine colours are untouched; WIPEOUTS keep their paper-white mask.
|
||||
if hatch.name != "WIPEOUT_FILL" {
|
||||
let is_light = r > 0.80 && g > 0.80 && b > 0.80;
|
||||
let is_yellow = r > 0.80 && g > 0.70 && b < 0.30;
|
||||
let is_cyan = r < 0.30 && g > 0.70 && b > 0.70;
|
||||
if is_light || is_yellow {
|
||||
r = 0.0;
|
||||
g = 0.0;
|
||||
b = 0.0;
|
||||
} else if is_cyan {
|
||||
r = 0.0;
|
||||
g = 0.15;
|
||||
b = 0.50;
|
||||
}
|
||||
}
|
||||
let world_ox = hatch.world_origin[0] as f32;
|
||||
let world_oy = hatch.world_origin[1] as f32;
|
||||
|
||||
|
||||
Reference in new issue
Block a user