Skip to main content

oxihuman_export/
microstructure_export.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5pub struct SkinMicrostructure {
6    pub furrow_depth_um: f32,
7    pub plateau_height_um: f32,
8    pub roughness_ra: f32,
9    pub scale_pattern: u8,
10}
11
12pub fn new_skin_microstructure() -> SkinMicrostructure {
13    SkinMicrostructure {
14        furrow_depth_um: 50.0,
15        plateau_height_um: 20.0,
16        roughness_ra: 3.5,
17        scale_pattern: 0,
18    }
19}
20
21/// Normalized roughness (Ra / 100).
22pub fn micro_roughness_index(m: &SkinMicrostructure) -> f32 {
23    (m.roughness_ra / 100.0).clamp(0.0, 1.0)
24}
25
26pub fn micro_to_json(m: &SkinMicrostructure) -> String {
27    format!(
28        "{{\"furrow_depth_um\":{:.2},\"plateau_height_um\":{:.2},\"roughness_ra\":{:.3},\"scale_pattern\":{}}}",
29        m.furrow_depth_um, m.plateau_height_um, m.roughness_ra, m.scale_pattern
30    )
31}
32
33pub fn micro_is_smooth(m: &SkinMicrostructure) -> bool {
34    m.roughness_ra < 5.0
35}
36
37/// Age index increases with roughness and furrow depth.
38pub fn micro_age_index(m: &SkinMicrostructure) -> f32 {
39    (m.roughness_ra / 50.0 + m.furrow_depth_um / 500.0).clamp(0.0, 1.0)
40}
41
42/// Estimate Fitzpatrick skin type from microstructure (rough heuristic, 1-6).
43pub fn micro_skin_type_estimate(m: &SkinMicrostructure) -> u8 {
44    match m.scale_pattern {
45        0 => 1,
46        1 => 2,
47        2 => 3,
48        3 => 4,
49        4 => 5,
50        _ => 6,
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_new_skin_microstructure() {
60        /* default fields */
61        let m = new_skin_microstructure();
62        assert!((m.roughness_ra - 3.5).abs() < 1e-6);
63    }
64
65    #[test]
66    fn test_is_smooth_default() {
67        /* default Ra < 5 => smooth */
68        let m = new_skin_microstructure();
69        assert!(micro_is_smooth(&m));
70    }
71
72    #[test]
73    fn test_is_not_smooth() {
74        /* high Ra => not smooth */
75        let m = SkinMicrostructure {
76            roughness_ra: 10.0,
77            ..new_skin_microstructure()
78        };
79        assert!(!micro_is_smooth(&m));
80    }
81
82    #[test]
83    fn test_to_json() {
84        /* JSON contains roughness_ra */
85        let m = new_skin_microstructure();
86        let json = micro_to_json(&m);
87        assert!(json.contains("roughness_ra"));
88    }
89
90    #[test]
91    fn test_age_index_range() {
92        /* age index is 0-1 */
93        let m = new_skin_microstructure();
94        let ai = micro_age_index(&m);
95        assert!((0.0..=1.0).contains(&ai));
96    }
97}