Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,028 changes: 754 additions & 274 deletions node-graph/libraries/core-types/src/list.rs

Large diffs are not rendered by default.

47 changes: 42 additions & 5 deletions node-graph/libraries/vector-types/src/vector/addressing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::connectivity::Connectivity;
use super::misc::HandleId;
use super::path::{CurveType, Path, curve_type_at};
use super::path::{CurveType, Path, curve_type_at, curve_types_of};
use super::vector_attributes::{PointId, SegmentId};
use core_types::list::{ATTR_ID, List};
use glam::DVec2;
Expand All @@ -27,9 +27,46 @@ impl Span {

/// Every span of every path, in path order.
pub fn spans(paths: &List<Path>) -> impl Iterator<Item = Span> + '_ {
paths.iter_element_values().enumerate().flat_map(|(path_index, path)| {
let curve_type = curve_type_at(paths, path_index);
(0..path.segment_count(curve_type) as u32).map(move |index| Span { path: path_index as u32, index })
let paths_with_curve_types = paths.iter_element_values().zip(curve_types_of(paths)).enumerate();

paths_with_curve_types.flat_map(|(path_index, (path, curve_type))| (0..path.segment_count(curve_type) as u32).map(move |index| Span { path: path_index as u32, index }))
}

/// A span together with what its path holds for it.
pub(crate) struct ResolvedSpan<'a> {
pub span: Span,
pub path: &'a Path,
pub curve_type: CurveType,
/// The span's stable ID, absent when its path names no spans.
pub id: Option<SegmentId>,
/// The pool points the span runs between.
pub endpoints: (u32, u32),
}

/// Every span of every path in path order, resolved in O(references) by reading each path's curve type, references, and IDs once.
pub(crate) fn resolved_spans(paths: &List<Path>) -> impl Iterator<Item = ResolvedSpan<'_>> + '_ {
paths.iter_element_values().zip(curve_types_of(paths)).enumerate().flat_map(move |(path_index, (path, curve_type))| {
let stride = curve_type.stride();
let references = path.0.iter_element_values().as_slice();
let ids = path.0.iter_attribute_values::<SegmentId>(ATTR_ID).map(|ids| ids.as_slice());

(0..path.segment_count(curve_type)).filter_map(move |index| {
let reference = index * stride;
let endpoints = (*references.get(reference)? as u32, *references.get(reference + stride)? as u32);
let span = Span {
path: path_index as u32,
index: index as u32,
};
let id = ids.and_then(|ids| ids.get(reference).copied());

Some(ResolvedSpan {
span,
path,
curve_type,
id,
endpoints,
})
})
})
}

Expand All @@ -44,7 +81,7 @@ pub fn segment_id_of(paths: &List<Path>, span: Span) -> Option<SegmentId> {

/// The span a segment ID names, found by scanning every span in O(references).
pub fn span_of_segment_id(paths: &List<Path>, segment: SegmentId) -> Option<Span> {
spans(paths).find(|&span| segment_id_of(paths, span) == Some(segment))
resolved_spans(paths).find(|resolved| resolved.id == Some(segment)).map(|resolved| resolved.span)
}

/// The pool points a span runs between.
Expand Down
7 changes: 3 additions & 4 deletions node-graph/libraries/vector-types/src/vector/connectivity.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::path::{CurveType, Path, curve_type_at};
use super::path::{CurveType, Path, curve_types_of};
use core_types::list::List;

/// One path's reference to a pool point, naming where in the weave that point is used.
Expand Down Expand Up @@ -49,9 +49,8 @@ impl Connectivity {

let mut cursors = starts[..point_count].to_vec();
let mut references = vec![Reference::default(); starts[point_count] as usize];
for (path_index, path) in paths.iter_element_values().enumerate() {
// Each path's curve type is read once here, so queries never look it up again
let curve_type = curve_type_at(paths, path_index);
// Each path's curve type is read once here, so queries never look it up again
for ((path_index, path), curve_type) in paths.iter_element_values().enumerate().zip(curve_types_of(paths)) {
let last = path.0.len().saturating_sub(1);

for (reference_index, point) in path.references().enumerate() {
Expand Down
4 changes: 2 additions & 2 deletions node-graph/libraries/vector-types/src/vector/contour.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::misc::dvec2_to_point;
use super::path::{CurveType, Path, append_segment, curve_type_at};
use super::path::{CurveType, Path, append_segment, curve_types_of};
use core_types::list::List;
use glam::DVec2;
use kurbo::BezPath;
Expand Down Expand Up @@ -94,7 +94,7 @@ pub fn contours(point_count: usize, paths: &List<Path>) -> Vec<Contour> {

/// The curve type of every path, read once so the stitching below never looks one up per path.
fn curve_types(paths: &List<Path>) -> Vec<CurveType> {
(0..paths.len()).map(|index| curve_type_at(paths, index)).collect()
curve_types_of(paths).collect()
}

fn contours_with(point_count: usize, paths: &List<Path>, curve_types: &[CurveType]) -> Vec<Contour> {
Expand Down
16 changes: 7 additions & 9 deletions node-graph/libraries/vector-types/src/vector/flatten.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::misc::{BezierHandles, HandleId, HandleType, segment_to_handles};
use super::path::{CurveType, Path, continues_previous_path, curve_type_at, push_path};
use super::path::{CurveType, Path, continues_previous_path, curve_types_of, push_paths};
use super::vector_attributes::{PointId, SegmentId};
use super::vector_types::Vector;
use core_types::list::{ATTR_ID, List};
Expand Down Expand Up @@ -44,8 +44,7 @@ impl WorkingVector {
let working_point = |pool_index: u32| pool_to_working.get(pool_index as usize).copied().flatten();

// One pass so a span that fails to resolve leaves every array at the same length
for (path_index, path) in paths.iter_element_values().enumerate() {
let curve_type = curve_type_at(paths, path_index);
for ((path_index, path), curve_type) in paths.iter_element_values().enumerate().zip(curve_types_of(paths)) {
let stride = curve_type.stride();
let span_ids = path.0.iter_attribute_values::<SegmentId>(ATTR_ID).map(|ids| ids.as_slice()).unwrap_or_default();

Expand Down Expand Up @@ -223,9 +222,7 @@ impl WorkingVector {
vector.0.set_attribute_values(ATTR_ID, point_ids);
}

for (curve_type, references, ids) in runs {
push_path(paths, curve_type, references, ids);
}
push_paths(paths, runs);

// G1 pairs narrow to the smooth flag on the anchor both handles face, and other pairings are dropped
let anchor = |handle: HandleId| {
Expand Down Expand Up @@ -331,9 +328,9 @@ pub(crate) fn chain_order(point_count: usize, endpoints: &[(usize, usize)], dire
let mut partner = vec![usize::MAX; segment_count * 2];
for ends in ends_at.iter().filter(|ends| ends.len() >= 2) {
if ends.len() > MOST_ENDS_PAIRED_BY_STRAIGHTNESS {
for pair in ends.chunks_exact(2) {
partner[pair[0]] = pair[1];
partner[pair[1]] = pair[0];
for &[first, second] in ends.as_chunks::<2>().0 {
partner[first] = second;
partner[second] = first;
}
continue;
}
Expand Down Expand Up @@ -509,6 +506,7 @@ pub fn vector_from_legacy_parts(
#[cfg(test)]
mod tests {
use super::*;
use crate::vector::path::{curve_type_at, push_path};
use core_types::list::{ATTR_CURVE_TYPE, ATTR_ID, ATTR_SMOOTH, Item};

fn working(points: usize, segments: &[(usize, usize, BezierHandles)]) -> WorkingVector {
Expand Down
4 changes: 0 additions & 4 deletions node-graph/libraries/vector-types/src/vector/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,6 @@ impl VectorGeometry {
self.vector.bezpath_from_segments_ignore_discontinuities(segments)
}

pub fn point_tangent(&self, point_index: usize) -> Option<DVec2> {
self.vector.point_tangent(&self.paths, point_index)
}

/// The manipulator's position in layer space. See [`ManipulatorPointId::get_position`].
pub fn position_of(&self, point: ManipulatorPointId) -> Option<DVec2> {
point.get_position(&self.vector, &self.paths)
Expand Down
Loading
Loading