Skip to content

Commit

Permalink
Adding tests with metis-rs
Browse files Browse the repository at this point in the history
  • Loading branch information
gents83 committed Feb 13, 2024
1 parent 72b2ac9 commit 1182346
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 73 deletions.
1 change: 1 addition & 0 deletions crates/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ regex = { git = "https://github.com/rust-lang/regex" }
gltf = { git = "https://github.com/gltf-rs/gltf", features = ["extras", "names", "KHR_materials_unlit", "KHR_lights_punctual", "KHR_materials_pbrSpecularGlossiness", "KHR_materials_transmission", "KHR_materials_variants", "KHR_materials_ior", "KHR_materials_emissive_strength", "KHR_materials_volume", "KHR_materials_specular"] }
mikktspace = { git = "https://github.com/gltf-rs/mikktspace" }
meshopt = { git = "https://github.com/gwihlidal/meshopt-rs" }
metis = { git = "https://github.com/LIHPC-Computational-Geometry/metis-rs"}

futures = { git = "https://github.com/rust-lang/futures-rs", features = ["std", "thread-pool"] }
raw-window-handle = { version = "0.6" }
Expand Down
3 changes: 2 additions & 1 deletion crates/plugins/binarizer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ crate-type = ["rlib", "cdylib"]

[target.'cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))'.dependencies]
meshopt = { workspace = true }
mikktspace = { worspace = true }
mikktspace = { workspace = true }
metis = { workspace = true }
naga = { workspace = true }
rspirv = { workspace = true }
regex = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions crates/plugins/binarizer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ mod mesh;
pub mod plugin;
mod simplify;
mod system;
mod tests;
pub mod utils;
78 changes: 6 additions & 72 deletions crates/plugins/binarizer/src/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ impl meshopt::DecodePosition for MeshVertex {

#[allow(dead_code)]
#[derive(Debug, Clone)]
struct LocalVertex {
pos: Vector3,
global_index: usize,
pub(crate) struct LocalVertex {
pub(crate) pos: Vector3,
pub(crate) global_index: usize,
}

impl Default for LocalVertex {
Expand Down Expand Up @@ -224,17 +224,8 @@ pub fn compute_clusters(
let (optimized_vertices, optimized_indices) =
optimize_mesh(&group_vertices, &group_indices);

/*
let locked_indices = crate::adjacency::find_border_vertices(&optimized_indices);

let mut simplified_indices = crate::simplify::simplify(
&optimized_vertices,
&optimized_indices,
0.5,
Some(&locked_indices),
);
*/

let target_count = (optimized_indices.len() as f32 * 0.5) as usize;
let target_error = 0.9;

Expand All @@ -247,7 +238,9 @@ pub fn compute_clusters(
None,
);

if simplified_indices.len() >= optimized_indices.len() {
if locked_indices.len() > optimized_vertices.len() + 1
&& simplified_indices.len() >= optimized_indices.len()
{
inox_log::debug_log!(
"No simplification happened [from {} to {}]",
optimized_indices.len(),
Expand Down Expand Up @@ -280,62 +273,3 @@ pub fn compute_clusters(
});
(cluster_indices, cluster_meshlets)
}

#[test]
fn simplify_test() {
use crate::adjacency::find_border_vertices;
use crate::simplify::simplify;

// 4----5----6
// | | |
// 1----2----7
// | | |
// 0----3----8
#[rustfmt::skip]
let vertices = [
LocalVertex{ pos: Vector3::new(0., 0., 0.), global_index: 0 },
LocalVertex{ pos: Vector3::new(0., 1., 0.), global_index: 1 },
LocalVertex{ pos: Vector3::new(1., 1., 0.), global_index: 2 },
LocalVertex{ pos: Vector3::new(1., 0., 0.), global_index: 3 },
LocalVertex{ pos: Vector3::new(0., 2., 0.), global_index: 4 },
LocalVertex{ pos: Vector3::new(1., 2., 0.), global_index: 5 },
LocalVertex{ pos: Vector3::new(2., 2., 0.), global_index: 6 },
LocalVertex{ pos: Vector3::new(2., 1., 0.), global_index: 7 },
LocalVertex{ pos: Vector3::new(2., 0., 0.), global_index: 8 },
];
#[rustfmt::skip]
let indices = [
0, 1, 2,
2, 3, 0,
1, 4, 5,
5, 2, 1,
2, 5, 6,
6, 7, 2,
2, 7, 3,
3, 7, 8,
];
let locked_indices = find_border_vertices(&indices);

let target_count = 6;
let target_error = 0.01;
let simplified_indices = meshopt::simplify_decoder(
&indices,
&vertices,
target_count,
target_error,
meshopt::SimplifyOptions::LockBorder,
None,
);

debug_assert!(
!simplified_indices.is_empty() && simplified_indices.len() < indices.len(),
"No simplification happened with meshoptimizer"
);

let simplified_indices = simplify(&vertices, &indices, 0.5, Some(&locked_indices));

debug_assert!(
!simplified_indices.is_empty() && simplified_indices.len() < indices.len(),
"No simplification happened with custom simplify"
);
}
231 changes: 231 additions & 0 deletions crates/plugins/binarizer/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
use inox_math::Vector3;
use metis::Graph;

use crate::{adjacency::find_border_vertices, mesh::LocalVertex};

#[allow(dead_code)]
fn simplify_test() {
// 4----5----6
// | | |
// 1----2----7
// | | |
// 0----3----8
#[rustfmt::skip]
let vertices = [
LocalVertex{ pos: Vector3::new(0., 0., 0.), global_index: 0 },
LocalVertex{ pos: Vector3::new(0., 1., 0.), global_index: 1 },
LocalVertex{ pos: Vector3::new(1., 1., 0.), global_index: 2 },
LocalVertex{ pos: Vector3::new(1., 0., 0.), global_index: 3 },
LocalVertex{ pos: Vector3::new(0., 2., 0.), global_index: 4 },
LocalVertex{ pos: Vector3::new(1., 2., 0.), global_index: 5 },
LocalVertex{ pos: Vector3::new(2., 2., 0.), global_index: 6 },
LocalVertex{ pos: Vector3::new(2., 1., 0.), global_index: 7 },
LocalVertex{ pos: Vector3::new(2., 0., 0.), global_index: 8 },
];
#[rustfmt::skip]
let indices = [
0, 1, 2,
2, 3, 0,
1, 4, 5,
5, 2, 1,
2, 5, 6,
6, 7, 2,
2, 7, 3,
3, 7, 8,
];
let locked_indices = find_border_vertices(&indices);

debug_assert!(
!locked_indices.is_empty() && locked_indices.len() < indices.len(),
"Locked indices are empty or exactly the same of total number of indices"
);

let target_count = 6;
let target_error = 0.01;
let simplified_indices = meshopt::simplify_decoder(
&indices,
&vertices,
target_count,
target_error,
meshopt::SimplifyOptions::LockBorder,
None,
);

debug_assert!(
!simplified_indices.is_empty() && simplified_indices.len() < indices.len(),
"No simplification happened with meshoptimizer"
);
}

#[allow(dead_code)]
fn partition_test() {
// 0----3----6----9----12
// | #0 | #1 | #2 | #3 |
// 1----4----7----10---13
// | #4 | #5 | #6 | #7 |
// 2----5----8----11---14
#[rustfmt::skip]
let clusters_adiacency = [
vec![1, 4],
vec![0, 2, 5],
vec![1, 3, 6],
vec![2, 7],
vec![0, 5],
vec![1, 4, 6],
vec![2, 5, 7],
vec![3, 6],
];

let num_meshlets = clusters_adiacency.len();
let mut xadj = Vec::new();
let mut adjncy = Vec::new();
for a in clusters_adiacency {
let start = adjncy.len() as i32;
xadj.push(start);
for v in a {
adjncy.push(v);
}
}
xadj.push(adjncy.len() as i32);

let mut groups = Vec::new();
let expected = vec![vec![0, 1, 4, 5], vec![2, 3, 6, 7]];
let num_groups = expected.len();
if let Ok(graph) = Graph::new(1, num_groups as i32, &xadj, &adjncy) {
let mut part = vec![0; num_meshlets];
if let Ok(result) = graph.part_kway(&mut part) {
for group_index in 0..num_groups as i32 {
let mut group = Vec::new();
part.iter().enumerate().for_each(|(i, &v)| {
if v == group_index {
group.push(i);
}
});
group.sort();
groups.push(group);
}
groups.sort();
println!("Result[{}] = {:?}", result, groups);
}
}
debug_assert!(
groups == expected,
"\nExpecting: {:?}\nResult: {:?}",
expected,
groups
);
}

#[allow(dead_code)]
fn weighted_partition_test() {
// X----X----X----X----X-----X----X
// | | |
// X #0 X----X #1 X
// | | |
// X----X----X----X----X-----X----X
// | | |
// X #3 X----X #2 X
// | | | |
// X----X----X----X X-----X----X
// | | |
// X #4 X #5 X
// | | |
// X----X----X----X----X-----X----X
#[rustfmt::skip]
let clusters_adiacency = [
vec![1, 3],
vec![0, 2, 3],
vec![1, 3, 5],
vec![0, 1, 2, 4, 5],
vec![3, 5],
vec![2, 3, 4],
];
#[rustfmt::skip]
let shared_edges = [
vec![0, 3, 0, 3, 0, 0],
vec![3, 0, 2, 1, 0, 0],
vec![0, 2, 0, 1, 0, 3],
vec![3, 1, 1, 0, 3, 2],
vec![0, 0, 0, 3, 0, 2],
vec![0, 0, 3, 2, 2, 0],
];

let num_meshlets = clusters_adiacency.len();
let mut xadj = Vec::new();
let mut adjncy = Vec::new();
let mut adjwgt = Vec::new();
clusters_adiacency
.iter()
.enumerate()
.for_each(|(cluster_index, a)| {
let start = adjncy.len() as i32;
xadj.push(start);
for v in a {
adjncy.push(*v);
adjwgt.push(shared_edges[cluster_index][*v as usize]);
}
});
xadj.push(adjncy.len() as i32);

let num_groups = 3;

let mut groups = Vec::new();
let expected_without_weights = vec![vec![0, 1], vec![2, 3], vec![4, 5]];
let expected_with_weights = vec![vec![0, 1], vec![2, 5], vec![3, 4]];

if let Ok(graph) = Graph::new(1, num_groups, &xadj, &adjncy) {
let mut part = vec![0; num_meshlets];
if let Ok(result) = graph.part_kway(&mut part) {
for group_index in 0..num_groups {
let mut group = Vec::new();
part.iter().enumerate().for_each(|(i, &v)| {
if v == group_index {
group.push(i);
}
});
group.sort();
groups.push(group);
}
groups.sort();
println!("Result[{}] = {:?}", result, groups);
}
}
debug_assert!(
groups == expected_without_weights,
"\nExpecting: {:?}\nResult: {:?}",
expected_without_weights,
expected_without_weights
);
groups.clear();

if let Ok(graph) = Graph::new(1, num_groups, &xadj, &adjncy) {
let mut part = vec![0; num_meshlets];
if let Ok(result) = graph.set_adjwgt(&adjwgt).part_kway(&mut part) {
for group_index in 0..num_groups {
let mut group = Vec::new();
part.iter().enumerate().for_each(|(i, &v)| {
if v == group_index {
group.push(i);
}
});
group.sort();
groups.push(group);
}
groups.sort();
println!("Result[{}] = {:?}", result, groups);
}
}
debug_assert!(
groups == expected_with_weights,
"\nExpecting: {:?}\nResult: {:?}",
expected_with_weights,
expected_with_weights
);
}

#[test]
fn tests() {
simplify_test();
partition_test();
weighted_partition_test();
}

0 comments on commit 1182346

Please sign in to comment.