oxihuman_export/
edge_select_export.rs1#![allow(dead_code)]
4
5use std::collections::HashMap;
6
7#[allow(dead_code)]
9pub struct SelectedEdge {
10 pub v0: u32,
11 pub v1: u32,
12 pub flags: EdgeFlags,
13}
14
15#[allow(dead_code)]
16pub struct EdgeFlags {
17 pub is_seam: bool,
18 pub is_sharp: bool,
19 pub is_crease: bool,
20 pub crease_value: f32,
21}
22
23#[allow(dead_code)]
24pub struct EdgeSelectExport {
25 pub edges: Vec<SelectedEdge>,
26}
27
28#[allow(dead_code)]
29pub fn new_edge_select_export() -> EdgeSelectExport {
30 EdgeSelectExport { edges: vec![] }
31}
32
33#[allow(dead_code)]
34pub fn add_selected_edge(export: &mut EdgeSelectExport, edge: SelectedEdge) {
35 export.edges.push(edge);
36}
37
38#[allow(dead_code)]
39pub fn selected_edge_count(export: &EdgeSelectExport) -> usize {
40 export.edges.len()
41}
42
43#[allow(dead_code)]
44pub fn seam_count(export: &EdgeSelectExport) -> usize {
45 export.edges.iter().filter(|e| e.flags.is_seam).count()
46}
47
48#[allow(dead_code)]
49pub fn sharp_count(export: &EdgeSelectExport) -> usize {
50 export.edges.iter().filter(|e| e.flags.is_sharp).count()
51}
52
53#[allow(dead_code)]
54pub fn crease_count(export: &EdgeSelectExport) -> usize {
55 export.edges.iter().filter(|e| e.flags.is_crease).count()
56}
57
58#[allow(dead_code)]
59pub fn average_crease_value(export: &EdgeSelectExport) -> f32 {
60 let crease_edges: Vec<f32> = export
61 .edges
62 .iter()
63 .filter(|e| e.flags.is_crease)
64 .map(|e| e.flags.crease_value)
65 .collect();
66 if crease_edges.is_empty() {
67 return 0.0;
68 }
69 crease_edges.iter().sum::<f32>() / crease_edges.len() as f32
70}
71
72#[allow(dead_code)]
73pub fn edge_select_to_json(export: &EdgeSelectExport) -> String {
74 format!(
75 "{{\"total\":{},\"seams\":{},\"sharp\":{},\"crease\":{}}}",
76 export.edges.len(),
77 seam_count(export),
78 sharp_count(export),
79 crease_count(export)
80 )
81}
82
83#[allow(dead_code)]
84pub fn build_edge_index(export: &EdgeSelectExport) -> HashMap<(u32, u32), usize> {
85 let mut map = HashMap::new();
86 for (i, e) in export.edges.iter().enumerate() {
87 let key = if e.v0 < e.v1 {
88 (e.v0, e.v1)
89 } else {
90 (e.v1, e.v0)
91 };
92 map.insert(key, i);
93 }
94 map
95}
96
97#[allow(dead_code)]
98pub fn has_edge(export: &EdgeSelectExport, v0: u32, v1: u32) -> bool {
99 let key = if v0 < v1 { (v0, v1) } else { (v1, v0) };
100 export.edges.iter().any(|e| {
101 let ek = if e.v0 < e.v1 {
102 (e.v0, e.v1)
103 } else {
104 (e.v1, e.v0)
105 };
106 ek == key
107 })
108}
109
110#[allow(dead_code)]
111pub fn validate_edge_export(export: &EdgeSelectExport) -> bool {
112 export
113 .edges
114 .iter()
115 .all(|e| e.v0 != e.v1 && (0.0..=1.0).contains(&e.flags.crease_value))
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 fn sample_export() -> EdgeSelectExport {
123 let mut e = new_edge_select_export();
124 add_selected_edge(
125 &mut e,
126 SelectedEdge {
127 v0: 0,
128 v1: 1,
129 flags: EdgeFlags {
130 is_seam: true,
131 is_sharp: false,
132 is_crease: false,
133 crease_value: 0.0,
134 },
135 },
136 );
137 add_selected_edge(
138 &mut e,
139 SelectedEdge {
140 v0: 1,
141 v1: 2,
142 flags: EdgeFlags {
143 is_seam: false,
144 is_sharp: true,
145 is_crease: true,
146 crease_value: 0.8,
147 },
148 },
149 );
150 e
151 }
152
153 #[test]
154 fn test_selected_edge_count() {
155 let e = sample_export();
156 assert_eq!(selected_edge_count(&e), 2);
157 }
158
159 #[test]
160 fn test_seam_count() {
161 let e = sample_export();
162 assert_eq!(seam_count(&e), 1);
163 }
164
165 #[test]
166 fn test_sharp_count() {
167 let e = sample_export();
168 assert_eq!(sharp_count(&e), 1);
169 }
170
171 #[test]
172 fn test_crease_count() {
173 let e = sample_export();
174 assert_eq!(crease_count(&e), 1);
175 }
176
177 #[test]
178 fn test_average_crease_value() {
179 let e = sample_export();
180 assert!((average_crease_value(&e) - 0.8).abs() < 1e-5);
181 }
182
183 #[test]
184 fn test_has_edge() {
185 let e = sample_export();
186 assert!(has_edge(&e, 0, 1));
187 assert!(!has_edge(&e, 3, 4));
188 }
189
190 #[test]
191 fn test_validate_export() {
192 let e = sample_export();
193 assert!(validate_edge_export(&e));
194 }
195
196 #[test]
197 fn test_to_json() {
198 let e = sample_export();
199 let j = edge_select_to_json(&e);
200 assert!(j.contains("seams"));
201 }
202
203 #[test]
204 fn test_build_edge_index() {
205 let e = sample_export();
206 let idx = build_edge_index(&e);
207 assert!(idx.contains_key(&(0, 1)));
208 }
209
210 #[test]
211 fn test_empty_average_crease() {
212 let e = new_edge_select_export();
213 assert_eq!(average_crease_value(&e), 0.0);
214 }
215}