oxihuman_export/
mesh_proxy_export.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct MeshProxyExport2 {
11 pub positions: Vec<[f32; 3]>,
12 pub indices: Vec<u32>,
13 pub source_vertex_count: usize,
14}
15
16#[allow(dead_code)]
17pub fn new_mesh_proxy2(
18 positions: &[[f32; 3]],
19 indices: &[u32],
20 source_count: usize,
21) -> MeshProxyExport2 {
22 MeshProxyExport2 {
23 positions: positions.to_vec(),
24 indices: indices.to_vec(),
25 source_vertex_count: source_count,
26 }
27}
28
29#[allow(dead_code)]
30pub fn proxy2_vertex_count_fn(p: &MeshProxyExport2) -> usize {
31 p.positions.len()
32}
33
34#[allow(dead_code)]
35pub fn proxy2_triangle_count(p: &MeshProxyExport2) -> usize {
36 p.indices.len() / 3
37}
38
39#[allow(dead_code)]
40pub fn proxy2_reduction_ratio(p: &MeshProxyExport2) -> f32 {
41 if p.source_vertex_count == 0 {
42 return 0.0;
43 }
44 p.positions.len() as f32 / p.source_vertex_count as f32
45}
46
47#[allow(dead_code)]
48pub fn proxy2_bounds_fn(p: &MeshProxyExport2) -> ([f32; 3], [f32; 3]) {
49 if p.positions.is_empty() {
50 return ([0.0; 3], [0.0; 3]);
51 }
52 let mut mn = p.positions[0];
53 let mut mx = p.positions[0];
54 for v in &p.positions {
55 for k in 0..3 {
56 mn[k] = mn[k].min(v[k]);
57 mx[k] = mx[k].max(v[k]);
58 }
59 }
60 (mn, mx)
61}
62
63#[allow(dead_code)]
64pub fn proxy2_center_fn(p: &MeshProxyExport2) -> [f32; 3] {
65 let (mn, mx) = proxy2_bounds_fn(p);
66 [
67 (mn[0] + mx[0]) * 0.5,
68 (mn[1] + mx[1]) * 0.5,
69 (mn[2] + mx[2]) * 0.5,
70 ]
71}
72
73#[allow(dead_code)]
74pub fn proxy2_to_obj(p: &MeshProxyExport2) -> String {
75 let mut s = String::new();
76 for v in &p.positions {
77 s.push_str(&format!("v {} {} {}\n", v[0], v[1], v[2]));
78 }
79 let tri = p.indices.len() / 3;
80 for t in 0..tri {
81 s.push_str(&format!(
82 "f {} {} {}\n",
83 p.indices[t * 3] + 1,
84 p.indices[t * 3 + 1] + 1,
85 p.indices[t * 3 + 2] + 1
86 ));
87 }
88 s
89}
90
91#[allow(dead_code)]
92pub fn mesh_proxy2_to_json(p: &MeshProxyExport2) -> String {
93 format!(
94 "{{\"vertices\":{},\"triangles\":{},\"ratio\":{:.6}}}",
95 p.positions.len(),
96 p.indices.len() / 3,
97 proxy2_reduction_ratio(p)
98 )
99}
100
101#[allow(dead_code)]
102pub fn proxy2_validate(p: &MeshProxyExport2) -> bool {
103 p.indices.iter().all(|&i| (i as usize) < p.positions.len())
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 fn tri() -> MeshProxyExport2 {
111 new_mesh_proxy2(
112 &[[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.5, 1.0, 0.0]],
113 &[0, 1, 2],
114 100,
115 )
116 }
117
118 #[test]
119 fn test_new() {
120 assert_eq!(proxy2_vertex_count_fn(&tri()), 3);
121 }
122
123 #[test]
124 fn test_triangle_count() {
125 assert_eq!(proxy2_triangle_count(&tri()), 1);
126 }
127
128 #[test]
129 fn test_reduction_ratio() {
130 assert!((proxy2_reduction_ratio(&tri()) - 0.03).abs() < 1e-6);
131 }
132
133 #[test]
134 fn test_bounds() {
135 let (mn, mx) = proxy2_bounds_fn(&tri());
136 assert!((mn[0]).abs() < 1e-6);
137 assert!((mx[0] - 1.0).abs() < 1e-6);
138 }
139
140 #[test]
141 fn test_center() {
142 let c = proxy2_center_fn(&tri());
143 assert!((c[0] - 0.5).abs() < 1e-6);
144 }
145
146 #[test]
147 fn test_to_obj() {
148 let s = proxy2_to_obj(&tri());
149 assert!(s.contains("v "));
150 assert!(s.contains("f "));
151 }
152
153 #[test]
154 fn test_to_json() {
155 assert!(mesh_proxy2_to_json(&tri()).contains("\"vertices\":3"));
156 }
157
158 #[test]
159 fn test_validate_ok() {
160 assert!(proxy2_validate(&tri()));
161 }
162
163 #[test]
164 fn test_validate_bad() {
165 let p = MeshProxyExport2 {
166 positions: vec![[0.0; 3]],
167 indices: vec![5],
168 source_vertex_count: 1,
169 };
170 assert!(!proxy2_validate(&p));
171 }
172
173 #[test]
174 fn test_empty_ratio() {
175 let p = new_mesh_proxy2(&[], &[], 0);
176 assert!((proxy2_reduction_ratio(&p)).abs() < 1e-6);
177 }
178}