1use nalgebra::Point3;
2
3use crate::ArraySequence;
4
5pub type Point = Point3<f32>;
6pub type Points = Vec<Point>;
7pub type Streamlines = ArraySequence<Point>;
8
9pub type TractogramItem = (Points, ArraySequence<f32>, Vec<f32>);
10pub type RefTractogramItem<'data> = (&'data [Point], &'data [f32], &'data [f32]);
11
12#[derive(Clone, PartialEq)]
13pub struct Tractogram {
14 pub streamlines: Streamlines,
15 pub scalars: ArraySequence<f32>,
16 pub properties: ArraySequence<f32>,
17}
18
19impl Tractogram {
20 pub fn new(
21 streamlines: Streamlines,
22 scalars: ArraySequence<f32>,
23 properties: ArraySequence<f32>,
24 ) -> Tractogram {
25 Tractogram { streamlines, scalars, properties }
26 }
27
28 pub fn item(&self, idx: usize) -> RefTractogramItem {
29 let scalars = if self.scalars.is_empty() { &[] } else { &self.scalars[idx] };
32 let properties = if self.properties.is_empty() { &[] } else { &self.properties[idx] };
33 (&self.streamlines[idx], scalars, properties)
34 }
35}
36
37impl<'data> IntoIterator for &'data Tractogram {
38 type Item = RefTractogramItem<'data>;
39 type IntoIter = TractogramIterator<'data>;
40
41 fn into_iter(self) -> Self::IntoIter {
42 TractogramIterator { tractogram: self, index: 0..self.streamlines.len() }
43 }
44}
45
46pub struct TractogramIterator<'data> {
47 tractogram: &'data Tractogram,
48 index: std::ops::Range<usize>,
49}
50
51impl<'data> Iterator for TractogramIterator<'data> {
52 type Item = RefTractogramItem<'data>;
53
54 fn next(&mut self) -> Option<Self::Item> {
55 let idx = self.index.next()?;
56 Some(self.tractogram.item(idx))
57 }
58
59 fn size_hint(&self) -> (usize, Option<usize>) {
60 (0, Some(self.tractogram.streamlines.len()))
61 }
62}
63
64impl<'data> ExactSizeIterator for TractogramIterator<'data> {}
65
66impl<'data> DoubleEndedIterator for TractogramIterator<'data> {
67 fn next_back(&mut self) -> Option<Self::Item> {
68 let idx = self.index.next_back()?;
69 Some(self.tractogram.item(idx))
70 }
71}