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
-2
@@ -212,9 +212,14 @@ impl Scene {
|
||||
let mut m = model.clone();
|
||||
m.color = self.render_style(entity).0;
|
||||
if let EntityType::Hatch(dxf) = entity {
|
||||
// Only re-apply pattern_scale/angle for catalog-derived patterns
|
||||
// (empty stored lines). A pattern built from the hatch's own
|
||||
// stored lines is already final (scale 1 / angle 0).
|
||||
if let model::hatch_model::HatchPattern::Pattern(_) = &m.pattern {
|
||||
m.angle_offset = dxf.pattern_angle as f32;
|
||||
m.scale = dxf.pattern_scale as f32;
|
||||
if dxf.pattern.lines.is_empty() {
|
||||
m.angle_offset = dxf.pattern_angle as f32;
|
||||
m.scale = dxf.pattern_scale as f32;
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.selected.contains(&handle) {
|
||||
@@ -222,6 +227,19 @@ impl Scene {
|
||||
}
|
||||
models.push(m);
|
||||
}
|
||||
// Hatch fills nested inside a block INSERT are owned by the block
|
||||
// record, so the loop above — which only keeps hatches owned by
|
||||
// `layout_block` — never sees them. Explode the layout's visible
|
||||
// INSERTs and materialize their fills at world position, exactly as the
|
||||
// viewport does, so the export carries the block's colours instead of
|
||||
// bare outlines. (No selection tint on export.)
|
||||
let hatch_bg = if self.current_layout != "Model" {
|
||||
self.paper_bg_color
|
||||
} else {
|
||||
self.bg_color
|
||||
};
|
||||
let exploded = self.exploded_insert_hatch_models(layout_block, hatch_bg, false);
|
||||
models.extend(exploded);
|
||||
Arc::new(models)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user