mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 02:48:12 +08:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user