Bulk gcore cleanup, replace core and alloc with std (#2735)

* gcore: replace `core` and `alloc` paths with `std`

* node-graph: remove unnecessary path prefix

* gcore: remove most `#[cfg(target_arch = "spirv")]`, keep some potentially useful ones

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Firestar99
2025-06-22 01:08:33 +02:00
committed by GitHub
parent 301368a0df
commit 990d5b37cf
46 changed files with 287 additions and 313 deletions

View File

@@ -108,7 +108,7 @@ pub fn t_value_to_parametric(bezpath: &BezPath, t: f64, euclidian: bool, segment
/// Finds the t value of point on the given path segment i.e fractional distance along the segment's total length.
/// It uses a binary search to find the value `t` such that the ratio `length_up_to_t / total_length` approximates the input `distance`.
pub fn eval_pathseg_euclidean(path_segment: kurbo::PathSeg, distance: f64, accuracy: f64) -> f64 {
pub fn eval_pathseg_euclidean(path_segment: PathSeg, distance: f64, accuracy: f64) -> f64 {
let mut low_t = 0.;
let mut mid_t = 0.5;
let mut high_t = 1.;
@@ -139,7 +139,7 @@ pub fn eval_pathseg_euclidean(path_segment: kurbo::PathSeg, distance: f64, accur
/// Converts from a bezpath (composed of multiple segments) to a point along a certain segment represented.
/// The returned tuple represents the segment index and the `t` value along that segment.
/// Both the input global `t` value and the output `t` value are in euclidean space, meaning there is a constant rate of change along the arc length.
fn global_euclidean_to_local_euclidean(bezpath: &kurbo::BezPath, global_t: f64, lengths: &[f64], total_length: f64) -> (usize, f64) {
fn global_euclidean_to_local_euclidean(bezpath: &BezPath, global_t: f64, lengths: &[f64], total_length: f64) -> (usize, f64) {
let mut accumulator = 0.;
for (index, length) in lengths.iter().enumerate() {
let length_ratio = length / total_length;
@@ -158,7 +158,7 @@ enum BezPathTValue {
/// Convert a [BezPathTValue] to a parametric `(segment_index, t)` tuple.
/// - Asserts that `t` values contained within the `SubpathTValue` argument lie in the range [0, 1].
fn bezpath_t_value_to_parametric(bezpath: &kurbo::BezPath, t: BezPathTValue, precomputed_segments_length: Option<&[f64]>) -> (usize, f64) {
fn bezpath_t_value_to_parametric(bezpath: &BezPath, t: BezPathTValue, precomputed_segments_length: Option<&[f64]>) -> (usize, f64) {
let segment_count = bezpath.segments().count();
assert!(segment_count >= 1);

View File

@@ -109,7 +109,7 @@ mod test {
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 core::future::Future<Output = T> + 'i + Send>>;
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 })

View File

@@ -8,7 +8,7 @@ const CUBIC_TO_BEZPATH_ACCURACY: f64 = 1e-3;
/// Constant used to determine if `f64`s are equivalent.
pub const MAX_ABSOLUTE_DIFFERENCE: f64 = 1e-3;
fn segment_to_bezier(seg: kurbo::PathSeg) -> bezier_rs::Bezier {
fn segment_to_bezier(seg: kurbo::PathSeg) -> Bezier {
match seg {
kurbo::PathSeg::Line(line) => Bezier::from_linear_coordinates(line.p0.x, line.p0.y, line.p1.x, line.p1.y),
kurbo::PathSeg::Quad(quad_bez) => Bezier::from_quadratic_coordinates(quad_bez.p0.x, quad_bez.p0.y, quad_bez.p1.x, quad_bez.p1.y, quad_bez.p1.x, quad_bez.p1.y),

View File

@@ -1,6 +1,6 @@
use core::f64;
use glam::DVec2;
use std::collections::HashMap;
use std::f64;
const DEEPEST_SUBDIVISION_LEVEL_BEFORE_DISCARDING: usize = 8;
@@ -27,7 +27,7 @@ pub fn poisson_disk_sample(
// - Dividing into an integer number of cells across the dartboard domain, to avoid wastefully throwing darts beyond the width and height of the dartboard domain
// - Being fully covered by the radius around a dart thrown anywhere in its area, where the worst-case is a corner which has a distance of sqrt(2) to the opposite corner
let greater_dimension = width.max(height);
let base_level_grid_size = greater_dimension / (greater_dimension * std::f64::consts::SQRT_2 / (diameter / 2.)).ceil();
let base_level_grid_size = greater_dimension / (greater_dimension * f64::consts::SQRT_2 / (diameter / 2.)).ceil();
// Initialize the problem by including all base-level squares in the active list since they're all part of the yet-to-be-targetted dartboard domain
let base_level = ActiveListLevel::new_filled(base_level_grid_size, offset, width, height, &point_in_shape_checker, &line_intersect_shape_checker);

View File

@@ -22,7 +22,7 @@ pub enum GradientType {
pub struct GradientStops(Vec<(f64, Color)>);
impl std::hash::Hash for GradientStops {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.len().hash(state);
self.0.iter().for_each(|(position, color)| {
position.to_bits().hash(state);
@@ -146,8 +146,8 @@ impl Default for Gradient {
}
}
impl core::hash::Hash for Gradient {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
impl std::hash::Hash for Gradient {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.stops.0.len().hash(state);
[].iter()
.chain(self.start.to_array().iter())
@@ -611,8 +611,8 @@ pub struct Stroke {
pub paint_order: PaintOrder,
}
impl core::hash::Hash for Stroke {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
impl std::hash::Hash for Stroke {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.color.hash(state);
self.weight.to_bits().hash(state);
{
@@ -850,8 +850,8 @@ pub struct PathStyle {
fill: Fill,
}
impl core::hash::Hash for PathStyle {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
impl std::hash::Hash for PathStyle {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.stroke.hash(state);
self.fill.hash(state);
}

View File

@@ -9,12 +9,12 @@ use crate::renderer::{ClickTargetType, FreePoint};
use crate::{AlphaBlending, Color, GraphicGroupTable};
pub use attributes::*;
use bezier_rs::ManipulatorGroup;
use core::borrow::Borrow;
use dyn_any::DynAny;
use glam::{DAffine2, DVec2};
pub use indexed::VectorDataIndex;
use kurbo::{Affine, Rect, Shape};
pub use modification::*;
use std::borrow::Borrow;
use std::collections::HashMap;
// TODO: Eventually remove this migration document upgrade code
@@ -105,8 +105,8 @@ impl Default for VectorData {
}
}
impl core::hash::Hash for VectorData {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
impl std::hash::Hash for VectorData {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.point_domain.hash(state);
self.segment_domain.hash(state);
self.region_domain.hash(state);

View File

@@ -1,11 +1,11 @@
use crate::vector::misc::dvec2_to_point;
use crate::vector::vector_data::{HandleId, VectorData};
use bezier_rs::{BezierHandles, ManipulatorGroup};
use core::iter::zip;
use dyn_any::DynAny;
use glam::{DAffine2, DVec2};
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::iter::zip;
/// A simple macro for creating strongly typed ids (to avoid confusion when passing around ids).
macro_rules! create_ids {
@@ -53,7 +53,7 @@ create_ids! { InstanceId, PointId, SegmentId, RegionId, StrokeId, FillId }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct NoHash(Option<u64>);
impl core::hash::Hasher for NoHash {
impl Hasher for NoHash {
fn finish(&self) -> u64 {
self.0.unwrap()
}
@@ -70,7 +70,7 @@ impl core::hash::Hasher for NoHash {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct NoHashBuilder;
impl core::hash::BuildHasher for NoHashBuilder {
impl std::hash::BuildHasher for NoHashBuilder {
type Hasher = NoHash;
fn build_hasher(&self) -> Self::Hasher {
NoHash::default()
@@ -86,8 +86,8 @@ pub struct PointDomain {
pub(crate) position: Vec<DVec2>,
}
impl core::hash::Hash for PointDomain {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
impl Hash for PointDomain {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
self.position.iter().for_each(|pos| pos.to_array().map(|v| v.to_bits()).hash(state));
}
@@ -203,7 +203,7 @@ pub struct SegmentDomain {
id: Vec<SegmentId>,
start_point: Vec<usize>,
end_point: Vec<usize>,
handles: Vec<bezier_rs::BezierHandles>,
handles: Vec<BezierHandles>,
stroke: Vec<StrokeId>,
}
@@ -293,7 +293,7 @@ impl SegmentDomain {
self.end_point[segment_index] = new;
}
pub fn handles(&self) -> &[bezier_rs::BezierHandles] {
pub fn handles(&self) -> &[BezierHandles] {
&self.handles
}
@@ -301,7 +301,7 @@ impl SegmentDomain {
&self.stroke
}
pub(crate) fn push(&mut self, id: SegmentId, start: usize, end: usize, handles: bezier_rs::BezierHandles, stroke: StrokeId) {
pub(crate) fn push(&mut self, id: SegmentId, start: usize, end: usize, handles: BezierHandles, stroke: StrokeId) {
debug_assert!(!self.id.contains(&id), "Tried to push an existing point to a point domain");
self.id.push(id);
@@ -319,12 +319,12 @@ impl SegmentDomain {
self.id.iter().copied().zip(self.end_point.iter_mut())
}
pub(crate) fn handles_mut(&mut self) -> impl Iterator<Item = (SegmentId, &mut bezier_rs::BezierHandles, usize, usize)> {
pub(crate) fn handles_mut(&mut self) -> impl Iterator<Item = (SegmentId, &mut BezierHandles, usize, usize)> {
let nested = self.id.iter().zip(&mut self.handles).zip(&self.start_point).zip(&self.end_point);
nested.map(|(((&a, b), &c), &d)| (a, b, c, d))
}
pub(crate) fn handles_and_points_mut(&mut self) -> impl Iterator<Item = (&mut bezier_rs::BezierHandles, &mut usize, &mut usize)> {
pub(crate) fn handles_and_points_mut(&mut self) -> impl Iterator<Item = (&mut BezierHandles, &mut usize, &mut usize)> {
let nested = self.handles.iter_mut().zip(&mut self.start_point).zip(&mut self.end_point);
nested.map(|((a, b), c)| (a, b, c))
}
@@ -368,7 +368,7 @@ impl SegmentDomain {
self.id.iter().position(|&check_id| check_id == id)
}
fn resolve_range(&self, range: &core::ops::RangeInclusive<SegmentId>) -> Option<core::ops::RangeInclusive<usize>> {
fn resolve_range(&self, range: &std::ops::RangeInclusive<SegmentId>) -> Option<std::ops::RangeInclusive<usize>> {
match (self.id_to_index(*range.start()), self.id_to_index(*range.end())) {
(Some(start), Some(end)) if start.max(end) < self.handles.len().min(self.id.len()).min(self.start_point.len()).min(self.end_point.len()) => Some(start..=end),
_ => {
@@ -446,7 +446,7 @@ impl SegmentDomain {
pub struct RegionDomain {
#[serde(alias = "ids")]
id: Vec<RegionId>,
segment_range: Vec<core::ops::RangeInclusive<SegmentId>>,
segment_range: Vec<std::ops::RangeInclusive<SegmentId>>,
fill: Vec<FillId>,
}
@@ -476,7 +476,7 @@ impl RegionDomain {
/// Like [`Self::retain`] but also gives the function access to the segment range.
///
/// Note that this function requires an allocation that `retain` avoids.
pub fn retain_with_region(&mut self, f: impl Fn(&RegionId, &core::ops::RangeInclusive<SegmentId>) -> bool) {
pub fn retain_with_region(&mut self, f: impl Fn(&RegionId, &std::ops::RangeInclusive<SegmentId>) -> bool) {
let keep = self.id.iter().zip(self.segment_range.iter()).map(|(id, range)| f(id, range)).collect::<Vec<_>>();
let mut iter = keep.iter().copied();
self.segment_range.retain(|_| iter.next().unwrap());
@@ -486,7 +486,7 @@ impl RegionDomain {
self.id.retain(|_| iter.next().unwrap());
}
pub fn push(&mut self, id: RegionId, segment_range: core::ops::RangeInclusive<SegmentId>, fill: FillId) {
pub fn push(&mut self, id: RegionId, segment_range: std::ops::RangeInclusive<SegmentId>, fill: FillId) {
if self.id.contains(&id) {
warn!("Duplicate region");
return;
@@ -504,7 +504,7 @@ impl RegionDomain {
self.id.iter().copied().max_by(|a, b| a.0.cmp(&b.0)).map(|mut id| id.next_id()).unwrap_or(RegionId::ZERO)
}
pub fn segment_range_mut(&mut self) -> impl Iterator<Item = (RegionId, &mut core::ops::RangeInclusive<SegmentId>)> {
pub fn segment_range_mut(&mut self) -> impl Iterator<Item = (RegionId, &mut std::ops::RangeInclusive<SegmentId>)> {
self.id.iter().copied().zip(self.segment_range.iter_mut())
}
@@ -516,7 +516,7 @@ impl RegionDomain {
&self.id
}
pub fn segment_range(&self) -> &[core::ops::RangeInclusive<SegmentId>] {
pub fn segment_range(&self) -> &[std::ops::RangeInclusive<SegmentId>] {
&self.segment_range
}
@@ -545,7 +545,7 @@ impl RegionDomain {
/// Iterates over regions in the domain.
///
/// Tuple is: (id, segment_range, fill)
pub fn iter(&self) -> impl Iterator<Item = (RegionId, core::ops::RangeInclusive<SegmentId>, FillId)> + '_ {
pub fn iter(&self) -> impl Iterator<Item = (RegionId, std::ops::RangeInclusive<SegmentId>, FillId)> + '_ {
let ids = self.id.iter().copied();
let segment_range = self.segment_range.iter().cloned();
let fill = self.fill.iter().copied();
@@ -643,7 +643,7 @@ impl FoundSubpath {
impl VectorData {
/// Construct a [`bezier_rs::Bezier`] curve spanning from the resolved position of the start and end points with the specified handles.
fn segment_to_bezier_with_index(&self, start: usize, end: usize, handles: bezier_rs::BezierHandles) -> bezier_rs::Bezier {
fn segment_to_bezier_with_index(&self, start: usize, end: usize, handles: BezierHandles) -> bezier_rs::Bezier {
let start = self.point_domain.positions()[start];
let end = self.point_domain.positions()[end];
bezier_rs::Bezier { start, end, handles }
@@ -752,15 +752,15 @@ impl VectorData {
}
/// Construct a [`bezier_rs::Bezier`] curve from an iterator of segments with (handles, start point, end point) independently of discontinuities.
pub fn subpath_from_segments_ignore_discontinuities(&self, segments: impl Iterator<Item = (bezier_rs::BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
pub fn subpath_from_segments_ignore_discontinuities(&self, segments: impl Iterator<Item = (BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
let mut first_point = None;
let mut groups = Vec::new();
let mut last: Option<(usize, bezier_rs::BezierHandles)> = None;
let mut last: Option<(usize, BezierHandles)> = None;
for (handle, start, end) in segments {
first_point = Some(first_point.unwrap_or(start));
groups.push(bezier_rs::ManipulatorGroup {
groups.push(ManipulatorGroup {
anchor: self.point_domain.positions()[start],
in_handle: last.and_then(|(_, handle)| handle.end()),
out_handle: handle.start(),
@@ -776,7 +776,7 @@ impl VectorData {
if closed {
groups[0].in_handle = last_handle.end();
} else {
groups.push(bezier_rs::ManipulatorGroup {
groups.push(ManipulatorGroup {
anchor: self.point_domain.positions()[end],
in_handle: last_handle.end(),
out_handle: None,
@@ -789,10 +789,10 @@ impl VectorData {
}
/// Construct a [`bezier_rs::Bezier`] curve from an iterator of segments with (handles, start point, end point). Returns None if any ids are invalid or if the segments are not continuous.
fn subpath_from_segments(&self, segments: impl Iterator<Item = (bezier_rs::BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
fn subpath_from_segments(&self, segments: impl Iterator<Item = (BezierHandles, usize, usize)>) -> Option<bezier_rs::Subpath<PointId>> {
let mut first_point = None;
let mut groups = Vec::new();
let mut last: Option<(usize, bezier_rs::BezierHandles)> = None;
let mut last: Option<(usize, BezierHandles)> = None;
for (handle, start, end) in segments {
if last.is_some_and(|(previous_end, _)| previous_end != start) {
@@ -801,7 +801,7 @@ impl VectorData {
}
first_point = Some(first_point.unwrap_or(start));
groups.push(bezier_rs::ManipulatorGroup {
groups.push(ManipulatorGroup {
anchor: self.point_domain.positions()[start],
in_handle: last.and_then(|(_, handle)| handle.end()),
out_handle: handle.start(),
@@ -817,7 +817,7 @@ impl VectorData {
if closed {
groups[0].in_handle = last_handle.end();
} else {
groups.push(bezier_rs::ManipulatorGroup {
groups.push(ManipulatorGroup {
anchor: self.point_domain.positions()[end],
in_handle: last_handle.end(),
out_handle: None,
@@ -908,13 +908,13 @@ impl VectorData {
})
}
/// Construct an iterator [`bezier_rs::ManipulatorGroup`] for stroke.
pub fn manipulator_groups(&self) -> impl Iterator<Item = bezier_rs::ManipulatorGroup<PointId>> + '_ {
/// Construct an iterator [`ManipulatorGroup`] for stroke.
pub fn manipulator_groups(&self) -> impl Iterator<Item = ManipulatorGroup<PointId>> + '_ {
self.stroke_bezier_paths().flat_map(|mut path| std::mem::take(path.manipulator_groups_mut()))
}
/// Get manipulator by id
pub fn manipulator_group_id(&self, id: impl Into<PointId>) -> Option<bezier_rs::ManipulatorGroup<PointId>> {
pub fn manipulator_group_id(&self, id: impl Into<PointId>) -> Option<ManipulatorGroup<PointId>> {
let id = id.into();
self.manipulator_groups().find(|group| group.id == id)
}
@@ -994,7 +994,7 @@ pub struct StrokePathIter<'a> {
}
impl Iterator for StrokePathIter<'_> {
type Item = (Vec<bezier_rs::ManipulatorGroup<PointId>>, bool);
type Item = (Vec<ManipulatorGroup<PointId>>, bool);
fn next(&mut self) -> Option<Self::Item> {
let current_start = if let Some((index, _)) = self.points.iter().enumerate().skip(self.skip).find(|(_, val)| val.connected() == 1) {
@@ -1016,7 +1016,7 @@ impl Iterator for StrokePathIter<'_> {
loop {
let Some(val) = self.points[point_index].take_first() else {
// Dead end
groups.push(bezier_rs::ManipulatorGroup {
groups.push(ManipulatorGroup {
anchor: self.vector_data.point_domain.positions()[point_index],
in_handle,
out_handle: None,
@@ -1035,7 +1035,7 @@ impl Iterator for StrokePathIter<'_> {
} else {
self.vector_data.segment_domain.end_point()[val.segment_index]
};
groups.push(bezier_rs::ManipulatorGroup {
groups.push(ManipulatorGroup {
anchor: self.vector_data.point_domain.positions()[point_index],
in_handle,
out_handle: handles.start(),

View File

@@ -3,10 +3,10 @@ use crate::Ctx;
use crate::instances::Instance;
use crate::uuid::generate_uuid;
use bezier_rs::BezierHandles;
use core::hash::BuildHasher;
use dyn_any::DynAny;
use kurbo::{BezPath, PathEl, Point};
use std::collections::{HashMap, HashSet};
use std::hash::BuildHasher;
/// Represents a procedural change to the [`PointDomain`] in [`VectorData`].
#[derive(Clone, Debug, Default, PartialEq)]
@@ -260,7 +260,7 @@ pub struct RegionModification {
add: Vec<RegionId>,
remove: HashSet<RegionId>,
#[serde(serialize_with = "serialize_hashmap", deserialize_with = "deserialize_hashmap")]
segment_range: HashMap<RegionId, core::ops::RangeInclusive<SegmentId>>,
segment_range: HashMap<RegionId, std::ops::RangeInclusive<SegmentId>>,
#[serde(serialize_with = "serialize_hashmap", deserialize_with = "deserialize_hashmap")]
fill: HashMap<RegionId, FillId>,
}
@@ -416,8 +416,8 @@ impl VectorModification {
}
}
impl core::hash::Hash for VectorModification {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
impl Hash for VectorModification {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
generate_uuid().hash(state)
}
}

View File

@@ -14,13 +14,13 @@ use crate::vector::style::{PaintOrder, StrokeAlign, StrokeCap, StrokeJoin};
use crate::vector::{FillId, PointDomain, RegionId};
use crate::{CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicElement, GraphicGroupTable, OwnedContextImpl};
use bezier_rs::{Join, ManipulatorGroup, Subpath};
use core::f64::consts::PI;
use core::hash::{Hash, Hasher};
use glam::{DAffine2, DVec2};
use kurbo::{Affine, BezPath, DEFAULT_ACCURACY, ParamCurve, PathEl, PathSeg, Point, Shape};
use rand::{Rng, SeedableRng};
use std::collections::hash_map::DefaultHasher;
use std::f64::consts::PI;
use std::f64::consts::TAU;
use std::hash::{Hash, Hasher};
/// Implemented for types that can be converted to an iterator of vector data.
/// Used for the fill and stroke node so they can be used on VectorData or GraphicGroup
@@ -1949,7 +1949,7 @@ mod test {
pub struct FutureWrapperNode<T: Clone>(T);
impl<'i, T: 'i + Clone + Send> Node<'i, Footprint> for FutureWrapperNode<T> {
type Output = Pin<Box<dyn core::future::Future<Output = T> + 'i + Send>>;
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 })
@@ -2011,7 +2011,7 @@ mod test {
// 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(core::f64::consts::FRAC_PI_4);
*square.get_mut(0).unwrap().transform *= DAffine2::from_angle(std::f64::consts::FRAC_PI_4);
let bounding_box = BoundingBoxNode {
vector_data: FutureWrapperNode(square),
}
@@ -2111,7 +2111,7 @@ mod test {
}
#[track_caller]
fn contains_segment(vector: VectorData, target: bezier_rs::Bezier) {
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!(
@@ -2132,16 +2132,16 @@ mod test {
assert_eq!(beveled.segment_domain.ids().len(), 8);
// Segments
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(95., 0.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(95., 100.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(0., 5.), DVec2::new(0., 95.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 5.), DVec2::new(100., 95.)));
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_rs::Bezier::from_linear_dvec2(DVec2::new(5., 0.), DVec2::new(0., 5.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(95., 0.), DVec2::new(100., 5.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 95.), DVec2::new(95., 100.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(5., 100.), DVec2::new(0., 95.)));
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]
@@ -2155,12 +2155,12 @@ mod test {
assert_eq!(beveled.segment_domain.ids().len(), 3);
// Segments
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-100., 0.)));
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_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
}
#[tokio::test]
@@ -2179,12 +2179,12 @@ mod test {
assert_eq!(beveled.segment_domain.ids().len(), 3);
// Segments
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(-10., 0.)));
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_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(DVec2::new(-5., 0.), trimmed.start));
}
#[tokio::test]
@@ -2197,13 +2197,13 @@ mod test {
assert_eq!(beveled.segment_domain.ids().len(), 5);
// Segments
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(0., 0.), DVec2::new(50., 0.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(100., 50.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
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_rs::Bezier::from_linear_dvec2(DVec2::new(50., 0.), DVec2::new(100., 50.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(100., 50.), DVec2::new(50., 100.)));
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]
@@ -2218,11 +2218,11 @@ mod test {
assert_eq!(beveled.segment_domain.ids().len(), 5);
// Segments
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-100., 0.), DVec2::new(-5., 0.)));
contains_segment(beveled.clone(), bezier_rs::Bezier::from_linear_dvec2(DVec2::new(-5., 0.), DVec2::new(0., 0.)));
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_rs::Bezier::from_linear_dvec2(start.start, start.end));
contains_segment(beveled.clone(), Bezier::from_linear_dvec2(start.start, start.end));
contains_segment(beveled.clone(), end);
}
}