mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-28 21:48:12 +08:00
Fix more flaws with 'Transform' node rad-to-deg migration; make 'Tangent on Path' also use degrees by default
This commit is contained in:
Generated
+1
-1
File diff suppressed because one or more lines are too long
Generated
+1
-1
File diff suppressed because one or more lines are too long
Generated
+1
-1
File diff suppressed because one or more lines are too long
Generated
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Generated
+1
-1
File diff suppressed because one or more lines are too long
Generated
+1
-1
File diff suppressed because one or more lines are too long
@@ -1341,6 +1341,13 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
persistent_metadata: DocumentNodePersistentMetadata {
|
persistent_metadata: DocumentNodePersistentMetadata {
|
||||||
display_name: "Transform".to_string(),
|
display_name: "Transform".to_string(),
|
||||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(7, 0)),
|
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(7, 0)),
|
||||||
|
input_metadata: vec![
|
||||||
|
("Value", "TODO").into(),
|
||||||
|
("Translation", "TODO").into(),
|
||||||
|
("Rotation", "TODO").into(),
|
||||||
|
("Scale", "TODO").into(),
|
||||||
|
("Skew", "TODO").into(),
|
||||||
|
],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
@@ -1002,10 +1002,7 @@ impl NodeNetworkInterface {
|
|||||||
.outward_wires(network_path)
|
.outward_wires(network_path)
|
||||||
.and_then(|outward_wires| outward_wires.get(output_connector))
|
.and_then(|outward_wires| outward_wires.get(output_connector))
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_default()
|
||||||
log::error!("Could not get {output_connector:?} in outward wires");
|
|
||||||
Vec::new()
|
|
||||||
})
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|input| match input {
|
.map(|input| match input {
|
||||||
InputConnector::Node { node_id, input_index } => {
|
InputConnector::Node { node_id, input_index } => {
|
||||||
@@ -6470,7 +6467,7 @@ pub struct NodeNetworkTransientMetadata {
|
|||||||
pub stack_dependents: TransientMetadata<HashMap<NodeId, LayerOwner>>,
|
pub stack_dependents: TransientMetadata<HashMap<NodeId, LayerOwner>>,
|
||||||
/// Cache for the bounding box around all nodes in node graph space.
|
/// Cache for the bounding box around all nodes in node graph space.
|
||||||
pub all_nodes_bounding_box: TransientMetadata<[DVec2; 2]>,
|
pub all_nodes_bounding_box: TransientMetadata<[DVec2; 2]>,
|
||||||
/// Cache bounding box for all "groups of nodes", which will be used to prevent overlapping nodes
|
// /// Cache bounding box for all "groups of nodes", which will be used to prevent overlapping nodes
|
||||||
// node_group_bounding_box: Vec<(Subpath<ManipulatorGroupId>, Vec<Nodes>)>,
|
// node_group_bounding_box: Vec<(Subpath<ManipulatorGroupId>, Vec<Nodes>)>,
|
||||||
/// Cache for all outward wire connections
|
/// Cache for all outward wire connections
|
||||||
pub outward_wires: TransientMetadata<HashMap<OutputConnector, Vec<InputConnector>>>,
|
pub outward_wires: TransientMetadata<HashMap<OutputConnector, Vec<InputConnector>>>,
|
||||||
|
|||||||
@@ -784,6 +784,22 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
|||||||
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::Bool(true), false), network_path);
|
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::Bool(true), false), network_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Upgrade the 'Tangent on Path' node to include a boolean input for whether the output should be in radians, which was previously the only option but is now not the default
|
||||||
|
if (reference == "Tangent on Path") && inputs_count == 4 {
|
||||||
|
let mut node_template = resolve_document_node_type(reference)?.default_node_template();
|
||||||
|
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
|
||||||
|
|
||||||
|
let old_inputs = document.network_interface.replace_inputs(node_id, network_path, &mut node_template)?;
|
||||||
|
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 0), old_inputs[0].clone(), network_path);
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 1), old_inputs[1].clone(), network_path);
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 2), old_inputs[2].clone(), network_path);
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 3), old_inputs[3].clone(), network_path);
|
||||||
|
document
|
||||||
|
.network_interface
|
||||||
|
.set_input(&InputConnector::node(*node_id, 4), NodeInput::value(TaggedValue::Bool(true), false), network_path);
|
||||||
|
}
|
||||||
|
|
||||||
// Upgrade the Modulo node to include a boolean input for whether the output should be always positive, which was previously not an option
|
// Upgrade the Modulo node to include a boolean input for whether the output should be always positive, which was previously not an option
|
||||||
if reference == "Modulo" && inputs_count == 2 {
|
if reference == "Modulo" && inputs_count == 2 {
|
||||||
let mut node_template = resolve_document_node_type(reference)?.default_node_template();
|
let mut node_template = resolve_document_node_type(reference)?.default_node_template();
|
||||||
@@ -1054,6 +1070,30 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
|||||||
|
|
||||||
// Migrate the Transform node to use degrees instead of radians
|
// Migrate the Transform node to use degrees instead of radians
|
||||||
if reference == "Transform" && node.inputs.get(6).is_none() {
|
if reference == "Transform" && node.inputs.get(6).is_none() {
|
||||||
|
let mut node_template = resolve_document_node_type("Transform")?.default_node_template();
|
||||||
|
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
|
||||||
|
|
||||||
|
let old_inputs = document.network_interface.replace_inputs(node_id, network_path, &mut node_template)?;
|
||||||
|
|
||||||
|
// Value
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 0), old_inputs[0].clone(), network_path);
|
||||||
|
// Translation
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 1), old_inputs[1].clone(), network_path);
|
||||||
|
// Rotation
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 2), old_inputs[2].clone(), network_path);
|
||||||
|
// Scale
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 3), old_inputs[3].clone(), network_path);
|
||||||
|
// Skew
|
||||||
|
document.network_interface.set_input(&InputConnector::node(*node_id, 4), old_inputs[4].clone(), network_path);
|
||||||
|
// Origin Offset
|
||||||
|
document
|
||||||
|
.network_interface
|
||||||
|
.set_input(&InputConnector::node(*node_id, 5), NodeInput::value(TaggedValue::DVec2(DVec2::ZERO), false), network_path);
|
||||||
|
// Scale Appearance
|
||||||
|
document
|
||||||
|
.network_interface
|
||||||
|
.set_input(&InputConnector::node(*node_id, 6), NodeInput::value(TaggedValue::Bool(true), false), network_path);
|
||||||
|
|
||||||
// Migrate rotation from radians to degrees
|
// Migrate rotation from radians to degrees
|
||||||
match node.inputs.get(2)? {
|
match node.inputs.get(2)? {
|
||||||
NodeInput::Value { tagged_value, exposed } => {
|
NodeInput::Value { tagged_value, exposed } => {
|
||||||
@@ -1099,31 +1139,6 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
|||||||
let new_input = NodeInput::value(TaggedValue::DVec2(new_value), *exposed);
|
let new_input = NodeInput::value(TaggedValue::DVec2(new_value), *exposed);
|
||||||
document.network_interface.set_input(&InputConnector::node(*node_id, 4), new_input, network_path);
|
document.network_interface.set_input(&InputConnector::node(*node_id, 4), new_input, network_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if document
|
|
||||||
.network_interface
|
|
||||||
.node_metadata(node_id, network_path)
|
|
||||||
.map(|x| x.persistent_metadata.input_metadata.len() > 5)
|
|
||||||
.unwrap_or_default()
|
|
||||||
{
|
|
||||||
// Remove the possible existence of the old "Pivot" hidden value input that was removed in #2730
|
|
||||||
let nested_transform_network = [network_path, &[*node_id]].concat();
|
|
||||||
if node.inputs.get(5).is_some() {
|
|
||||||
document.network_interface.remove_import(5, &nested_transform_network);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the Origin Offset parameter as a hidden input, which will be given actual functionality in the future but is currently used as a marker to detect not-yet-upgraded Transform nodes
|
|
||||||
document
|
|
||||||
.network_interface
|
|
||||||
.add_import(TaggedValue::DVec2(DVec2::ZERO), false, 5, "Origin Offset", "", &nested_transform_network);
|
|
||||||
document.network_interface.set_input_override(node_id, 5, Some("hidden".to_string()), network_path); // Hide it while we're not yet using it
|
|
||||||
|
|
||||||
// Add the Scale Appearance parameter as a hidden input, which will be given actual functionality in the future but is currently used as a marker to detect not-yet-upgraded Transform nodes
|
|
||||||
document
|
|
||||||
.network_interface
|
|
||||||
.add_import(TaggedValue::Bool(true), false, 6, "Scale Appearance", "", &nested_transform_network);
|
|
||||||
document.network_interface.set_input_override(node_id, 6, Some("hidden".to_string()), network_path); // Hide it while we're not yet using it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add context features to nodes that don't have them (fine-grained context caching migration)
|
// Add context features to nodes that don't have them (fine-grained context caching migration)
|
||||||
|
|||||||
@@ -1211,10 +1211,10 @@ async fn position_on_path(
|
|||||||
let euclidian = !parameterized_distance;
|
let euclidian = !parameterized_distance;
|
||||||
|
|
||||||
let mut bezpaths = content
|
let mut bezpaths = content
|
||||||
.into_iter()
|
.iter()
|
||||||
.flat_map(|vector| {
|
.flat_map(|vector| {
|
||||||
let transform = vector.transform;
|
let transform = *vector.transform;
|
||||||
vector.element.stroke_bezpath_iter().map(|bezpath| (bezpath, transform)).collect::<Vec<_>>()
|
vector.element.stroke_bezpath_iter().map(move |bezpath| (bezpath, transform))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let bezpath_count = bezpaths.len() as f64;
|
let bezpath_count = bezpaths.len() as f64;
|
||||||
@@ -1246,14 +1246,16 @@ async fn tangent_on_path(
|
|||||||
reverse: bool,
|
reverse: bool,
|
||||||
/// Traverse the path using each segment's Bézier curve parameterization instead of the Euclidean distance. Faster to compute but doesn't respect actual distances.
|
/// Traverse the path using each segment's Bézier curve parameterization instead of the Euclidean distance. Faster to compute but doesn't respect actual distances.
|
||||||
parameterized_distance: bool,
|
parameterized_distance: bool,
|
||||||
|
/// Whether the resulting angle should be given in as radians instead of degrees.
|
||||||
|
radians: bool,
|
||||||
) -> f64 {
|
) -> f64 {
|
||||||
let euclidian = !parameterized_distance;
|
let euclidian = !parameterized_distance;
|
||||||
|
|
||||||
let mut bezpaths = content
|
let mut bezpaths = content
|
||||||
.into_iter()
|
.iter()
|
||||||
.flat_map(|vector| {
|
.flat_map(|vector| {
|
||||||
let transform = vector.transform;
|
let transform = *vector.transform;
|
||||||
vector.element.stroke_bezpath_iter().map(|bezpath| (bezpath, transform)).collect::<Vec<_>>()
|
vector.element.stroke_bezpath_iter().map(move |bezpath| (bezpath, transform))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let bezpath_count = bezpaths.len() as f64;
|
let bezpath_count = bezpaths.len() as f64;
|
||||||
@@ -1261,7 +1263,7 @@ async fn tangent_on_path(
|
|||||||
let progress = if reverse { bezpath_count - progress } else { progress };
|
let progress = if reverse { bezpath_count - progress } else { progress };
|
||||||
let index = if progress >= bezpath_count { (bezpath_count - 1.) as usize } else { progress as usize };
|
let index = if progress >= bezpath_count { (bezpath_count - 1.) as usize } else { progress as usize };
|
||||||
|
|
||||||
bezpaths.get_mut(index).map_or(0., |(bezpath, transform)| {
|
let angle = bezpaths.get_mut(index).map_or(0., |(bezpath, transform)| {
|
||||||
let t = if progress == bezpath_count { 1. } else { progress.fract() };
|
let t = if progress == bezpath_count { 1. } else { progress.fract() };
|
||||||
let t_value = |t: f64| if euclidian { TValue::Euclidean(t) } else { TValue::Parametric(t) };
|
let t_value = |t: f64| if euclidian { TValue::Euclidean(t) } else { TValue::Parametric(t) };
|
||||||
|
|
||||||
@@ -1277,7 +1279,9 @@ async fn tangent_on_path(
|
|||||||
}
|
}
|
||||||
|
|
||||||
-tangent.angle_to(if reverse { -DVec2::X } else { DVec2::X })
|
-tangent.angle_to(if reverse { -DVec2::X } else { DVec2::X })
|
||||||
})
|
});
|
||||||
|
|
||||||
|
if radians { angle } else { angle.to_degrees() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node_macro::node(category(""), path(graphene_core::vector))]
|
#[node_macro::node(category(""), path(graphene_core::vector))]
|
||||||
|
|||||||
Reference in New Issue
Block a user