Skip to main content

draco_oxide_core/buffer/
attribute.rs

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    /// Contains the data of the attribute.
14    data: RawBuffer,
15
16    /// The number of values of the attribute.
17    len: usize,
18
19    /// pointer to the last element.
20    #[allow(unused)]
21    last: *mut u8,
22
23    /// component type of the attribute.
24    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        // just checked the condition
64        unsafe { self.get_unchecked::<Data, N>(idx) }
65    }
66
67    /// # Safety:
68    /// Two checks are ignored in this function:
69    /// (1) 'std::mem::size_of::<Data>()==component.size() * num_components', and
70    /// (2) idx < self.len
71    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        // Safety: upheld
86        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    /// pushes a value into the buffer without checking the type and the number of components.
129    /// # Safety
130    /// This function is unsafe because it does not check the type and the number of components of the data.
131    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    /// Returns the number of values of the attribute.
157    pub fn len(&self) -> usize {
158        self.len
159    }
160
161    #[inline]
162    /// Returns a slice of all the values in the buffer casted to the static type `Data`.
163    /// # Safety
164    /// This function assumes that the buffer's data is properly aligned and matches the type `Data`.
165    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    /// Returns the mutable slice of all the values in the buffer casted to the static type `Data`.
180    /// # Safety
181    /// This function assumes that the buffer's data is properly aligned and matches the type `Data`.
182    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    /// Returns a slice of all the values in the buffer casted to the static type `u8`.
241    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    /// #Safety
251    /// This function assumes that the permutation is welll-defined in the sense that
252    /// (1) it has the same length as the buffer,
253    /// (2) its elements are distinct.
254    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            // Copy the value at self[i] to tmp_att[new_idx]
274            // We need to copy the raw bytes for each element.
275            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    /// Swaps the elements at indices `i` and `j` in the buffer without checking the bounds.
285    /// # Safety
286    /// This function assumes that `i` and `j` are within the bounds of the buffer.
287    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        // Update the last pointer
328        self.last = unsafe { self.as_ptr().add(self.len * elem_size) };
329    }
330
331    /// Retains only the elements at the given sorted indices, compacting the buffer in O(n).
332    /// `keep_indices` must be sorted in ascending order and contain valid indices < self.len.
333    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    /// Contains the data of the attribute.
532    data: RawBuffer,
533
534    /// The length of allocation.
535    len: usize,
536
537    /// pointer of the last element.
538    last: *mut u8,
539
540    component_type: ComponentDataType,
541
542    num_components: usize,
543
544    /// Debugging purpose only; only read by the `safety_assert!` checks, which run
545    /// in debug builds with the (default-on) `safety_assertions` feature enabled.
546    #[allow(dead_code)]
547    initialized_elements: Vec<bool>,
548}
549
550impl MaybeInitAttributeBuffer {
551    /// Creates a new attribute buffer with the given component type and number of components.
552    /// This allocates memory for the buffer, but does not initialize it.
553    #[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    /// Returns a slice of all the values in the buffer casted to the static type `Data`.
576    /// Safety: Callers must know exactly which part of resulting slice is valid. \
577    /// Dereferencing the uninitialized part of the slice is undefined behavior.
578    /// Moreover, 'num_components * component_type.size()' must equal 'std::mem::size_of::<Data>()'.
579    #[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        // Safety: upheld.
591        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    /// Safety: The caller must ensure that the type of the data matches the type of the buffer.
619    /// Furthermore, the index must be within the bounds of the buffer.
620    #[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    /// Returns the number of values of the attribute.
652    #[inline(always)]
653    #[allow(unused)]
654    pub fn len(&self) -> usize {
655        self.len
656    }
657
658    /// Returns the component type of the attribute.
659    #[inline(always)]
660    #[allow(unused)]
661    pub fn get_component_type(&self) -> ComponentDataType {
662        self.component_type
663    }
664
665    /// Returns the number of components.
666    #[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; // 2 is a generator of $ \Z / 5 \Z $
720            buffer.write(idx, data[idx]);
721        }
722        buffer.write(0, data[0]);
723
724        let att = AttributeBuffer::from(buffer);
725        // check if the data is correct
726        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}