Allow the Path tool to edit an upstream path even if there's a type conversion midway (#2055)

Remove type check when iterating upstream

Convert to doc comment
This commit is contained in:
adamgerhant 2024-10-26 11:39:48 -07:00 committed by GitHub
parent b1399af5cd
commit ff8fec6eca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 13 deletions

View File

@ -5,6 +5,7 @@ use crate::messages::portfolio::document::utility_types::network_interface::{sel
use crate::messages::prelude::*;
use bezier_rs::Subpath;
use graph_craft::concrete;
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput};
use graphene_core::raster::{BlendMode, ImageFrame};
@ -16,6 +17,7 @@ use graphene_core::{Artboard, Color};
use glam::{DAffine2, DVec2, IVec2};
use graphene_std::vector::VectorData;
use graphene_std::GraphicGroup;
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
pub enum TransformIn {
@ -236,11 +238,13 @@ impl<'a> ModifyInputsContext<'a> {
}
})
}
// Gets the node id of a node with a specific reference that is upstream from the layer node, and creates it if it does not exist
/// Gets the node id of a node with a specific reference that is upstream from the layer node, and creates it if it does not exist
/// The returned node is based on the selection dots in the layer. The right most dot will always insert/access the path that flows directly into the layer
/// Each dot after that represents an existing path node
/// If there is an existing upstream node, then it will always be returned first.
pub fn existing_node_id(&mut self, reference: &'static str) -> Option<NodeId> {
// Start from the layer node or export
let output_layer = self.get_output_layer()?;
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]).0.nested_type();
let upstream = self
.network_interface
@ -249,8 +253,6 @@ impl<'a> ModifyInputsContext<'a> {
// Take until another layer node is found (but not the first layer node)
let mut existing_node_id = None;
for upstream_node in upstream.collect::<Vec<_>>() {
let upstream_node_input_type = self.network_interface.input_type(&InputConnector::node(upstream_node, 0), &[]).0.nested_type();
// Check if this is the node we have been searching for.
if self.network_interface.reference(&upstream_node, &[]).is_some_and(|node_reference| node_reference == reference) {
existing_node_id = Some(upstream_node);
@ -261,8 +263,7 @@ impl<'a> ModifyInputsContext<'a> {
self.layer_node.map(|layer| layer.to_node()) == Some(node_id) || self.network_interface.network(&[]).unwrap().exports.iter().any(|export| export.as_node() == Some(node_id))
};
// If the type changes then break?? This should at least be after checking if the node is correct (otherwise the brush tool breaks.)
if !is_traversal_start(upstream_node) && (self.network_interface.is_layer(&upstream_node, &[]) || upstream_node_input_type != layer_input_type) {
if !is_traversal_start(upstream_node) && (self.network_interface.is_layer(&upstream_node, &[])) {
break;
}
}
@ -278,6 +279,20 @@ impl<'a> ModifyInputsContext<'a> {
log::error!("Node type {} does not exist in ModifyInputsContext::existing_node_id", reference);
return None;
};
// If inserting a path node, insert a flatten vector elements if the type is a graphic group.
// TODO: Allow the path node to operate on Graphic Group data by utilizing the reference for each vector data in a group.
if node_definition.identifier == "Path" {
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]).0.nested_type();
if layer_input_type == concrete!(GraphicGroup) {
let Some(flatten_vector_elements_definition) = resolve_document_node_type("Flatten Vector Elements") else {
log::error!("Flatten Vector Elements does not exist in ModifyInputsContext::existing_node_id");
return None;
};
let node_id = NodeId::new();
self.network_interface.insert_node(node_id, flatten_vector_elements_definition.default_node_template(), &[]);
self.network_interface.move_node_to_chain_start(&node_id, output_layer, &[]);
}
}
let node_id = NodeId::new();
self.network_interface.insert_node(node_id, node_definition.default_node_template(), &[]);
self.network_interface.move_node_to_chain_start(&node_id, output_layer, &[]);

View File

@ -6,7 +6,6 @@ use crate::messages::portfolio::document::utility_types::network_interface::Node
use crate::messages::prelude::*;
use bezier_rs::{Bezier, BezierHandles, TValue};
use dyn_any::DynAny;
use graphene_core::transform::Transform;
use graphene_core::vector::{ManipulatorPointId, PointId, VectorData, VectorModificationType};
@ -1071,11 +1070,7 @@ impl ShapeState {
continue;
};
for point in self.selected_points() {
if let Some(_) = point.as_anchor() {
continue;
}
for point in self.selected_points().filter(|point| point.as_handle().is_some()) {
let anchor = point.get_anchor(&vector_data);
if let Some(handles) = point.get_handle_pair(&vector_data) {
points_to_select.push((layer, anchor, Some(handles[1].to_manipulator_point())));

View File

@ -547,7 +547,9 @@ async fn flatten_vector_elements<F: 'n + Send>(
graphic_group_input: impl Node<F, Output = GraphicGroup>,
) -> VectorData {
let graphic_group = graphic_group_input.eval(footprint).await;
// A node based solution to support passing through vector data could be a network node with a cache node connected to
// a flatten vector elements connected to an if else node, another connection from the cache directly
// To the if else node, and another connection from the cache to a matches type node connected to the if else node.
fn concat_group(graphic_group: &GraphicGroup, current_transform: DAffine2, result: &mut VectorData) {
for (element, reference) in graphic_group.iter() {
match element {