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:
parent
b1399af5cd
commit
ff8fec6eca
|
|
@ -5,6 +5,7 @@ use crate::messages::portfolio::document::utility_types::network_interface::{sel
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
|
use graph_craft::concrete;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::raster::{BlendMode, ImageFrame};
|
use graphene_core::raster::{BlendMode, ImageFrame};
|
||||||
|
|
@ -16,6 +17,7 @@ use graphene_core::{Artboard, Color};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use graphene_std::vector::VectorData;
|
use graphene_std::vector::VectorData;
|
||||||
|
use graphene_std::GraphicGroup;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum TransformIn {
|
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> {
|
pub fn existing_node_id(&mut self, reference: &'static str) -> Option<NodeId> {
|
||||||
// Start from the layer node or export
|
// Start from the layer node or export
|
||||||
let output_layer = self.get_output_layer()?;
|
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
|
let upstream = self
|
||||||
.network_interface
|
.network_interface
|
||||||
|
|
@ -249,8 +253,6 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
// Take until another layer node is found (but not the first layer node)
|
// Take until another layer node is found (but not the first layer node)
|
||||||
let mut existing_node_id = None;
|
let mut existing_node_id = None;
|
||||||
for upstream_node in upstream.collect::<Vec<_>>() {
|
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.
|
// 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) {
|
if self.network_interface.reference(&upstream_node, &[]).is_some_and(|node_reference| node_reference == reference) {
|
||||||
existing_node_id = Some(upstream_node);
|
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))
|
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, &[])) {
|
||||||
if !is_traversal_start(upstream_node) && (self.network_interface.is_layer(&upstream_node, &[]) || upstream_node_input_type != layer_input_type) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,6 +279,20 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
log::error!("Node type {} does not exist in ModifyInputsContext::existing_node_id", reference);
|
log::error!("Node type {} does not exist in ModifyInputsContext::existing_node_id", reference);
|
||||||
return None;
|
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();
|
let node_id = NodeId::new();
|
||||||
self.network_interface.insert_node(node_id, node_definition.default_node_template(), &[]);
|
self.network_interface.insert_node(node_id, node_definition.default_node_template(), &[]);
|
||||||
self.network_interface.move_node_to_chain_start(&node_id, output_layer, &[]);
|
self.network_interface.move_node_to_chain_start(&node_id, output_layer, &[]);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use crate::messages::portfolio::document::utility_types::network_interface::Node
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bezier_rs::{Bezier, BezierHandles, TValue};
|
use bezier_rs::{Bezier, BezierHandles, TValue};
|
||||||
use dyn_any::DynAny;
|
|
||||||
use graphene_core::transform::Transform;
|
use graphene_core::transform::Transform;
|
||||||
use graphene_core::vector::{ManipulatorPointId, PointId, VectorData, VectorModificationType};
|
use graphene_core::vector::{ManipulatorPointId, PointId, VectorData, VectorModificationType};
|
||||||
|
|
||||||
|
|
@ -1071,11 +1070,7 @@ impl ShapeState {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
for point in self.selected_points() {
|
for point in self.selected_points().filter(|point| point.as_handle().is_some()) {
|
||||||
if let Some(_) = point.as_anchor() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let anchor = point.get_anchor(&vector_data);
|
let anchor = point.get_anchor(&vector_data);
|
||||||
if let Some(handles) = point.get_handle_pair(&vector_data) {
|
if let Some(handles) = point.get_handle_pair(&vector_data) {
|
||||||
points_to_select.push((layer, anchor, Some(handles[1].to_manipulator_point())));
|
points_to_select.push((layer, anchor, Some(handles[1].to_manipulator_point())));
|
||||||
|
|
|
||||||
|
|
@ -547,7 +547,9 @@ async fn flatten_vector_elements<F: 'n + Send>(
|
||||||
graphic_group_input: impl Node<F, Output = GraphicGroup>,
|
graphic_group_input: impl Node<F, Output = GraphicGroup>,
|
||||||
) -> VectorData {
|
) -> VectorData {
|
||||||
let graphic_group = graphic_group_input.eval(footprint).await;
|
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) {
|
fn concat_group(graphic_group: &GraphicGroup, current_transform: DAffine2, result: &mut VectorData) {
|
||||||
for (element, reference) in graphic_group.iter() {
|
for (element, reference) in graphic_group.iter() {
|
||||||
match element {
|
match element {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue