From f5587129b0aea650c717290e01a83a9492a0971c Mon Sep 17 00:00:00 2001 From: hypercube <0hypercube@gmail.com> Date: Thu, 24 Jul 2025 20:17:51 +0100 Subject: [PATCH 1/5] Ignore hidden path nodes --- .../portfolio/document/utility_types/document_metadata.rs | 2 +- .../portfolio/document/utility_types/network_interface.rs | 2 +- .../tool/common_functionality/graph_modification_utils.rs | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/editor/src/messages/portfolio/document/utility_types/document_metadata.rs b/editor/src/messages/portfolio/document/utility_types/document_metadata.rs index 600d4958f6..8ab61cc7c4 100644 --- a/editor/src/messages/portfolio/document/utility_types/document_metadata.rs +++ b/editor/src/messages/portfolio/document/utility_types/document_metadata.rs @@ -90,7 +90,7 @@ impl DocumentMetadata { let mut use_local = true; let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, network_interface); - if let Some(path_node) = graph_layer.upstream_node_id_from_name("Path") { + if let Some(path_node) = graph_layer.upstream_visible_node_id_from_name("Path") { if let Some(&source) = self.first_instance_source_ids.get(&layer.to_node()) { if !network_interface .upstream_flow_back_from_nodes(vec![path_node], &[], FlowType::HorizontalFlow) 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 290247f621..5ac0f7136b 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -3445,7 +3445,7 @@ impl NodeNetworkInterface { pub fn compute_modified_vector(&self, layer: LayerNodeIdentifier) -> Option { let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, self); - if let Some(vector_data) = graph_layer.upstream_node_id_from_name("Path").and_then(|node| self.document_metadata.vector_modify.get(&node)) { + if let Some(vector_data) = graph_layer.upstream_visible_node_id_from_name("Path").and_then(|node| self.document_metadata.vector_modify.get(&node)) { let mut modified = vector_data.clone(); if let Some(TaggedValue::VectorModification(modification)) = graph_layer.find_input("Path", 1) { modification.apply(&mut modified); diff --git a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs index 126e5b160c..084ae249e2 100644 --- a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs +++ b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs @@ -424,6 +424,13 @@ impl<'a> NodeGraphLayer<'a> { .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) } + /// Node id of a visible node if it exists in the layer's primary flow + pub fn upstream_visible_node_id_from_name(&self, node_name: &str) -> Option { + self.horizontal_layer_flow() + .filter(|node_id| self.network_interface.is_visible(node_id, &[])) + .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) + } + /// Node id of a protonode if it exists in the layer's primary flow pub fn upstream_node_id_from_protonode(&self, protonode_identifier: ProtoNodeIdentifier) -> Option { self.horizontal_layer_flow() From e090aac6511772747b4fdb8f64dbc481dd58f844 Mon Sep 17 00:00:00 2001 From: hypercube <0hypercube@gmail.com> Date: Fri, 25 Jul 2025 09:43:21 +0100 Subject: [PATCH 2/5] Use correct path node vector modification --- .../utility_types/network_interface.rs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) 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 5ac0f7136b..c40bb6c350 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -3445,12 +3445,22 @@ impl NodeNetworkInterface { pub fn compute_modified_vector(&self, layer: LayerNodeIdentifier) -> Option { let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, self); - if let Some(vector_data) = graph_layer.upstream_visible_node_id_from_name("Path").and_then(|node| self.document_metadata.vector_modify.get(&node)) { - let mut modified = vector_data.clone(); - if let Some(TaggedValue::VectorModification(modification)) = graph_layer.find_input("Path", 1) { - modification.apply(&mut modified); + if let Some(path_node) = graph_layer.upstream_visible_node_id_from_name("Path") { + if let Some(vector_data) = self.document_metadata.vector_modify.get(&path_node) { + let mut modified = vector_data.clone(); + + if let Some(TaggedValue::VectorModification(modification)) = self + .document_network() + .nodes + .get(&path_node) + .map(|node| &node.inputs) + .and_then(|inputs| inputs.get(1)) + .and_then(|input| input.as_value()) + { + modification.apply(&mut modified); + } + return Some(modified); } - return Some(modified); } self.document_metadata From 676f90d32fabe30d8e34453e4bd8b20083bdd32c Mon Sep 17 00:00:00 2001 From: hypercube <0hypercube@gmail.com> Date: Fri, 25 Jul 2025 11:26:35 +0100 Subject: [PATCH 3/5] Break test --- .../document/utility_types/network_interface.rs | 14 ++++++-------- .../graph_modification_utils.rs | 9 +++++++++ .../messages/tool/tool_messages/freehand_tool.rs | 10 +--------- 3 files changed, 16 insertions(+), 17 deletions(-) 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 c40bb6c350..f1b07d833c 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -3449,14 +3449,12 @@ impl NodeNetworkInterface { if let Some(vector_data) = self.document_metadata.vector_modify.get(&path_node) { let mut modified = vector_data.clone(); - if let Some(TaggedValue::VectorModification(modification)) = self - .document_network() - .nodes - .get(&path_node) - .map(|node| &node.inputs) - .and_then(|inputs| inputs.get(1)) - .and_then(|input| input.as_value()) - { + let my_input = graph_layer + .upstream_visible_node_id_from_name_in_layer("Path") + .and_then(|id| self.document_network().nodes.get(&id)) + .and_then(|node: &DocumentNode| node.inputs.get(1)) + .and_then(|input| input.as_value()); + if let Some(TaggedValue::VectorModification(modification)) = my_input { modification.apply(&mut modified); } return Some(modified); diff --git a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs index 084ae249e2..f996b87ca1 100644 --- a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs +++ b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs @@ -431,6 +431,15 @@ impl<'a> NodeGraphLayer<'a> { .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) } + /// Node id of a visible node if it exists in the layer's primary flow until another layer + pub fn upstream_visible_node_id_from_name_in_layer(&self, node_name: &str) -> Option { + self.horizontal_layer_flow() + .skip(1)// Skip self + .take_while(|node_id| !self.network_interface.is_layer(node_id,&[])) + .filter(|node_id| self.network_interface.is_visible(node_id, &[])) + .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) + } + /// Node id of a protonode if it exists in the layer's primary flow pub fn upstream_node_id_from_protonode(&self, protonode_identifier: ProtoNodeIdentifier) -> Option { self.horizontal_layer_flow() diff --git a/editor/src/messages/tool/tool_messages/freehand_tool.rs b/editor/src/messages/tool/tool_messages/freehand_tool.rs index 8b0dbb73f3..766333bb2a 100644 --- a/editor/src/messages/tool/tool_messages/freehand_tool.rs +++ b/editor/src/messages/tool/tool_messages/freehand_tool.rs @@ -383,15 +383,7 @@ mod test_freehand { let point_count = vector_data.point_domain.ids().len(); let segment_count = vector_data.segment_domain.ids().len(); - let actual_positions: Vec = vector_data - .point_domain - .ids() - .iter() - .filter_map(|&point_id| { - let position = vector_data.point_domain.position_from_id(point_id)?; - Some(transform.transform_point2(position)) - }) - .collect(); + let actual_positions: Vec = vector_data.point_domain.positions().iter().map(|&position| transform.transform_point2(position)).collect(); if segment_count != point_count - 1 { return Err(format!("Expected segments to be one less than points, got {} segments for {} points", segment_count, point_count)); From a4d4509b009a66a701a7d858da57036ebb47e4b2 Mon Sep 17 00:00:00 2001 From: hypercube <0hypercube@gmail.com> Date: Sat, 2 Aug 2025 23:00:25 +0100 Subject: [PATCH 4/5] Better fix for test --- .../document/utility_types/document_metadata.rs | 2 +- .../document/utility_types/network_interface.rs | 11 ++++------- .../common_functionality/graph_modification_utils.rs | 7 ------- .../src/messages/tool/tool_messages/freehand_tool.rs | 10 ++++++---- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/editor/src/messages/portfolio/document/utility_types/document_metadata.rs b/editor/src/messages/portfolio/document/utility_types/document_metadata.rs index 8ab61cc7c4..0f4286af44 100644 --- a/editor/src/messages/portfolio/document/utility_types/document_metadata.rs +++ b/editor/src/messages/portfolio/document/utility_types/document_metadata.rs @@ -90,7 +90,7 @@ impl DocumentMetadata { let mut use_local = true; let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, network_interface); - if let Some(path_node) = graph_layer.upstream_visible_node_id_from_name("Path") { + if let Some(path_node) = graph_layer.upstream_visible_node_id_from_name_in_layer("Path") { if let Some(&source) = self.first_instance_source_ids.get(&layer.to_node()) { if !network_interface .upstream_flow_back_from_nodes(vec![path_node], &[], FlowType::HorizontalFlow) 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 f1b07d833c..8efa7aeea9 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -3445,16 +3445,13 @@ impl NodeNetworkInterface { pub fn compute_modified_vector(&self, layer: LayerNodeIdentifier) -> Option { let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, self); - if let Some(path_node) = graph_layer.upstream_visible_node_id_from_name("Path") { + if let Some(path_node) = graph_layer.upstream_visible_node_id_from_name_in_layer("Path") { if let Some(vector_data) = self.document_metadata.vector_modify.get(&path_node) { let mut modified = vector_data.clone(); - let my_input = graph_layer - .upstream_visible_node_id_from_name_in_layer("Path") - .and_then(|id| self.document_network().nodes.get(&id)) - .and_then(|node: &DocumentNode| node.inputs.get(1)) - .and_then(|input| input.as_value()); - if let Some(TaggedValue::VectorModification(modification)) = my_input { + let path_node = self.document_network().nodes.get(&path_node); + let modification_input = path_node.and_then(|node: &DocumentNode| node.inputs.get(1)).and_then(|input| input.as_value()); + if let Some(TaggedValue::VectorModification(modification)) = modification_input { modification.apply(&mut modified); } return Some(modified); diff --git a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs index f996b87ca1..8b987ff14a 100644 --- a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs +++ b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs @@ -424,13 +424,6 @@ impl<'a> NodeGraphLayer<'a> { .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) } - /// Node id of a visible node if it exists in the layer's primary flow - pub fn upstream_visible_node_id_from_name(&self, node_name: &str) -> Option { - self.horizontal_layer_flow() - .filter(|node_id| self.network_interface.is_visible(node_id, &[])) - .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) - } - /// Node id of a visible node if it exists in the layer's primary flow until another layer pub fn upstream_visible_node_id_from_name_in_layer(&self, node_name: &str) -> Option { self.horizontal_layer_flow() diff --git a/editor/src/messages/tool/tool_messages/freehand_tool.rs b/editor/src/messages/tool/tool_messages/freehand_tool.rs index 766333bb2a..87cc006256 100644 --- a/editor/src/messages/tool/tool_messages/freehand_tool.rs +++ b/editor/src/messages/tool/tool_messages/freehand_tool.rs @@ -353,7 +353,7 @@ fn extend_path_with_next_segment(tool_data: &mut FreehandToolData, position: DVe mod test_freehand { use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, MouseKeys, ScrollDelta}; use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn; - use crate::messages::tool::common_functionality::graph_modification_utils::get_stroke_width; + use crate::messages::tool::common_functionality::graph_modification_utils::{NodeGraphLayer, get_stroke_width}; use crate::messages::tool::tool_messages::freehand_tool::FreehandOptionsUpdate; use crate::test_utils::test_prelude::*; use glam::{DAffine2, DVec2}; @@ -365,6 +365,10 @@ mod test_freehand { layers .filter_map(|layer| { + let graph_layer = NodeGraphLayer::new(layer, &document.network_interface); + // Only get layers with path nodes + let _ = graph_layer.upstream_visible_node_id_from_name_in_layer("Path")?; + let vector_data = document.network_interface.compute_modified_vector(layer)?; let transform = document.metadata().transform_to_viewport(layer); Some((vector_data, transform)) @@ -373,9 +377,7 @@ mod test_freehand { } fn verify_path_points(vector_data_list: &[(VectorData, DAffine2)], expected_captured_points: &[DVec2], tolerance: f64) -> Result<(), String> { - if vector_data_list.len() == 0 { - return Err("No vector data found after drawing".to_string()); - } + assert_eq!(vector_data_list.len(), 1, "there should be one vector data"); let path_data = vector_data_list.iter().find(|(data, _)| data.point_domain.ids().len() > 0).ok_or("Could not find path data")?; From 5bf8576b0225833d05ff37a19f52810f27bcbf0c Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sat, 2 Aug 2025 15:42:35 -0700 Subject: [PATCH 5/5] Fix rustfmt --- .../common_functionality/graph_modification_utils.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs index 6d1a99d845..2bc1ca14da 100644 --- a/editor/src/messages/tool/common_functionality/graph_modification_utils.rs +++ b/editor/src/messages/tool/common_functionality/graph_modification_utils.rs @@ -435,9 +435,10 @@ impl<'a> NodeGraphLayer<'a> { /// Node id of a visible node if it exists in the layer's primary flow until another layer pub fn upstream_visible_node_id_from_name_in_layer(&self, node_name: &str) -> Option { + // `.skip(1)` is used to skip self self.horizontal_layer_flow() - .skip(1)// Skip self - .take_while(|node_id| !self.network_interface.is_layer(node_id,&[])) + .skip(1) + .take_while(|node_id| !self.network_interface.is_layer(node_id, &[])) .filter(|node_id| self.network_interface.is_visible(node_id, &[])) .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) } @@ -456,10 +457,11 @@ impl<'a> NodeGraphLayer<'a> { /// Find all of the inputs of a specific node within the layer's primary flow, up until the next layer is reached. pub fn find_node_inputs(&self, node_name: &str) -> Option<&'a Vec> { + // `.skip(1)` is used to skip self self.horizontal_layer_flow() - .skip(1)// Skip self - .take_while(|node_id| !self.network_interface.is_layer(node_id,&[])) - .find(|node_id| self.network_interface.reference(node_id,&[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) + .skip(1) + .take_while(|node_id| !self.network_interface.is_layer(node_id, &[])) + .find(|node_id| self.network_interface.reference(node_id, &[]).is_some_and(|reference| *reference == Some(node_name.to_string()))) .and_then(|node_id| self.network_interface.document_network().nodes.get(&node_id).map(|node| &node.inputs)) }