1use crate::{safety_assert, safety_assert_eq};
2use serde::ser::SerializeSeq;
3use serde::Serialize;
4use std::{mem, ptr};
5
6use crate::attribute::ComponentDataType;
7use crate::types::Vector;
8use crate::types::{AttributeValueIdx, DataValue};
9
10use super::RawBuffer;
11
12pub struct AttributeBuffer {
13 data: RawBuffer,
15
16 len: usize,
18
19 #[allow(unused)]
21 last: *mut u8,
22
23 component_type: ComponentDataType,
25
26 num_components: usize,
27}
28
29impl AttributeBuffer {
30 pub fn new(component_type: ComponentDataType, num_components: usize) -> Self {
31 let data = RawBuffer::with_capacity(0);
32 let len = 0;
33 let last = unsafe {
34 data.as_ptr()
35 .add(len * component_type.size() * num_components)
36 };
37
38 Self {
39 data,
40 len,
41 last,
42 component_type,
43 num_components,
44 }
45 }
46
47 fn as_ptr(&self) -> *mut u8 {
48 self.data.as_ptr()
49 }
50
51 pub fn get<Data, const N: usize>(&self, idx: AttributeValueIdx) -> Data
52 where
53 Data: Vector<N>,
54 Data::Component: DataValue,
55 {
56 let idx_usize = usize::from(idx);
57 assert!(
58 size_of::<Data>() == self.component_type.size() * self.num_components,
59 "Cannot read from buffer: Trying to read data of size {}, but the buffer stores the elements of size {} with {} components",
60 size_of::<Data>(), self.component_type.size(), self.num_components
61 );
62 assert!(idx_usize < self.len, "Index out of bounds: The index {} is out of bounds for the attribute buffer with length {}", idx_usize, self.len);
63 unsafe { self.get_unchecked::<Data, N>(idx) }
65 }
66
67 pub unsafe fn get_unchecked<Data, const N: usize>(&self, idx: AttributeValueIdx) -> Data
72 where
73 Data: Vector<N>,
74 Data::Component: DataValue,
75 {
76 let idx = usize::from(idx);
77 safety_assert!(
78 size_of::<Data>() == self.component_type.size() * self.num_components,
79 "Cannot read from buffer: Trying to read {}, but the buffer stores the elements of type {} with {} components",
80 size_of::<Data>(), self.component_type.size(), self.num_components
81 );
82 safety_assert!(idx < self.len, "Index out of bounds: The index {} is out of bounds for the attribute buffer with length {}", idx, self.len);
83 let size = mem::size_of::<Data>();
84 let ptr = unsafe { self.as_ptr().add(size * idx) };
85 ptr::read(ptr as *const Data)
87 }
88
89 pub fn get_component_type(&self) -> ComponentDataType {
90 self.component_type
91 }
92
93 pub fn set_component_type(&mut self, component_type: ComponentDataType) {
94 self.component_type = component_type;
95 }
96
97 pub fn set_num_components(&mut self, num_components: usize) {
98 self.num_components = num_components;
99 }
100
101 pub fn get_num_components(&self) -> usize {
102 self.num_components
103 }
104
105 #[allow(unused)]
106 pub fn push<Data, const N: usize>(&mut self, data: Data)
107 where
108 Data: Vector<N>,
109 Data::Component: DataValue,
110 {
111 assert_eq!(
112 Data::Component::get_dyn(),
113 self.component_type,
114 "Data type mismatch: Cannot push data of type {:?} into attribute buffer of type {:?}",
115 Data::Component::get_dyn(),
116 self.component_type
117 );
118 assert!(
119 N == self.num_components,
120 "Number of components mismatch: Cannot push data with {} components into attribute buffer with {} components",
121 N, self.num_components
122 );
123 unsafe {
124 self.push_type_unchecked(data);
125 }
126 }
127
128 pub unsafe fn push_type_unchecked<Data, const N: usize>(&mut self, data: Data)
132 where
133 Data: Vector<N>,
134 Data::Component: DataValue,
135 {
136 safety_assert_eq!(
137 Data::Component::get_dyn(), self.component_type,
138 "Unsafe Condition Failed: Data type mismatch: Cannot push data of type {:?} into attribute buffer of type {:?}",
139 Data::Component::get_dyn(), self.component_type
140 );
141 safety_assert!(
142 N == self.num_components,
143 "Unsafe Condition Failed: Number of components mismatch: Cannot push data with {} components into attribute buffer with {} components",
144 N, self.num_components
145 );
146
147 self.len += 1;
148 if self.len * size_of::<Data>() > self.data.cap {
149 self.data.double();
150 }
151
152 ptr::write(self.last as *mut Data, data);
153 }
154
155 #[inline(always)]
156 pub fn len(&self) -> usize {
158 self.len
159 }
160
161 #[inline]
162 pub unsafe fn as_slice<Data>(&self) -> &[Data] {
166 safety_assert!(
167 mem::size_of::<Data>() == self.component_type.size() * self.num_components,
168 "Cannot create slice: Trying to cast to data of size {}, but the buffer stores elements of type {}D vector of {:?}, which has size {}",
169 mem::size_of::<Data>(),
170 self.num_components,
171 self.component_type,
172 self.component_type.size(),
173 );
174
175 std::slice::from_raw_parts(self.as_ptr() as *const Data, self.len)
176 }
177
178 #[inline]
179 pub unsafe fn as_slice_mut<Data>(&mut self) -> &mut [Data] {
183 safety_assert!(
184 mem::size_of::<Data>() == self.component_type.size() * self.num_components,
185 "Cannot create slice: Trying to cast to data of size {}, but the buffer stores elements of type {}D vector of {:?}, which has size {}",
186 mem::size_of::<Data>(),
187 self.num_components,
188 self.component_type,
189 self.component_type.size(),
190 );
191
192 std::slice::from_raw_parts_mut(self.as_ptr() as *mut Data, self.len)
193 }
194
195 #[allow(unused)]
196 pub unsafe fn into_vec<Data, const N: usize>(self) -> Vec<Data>
197 where
198 Data: Vector<N>,
199 {
200 assert_eq!(
201 Data::Component::get_dyn(),
202 self.component_type,
203 "Data type mismatch: Cannot push data of type {:?} into attribute buffer of type {:?}",
204 Data::Component::get_dyn(),
205 self.component_type
206 );
207 assert!(
208 N == self.num_components,
209 "Number of components mismatch: Cannot push data with {} components into attribute buffer with {} components",
210 N, self.num_components
211 );
212
213 self.into_vec_unchecked()
214 }
215
216 pub unsafe fn into_vec_unchecked<Data, const N: usize>(self) -> Vec<Data>
217 where
218 Data: Vector<N>,
219 {
220 safety_assert_eq!(
221 Data::Component::get_dyn(),
222 self.component_type,
223 "Data type mismatch: Cannot push data of type {:?} into attribute buffer of type {:?}",
224 Data::Component::get_dyn(),
225 self.component_type
226 );
227 safety_assert!(
228 N == self.num_components,
229 "Number of components mismatch: Cannot push data with {} components into attribute buffer with {} components",
230 N, self.num_components
231 );
232
233 unsafe {
234 let slice = self.as_slice::<Data>();
235 Vec::from_raw_parts(slice.as_ptr() as *mut Data, self.len, self.len)
236 }
237 }
238
239 #[inline]
240 pub fn as_slice_u8(&self) -> &[u8] {
242 unsafe {
243 std::slice::from_raw_parts(
244 self.as_ptr(),
245 self.len * self.num_components * self.component_type.size(),
246 )
247 }
248 }
249
250 pub unsafe fn permute_unchecked(&mut self, permutation: &[usize]) {
255 safety_assert_eq!(
256 self.len,
257 permutation.len(),
258 "Permutation length does not match the buffer length"
259 );
260 safety_assert!(
261 {
262 let mut p = permutation.to_vec();
263 p.sort();
264 p.into_iter().enumerate().all(|(i, x)| i == x)
265 },
266 "Permutation is not a valid permutation: This violates the safety contract of the function, so need to get resolved immediately. permutation: {:?}",
267 permutation
268 );
269 let mut tmp_att = self.clone();
270
271 let elem_size = self.num_components * self.component_type.size();
272 for (i, &new_idx) in permutation.iter().enumerate() {
273 let src = unsafe { self.as_ptr().add(i * elem_size) };
276 let dst = unsafe { tmp_att.as_ptr().add(new_idx * elem_size) };
277 unsafe {
278 std::ptr::copy_nonoverlapping(src, dst, elem_size);
279 }
280 }
281 mem::swap(self, &mut tmp_att);
282 }
283
284 pub unsafe fn swap_unchecked(&mut self, i: usize, j: usize) {
288 safety_assert!(i < self.len, "Index out of bounds: The index {} is out of bounds for the attribute buffer with length {}", i, self.len);
289 safety_assert!(j < self.len, "Index out of bounds: The index {} is out of bounds for the attribute buffer with length {}", j, self.len);
290
291 let elem_size = self.num_components * self.component_type.size();
292 let ptr_i = unsafe { self.as_ptr().add(i * elem_size) };
293 let ptr_j = unsafe { self.as_ptr().add(j * elem_size) };
294 unsafe {
295 std::ptr::copy_nonoverlapping(ptr_i, ptr_j, elem_size);
296 }
297 }
298
299 pub fn from_vec<Data, const N: usize>(data: Vec<Data>) -> Self
300 where
301 Data: Vector<N>,
302 Data::Component: DataValue,
303 {
304 let component_type = Data::Component::get_dyn();
305 let num_components = N;
306 let len = data.len();
307 let buffer = RawBuffer::from_vec(data);
308 let last = unsafe { buffer.as_ptr().add(len * mem::size_of::<Data>()) };
309
310 Self {
311 data: buffer,
312 len,
313 last,
314 component_type,
315 num_components,
316 }
317 }
318
319 pub fn remove<Data, const N: usize>(&mut self, i: usize) {
320 assert!(i < self.len, "Index out of bounds: The index {} is out of bounds for the attribute buffer with length {}", i, self.len);
321 let elem_size = self.num_components * self.component_type.size();
322 let ptr = unsafe { self.as_ptr().add(i * elem_size) };
323 unsafe {
324 std::ptr::copy(ptr.add(elem_size), ptr, (self.len - i - 1) * elem_size);
325 }
326 self.len -= 1;
327 self.last = unsafe { self.as_ptr().add(self.len * elem_size) };
329 }
330
331 pub fn retain_indices(&mut self, keep_indices: &[usize]) {
334 let elem_size = self.num_components * self.component_type.size();
335 let mut write_pos = 0;
336 for &idx in keep_indices {
337 safety_assert!(
338 idx < self.len,
339 "retain_indices: index {} out of bounds (len {})",
340 idx,
341 self.len
342 );
343 if write_pos != idx {
344 unsafe {
345 let src = self.as_ptr().add(idx * elem_size);
346 let dst = self.as_ptr().add(write_pos * elem_size);
347 ptr::copy_nonoverlapping(src, dst, elem_size);
348 }
349 }
350 write_pos += 1;
351 }
352 self.len = keep_indices.len();
353 self.last = unsafe { self.as_ptr().add(self.len * elem_size) };
354 }
355}
356
357impl Serialize for AttributeBuffer {
358 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
359 where
360 S: serde::Serializer,
361 {
362 let mut s = serializer.serialize_seq(Some(self.len))?;
363 match self.component_type {
364 ComponentDataType::U8 => match self.num_components {
365 1 => s.serialize_element(unsafe { self.as_slice::<[u8; 1]>() }),
366 2 => s.serialize_element(unsafe { self.as_slice::<[u8; 2]>() }),
367 3 => s.serialize_element(unsafe { self.as_slice::<[u8; 3]>() }),
368 4 => s.serialize_element(unsafe { self.as_slice::<[u8; 4]>() }),
369 _ => panic!("Unsupported number of components: {}", self.num_components),
370 },
371 ComponentDataType::U16 => match self.num_components {
372 1 => s.serialize_element(unsafe { self.as_slice::<[u16; 1]>() }),
373 2 => s.serialize_element(unsafe { self.as_slice::<[u16; 2]>() }),
374 3 => s.serialize_element(unsafe { self.as_slice::<[u16; 3]>() }),
375 4 => s.serialize_element(unsafe { self.as_slice::<[u16; 4]>() }),
376 _ => panic!("Unsupported number of components: {}", self.num_components),
377 },
378 ComponentDataType::U32 => match self.num_components {
379 1 => s.serialize_element(unsafe { self.as_slice::<[u32; 1]>() }),
380 2 => s.serialize_element(unsafe { self.as_slice::<[u32; 2]>() }),
381 3 => s.serialize_element(unsafe { self.as_slice::<[u32; 3]>() }),
382 4 => s.serialize_element(unsafe { self.as_slice::<[u32; 4]>() }),
383 _ => panic!("Unsupported number of components: {}", self.num_components),
384 },
385 ComponentDataType::U64 => match self.num_components {
386 1 => s.serialize_element(unsafe { self.as_slice::<[u64; 1]>() }),
387 2 => s.serialize_element(unsafe { self.as_slice::<[u64; 2]>() }),
388 3 => s.serialize_element(unsafe { self.as_slice::<[u64; 3]>() }),
389 4 => s.serialize_element(unsafe { self.as_slice::<[u64; 4]>() }),
390 _ => panic!("Unsupported number of components: {}", self.num_components),
391 },
392 ComponentDataType::F32 => match self.num_components {
393 1 => s.serialize_element(unsafe { self.as_slice::<[f32; 1]>() }),
394 2 => s.serialize_element(unsafe { self.as_slice::<[f32; 2]>() }),
395 3 => s.serialize_element(unsafe { self.as_slice::<[f32; 3]>() }),
396 4 => s.serialize_element(unsafe { self.as_slice::<[f32; 4]>() }),
397 _ => panic!("Unsupported number of components: {}", self.num_components),
398 },
399 ComponentDataType::F64 => match self.num_components {
400 1 => s.serialize_element(unsafe { self.as_slice::<[f64; 1]>() }),
401 2 => s.serialize_element(unsafe { self.as_slice::<[f64; 2]>() }),
402 3 => s.serialize_element(unsafe { self.as_slice::<[f64; 3]>() }),
403 4 => s.serialize_element(unsafe { self.as_slice::<[f64; 4]>() }),
404 _ => panic!("Unsupported number of components: {}", self.num_components),
405 },
406 _ => unimplemented!(),
407 }?;
408 s.end()
409 }
410}
411
412impl Clone for AttributeBuffer {
413 fn clone(&self) -> Self {
414 let data = self.as_slice_u8().to_vec();
415 let component_type = self.component_type;
416 let num_components = self.num_components;
417 let len = self.len;
418 let buffer = RawBuffer::from_vec(data);
419 let last = unsafe { buffer.as_ptr().add(len * mem::size_of::<u8>()) };
420
421 Self {
422 data: buffer,
423 len,
424 last,
425 component_type,
426 num_components,
427 }
428 }
429}
430
431impl std::fmt::Debug for AttributeBuffer {
432 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
433 let data = match self.component_type {
434 ComponentDataType::Invalid => {
435 return format!("Invalid component type").fmt(f);
436 }
437 ComponentDataType::U8 => match self.num_components {
438 1 => format!("{:?}", unsafe { self.as_slice::<[u8; 1]>() }),
439 2 => format!("{:?}", unsafe { self.as_slice::<[u8; 2]>() }),
440 3 => format!("{:?}", unsafe { self.as_slice::<[u8; 3]>() }),
441 4 => format!("{:?}", unsafe { self.as_slice::<[u8; 4]>() }),
442 _ => panic!("Unsupported number of components: {}", self.num_components),
443 },
444 ComponentDataType::U16 => match self.num_components {
445 1 => format!("{:?}", unsafe { self.as_slice::<[u16; 1]>() }),
446 2 => format!("{:?}", unsafe { self.as_slice::<[u16; 2]>() }),
447 3 => format!("{:?}", unsafe { self.as_slice::<[u16; 3]>() }),
448 4 => format!("{:?}", unsafe { self.as_slice::<[u16; 4]>() }),
449 _ => panic!("Unsupported number of components: {}", self.num_components),
450 },
451 ComponentDataType::U32 => match self.num_components {
452 1 => format!("{:?}", unsafe { self.as_slice::<[u32; 1]>() }),
453 2 => format!("{:?}", unsafe { self.as_slice::<[u32; 2]>() }),
454 3 => format!("{:?}", unsafe { self.as_slice::<[u32; 3]>() }),
455 4 => format!("{:?}", unsafe { self.as_slice::<[u32; 4]>() }),
456 _ => panic!("Unsupported number of components: {}", self.num_components),
457 },
458 ComponentDataType::U64 => match self.num_components {
459 1 => format!("{:?}", unsafe { self.as_slice::<[u64; 1]>() }),
460 2 => format!("{:?}", unsafe { self.as_slice::<[u64; 2]>() }),
461 3 => format!("{:?}", unsafe { self.as_slice::<[u64; 3]>() }),
462 4 => format!("{:?}", unsafe { self.as_slice::<[u64; 4]>() }),
463 _ => panic!("Unsupported number of components: {}", self.num_components),
464 },
465 ComponentDataType::F32 => match self.num_components {
466 1 => format!("{:?}", unsafe { self.as_slice::<[f32; 1]>() }),
467 2 => format!("{:?}", unsafe { self.as_slice::<[f32; 2]>() }),
468 3 => format!("{:?}", unsafe { self.as_slice::<[f32; 3]>() }),
469 4 => format!("{:?}", unsafe { self.as_slice::<[f32; 4]>() }),
470 _ => panic!("Unsupported number of components: {}", self.num_components),
471 },
472 ComponentDataType::F64 => match self.num_components {
473 1 => format!("{:?}", unsafe { self.as_slice::<[f64; 1]>() }),
474 2 => format!("{:?}", unsafe { self.as_slice::<[f64; 2]>() }),
475 3 => format!("{:?}", unsafe { self.as_slice::<[f64; 3]>() }),
476 4 => format!("{:?}", unsafe { self.as_slice::<[f64; 4]>() }),
477 _ => panic!("Unsupported number of components: {}", self.num_components),
478 },
479 ComponentDataType::I8 => match self.num_components {
480 1 => format!("{:?}", unsafe { self.as_slice::<[i8; 1]>() }),
481 2 => format!("{:?}", unsafe { self.as_slice::<[i8; 2]>() }),
482 3 => format!("{:?}", unsafe { self.as_slice::<[i8; 3]>() }),
483 4 => format!("{:?}", unsafe { self.as_slice::<[i8; 4]>() }),
484 _ => panic!("Unsupported number of components: {}", self.num_components),
485 },
486 ComponentDataType::I16 => match self.num_components {
487 1 => format!("{:?}", unsafe { self.as_slice::<[i16; 1]>() }),
488 2 => format!("{:?}", unsafe { self.as_slice::<[i16; 2]>() }),
489 3 => format!("{:?}", unsafe { self.as_slice::<[i16; 3]>() }),
490 4 => format!("{:?}", unsafe { self.as_slice::<[i16; 4]>() }),
491 _ => panic!("Unsupported number of components: {}", self.num_components),
492 },
493 ComponentDataType::I32 => match self.num_components {
494 1 => format!("{:?}", unsafe { self.as_slice::<[i32; 1]>() }),
495 2 => format!("{:?}", unsafe { self.as_slice::<[i32; 2]>() }),
496 3 => format!("{:?}", unsafe { self.as_slice::<[i32; 3]>() }),
497 4 => format!("{:?}", unsafe { self.as_slice::<[i32; 4]>() }),
498 _ => panic!("Unsupported number of components: {}", self.num_components),
499 },
500 ComponentDataType::I64 => match self.num_components {
501 1 => format!("{:?}", unsafe { self.as_slice::<[i64; 1]>() }),
502 2 => format!("{:?}", unsafe { self.as_slice::<[i64; 2]>() }),
503 3 => format!("{:?}", unsafe { self.as_slice::<[i64; 3]>() }),
504 4 => format!("{:?}", unsafe { self.as_slice::<[i64; 4]>() }),
505 _ => panic!("Unsupported number of components: {}", self.num_components),
506 },
507 };
508 f.debug_struct("AttributeBuffer")
509 .field("len", &self.len)
510 .field("component_type", &self.component_type)
511 .field("num_components", &self.num_components)
512 .field("data", &data)
513 .finish()
514 }
515}
516
517impl std::cmp::PartialEq for AttributeBuffer {
518 fn eq(&self, other: &Self) -> bool {
519 self.len == other.len
520 && self.component_type == other.component_type
521 && self.num_components == other.num_components
522 && (0..self.len() * self.num_components * self.component_type.size()).all(|i| {
523 let self_ptr = unsafe { self.as_ptr().add(i) };
524 let other_ptr = unsafe { other.as_ptr().add(i) };
525 unsafe { ptr::read(self_ptr) == ptr::read(other_ptr) }
526 })
527 }
528}
529
530pub struct MaybeInitAttributeBuffer {
531 data: RawBuffer,
533
534 len: usize,
536
537 last: *mut u8,
539
540 component_type: ComponentDataType,
541
542 num_components: usize,
543
544 #[allow(dead_code)]
547 initialized_elements: Vec<bool>,
548}
549
550impl MaybeInitAttributeBuffer {
551 #[allow(unused)]
554 pub fn new(len: usize, component_type: ComponentDataType, num_components: usize) -> Self {
555 let data = RawBuffer::with_capacity(len * component_type.size() * num_components);
556 let last = unsafe {
557 data.as_ptr()
558 .add(len * component_type.size() * num_components)
559 };
560 let mut initialized_elements = Vec::with_capacity(len);
561 #[cfg(all(debug_assertions, feature = "safety_assertions"))]
562 {
563 initialized_elements.resize(len, false);
564 }
565 Self {
566 data,
567 len,
568 last,
569 component_type,
570 num_components,
571 initialized_elements,
572 }
573 }
574
575 #[allow(unused)]
580 pub fn as_slice_unchecked<Data, const N: usize>(&self) -> &[Data]
581 where
582 Data: Vector<N>,
583 Data::Component: DataValue,
584 {
585 safety_assert_eq!(
586 mem::size_of::<Data>(), self.component_type.size() * self.num_components,
587 "Cannot create slice: Trying to cast to {}, but the buffer stores elements of type {}D vector of {:?}, which has size {}",
588 mem::size_of::<Data>(), self.num_components, self.component_type, self.component_type.size(),
589 );
590 unsafe { std::slice::from_raw_parts(self.data.as_ptr() as *const Data, self.len) }
592 }
593
594 #[allow(unused)]
595 #[inline]
596 pub fn write<Data, const N: usize>(&mut self, idx: usize, data: Data)
597 where
598 Data: Vector<N>,
599 Data::Component: DataValue,
600 {
601 assert_eq!(
602 Data::Component::get_dyn(),
603 self.component_type,
604 "Data type mismatch: Cannot push data of type {:?} into attribute buffer of type {:?}",
605 Data::Component::get_dyn(),
606 self.component_type
607 );
608 assert!(
609 N == self.num_components,
610 "Number of components mismatch: Cannot push data with {} components into attribute buffer with {} components",
611 N, self.num_components
612 );
613 assert!(idx < self.len, "Index out of bounds: The index {} is out of bounds for the attribute buffer with length {}", idx, self.len);
614
615 self.write_type_unchecked(idx, data);
616 }
617
618 #[inline]
621 pub fn write_type_unchecked<Data, const N: usize>(&mut self, idx: usize, data: Data)
622 where
623 Data: Vector<N>,
624 Data::Component: DataValue,
625 {
626 safety_assert_eq!(
627 Data::Component::get_dyn(),
628 self.component_type,
629 "Data type mismatch: Cannot push data of type {:?} into attribute buffer of type {:?}",
630 Data::Component::get_dyn(),
631 self.component_type
632 );
633 safety_assert!(
634 N == self.num_components,
635 "Number of components mismatch: Cannot push data with {} components into attribute buffer with {} components",
636 N, self.num_components
637 );
638
639 safety_assert!(idx < self.len, "Index out of bounds: The index {} is out of bounds for the attribute buffer with length {}", idx, self.len);
640
641 #[cfg(all(debug_assertions, feature = "safety_assertions"))]
642 {
643 self.initialized_elements[idx] = true;
644 }
645
646 unsafe {
647 (self.data.as_ptr() as *mut Data).add(idx).write(data);
648 }
649 }
650
651 #[inline(always)]
653 #[allow(unused)]
654 pub fn len(&self) -> usize {
655 self.len
656 }
657
658 #[inline(always)]
660 #[allow(unused)]
661 pub fn get_component_type(&self) -> ComponentDataType {
662 self.component_type
663 }
664
665 #[inline(always)]
667 #[allow(unused)]
668 pub fn get_num_components(&self) -> usize {
669 self.num_components
670 }
671}
672
673impl From<MaybeInitAttributeBuffer> for AttributeBuffer {
674 fn from(maybe_init: MaybeInitAttributeBuffer) -> Self {
675 safety_assert!(
676 maybe_init.initialized_elements.iter().all(|&x| x),
677 "Not all elements are initialized: Out of {} elements, uninitialized are {:?}",
678 maybe_init.len,
679 maybe_init.initialized_elements.iter().filter(|&&x| !x)
680 );
681
682 Self {
683 data: maybe_init.data,
684 len: maybe_init.len,
685 last: maybe_init.last,
686 component_type: maybe_init.component_type,
687 num_components: maybe_init.num_components,
688 }
689 }
690}
691
692#[cfg(test)]
693mod tests {
694 use crate::types::NdVector;
695
696 use super::*;
697 #[test]
698 fn clone() {
699 let data = vec![
700 NdVector::from([1.0f32, 2.0, 3.0]),
701 NdVector::from([4.0f32, 5.0, 6.0]),
702 NdVector::from([7.0f32, 8.0, 9.0]),
703 ];
704
705 let att = AttributeBuffer::from_vec(data);
706
707 let att_clone = att.clone();
708 assert_eq!(att, att_clone, "The clone is not equal to the original");
709 }
710
711 #[test]
712 fn maybe_init() {
713 let mut buffer = MaybeInitAttributeBuffer::new(5, ComponentDataType::F32, 3);
714 let data = (0..5)
715 .map(|i| NdVector::from([i as f32, i as f32, i as f32]))
716 .collect::<Vec<_>>();
717 let mut idx = 1;
718 for _ in 0..5 {
719 idx = (idx * 2) % 5; buffer.write(idx, data[idx]);
721 }
722 buffer.write(0, data[0]);
723
724 let att = AttributeBuffer::from(buffer);
725 let answer = AttributeBuffer::from_vec(data);
727 assert_eq!(
728 att, answer,
729 "The attribute buffer is not equal to the original"
730 );
731 }
732
733 #[test]
734 fn test_permute() {
735 let data = vec![
736 NdVector::from([1f32, 2.0, 3.0]),
737 NdVector::from([4f32, 5.0, 6.0]),
738 NdVector::from([7f32, 8.0, 9.0]),
739 ];
740 let mut att = AttributeBuffer::from_vec(data);
741 let permutation = vec![2, 1, 0];
742 unsafe {
743 att.permute_unchecked(&permutation);
744 }
745 let expected_data = vec![
746 NdVector::from([7f32, 8.0, 9.0]),
747 NdVector::from([4f32, 5.0, 6.0]),
748 NdVector::from([1f32, 2.0, 3.0]),
749 ];
750 let expected_att = AttributeBuffer::from_vec(expected_data);
751 assert_eq!(att, expected_att);
752 }
753}