Skip to content

Commit 34b177a

Browse files
committed
Fix click target propagation with the Rasterize node
1 parent 5dc2bc9 commit 34b177a

3 files changed

Lines changed: 38 additions & 5 deletions

File tree

editor/src/messages/portfolio/document/data_panel/data_panel_message_handler.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ impl<T: TableRowLayout> TableRowLayout for Table<T> {
272272
() if let Some(&value) = ty.downcast_ref::<DVec2>() => format_dvec2(value),
273273
() if let Some(&value) = ty.downcast_ref::<AlphaBlending>() => format_alpha_blending(value),
274274
() if let Some(&value) = ty.downcast_ref::<Option<NodeId>>() => value.map_or_else(|| "-".to_string(), |id| id.to_string()),
275+
() if let Some(value) = ty.downcast_ref::<Option<Table<Graphic>>>() => value.as_ref().map_or_else(|| "-".to_string(), |table| format!("{} Objects", table.len())),
275276
_ => return None,
276277
})
277278
})

node-graph/libraries/rendering/src/renderer.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,18 @@ impl Render for Table<Raster<CPU>> {
15881588
metadata.upstream_footprints.insert(element_id, footprint);
15891589
// TODO: Find a way to handle more than one row of the raster table
15901590
if !self.is_empty() {
1591-
metadata.local_transforms.insert(element_id, self.attribute_cloned_or_default("transform", 0));
1591+
let transform: DAffine2 = self.attribute_cloned_or_default("transform", 0);
1592+
metadata.local_transforms.insert(element_id, transform);
1593+
1594+
// If this raster carries a snapshot of upstream graphic content (e.g. it was produced by Rasterize,
1595+
// which destructively merges its inputs into pixels), recurse into that snapshot so the editor can
1596+
// surface the original child layers' click targets (the same mechanism Boolean Operation uses).
1597+
// The snapshot was captured before Rasterize shifted its input transforms to align with the rasterization
1598+
// area, so the children are already in the coordinate space matching `footprint` here — we must NOT
1599+
// multiply in `transform` (which is the rasterization area, not a layer-stack transform).
1600+
if let Some(upstream_nested_layers) = self.attribute_cloned_or_default::<Option<Table<Graphic>>>("upstream_data", 0) {
1601+
upstream_nested_layers.collect_metadata(metadata, footprint, None);
1602+
}
15921603
}
15931604
}
15941605

@@ -1666,7 +1677,18 @@ impl Render for Table<Raster<GPU>> {
16661677
metadata.upstream_footprints.insert(element_id, footprint);
16671678
// TODO: Find a way to handle more than one row of the raster table
16681679
if !self.is_empty() {
1669-
metadata.local_transforms.insert(element_id, self.attribute_cloned_or_default("transform", 0));
1680+
let transform: DAffine2 = self.attribute_cloned_or_default("transform", 0);
1681+
metadata.local_transforms.insert(element_id, transform);
1682+
1683+
// If this raster carries a snapshot of upstream graphic content (e.g. it was produced by Rasterize,
1684+
// which destructively merges its inputs into pixels), recurse into that snapshot so the editor can
1685+
// surface the original child layers' click targets (the same mechanism Boolean Operation uses).
1686+
// The snapshot was captured before Rasterize shifted its input transforms to align with the rasterization
1687+
// area, so the children are already in the coordinate space matching `footprint` here — we must NOT
1688+
// multiply in `transform` (which is the rasterization area, not a layer-stack transform).
1689+
if let Some(upstream_nested_layers) = self.attribute_cloned_or_default::<Option<Table<Graphic>>>("upstream_data", 0) {
1690+
upstream_nested_layers.collect_metadata(metadata, footprint, None);
1691+
}
16701692
}
16711693
}
16721694

node-graph/nodes/gstd/src/platform_application_io.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub use graphene_canvas_utils as canvas_utils;
1818
#[cfg(target_family = "wasm")]
1919
use graphic_types::Graphic;
2020
#[cfg(target_family = "wasm")]
21+
use graphic_types::IntoGraphicTable;
22+
#[cfg(target_family = "wasm")]
2123
use graphic_types::Vector;
2224
use graphic_types::raster_types::Image;
2325
use graphic_types::raster_types::{CPU, Raster};
@@ -170,7 +172,7 @@ async fn create_canvas(_: impl Ctx) -> CanvasHandle {
170172
/// Renders a view of the input graphic within an area defined by the *Footprint*.
171173
#[cfg(target_family = "wasm")]
172174
#[node_macro::node(category(""))]
173-
async fn rasterize<T: WasmNotSend + 'n>(
175+
async fn rasterize<T: WasmNotSend + Clone + 'n>(
174176
_: impl Ctx,
175177
#[implementations(
176178
Table<Vector>,
@@ -184,7 +186,7 @@ async fn rasterize<T: WasmNotSend + 'n>(
184186
mut canvas: CanvasHandle,
185187
) -> Table<Raster<CPU>>
186188
where
187-
Table<T>: Render,
189+
Table<T>: Render + Clone + graphic_types::IntoGraphicTable,
188190
{
189191
use core_types::table::TableRow;
190192
use glam::{DAffine2, DVec2};
@@ -194,6 +196,10 @@ where
194196
return Table::new();
195197
}
196198

199+
// Snapshot the input as a Table<Graphic> so the renderer can recurse into the original child layers
200+
// when collecting metadata, exposing their click targets to editor tools (same mechanism as Boolean Operation).
201+
let upstream_graphic_table = data.clone().into_graphic_table();
202+
197203
let mut render = SvgRender::new();
198204
let aabb = Bbox::from_transform(footprint.transform).to_axis_aligned_bbox();
199205
let size = aabb.size();
@@ -229,5 +235,9 @@ where
229235
let rasterized = context.get_image_data(0., 0., resolution.x as f64, resolution.y as f64).unwrap();
230236

231237
let image = Image::from_image_data(&rasterized.data().0, resolution.x as u32, resolution.y as u32);
232-
Table::new_from_row(TableRow::new_from_element(Raster::new_cpu(image)).with_attribute("transform", footprint.transform))
238+
Table::new_from_row(
239+
TableRow::new_from_element(Raster::new_cpu(image))
240+
.with_attribute("transform", footprint.transform)
241+
.with_attribute("upstream_data", Some(upstream_graphic_table)),
242+
)
233243
}

0 commit comments

Comments
 (0)