1use crate::{
2 decode::{Decoder, DecoderBuffer},
3 encode::{Encoder, EncoderBuffer},
4 prelude::*,
5};
6use autocxx::prelude::*;
7
8pub type PointCloudBuilder = WrappedDracoObject<ffi::draco::PointCloudBuilder>;
9
10impl PointCloudBuilder {
11 pub fn new(num: u32) -> Self {
12 let mut builder = ffi::draco::PointCloudBuilder::new().within_unique_ptr();
13 builder.pin_mut().Start(num);
14 Self(builder)
15 }
16
17 pub fn add_attribute(
18 &mut self,
19 attribute_type: ffi::draco::GeometryAttribute_Type,
20 num_components: i8,
21 data_type: ffi::draco::DataType,
22 ) -> AttrId {
23 self.0
24 .pin_mut()
25 .AddAttribute(attribute_type, num_components, data_type)
26 .into()
27 }
28
29 pub fn add_point<T>(
36 &mut self,
37 attr_id: AttrId,
38 point_index: impl Into<ffi::draco::PointIndex>,
39 point: &[T],
40 ) {
41 unsafe { self.add_point_with_ptr(attr_id, point_index, point.as_ptr() as *const c_void) }
42 }
43
44 pub unsafe fn add_point_with_ptr(
54 &mut self,
55 attr_id: AttrId,
56 point_index: impl Into<ffi::draco::PointIndex>,
57 ptr: *const c_void,
58 ) {
59 self.0
60 .pin_mut()
61 .SetAttributeValueForPoint(attr_id.into(), point_index.into(), ptr);
62 }
63
64 pub fn build(mut self, deduplicate_points: bool) -> PointCloud {
65 PointCloud {
66 0: self.0.pin_mut().Finalize(deduplicate_points),
67 }
68 }
69}
70
71pub type PointCloud = WrappedDracoObject<ffi::draco::PointCloud>;
72
73impl Default for PointCloud {
74 fn default() -> Self {
75 Self::new()
76 }
77}
78
79impl PointCloud {
80 pub fn new() -> Self {
81 let pc = ffi::draco::PointCloud::new().within_unique_ptr();
82 Self(pc)
83 }
84
85 pub fn get_point<T>(
88 &mut self,
89 attr_id: AttrId,
90 point_index: impl Into<ffi::draco::PointIndex>,
91 point_container: &mut [T],
92 ) where
93 T: Default + Copy,
94 {
95 let pa_ptr = self.0.pin_mut().GetAttributeByUniqueId(attr_id.as_u32());
96 unsafe {
97 (*pa_ptr).GetMappedValue(
98 point_index.into(),
99 point_container.as_mut_ptr() as *mut c_void,
100 );
101 };
102 }
103
104 pub fn get_point_alloc<T, const N: usize>(
106 &mut self,
107 attr_id: AttrId,
108 point_index: impl Into<ffi::draco::PointIndex>,
109 ) -> [T; N]
110 where
111 T: Default + Copy,
112 {
113 let mut point = [T::default(); N];
114 self.get_point(attr_id, point_index, &mut point);
115 point
116 }
117
118 pub fn num_named_attributes(&self, attr_type: ffi::draco::GeometryAttribute_Type) -> i32 {
120 self.0.NumNamedAttributes(attr_type)
121 }
122
123 pub fn get_named_attribute_id(
125 &self,
126 attr_type: ffi::draco::GeometryAttribute_Type,
127 i: i32,
128 ) -> Option<AttrId> {
129 let id = self.0.GetNamedAttributeId1(attr_type, i.into());
130 if id < 0 {
131 None
132 } else {
133 Some(AttrId(id))
134 }
135 }
136
137 pub fn num_points(&self) -> u32 {
166 self.0.num_points()
167 }
168
169 pub fn len(&self) -> u32 {
170 self.0.num_points()
171 }
172
173 pub fn is_empty(&self) -> bool {
174 self.0.num_points() == 0
175 }
176
177 pub fn to_buffer(&self, encoder: &mut Encoder) -> DracoStatusType<EncoderBuffer> {
179 let mut buffer = EncoderBuffer::new();
180
181 let status = unsafe {
182 encoder
183 .0
184 .pin_mut()
185 .EncodePointCloudToBuffer(self.0.as_ref().unwrap(), buffer.as_mut_ptr())
186 .within_unique_ptr()
187 };
188
189 if status.ok() {
190 Ok(buffer)
191 } else {
192 Err(status.into())
193 }
194 }
195
196 pub fn from_buffer(decoder: &mut Decoder, buffer: &mut DecoderBuffer) -> DracoStatusType<Self> {
202 let mut status_or = unsafe {
203 decoder
204 .decoder
205 .pin_mut()
206 .DecodePointCloudFromBuffer(buffer.0.as_mut_ptr())
207 };
208 if status_or.ok() {
209 Ok(Self(status_or.pin_mut().value()))
210 } else {
211 Err(status_or.status().within_unique_ptr().into())
212 }
213 }
214}