Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
40b5661
Create node (no implementation)
Chase-Percy May 20, 2023
cc4fce2
Resampling - WIP
Chase-Percy May 21, 2023
2086b28
use bezier::from_linear_dvec2
Chase-Percy May 21, 2023
13a97cd
Use from anchors instead of Bezier
Chase-Percy May 21, 2023
85579a3
Tidy up anchor collection & subpath creation
Chase-Percy May 21, 2023
d40f084
Add Spline from Points node (not implemented)
Chase-Percy May 22, 2023
a551552
Add spline from points node implementation
Chase-Percy May 22, 2023
6a3ab87
Update resampling
Chase-Percy May 25, 2023
9f6d0bd
Update minimum density 0.01 -> 1.0
Chase-Percy May 25, 2023
069473a
Add a way to create a custom vector network
Chase-Percy May 29, 2023
ecd0bae
Add spline from points node to spline tool
Chase-Percy May 29, 2023
e57197d
Fix crash when no points
Chase-Percy May 29, 2023
c9dd501
Add anchor method to subpath
Chase-Percy May 30, 2023
492d186
Exact start and end point
0HyperCube Aug 20, 2023
4666e83
Fix compile errors from rebase
0HyperCube Aug 20, 2023
d8cdd81
Fix spline tool
0HyperCube Aug 25, 2023
dcb248d
Rename 'Density' to 'Spacing'
Keavon Aug 27, 2023
c9cfc00
Fix transforms
0HyperCube Aug 30, 2023
8ecef0d
Merge branch 'main' into Resample-Curve-Node
0HyperCube Aug 30, 2023
d0448f3
Only close subpaths with >1 anchor
0HyperCube Aug 30, 2023
d920452
Fix compile
0HyperCube Aug 30, 2023
8be2681
Fix compile error
0HyperCube Aug 30, 2023
b2fb370
Fix from points with many subpaths
0HyperCube Aug 30, 2023
6ef8abd
Fix new_cubic_spline crash with one point
0HyperCube Aug 30, 2023
14325c2
Rename to resample as polyline
0HyperCube Aug 30, 2023
2049783
Fix div zero
0HyperCube Aug 30, 2023
12ec0d0
Fix missing file
0HyperCube Aug 30, 2023
4354b89
Fix resample
0HyperCube Aug 30, 2023
0eb363a
Rename to resample points
0HyperCube Aug 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,27 @@ fn static_nodes() -> Vec<DocumentNodeType> {
properties: node_properties::circular_repeat_properties,
..Default::default()
},
DocumentNodeType {
name: "Resample Points",
category: "Vector",
identifier: NodeImplementation::proto("graphene_core::vector::ResamplePoints<_>"),
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Spacing", TaggedValue::F64(100.), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::resample_points_properties,
..Default::default()
},
DocumentNodeType {
name: "Spline from Points",
category: "Vector",
identifier: NodeImplementation::proto("graphene_core::vector::SplineFromPointsNode"),
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::no_properties,
..Default::default()
},
DocumentNodeType {
name: "Image Segmentation",
category: "Image Adjustments",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,12 @@ pub fn circular_repeat_properties(document_node: &DocumentNode, node_id: NodeId,
vec![LayoutGroup::Row { widgets: angle_offset }, LayoutGroup::Row { widgets: radius }, LayoutGroup::Row { widgets: count }]
}

pub fn resample_points_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let spacing = number_widget(document_node, node_id, 1, "Spacing", NumberInput::default().min(1.), true);

vec![LayoutGroup::Row { widgets: spacing }]
}

/// Fill Node Widgets LayoutGroup
pub fn fill_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let fill_type_index = 1;
Expand Down
7 changes: 7 additions & 0 deletions libraries/bezier-rs/src/bezier/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ use super::*;
impl Bezier {
/// Convert a euclidean distance ratio along the `Bezier` curve to a parametric `t`-value.
pub fn euclidean_to_parametric(&self, ratio: f64, error: f64) -> f64 {
if ratio < error {
return 0.;
}
if 1. - ratio < error {
return 1.;
}

let mut low = 0.;
let mut mid = 0.;
let mut high = 1.;
Expand Down
7 changes: 6 additions & 1 deletion libraries/bezier-rs/src/subpath/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ impl<ManipulatorGroupId: crate::Identifier> Subpath<ManipulatorGroupId> {
&self.manipulator_groups
}

/// Returns a vector of all the anchors (DVec2) for this `Subpath`.
pub fn anchors(&self) -> Vec<DVec2> {
self.manipulator_groups().iter().map(|group| group.anchor).collect()
}

/// Returns if the Subpath is equivalent to a single point.
pub fn is_point(&self) -> bool {
if self.is_empty() {
Expand Down Expand Up @@ -254,7 +259,7 @@ impl<ManipulatorGroupId: crate::Identifier> Subpath<ManipulatorGroupId> {
/// Construct a cubic spline from a list of points.
/// Based on <https://mathworld.wolfram.com/CubicSpline.html>.
pub fn new_cubic_spline(points: Vec<DVec2>) -> Self {
if points.is_empty() {
if points.len() < 2 {
return Self::new(Vec::new(), false);
}

Expand Down
12 changes: 12 additions & 0 deletions libraries/bezier-rs/src/subpath/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,16 @@ mod tests {
assert_eq!(closed_subpath.t_value_to_parametric(SubpathTValue::GlobalParametric(0.)), (0, 0.));
assert_eq!(closed_subpath.t_value_to_parametric(SubpathTValue::GlobalParametric(1.)), (4, 1.));
}

#[test]
fn exact_start_end() {
let start = DVec2::new(20., 30.);
let end = DVec2::new(60., 45.);
let handle = DVec2::new(75., 85.);

let subpath: Subpath<EmptyId> = Subpath::from_bezier(&Bezier::from_quadratic_dvec2(start, handle, end));

assert_eq!(subpath.evaluate(SubpathTValue::GlobalEuclidean(0.0)), start);
assert_eq!(subpath.evaluate(SubpathTValue::GlobalEuclidean(1.0)), end);
}
}
42 changes: 40 additions & 2 deletions node-graph/gcore/src/vector/vector_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use super::style::{Fill, FillType, Gradient, GradientType, Stroke};
use super::VectorData;
use crate::{Color, Node};

use bezier_rs::Subpath;

use bezier_rs::{Subpath, SubpathTValue};
use glam::{DAffine2, DVec2};
use num_traits::Zero;

#[derive(Debug, Clone, Copy)]
pub struct SetFillNode<FillType, SolidColor, GradientType, Start, End, Transform, Positions> {
Expand Down Expand Up @@ -147,3 +147,41 @@ fn generate_bounding_box(vector_data: VectorData) -> VectorData {
vector_data.transform.transform_point2(bounding_box[1]),
)])
}

#[derive(Debug, Clone, Copy)]
pub struct ResamplePoints<Spacing> {
spacing: Spacing,
}

#[node_macro::node_fn(ResamplePoints)]
fn resample_points(mut vector_data: VectorData, spacing: f64) -> VectorData {
for subpath in &mut vector_data.subpaths {
if subpath.is_empty() || spacing.is_zero() || !spacing.is_finite() {
continue;
}

subpath.apply_transform(vector_data.transform);
let length = subpath.length(None);
let rounded_count = (length / spacing).round();

if rounded_count >= 1. {
let new_anchors = (0..=rounded_count as usize).map(|c| subpath.evaluate(SubpathTValue::GlobalEuclidean(c as f64 / rounded_count)));
*subpath = Subpath::from_anchors(new_anchors, subpath.closed() && rounded_count as usize > 1);
}

subpath.apply_transform(vector_data.transform.inverse());
}
vector_data
}

#[derive(Debug, Clone, Copy)]
pub struct SplineFromPointsNode {}

#[node_macro::node_fn(SplineFromPointsNode)]
fn spline_from_points(mut vector_data: VectorData) -> VectorData {
for subpath in &mut vector_data.subpaths {
*subpath = Subpath::new_cubic_spline(subpath.anchors());
}

vector_data
}
2 changes: 2 additions & 0 deletions node-graph/interpreted-executor/src/node_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
register_node!(graphene_core::vector::RepeatNode<_, _>, input: VectorData, params: [DVec2, u32]),
register_node!(graphene_core::vector::BoundingBoxNode, input: VectorData, params: []),
register_node!(graphene_core::vector::CircularRepeatNode<_, _, _>, input: VectorData, params: [f32, f32, u32]),
register_node!(graphene_core::vector::ResamplePoints<_>, input: VectorData, params: [f64]),
register_node!(graphene_core::vector::SplineFromPointsNode, input: VectorData, params: []),
register_node!(graphene_core::vector::generator_nodes::CircleGenerator<_>, input: (), params: [f32]),
register_node!(graphene_core::vector::generator_nodes::EllipseGenerator<_, _>, input: (), params: [f32, f32]),
register_node!(graphene_core::vector::generator_nodes::RectangleGenerator<_, _>, input: (), params: [f32, f32]),
Expand Down