#![allow(dead_code)]
#[derive(Clone, Copy, PartialEq)]
pub enum AttrDomain {
Vertex,
Edge,
Face,
FaceCorner,
}
pub struct AttributeLayer {
pub name: String,
pub domain: AttrDomain,
pub data: Vec<f32>,
}
pub struct AttributeLayerSet {
pub layers: Vec<AttributeLayer>,
}
pub fn new_attribute_layer_set() -> AttributeLayerSet {
AttributeLayerSet { layers: Vec::new() }
}
pub fn add_attribute_layer(
set: &mut AttributeLayerSet,
name: &str,
domain: AttrDomain,
element_count: usize,
default_val: f32,
) {
set.layers.push(AttributeLayer {
name: name.to_string(),
domain,
data: vec![default_val; element_count],
});
}
pub fn get_attribute_layer<'a>(
set: &'a AttributeLayerSet,
name: &str,
) -> Option<&'a AttributeLayer> {
set.layers.iter().find(|l| l.name == name)
}
pub fn get_attribute_layer_mut<'a>(
set: &'a mut AttributeLayerSet,
name: &str,
) -> Option<&'a mut AttributeLayer> {
set.layers.iter_mut().find(|l| l.name == name)
}
pub fn remove_attribute_layer(set: &mut AttributeLayerSet, name: &str) -> bool {
if let Some(pos) = set.layers.iter().position(|l| l.name == name) {
set.layers.remove(pos);
true
} else {
false
}
}
pub fn attribute_layer_count(set: &AttributeLayerSet) -> usize {
set.layers.len()
}
pub fn attribute_average(set: &AttributeLayerSet, name: &str) -> Option<f32> {
let layer = get_attribute_layer(set, name)?;
if layer.data.is_empty() {
return Some(0.0);
}
let sum: f32 = layer.data.iter().sum();
Some(sum / layer.data.len() as f32)
}
pub fn validate_attribute_layers(set: &AttributeLayerSet, vertex_count: usize) -> bool {
set.layers.iter().all(|l| match l.domain {
AttrDomain::Vertex => l.data.len() == vertex_count,
_ => true,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_set_empty() {
let s = new_attribute_layer_set();
assert_eq!(attribute_layer_count(&s), 0 );
}
#[test]
fn add_layer_increments() {
let mut s = new_attribute_layer_set();
add_attribute_layer(&mut s, "weights", AttrDomain::Vertex, 4, 0.0);
assert_eq!(attribute_layer_count(&s), 1 );
}
#[test]
fn get_layer_by_name() {
let mut s = new_attribute_layer_set();
add_attribute_layer(&mut s, "ao", AttrDomain::Vertex, 3, 1.0);
let l = get_attribute_layer(&s, "ao");
assert!(l.is_some() );
assert_eq!(l.expect("should succeed").data.len(), 3 );
}
#[test]
fn get_missing_none() {
let s = new_attribute_layer_set();
assert!(get_attribute_layer(&s, "x").is_none() );
}
#[test]
fn remove_layer_works() {
let mut s = new_attribute_layer_set();
add_attribute_layer(&mut s, "del", AttrDomain::Face, 2, 0.0);
let ok = remove_attribute_layer(&mut s, "del");
assert!(ok );
assert_eq!(attribute_layer_count(&s), 0 );
}
#[test]
fn remove_missing_false() {
let mut s = new_attribute_layer_set();
assert!(!remove_attribute_layer(&mut s, "none") );
}
#[test]
fn attribute_average_correct() {
let mut s = new_attribute_layer_set();
add_attribute_layer(&mut s, "val", AttrDomain::Vertex, 4, 0.0);
if let Some(l) = get_attribute_layer_mut(&mut s, "val") {
l.data[0] = 2.0;
l.data[1] = 4.0;
l.data[2] = 6.0;
l.data[3] = 8.0;
}
let avg = attribute_average(&s, "val").expect("should succeed");
assert!((avg - 5.0).abs() < 1e-6 );
}
#[test]
fn attribute_average_missing_none() {
let s = new_attribute_layer_set();
assert!(attribute_average(&s, "x").is_none() );
}
#[test]
fn validate_vertex_layer_correct_count() {
let mut s = new_attribute_layer_set();
add_attribute_layer(&mut s, "v", AttrDomain::Vertex, 5, 0.0);
assert!(validate_attribute_layers(&s, 5) );
assert!(!validate_attribute_layers(&s, 3) );
}
}