comment out tests

This commit is contained in:
Adam
2025-07-10 15:14:36 -07:00
parent cf0a32b9b1
commit f5c6b65fcc
35 changed files with 2963 additions and 3098 deletions

View File

@@ -214,11 +214,12 @@ where
let input = Box::new(input);
let future = self.node.eval(input);
Box::pin(async move {
let out = dyn_any::downcast(future.await).unwrap_or_else(|e| panic!("DowncastBothNode Input {e} in: \n{:?}", self.node.node_name()));
let out = dyn_any::downcast(future.await).unwrap_or_else(|e| panic!("DowncastBothNode Error: {e}"));
*out
})
}
}
fn reset(&self) {
self.node.reset();
}

View File

@@ -94,47 +94,47 @@ async fn instance_index(ctx: impl Ctx + ExtractIndex, _primary: (), loop_level:
.unwrap_or_default() as f64
}
#[cfg(test)]
mod test {
use super::*;
use crate::Node;
use crate::extract_xy::{ExtractXyNode, XY};
use crate::vector::VectorData;
use bezier_rs::Subpath;
use glam::DVec2;
use std::pin::Pin;
// #[cfg(test)]
// mod test {
// use super::*;
// use crate::Node;
// use crate::extract_xy::{ExtractXyNode, XY};
// use crate::vector::VectorData;
// use bezier_rs::Subpath;
// use glam::DVec2;
// use std::pin::Pin;
#[derive(Clone)]
pub struct FutureWrapperNode<T: Clone>(T);
// #[derive(Clone)]
// pub struct FutureWrapperNode<T: Clone>(T);
impl<'i, I: Ctx, T: 'i + Clone + Send> Node<'i, I> for FutureWrapperNode<T> {
type Output = Pin<Box<dyn Future<Output = T> + 'i + Send>>;
fn eval(&'i self, _input: I) -> Self::Output {
let value = self.0.clone();
Box::pin(async move { value })
}
}
// impl<'i, I: Ctx, T: 'i + Clone + Send> Node<'i, I> for FutureWrapperNode<T> {
// type Output = Pin<Box<dyn Future<Output = T> + 'i + Send>>;
// fn eval(&'i self, _input: I) -> Self::Output {
// let value = self.0.clone();
// Box::pin(async move { value })
// }
// }
#[tokio::test]
async fn instance_on_points_test() {
let owned = OwnedContextImpl::default().into_context();
let rect = crate::vector::generator_nodes::RectangleNode::new(
FutureWrapperNode(()),
ExtractXyNode::new(InstancePositionNode {}, FutureWrapperNode(XY::Y)),
FutureWrapperNode(2_f64),
FutureWrapperNode(false),
FutureWrapperNode(0_f64),
FutureWrapperNode(false),
);
// #[tokio::test]
// async fn instance_on_points_test() {
// let owned = OwnedContextImpl::default().into_context();
// let rect = crate::vector::generator_nodes::RectangleNode::new(
// FutureWrapperNode(()),
// ExtractXyNode::new(InstancePositionNode {}, FutureWrapperNode(XY::Y)),
// FutureWrapperNode(2_f64),
// FutureWrapperNode(false),
// FutureWrapperNode(0_f64),
// FutureWrapperNode(false),
// );
let positions = [DVec2::new(40., 20.), DVec2::ONE, DVec2::new(-42., 9.), DVec2::new(10., 345.)];
let points = VectorDataTable::new(VectorData::from_subpath(Subpath::from_anchors_linear(positions, false)));
let repeated = super::instance_on_points(owned, points, &rect, false).await;
assert_eq!(repeated.len(), positions.len());
for (position, instanced) in positions.into_iter().zip(repeated.instance_ref_iter()) {
let bounds = instanced.instance.bounding_box_with_transform(*instanced.transform).unwrap();
assert!(position.abs_diff_eq((bounds[0] + bounds[1]) / 2., 1e-10));
assert_eq!((bounds[1] - bounds[0]).x, position.y);
}
}
}
// let positions = [DVec2::new(40., 20.), DVec2::ONE, DVec2::new(-42., 9.), DVec2::new(10., 345.)];
// let points = VectorDataTable::new(VectorData::from_subpath(Subpath::from_anchors_linear(positions, false)));
// let repeated = super::instance_on_points(owned, points, &rect, false).await;
// assert_eq!(repeated.len(), positions.len());
// for (position, instanced) in positions.into_iter().zip(repeated.instance_ref_iter()) {
// let bounds = instanced.instance.bounding_box_with_transform(*instanced.transform).unwrap();
// assert!(position.abs_diff_eq((bounds[0] + bounds[1]) / 2., 1e-10));
// assert_eq!((bounds[1] - bounds[0]).x, position.y);
// }
// }
// }

View File

@@ -2129,315 +2129,322 @@ async fn centroid(ctx: impl Ctx + CloneVarArgs + ExtractAll, vector_data: impl N
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::Node;
use bezier_rs::Bezier;
use kurbo::Rect;
use std::pin::Pin;
// #[cfg(test)]
// mod test {
// use super::*;
// use crate::Node;
// use bezier_rs::Bezier;
// use kurbo::Rect;
// use std::pin::Pin;
#[derive(Clone)]
pub struct FutureWrapperNode<T: Clone>(T);
// #[derive(Clone)]
// pub struct FutureWrapperNode<T: Clone>(T);
impl<'i, T: 'i + Clone + Send> Node<'i, Footprint> for FutureWrapperNode<T> {
type Output = Pin<Box<dyn Future<Output = T> + 'i + Send>>;
fn eval(&'i self, _input: Footprint) -> Self::Output {
let value = self.0.clone();
Box::pin(async move { value })
}
}
// impl<'i, T: 'i + Clone + Send> Node<'i, Footprint> for FutureWrapperNode<T> {
// type Output = Pin<Box<dyn Future<Output = T> + 'i + Send>>;
// fn eval(&'i self, _input: Footprint) -> Self::Output {
// let value = self.0.clone();
// Box::pin(async move { value })
// }
// }
fn vector_node(data: Subpath<PointId>) -> VectorDataTable {
VectorDataTable::new(VectorData::from_subpath(data))
}
// fn vector_node(data: Subpath<PointId>) -> VectorDataTable {
// VectorDataTable::new(VectorData::from_subpath(data))
// }
fn create_vector_data_instance(bezpath: BezPath, transform: DAffine2) -> Instance<VectorData> {
let mut instance = VectorData::default();
instance.append_bezpath(bezpath);
Instance {
instance,
transform,
..Default::default()
}
}
// fn create_vector_data_instance(bezpath: BezPath, transform: DAffine2) -> Instance<VectorData> {
// let mut instance = VectorData::default();
// instance.append_bezpath(bezpath);
// Instance {
// instance,
// transform,
// ..Default::default()
// }
// }
fn vector_node_from_instances(data: Vec<Instance<VectorData>>) -> VectorDataTable {
let mut vector_data_table = VectorDataTable::default();
for instance in data {
vector_data_table.push(instance);
}
vector_data_table
}
// fn vector_node_from_instances(data: Vec<Instance<VectorData>>) -> VectorDataTable {
// let mut vector_data_table = VectorDataTable::default();
// for instance in data {
// vector_data_table.push(instance);
// }
// vector_data_table
// }
#[tokio::test]
async fn repeat() {
let direction = DVec2::X * 1.5;
let instances = 3;
let repeated = super::repeat(Footprint::default(), vector_node(Subpath::new_rect(DVec2::ZERO, DVec2::ONE)), direction, 0., instances).await;
let vector_data = super::flatten_path(Footprint::default(), repeated).await;
let vector_data = vector_data.instance_ref_iter().next().unwrap().instance;
assert_eq!(vector_data.region_bezier_paths().count(), 3);
for (index, (_, subpath)) in vector_data.region_bezier_paths().enumerate() {
assert!((subpath.manipulator_groups()[0].anchor - direction * index as f64 / (instances - 1) as f64).length() < 1e-5);
}
}
#[tokio::test]
async fn repeat_transform_position() {
let direction = DVec2::new(12., 10.);
let instances = 8;
let repeated = super::repeat(Footprint::default(), vector_node(Subpath::new_rect(DVec2::ZERO, DVec2::ONE)), direction, 0., instances).await;
let vector_data = super::flatten_path(Footprint::default(), repeated).await;
let vector_data = vector_data.instance_ref_iter().next().unwrap().instance;
assert_eq!(vector_data.region_bezier_paths().count(), 8);
for (index, (_, subpath)) in vector_data.region_bezier_paths().enumerate() {
assert!((subpath.manipulator_groups()[0].anchor - direction * index as f64 / (instances - 1) as f64).length() < 1e-5);
}
}
#[tokio::test]
async fn circular_repeat() {
let repeated = super::circular_repeat(Footprint::default(), vector_node(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE)), 45., 4., 8).await;
let vector_data = super::flatten_path(Footprint::default(), repeated).await;
let vector_data = vector_data.instance_ref_iter().next().unwrap().instance;
assert_eq!(vector_data.region_bezier_paths().count(), 8);
// #[tokio::test]
// async fn repeat() {
// let direction = DVec2::X * 1.5;
// let instances = 3;
// let repeated = super::repeat(Footprint::default(), vector_node(Subpath::new_rect(DVec2::ZERO, DVec2::ONE)), direction, 0., instances).await;
// let vector_data = super::flatten_path(Footprint::default(), repeated).await;
// let vector_data = vector_data.instance_ref_iter().next().unwrap().instance;
// assert_eq!(vector_data.region_bezier_paths().count(), 3);
// for (index, (_, subpath)) in vector_data.region_bezier_paths().enumerate() {
// assert!((subpath.manipulator_groups()[0].anchor - direction * index as f64 / (instances - 1) as f64).length() < 1e-5);
// }
// }
// #[tokio::test]
// async fn repeat_transform_position() {
// let direction = DVec2::new(12., 10.);
// let instances = 8;
// let repeated = super::repeat(Footprint::default(), vector_node(Subpath::new_rect(DVec2::ZERO, DVec2::ONE)), direction, 0., instances).await;
// let vector_data = super::flatten_path(Footprint::default(), repeated).await;
// let vector_data = vector_data.instance_ref_iter().next().unwrap().instance;
// assert_eq!(vector_data.region_bezier_paths().count(), 8);
// for (index, (_, subpath)) in vector_data.region_bezier_paths().enumerate() {
// assert!((subpath.manipulator_groups()[0].anchor - direction * index as f64 / (instances - 1) as f64).length() < 1e-5);
// }
// }
// #[tokio::test]
// async fn circular_repeat() {
// let repeated = super::circular_repeat(Footprint::default(), vector_node(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE)), 45., 4., 8).await;
// let vector_data = super::flatten_path(Footprint::default(), repeated).await;
// let vector_data = vector_data.instance_ref_iter().next().unwrap().instance;
// assert_eq!(vector_data.region_bezier_paths().count(), 8);
for (index, (_, subpath)) in vector_data.region_bezier_paths().enumerate() {
let expected_angle = (index as f64 + 1.) * 45.;
// for (index, (_, subpath)) in vector_data.region_bezier_paths().enumerate() {
// let expected_angle = (index as f64 + 1.) * 45.;
let center = (subpath.manipulator_groups()[0].anchor + subpath.manipulator_groups()[2].anchor) / 2.;
let actual_angle = DVec2::Y.angle_to(center).to_degrees();
// let center = (subpath.manipulator_groups()[0].anchor + subpath.manipulator_groups()[2].anchor) / 2.;
// let actual_angle = DVec2::Y.angle_to(center).to_degrees();
assert!((actual_angle - expected_angle).abs() % 360. < 1e-5, "Expected {expected_angle} found {actual_angle}");
}
}
#[tokio::test]
async fn bounding_box() {
let bounding_box = super::bounding_box((), vector_node(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE))).await;
let bounding_box = bounding_box.instance_ref_iter().next().unwrap().instance;
assert_eq!(bounding_box.region_bezier_paths().count(), 1);
let subpath = bounding_box.region_bezier_paths().next().unwrap().1;
assert_eq!(&subpath.anchors()[..4], &[DVec2::NEG_ONE, DVec2::new(1., -1.), DVec2::ONE, DVec2::new(-1., 1.),]);
// assert!((actual_angle - expected_angle).abs() % 360. < 1e-5, "Expected {expected_angle} found {actual_angle}");
// }
// }
// #[tokio::test]
// async fn bounding_box() {
// let bounding_box = super::bounding_box((), vector_node(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE))).await;
// let bounding_box = bounding_box.instance_ref_iter().next().unwrap().instance;
// assert_eq!(bounding_box.region_bezier_paths().count(), 1);
// let subpath = bounding_box.region_bezier_paths().next().unwrap().1;
// assert_eq!(&subpath.anchors()[..4], &[DVec2::NEG_ONE, DVec2::new(1., -1.), DVec2::ONE, DVec2::new(-1., 1.),]);
// Test a VectorData with non-zero rotation
let square = VectorData::from_subpath(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE));
let mut square = VectorDataTable::new(square);
*square.get_mut(0).unwrap().transform *= DAffine2::from_angle(std::f64::consts::FRAC_PI_4);
let bounding_box = BoundingBoxNode {
vector_data: FutureWrapperNode(square),
}
.eval(Footprint::default())
.await;
let bounding_box = bounding_box.instance_ref_iter().next().unwrap().instance;
assert_eq!(bounding_box.region_bezier_paths().count(), 1);
let subpath = bounding_box.region_bezier_paths().next().unwrap().1;
let expected_bounding_box = [DVec2::NEG_ONE, DVec2::new(1., -1.), DVec2::ONE, DVec2::new(-1., 1.)];
for i in 0..4 {
assert_eq!(subpath.anchors()[i], expected_bounding_box[i]);
}
}
#[tokio::test]
async fn copy_to_points() {
let points = Subpath::new_rect(DVec2::NEG_ONE * 10., DVec2::ONE * 10.);
let instance = Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE);
// // Test a VectorData with non-zero rotation
// let square = VectorData::from_subpath(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE));
// let mut square = VectorDataTable::new(square);
// *square.get_mut(0).unwrap().transform *= DAffine2::from_angle(std::f64::consts::FRAC_PI_4);
// let bounding_box = BoundingBoxNode {
// vector_data: FutureWrapperNode(square),
// }
// .eval(Footprint::default())
// .await;
// let bounding_box = bounding_box.instance_ref_iter().next().unwrap().instance;
// assert_eq!(bounding_box.region_bezier_paths().count(), 1);
// let subpath = bounding_box.region_bezier_paths().next().unwrap().1;
// let expected_bounding_box = [DVec2::NEG_ONE, DVec2::new(1., -1.), DVec2::ONE, DVec2::new(-1., 1.)];
// for i in 0..4 {
// assert_eq!(subpath.anchors()[i], expected_bounding_box[i]);
// }
// }
// #[tokio::test]
// async fn copy_to_points() {
// let points = Subpath::new_rect(DVec2::NEG_ONE * 10., DVec2::ONE * 10.);
// let instance = Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE);
let expected_points = VectorData::from_subpath(points.clone()).point_domain.positions().to_vec();
// let expected_points = VectorData::from_subpath(points.clone()).point_domain.positions().to_vec();
let copy_to_points = super::copy_to_points(Footprint::default(), vector_node(points), vector_node(instance), 1., 1., 0., 0, 0., 0).await;
let flatten_path = super::flatten_path(Footprint::default(), copy_to_points).await;
let flattened_copy_to_points = flatten_path.instance_ref_iter().next().unwrap().instance;
// let copy_to_points = super::copy_to_points(Footprint::default(), vector_node(points), vector_node(instance), 1., 1., 0., 0, 0., 0).await;
// let flatten_path = super::flatten_path(Footprint::default(), copy_to_points).await;
// let flattened_copy_to_points = flatten_path.instance_ref_iter().next().unwrap().instance;
assert_eq!(flattened_copy_to_points.region_bezier_paths().count(), expected_points.len());
// assert_eq!(flattened_copy_to_points.region_bezier_paths().count(), expected_points.len());
for (index, (_, subpath)) in flattened_copy_to_points.region_bezier_paths().enumerate() {
let offset = expected_points[index];
assert_eq!(
&subpath.anchors(),
&[offset + DVec2::NEG_ONE, offset + DVec2::new(1., -1.), offset + DVec2::ONE, offset + DVec2::new(-1., 1.),]
);
}
}
#[tokio::test]
async fn sample_polyline() {
let path = Subpath::from_bezier(&Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::ZERO, DVec2::X * 100., DVec2::X * 100.));
let sample_polyline = super::sample_polyline(Footprint::default(), vector_node(path), PointSpacingType::Separation, 30., 0, 0., 0., false, vec![100.]).await;
let sample_polyline = sample_polyline.instance_ref_iter().next().unwrap().instance;
assert_eq!(sample_polyline.point_domain.positions().len(), 4);
for (pos, expected) in sample_polyline.point_domain.positions().iter().zip([DVec2::X * 0., DVec2::X * 30., DVec2::X * 60., DVec2::X * 90.]) {
assert!(pos.distance(expected) < 1e-3, "Expected {expected} found {pos}");
}
}
#[tokio::test]
async fn sample_polyline_adaptive_spacing() {
let path = Subpath::from_bezier(&Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::ZERO, DVec2::X * 100., DVec2::X * 100.));
let sample_polyline = super::sample_polyline(Footprint::default(), vector_node(path), PointSpacingType::Separation, 18., 0, 45., 10., true, vec![100.]).await;
let sample_polyline = sample_polyline.instance_ref_iter().next().unwrap().instance;
assert_eq!(sample_polyline.point_domain.positions().len(), 4);
for (pos, expected) in sample_polyline.point_domain.positions().iter().zip([DVec2::X * 45., DVec2::X * 60., DVec2::X * 75., DVec2::X * 90.]) {
assert!(pos.distance(expected) < 1e-3, "Expected {expected} found {pos}");
}
}
#[tokio::test]
async fn poisson() {
let poisson_points = super::poisson_disk_points(
Footprint::default(),
vector_node(Subpath::new_ellipse(DVec2::NEG_ONE * 50., DVec2::ONE * 50.)),
10. * std::f64::consts::SQRT_2,
0,
)
.await;
let poisson_points = poisson_points.instance_ref_iter().next().unwrap().instance;
assert!(
(20..=40).contains(&poisson_points.point_domain.positions().len()),
"actual len {}",
poisson_points.point_domain.positions().len()
);
for point in poisson_points.point_domain.positions() {
assert!(point.length() < 50. + 1., "Expected point in circle {point}")
}
}
#[tokio::test]
async fn segment_lengths() {
let subpath = Subpath::from_bezier(&Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::ZERO, DVec2::X * 100., DVec2::X * 100.));
let lengths = subpath_segment_lengths(Footprint::default(), vector_node(subpath)).await;
assert_eq!(lengths, vec![100.]);
}
#[tokio::test]
async fn path_length() {
let bezpath = Rect::new(100., 100., 201., 201.).to_path(DEFAULT_ACCURACY);
let transform = DAffine2::from_scale(DVec2::new(2., 2.));
let instance = create_vector_data_instance(bezpath, transform);
let instances = (0..5).map(|_| instance.clone()).collect::<Vec<Instance<VectorData>>>();
// for (index, (_, subpath)) in flattened_copy_to_points.region_bezier_paths().enumerate() {
// let offset = expected_points[index];
// assert_eq!(
// &subpath.anchors(),
// &[offset + DVec2::NEG_ONE, offset + DVec2::new(1., -1.), offset + DVec2::ONE, offset + DVec2::new(-1., 1.),]
// );
// }
// }
// #[tokio::test]
// async fn sample_polyline() {
// let path = Subpath::from_bezier(&Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::ZERO, DVec2::X * 100., DVec2::X * 100.));
// let sample_polyline = super::sample_polyline(Footprint::default(), vector_node(path), PointSpacingType::Separation, 30., 0, 0., 0., false, vec![100.]).await;
// let sample_polyline = sample_polyline.instance_ref_iter().next().unwrap().instance;
// assert_eq!(sample_polyline.point_domain.positions().len(), 4);
// for (pos, expected) in sample_polyline.point_domain.positions().iter().zip([DVec2::X * 0., DVec2::X * 30., DVec2::X * 60., DVec2::X * 90.]) {
// assert!(pos.distance(expected) < 1e-3, "Expected {expected} found {pos}");
// }
// }
// #[tokio::test]
// async fn sample_polyline_adaptive_spacing() {
// let path = Subpath::from_bezier(&Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::ZERO, DVec2::X * 100., DVec2::X * 100.));
// let sample_polyline = super::sample_polyline(Footprint::default(), vector_node(path), PointSpacingType::Separation, 18., 0, 45., 10., true, vec![100.]).await;
// let sample_polyline = sample_polyline.instance_ref_iter().next().unwrap().instance;
// assert_eq!(sample_polyline.point_domain.positions().len(), 4);
// for (pos, expected) in sample_polyline.point_domain.positions().iter().zip([DVec2::X * 45., DVec2::X * 60., DVec2::X * 75., DVec2::X * 90.]) {
// assert!(pos.distance(expected) < 1e-3, "Expected {expected} found {pos}");
// }
// }
// #[tokio::test]
// async fn poisson() {
// let poisson_points = super::poisson_disk_points(
// Footprint::default(),
// vector_node(Subpath::new_ellipse(DVec2::NEG_ONE * 50., DVec2::ONE * 50.)),
// 10. * std::f64::consts::SQRT_2,
// 0,
// )
// .await;
// let poisson_points = poisson_points.instance_ref_iter().next().unwrap().instance;
// assert!(
// (20..=40).contains(&poisson_points.point_domain.positions().len()),
// "actual len {}",
// poisson_points.point_domain.positions().len()
// );
// for point in poisson_points.point_domain.positions() {
// assert!(point.length() < 50. + 1., "Expected point in circle {point}")
// }
// }
// #[tokio::test]
// async fn segment_lengths() {
// let subpath = Subpath::from_bezier(&Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::ZERO, DVec2::X * 100., DVec2::X * 100.));
// let lengths = subpath_segment_lengths(Footprint::default(), vector_node(subpath)).await;
// assert_eq!(lengths, vec![100.]);
// }
// #[tokio::test]
// async fn path_length() {
// let bezpath = Rect::new(100., 100., 201., 201.).to_path(DEFAULT_ACCURACY);
// let transform = DAffine2::from_scale(DVec2::new(2., 2.));
// let instance = create_vector_data_instance(bezpath, transform);
// let instances = (0..5).map(|_| instance.clone()).collect::<Vec<Instance<VectorData>>>();
let length = super::path_length(Footprint::default(), vector_node_from_instances(instances)).await;
// let length = super::path_length(Footprint::default(), vector_node_from_instances(instances)).await;
// 101 (each rectangle edge length) * 4 (rectangle perimeter) * 2 (scale) * 5 (number of rows)
assert_eq!(length, 101. * 4. * 2. * 5.);
}
#[tokio::test]
async fn spline() {
let spline = super::spline(Footprint::default(), vector_node(Subpath::new_rect(DVec2::ZERO, DVec2::ONE * 100.))).await;
let spline = spline.instance_ref_iter().next().unwrap().instance;
assert_eq!(spline.stroke_bezier_paths().count(), 1);
assert_eq!(spline.point_domain.positions(), &[DVec2::ZERO, DVec2::new(100., 0.), DVec2::new(100., 100.), DVec2::new(0., 100.)]);
}
#[tokio::test]
async fn morph() {
let source = Subpath::new_rect(DVec2::ZERO, DVec2::ONE * 100.);
let target = Subpath::new_ellipse(DVec2::NEG_ONE * 100., DVec2::ZERO);
let morphed = super::morph(Footprint::default(), vector_node(source), vector_node(target), 0.5).await;
let morphed = morphed.instance_ref_iter().next().unwrap().instance;
assert_eq!(
&morphed.point_domain.positions()[..4],
vec![DVec2::new(-25., -50.), DVec2::new(50., -25.), DVec2::new(25., 50.), DVec2::new(-50., 25.)]
);
}
// // 101 (each rectangle edge length) * 4 (rectangle perimeter) * 2 (scale) * 5 (number of rows)
// assert_eq!(length, 101. * 4. * 2. * 5.);
// }
// #[tokio::test]
// async fn spline() {
// let spline = super::spline(Footprint::default(), vector_node(Subpath::new_rect(DVec2::ZERO, DVec2::ONE * 100.))).await;
// let spline = spline.instance_ref_iter().next().unwrap().instance;
// assert_eq!(spline.stroke_bezier_paths().count(), 1);
// assert_eq!(spline.point_domain.positions(), &[DVec2::ZERO, DVec2::new(100., 0.), DVec2::new(100., 100.), DVec2::new(0., 100.)]);
// }
// #[tokio::test]
// async fn morph() {
// let source = Subpath::new_rect(DVec2::ZERO, DVec2::ONE * 100.);
// let target = Subpath::new_ellipse(DVec2::NEG_ONE * 100., DVec2::ZERO);
// let morphed = super::morph(Footprint::default(), vector_node(source), vector_node(target), 0.5).await;
// let morphed = morphed.instance_ref_iter().next().unwrap().instance;
// assert_eq!(
// &morphed.point_domain.positions()[..4],
// vec![DVec2::new(-25., -50.), DVec2::new(50., -25.), DVec2::new(25., 50.), DVec2::new(-50., 25.)]
// );
// }
#[track_caller]
fn contains_segment(vector: VectorData, target: Bezier) {
let segments = vector.segment_bezier_iter().map(|x| x.1);
let count = segments.filter(|bezier| bezier.abs_diff_eq(&target, 0.01) || bezier.reversed().abs_diff_eq(&target, 0.01)).count();
assert_eq!(
count,
1,
"Expected exactly one matching segment for {target:?}, but found {count}. The given segments are: {:#?}",
vector.segment_bezier_iter().collect::<Vec<_>>()
);
}
// #[track_caller]
// fn contains_segment(vector: VectorData, target: Bezier) {
// let segments = vector.segment_bezier_iter().map(|x| x.1);
// let count = segments.filter(|bezier| bezier.abs_diff_eq(&target, 0.01) || bezier.reversed().abs_diff_eq(&target, 0.01)).count();
// assert_eq!(
// count,
// 1,
// "Expected exactly one matching segment for {target:?}, but found {count}. The given segments are: {:#?}",
// vector.segment_bezier_iter().collect::<Vec<_>>()
// );
// }
#[tokio::test]
async fn bevel_rect() {
let source = Subpath::new_rect(DVec2::ZERO, DVec2::ONE * 100.);
let beveled = super::bevel(Footprint::default(), vector_node(source), 2_f64.sqrt() * 10.);
let beveled = beveled.instance_ref_iter().next().unwrap().instance;
// #[tokio::test]
// async fn bevel_rect() {
// let source = Subpath::new_rect(DVec2::ZERO, DVec2::ONE * 100.);
// let beveled = super::bevel(Footprint::default(), vector_node(source), 5.);
// let beveled = beveled.instance_ref_iter().next().unwrap().instance;
assert_eq!(beveled.point_domain.positions().len(), 8);
assert_eq!(beveled.segment_domain.ids().len(), 8);
// assert_eq!(beveled.point_domain.positions().len(), 8);
// assert_eq!(beveled.segment_domain.ids().len(), 8);
// Segments
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(10., 0.), DVec2::new(90., 0.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(10., 100.), DVec2::new(90., 100.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(0., 10.), DVec2::new(0., 90.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 10.), DVec2::new(100., 90.)));
// // Segments
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(95., 0.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(95., 100.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(0., 5.), DVec2::new(0., 95.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 5.), DVec2::new(100., 95.)));
// Joins
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(10., 0.), DVec2::new(0., 10.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(90., 0.), DVec2::new(100., 10.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 90.), DVec2::new(90., 100.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(10., 100.), DVec2::new(0., 90.)));
}
// // Joins
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(0., 5.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(95., 0.), DVec2::new(100., 5.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 95.), DVec2::new(95., 100.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(0., 95.)));
// }
#[tokio::test]
async fn bevel_open_curve() {
let curve = Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::new(10., 0.), DVec2::new(10., 100.), DVec2::X * 100.);
let source = Subpath::from_beziers(&[Bezier::from_linear_dvec2(DVec2::X * -100., DVec2::ZERO), curve], false);
let beveled = super::bevel((), vector_node(source), 2_f64.sqrt() * 10.);
let beveled = beveled.instance_ref_iter().next().unwrap().instance;
// #[tokio::test]
// async fn bevel_open_curve() {
// let curve = Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::new(10., 0.), DVec2::new(10., 100.), DVec2::X * 100.);
// let source = Subpath::from_beziers(&[Bezier::from_linear_dvec2(DVec2::X * -100., DVec2::ZERO), curve], false);
// let beveled = super::bevel((), vector_node(source), 5.);
// let beveled = beveled.instance_ref_iter().next().unwrap().instance;
assert_eq!(beveled.point_domain.positions().len(), 4);
assert_eq!(beveled.segment_domain.ids().len(), 3);
// assert_eq!(beveled.point_domain.positions().len(), 4);
// assert_eq!(beveled.segment_domain.ids().len(), 3);
// Segments
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-8.2, 0.), DVec2::new(-100., 0.)));
let trimmed = curve.trim(bezier_rs::TValue::Euclidean(8.2 / curve.length(Some(0.00001))), bezier_rs::TValue::Parametric(1.));
contains_segment(beveled.clone(), trimmed);
// // Segments
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-100., 0.)));
// let trimmed = curve.trim(bezier_rs::TValue::Euclidean(5. / curve.length(Some(0.00001))), bezier_rs::TValue::Parametric(1.));
// contains_segment(beveled.clone(), trimmed);
// Join
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-8.2, 0.), trimmed.start));
}
// // Join
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
// }
#[tokio::test]
async fn bevel_with_transform() {
let curve = Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::new(10., 0.), DVec2::new(10., 100.), DVec2::new(100., 0.));
let source = Subpath::<PointId>::from_beziers(&[Bezier::from_linear_dvec2(DVec2::new(-100., 0.), DVec2::ZERO), curve], false);
let vector_data = VectorData::from_subpath(source);
let mut vector_data_table = VectorDataTable::new(vector_data.clone());
// #[tokio::test]
// async fn bevel_with_transform() {
// let curve = Bezier::from_cubic_dvec2(DVec2::new(0., 0.), DVec2::new(1., 0.), DVec2::new(1., 10.), DVec2::new(10., 0.));
// let source = Subpath::<PointId>::from_beziers(&[Bezier::from_linear_dvec2(DVec2::new(-10., 0.), DVec2::ZERO), curve], false);
// let vector_data = VectorData::from_subpath(source);
// let mut vector_data_table = VectorDataTable::new(vector_data.clone());
*vector_data_table.get_mut(0).unwrap().transform = DAffine2::from_scale_angle_translation(DVec2::splat(10.), 1., DVec2::new(99., 77.));
// *vector_data_table.get_mut(0).unwrap().transform = DAffine2::from_scale_angle_translation(DVec2::splat(10.), 1., DVec2::new(99., 77.));
let beveled = super::bevel((), VectorDataTable::new(vector_data), 2_f64.sqrt() * 10.);
let beveled = beveled.instance_ref_iter().next().unwrap().instance;
// let beveled = super::bevel((), VectorDataTable::new(vector_data), 5.);
// let beveled = beveled.instance_ref_iter().next().unwrap().instance;
assert_eq!(beveled.point_domain.positions().len(), 4);
assert_eq!(beveled.segment_domain.ids().len(), 3);
// assert_eq!(beveled.point_domain.positions().len(), 4);
// assert_eq!(beveled.segment_domain.ids().len(), 3);
// Segments
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-8.2, 0.), DVec2::new(-100., 0.)));
let trimmed = curve.trim(bezier_rs::TValue::Euclidean(8.2 / curve.length(Some(0.00001))), bezier_rs::TValue::Parametric(1.));
contains_segment(beveled.clone(), trimmed);
// // Segments
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-10., 0.)));
// let trimmed = curve.trim(bezier_rs::TValue::Euclidean(5. / curve.length(Some(0.00001))), bezier_rs::TValue::Parametric(1.));
// contains_segment(beveled.clone(), trimmed);
// Join
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-8.2, 0.), trimmed.start));
}
// // Join
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
// }
#[tokio::test]
async fn bevel_too_high() {
let source = Subpath::from_anchors([DVec2::ZERO, DVec2::new(100., 0.), DVec2::new(100., 100.), DVec2::new(0., 100.)], false);
let beveled = super::bevel(Footprint::default(), vector_node(source), 999.);
let beveled = beveled.instance_ref_iter().next().unwrap().instance;
// #[tokio::test]
// async fn bevel_too_high() {
// let source = Subpath::from_anchors([DVec2::ZERO, DVec2::new(100., 0.), DVec2::new(100., 100.), DVec2::new(0., 100.)], false);
// let beveled = super::bevel(Footprint::default(), vector_node(source), 999.);
// let beveled = beveled.instance_ref_iter().next().unwrap().instance;
assert_eq!(beveled.point_domain.positions().len(), 6);
assert_eq!(beveled.segment_domain.ids().len(), 5);
// assert_eq!(beveled.point_domain.positions().len(), 6);
// assert_eq!(beveled.segment_domain.ids().len(), 5);
// Segments
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(0., 0.), DVec2::new(50., 0.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(100., 50.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
// // Segments
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(0., 0.), DVec2::new(50., 0.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(100., 50.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
// Joins
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(50., 0.), DVec2::new(100., 50.)));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
}
// // Joins
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(50., 0.), DVec2::new(100., 50.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
// }
#[tokio::test]
async fn bevel_repeated_point() {
let line = Bezier::from_linear_dvec2(DVec2::ZERO, DVec2::new(100., 0.));
let point = Bezier::from_cubic_dvec2(DVec2::new(100., 0.), DVec2::ZERO, DVec2::ZERO, DVec2::new(100., 0.));
let curve = Bezier::from_cubic_dvec2(DVec2::new(100., 0.), DVec2::new(110., 0.), DVec2::new(110., 200.), DVec2::new(200., 0.));
let subpath = Subpath::from_beziers(&[line, point, curve], false);
let beveled_table = super::bevel(Footprint::default(), vector_node(subpath), 5.);
let beveled = beveled_table.instance_ref_iter().next().unwrap().instance;
// #[tokio::test]
// async fn bevel_repeated_point() {
// let curve = Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::new(10., 0.), DVec2::new(10., 100.), DVec2::X * 100.);
// let point = Bezier::from_cubic_dvec2(DVec2::ZERO, DVec2::ZERO, DVec2::ZERO, DVec2::ZERO);
// let source = Subpath::from_beziers(&[Bezier::from_linear_dvec2(DVec2::X * -100., DVec2::ZERO), point, curve], false);
// let beveled = super::bevel(Footprint::default(), vector_node(source), 5.);
// let beveled = beveled.instance_ref_iter().next().unwrap().instance;
assert_eq!(beveled.point_domain.positions().len(), 6);
assert_eq!(beveled.segment_domain.ids().len(), 5);
}
}
// assert_eq!(beveled.point_domain.positions().len(), 6);
// assert_eq!(beveled.segment_domain.ids().len(), 5);
// // Segments
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-100., 0.), DVec2::new(-5., 0.)));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(0., 0.)));
// contains_segment(beveled.clone(), point);
// let [start, end] = curve.split(bezier_rs::TValue::Euclidean(5. / curve.length(Some(0.00001))));
// contains_segment(beveled.clone(), Bezier::from_linear_dvec2(start.start, start.end));
// contains_segment(beveled.clone(), end);
// }
// }