Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -2235,34 +2235,34 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
properties: node_properties::stroke_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Bounding Box",
category: "Vector",
implementation: NodeImplementation::proto("graphene_core::vector::BoundingBoxNode"),
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::node_no_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Repeat",
category: "Vector",
implementation: NodeImplementation::proto("graphene_core::vector::RepeatNode<_, _>"),
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Instance", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Direction", TaggedValue::DVec2((100., 0.).into()), false),
DocumentInputType::value("Count", TaggedValue::U32(10), false),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::repeat_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Bounding Box",
category: "Vector",
implementation: NodeImplementation::proto("graphene_core::vector::BoundingBoxNode"),
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::node_no_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Circular Repeat",
category: "Vector",
implementation: NodeImplementation::proto("graphene_core::vector::CircularRepeatNode<_, _, _>"),
inputs: vec![
DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Instance", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Angle Offset", TaggedValue::F32(0.), false),
DocumentInputType::value("Radius", TaggedValue::F32(5.), false),
DocumentInputType::value("Count", TaggedValue::U32(10), false),
Expand All @@ -2271,6 +2271,18 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
properties: node_properties::circular_repeat_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Copy to Points",
category: "Vector",
implementation: NodeImplementation::proto("graphene_core::vector::CopyToPoints<_>"),
inputs: vec![
DocumentInputType::value("Points", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
DocumentInputType::value("Instance", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true),
],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::copy_to_points_properties,
..Default::default()
},
DocumentNodeDefinition {
name: "Resample Points",
category: "Vector",
Expand All @@ -2284,9 +2296,9 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
},
DocumentNodeDefinition {
name: "Spline from Points",
name: "Splines from Points",
category: "Vector",
implementation: NodeImplementation::proto("graphene_core::vector::SplineFromPointsNode"),
implementation: NodeImplementation::proto("graphene_core::vector::SplinesFromPointsNode"),
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
properties: node_properties::node_no_properties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,14 @@ fn font_inputs(document_node: &DocumentNode, node_id: NodeId, index: usize, name
(first_widgets, second_widgets)
}

fn vector_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> Vec<WidgetHolder> {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Vector, blank_assist);

widgets.push(TextLabel::new("Vector data must be supplied through the graph").widget_holder());

widgets
}

fn number_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, number_props: NumberInput, blank_assist: bool) -> Vec<WidgetHolder> {
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Number, blank_assist);

Expand Down Expand Up @@ -2107,6 +2115,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 copy_to_points_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let instance = vector_widget(document_node, node_id, 1, "Spacing", true);

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

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);

Expand Down
46 changes: 36 additions & 10 deletions node-graph/gcore/src/vector/vector_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,18 @@ pub struct CircularRepeatNode<AngleOffset, Radius, Count> {

#[node_macro::node_fn(CircularRepeatNode)]
fn circular_repeat_vector_data(mut vector_data: VectorData, angle_offset: f32, radius: f32, count: u32) -> VectorData {
// repeat the vector data
let VectorData { subpaths, transform, .. } = &vector_data;

let mut new_subpaths: Vec<Subpath<_>> = Vec::with_capacity(subpaths.len() * count as usize);
let mut new_subpaths: Vec<Subpath<_>> = Vec::with_capacity(vector_data.subpaths.len() * count as usize);

let bounding_box = vector_data.bounding_box().unwrap();
let center = (bounding_box[0] + bounding_box[1]) / 2.;

//let inverse = transform.inverse();
//let radius_transform = DAffine2::from_translation(DVec2::new(0., radius as f64));
let base_transform = DVec2::new(0., radius as f64) - center;

for i in 0..count {
let angle = (2. * std::f64::consts::PI / count as f64) * i as f64 + angle_offset.to_radians() as f64;
let rotation = DAffine2::from_angle(angle);
let transform = DAffine2::from_translation(center) * rotation * DAffine2::from_translation(base_transform);
for mut subpath in subpaths.clone() {
for mut subpath in vector_data.subpaths.clone() {
subpath.apply_transform(transform);
new_subpaths.push(subpath);
}
Expand All @@ -148,6 +143,37 @@ fn generate_bounding_box(vector_data: VectorData) -> VectorData {
)])
}

#[derive(Debug, Clone, Copy)]
pub struct CopyToPoints<Instance> {
instance: Instance,
}

#[node_macro::node_fn(CopyToPoints)]
fn copy_to_points(points: VectorData, instance: VectorData) -> VectorData {
let points_list = points.subpaths.iter().flat_map(|s| s.anchors());

let instance_bounding_box = instance.bounding_box().unwrap_or_default();
let instance_center = DAffine2::from_translation(-0.5 * (instance_bounding_box[0] + instance_bounding_box[1]));

let mut instanced_subpaths: Vec<Subpath<_>> = Vec::new();
for point in points_list {
let transform = DAffine2::from_translation(point) * instance_center;

for mut subpath in instance.subpaths.clone() {
subpath.apply_transform(transform);
instanced_subpaths.push(subpath);
}
}

VectorData {
subpaths: instanced_subpaths,
transform: DAffine2::IDENTITY,
style: instance.style,
alpha_blending: instance.alpha_blending,
mirror_angle: instance.mirror_angle,
}
}

#[derive(Debug, Clone, Copy)]
pub struct ResamplePoints<Spacing> {
spacing: Spacing,
Expand Down Expand Up @@ -175,10 +201,10 @@ fn resample_points(mut vector_data: VectorData, spacing: f64) -> VectorData {
}

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

#[node_macro::node_fn(SplineFromPointsNode)]
fn spline_from_points(mut vector_data: VectorData) -> VectorData {
#[node_macro::node_fn(SplinesFromPointsNode)]
fn splines_from_points(mut vector_data: VectorData) -> VectorData {
for subpath in &mut vector_data.subpaths {
*subpath = Subpath::new_cubic_spline(subpath.anchors());
}
Expand Down
3 changes: 2 additions & 1 deletion node-graph/interpreted-executor/src/node_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,8 +837,9 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
)],
register_node!(graphene_std::raster::SampleNode<_>, input: Footprint, params: [ImageFrame<Color>]),
register_node!(graphene_std::raster::MandelbrotNode, input: Footprint, params: []),
register_node!(graphene_core::vector::CopyToPoints<_>, input: VectorData, params: [VectorData]),
register_node!(graphene_core::vector::ResamplePoints<_>, input: VectorData, params: [f64]),
register_node!(graphene_core::vector::SplineFromPointsNode, input: VectorData, params: []),
register_node!(graphene_core::vector::SplinesFromPointsNode, 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