Files
hcie-rust-v3.05/hcie-brush-engine
phantom 0d1b0eae4c fix: optimize brush stroke handling and improve cursor preview
- Changed default VISION_BACKEND from CPU to GPU for better performance.
- Made `map_brush_style` public to allow external access.
- Updated `Engine` struct to use pooled buffers for stroke snapshots, reducing memory allocations during brush strokes.
- Introduced `CompositeSnapshot` for efficient background compositing without blocking the UI thread.
- Implemented `SendPtr` for safe raw pointer handling across threads.
- Enhanced `commit_pending_history` to recycle buffers and improve performance.
- Fixed cursor preview issues for procedural brushes by removing unnecessary preset synchronization.
- Added tests and documentation for new features and performance improvements.
2026-07-11 08:53:17 +03:00
..
2026-07-09 02:59:53 +03:00
2026-07-09 02:59:53 +03:00
2026-07-09 02:59:53 +03:00
2026-07-09 02:59:53 +03:00

HCIE Brush Engine

High-performance procedural brush engine for paint/drawing applications. Provides 33 brush styles with GPU-accelerated test tool.

Project Structure

hcie-brush-engine/
├── Cargo.toml              # Project manifest
├── src/
│   ├── lib.rs              # Core library: brush stamps, strokes, FFI
│   ├── dynamics.rs         # Pressure, velocity, tilt mapping
│   └── presets.rs          # Predefined brush presets (28 presets)
├── examples/
│   └── brush_test.rs       # GPU-accelerated tiled test tool (egui/eframe)
└── tests/
    └── stamp.rs            # Integration tests

Quick Start

Run Tests

cargo test

Run Test GUI (Brush Visualizer)

cargo run --example brush_test

The test tool opens a window with:

  • Canvas: 5124096px resolution, auto-scaled to window
  • Tiled GPU rendering: 512px tiles, only modified tiles uploaded
  • Brush presets: 28 preset brushes in categories (Basic, Sketch, Paint, Nature, Texture, Effect, Mixer)
  • Parameters: Size, hardness, opacity, spacing sliders
  • FPS cap: 30 / 60 / 165 / Unlimited selectable
  • Live diagnostics: FPS counter, dirty tile count, stroke counter

Run Benchmarks

cargo test --release

Library API

Core Types

// Brush style enum (33 variants)
pub enum BrushStyle { Round, Square, HardRound, SoftRound, Star, Noise, Texture,
    Spray, Pencil, Pen, Calligraphy, Oil, Charcoal, Leaf, Rock, Meadow, Wood,
    Watercolor, Marker, Sketch, Hatch, Glow, Airbrush, Crayon, WetPaint, InkPen,
    Clouds, Dirt, Tree, Bristle, Mixer, Blender, Bitmap }

// Brush tip configuration
pub struct BrushTip {
    pub style: BrushStyle,
    pub size: f32,              // diameter in pixels
    pub opacity: f32,           // 0.01.0
    pub hardness: f32,          // 0.0 (soft)  1.0 (hard)
    pub spacing: f32,           // 0.015.0, relative to size
    pub jitter_amount: f32,     // random position jitter
    pub scatter_amount: f32,    // random scatter offset
    pub angle: f32,             // brush angle in radians
    pub roundness: f32,         // 0.01.0, 1.0 = perfect circle
    pub spray_particle_size: f32,
    pub spray_density: u32,
    pub bitmap_pixels: Vec<u8>, // for Bitmap brush style
    pub bitmap_w: u32,
    pub bitmap_h: u32,
}

Essential Functions

Function Description
generate_brush_stamp(tip: &BrushTip) -> Vec<u8> Procedural alpha mask (diameter × diameter, 0-255)
sample_stamp(stamp: &[u8], diameter: usize, x: f32, y: f32) -> f32 Bilinear sample from stamp
brush_spacing_pixels(size: f32, spacing_ratio: f32) -> f32 Effective spacing in pixels
jitter_offset(jitter_amount: f32, size: f32) -> (f32, f32) Random jitter offset
scatter_offset(scatter_amount: f32, size: f32) -> (f32, f32) Random scatter offset
draw_dab(pixels: &mut [u8], w: u32, h: u32, cx: f32, cy: f32, size: f32, hardness: f32, color: [u8;4], opacity: f32, is_eraser: bool, mask: Option<&[u8]>) Single brush dab (RGBA)
draw_specialized_stroke(...) Full stroke with interpolation for all brush styles

Brush Drawing Functions

Each brush style has its own signature (oil, charcoal, watercolor, calligraphy, marker, glow, airbrush, spray, pencil, square, wetpaint, mixer, leaf, crayon, tree, meadow, rock, clouds, dirt, stipple, bristle, wood, sketch, hatch).

See src/lib.rs for full signatures.

Presets (hcie_brush_engine::presets)

pub struct BrushPreset {
    pub id: String,
    pub name: String,
    pub category: String,
    pub tip: BrushTip,
    pub style: BrushStyle,
    pub pressure_size: bool,
    pub pressure_opacity: bool,
    pub pressure_flow: bool,
    pub jitter_position: f32,
    pub jitter_angle: f32,
}

impl BrushPreset {
    pub fn all_defaults() -> Vec<Self>;  // returns all 28 presets
    pub fn basic_round() -> Self;
    pub fn hard_round() -> Self;
    pub fn soft_round() -> Self;
    pub fn soft_airbrush() -> Self;
    pub fn pencil() -> Self;
    pub fn ink_pen() -> Self;
    pub fn charcoal() -> Self;
    pub fn marker() -> Self;
    pub fn watercolor_wash() -> Self;
    pub fn watercolor() -> Self;
    pub fn oil_paint() -> Self;
    pub fn gouache() -> Self;
    pub fn crayon() -> Self;
    pub fn spray() -> Self;
    pub fn calligraphy() -> Self;
    pub fn smudge() -> Self;
    pub fn mixer() -> Self;
    pub fn blender() -> Self;
    pub fn meadow_grass() -> Self;
    pub fn rock_texture() -> Self;
    pub fn clouds() -> Self;
    pub fn dirt() -> Self;
    pub fn tree_bark() -> Self;
    pub fn stipple() -> Self;
    pub fn splatter() -> Self;
    pub fn pastel() -> Self;
    pub fn bristle() -> Self;
    pub fn glow() -> Self;
    pub fn hatch() -> Self;
    pub fn sketch() -> Self;
}

Dynamics (hcie_brush_engine::dynamics)

pub struct StrokeDynamics {
    pub pressure: f32,     // 0.01.0
    pub velocity: f32,     // px/frame
    pub tilt: (f32, f32),  // degrees
}

pub fn effective_size(base: f32, dyn: &StrokeDynamics, sensitive: bool) -> f32;
pub fn effective_opacity(base: f32, dyn: &StrokeDynamics, sensitive: bool) -> f32;
pub fn effective_flow(base: f32, dyn: &StrokeDynamics, sensitive: bool) -> f32;
pub fn velocity_size_modifier(velocity: f32) -> f32;
pub fn build_dynamic_tip(base: &BrushTip, dyn: &StrokeDynamics, press_size: bool, press_opacity: bool) -> BrushTip;
pub fn simulate_pressure_from_velocity(velocity: f32, max_velocity: f32) -> f32;
pub struct VelocityTracker { /* tracks velocity from consecutive points */ }

FFI (C Foreign Function Interface)

The library builds as cdylib. Primary entry point:

// See src/lib.rs for exact signatures
void draw_specialized_stroke_ffi(
    uint8_t* pixels, uint32_t pixels_len,
    uint32_t width, uint32_t height,
    const float* points, uint32_t points_count,
    int32_t brush_style,
    float size, float hardness,
    const uint8_t* color,
    float opacity, float spacing_ratio,
    uint8_t is_eraser,
    /* ... mask/stroke_mask/bg params ... */
);

For detailed FFI signatures, see the #[no_mangle] functions at the bottom of src/lib.rs.


Linking Without Source Code

Cargo (Rust Projects)

[dependencies]
hcie-brush-engine = { git = "https://github.com/your-org/hcie-brush-engine" }
# or local path:
hcie-brush-engine = { path = "../hcie-brush-engine" }

C/C++ Projects

  1. Build the library:
    cargo build --release
    
  2. Link against the produced shared library (target/release/libhcie_brush_engine.so / .dylib / .dll).
  3. Include the header generated by cbindgen or use the raw C declarations from the #[no_mangle] functions in src/lib.rs.

License

[Your license here]