threecrate_core/
point_cloud.rs

1//! Point cloud data structures and functionality
2
3use crate::point::*;
4use crate::transform::Transform3D;
5// use nalgebra::{Point3, Vector3};
6use serde::{Deserialize, Serialize};
7use std::ops::{Index, IndexMut};
8
9/// A generic point cloud container
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct PointCloud<T> {
12    pub points: Vec<T>,
13}
14
15/// A point cloud with 3D points
16pub type PointCloud3f = PointCloud<Point3f>;
17
18/// A point cloud with colored points
19pub type ColoredPointCloud3f = PointCloud<ColoredPoint3f>;
20
21/// A point cloud with normal vectors
22pub type NormalPointCloud3f = PointCloud<NormalPoint3f>;
23
24/// A point cloud with colors and normals
25pub type ColoredNormalPointCloud3f = PointCloud<ColoredNormalPoint3f>;
26
27impl<T> PointCloud<T> {
28    /// Create a new empty point cloud
29    pub fn new() -> Self {
30        Self {
31            points: Vec::new(),
32        }
33    }
34
35    /// Create a new point cloud with specified capacity
36    pub fn with_capacity(capacity: usize) -> Self {
37        Self {
38            points: Vec::with_capacity(capacity),
39        }
40    }
41
42    /// Create a point cloud from a vector of points
43    pub fn from_points(points: Vec<T>) -> Self {
44        Self { points }
45    }
46
47    /// Get the number of points in the cloud
48    pub fn len(&self) -> usize {
49        self.points.len()
50    }
51
52    /// Check if the point cloud is empty
53    pub fn is_empty(&self) -> bool {
54        self.points.is_empty()
55    }
56
57    /// Add a point to the cloud
58    pub fn push(&mut self, point: T) {
59        self.points.push(point);
60    }
61
62    /// Get an iterator over the points
63    pub fn iter(&self) -> std::slice::Iter<T> {
64        self.points.iter()
65    }
66
67    /// Get a mutable iterator over the points
68    pub fn iter_mut(&mut self) -> std::slice::IterMut<T> {
69        self.points.iter_mut()
70    }
71
72    /// Clear all points from the cloud
73    pub fn clear(&mut self) {
74        self.points.clear();
75    }
76
77    /// Reserve capacity for additional points
78    pub fn reserve(&mut self, additional: usize) {
79        self.points.reserve(additional);
80    }
81}
82
83impl<T> Default for PointCloud<T> {
84    fn default() -> Self {
85        Self::new()
86    }
87}
88
89impl<T> Index<usize> for PointCloud<T> {
90    type Output = T;
91
92    fn index(&self, index: usize) -> &Self::Output {
93        &self.points[index]
94    }
95}
96
97impl<T> IndexMut<usize> for PointCloud<T> {
98    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
99        &mut self.points[index]
100    }
101}
102
103impl<T> IntoIterator for PointCloud<T> {
104    type Item = T;
105    type IntoIter = std::vec::IntoIter<T>;
106
107    fn into_iter(self) -> Self::IntoIter {
108        self.points.into_iter()
109    }
110}
111
112impl<'a, T> IntoIterator for &'a PointCloud<T> {
113    type Item = &'a T;
114    type IntoIter = std::slice::Iter<'a, T>;
115
116    fn into_iter(self) -> Self::IntoIter {
117        self.points.iter()
118    }
119}
120
121impl<'a, T> IntoIterator for &'a mut PointCloud<T> {
122    type Item = &'a mut T;
123    type IntoIter = std::slice::IterMut<'a, T>;
124
125    fn into_iter(self) -> Self::IntoIter {
126        self.points.iter_mut()
127    }
128}
129
130impl<T> Extend<T> for PointCloud<T> {
131    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
132        self.points.extend(iter);
133    }
134}
135
136impl<T> FromIterator<T> for PointCloud<T> {
137    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
138        Self {
139            points: Vec::from_iter(iter),
140        }
141    }
142}
143
144impl PointCloud<Point3f> {
145    /// Apply a transformation to all points in the cloud
146    pub fn transform(&mut self, transform: &Transform3D) {
147        for point in &mut self.points {
148            *point = transform.transform_point(point);
149        }
150    }
151}