3D: a group's fill or stroke takes no 3D effect

Revolve, Extrude & Bevel, Inflate and Rotate on a group or layer draw only as the group's own effect. On the group's fill or stroke they drew nothing, yet effect.apply and effect.setParams accepted them. Both now refuse that placement.
This commit is contained in:
dotCooCoo
2026-11-09 17:51:22 -08:00
parent 32ddc21045
commit cddebdf7f6
3 changed files with 15 additions and 1 deletions
+11
View File
@@ -717,6 +717,17 @@ mod tests {
assert_eq!(revolve_art(&both), None, "past the limits the source draws");
}
#[test]
fn a_3d_effect_on_a_groups_fill_is_refused() {
let mut group = Node::group(NodeId(9), vec![member(1, 0.0)]);
group.appearance = Appearance::basic(Paint::solid(Color::BLACK), Paint::None, 0.0).into();
for id in [REVOLVE, crate::EXTRUDE] {
assert!(crate::validate_three_d(&group, id, &json!({})).is_ok(), "{id} on the group itself");
let refused = crate::validate_three_d_at(&group, id, &json!({}), Some((0, 0))).unwrap_err();
assert!(refused.contains("on the group itself"), "{id}: {refused}");
}
}
#[test]
fn validation_measures_the_profile_after_the_geometry_effects_before_revolve() {
let roughen = crate::new_effect("distort.roughen", &json!({"size": 1, "detail": 100})).unwrap();
+2
View File
@@ -302,8 +302,10 @@ pub fn validate_three_d(n: &Node, id: &str, p: &Value) -> Result<(), String> {
/// appearance item `item` of `n` (the effects' length for a new effect), or on the object itself
/// when `at` is `None`. A Revolve on a fill or stroke is checked in that item's paint, after the
/// item's geometry effects before it, together with the object's other items that carry a Revolve.
/// A group's or layer's fills and strokes take no 3D effect: only the group's own effect draws.
pub fn validate_three_d_at(n: &Node, id: &str, p: &Value, at: Option<(usize, usize)>) -> Result<(), String> {
match at {
Some(_) if is_container(n) => Err("A 3D effect on a group or layer goes on the group itself, not on its fill or stroke".into()),
Some((item, index)) if id == crate::REVOLVE => crate::revolve::validate_item_revolve(n, p, item, index),
_ => validate_three_d(n, id, p),
}
+2 -1
View File
@@ -2461,7 +2461,8 @@ checked as that effect's. It is one undo step. Any other `threeDType` value, or
`effect.apply {effect: "threeD.extrude" | "threeD.inflate" | "threeD.rotate", params: {...}, ids?, item?}` applies
the other 3D types to a path or compound path, live like Revolve (the source stays editable; SVG/PDF exports and
`effect.expandAppearance` use the same shaded faces). An object takes one 3D effect, Revolve included.
`effect.expandAppearance` use the same shaded faces). An object takes one 3D effect, Revolve included. On a group or
layer the 3D effect goes on the group itself: `effect.apply` and `effect.setParams` refuse one on its fill or stroke.
`threeD.extrude`: `depth` (points, 0..2000, default 50), `twist` (degrees, 0..360, 0), `taper` (1..100%, 100),
`cap` (true solid, false hollow), `bevel` (`none`, `classic`, `rounded`, `cove`, `step`, `ogee`), `bevelWidth`