Skip to content

Commit fbb79fd

Browse files
adamgerhantKeavon
authored andcommitted
Improve recursion
1 parent 1a406b2 commit fbb79fd

File tree

6 files changed

+57
-150
lines changed

6 files changed

+57
-150
lines changed

editor/src/messages/portfolio/document/document_message_handler.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,12 +1063,10 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
10631063
let layer_click_targets = click_targets
10641064
.into_iter()
10651065
.filter_map(|(node_id, click_targets)| {
1066-
if self.network_interface.is_layer(&node_id, &[]) {
1066+
self.network_interface.is_layer(&node_id, &[]).then(|| {
10671067
let layer = LayerNodeIdentifier::new(node_id, &self.network_interface, &[]);
1068-
Some((layer, click_targets))
1069-
} else {
1070-
None
1071-
}
1068+
(layer, click_targets)
1069+
})
10721070
})
10731071
.collect();
10741072
self.network_interface.update_click_targets(layer_click_targets);

editor/src/messages/tool/tool_messages/select_tool.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,6 @@ impl Fsm for SelectToolFsmState {
445445
.unwrap()
446446
.selected_visible_and_unlocked_layers(&document.network_interface)
447447
.filter(|layer| !document.network_interface.is_artboard(&layer.to_node(), &[]))
448-
// .flat_map(|layer| layer.descendants(document.metadata()).chain(std::iter::once(layer)))
449-
// .collect::<HashSet<_>>()
450-
// .iter()
451448
.filter_map(|layer| {
452449
document
453450
.metadata()

editor/src/node_graph_executor.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions:
44
use crate::messages::prelude::*;
55

66
use graph_craft::concrete;
7-
use graph_craft::document::value::{RenderMetadata, RenderOutput, TaggedValue};
7+
use graph_craft::document::value::{RenderOutput, TaggedValue};
88
use graph_craft::document::{generate_uuid, DocumentNodeImplementation, NodeId, NodeNetwork};
99
use graph_craft::graphene_compiler::Compiler;
1010
use graph_craft::proto::GraphErrors;
@@ -16,7 +16,7 @@ use graphene_core::renderer::{RenderSvgSegmentList, SvgSegment};
1616
use graphene_core::text::FontCache;
1717
use graphene_core::transform::Footprint;
1818
use graphene_core::vector::style::ViewMode;
19-
use graphene_std::renderer::format_transform_matrix;
19+
use graphene_std::renderer::{format_transform_matrix, RenderMetadata};
2020
use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
2121
use interpreted_executor::dynamic_executor::{DynamicExecutor, IntrospectError, ResolvedDocumentNodeTypesDelta};
2222

@@ -297,10 +297,6 @@ impl NodeRuntime {
297297
responses: &mut VecDeque<FrontendMessage>,
298298
update_thumbnails: bool,
299299
) {
300-
// let click_targets = click_targets.entry(parent_network_node_id).or_default();
301-
// click_targets.clear();
302-
// graphic_element.add_click_targets(click_targets);
303-
304300
// RENDER THUMBNAIL
305301

306302
if !update_thumbnails {
@@ -554,8 +550,6 @@ impl NodeGraphExecutor {
554550
};
555551

556552
responses.extend(existing_responses.into_iter().map(Into::into));
557-
// document.network_interface.update_click_targets(new_click_targets);
558-
// document.network_interface.update_vector_modify(new_vector_modify);
559553

560554
let execution_context = self.futures.remove(&execution_id).ok_or_else(|| "Invalid generation ID".to_string())?;
561555
if let Some(export_config) = execution_context.export_config {
@@ -629,7 +623,6 @@ impl NodeGraphExecutor {
629623
match render_output.data {
630624
graphene_std::wasm_application_io::RenderOutputType::Svg(svg) => {
631625
// Send to frontend
632-
//log::debug!("Render output footprints: {footprints:?}");
633626
responses.add(FrontendMessage::UpdateDocumentArtwork { svg });
634627
}
635628
graphene_std::wasm_application_io::RenderOutputType::CanvasFrame(frame) => {
@@ -645,11 +638,11 @@ impl NodeGraphExecutor {
645638
return Err(format!("Invalid node graph output type: {:#?}", render_output.data));
646639
}
647640
}
648-
responses.add(DocumentMessage::RenderScrollbars);
649-
responses.add(DocumentMessage::RenderRulers);
650641
responses.add(DocumentMessage::UpdateUpstreamTransforms { upstream_transforms: footprints });
651642
responses.add(DocumentMessage::UpdateClickTargets { click_targets });
652643
responses.add(DocumentMessage::UpdateVectorModify { vector_modify: vector_data });
644+
responses.add(DocumentMessage::RenderScrollbars);
645+
responses.add(DocumentMessage::RenderRulers);
653646
responses.add(OverlaysMessage::Draw);
654647
}
655648
TaggedValue::Bool(render_object) => Self::debug_render(render_object, transform, responses),

node-graph/gcore/src/graphic_element/renderer.rs

Lines changed: 43 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod quad;
22
mod rect;
3+
use dyn_any::DynAny;
34
pub use quad::Quad;
45
pub use rect::Rect;
56

@@ -269,15 +270,24 @@ pub fn to_transform(transform: DAffine2) -> usvg::Transform {
269270
usvg::Transform::from_row(cols[0] as f32, cols[1] as f32, cols[2] as f32, cols[3] as f32, cols[4] as f32, cols[5] as f32)
270271
}
271272

273+
use dyn_any::StaticType;
274+
#[derive(Debug, Clone, PartialEq, DynAny)]
275+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
276+
pub struct RenderMetadata {
277+
pub footprints: HashMap<NodeId, (Footprint, DAffine2)>,
278+
pub click_targets: HashMap<NodeId, Vec<ClickTarget>>,
279+
pub vector_data: HashMap<NodeId, VectorData>,
280+
}
281+
272282
pub trait GraphicElementRendered {
273283
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams);
274284
fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]>;
275-
fn add_click_targets(&self, _click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, _element_id: Option<NodeId>) {}
285+
// The upstream click targets for each layer are collected during the render so that they do not have to be calculated for each click detection
276286
fn add_upstream_click_targets(&self, _click_targets: &mut Vec<ClickTarget>) {}
277287
// TODO: Store all click targets in a vec which contains the AABB, click target, and path
278288
// fn add_click_targets(&self, click_targets: &mut Vec<([DVec2; 2], ClickTarget, Vec<NodeId>)>, current_path: Option<NodeId>) {}
279-
fn add_vector_modify(&self, _vector_modify: &mut HashMap<NodeId, VectorData>, _element_id: Option<NodeId>) {}
280-
fn add_footprints(&self, _footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, _footprint: Footprint, _element_id: Option<NodeId>) {}
289+
// Recursively iterate over data in the render (including groups upstream from vector data in the case of a boolean operation) to collect the footprints, click targets, and vector modify
290+
fn collect_metadata(&self, _metadata: &mut RenderMetadata, _footprint: Footprint, _element_id: Option<NodeId>) {}
281291
#[cfg(feature = "vello")]
282292
fn to_vello_scene(&self, transform: DAffine2, context: &mut RenderContext) -> Scene {
283293
let mut scene = vello::Scene::new();
@@ -322,18 +332,17 @@ impl GraphicElementRendered for GraphicGroup {
322332
self.iter().filter_map(|(element, _)| element.bounding_box(transform * self.transform)).reduce(Quad::combine_bounds)
323333
}
324334

325-
fn add_click_targets(&self, click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, element_id: Option<NodeId>) {
335+
fn collect_metadata(&self, metadata: &mut RenderMetadata, mut footprint: Footprint, element_id: Option<NodeId>) {
336+
footprint.transform *= self.transform;
326337
for (element, element_id) in self.elements.iter() {
327338
if let Some(element_id) = element_id {
328-
let mut new_click_targets = HashMap::new();
329-
element.add_click_targets(&mut new_click_targets, Some(*element_id));
330-
click_targets.extend(new_click_targets);
339+
element.collect_metadata(metadata, footprint, Some(*element_id));
331340
}
332341
}
333342
if let Some(graphic_group_id) = element_id {
334343
let mut all_upstream_click_targets = Vec::new();
335344
self.add_upstream_click_targets(&mut all_upstream_click_targets);
336-
click_targets.insert(graphic_group_id, all_upstream_click_targets);
345+
metadata.click_targets.insert(graphic_group_id, all_upstream_click_targets);
337346
}
338347
}
339348

@@ -348,23 +357,6 @@ impl GraphicElementRendered for GraphicGroup {
348357
}
349358
}
350359

351-
fn add_vector_modify(&self, vector_modify: &mut HashMap<NodeId, VectorData>, _element_id: Option<NodeId>) {
352-
for (element, element_id) in self.elements.iter() {
353-
element.add_vector_modify(vector_modify, *element_id);
354-
}
355-
}
356-
357-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, mut footprint: Footprint, _: Option<NodeId>) {
358-
footprint.transform *= self.transform;
359-
for (element, optional_node_id) in self.elements.iter() {
360-
if let Some(element_id) = optional_node_id {
361-
let mut new_footprints = HashMap::new();
362-
element.add_footprints(&mut new_footprints, footprint, Some(*element_id));
363-
footprints.extend(new_footprints);
364-
}
365-
}
366-
}
367-
368360
#[cfg(feature = "vello")]
369361
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
370362
let child_transform = transform * self.transform;
@@ -433,7 +425,7 @@ impl GraphicElementRendered for VectorData {
433425
self.bounding_box_with_transform(transform * self.transform).map(|[a, b]| [a - offset, b + offset])
434426
}
435427

436-
fn add_click_targets(&self, click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, element_id: Option<NodeId>) {
428+
fn collect_metadata(&self, metadata: &mut RenderMetadata, mut footprint: Footprint, element_id: Option<NodeId>) {
437429
if let Some(element_id) = element_id {
438430
let stroke_width = self.style.stroke().as_ref().map_or(0., Stroke::weight);
439431
let filled = self.style.fill() != &Fill::None;
@@ -443,10 +435,14 @@ impl GraphicElementRendered for VectorData {
443435
}
444436
subpath
445437
};
446-
click_targets.insert(element_id, self.stroke_bezier_paths().map(fill).map(|subpath| ClickTarget::new(subpath, stroke_width)).collect());
438+
metadata
439+
.click_targets
440+
.insert(element_id, self.stroke_bezier_paths().map(fill).map(|subpath| ClickTarget::new(subpath, stroke_width)).collect());
441+
metadata.vector_data.insert(element_id, self.clone());
447442
}
448443
if let Some(upstream_graphic_group) = &self.upstream_graphic_group {
449-
upstream_graphic_group.add_click_targets(click_targets, None);
444+
footprint.transform *= self.transform;
445+
upstream_graphic_group.collect_metadata(metadata, footprint, None);
450446
}
451447
}
452448

@@ -462,22 +458,6 @@ impl GraphicElementRendered for VectorData {
462458
click_targets.extend(self.stroke_bezier_paths().map(fill).map(|subpath| ClickTarget::new(subpath, stroke_width)));
463459
}
464460

465-
fn add_vector_modify(&self, vector_modify: &mut HashMap<NodeId, VectorData>, element_id: Option<NodeId>) {
466-
if let Some(element_id) = element_id {
467-
vector_modify.insert(element_id, self.clone());
468-
}
469-
if let Some(upstream_graphic_group) = &self.upstream_graphic_group {
470-
upstream_graphic_group.add_vector_modify(vector_modify, None);
471-
}
472-
}
473-
474-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, mut footprint: Footprint, _element_id: Option<NodeId>) {
475-
if let Some(upstream_graphic_group) = &self.upstream_graphic_group {
476-
footprint.transform *= self.transform;
477-
upstream_graphic_group.add_footprints(footprints, footprint, None);
478-
}
479-
}
480-
481461
#[cfg(feature = "vello")]
482462
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, _: &mut RenderContext) {
483463
use crate::vector::style::GradientType;
@@ -651,12 +631,13 @@ impl GraphicElementRendered for Artboard {
651631
}
652632
}
653633

654-
fn add_click_targets(&self, click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, element_id: Option<NodeId>) {
634+
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
655635
if let Some(element_id) = element_id {
656636
let subpath = Subpath::new_rect(DVec2::ZERO, self.dimensions.as_dvec2());
657-
click_targets.insert(element_id, vec![ClickTarget::new(subpath, 0.)]);
637+
metadata.click_targets.insert(element_id, vec![ClickTarget::new(subpath, 0.)]);
638+
metadata.footprints.insert(element_id, (footprint, DAffine2::from_translation(self.location.as_dvec2())));
658639
}
659-
self.graphic_group.add_click_targets(click_targets, None);
640+
self.graphic_group.collect_metadata(metadata, footprint, None);
660641
}
661642

662643
fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
@@ -665,17 +646,6 @@ impl GraphicElementRendered for Artboard {
665646
click_targets.push(ClickTarget::new(subpath, 0.));
666647
}
667648

668-
fn add_vector_modify(&self, vector_modify: &mut HashMap<NodeId, VectorData>, _element_id: Option<NodeId>) {
669-
self.graphic_group.add_vector_modify(vector_modify, None);
670-
}
671-
672-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {
673-
if let Some(element_id) = element_id {
674-
footprints.insert(element_id, (footprint, DAffine2::from_translation(self.location.as_dvec2())));
675-
}
676-
self.graphic_group.add_footprints(footprints, footprint, None);
677-
}
678-
679649
#[cfg(feature = "vello")]
680650
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
681651
use vello::peniko;
@@ -713,9 +683,9 @@ impl GraphicElementRendered for crate::ArtboardGroup {
713683
self.artboards.iter().filter_map(|(element, _)| element.bounding_box(transform)).reduce(Quad::combine_bounds)
714684
}
715685

716-
fn add_click_targets(&self, click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, _element_id: Option<NodeId>) {
686+
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, _element_id: Option<NodeId>) {
717687
for (artboard, element_id) in &self.artboards {
718-
artboard.add_click_targets(click_targets, *element_id);
688+
artboard.collect_metadata(metadata, footprint, *element_id);
719689
}
720690
}
721691

@@ -725,18 +695,6 @@ impl GraphicElementRendered for crate::ArtboardGroup {
725695
}
726696
}
727697

728-
fn add_vector_modify(&self, vector_modify: &mut HashMap<NodeId, VectorData>, _element_id: Option<NodeId>) {
729-
for (artboard, _) in &self.artboards {
730-
artboard.add_vector_modify(vector_modify, None);
731-
}
732-
}
733-
734-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, _element_id: Option<NodeId>) {
735-
for (artboard, element_id) in &self.artboards {
736-
artboard.add_footprints(footprints, footprint, *element_id);
737-
}
738-
}
739-
740698
#[cfg(feature = "vello")]
741699
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
742700
for (artboard, _) in &self.artboards {
@@ -790,10 +748,11 @@ impl GraphicElementRendered for ImageFrame<Color> {
790748
(transform.matrix2 != glam::DMat2::ZERO).then(|| (transform * Quad::from_box([DVec2::ZERO, DVec2::ONE])).bounding_box())
791749
}
792750

793-
fn add_click_targets(&self, click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, element_id: Option<NodeId>) {
751+
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
794752
if let Some(element_id) = element_id {
795753
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
796-
click_targets.insert(element_id, vec![ClickTarget::new(subpath, 0.)]);
754+
metadata.click_targets.insert(element_id, vec![ClickTarget::new(subpath, 0.)]);
755+
metadata.footprints.insert(element_id, (footprint, self.transform));
797756
}
798757
}
799758

@@ -802,12 +761,6 @@ impl GraphicElementRendered for ImageFrame<Color> {
802761
click_targets.push(ClickTarget::new(subpath, 0.));
803762
}
804763

805-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {
806-
if let Some(element_id) = element_id {
807-
footprints.insert(element_id, (footprint, self.transform));
808-
}
809-
}
810-
811764
#[cfg(feature = "vello")]
812765
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, _: &mut RenderContext) {
813766
use vello::peniko;
@@ -873,10 +826,11 @@ impl GraphicElementRendered for Raster {
873826
(transform.matrix2 != glam::DMat2::ZERO).then(|| (transform * Quad::from_box([DVec2::ZERO, DVec2::ONE])).bounding_box())
874827
}
875828

876-
fn add_click_targets(&self, click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, element_id: Option<NodeId>) {
829+
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
877830
if let Some(element_id) = element_id {
878831
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
879-
click_targets.insert(element_id, vec![ClickTarget::new(subpath, 0.)]);
832+
metadata.click_targets.insert(element_id, vec![ClickTarget::new(subpath, 0.)]);
833+
metadata.footprints.insert(element_id, (footprint, self.transform()));
880834
}
881835
}
882836

@@ -885,12 +839,6 @@ impl GraphicElementRendered for Raster {
885839
click_targets.push(ClickTarget::new(subpath, 0.));
886840
}
887841

888-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {
889-
if let Some(element_id) = element_id {
890-
footprints.insert(element_id, (footprint, self.transform()));
891-
}
892-
}
893-
894842
#[cfg(feature = "vello")]
895843
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
896844
use vello::peniko;
@@ -948,11 +896,14 @@ impl GraphicElementRendered for GraphicElement {
948896
}
949897
}
950898

951-
fn add_click_targets(&self, click_targets: &mut HashMap<NodeId, Vec<ClickTarget>>, element_id: Option<NodeId>) {
899+
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
900+
if let Some(element_id) = element_id {
901+
metadata.footprints.insert(element_id, (footprint, self.transform()));
902+
}
952903
match self {
953-
GraphicElement::VectorData(vector_data) => vector_data.add_click_targets(click_targets, element_id),
954-
GraphicElement::Raster(raster) => raster.add_click_targets(click_targets, element_id),
955-
GraphicElement::GraphicGroup(graphic_group) => graphic_group.add_click_targets(click_targets, element_id),
904+
GraphicElement::VectorData(vector_data) => vector_data.collect_metadata(metadata, footprint, element_id),
905+
GraphicElement::Raster(raster) => raster.collect_metadata(metadata, footprint, element_id),
906+
GraphicElement::GraphicGroup(graphic_group) => graphic_group.collect_metadata(metadata, footprint, element_id),
956907
}
957908
}
958909

@@ -964,23 +915,6 @@ impl GraphicElementRendered for GraphicElement {
964915
}
965916
}
966917

967-
fn add_vector_modify(&self, vector_modify: &mut HashMap<NodeId, VectorData>, element_id: Option<NodeId>) {
968-
if let GraphicElement::VectorData(vector_data) = self {
969-
vector_data.add_vector_modify(vector_modify, element_id);
970-
}
971-
}
972-
973-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {
974-
if let Some(element_id) = element_id {
975-
footprints.insert(element_id, (footprint, self.transform()));
976-
}
977-
match self {
978-
GraphicElement::VectorData(vector_data) => vector_data.add_footprints(footprints, footprint, None),
979-
GraphicElement::Raster(raster) => raster.add_footprints(footprints, footprint, None),
980-
GraphicElement::GraphicGroup(graphic_group) => graphic_group.add_footprints(footprints, footprint, None),
981-
}
982-
}
983-
984918
#[cfg(feature = "vello")]
985919
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
986920
match self {

0 commit comments

Comments
 (0)