pub fn from_vtx2vtx(vtx2idx: &[usize], idx2vtx: &[usize], num_cluster: usize) -> Vec<usize> {
let num_vtx = vtx2idx.len() - 1;
let mut vtx2group = vec![0; num_vtx];
let (mut vtx2dist0, _) = crate::dijkstra::vtx2dist_for_vtx2vtx(0, vtx2idx, idx2vtx, None);
for i_cluster in 1..num_cluster {
let (i_vtx_max_dist, &max_dist) = vtx2dist0
.iter()
.enumerate()
.max_by_key(|(_i_vtx, &i_dist)| i_dist)
.unwrap();
assert_eq!(max_dist, vtx2dist0[i_vtx_max_dist]);
let (vtx2dist1, _) =
crate::dijkstra::vtx2dist_for_vtx2vtx(i_vtx_max_dist, vtx2idx, idx2vtx, Some(max_dist));
vtx2dist0
.iter_mut()
.enumerate()
.zip(vtx2dist1.iter())
.for_each(|((i_vtx, dist0), &dist1)| {
if dist1 < *dist0 {
*dist0 = dist1;
vtx2group[i_vtx] = i_cluster
}
});
}
vtx2group
}
#[test]
fn test_vtx2dist_for_vtx2vtx() {
let path_dir = std::path::Path::new("../target/out_del_msh_cpu");
std::fs::create_dir_all(path_dir).unwrap();
let trimesh3 = crate::trimesh3_primitive::sphere_yup::<usize, f64>(1.0, 64, 64);
let (vtx2idx, idx2vtx) =
crate::vtx2vtx::from_uniform_mesh(&trimesh3.tri2vtx, trimesh3.vtx2xyz.len(), false);
let num_group = 30;
let vtx2group = from_vtx2vtx(&vtx2idx, &idx2vtx, num_group);
let vtx2rgb: Vec<[f32; 3]> = {
use rand::RngExt;
use rand::SeedableRng;
let mut rng = rand_chacha::ChaChaRng::seed_from_u64(0u64);
let group2rgb: Vec<_> = (0..num_group * 3).map(|_| rng.random::<f32>()).collect();
vtx2group
.iter()
.map(|&i_group| {
[
group2rgb[i_group * 3],
group2rgb[i_group * 3 + 1],
group2rgb[i_group * 3 + 2],
]
})
.collect()
};
crate::io_wavefront_obj::save_tri2vtx_vtx2xyz_vtx2rgb(
path_dir.join("vtx2dist_from_vtx2vtx.obj"),
&trimesh3.tri2vtx,
&trimesh3.vtx2xyz,
&vtx2rgb,
)
.unwrap();
}