dedup_mesh 0.2.0

Deduplicates vertices in a 3d mesh
Documentation
// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2025 lacklustr@protonmail.com https://github.com/eadf

use num_traits::AsPrimitive;
use rand::prelude::StdRng;
use rand::{Rng, SeedableRng};

#[allow(dead_code)]
fn generate_random_vertices<T: dedup_mesh::Scalar>(rng: &mut StdRng, count: usize) -> Vec<[T; 3]>
where
    f64: AsPrimitive<T>,
    f32: AsPrimitive<T>,
{
    (0..count)
        .map(|_| {
            [
                rng.random_range(-100.0..100.0).as_(),
                rng.random_range(-100.0..100.0).as_(),
                rng.random_range(-100.0..100.0).as_(),
            ]
        })
        .collect()
}

#[allow(dead_code)]
fn generate_clustered_vertices<T: dedup_mesh::Scalar>(
    rng: &mut StdRng,
    base_vertices: &[[T; 3]],
    count: usize,
) -> Vec<[T; 3]>
where
    f64: AsPrimitive<T>,
    f32: AsPrimitive<T>,
{
    (0..count)
        .map(|_| {
            if base_vertices.is_empty() {
                return [
                    rng.random_range(-100.0..100.0).as_(),
                    rng.random_range(-100.0..100.0).as_(),
                    rng.random_range(-100.0..100.0).as_(),
                ];
            }

            let base_idx = rng.random_range(0..base_vertices.len());
            let base = base_vertices[base_idx];

            // Generate [f32;3] close to the base [T;3]
            let offset_range = 0.01; // Small offset to create near-duplicates
            [
                base[0] + rng.random_range(-offset_range..offset_range).as_(),
                base[1] + rng.random_range(-offset_range..offset_range).as_(),
                base[2] + rng.random_range(-offset_range..offset_range).as_(),
            ]
        })
        .collect()
}

#[allow(dead_code)]
pub(crate) fn generate_test_data<T: dedup_mesh::Scalar>(vertex_count: usize) -> Vec<[T; 3]>
where
    f64: AsPrimitive<T>,
    f32: AsPrimitive<T>,
{
    let mut rng = StdRng::seed_from_u64(42); // Deterministic seed

    // Generate initial random vertices (30% of total)
    let initial_count = vertex_count * 3 / 10;
    let mut vertices: Vec<[T; 3]> = generate_random_vertices::<T>(&mut rng, initial_count);

    // Generate clustered vertices that create near-duplicates (70% of total)
    let clustered_count = vertex_count - initial_count;
    let clustered = generate_clustered_vertices::<T>(&mut rng, &vertices, clustered_count);
    vertices.extend(clustered);

    // Shuffle to mix random and clustered vertices
    use rand::seq::SliceRandom;
    vertices.shuffle(&mut rng);

    vertices
}