Experimental vector meshes (#2223)

* Experimental vector meshes

* Clarify limitations in label and tooltip

* Restore old traversal direction

* Fix Bezier-rs crashes

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
James Lindsay 2025-01-26 01:13:35 +00:00 committed by GitHub
parent 26d66298cf
commit 93880abc4c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 102 additions and 78 deletions

View file

@ -55,6 +55,7 @@ glam = { workspace = true, default-features = false, features = [
# Required dependencies
half = { version = "2.4.1", default-features = false, features = ["bytemuck"] }
tinyvec = { version = "1" }
# Optional workspace dependencies
dyn-any = { workspace = true, optional = true }

View file

@ -243,14 +243,12 @@ impl VectorData {
self.point_domain.resolve_id(point).map_or(0, |point| self.segment_domain.connected_count(point))
}
/// Points connected to a single segment
pub fn single_connected_points(&self) -> impl Iterator<Item = PointId> + '_ {
self.point_domain
.ids()
.iter()
.enumerate()
.filter(|(index, _)| self.segment_domain.connected_count(*index) == 1)
.map(|(_, &id)| id)
/// Points that can be extended from.
///
/// This is usually only points with exactly one connection unless vector meshes are enabled.
pub fn extendable_points(&self, vector_meshes: bool) -> impl Iterator<Item = PointId> + '_ {
let point_ids = self.point_domain.ids().iter().enumerate();
point_ids.filter(move |(index, _)| vector_meshes || self.segment_domain.connected_count(*index) == 1).map(|(_, &id)| id)
}
/// Computes if all the connected handles are colinear for an anchor, or if that handle is colinear for a handle.

View file

@ -654,7 +654,7 @@ impl super::VectorData {
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
struct StrokePathIterPointSegmentMetadata {
segment_index: usize,
start_from_end: bool,
@ -675,28 +675,24 @@ impl StrokePathIterPointSegmentMetadata {
}
#[derive(Clone, Default)]
struct StrokePathIterPointMetadata([Option<StrokePathIterPointSegmentMetadata>; 2]);
struct StrokePathIterPointMetadata(tinyvec::TinyVec<[StrokePathIterPointSegmentMetadata; 2]>);
impl StrokePathIterPointMetadata {
fn set(&mut self, value: StrokePathIterPointSegmentMetadata) {
if self.0[0].is_none() {
self.0[0] = Some(value)
} else if self.0[1].is_none() {
self.0[1] = Some(value);
} else {
panic!("Mesh networks are not supported");
}
self.0.insert(0, value);
}
#[must_use]
fn connected(&self) -> usize {
self.0.iter().filter(|val| val.is_some()).count()
self.0.len()
}
#[must_use]
fn take_first(&mut self) -> Option<StrokePathIterPointSegmentMetadata> {
self.0[0].take().or_else(|| self.0[1].take())
self.0.pop()
}
fn take_eq(&mut self, target: StrokePathIterPointSegmentMetadata) -> bool {
self.0[0].take_if(|&mut value| value == target).or_else(|| self.0[1].take_if(|&mut value| value == target)).is_some()
let has_taken = self.0.contains(&target);
self.0.retain(|value| *value != target);
has_taken
}
}