fix(point): keep DDPTYPE off dimension definition points
Dimension definition points come out of a DWG as ordinary POINT entities on the Defpoints layer, so the header's PDMODE applied to them like any other point. Opening a drawing authored elsewhere with a point style set stamped that glyph on every dimension end, burying the drawing under crosses and circles. They are a dimension's bookkeeping, not draughting the user placed, so resolve PDMODE to 0 for them and leave the single pixel-sized dot. Both render paths — the header one and the viewport-aware relative-PDSIZE one — go through the same resolution, so a relative PDSIZE cannot bring the glyph back. Fixes #790
This commit is contained in:
parent
97a6322e2a
commit
f6f4317b7f
1 changed files with 77 additions and 2 deletions
|
|
@ -82,7 +82,7 @@ pub fn relative_render(
|
|||
return None;
|
||||
};
|
||||
let pdsize = document.header.point_display_size;
|
||||
let pdmode = document.header.point_display_mode;
|
||||
let pdmode = effective_pdmode(pt, document.header.point_display_mode);
|
||||
if pdsize > 0.0 || pdmode == 0 {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -173,8 +173,26 @@ fn point_glyph(cx: f64, cy: f64, z: f64, pdmode: i16, s_half: f64) -> Vec<[f64;
|
|||
pts
|
||||
}
|
||||
|
||||
/// Layer AutoCAD writes dimension definition points to.
|
||||
const DEFPOINTS_LAYER: &str = "DEFPOINTS";
|
||||
|
||||
/// PDMODE as it applies to `pt`.
|
||||
///
|
||||
/// Definition points are ordinary POINT entities on the Defpoints layer, but
|
||||
/// they are a dimension's bookkeeping rather than draughting the user placed.
|
||||
/// Letting DDPTYPE stamp its glyph on them buries a drawing imported from other
|
||||
/// software under crosses and circles at every dimension end, so they stay the
|
||||
/// pixel-sized dot whatever the header says. (#378, #790)
|
||||
fn effective_pdmode(pt: &Point, pdmode: i16) -> i16 {
|
||||
if pt.common.layer.eq_ignore_ascii_case(DEFPOINTS_LAYER) {
|
||||
0
|
||||
} else {
|
||||
pdmode
|
||||
}
|
||||
}
|
||||
|
||||
fn to_render(pt: &Point, document: &acadrust::CadDocument) -> RenderEntity {
|
||||
let pdmode = document.header.point_display_mode;
|
||||
let pdmode = effective_pdmode(pt, document.header.point_display_mode);
|
||||
let s = pdsize_world(document.header.point_display_size) * 0.5;
|
||||
point_render(pt, pdmode, s)
|
||||
}
|
||||
|
|
@ -240,3 +258,60 @@ impl RenderConvertible for Point {
|
|||
}
|
||||
|
||||
crate::impl_entity_basics!(Point);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn point_on(layer: &str) -> Point {
|
||||
let mut pt = Point::default();
|
||||
pt.common.layer = layer.to_string();
|
||||
pt.location = acadrust::types::Vector3::new(1.0, 2.0, 0.0);
|
||||
pt
|
||||
}
|
||||
|
||||
/// #378 / #790: DDPTYPE must not reach a dimension's definition points.
|
||||
#[test]
|
||||
fn definition_points_ignore_the_point_style() {
|
||||
let mut doc = acadrust::CadDocument::new();
|
||||
// Circle-enclosed cross: the style that made imported drawings unreadable.
|
||||
doc.header.point_display_mode = 34;
|
||||
doc.header.point_display_size = 2.0;
|
||||
|
||||
let drawn = to_render(&point_on("0"), &doc);
|
||||
assert!(
|
||||
matches!(drawn.object, RenderObject::Lines(ref pts) if !pts.is_empty()),
|
||||
"a point the user placed still follows PDMODE"
|
||||
);
|
||||
|
||||
for layer in ["Defpoints", "DEFPOINTS", "defpoints"] {
|
||||
let defpoint = to_render(&point_on(layer), &doc);
|
||||
assert!(
|
||||
matches!(defpoint.object, RenderObject::Dot(_)),
|
||||
"a definition point on {layer} must stay a dot"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The relative-PDSIZE path hands the glyph a viewport size; it must make
|
||||
/// the same call, or a definition point would come back as a sized cross.
|
||||
#[test]
|
||||
fn definition_points_ignore_the_point_style_at_relative_pdsize() {
|
||||
let mut doc = acadrust::CadDocument::new();
|
||||
doc.header.point_display_mode = 34;
|
||||
doc.header.point_display_size = -5.0;
|
||||
|
||||
let drawn = relative_render(&EntityType::Point(point_on("0")), &doc, Some(0.01));
|
||||
assert!(drawn.is_some(), "a user point still takes the viewport-aware path");
|
||||
|
||||
let defpoint = relative_render(
|
||||
&EntityType::Point(point_on("Defpoints")),
|
||||
&doc,
|
||||
Some(0.01),
|
||||
);
|
||||
assert!(
|
||||
defpoint.is_none(),
|
||||
"a definition point falls through to the dot instead of a sized glyph"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue