New node: Copy to Points (#1513)
* New node: Copy to Points * Remove dead code
This commit is contained in:
parent
9f0ea35d9b
commit
9e06e70aa2
|
|
@ -2235,19 +2235,6 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||||
properties: node_properties::stroke_properties,
|
properties: node_properties::stroke_properties,
|
||||||
..Default::default()
|
..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("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 {
|
DocumentNodeDefinition {
|
||||||
name: "Bounding Box",
|
name: "Bounding Box",
|
||||||
category: "Vector",
|
category: "Vector",
|
||||||
|
|
@ -2257,12 +2244,25 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||||
properties: node_properties::node_no_properties,
|
properties: node_properties::node_no_properties,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
DocumentNodeDefinition {
|
||||||
|
name: "Repeat",
|
||||||
|
category: "Vector",
|
||||||
|
implementation: NodeImplementation::proto("graphene_core::vector::RepeatNode<_, _>"),
|
||||||
|
inputs: vec![
|
||||||
|
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 {
|
DocumentNodeDefinition {
|
||||||
name: "Circular Repeat",
|
name: "Circular Repeat",
|
||||||
category: "Vector",
|
category: "Vector",
|
||||||
implementation: NodeImplementation::proto("graphene_core::vector::CircularRepeatNode<_, _, _>"),
|
implementation: NodeImplementation::proto("graphene_core::vector::CircularRepeatNode<_, _, _>"),
|
||||||
inputs: vec![
|
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("Angle Offset", TaggedValue::F32(0.), false),
|
||||||
DocumentInputType::value("Radius", TaggedValue::F32(5.), false),
|
DocumentInputType::value("Radius", TaggedValue::F32(5.), false),
|
||||||
DocumentInputType::value("Count", TaggedValue::U32(10), false),
|
DocumentInputType::value("Count", TaggedValue::U32(10), false),
|
||||||
|
|
@ -2271,6 +2271,18 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||||
properties: node_properties::circular_repeat_properties,
|
properties: node_properties::circular_repeat_properties,
|
||||||
..Default::default()
|
..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 {
|
DocumentNodeDefinition {
|
||||||
name: "Resample Points",
|
name: "Resample Points",
|
||||||
category: "Vector",
|
category: "Vector",
|
||||||
|
|
@ -2284,9 +2296,9 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DocumentNodeDefinition {
|
DocumentNodeDefinition {
|
||||||
name: "Spline from Points",
|
name: "Splines from Points",
|
||||||
category: "Vector",
|
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)],
|
inputs: vec![DocumentInputType::value("Vector Data", TaggedValue::VectorData(graphene_core::vector::VectorData::empty()), true)],
|
||||||
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
|
outputs: vec![DocumentOutputType::new("Vector", FrontendGraphDataType::Subpath)],
|
||||||
properties: node_properties::node_no_properties,
|
properties: node_properties::node_no_properties,
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,14 @@ fn font_inputs(document_node: &DocumentNode, node_id: NodeId, index: usize, name
|
||||||
(first_widgets, second_widgets)
|
(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> {
|
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);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::Number, blank_assist);
|
||||||
|
|
||||||
|
|
@ -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 }]
|
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> {
|
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);
|
let spacing = number_widget(document_node, node_id, 1, "Spacing", NumberInput::default().min(1.), true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,23 +110,18 @@ pub struct CircularRepeatNode<AngleOffset, Radius, Count> {
|
||||||
|
|
||||||
#[node_macro::node_fn(CircularRepeatNode)]
|
#[node_macro::node_fn(CircularRepeatNode)]
|
||||||
fn circular_repeat_vector_data(mut vector_data: VectorData, angle_offset: f32, radius: f32, count: u32) -> VectorData {
|
fn circular_repeat_vector_data(mut vector_data: VectorData, angle_offset: f32, radius: f32, count: u32) -> VectorData {
|
||||||
// repeat the vector data
|
let mut new_subpaths: Vec<Subpath<_>> = Vec::with_capacity(vector_data.subpaths.len() * count as usize);
|
||||||
let VectorData { subpaths, transform, .. } = &vector_data;
|
|
||||||
|
|
||||||
let mut new_subpaths: Vec<Subpath<_>> = Vec::with_capacity(subpaths.len() * count as usize);
|
|
||||||
|
|
||||||
let bounding_box = vector_data.bounding_box().unwrap();
|
let bounding_box = vector_data.bounding_box().unwrap();
|
||||||
let center = (bounding_box[0] + bounding_box[1]) / 2.;
|
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;
|
let base_transform = DVec2::new(0., radius as f64) - center;
|
||||||
|
|
||||||
for i in 0..count {
|
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 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 rotation = DAffine2::from_angle(angle);
|
||||||
let transform = DAffine2::from_translation(center) * rotation * DAffine2::from_translation(base_transform);
|
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);
|
subpath.apply_transform(transform);
|
||||||
new_subpaths.push(subpath);
|
new_subpaths.push(subpath);
|
||||||
}
|
}
|
||||||
|
|
@ -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)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct ResamplePoints<Spacing> {
|
pub struct ResamplePoints<Spacing> {
|
||||||
spacing: Spacing,
|
spacing: Spacing,
|
||||||
|
|
@ -175,10 +201,10 @@ fn resample_points(mut vector_data: VectorData, spacing: f64) -> VectorData {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct SplineFromPointsNode {}
|
pub struct SplinesFromPointsNode {}
|
||||||
|
|
||||||
#[node_macro::node_fn(SplineFromPointsNode)]
|
#[node_macro::node_fn(SplinesFromPointsNode)]
|
||||||
fn spline_from_points(mut vector_data: VectorData) -> VectorData {
|
fn splines_from_points(mut vector_data: VectorData) -> VectorData {
|
||||||
for subpath in &mut vector_data.subpaths {
|
for subpath in &mut vector_data.subpaths {
|
||||||
*subpath = Subpath::new_cubic_spline(subpath.anchors());
|
*subpath = Subpath::new_cubic_spline(subpath.anchors());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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::SampleNode<_>, input: Footprint, params: [ImageFrame<Color>]),
|
||||||
register_node!(graphene_std::raster::MandelbrotNode, input: Footprint, params: []),
|
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::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::CircleGenerator<_>, input: (), params: [f32]),
|
||||||
register_node!(graphene_core::vector::generator_nodes::EllipseGenerator<_, _>, input: (), params: [f32, 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::RectangleGenerator<_, _>, input: (), params: [f32, f32]),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue