Migrate remaining node graph data types from Vec to Table (#4067)

* Move Vec<String> to Table<String>

* Remove old VecDVec2

* Move Vec<u8> to Table<u8>

* Move Vec<f64> to Table<f64>

* Move [f64; 4] to Table<f64>

* Move Vec<NodeId> to Table<NodeId>

* Tidy up the TaggedValue variants

* Move Vec<BrushStroke> to Table<BrushStroke>

* Add missing type implementations

* Fix tests

---------
This commit is contained in:
Keavon Chambers
2026-04-28 13:44:25 -07:00
committed by GitHub
parent cf150b5cff
commit b396d17211
25 changed files with 277 additions and 341 deletions
+9 -5
View File
@@ -192,7 +192,7 @@ async fn brush(
/// Optional raster content that may be drawn onto.
mut image: Table<Raster<CPU>>,
/// The list of brush stroke paths drawn by the Brush tool, with each including both its coordinates and styles.
strokes: Vec<BrushStroke>,
strokes: Table<BrushStroke>,
/// Internal cache data used to accelerate rendering of the brush content.
cache: BrushCache,
) -> Table<Raster<CPU>> {
@@ -205,11 +205,15 @@ async fn brush(
let bounds = Table::new_from_row(table_row.clone()).bounding_box(DAffine2::IDENTITY, false);
let [start, end] = if let RenderBoundingBox::Rectangle(rect) = bounds { rect } else { [DVec2::ZERO, DVec2::ZERO] };
let image_bbox = AxisAlignedBbox { start, end };
let stroke_bbox = strokes.iter().map(|s| s.bounding_box()).reduce(|a, b| a.union(&b)).unwrap_or(AxisAlignedBbox::ZERO);
let stroke_bbox = strokes.iter_element_values().map(|s| s.bounding_box()).reduce(|a, b| a.union(&b)).unwrap_or(AxisAlignedBbox::ZERO);
let bbox = if image_bbox.size().length() < 0.1 { stroke_bbox } else { stroke_bbox.union(&image_bbox) };
let background_bounds = bbox.to_transform();
let mut draw_strokes: Vec<_> = strokes.iter().filter(|&s| !matches!(s.style.blend_mode, BlendMode::Erase | BlendMode::Restore)).cloned().collect();
let mut draw_strokes: Vec<_> = strokes
.iter_element_values()
.filter(|&s| !matches!(s.style.blend_mode, BlendMode::Erase | BlendMode::Restore))
.cloned()
.collect();
let mut brush_plan = cache.compute_brush_plan(table_row, &draw_strokes);
@@ -273,12 +277,12 @@ async fn brush(
actual_image = blend_with_mode(actual_image, stroke_texture, stroke.style.blend_mode, (stroke.style.color.a() * 100.) as f64);
}
let has_erase_or_restore_strokes = strokes.iter().any(|s| matches!(s.style.blend_mode, BlendMode::Erase | BlendMode::Restore));
let has_erase_or_restore_strokes = strokes.iter_element_values().any(|s| matches!(s.style.blend_mode, BlendMode::Erase | BlendMode::Restore));
if has_erase_or_restore_strokes {
let opaque_image = Image::new(bbox.size().x as u32, bbox.size().y as u32, Color::WHITE);
let mut erase_restore_mask = TableRow::new_from_element(Raster::new_cpu(opaque_image)).with_attribute("transform", background_bounds);
for stroke in strokes {
for stroke in strokes.into_iter().map(|row| row.into_element()) {
let mut brush_texture = cache.get_cached_brush(&stroke.style);
if brush_texture.is_none() {
let tex = create_brush_texture(&stroke.style).await;
+22
View File
@@ -1,3 +1,25 @@
pub mod brush;
pub mod brush_cache;
pub mod brush_stroke;
pub mod migrations {
use crate::brush_stroke::BrushStroke;
use core_types::table::{Table, TableRow};
// TODO: Eventually remove this migration document upgrade code
pub fn migrate_brush_strokes_to_table<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Table<BrushStroke>, D::Error> {
use serde::Deserialize;
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
enum BrushStrokeTableFormat {
BrushStrokes(Vec<BrushStroke>),
BrushStrokeTable(Table<BrushStroke>),
}
Ok(match BrushStrokeTableFormat::deserialize(deserializer)? {
BrushStrokeTableFormat::BrushStrokes(strokes) => strokes.into_iter().map(TableRow::new_from_element).collect(),
BrushStrokeTableFormat::BrushStrokeTable(table) => table,
})
}
}