mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 07:48:12 +08:00
Add Area and Centroid nodes (#1749)
* initial attempt for area node * allow node preview for more types * make AreaNode sync and add CentroidNode * cargo fmt * preview of DVec2 * make the nodes async again * use segment domain instead of region domain * modify the check for linearity * create a limit for area in centroid calculation * cargo fmt * reverse unnecessary changes * add threshold to area calculation too. * handle zero area edge case * add todo comment * implement 1D centroid and use it as fallback * formatting floats to skip last zero * add Centroid Type radio button to Centroid Node * rename docs to use area and perimeter centroid * add web demos for perimeter centroid * add tests for perimeter centroid * add fallback to use average of points * Fix for broken area * missing fixes * Code review and rename Perimeter Centroid to Length Centroid * Use dummy footprint in Area and Centroid nodes * add doc and todo to clarify when `is_linear` fails * use epsilon instead of zero --------- Co-authored-by: 0hypercube <0hypercube@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com> Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
co-authored by
0hypercube
Keavon Chambers
Dennis Kobert
parent
4587457bfa
commit
5a1c171fc3
@@ -2598,6 +2598,29 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||
properties: node_properties::node_no_properties,
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeDefinition {
|
||||
name: "Area",
|
||||
category: "Vector",
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::vector::AreaNode<_>"),
|
||||
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
|
||||
properties: node_properties::node_no_properties,
|
||||
manual_composition: Some(concrete!(())),
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeDefinition {
|
||||
name: "Centroid",
|
||||
category: "Vector",
|
||||
implementation: DocumentNodeImplementation::proto("graphene_core::vector::CentroidNode<_, _>"),
|
||||
inputs: vec![
|
||||
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
|
||||
DocumentInputType::value("Centroid Type", TaggedValue::CentroidType(graphene_core::vector::misc::CentroidType::Area), false),
|
||||
],
|
||||
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Vector)],
|
||||
properties: node_properties::centroid_properties,
|
||||
manual_composition: Some(concrete!(())),
|
||||
..Default::default()
|
||||
},
|
||||
DocumentNodeDefinition {
|
||||
name: "Morph",
|
||||
category: "Vector",
|
||||
|
||||
@@ -14,6 +14,7 @@ use graphene_core::raster::{
|
||||
SelectiveColorChoice,
|
||||
};
|
||||
use graphene_core::text::Font;
|
||||
use graphene_core::vector::misc::CentroidType;
|
||||
use graphene_core::vector::style::{FillType, GradientType, LineCap, LineJoin};
|
||||
|
||||
use glam::{DVec2, IVec2, UVec2};
|
||||
@@ -882,6 +883,39 @@ fn curves_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, na
|
||||
LayoutGroup::Row { widgets }
|
||||
}
|
||||
|
||||
fn centroid_widget(document_node: &DocumentNode, node_id: NodeId, index: usize) -> LayoutGroup {
|
||||
let mut widgets = start_widgets(document_node, node_id, index, "Centroid Type", FrontendGraphDataType::General, true);
|
||||
if let &NodeInput::Value {
|
||||
tagged_value: TaggedValue::CentroidType(centroid_type),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
let entries = vec![
|
||||
RadioEntryData::new("area")
|
||||
.label("Area")
|
||||
.tooltip("Center of mass for the interior area of the shape")
|
||||
.on_update(update_value(move |_| TaggedValue::CentroidType(CentroidType::Area), node_id, index))
|
||||
.on_commit(commit_value),
|
||||
RadioEntryData::new("length")
|
||||
.label("Length")
|
||||
.tooltip("Center of mass for the perimeter arc length of the shape")
|
||||
.on_update(update_value(move |_| TaggedValue::CentroidType(CentroidType::Length), node_id, index))
|
||||
.on_commit(commit_value),
|
||||
];
|
||||
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||
RadioInput::new(entries)
|
||||
.selected_index(match centroid_type {
|
||||
CentroidType::Area => Some(0),
|
||||
CentroidType::Length => Some(1),
|
||||
})
|
||||
.widget_holder(),
|
||||
]);
|
||||
}
|
||||
LayoutGroup::Row { widgets }
|
||||
}
|
||||
|
||||
pub fn levels_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let input_shadows = number_widget(document_node, node_id, 1, "Shadows", NumberInput::default().mode_range().min(0.).max(100.).unit("%"), true);
|
||||
let input_midtones = number_widget(document_node, node_id, 2, "Midtones", NumberInput::default().mode_range().min(0.).max(100.).unit("%"), true);
|
||||
@@ -2438,3 +2472,9 @@ pub fn image_color_palette(document_node: &DocumentNode, node_id: NodeId, _conte
|
||||
|
||||
vec![LayoutGroup::Row { widgets: size }]
|
||||
}
|
||||
|
||||
pub fn centroid_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||
let centroid_type = centroid_widget(document_node, node_id, 1);
|
||||
|
||||
vec![centroid_type]
|
||||
}
|
||||
|
||||
@@ -638,6 +638,7 @@ impl NodeGraphExecutor {
|
||||
TaggedValue::Bool(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
TaggedValue::String(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
TaggedValue::F64(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
TaggedValue::DVec2(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
TaggedValue::OptionalColor(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
TaggedValue::VectorData(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
TaggedValue::GraphicGroup(render_object) => Self::debug_render(render_object, transform, responses),
|
||||
|
||||
Reference in New Issue
Block a user