mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-24 12:38:11 +08:00
Add path-bool library (#1952)
* Add path-bool library * Cleanup code * Cargo format * Integrate boolean ops into graphite * Add test for editor crash * Fix edge sort floating point instability * Add unit test for red-dress failure * Backport tests and aux functions * Use curvature based sorting * Convert linear cubic splines to line segments * Deduplicate reversed path segments * Fix epsilon for empty segments * Remove parameter based intersection pruning * Add support for reversed paths * Add benchmark infrastructure * Add intersection benchmark * Add recursion bound * Implement support for overlapping path segments * Remove rouge prinln * Fix sorting for bezier segments with one control point at the start of the segment * Cleanup log statements * Directly translate graphite paths to Path segments * Round data before passing it to path_bool * Fix flag_faces traversal order * Add test for white dots in bottom right of painted dreams * Make rounding configurable * Update demo artwork to remove manual path modifications * Convert from path segments to manipulator groups directly * Remove dead code * Fix clippy lints * Replace functions in path segment with methods and add documentation * Add more documentation * Close subpaths * Reorganize files and add README.md * Add license information * Code review * Fix license info * Adopt new node macro and fix demo artwork * Close subpaths with Z --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
2febbfd698
commit
3eb98c6d6d
@@ -145,15 +145,15 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
}
|
||||
|
||||
pub fn insert_vector_data(&mut self, subpaths: Vec<Subpath<PointId>>, layer: LayerNodeIdentifier) {
|
||||
let shape = resolve_document_node_type("Shape")
|
||||
.expect("Shape node does not exist")
|
||||
let path = resolve_document_node_type("Path")
|
||||
.expect("Path node does not exist")
|
||||
.node_template_input_override([Some(NodeInput::value(TaggedValue::Subpaths(subpaths), false))]);
|
||||
let transform = resolve_document_node_type("Transform").expect("Transform node does not exist").default_node_template();
|
||||
let fill = resolve_document_node_type("Fill").expect("Fill node does not exist").default_node_template();
|
||||
let stroke = resolve_document_node_type("Stroke").expect("Stroke node does not exist").default_node_template();
|
||||
|
||||
let shape_id = NodeId(generate_uuid());
|
||||
self.network_interface.insert_node(shape_id, shape, &[]);
|
||||
self.network_interface.insert_node(shape_id, path, &[]);
|
||||
self.network_interface.move_node_to_chain_start(&shape_id, layer, &[]);
|
||||
|
||||
let transform_id = NodeId(generate_uuid());
|
||||
|
||||
@@ -2159,12 +2159,13 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::network(concrete!(VectorData), 0), NodeInput::network(concrete!(vector::style::Fill), 1)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::vector::BooleanOperationNode")),
|
||||
manual_composition: Some(generic!(T)),
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::node(NodeId(0), 0)],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::memo::ImpureMemoNode")),
|
||||
manual_composition: Some(concrete!(Footprint)),
|
||||
manual_composition: Some(generic!(T)),
|
||||
..Default::default()
|
||||
},
|
||||
]
|
||||
|
||||
@@ -2268,17 +2268,10 @@ pub(crate) fn generate_node_properties(document_node: &DocumentNode, node_id: No
|
||||
}
|
||||
|
||||
pub(crate) fn boolean_operation_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let group_of_paths_index = 0;
|
||||
let operation_index = 1;
|
||||
|
||||
let mut widgets = start_widgets(document_node, node_id, group_of_paths_index, "Group of Paths", FrontendGraphDataType::Graphic, true);
|
||||
|
||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
widgets.push(TextLabel::new("The output of a layer stack, which contains all elements to operate on").widget_holder());
|
||||
|
||||
let operation = boolean_operation_radio_buttons(document_node, node_id, operation_index, "Operation", true);
|
||||
|
||||
vec![LayoutGroup::Row { widgets }, operation]
|
||||
vec![operation]
|
||||
}
|
||||
|
||||
pub(crate) fn copy_to_points_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
|
||||
Reference in New Issue
Block a user