Extract gbrush (#2784)
Some checks failed
Editor: Dev & CI / build (push) Has been cancelled
Editor: Dev & CI / cargo-deny (push) Has been cancelled

This commit is contained in:
Firestar99 2025-07-01 20:38:47 +02:00 committed by GitHub
parent 602d7e8bd1
commit a182a7347e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 85 additions and 30 deletions

View file

@ -0,0 +1,28 @@
[package]
name = "graphene-brush"
version = "0.1.0"
edition = "2024"
description = "graphene brush"
authors = ["Graphite Authors <contact@graphite.rs>"]
license = "MIT OR Apache-2.0"
[features]
default = ["serde"]
serde = ["dep:serde"]
[dependencies]
# Local dependencies
dyn-any = { workspace = true }
graphene-core = { workspace = true }
graphene-raster-nodes = { workspace = true }
node-macro = { workspace = true }
# Workspace dependencies
glam = { workspace = true }
# Optional workspace dependencies
serde = { workspace = true, optional = true, features = ["derive"] }
[dev-dependencies]
# Workspace dependencies
tokio = { workspace = true }

View file

@ -1,17 +1,19 @@
use crate::brush_cache::BrushCache;
use crate::brush_stroke::{BrushStroke, BrushStyle};
use glam::{DAffine2, DVec2};
use graph_craft::generic::FnNode;
use graph_craft::proto::FutureWrapperNode;
use graphene_core::blending::BlendMode;
use graphene_core::bounds::BoundingBox;
use graphene_core::color::{Alpha, Color, Pixel, Sample};
use graphene_core::generic::FnNode;
use graphene_core::instances::Instance;
use graphene_core::math::bbox::{AxisAlignedBbox, Bbox};
use graphene_core::raster::brush_cache::BrushCache;
use graphene_core::raster::BitmapMut;
use graphene_core::raster::image::Image;
use graphene_core::raster::{Alpha, BitmapMut, BlendMode, Color, Pixel, Sample};
use graphene_core::raster_types::{CPU, Raster, RasterDataTable};
use graphene_core::registry::FutureWrapperNode;
use graphene_core::transform::Transform;
use graphene_core::value::ClonedNode;
use graphene_core::vector::brush_stroke::{BrushStroke, BrushStyle};
use graphene_core::{Ctx, GraphicElement, Node};
use graphene_core::{Ctx, Node};
use graphene_raster_nodes::adjustments::blend_colors;
use graphene_raster_nodes::std_nodes::{empty_image, extend_image_to_bounds};
@ -50,7 +52,7 @@ impl<P: Pixel + Alpha> Sample for BrushStampGenerator<P> {
return None;
};
use graphene_core::raster::Channel;
use graphene_core::color::Channel;
Some(self.color.multiplied_alpha(P::AlphaChannel::from_linear(result)))
}
}
@ -78,7 +80,6 @@ fn brush_stamp_generator(#[unit(" px")] diameter: f64, color: Color, hardness: f
fn blit<BlendFn>(mut target: RasterDataTable<CPU>, texture: Raster<CPU>, positions: Vec<DVec2>, blend_mode: BlendFn) -> RasterDataTable<CPU>
where
BlendFn: for<'any_input> Node<'any_input, (Color, Color), Output = Color>,
GraphicElement: From<Raster<CPU>>,
{
if positions.is_empty() {
return target;
@ -392,7 +393,7 @@ mod test {
(),
RasterDataTable::<CPU>::new(Raster::new_cpu(Image::<Color>::default())),
vec![BrushStroke {
trace: vec![crate::vector::brush_stroke::BrushInputSample { position: DVec2::ZERO }],
trace: vec![crate::brush_stroke::BrushInputSample { position: DVec2::ZERO }],
style: BrushStyle {
color: Color::BLACK,
diameter: 20.,

View file

@ -1,9 +1,9 @@
use crate::instances::Instance;
use crate::raster_types::CPU;
use crate::raster_types::Raster;
use crate::vector::brush_stroke::BrushStroke;
use crate::vector::brush_stroke::BrushStyle;
use crate::brush_stroke::BrushStroke;
use crate::brush_stroke::BrushStyle;
use dyn_any::DynAny;
use graphene_core::instances::Instance;
use graphene_core::raster_types::CPU;
use graphene_core::raster_types::Raster;
use std::collections::HashMap;
use std::hash::Hash;
use std::sync::Arc;
@ -15,11 +15,11 @@ struct BrushCacheImpl {
prev_input: Vec<BrushStroke>,
// The strokes that have been fully processed and blended into the background.
#[serde(deserialize_with = "crate::graphene_core::raster::image::migrate_image_frame_instance")]
#[serde(deserialize_with = "graphene_core::raster::image::migrate_image_frame_instance")]
background: Instance<Raster<CPU>>,
#[serde(deserialize_with = "crate::graphene_core::raster::image::migrate_image_frame_instance")]
#[serde(deserialize_with = "graphene_core::raster::image::migrate_image_frame_instance")]
blended_image: Instance<Raster<CPU>>,
#[serde(deserialize_with = "crate::graphene_core::raster::image::migrate_image_frame_instance")]
#[serde(deserialize_with = "graphene_core::raster::image::migrate_image_frame_instance")]
last_stroke_texture: Instance<Raster<CPU>>,
// A cache for brush textures.

View file

@ -1,8 +1,8 @@
use crate::Color;
use crate::math::bbox::AxisAlignedBbox;
use crate::raster::BlendMode;
use dyn_any::DynAny;
use glam::DVec2;
use graphene_core::blending::BlendMode;
use graphene_core::color::Color;
use graphene_core::math::bbox::AxisAlignedBbox;
use std::hash::{Hash, Hasher};
/// The style of a brush.

View file

@ -0,0 +1,3 @@
pub mod brush;
pub mod brush_cache;
pub mod brush_stroke;

View file

@ -12,7 +12,6 @@ pub mod color {
pub use super::*;
}
pub mod brush_cache;
pub mod image;
pub use self::image::Image;

View file

@ -1,5 +1,4 @@
pub mod algorithms;
pub mod brush_stroke;
pub mod click_target;
pub mod generator_nodes;
pub mod misc;

View file

@ -17,6 +17,7 @@ loading = ["serde_json"]
dyn-any = { workspace = true }
graphene-core = { workspace = true }
graphene-path-bool = { workspace = true }
graphene-brush = { workspace = true }
graphene-application-io = { workspace = true }
graphene-svg-renderer = { workspace = true }
graphene-raster-nodes = { workspace = true }

View file

@ -5,7 +5,8 @@ use dyn_any::DynAny;
pub use dyn_any::StaticType;
pub use glam::{DAffine2, DVec2, IVec2, UVec2};
use graphene_application_io::SurfaceFrame;
use graphene_core::raster::brush_cache::BrushCache;
use graphene_brush::brush_cache::BrushCache;
use graphene_brush::brush_stroke::BrushStroke;
use graphene_core::raster_types::CPU;
use graphene_core::transform::ReferencePoint;
use graphene_core::uuid::NodeId;
@ -208,7 +209,7 @@ tagged_value! {
#[serde(alias = "GradientPositions")] // TODO: Eventually remove this alias document upgrade code
GradientStops(graphene_core::vector::style::GradientStops),
Font(graphene_core::text::Font),
BrushStrokes(Vec<graphene_core::vector::brush_stroke::BrushStroke>),
BrushStrokes(Vec<BrushStroke>),
BrushCache(BrushCache),
DocumentNode(DocumentNode),
Curve(graphene_raster_nodes::curve::Curve),

View file

@ -33,6 +33,7 @@ graphene-math-nodes = { workspace = true }
graphene-svg-renderer = { workspace = true }
graphene-application-io = { workspace = true }
graphene-raster-nodes = { workspace = true }
graphene-brush = { workspace = true }
# Workspace dependencies
fastnoise-lite = { workspace = true }

View file

@ -1,11 +1,11 @@
pub mod any;
pub mod brush;
pub mod http;
pub mod text;
#[cfg(feature = "wasm")]
pub mod wasm_application_io;
pub use graphene_application_io as application_io;
pub use graphene_brush as brush;
pub use graphene_core::vector;
pub use graphene_core::*;
pub use graphene_math_nodes as math_nodes;