Add the 'Basic Brush' node and replace the legacy Brush tool implementation with it (#4469)

* Draw raster images with pad extension instead of repeat

* Add the GPU basic brush renderer

* Rework the brush tool around the GPU basic brush

* Remove the CPU brush implementation
This commit is contained in:
Timon
2026-08-27 15:19:02 +00:00
committed by GitHub
parent fd31f2d89b
commit c7a64fff0c
31 changed files with 2181 additions and 1016 deletions
+9 -33
View File
@@ -3,20 +3,23 @@ use core_types::registry::types::Percentage;
use core_types::{Color, Ctx};
use graphic_types::Graphic;
pub mod brush;
mod brush_cache;
pub mod brush_stroke;
pub mod basic_brush;
pub use brush_types::*;
pub(crate) const DEFAULT_DIAMETER: f64 = 40.;
pub(crate) const DEFAULT_HARDNESS: f64 = 0.;
pub(crate) const DEFAULT_FLOW: f64 = 100.;
pub(crate) const DEFAULT_COLOR: Color = Color::BLACK;
#[node_macro::node(category("Raster: Brush"))]
fn brush_strokes(
_: impl Ctx,
strokes: List<Stroke>,
color: List<Color>,
#[default(40.)] diameter: Item<f64>,
#[default(0.)] hardness: Item<Percentage>,
#[default(100.)] flow: Item<Percentage>,
#[default(DEFAULT_DIAMETER)] diameter: Item<f64>,
#[default(DEFAULT_HARDNESS)] hardness: Item<Percentage>,
#[default(DEFAULT_FLOW)] flow: Item<Percentage>,
) -> List<Graphic> {
let (diameter, hardness, flow) = (diameter.into_element(), hardness.into_element(), flow.into_element());
List::new_from_item(
@@ -27,30 +30,3 @@ fn brush_strokes(
.with_attribute(ATTR_FLOW, (flow / 100.).clamp(0., 1.)),
)
}
pub mod migrations {
use crate::brush_stroke::BrushStroke;
// TODO: Eventually remove this document upgrade code
pub fn migrate_to_brush_strokes<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Vec<BrushStroke>, D::Error> {
use serde::Deserialize;
#[derive(serde::Deserialize)]
struct LegacyTable {
#[serde(alias = "instances", alias = "instance")]
element: Vec<BrushStroke>,
}
#[derive(serde::Deserialize)]
#[serde(untagged)]
enum BrushStrokesFormat {
Strokes(Vec<BrushStroke>),
List(LegacyTable),
}
Ok(match BrushStrokesFormat::deserialize(deserializer)? {
BrushStrokesFormat::Strokes(strokes) => strokes,
BrushStrokesFormat::List(list) => list.element,
})
}
}