nd_triangulation/
cell.rs

1use crate::{Triangulation, VertexIter};
2
3/// Iterator over cells/facets of a triangulation
4#[derive(Debug)]
5pub struct CellIter<'a> {
6    cur: usize,
7    size: usize,
8    cells: *mut u8, //c++ type: Full_cells*
9    pub(crate) tri: &'a Triangulation,
10}
11
12impl<'a> CellIter<'a> {
13    pub(crate) fn new(tri: &'a Triangulation, cells: *mut u8) -> CellIter<'a> {
14        #[cfg(not(feature = "docs-rs"))]
15        let size = unsafe {
16            cpp!([cells as "Full_cells*"] -> usize as "size_t" {
17                return cells->size();
18            })
19        };
20
21        #[cfg(feature = "docs-rs")]
22        let size = 0;
23
24        CellIter {
25            cur: 0,
26            size,
27            cells,
28            tri,
29        }
30    }
31
32    unsafe fn cell_ptr(&self, cur: usize) -> *mut u8 {
33        let cells = self.cells;
34        #[cfg(not(feature = "docs-rs"))]
35        return cpp!([cells as "Full_cells*", cur as "size_t"] -> *mut u8 as "Full_cell_handle" {
36            auto& cell = (*cells)[cur];
37            return cell;
38        });
39
40        #[cfg(feature = "docs-rs")]
41        std::ptr::null_mut()
42    }
43}
44
45impl<'a> Iterator for CellIter<'a> {
46    type Item = Cell<'a>;
47    fn next(&mut self) -> Option<Self::Item> {
48        if self.cur >= self.size {
49            return None;
50        }
51
52        let cur = self.cur;
53        let ptr = unsafe { self.cell_ptr(cur) };
54        self.cur += 1;
55        Some(Cell { ptr, tri: self.tri })
56    }
57}
58
59/// Representation of a specific cell of a triangulation
60#[derive(Debug, PartialEq, Eq)]
61pub struct Cell<'a> {
62    ptr: *mut u8, // c++ type Full_cell_handle
63    tri: &'a Triangulation,
64}
65
66impl<'a> Cell<'a> {
67    /// Returns an iterator over all vertices that are part of this cell.
68    pub fn vertices(&self) -> VertexIter<'_> {
69        VertexIter::new(&self)
70    }
71
72    /// Unique id between all cells of one triangulation
73    ///
74    /// Cell ids start with one because they are assigned lazily to
75    /// the cells and zero ist the default value for `size_t`s in c++
76    pub fn id(&self) -> usize {
77        unsafe { self.retrieve_id() }
78    }
79
80    pub(crate) fn tri(&self) -> &Triangulation {
81        self.tri
82    }
83
84    pub(crate) fn ptr(&self) -> *mut u8 {
85        self.ptr
86    }
87
88    #[rustfmt::skip]
89    unsafe fn retrieve_id(&self) -> usize {
90        let ptr = self.ptr;
91        #[cfg(not(feature = "docs-rs"))]
92        return cpp!([ptr as "Full_cell_handle"] -> usize as "size_t"{
93            return ptr->data();
94        });
95
96	#[cfg(feature = "docs-rs")]
97	0
98    }
99}
100
101impl<'a> Drop for CellIter<'a> {
102    #[rustfmt::skip]
103    fn drop(&mut self) {
104        let cells = self.cells;
105        unsafe {
106            #[cfg(not(feature = "docs-rs"))]
107            cpp!([cells as "Full_cells*"]{
108		delete cells;
109            })
110        }
111    }
112}
113
114#[test]
115fn test_cells_get_assigned_increasing_ids() {
116    let mut tri = Triangulation::new(2);
117
118    tri.add_vertex(&[1.0, 1.0]).unwrap();
119    tri.add_vertex(&[2.0, 1.0]).unwrap();
120    tri.add_vertex(&[1.5, 1.5]).unwrap();
121
122    let mut expected_cell_id = 1;
123
124    for cell in tri.convex_hull_cells() {
125        assert_eq!(expected_cell_id, cell.id());
126        expected_cell_id += 1;
127    }
128}