New nodes: shape/curve primitives (#1389)

* Add new Primitive Shape/Curve Nodes

* Elipse Node and Debug

* N-input Spline node

* Debuging

* Debug

* fmt

* remov debug

* Changes from code review

* Debug: Empty Spline Input

* Changes from code review

* Fix spelling of ellipse

* Rename polygon to regular polygon

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Ezbaze
2023-08-27 22:22:09 +01:00
committed by GitHub
parent 9d27bf49cf
commit 226b96260c
7 changed files with 263 additions and 15 deletions

View File

@@ -6,19 +6,94 @@ use bezier_rs::Subpath;
use glam::DVec2;
pub struct UnitCircleGenerator;
#[derive(Debug, Clone, Copy)]
pub struct CircleGenerator<Radius> {
radius: Radius,
}
#[node_macro::node_fn(UnitCircleGenerator)]
fn unit_circle(_input: ()) -> VectorData {
super::VectorData::from_subpath(Subpath::new_ellipse(DVec2::ZERO, DVec2::ONE))
#[node_macro::node_fn(CircleGenerator)]
fn circle_generator(_input: (), radius: f32) -> VectorData {
let radius: f64 = radius.into();
super::VectorData::from_subpath(Subpath::new_ellipse(DVec2::splat(-radius), DVec2::splat(radius)))
}
#[derive(Debug, Clone, Copy)]
pub struct UnitSquareGenerator;
pub struct EllipseGenerator<RadiusX, RadiusY> {
radius_x: RadiusX,
radius_y: RadiusY,
}
#[node_macro::node_fn(UnitSquareGenerator)]
fn unit_square(_input: ()) -> VectorData {
super::VectorData::from_subpaths(vec![Subpath::new_ellipse(DVec2::ZERO, DVec2::ONE)])
#[node_macro::node_fn(EllipseGenerator)]
fn ellipse_generator(_input: (), radius_x: f32, radius_y: f32) -> VectorData {
let radius = DVec2::new(radius_x as f64, radius_y as f64);
let corner1 = -radius;
let corner2 = radius;
super::VectorData::from_subpath(Subpath::new_ellipse(corner1, corner2))
}
#[derive(Debug, Clone, Copy)]
pub struct RectangleGenerator<SizeX, SizeY> {
size_x: SizeX,
size_y: SizeY,
}
#[node_macro::node_fn(RectangleGenerator)]
fn square_generator(_input: (), size_x: f32, size_y: f32) -> VectorData {
let size = DVec2::new(size_x as f64, size_y as f64);
let corner1 = -size / 2.;
let corner2 = size / 2.;
super::VectorData::from_subpaths(vec![Subpath::new_rect(corner1, corner2)])
}
#[derive(Debug, Clone, Copy)]
pub struct RegularPolygonGenerator<Points, Radius> {
points: Points,
radius: Radius,
}
#[node_macro::node_fn(RegularPolygonGenerator)]
fn regular_polygon_generator(_input: (), points: u32, radius: f32) -> VectorData {
let points = points.into();
let radius: f64 = (radius * 2.).into();
super::VectorData::from_subpath(Subpath::new_regular_polygon(DVec2::splat(-radius), points, radius))
}
#[derive(Debug, Clone, Copy)]
pub struct StarGenerator<Points, Radius, InnerRadius> {
points: Points,
radius: Radius,
inner_radius: InnerRadius,
}
#[node_macro::node_fn(StarGenerator)]
fn star_generator(_input: (), points: u32, radius: f32, inner_radius: f32) -> VectorData {
let points = points.into();
let diameter: f64 = (radius * 2.).into();
let inner_diameter = (inner_radius * 2.).into();
super::VectorData::from_subpath(Subpath::new_star_polygon(DVec2::splat(-diameter), points, diameter, inner_diameter))
}
#[derive(Debug, Clone, Copy)]
pub struct LineGenerator<Pos1, Pos2> {
pos_1: Pos1,
pos_2: Pos2,
}
#[node_macro::node_fn(LineGenerator)]
fn line_generator(_input: (), pos_1: DVec2, pos_2: DVec2) -> VectorData {
super::VectorData::from_subpaths(vec![Subpath::new_line(pos_1, pos_2)])
}
#[derive(Debug, Clone, Copy)]
pub struct SplineGenerator<Positions> {
positions: Positions,
}
#[node_macro::node_fn(SplineGenerator)]
fn spline_generator(_input: (), positions: Vec<DVec2>) -> VectorData {
super::VectorData::from_subpaths(vec![Subpath::new_cubic_spline(positions)])
}
// TODO(TrueDoctor): I removed the Arc requirement we should think about when it makes sense to use it vs making a generic value node

View File

@@ -42,6 +42,7 @@ pub enum TaggedValue {
Fill(graphene_core::vector::style::Fill),
Stroke(graphene_core::vector::style::Stroke),
VecF32(Vec<f32>),
VecDVec2(Vec<DVec2>),
RedGreenBlue(graphene_core::raster::RedGreenBlue),
NoiseType(graphene_core::raster::NoiseType),
RelativeAbsolute(graphene_core::raster::RelativeAbsolute),
@@ -100,6 +101,7 @@ impl Hash for TaggedValue {
Self::Fill(fill) => fill.hash(state),
Self::Stroke(stroke) => stroke.hash(state),
Self::VecF32(vec_f32) => vec_f32.iter().for_each(|val| val.to_bits().hash(state)),
Self::VecDVec2(vec_dvec2) => vec_dvec2.iter().for_each(|val| val.to_array().iter().for_each(|x| x.to_bits().hash(state))),
Self::RedGreenBlue(red_green_blue) => red_green_blue.hash(state),
Self::NoiseType(noise_type) => noise_type.hash(state),
Self::RelativeAbsolute(relative_absolute) => relative_absolute.hash(state),
@@ -165,6 +167,7 @@ impl<'a> TaggedValue {
TaggedValue::Fill(x) => Box::new(x),
TaggedValue::Stroke(x) => Box::new(x),
TaggedValue::VecF32(x) => Box::new(x),
TaggedValue::VecDVec2(x) => Box::new(x),
TaggedValue::RedGreenBlue(x) => Box::new(x),
TaggedValue::NoiseType(x) => Box::new(x),
TaggedValue::RelativeAbsolute(x) => Box::new(x),
@@ -233,6 +236,7 @@ impl<'a> TaggedValue {
TaggedValue::Fill(_) => concrete!(graphene_core::vector::style::Fill),
TaggedValue::Stroke(_) => concrete!(graphene_core::vector::style::Stroke),
TaggedValue::VecF32(_) => concrete!(Vec<f32>),
TaggedValue::VecDVec2(_) => concrete!(Vec<DVec2>),
TaggedValue::RedGreenBlue(_) => concrete!(graphene_core::raster::RedGreenBlue),
TaggedValue::NoiseType(_) => concrete!(graphene_core::raster::NoiseType),
TaggedValue::RelativeAbsolute(_) => concrete!(graphene_core::raster::RelativeAbsolute),
@@ -288,6 +292,7 @@ impl<'a> TaggedValue {
x if x == TypeId::of::<graphene_core::vector::style::Fill>() => Ok(TaggedValue::Fill(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::vector::style::Stroke>() => Ok(TaggedValue::Stroke(*downcast(input).unwrap())),
x if x == TypeId::of::<Vec<f32>>() => Ok(TaggedValue::VecF32(*downcast(input).unwrap())),
x if x == TypeId::of::<Vec<DVec2>>() => Ok(TaggedValue::VecDVec2(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::raster::RedGreenBlue>() => Ok(TaggedValue::RedGreenBlue(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::raster::NoiseType>() => Ok(TaggedValue::NoiseType(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::raster::RelativeAbsolute>() => Ok(TaggedValue::RelativeAbsolute(*downcast(input).unwrap())),

View File

@@ -630,7 +630,13 @@ 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::generator_nodes::UnitCircleGenerator, input: (), 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]),
register_node!(graphene_core::vector::generator_nodes::RegularPolygonGenerator<_, _>, input: (), params: [u32, f32]),
register_node!(graphene_core::vector::generator_nodes::StarGenerator<_, _, _>, input: (), params: [u32, f32, f32]),
register_node!(graphene_core::vector::generator_nodes::LineGenerator<_, _>, input: (), params: [DVec2, DVec2]),
register_node!(graphene_core::vector::generator_nodes::SplineGenerator<_>, input: (), params: [Vec<DVec2>]),
register_node!(
graphene_core::vector::generator_nodes::PathGenerator<_>,
input: Vec<graphene_core::vector::bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>,