mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 13:18:11 +08:00
Rename the nodes 'Length' -> 'Magnitude', 'Flatten Path' -> 'Combine Paths', 'Vec2 Value' -> 'Combine Vec2', and add a new 'Vec2 Value' node (#4349)
* Rename the node 'Length' -> 'Magnitude' * Rename the node 'Flatten Path' -> 'Combine Paths' * Replace the node 'Vec2 Value' with 'Combine Vec2' and add a new 'Vec2 Value' that's actually a vec2 * Update demo artwork
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
@@ -433,17 +433,17 @@ impl<'a> ModifyInputsContext<'a> {
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If inserting a 'Path' node, insert a 'Flatten Path' node if the type is `Graphic`.
|
// If inserting a 'Path' node, insert a 'Combine Paths' node if the type is `Graphic`.
|
||||||
// TODO: Allow the 'Path' node to operate on `List` data by utilizing the reference (index or ID?) for each item.
|
// TODO: Allow the 'Path' node to operate on `List` data by utilizing the reference (index or ID?) for each item.
|
||||||
if node_definition.identifier == "Path" {
|
if node_definition.identifier == "Path" {
|
||||||
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]);
|
let layer_input_type = self.network_interface.input_type(&InputConnector::node(output_layer.to_node(), 1), &[]);
|
||||||
if layer_input_type.compiled_element_name().as_deref() == Some("Graphic") {
|
if layer_input_type.compiled_element_name().as_deref() == Some("Graphic") {
|
||||||
let Some(flatten_path_definition) = resolve_proto_node_type(graphene_std::vector_nodes::flatten_path::IDENTIFIER) else {
|
let Some(combine_paths_definition) = resolve_proto_node_type(graphene_std::vector_nodes::combine_paths::IDENTIFIER) else {
|
||||||
log::error!("Flatten Path does not exist in ModifyInputsContext::existing_node_id");
|
log::error!("Combine Paths does not exist in ModifyInputsContext::existing_node_id");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let node_id = NodeId::new();
|
let node_id = NodeId::new();
|
||||||
self.network_interface.insert_node(node_id, flatten_path_definition.default_node_template(), &[]);
|
self.network_interface.insert_node(node_id, combine_paths_definition.default_node_template(), &[]);
|
||||||
self.network_interface.move_node_to_chain_start(&node_id, output_layer, &[], self.import);
|
self.network_interface.move_node_to_chain_start(&node_id, output_layer, &[], self.import);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -806,9 +806,9 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
|||||||
inputs: vec![NodeInput::node(NodeId(4), 0), NodeInput::node(NodeId(3), 0)],
|
inputs: vec![NodeInput::node(NodeId(4), 0), NodeInput::node(NodeId(3), 0)],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
// 6: Flatten Path
|
// 6: Combine Paths
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
implementation: DocumentNodeImplementation::ProtoNode(vector::flatten_path::IDENTIFIER),
|
implementation: DocumentNodeImplementation::ProtoNode(vector::combine_paths::IDENTIFIER),
|
||||||
inputs: vec![NodeInput::node(NodeId(5), 0)],
|
inputs: vec![NodeInput::node(NodeId(5), 0)],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -883,7 +883,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
|||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
// 6: Flatten Path
|
// 6: Combine Paths
|
||||||
DocumentNodeMetadata {
|
DocumentNodeMetadata {
|
||||||
persistent_metadata: DocumentNodePersistentMetadata {
|
persistent_metadata: DocumentNodePersistentMetadata {
|
||||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(35, 0)),
|
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(35, 0)),
|
||||||
@@ -1239,7 +1239,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
|
|||||||
description: Cow::Borrowed(
|
description: Cow::Borrowed(
|
||||||
"Decomposes the X and Y components of a vec2.\n\
|
"Decomposes the X and Y components of a vec2.\n\
|
||||||
\n\
|
\n\
|
||||||
The inverse of this node is \"Vec2 Value\", which can have either or both its X and Y parameters exposed as graph inputs.",
|
The inverse of this node is **Combine Vec2**, which composes a vec2 from its X and Y components.",
|
||||||
),
|
),
|
||||||
properties: None,
|
properties: None,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -294,8 +294,8 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
NodeReplacement {
|
NodeReplacement {
|
||||||
node: graphene_std::math_nodes::length::IDENTIFIER,
|
node: graphene_std::math_nodes::magnitude::IDENTIFIER,
|
||||||
aliases: &["graphene_math_nodes::LengthNode", "graphene_core::ops::LenghtNode"],
|
aliases: &["math_nodes::LengthNode", "graphene_math_nodes::LengthNode", "graphene_core::ops::LenghtNode"],
|
||||||
},
|
},
|
||||||
NodeReplacement {
|
NodeReplacement {
|
||||||
node: graphene_std::math_nodes::less_than::IDENTIFIER,
|
node: graphene_std::math_nodes::less_than::IDENTIFIER,
|
||||||
@@ -420,6 +420,8 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
|
|||||||
node: graphene_std::math_nodes::as_u_64::IDENTIFIER,
|
node: graphene_std::math_nodes::as_u_64::IDENTIFIER,
|
||||||
aliases: &["graphene_math_nodes::ToU64Node", "graphene_core::ops::ToU64Node", "math_nodes::ToU64Node"],
|
aliases: &["graphene_math_nodes::ToU64Node", "graphene_core::ops::ToU64Node", "math_nodes::ToU64Node"],
|
||||||
},
|
},
|
||||||
|
// The old 'Vec2 Value' node took separate X and Y inputs, a role now filled by 'Combine Vec2', while the new 'Vec2 Value' node takes a single vec2 input.
|
||||||
|
// Old references (including these older aliases) are remapped here to `vec_2_value::IDENTIFIER` so the per-node migration in `migrate_node` can detect the leftover 3-input shape and convert it into a 'Combine Vec2' node.
|
||||||
NodeReplacement {
|
NodeReplacement {
|
||||||
node: graphene_std::math_nodes::vec_2_value::IDENTIFIER,
|
node: graphene_std::math_nodes::vec_2_value::IDENTIFIER,
|
||||||
aliases: &[
|
aliases: &[
|
||||||
@@ -803,7 +805,7 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
|
|||||||
aliases: &["graphene_core::vector::vector_nodes::FillNode", "graphene_core::vector::FillNode"],
|
aliases: &["graphene_core::vector::vector_nodes::FillNode", "graphene_core::vector::FillNode"],
|
||||||
},
|
},
|
||||||
NodeReplacement {
|
NodeReplacement {
|
||||||
node: graphene_std::vector::flatten_path::IDENTIFIER,
|
node: graphene_std::vector::combine_paths::IDENTIFIER,
|
||||||
aliases: &[
|
aliases: &[
|
||||||
"graphene_core::vector::vector_nodes::FlattenPathNode",
|
"graphene_core::vector::vector_nodes::FlattenPathNode",
|
||||||
"graphene_core::vector::FlattenVectorElementsNode",
|
"graphene_core::vector::FlattenVectorElementsNode",
|
||||||
@@ -2021,6 +2023,20 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
|||||||
.set_input(&InputConnector::node(*node_id, 2), NodeInput::value(TaggedValue::Bool(false), false), network_path);
|
.set_input(&InputConnector::node(*node_id, 2), NodeInput::value(TaggedValue::Bool(false), false), network_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert the old 'Vec2 Value' node, identified by its leftover 3-input shape with separate X and Y inputs,
|
||||||
|
// into the 'Combine Vec2' node which now fills that role (the new 'Vec2 Value' node instead takes a single vec2 input)
|
||||||
|
if reference == DefinitionIdentifier::ProtoNode(graphene_std::math_nodes::vec_2_value::IDENTIFIER) && inputs_count == 3 {
|
||||||
|
let combine_vec2_reference = DefinitionIdentifier::ProtoNode(graphene_std::math_nodes::combine_vec_2::IDENTIFIER);
|
||||||
|
let mut node_template = resolve_document_node_type(&combine_vec2_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);
|
||||||
|
}
|
||||||
|
|
||||||
// Upgrade the Mirror node to add the `keep_original` boolean input
|
// Upgrade the Mirror node to add the `keep_original` boolean input
|
||||||
if reference == DefinitionIdentifier::ProtoNode(graphene_std::graphic::mirror::IDENTIFIER) && inputs_count == 3 {
|
if reference == DefinitionIdentifier::ProtoNode(graphene_std::graphic::mirror::IDENTIFIER) && inputs_count == 3 {
|
||||||
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
|
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
|
||||||
|
|||||||
@@ -101,21 +101,21 @@ pub fn merge_layers(document: &DocumentMessageHandler, first_layer: LayerNodeIde
|
|||||||
delete_children: false,
|
delete_children: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a Flatten Path node after the merge
|
// Add a Combine Paths node after the merge
|
||||||
let flatten_node_id = NodeId::new();
|
let combine_paths_node_id = NodeId::new();
|
||||||
let flatten_node = document_node_definitions::resolve_proto_node_type(graphene_std::vector::flatten_path::IDENTIFIER)
|
let combine_paths_node = document_node_definitions::resolve_proto_node_type(graphene_std::vector::combine_paths::IDENTIFIER)
|
||||||
.expect("Failed to create flatten node")
|
.expect("Failed to create combine paths node")
|
||||||
.default_node_template();
|
.default_node_template();
|
||||||
responses.add(NodeGraphMessage::InsertNode {
|
responses.add(NodeGraphMessage::InsertNode {
|
||||||
node_id: flatten_node_id,
|
node_id: combine_paths_node_id,
|
||||||
node_template: Box::new(flatten_node),
|
node_template: Box::new(combine_paths_node),
|
||||||
});
|
});
|
||||||
responses.add(NodeGraphMessage::MoveNodeToChainStart {
|
responses.add(NodeGraphMessage::MoveNodeToChainStart {
|
||||||
node_id: flatten_node_id,
|
node_id: combine_paths_node_id,
|
||||||
parent: first_layer,
|
parent: first_layer,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a path node after the flatten node
|
// Add a path node after the combine paths node
|
||||||
let path_node_id = NodeId::new();
|
let path_node_id = NodeId::new();
|
||||||
let path_node = document_node_definitions::resolve_network_node_type("Path")
|
let path_node = document_node_definitions::resolve_network_node_type("Path")
|
||||||
.expect("Failed to create path node")
|
.expect("Failed to create path node")
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ impl ShapeState {
|
|||||||
(point.as_handle().is_some() && self.ignore_handles) || (point.as_anchor().is_some() && self.ignore_anchors)
|
(point.as_handle().is_some() && self.ignore_handles) || (point.as_anchor().is_some() && self.ignore_anchors)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies a dummy vector modification to the layer. In the case where a group containing some vector data is selected, this triggers the creation of a Flatten Path node.
|
/// Applies a dummy vector modification to the layer. In the case where a group containing some vector data is selected, this triggers the creation of a Combine Paths node.
|
||||||
fn add_dummy_modification_to_trigger_graph_reorganization(layer: LayerNodeIdentifier, start_point: PointId, _end_point: PointId, responses: &mut VecDeque<Message>) {
|
fn add_dummy_modification_to_trigger_graph_reorganization(layer: LayerNodeIdentifier, start_point: PointId, _end_point: PointId, responses: &mut VecDeque<Message>) {
|
||||||
// Apply a zero-delta to one of the points to trigger reorganization
|
// Apply a zero-delta to one of the points to trigger reorganization
|
||||||
let dummy_modification = VectorModificationType::ApplyPointDelta {
|
let dummy_modification = VectorModificationType::ApplyPointDelta {
|
||||||
|
|||||||
@@ -1623,7 +1623,7 @@ impl Render for List<Vector> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If this item carries a snapshot of upstream graphic content (e.g. it was produced by Boolean Operation,
|
// If this item carries a snapshot of upstream graphic content (e.g. it was produced by Boolean Operation,
|
||||||
// Flatten Path, Morph, or any other destructive merge), recurse into that snapshot so the editor can
|
// Combine Paths, Morph, or any other destructive merge), recurse into that snapshot so the editor can
|
||||||
// surface the original child layers' click targets.
|
// surface the original child layers' click targets.
|
||||||
let upstream_nested_layers = self.attribute_cloned_or_default::<List<Graphic>>(ATTR_EDITOR_MERGED_LAYERS, index);
|
let upstream_nested_layers = self.attribute_cloned_or_default::<List<Graphic>>(ATTR_EDITOR_MERGED_LAYERS, index);
|
||||||
if !upstream_nested_layers.is_empty() {
|
if !upstream_nested_layers.is_empty() {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use glam::{DVec2, IVec2, UVec2};
|
|||||||
|
|
||||||
/// Obtains the X or Y component of a vec2.
|
/// Obtains the X or Y component of a vec2.
|
||||||
///
|
///
|
||||||
/// The inverse of this node is "Vec2 Value", which can have either or both its X and Y parameters exposed as graph inputs.
|
/// The inverse of this node is **Combine Vec2**, which composes a vec2 from its X and Y components.
|
||||||
#[node_macro::node(name("Extract XY"), category("Math: Vector"))]
|
#[node_macro::node(name("Extract XY"), category("Math: Vector"))]
|
||||||
fn extract_xy<T: Into<DVec2>>(_: impl Ctx, #[implementations(DVec2, IVec2, UVec2)] vector: Item<T>, axis: Item<XY>) -> Item<f64> {
|
fn extract_xy<T: Into<DVec2>>(_: impl Ctx, #[implementations(DVec2, IVec2, UVec2)] vector: Item<T>, axis: Item<XY>) -> Item<f64> {
|
||||||
let vector = vector.into_element();
|
let vector = vector.into_element();
|
||||||
|
|||||||
@@ -967,7 +967,7 @@ pub async fn flatten_vector<T: IntoGraphicList>(_: impl Ctx, #[implementations(L
|
|||||||
// TODO: we stash the pre-flattened list on the output so `List<Vector>::collect_metadata` can recurse into it,
|
// TODO: we stash the pre-flattened list on the output so `List<Vector>::collect_metadata` can recurse into it,
|
||||||
// TODO: which conflates render output with editor metadata and forces the pre-compensation dance below.
|
// TODO: which conflates render output with editor metadata and forces the pre-compensation dance below.
|
||||||
// TODO: The cleaner fix is to drive each layer's metadata from its own Monitor's captured `(Context, List<Graphic>)`,
|
// TODO: The cleaner fix is to drive each layer's metadata from its own Monitor's captured `(Context, List<Graphic>)`,
|
||||||
// TODO: at which point this attribute (and the equivalents in Boolean Operation, Solidify Stroke, Flatten Path,
|
// TODO: at which point this attribute (and the equivalents in Boolean Operation, Solidify Stroke, Combine Paths,
|
||||||
// TODO: Morph, Rasterize) become unnecessary.
|
// TODO: Morph, Rasterize) become unnecessary.
|
||||||
if !output.is_empty() {
|
if !output.is_empty() {
|
||||||
// Item 0 carries a composed transform inherited from the flattened input, but the merged_layers
|
// Item 0 carries a composed transform inherited from the flattened input, but the merged_layers
|
||||||
|
|||||||
@@ -975,8 +975,8 @@ fn percentage_value(_: impl Ctx, _primary: (), percentage: Item<Percentage>) ->
|
|||||||
|
|
||||||
/// Constructs a two-dimensional vector value which may be set to any XY pair.
|
/// Constructs a two-dimensional vector value which may be set to any XY pair.
|
||||||
#[node_macro::node(category("Value"), name("Vec2 Value"))]
|
#[node_macro::node(category("Value"), name("Vec2 Value"))]
|
||||||
fn vec2_value(_: impl Ctx, _primary: (), x: Item<f64>, y: Item<f64>) -> Item<DVec2> {
|
fn vec2_value(_: impl Ctx, _primary: (), #[name("Vec2")] vec2: Item<DVec2>) -> Item<DVec2> {
|
||||||
Item::new_from_element(DVec2::new(*x.element(), *y.element()))
|
vec2
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a color value which may be set to any color.
|
/// Constructs a color value which may be set to any color.
|
||||||
@@ -1073,6 +1073,23 @@ fn footprint_value(_: impl Ctx, _primary: (), transform: Item<DAffine2>, #[defau
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Composes a vec2 from its X and Y components.
|
||||||
|
///
|
||||||
|
/// The inverse of this node is **Split Vec2**, which decomposes a vec2 back into its X and Y components.
|
||||||
|
#[node_macro::node(category("Math: Vector"), name("Combine Vec2"))]
|
||||||
|
fn combine_vec2(
|
||||||
|
_: impl Ctx,
|
||||||
|
_primary: (),
|
||||||
|
/// The X component of the vec2.
|
||||||
|
#[expose]
|
||||||
|
x: Item<f64>,
|
||||||
|
/// The Y component of the vec2.
|
||||||
|
#[expose]
|
||||||
|
y: Item<f64>,
|
||||||
|
) -> Item<DVec2> {
|
||||||
|
Item::new_from_element(DVec2::new(*x.element(), *y.element()))
|
||||||
|
}
|
||||||
|
|
||||||
/// The dot product operation (`·`) calculates the degree of similarity of a vec2 pair based on their angles and lengths.
|
/// The dot product operation (`·`) calculates the degree of similarity of a vec2 pair based on their angles and lengths.
|
||||||
///
|
///
|
||||||
/// Calculated as `‖a‖‖b‖cos(θ)`, it represents the product of their lengths (`‖a‖‖b‖`) scaled by the alignment of their directions (`cos(θ)`).
|
/// Calculated as `‖a‖‖b‖cos(θ)`, it represents the product of their lengths (`‖a‖‖b‖`) scaled by the alignment of their directions (`cos(θ)`).
|
||||||
@@ -1152,10 +1169,9 @@ fn angle_to<T: ToPosition, U: ToPosition>(
|
|||||||
Item::from_parts(result, attributes)
|
Item::from_parts(result, attributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Rename to "Magnitude"
|
|
||||||
/// The magnitude operator (`‖x‖`) calculates the length of a vec2, which is the distance from the base to the tip of the arrow represented by the vector.
|
/// The magnitude operator (`‖x‖`) calculates the length of a vec2, which is the distance from the base to the tip of the arrow represented by the vector.
|
||||||
#[node_macro::node(category("Math: Vector"))]
|
#[node_macro::node(category("Math: Vector"))]
|
||||||
fn length(_: impl Ctx, vector: Item<DVec2>) -> Item<f64> {
|
fn magnitude(_: impl Ctx, vector: Item<DVec2>) -> Item<f64> {
|
||||||
let (vector, attributes) = vector.into_parts();
|
let (vector, attributes) = vector.into_parts();
|
||||||
|
|
||||||
Item::from_parts(vector.length(), attributes)
|
Item::from_parts(vector.length(), attributes)
|
||||||
@@ -1185,9 +1201,9 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn length_function() {
|
pub fn magnitude_function() {
|
||||||
let vector = Item::new_from_element(DVec2::new(3., 4.));
|
let vector = Item::new_from_element(DVec2::new(3., 4.));
|
||||||
assert_eq!(length((), vector).into_element(), 5.);
|
assert_eq!(magnitude((), vector).into_element(), 5.);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ mod test {
|
|||||||
Item::new_from_element(count),
|
Item::new_from_element(count),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let vector_list = List::new_from_item(vector_nodes::flatten_path(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
let vector_list = List::new_from_item(vector_nodes::combine_paths(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
||||||
let vector = vector_list.element(0).unwrap();
|
let vector = vector_list.element(0).unwrap();
|
||||||
assert_eq!(vector.region_manipulator_groups().count(), 3);
|
assert_eq!(vector.region_manipulator_groups().count(), 3);
|
||||||
for (index, (_, manipulator_groups)) in vector.region_manipulator_groups().enumerate() {
|
for (index, (_, manipulator_groups)) in vector.region_manipulator_groups().enumerate() {
|
||||||
@@ -340,7 +340,7 @@ mod test {
|
|||||||
Item::new_from_element(1),
|
Item::new_from_element(1),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let vector_list = List::new_from_item(vector_nodes::flatten_path(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
let vector_list = List::new_from_item(vector_nodes::combine_paths(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
||||||
let vector = vector_list.element(0).unwrap();
|
let vector = vector_list.element(0).unwrap();
|
||||||
assert_eq!(vector.region_manipulator_groups().count(), 1);
|
assert_eq!(vector.region_manipulator_groups().count(), 1);
|
||||||
|
|
||||||
@@ -362,7 +362,7 @@ mod test {
|
|||||||
Item::new_from_element(count),
|
Item::new_from_element(count),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let vector_list = List::new_from_item(vector_nodes::flatten_path(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
let vector_list = List::new_from_item(vector_nodes::combine_paths(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
||||||
let vector = vector_list.element(0).unwrap();
|
let vector = vector_list.element(0).unwrap();
|
||||||
assert_eq!(vector.region_manipulator_groups().count(), 8);
|
assert_eq!(vector.region_manipulator_groups().count(), 8);
|
||||||
for (index, (_, manipulator_groups)) in vector.region_manipulator_groups().enumerate() {
|
for (index, (_, manipulator_groups)) in vector.region_manipulator_groups().enumerate() {
|
||||||
@@ -381,7 +381,7 @@ mod test {
|
|||||||
Item::new_from_element(8),
|
Item::new_from_element(8),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let vector_list = List::new_from_item(vector_nodes::flatten_path(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
let vector_list = List::new_from_item(vector_nodes::combine_paths(Footprint::default(), List::new_from_element(Graphic::Vector(repeated))).await);
|
||||||
let vector = vector_list.element(0).unwrap();
|
let vector = vector_list.element(0).unwrap();
|
||||||
assert_eq!(vector.region_manipulator_groups().count(), 8);
|
assert_eq!(vector.region_manipulator_groups().count(), 8);
|
||||||
|
|
||||||
|
|||||||
@@ -1560,9 +1560,8 @@ async fn map_points(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: Item<Vec
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Combines every vector path across the input into a single compound path.
|
/// Combines every vector path across the input into a single compound path.
|
||||||
// TODO: Rename to "Combine Paths" with a document migration
|
|
||||||
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
|
#[node_macro::node(category("Vector"), path(graphene_core::vector))]
|
||||||
pub async fn flatten_path<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Vector>)] content: T) -> Item<Vector> {
|
pub async fn combine_paths<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Vector>)] content: T) -> Item<Vector> {
|
||||||
let graphic_list = content.into_graphic_list();
|
let graphic_list = content.into_graphic_list();
|
||||||
let flattened = graphic_list.clone().into_flattened_list::<Vector>();
|
let flattened = graphic_list.clone().into_flattened_list::<Vector>();
|
||||||
|
|
||||||
@@ -3597,12 +3596,12 @@ mod test {
|
|||||||
Item::new_from_element(0),
|
Item::new_from_element(0),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
let flatten_path = List::new_from_item(super::flatten_path(Footprint::default(), List::new_from_element(Graphic::Vector(copy_to_points))).await);
|
let combined = List::new_from_item(super::combine_paths(Footprint::default(), List::new_from_element(Graphic::Vector(copy_to_points))).await);
|
||||||
let flattened_copy_to_points = flatten_path.element(0).unwrap();
|
let combined_copy_to_points = combined.element(0).unwrap();
|
||||||
|
|
||||||
assert_eq!(flattened_copy_to_points.region_manipulator_groups().count(), expected_points.len());
|
assert_eq!(combined_copy_to_points.region_manipulator_groups().count(), expected_points.len());
|
||||||
|
|
||||||
for (index, (_, manipulator_groups)) in flattened_copy_to_points.region_manipulator_groups().enumerate() {
|
for (index, (_, manipulator_groups)) in combined_copy_to_points.region_manipulator_groups().enumerate() {
|
||||||
let offset = expected_points[index];
|
let offset = expected_points[index];
|
||||||
let manipulator_groups_anchors = manipulator_groups.iter().map(|manipulators| manipulators.anchor).collect::<Vec<DVec2>>();
|
let manipulator_groups_anchors = manipulator_groups.iter().map(|manipulators| manipulators.anchor).collect::<Vec<DVec2>>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
Reference in New Issue
Block a user