feat(gradient): selectable gradient types + working creation
GRADIENT silently degraded to a plain hatch: add_hatch rebuilt the render model from the DXF entity but never encoded the gradient on it, so the committed fill lost its gradient entirely. The entity now carries the full gradient record (name, angle, colour stops, solid-fill flag), and the standard shape set became selectable: Linear / Cylinder / Spherical / Hemispherical / Curved plus an Invert toggle, offered as prompt buttons on the GRADIENT command and as a Gradient type dropdown + Invert box in the properties panel. All nine standard DXF names round-trip (inverted linear persists by swapping the colour stops), and the shaders shape each kind distinctly — mirrored cylinder, eased curve, dome-profiled hemisphere — on both the native and web pipelines without changing the GPU struct sizes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
9bfcad18b9
commit
930d8c51ea
8 changed files with 290 additions and 32 deletions
|
|
@ -213,7 +213,33 @@ fn properties(h: &Hatch) -> Vec<PropSection> {
|
|||
options: vec!["Two color".into(), "One color".into()],
|
||||
},
|
||||
},
|
||||
ro("Gradient name", "gradient_name", g.name.clone()),
|
||||
{
|
||||
let (kind, invert) =
|
||||
crate::scene::model::hatch_model::GradientKind::from_name(&g.name);
|
||||
let _ = invert;
|
||||
Property {
|
||||
label: "Gradient type".into(),
|
||||
field: "gradient_type",
|
||||
value: PropValue::Choice {
|
||||
selected: kind.label().to_string(),
|
||||
options: crate::scene::model::hatch_model::GradientKind::ALL
|
||||
.iter()
|
||||
.map(|k| k.label().to_string())
|
||||
.collect(),
|
||||
},
|
||||
}
|
||||
},
|
||||
Property {
|
||||
label: "Invert".into(),
|
||||
field: "gradient_invert",
|
||||
value: PropValue::BoolToggle {
|
||||
field: "gradient_invert",
|
||||
value: crate::scene::model::hatch_model::GradientKind::from_name(
|
||||
&g.name,
|
||||
)
|
||||
.1,
|
||||
},
|
||||
},
|
||||
Property {
|
||||
label: "Color 1".into(),
|
||||
field: "gradient_color_1",
|
||||
|
|
@ -427,6 +453,30 @@ fn apply_geom_prop(h: &mut Hatch, field: &str, value: &str) {
|
|||
h.gradient_color.is_single_color = value == "One color";
|
||||
return;
|
||||
}
|
||||
// Gradient shape selection + stop inversion (#415). Both re-derive the
|
||||
// standard DXF gradient name; Linear has no INV name, so inverting a
|
||||
// linear swaps the colour stops instead.
|
||||
"gradient_type" => {
|
||||
use crate::scene::model::hatch_model::GradientKind;
|
||||
let (_, invert) = GradientKind::from_name(&h.gradient_color.name);
|
||||
if let Some(kind) = GradientKind::from_label(value) {
|
||||
h.gradient_color.name = kind.dxf_name(invert).to_string();
|
||||
}
|
||||
return;
|
||||
}
|
||||
"gradient_invert" => {
|
||||
use crate::scene::model::hatch_model::GradientKind;
|
||||
let (kind, invert) = GradientKind::from_name(&h.gradient_color.name);
|
||||
let invert = !invert;
|
||||
if matches!(kind, GradientKind::Linear) {
|
||||
if h.gradient_color.colors.len() >= 2 {
|
||||
h.gradient_color.colors.swap(0, 1);
|
||||
}
|
||||
} else {
|
||||
h.gradient_color.name = kind.dxf_name(invert).to_string();
|
||||
}
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let Some(v) = parse_f64(value) else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue