oxihuman_export/
curve_modifier_export.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
8#[derive(Debug, Clone, Copy, PartialEq)]
9pub enum CurveModAxis {
10 X,
11 Y,
12 Z,
13}
14
15#[allow(dead_code)]
16#[derive(Debug, Clone)]
17pub struct CurveModEntry {
18 pub control_points: Vec<[f32; 3]>,
19 pub axis: CurveModAxis,
20 pub stretch: bool,
21 pub bounds_clamp: bool,
22}
23
24#[allow(dead_code)]
25#[derive(Debug, Clone)]
26pub struct CurveModifierExport {
27 pub modifiers: Vec<CurveModEntry>,
28}
29
30#[allow(dead_code)]
31pub fn new_curve_modifier_export() -> CurveModifierExport {
32 CurveModifierExport {
33 modifiers: Vec::new(),
34 }
35}
36
37#[allow(dead_code)]
38pub fn add_curve_mod(exp: &mut CurveModifierExport, points: Vec<[f32; 3]>, axis: CurveModAxis) {
39 exp.modifiers.push(CurveModEntry {
40 control_points: points,
41 axis,
42 stretch: false,
43 bounds_clamp: true,
44 });
45}
46
47#[allow(dead_code)]
48pub fn mod_count(exp: &CurveModifierExport) -> usize {
49 exp.modifiers.len()
50}
51
52#[allow(dead_code)]
53pub fn curve_mod_length(entry: &CurveModEntry) -> f32 {
54 let mut len = 0.0_f32;
55 for pair in entry.control_points.windows(2) {
56 let d = [
57 pair[1][0] - pair[0][0],
58 pair[1][1] - pair[0][1],
59 pair[1][2] - pair[0][2],
60 ];
61 len += (d[0] * d[0] + d[1] * d[1] + d[2] * d[2]).sqrt();
62 }
63 len
64}
65
66#[allow(dead_code)]
67pub fn axis_name(axis: CurveModAxis) -> &'static str {
68 match axis {
69 CurveModAxis::X => "X",
70 CurveModAxis::Y => "Y",
71 CurveModAxis::Z => "Z",
72 }
73}
74
75#[allow(dead_code)]
76pub fn validate_curve_mod(entry: &CurveModEntry) -> bool {
77 entry.control_points.len() >= 2
78}
79
80#[allow(dead_code)]
81pub fn curve_modifier_to_json(exp: &CurveModifierExport) -> String {
82 format!("{{\"modifier_count\":{}}}", exp.modifiers.len())
83}
84
85#[allow(dead_code)]
86pub fn total_curve_length(exp: &CurveModifierExport) -> f32 {
87 exp.modifiers.iter().map(curve_mod_length).sum()
88}
89
90#[allow(dead_code)]
91pub fn clear_curve_mods(exp: &mut CurveModifierExport) {
92 exp.modifiers.clear();
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 fn sample_points() -> Vec<[f32; 3]> {
100 vec![[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [2.0, 0.0, 0.0]]
101 }
102
103 #[test]
104 fn test_new_empty() {
105 let exp = new_curve_modifier_export();
106 assert_eq!(mod_count(&exp), 0);
107 }
108
109 #[test]
110 fn test_add_mod() {
111 let mut exp = new_curve_modifier_export();
112 add_curve_mod(&mut exp, sample_points(), CurveModAxis::Y);
113 assert_eq!(mod_count(&exp), 1);
114 }
115
116 #[test]
117 fn test_curve_length() {
118 let entry = CurveModEntry {
119 control_points: sample_points(),
120 axis: CurveModAxis::Y,
121 stretch: false,
122 bounds_clamp: true,
123 };
124 assert!((curve_mod_length(&entry) - 2.0).abs() < 1e-5);
125 }
126
127 #[test]
128 fn test_axis_name_y() {
129 assert_eq!(axis_name(CurveModAxis::Y), "Y");
130 }
131
132 #[test]
133 fn test_validate_valid() {
134 let entry = CurveModEntry {
135 control_points: sample_points(),
136 axis: CurveModAxis::X,
137 stretch: false,
138 bounds_clamp: true,
139 };
140 assert!(validate_curve_mod(&entry));
141 }
142
143 #[test]
144 fn test_validate_single_point() {
145 let entry = CurveModEntry {
146 control_points: vec![[0.0; 3]],
147 axis: CurveModAxis::X,
148 stretch: false,
149 bounds_clamp: true,
150 };
151 assert!(!validate_curve_mod(&entry));
152 }
153
154 #[test]
155 fn test_json_output() {
156 let exp = new_curve_modifier_export();
157 let j = curve_modifier_to_json(&exp);
158 assert!(j.contains("modifier_count"));
159 }
160
161 #[test]
162 fn test_total_length() {
163 let mut exp = new_curve_modifier_export();
164 add_curve_mod(&mut exp, sample_points(), CurveModAxis::Z);
165 assert!(total_curve_length(&exp) > 0.0);
166 }
167
168 #[test]
169 fn test_clear_mods() {
170 let mut exp = new_curve_modifier_export();
171 add_curve_mod(&mut exp, sample_points(), CurveModAxis::X);
172 clear_curve_mods(&mut exp);
173 assert_eq!(mod_count(&exp), 0);
174 }
175
176 #[test]
177 fn test_axis_x_name() {
178 assert_eq!(axis_name(CurveModAxis::X), "X");
179 }
180}