From 1b6d45ad306ded762f7e7f7420bfa0fdc9012065 Mon Sep 17 00:00:00 2001 From: Utsav Singh Date: Sun, 11 Aug 2024 11:59:34 +0530 Subject: [PATCH] Respect 'Clip' on Artboards when exporting "All Artworks". (#1916) * Add constraint_bounds function to Quad implementation * Respect Clip property when exporting All Artworks and centering document using the ctrl + 0 hotkey. Calculate artboard_clip_bounds and then constraint the all_layer_bounds to respect the bounds of the Clipped Artboards. * Use parent_artboard to find ancestor artboards of each layer and constrain bounds if artboard is clipped * Remove redundant comments --- .../utility_types/network_interface.rs | 27 ++++++++++++++++++- .../src/graphic_element/renderer/quad.rs | 8 ++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface.rs b/editor/src/messages/portfolio/document/utility_types/network_interface.rs index 5f48e3a6..531f15b5 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -905,6 +905,15 @@ impl NodeNetworkInterface { .is_some_and(|reference| reference == "Artboard" && self.connected_to_output(node_id, &[])) } + pub fn parent_artboard(&self, layer: LayerNodeIdentifier) -> Option { + let ancestors: Vec<_> = layer.ancestors(self.document_metadata()).collect(); + match ancestors.as_slice() { + [_, second_last, _last] if self.is_artboard(&second_last.to_node(), &[]) => Some(*second_last), + [_, last] if self.is_artboard(&last.to_node(), &[]) => Some(*last), + _ => None, + } + } + pub fn all_artboards(&self) -> HashSet { self.network_metadata(&[]) .unwrap() @@ -949,7 +958,23 @@ impl NodeNetworkInterface { self.document_metadata .all_layers() .filter(|layer| include_artboards || !self.is_artboard(&layer.to_node(), &[])) - .filter_map(|layer| self.document_metadata.bounding_box_document(layer)) + .filter_map(|layer| { + if !self.is_artboard(&layer.to_node(), &[]) { + if let Some(artboard_node_identifier) = self.parent_artboard(layer) { + let artboard = self.network(&[]).unwrap().nodes.get(&artboard_node_identifier.to_node()); + let clip_input = artboard.unwrap().inputs.get(5).unwrap(); + if let NodeInput::Value { tagged_value, .. } = clip_input { + if tagged_value.to_primitive_string() == "true" { + return Some(Quad::constraint_bounds( + self.document_metadata.bounding_box_document(layer).unwrap_or_default(), + self.document_metadata.bounding_box_document(artboard_node_identifier).unwrap_or_default(), + )); + } + } + } + } + self.document_metadata.bounding_box_document(layer) + }) .reduce(Quad::combine_bounds) } diff --git a/node-graph/gcore/src/graphic_element/renderer/quad.rs b/node-graph/gcore/src/graphic_element/renderer/quad.rs index e131b8bd..fa905804 100644 --- a/node-graph/gcore/src/graphic_element/renderer/quad.rs +++ b/node-graph/gcore/src/graphic_element/renderer/quad.rs @@ -49,6 +49,14 @@ impl Quad { [a[0].min(b[0]), a[1].max(b[1])] } + /// "Clip" bounds of 'a' to the limits of 'b' + pub fn constraint_bounds(a: [DVec2; 2], b: [DVec2; 2]) -> [DVec2; 2] { + [ + a[0].max(b[0]), // Constrain min corner + a[1].min(b[1]), // Constrain max corner + ] + } + /// Expand a quad by a certain amount on all sides. /// /// Not currently very optimised