nd_triangulation/
vertex.rs

1use crate::Cell;
2
3/// A vertex which is part of a triangulation
4#[derive(Debug, PartialEq, Eq)]
5pub struct Vertex<'a> {
6    ptr: *mut u8, //c++ type: Vertex_handle
7    cell: &'a Cell<'a>,
8}
9
10impl<'a> Vertex<'a> {
11    /// Unique id between all vertices within the same triangulation
12    pub fn id(&self) -> usize {
13        unsafe { self.retrieve_id() }
14    }
15
16    /// Coordinates of the vertex
17    pub fn coords(&self) -> &'a [f64] {
18        unsafe { self.retrieve_coords() }
19    }
20
21    unsafe fn retrieve_id(&self) -> usize {
22        let ptr = self.ptr;
23        #[cfg(not(feature = "docs-rs"))]
24        return cpp!([ptr as "Vertex_handle"] -> usize as "size_t"{
25            return ptr->data();
26        });
27
28        #[cfg(feature = "docs-rs")]
29        0
30    }
31
32    unsafe fn retrieve_coords(&self) -> &'a [f64] {
33        let ptr = self.ptr;
34        #[cfg(not(feature = "docs-rs"))]
35        let point = cpp!([ptr as "Vertex_handle"] -> *const f64 as "const double*"{
36            auto& p = ptr->point();
37            return p.data();
38        });
39
40        #[cfg(feature = "docs-rs")]
41        let point = std::ptr::null();
42
43        std::slice::from_raw_parts(point, self.cell.tri().dim)
44    }
45}
46
47/// Iterator over vertices beloning to a cell
48#[derive(Debug)]
49pub struct VertexIter<'a> {
50    cur: usize,
51    cell: &'a Cell<'a>,
52}
53
54impl<'a> VertexIter<'a> {
55    /// Creates an Iterator over the vertices of a cell
56    pub fn new(cell: &'a Cell) -> VertexIter<'a> {
57        VertexIter { cur: 0, cell }
58    }
59
60    #[rustfmt::skip]
61    unsafe fn skip_bogus_vertices(&self) -> i64 {
62        let tri = self.cell.tri().ptr;
63        let cell = self.cell.ptr();
64        let cur = self.cur;
65        #[cfg(not(feature = "docs-rs"))]
66        return cpp!([tri as "Triangulation*", cell as "Full_cell_handle", cur as "size_t"] -> i64 as "int64_t" {
67            auto v = cell->vertices_begin();
68            std::advance(v, cur);
69            if (v == cell->vertices_end()){
70		return -1;
71            }
72            if (*v == Vertex_handle() || tri->is_infinite(*v)){
73		std::advance(v,1);
74		return 1;
75            }
76            return 0;
77
78        });
79
80	#[cfg(feature = "docs-rs")]
81	0
82    }
83
84    #[rustfmt::skip]
85    unsafe fn get_vertex(&mut self) -> Option<Vertex<'a>> {
86        let cur_update = self.skip_bogus_vertices();
87
88        if cur_update < 0 {
89            return None;
90        }
91
92        self.cur += cur_update as usize;
93
94        let cell = self.cell.ptr();
95        let cur = self.cur;
96
97        #[cfg(not(feature = "docs-rs"))]
98        let ptr = cpp!([cell as "Full_cell_handle", cur as "size_t"] -> *mut u8 as "Vertex_handle"{
99            auto v = cell->vertices_begin();
100            std::advance(v, cur);
101
102            if (v != cell->vertices_end()){
103		return *v;
104            }
105            return nullptr;
106
107        });
108
109        #[cfg(feature = "docs-rs")]
110	let ptr: *mut u8 = std::ptr::null_mut();
111
112        if ptr.is_null() {
113	    return None;
114        }
115
116        Some(Vertex {
117            ptr,
118            cell: self.cell,
119        })
120    }
121}
122
123impl<'a> Iterator for VertexIter<'a> {
124    type Item = Vertex<'a>;
125
126    fn next(&mut self) -> Option<Self::Item> {
127        let next = unsafe { self.get_vertex() };
128        self.cur += 1;
129        next
130    }
131}