diff --git a/node-graph/libraries/wgpu-executor/src/vector_to_raster.rs b/node-graph/libraries/wgpu-executor/src/vector_to_raster.rs index aa65f2bf8b..172d7920ef 100644 --- a/node-graph/libraries/wgpu-executor/src/vector_to_raster.rs +++ b/node-graph/libraries/wgpu-executor/src/vector_to_raster.rs @@ -1,7 +1,9 @@ use crate::WgpuExecutor; +use core_types::bounds::{BoundingBox, RenderBoundingBox}; use core_types::ops::Convert; use core_types::table::Table; use core_types::transform::Footprint; +use glam::{DAffine2, DVec2, UVec2}; use graphic_types::Vector; use graphic_types::raster_types::{GPU, Raster}; use rendering::{Render, RenderOutputType, RenderParams}; @@ -19,22 +21,51 @@ impl<'i> Convert>, &'i WgpuExecutor> for Table { footprint, ..Default::default() }; - log::debug!("rasterizing vector data with footprint {footprint:?}"); let vector = &self; - log::debug!("{vector:?}"); + let bounding_box = vector.bounding_box(DAffine2::IDENTITY, true); + let RenderBoundingBox::Rectangle(rect) = bounding_box else { + panic!("did not find valid bounding box") + }; // Create a Vello scene for this vector let mut scene = vello::Scene::new(); let mut context = crate::RenderContext::default(); - // Render the vector to the Vello scene with the row's transform - vector.render_to_vello(&mut scene, footprint.transform, &mut context, &render_params); + let viewport_bounds = footprint.viewport_bounds_in_local_space(); + log::debug!("viewport bounds: {viewport_bounds:?}"); + log::debug!("vector bounds: {bounding_box:?}"); + + let image_bounds = core_types::math::bbox::AxisAlignedBbox { start: rect[0], end: rect[1] }; + let intersection = viewport_bounds.intersect(&image_bounds); + + log::debug!("intersection: {intersection:?}"); + let size = intersection.size(); + + // let offset = (intersection.start - image_bounds.start).max(DVec2::ZERO); + let offset = (intersection.start - image_bounds.start).max(DVec2::ZERO) + image_bounds.start; + log::debug!("size: {size} offset: {offset}"); + + // If the image would not be visible, return an empty image + if size.x <= 0. || size.y <= 0. { + return Table::new(); + } + + let scale = footprint.scale(); + log::debug!("scale: {scale:?}"); + let width = (size.x * scale.x) as u32; + let height = (size.y * scale.y) as u32; // Render the scene to a GPU texture - let resolution = footprint.resolution; + let resolution = UVec2::new(width, height); + log::debug!("resolution: {resolution:?}"); let background = core_types::Color::TRANSPARENT; + let render_transform = DAffine2::from_scale(scale) * DAffine2::from_translation(-offset); + log::debug!("render transform: {render_transform:?}"); + // Render the vector to the Vello scene with the row's transform + vector.render_to_vello(&mut scene, render_transform, &mut context, &render_params); + // Use async rendering to get the texture let texture = executor .render_vello_scene_to_texture(&scene, resolution, &context, background) @@ -67,7 +98,8 @@ impl<'i> Convert>, &'i WgpuExecutor> for Table { queue.submit([command_buffer]); let mut table = Table::new_from_element(Raster::new_gpu(new_texture)); - *(table.get_mut(0).as_mut().unwrap().transform) = footprint.transform.inverse() * DAffine2::from_scale((texture.width() as f64, texture.height() as f64).into()); + *(table.get_mut(0).as_mut().unwrap().transform) = DAffine2::from_translation(offset) * DAffine2::from_scale(size); + texture.destroy(); table } }