1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! Mesh builder data structure and implementation
use super::{
Mesh, Octree,
cell::{CellIndex, CellVertex},
dc,
frame::Frame,
};
/// Container used during construction of a [`Mesh`]
#[derive(Default)]
pub struct MeshBuilder {
/// Map from indexes in [`Octree::verts`](super::Octree::verts) to
/// `out.vertices`
///
/// `usize::MAX` is used a marker for an unmapped vertex
map: Vec<usize>,
out: Mesh,
}
impl MeshBuilder {
pub fn take(self) -> Mesh {
self.out
}
pub(crate) fn cell(&mut self, octree: &Octree, cell: CellIndex<3>) {
dc::dc_cell(octree, cell, self);
}
pub(crate) fn face<F: Frame>(
&mut self,
octree: &Octree,
a: CellIndex<3>,
b: CellIndex<3>,
) {
dc::dc_face::<F>(octree, a, b, self)
}
/// Handles four cells that share a common edge aligned on axis `T`
///
/// Cells positions are in the order `[0, U, U | V, U]`, i.e. a right-handed
/// winding about `+T` (where `T, U, V` is a right-handed coordinate frame)
pub(crate) fn edge<F: Frame>(
&mut self,
octree: &Octree,
a: CellIndex<3>,
b: CellIndex<3>,
c: CellIndex<3>,
d: CellIndex<3>,
) {
dc::dc_edge::<F>(octree, a, b, c, d, self)
}
/// Record the given triangle
///
/// Vertices are indices given by calls to [`Self::vertex`]
///
/// The vertices are given in a clockwise winding with the intersection
/// vertex (i.e. the one on the edge) always last.
pub(crate) fn triangle(&mut self, a: usize, b: usize, c: usize) {
self.out.triangles.push(nalgebra::Vector3::new(a, b, c))
}
/// Looks up the given vertex, localizing it within a cell
///
/// `v` is an absolute offset into `verts`, which should be a reference to
/// [`Octree::verts`](super::Octree::verts).
pub(crate) fn vertex(
&mut self,
v: usize,
verts: &[CellVertex<3>],
) -> usize {
if v >= self.map.len() {
self.map.resize(v + 1, usize::MAX);
}
match self.map[v] {
usize::MAX => {
let next_vert = self.out.vertices.len();
self.out.vertices.push(verts[v].pos);
self.map[v] = next_vert;
next_vert
}
u => u,
}
}
}