Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/manifold/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,18 @@ impl<S: Data> Manifold<S> {
if !pos.len().is_multiple_of(3) { return Err("pos must be a multiple of 3".into()); }
if !idx.len().is_multiple_of(3) { return Err("idx must be a multiple of 3".into()); }
if !val.is_empty() && val.len() != idx.len() { return Err("val must hold one value per corner".into()); }
let nv = pos.len() / 3;
if idx.iter().any(|&i| i >= nv) { return Err("idx must refer to vertices in pos".into()); }

// dedup vertices
let mut hash = HashMap::with_capacity(pos.len() / 3);
let mut weld = Vec::with_capacity(pos.len() / 3);
let mut rmap = vec![0; pos.len()];
let mut hash = HashMap::with_capacity(nv);
let mut weld = Vec::with_capacity(nv);
let mut rmap = vec![0; nv];
let mut hs = Vec::with_capacity(idx.len());

for (i, p) in pos.chunks(3).enumerate() {
let v = Vec3::new(p[0] as Real, p[1] as Real, p[2] as Real);
if !v.is_finite() { return Err("pos must not contain NaN or infinite coordinates".into()); }
let k = (v.x.to_bits(), v.y.to_bits(), v.z.to_bits());
if let Some(&w) = hash.get(&k) { rmap[i] = w; } else {
let n = weld.len();
Expand Down
38 changes: 38 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,3 +763,41 @@ mod test_values {
}

}

#[cfg(test)]
mod test_input_validation {
use crate::prelude::Manifold;

// A unit tetrahedron: valid input, so each test changes one thing.
const POS: [f64; 12] = [0., 0., 0., 1., 0., 0., 0., 1., 0., 0., 0., 1.];
const IDX: [usize; 12] = [0, 2, 1, 0, 1, 3, 0, 3, 2, 1, 2, 3];

#[test]
fn test_valid_tet_is_accepted() {
assert!(Manifold::new(&POS, &IDX).is_ok());
}

#[test]
fn test_index_past_end_of_pos_is_an_error() {
let mut idx = IDX;
idx[0] = 99;
assert!(Manifold::new(&POS, &idx).is_err());
}

#[test]
fn test_index_past_last_vertex_is_an_error() {
// 4 vertices, but `pos.len()` is 12: index 5 used to be read as vertex 0.
let mut idx = IDX;
idx[0] = 5;
assert!(Manifold::new(&POS, &idx).is_err());
}

#[test]
fn test_non_finite_coordinates_are_errors() {
for bad in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
let mut pos = POS;
pos[3] = bad;
assert!(Manifold::new(&pos, &IDX).is_err(), "{bad} was accepted");
}
}
}
Loading