#![allow(dead_code)]
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct FaceMap {
pub groups: HashMap<String, Vec<usize>>,
}
impl FaceMap {
pub fn new() -> Self {
Self {
groups: HashMap::new(),
}
}
pub fn add_group(&mut self, name: &str, faces: Vec<usize>) {
self.groups.insert(name.to_string(), faces);
}
pub fn remove_group(&mut self, name: &str) -> Option<Vec<usize>> {
self.groups.remove(name)
}
pub fn group_count(&self) -> usize {
self.groups.len()
}
pub fn group_names(&self) -> Vec<String> {
let mut names: Vec<String> = self.groups.keys().cloned().collect();
names.sort();
names
}
pub fn get_group(&self, name: &str) -> Option<&Vec<usize>> {
self.groups.get(name)
}
}
impl Default for FaceMap {
fn default() -> Self {
Self::new()
}
}
pub fn total_face_count(fm: &FaceMap) -> usize {
fm.groups.values().map(|v| v.len()).sum()
}
pub fn face_in_any_group(fm: &FaceMap, face_idx: usize) -> bool {
fm.groups.values().any(|v| v.contains(&face_idx))
}
pub fn merge_face_maps(a: &FaceMap, b: &FaceMap) -> FaceMap {
let mut result = a.clone();
for (name, faces) in &b.groups {
result.groups.insert(name.clone(), faces.clone());
}
result
}
pub fn rename_group(fm: &mut FaceMap, old_name: &str, new_name: &str) -> bool {
if let Some(faces) = fm.groups.remove(old_name) {
fm.groups.insert(new_name.to_string(), faces);
true
} else {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
fn basic_map() -> FaceMap {
let mut fm = FaceMap::new();
fm.add_group("left_arm", vec![0, 1, 2]);
fm.add_group("right_arm", vec![3, 4, 5]);
fm
}
#[test]
fn test_group_count() {
let fm = basic_map();
assert_eq!(fm.group_count(), 2);
}
#[test]
fn test_get_group() {
let fm = basic_map();
let g = fm.get_group("left_arm").expect("should succeed");
assert_eq!(g, &vec![0, 1, 2]);
}
#[test]
fn test_remove_group() {
let mut fm = basic_map();
fm.remove_group("left_arm");
assert_eq!(fm.group_count(), 1);
}
#[test]
fn test_total_face_count() {
let fm = basic_map();
assert_eq!(total_face_count(&fm), 6);
}
#[test]
fn test_face_in_any_group() {
let fm = basic_map();
assert!(face_in_any_group(&fm, 4));
assert!(!face_in_any_group(&fm, 99));
}
#[test]
fn test_merge_face_maps() {
let fm1 = basic_map();
let mut fm2 = FaceMap::new();
fm2.add_group("head", vec![10, 11]);
let merged = merge_face_maps(&fm1, &fm2);
assert_eq!(merged.group_count(), 3);
}
#[test]
fn test_rename_group() {
let mut fm = basic_map();
assert!(rename_group(&mut fm, "left_arm", "arm_left"));
assert!(fm.get_group("arm_left").is_some());
assert!(fm.get_group("left_arm").is_none());
}
#[test]
fn test_group_names_sorted() {
let fm = basic_map();
let names = fm.group_names();
assert_eq!(names[0], "left_arm");
assert_eq!(names[1], "right_arm");
}
#[test]
fn test_rename_nonexistent_returns_false() {
let mut fm = basic_map();
assert!(!rename_group(&mut fm, "no_such_group", "new_name"));
}
}