Skip to content

Commit 355a8ad

Browse files
adamgerhantKeavon
authored andcommitted
Render Output footprints
1 parent e30eef7 commit 355a8ad

File tree

12 files changed

+154
-56
lines changed

12 files changed

+154
-56
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use graphene_core::vector::style::ViewMode;
1313
use graphene_core::Color;
1414

1515
use glam::DAffine2;
16+
use graphene_std::transform::Footprint;
1617

1718
#[impl_message(Message, PortfolioMessage, Document)]
1819
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
@@ -155,6 +156,9 @@ pub enum DocumentMessage {
155156
ToggleGridVisibility,
156157
ToggleOverlaysVisibility,
157158
ToggleSnapping,
159+
UpdateUpstreamTransforms {
160+
upstream_transforms: HashMap<NodeId, (Footprint, DAffine2)>,
161+
},
158162
Undo,
159163
UngroupSelectedLayers,
160164
UngroupLayer {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,9 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
10391039
self.snapping_state.snapping_enabled = !self.snapping_state.snapping_enabled;
10401040
responses.add(PortfolioMessage::UpdateDocumentWidgets);
10411041
}
1042+
DocumentMessage::UpdateUpstreamTransforms { upstream_transforms } => {
1043+
self.network_interface.document_metadata_mut().update_transforms(upstream_transforms);
1044+
}
10421045
DocumentMessage::Undo => {
10431046
if self.network_interface.transaction_status() != TransactionStatus::Finished {
10441047
return;

editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,9 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
359359
inputs: vec![
360360
NodeInput::network(graphene_core::Type::Fn(Box::new(concrete!(Footprint)), Box::new(concrete!(ArtboardGroup))), 0),
361361
NodeInput::node(NodeId(1), 0),
362+
NodeInput::value(TaggedValue::OptionalNodeId(None), false),
362363
],
363-
implementation: DocumentNodeImplementation::proto("graphene_core::AddArtboardNode<_, _>"),
364+
implementation: DocumentNodeImplementation::proto("graphene_core::AddArtboardNode<_, _, _>"),
364365
..Default::default()
365366
},
366367
]

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,6 @@ impl Fsm for SelectToolFsmState {
528528

529529
edges
530530
});
531-
532531
let rotating_bounds = tool_data
533532
.bounding_box_manager
534533
.as_ref()
@@ -634,7 +633,6 @@ impl Fsm for SelectToolFsmState {
634633
tool_data.layers_dragging = selected;
635634

636635
tool_data.get_snap_candidates(document, input);
637-
638636
SelectToolFsmState::Dragging
639637
}
640638
// Dragging a selection box
@@ -656,7 +654,6 @@ impl Fsm for SelectToolFsmState {
656654
_ => drag_deepest_manipulation(responses, selected, tool_data, document),
657655
}
658656
tool_data.get_snap_candidates(document, input);
659-
660657
responses.add(DocumentMessage::StartTransaction);
661658
SelectToolFsmState::Dragging
662659
} else {
@@ -1200,9 +1197,12 @@ fn drag_shallowest_manipulation(responses: &mut VecDeque<Message>, selected: Vec
12001197
}
12011198

12021199
fn drag_deepest_manipulation(responses: &mut VecDeque<Message>, selected: Vec<LayerNodeIdentifier>, tool_data: &mut SelectToolData, document: &DocumentMessageHandler) {
1203-
tool_data.layers_dragging.append(&mut vec![document
1204-
.find_deepest(&selected)
1205-
.unwrap_or(LayerNodeIdentifier::ROOT_PARENT.children(document.metadata()).next().expect("Child should exist when dragging deepest"))]);
1200+
tool_data.layers_dragging.append(&mut vec![document.find_deepest(&selected).unwrap_or(
1201+
LayerNodeIdentifier::ROOT_PARENT
1202+
.children(document.metadata())
1203+
.next()
1204+
.expect("ROOT_PARENT should have a layer child when clicking"),
1205+
)]);
12061206
responses.add(NodeGraphMessage::SelectedNodesSet {
12071207
nodes: tool_data
12081208
.layers_dragging

editor/src/node_graph_executor.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ impl NodeGraphExecutor {
536536
}
537537

538538
fn export(&self, node_graph_output: TaggedValue, export_config: ExportConfig, responses: &mut VecDeque<Message>) -> Result<(), String> {
539-
let TaggedValue::RenderOutput(graphene_std::wasm_application_io::RenderOutput::Svg(svg)) = node_graph_output else {
539+
let TaggedValue::RenderOutput(graphene_std::wasm_application_io::RenderOutput::Svg((svg, _))) = node_graph_output else {
540540
return Err("Incorrect render type for exportign (expected RenderOutput::Svg)".to_string());
541541
};
542542

@@ -592,7 +592,7 @@ impl NodeGraphExecutor {
592592
};
593593

594594
responses.extend(existing_responses.into_iter().map(Into::into));
595-
document.network_interface.document_metadata_mut().update_transforms(new_upstream_transforms);
595+
//document.network_interface.document_metadata_mut().update_transforms(new_upstream_transforms);
596596
document.network_interface.document_metadata_mut().update_from_monitor(new_click_targets, new_vector_modify);
597597

598598
let execution_context = self.futures.remove(&execution_id).ok_or_else(|| "Invalid generation ID".to_string())?;
@@ -657,12 +657,16 @@ impl NodeGraphExecutor {
657657
TaggedValue::SurfaceFrame(SurfaceFrame { .. }) => {
658658
// TODO: Reimplement this now that document-legacy is gone
659659
}
660-
TaggedValue::RenderOutput(graphene_std::wasm_application_io::RenderOutput::Svg(svg)) => {
660+
TaggedValue::RenderOutput(graphene_std::wasm_application_io::RenderOutput::Svg((svg, footprints))) => {
661661
// Send to frontend
662+
log::debug!("Render output footprints: {footprints:?}");
662663
responses.add(FrontendMessage::UpdateDocumentArtwork { svg });
663664
responses.add(DocumentMessage::RenderScrollbars);
664665
responses.add(DocumentMessage::RenderRulers);
666+
responses.add(DocumentMessage::UpdateUpstreamTransforms { upstream_transforms: footprints });
667+
responses.add(OverlaysMessage::Draw);
665668
}
669+
666670
TaggedValue::RenderOutput(graphene_std::wasm_application_io::RenderOutput::CanvasFrame(frame)) => {
667671
let matrix = format_transform_matrix(frame.transform);
668672
let transform = if matrix.is_empty() { String::new() } else { format!(" transform=\"{}\"", matrix) };

node-graph/gcore/src/graphic_element.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::application_io::TextureFrame;
22
use crate::raster::{BlendMode, ImageFrame};
33
use crate::transform::{Footprint, Transform, TransformMut};
4+
use crate::uuid::NodeId;
45
use crate::vector::VectorData;
56
use crate::{Color, Node};
67

@@ -43,7 +44,7 @@ impl AlphaBlending {
4344
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4445
pub struct GraphicGroup {
4546
// TODO: Separate into multiple Vecs in a spread sheet format.
46-
elements: Vec<(GraphicElement, Option<(u64, Footprint)>)>,
47+
elements: Vec<(GraphicElement, Option<NodeId>)>,
4748
// TODO: Convert to Vec<DAffine2>
4849
pub transform: DAffine2,
4950
// TODO: Convert to Vec<AlphaBlending>
@@ -219,7 +220,7 @@ impl Artboard {
219220
#[derive(Clone, Default, Debug, Hash, PartialEq, DynAny)]
220221
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
221222
pub struct ArtboardGroup {
222-
pub artboards: Vec<Artboard>,
223+
pub artboards: Vec<(Artboard, Option<NodeId>)>,
223224
}
224225

225226
impl ArtboardGroup {
@@ -229,8 +230,8 @@ impl ArtboardGroup {
229230
Default::default()
230231
}
231232

232-
fn add_artboard(&mut self, artboard: Artboard) {
233-
self.artboards.push(artboard);
233+
fn add_artboard(&mut self, artboard: Artboard, node_id: Option<NodeId>) {
234+
self.artboards.push((artboard, node_id));
234235
}
235236
}
236237

@@ -245,15 +246,11 @@ async fn construct_layer<Data: Into<GraphicElement> + Send>(
245246
footprint: crate::transform::Footprint,
246247
mut stack: impl Node<crate::transform::Footprint, Output = GraphicGroup>,
247248
graphic_element: impl Node<crate::transform::Footprint, Output = Data>,
248-
node_id: Option<u64>,
249+
node_id: Option<NodeId>,
249250
) -> GraphicGroup {
250251
let graphic_element = self.graphic_element.eval(footprint).await;
251252
let mut stack = self.stack.eval(footprint).await;
252-
if let Some(node_id) = node_id {
253-
stack.push((graphic_element.into(), Some((node_id, footprint))));
254-
} else {
255-
stack.push((graphic_element.into(), None));
256-
}
253+
stack.push((graphic_element.into(), node_id));
257254
stack
258255
}
259256

@@ -302,17 +299,23 @@ async fn construct_artboard(
302299
clip,
303300
}
304301
}
305-
pub struct AddArtboardNode<ArtboardGroup, Artboard> {
302+
pub struct AddArtboardNode<ArtboardGroup, Artboard, OptionalNodeId> {
306303
artboards: ArtboardGroup,
307304
artboard: Artboard,
305+
node_id: OptionalNodeId,
308306
}
309307

310308
#[node_fn(AddArtboardNode)]
311-
async fn add_artboard<Data: Into<Artboard> + Send>(footprint: Footprint, artboards: impl Node<Footprint, Output = ArtboardGroup>, artboard: impl Node<Footprint, Output = Data>) -> ArtboardGroup {
309+
async fn add_artboard<Data: Into<Artboard> + Send>(
310+
footprint: Footprint,
311+
artboards: impl Node<Footprint, Output = ArtboardGroup>,
312+
artboard: impl Node<Footprint, Output = Data>,
313+
node_id: Option<NodeId>,
314+
) -> ArtboardGroup {
312315
let artboard = self.artboard.eval(footprint).await;
313316
let mut artboards = self.artboards.eval(footprint).await;
314317

315-
artboards.add_artboard(artboard.into());
318+
artboards.add_artboard(artboard.into(), node_id);
316319

317320
artboards
318321
}
@@ -339,7 +342,7 @@ impl From<GraphicGroup> for GraphicElement {
339342
}
340343

341344
impl Deref for GraphicGroup {
342-
type Target = Vec<(GraphicElement, Option<(u64, Footprint)>)>;
345+
type Target = Vec<(GraphicElement, Option<NodeId>)>;
343346
fn deref(&self) -> &Self::Target {
344347
&self.elements
345348
}

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

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ pub use quad::Quad;
44
pub use rect::Rect;
55

66
use crate::raster::{BlendMode, Image, ImageFrame};
7-
use crate::transform::Transform;
8-
use crate::uuid::generate_uuid;
7+
use crate::transform::{self, Footprint, Transform};
8+
use crate::uuid::{generate_uuid, NodeId};
99
use crate::vector::style::{Fill, Stroke, ViewMode};
1010
use crate::vector::PointId;
1111
use crate::Raster;
@@ -16,6 +16,7 @@ use bezier_rs::Subpath;
1616
use base64::Engine;
1717
use glam::{DAffine2, DVec2};
1818
use num_traits::Zero;
19+
use std::collections::HashMap;
1920
use std::fmt::Write;
2021
#[cfg(feature = "vello")]
2122
use vello::*;
@@ -272,7 +273,7 @@ pub trait GraphicElementRendered {
272273
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams);
273274
fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]>;
274275
fn add_click_targets(&self, click_targets: &mut Vec<ClickTarget>);
275-
fn add_footprints(&self, footprints: &mut HashMap<NodeId, Footprint>)
276+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>);
276277
#[cfg(feature = "vello")]
277278
fn to_vello_scene(&self, transform: DAffine2, context: &mut RenderContext) -> Scene {
278279
let mut scene = vello::Scene::new();
@@ -328,6 +329,19 @@ impl GraphicElementRendered for GraphicGroup {
328329
}
329330
}
330331

332+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, mut footprint: Footprint, _: Option<NodeId>) {
333+
log::debug!("Transform for graphic group: {:?}", self.transform);
334+
footprint.transform *= self.transform;
335+
for (element, optional_node_id) in self.elements.iter() {
336+
log::debug!("Optional node id: {:?}", optional_node_id);
337+
if let Some(element_id) = optional_node_id {
338+
let mut new_footprints = HashMap::new();
339+
element.add_footprints(&mut new_footprints, footprint, Some(*element_id));
340+
footprints.extend(new_footprints);
341+
}
342+
}
343+
}
344+
331345
#[cfg(feature = "vello")]
332346
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
333347
let child_transform = transform * self.transform;
@@ -411,6 +425,8 @@ impl GraphicElementRendered for VectorData {
411425
click_targets.extend(self.stroke_bezier_paths().map(fill).map(|subpath| ClickTarget::new(subpath, stroke_width)));
412426
}
413427

428+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, _: Option<NodeId>) {}
429+
414430
#[cfg(feature = "vello")]
415431
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, _: &mut RenderContext) {
416432
use crate::vector::style::GradientType;
@@ -626,35 +642,52 @@ impl GraphicElementRendered for Artboard {
626642
click_targets.push(ClickTarget::new(subpath, 0.));
627643
}
628644

645+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, mut footprint: Footprint, node_id: Option<NodeId>) {
646+
log::debug!("Adding footprints for artboard");
647+
let mut graphic_group_footprint = footprint.clone();
648+
graphic_group_footprint.transform *= self.transform();
649+
self.graphic_group.add_footprints(footprints, graphic_group_footprint, None);
650+
// footprint.transform *= self.transform();
651+
if let Some(node_id) = node_id {
652+
footprints.insert(node_id, (footprint, DAffine2::from_translation(self.location.as_dvec2())));
653+
}
654+
}
655+
629656
fn contains_artboard(&self) -> bool {
630657
true
631658
}
632659
}
633660

634661
impl GraphicElementRendered for crate::ArtboardGroup {
635662
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
636-
for artboard in &self.artboards {
663+
for (artboard, _) in &self.artboards {
637664
artboard.render_svg(render, render_params);
638665
}
639666
}
640667

641668
fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]> {
642-
self.artboards.iter().filter_map(|element| element.bounding_box(transform)).reduce(Quad::combine_bounds)
669+
self.artboards.iter().filter_map(|(element, _)| element.bounding_box(transform)).reduce(Quad::combine_bounds)
643670
}
644671

645672
fn add_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
646-
for artboard in &self.artboards {
673+
for (artboard, _) in &self.artboards {
647674
artboard.add_click_targets(click_targets);
648675
}
649676
}
650677

651678
#[cfg(feature = "vello")]
652679
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
653-
for artboard in &self.artboards {
680+
for (artboard, _) in &self.artboards {
654681
artboard.render_to_vello(scene, transform, context)
655682
}
656683
}
657684

685+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, _: Option<NodeId>) {
686+
for (artboard, node_id) in &self.artboards {
687+
artboard.add_footprints(footprints, footprint, *node_id)
688+
}
689+
}
690+
658691
fn contains_artboard(&self) -> bool {
659692
!self.artboards.is_empty()
660693
}
@@ -706,6 +739,12 @@ impl GraphicElementRendered for ImageFrame<Color> {
706739
click_targets.push(ClickTarget::new(subpath, 0.));
707740
}
708741

742+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {
743+
if let Some(element_id) = element_id {
744+
footprints.insert(element_id, (footprint, self.transform));
745+
}
746+
}
747+
709748
#[cfg(feature = "vello")]
710749
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, _: &mut RenderContext) {
711750
use vello::peniko;
@@ -776,6 +815,10 @@ impl GraphicElementRendered for Raster {
776815
click_targets.push(ClickTarget::new(subpath, 0.));
777816
}
778817

818+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {
819+
//footprints.insert(element_id, (transform, self.transform));
820+
}
821+
779822
#[cfg(feature = "vello")]
780823
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
781824
use vello::peniko;
@@ -841,6 +884,17 @@ impl GraphicElementRendered for GraphicElement {
841884
}
842885
}
843886

887+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {
888+
if let Some(element_id) = element_id {
889+
footprints.insert(element_id, (footprint, self.transform()));
890+
}
891+
match self {
892+
GraphicElement::VectorData(vector_data) => vector_data.add_footprints(footprints, footprint, None),
893+
GraphicElement::Raster(raster) => raster.add_footprints(footprints, footprint, None),
894+
GraphicElement::GraphicGroup(graphic_group) => graphic_group.add_footprints(footprints, footprint, None),
895+
}
896+
}
897+
844898
#[cfg(feature = "vello")]
845899
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
846900
match self {
@@ -883,6 +937,7 @@ impl<T: Primitive> GraphicElementRendered for T {
883937
}
884938

885939
fn add_click_targets(&self, _click_targets: &mut Vec<ClickTarget>) {}
940+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {}
886941
}
887942

888943
impl GraphicElementRendered for Option<Color> {
@@ -910,6 +965,8 @@ impl GraphicElementRendered for Option<Color> {
910965
}
911966

912967
fn add_click_targets(&self, _click_targets: &mut Vec<ClickTarget>) {}
968+
969+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {}
913970
}
914971

915972
impl GraphicElementRendered for Vec<Color> {
@@ -933,6 +990,8 @@ impl GraphicElementRendered for Vec<Color> {
933990
}
934991

935992
fn add_click_targets(&self, _click_targets: &mut Vec<ClickTarget>) {}
993+
994+
fn add_footprints(&self, footprints: &mut HashMap<NodeId, (Footprint, DAffine2)>, footprint: Footprint, element_id: Option<NodeId>) {}
936995
}
937996

938997
/// A segment of an svg string to allow for embedding blob urls

0 commit comments

Comments
 (0)