.ai import: an Art brushed path opens live only when its own settings would

A path's Art brush settings matched the brush's within a small tolerance, and only the brush's were checked. A path with a Spacing of 0.0005, or guides that leave no art between them, opened live with the brush's settings. The path's settings now pass the same checks as the brush's, and such a path keeps its drawn look.
This commit is contained in:
dotCooCoo
2026-11-13 20:03:35 -08:00
parent 49a3c3d718
commit 991c36458a
2 changed files with 11 additions and 4 deletions
+5 -2
View File
@@ -277,7 +277,8 @@ pub(super) fn bending_art(drafts: &[BrushDraft], art: &HashMap<String, Node>) ->
/// Does the brush `draft` draw as `settings`, the settings a path's art style gives it? A path whose
/// settings differ (Options of Selected Object) keeps its drawn look: a stroke names a brush, and
/// has no settings of its own. An Art brush's settings that don't draw ([`drawn`]) may differ.
/// has no settings of its own. An Art brush's settings that don't draw ([`drawn`]) may differ, and
/// the path's own settings must be ones the brush would open with ([`art_options`], [`opens_live`]).
/// `bending`: [`bending_art`].
pub(super) fn draws_as(draft: &BrushDraft, settings: &PathBrush, bending: &HashMap<String, f64>) -> bool {
let close = |a: f64, b: f64| (a - b).abs() <= 1e-3 * a.abs().max(b.abs()).max(1.0);
@@ -290,7 +291,9 @@ pub(super) fn draws_as(draft: &BrushDraft, settings: &PathBrush, bending: &HashM
&& d.modes() == c.modes()
}
(DraftKind::Art { settings: Some(d), art: name, .. }, PathBrush::Art(s)) => {
drawn(d).iter().zip(drawn(s)).all(|(a, b)| close(*a, b)) && bending.get(name).is_some_and(|length| opens_live(d, *length))
drawn(d).iter().zip(drawn(s)).all(|(a, b)| close(*a, b))
&& art_options(s).is_some()
&& bending.get(name).is_some_and(|length| opens_live(d, *length) && opens_live(s, *length))
}
_ => false,
}
+6 -2
View File
@@ -10601,7 +10601,8 @@ fn an_art_brushed_path_the_brush_cant_draw_keeps_its_drawn_look() {
("its own width", good.clone(), style_with("Scaling", "2")),
("a width on the pen", good.clone(), style_with("ScaleYDependsOn", "2")),
("spacing", good.clone(), style_with("Spacing", "1")),
("flipped", good.clone(), style_with("UpsideDown", "1")),
("a spacing close to the brush's 0", good.clone(), style_with("Spacing", "0.0005")),
("flipped",good.clone(), style_with("UpsideDown", "1")),
("flipped the other way", good.clone(), style_with("Counterclockwise", "1")),
("another adjustment", good.clone(), style_with("Adjustment", "2")),
("no fold adjustment", good.clone(), style_with("FoldAdjustment", "0")),
@@ -10639,13 +10640,16 @@ fn an_art_brushed_path_the_brush_cant_draw_keeps_its_drawn_look() {
("both: guides that leave no art between them", &[(10, "1"), (11, "30"), (12, "10")]),
("both: a guide past the start", &[(10, "1"), (11, "-5"), (12, "10")]),
];
let cases: Vec<(&str, String, String)> = cases
let mut cases: Vec<(&str, String, String)> = cases
.into_iter()
.chain(own.iter().map(|(why, changes)| {
let (def, style) = ribbon_with(changes);
(*why, def, style)
}))
.collect();
// The brush's guides leave art between them, and the path's, close to them, leave none.
let (def, style) = ribbon_with(&[(10, "1"), (11, "20"), (12, "19.99")]);
cases.push(("path guides close to the brush's that leave no art between them", def, style.replace("19.99 /", "20 /")));
let mut wrong = vec![];
for (why, def, style) in cases {
let r = read_ok(&format!("{def}{style}{}", layer(&brushed_path())));