Skip to main content

oxihuman_export/
material_texture_export.rs

1#![allow(dead_code)]
2//! Material texture export.
3
4/// Material texture export data.
5#[allow(dead_code)]
6#[derive(Debug, Clone, PartialEq)]
7pub struct MaterialTextureExport {
8    pub slots: Vec<TextureSlot>,
9}
10
11/// A texture slot.
12#[allow(dead_code)]
13#[derive(Debug, Clone, PartialEq)]
14pub struct TextureSlot {
15    pub name: String,
16    pub texture_path: String,
17    pub uv_channel: u32,
18}
19
20/// Export material textures.
21#[allow(dead_code)]
22pub fn export_material_textures(slots: Vec<TextureSlot>) -> MaterialTextureExport {
23    MaterialTextureExport { slots }
24}
25
26/// Get slot count.
27#[allow(dead_code)]
28pub fn texture_slot_count(e: &MaterialTextureExport) -> usize {
29    e.slots.len()
30}
31
32/// Get slot name.
33#[allow(dead_code)]
34pub fn slot_name(e: &MaterialTextureExport, index: usize) -> &str {
35    if index < e.slots.len() {
36        &e.slots[index].name
37    } else {
38        ""
39    }
40}
41
42/// Get slot texture path.
43#[allow(dead_code)]
44pub fn slot_texture_path(e: &MaterialTextureExport, index: usize) -> &str {
45    if index < e.slots.len() {
46        &e.slots[index].texture_path
47    } else {
48        ""
49    }
50}
51
52/// Serialize slot to JSON.
53#[allow(dead_code)]
54pub fn slot_to_json(e: &MaterialTextureExport, index: usize) -> String {
55    if index < e.slots.len() {
56        let s = &e.slots[index];
57        format!(
58            "{{\"name\":\"{}\",\"path\":\"{}\",\"uv\":{}}}",
59            s.name, s.texture_path, s.uv_channel
60        )
61    } else {
62        "{}".to_string()
63    }
64}
65
66/// Get UV channel for slot.
67#[allow(dead_code)]
68pub fn slot_uv_channel(e: &MaterialTextureExport, index: usize) -> u32 {
69    if index < e.slots.len() {
70        e.slots[index].uv_channel
71    } else {
72        0
73    }
74}
75
76/// Get export size estimate.
77#[allow(dead_code)]
78pub fn texture_export_size_mt(e: &MaterialTextureExport) -> usize {
79    e.slots
80        .iter()
81        .map(|s| s.name.len() + s.texture_path.len() + 4)
82        .sum()
83}
84
85/// Validate material textures.
86#[allow(dead_code)]
87pub fn validate_material_textures(e: &MaterialTextureExport) -> bool {
88    e.slots
89        .iter()
90        .all(|s| !s.name.is_empty() && !s.texture_path.is_empty())
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    fn make_slot(name: &str, path: &str, uv: u32) -> TextureSlot {
98        TextureSlot {
99            name: name.to_string(),
100            texture_path: path.to_string(),
101            uv_channel: uv,
102        }
103    }
104
105    #[test]
106    fn test_export_material_textures() {
107        let e = export_material_textures(vec![make_slot("diffuse", "tex.png", 0)]);
108        assert_eq!(e.slots.len(), 1);
109    }
110
111    #[test]
112    fn test_texture_slot_count() {
113        let e = export_material_textures(vec![make_slot("a", "b", 0)]);
114        assert_eq!(texture_slot_count(&e), 1);
115    }
116
117    #[test]
118    fn test_slot_name() {
119        let e = export_material_textures(vec![make_slot("diffuse", "t.png", 0)]);
120        assert_eq!(slot_name(&e, 0), "diffuse");
121        assert_eq!(slot_name(&e, 5), "");
122    }
123
124    #[test]
125    fn test_slot_texture_path() {
126        let e = export_material_textures(vec![make_slot("d", "path.png", 0)]);
127        assert_eq!(slot_texture_path(&e, 0), "path.png");
128    }
129
130    #[test]
131    fn test_slot_to_json() {
132        let e = export_material_textures(vec![make_slot("d", "t.png", 0)]);
133        let j = slot_to_json(&e, 0);
134        assert!(j.contains("name"));
135    }
136
137    #[test]
138    fn test_slot_to_json_oob() {
139        let e = export_material_textures(vec![]);
140        assert_eq!(slot_to_json(&e, 0), "{}");
141    }
142
143    #[test]
144    fn test_slot_uv_channel() {
145        let e = export_material_textures(vec![make_slot("d", "t.png", 2)]);
146        assert_eq!(slot_uv_channel(&e, 0), 2);
147        assert_eq!(slot_uv_channel(&e, 5), 0);
148    }
149
150    #[test]
151    fn test_texture_export_size() {
152        let e = export_material_textures(vec![make_slot("ab", "cd", 0)]);
153        assert!(texture_export_size_mt(&e) > 0);
154    }
155
156    #[test]
157    fn test_validate_ok() {
158        let e = export_material_textures(vec![make_slot("a", "b", 0)]);
159        assert!(validate_material_textures(&e));
160    }
161
162    #[test]
163    fn test_validate_empty_name() {
164        let e = export_material_textures(vec![make_slot("", "b", 0)]);
165        assert!(!validate_material_textures(&e));
166    }
167}