1#![allow(dead_code)]
7
8#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct VdbConfig {
11 pub grid_name: String,
12 pub voxel_size: f32,
13 pub background_value: f32,
14}
15
16#[allow(dead_code)]
17#[derive(Debug, Clone)]
18pub struct VdbGrid {
19 pub config: VdbConfig,
20 pub active_voxels: Vec<([i32; 3], f32)>,
21}
22
23#[allow(dead_code)]
24#[derive(Debug, Clone)]
25pub struct VdbExportResult {
26 pub voxel_count: usize,
27 pub min_value: f32,
28 pub max_value: f32,
29}
30
31#[allow(dead_code)]
32pub fn default_vdb_config() -> VdbConfig {
33 VdbConfig {
34 grid_name: "density".to_string(),
35 voxel_size: 0.1,
36 background_value: 0.0,
37 }
38}
39
40#[allow(dead_code)]
41pub fn new_vdb_grid(config: VdbConfig) -> VdbGrid {
42 VdbGrid {
43 config,
44 active_voxels: Vec::new(),
45 }
46}
47
48#[allow(dead_code)]
49pub fn vdb_set_voxel(grid: &mut VdbGrid, coord: [i32; 3], value: f32) {
50 if let Some(entry) = grid.active_voxels.iter_mut().find(|(c, _)| *c == coord) {
51 entry.1 = value;
52 } else {
53 grid.active_voxels.push((coord, value));
54 }
55}
56
57#[allow(dead_code)]
58pub fn vdb_get_voxel(grid: &VdbGrid, coord: [i32; 3]) -> f32 {
59 grid.active_voxels
60 .iter()
61 .find(|(c, _)| *c == coord)
62 .map(|(_, v)| *v)
63 .unwrap_or(grid.config.background_value)
64}
65
66#[allow(dead_code)]
67pub fn vdb_active_count(grid: &VdbGrid) -> usize {
68 grid.active_voxels.len()
69}
70
71#[allow(dead_code)]
72pub fn vdb_clear(grid: &mut VdbGrid) {
73 grid.active_voxels.clear();
74}
75
76#[allow(dead_code)]
77pub fn vdb_stats(grid: &VdbGrid) -> VdbExportResult {
78 if grid.active_voxels.is_empty() {
79 return VdbExportResult {
80 voxel_count: 0,
81 min_value: grid.config.background_value,
82 max_value: grid.config.background_value,
83 };
84 }
85 let values: Vec<f32> = grid.active_voxels.iter().map(|(_, v)| *v).collect();
86 let min_value = values.iter().cloned().fold(f32::MAX, f32::min);
87 let max_value = values.iter().cloned().fold(f32::MIN, f32::max);
88 VdbExportResult {
89 voxel_count: grid.active_voxels.len(),
90 min_value,
91 max_value,
92 }
93}
94
95#[allow(dead_code)]
96pub fn vdb_export_to_bytes(grid: &VdbGrid) -> Vec<u8> {
97 let mut bytes = Vec::with_capacity(grid.active_voxels.len() * 16);
99 for (coord, value) in &grid.active_voxels {
100 for &c in coord {
101 bytes.extend_from_slice(&c.to_le_bytes());
102 }
103 bytes.extend_from_slice(&value.to_le_bytes());
104 }
105 bytes
106}
107
108#[allow(dead_code)]
109pub fn vdb_to_json(grid: &VdbGrid) -> String {
110 let stats = vdb_stats(grid);
111 format!(
112 "{{\"grid_name\":\"{}\",\"voxel_size\":{},\"active_voxels\":{},\"min\":{},\"max\":{}}}",
113 grid.config.grid_name,
114 grid.config.voxel_size,
115 stats.voxel_count,
116 stats.min_value,
117 stats.max_value
118 )
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_default_config() {
127 let cfg = default_vdb_config();
128 assert_eq!(cfg.grid_name, "density");
129 }
130
131 #[test]
132 fn test_set_get_voxel() {
133 let mut grid = new_vdb_grid(default_vdb_config());
134 vdb_set_voxel(&mut grid, [0, 0, 0], 1.0);
135 assert!((vdb_get_voxel(&grid, [0, 0, 0]) - 1.0).abs() < 1e-6);
136 }
137
138 #[test]
139 fn test_get_background() {
140 let grid = new_vdb_grid(default_vdb_config());
141 assert!((vdb_get_voxel(&grid, [5, 5, 5]) - 0.0).abs() < 1e-6);
142 }
143
144 #[test]
145 fn test_active_count() {
146 let mut grid = new_vdb_grid(default_vdb_config());
147 vdb_set_voxel(&mut grid, [0, 0, 0], 1.0);
148 vdb_set_voxel(&mut grid, [1, 0, 0], 0.5);
149 assert_eq!(vdb_active_count(&grid), 2);
150 }
151
152 #[test]
153 fn test_set_voxel_updates() {
154 let mut grid = new_vdb_grid(default_vdb_config());
155 vdb_set_voxel(&mut grid, [0, 0, 0], 1.0);
156 vdb_set_voxel(&mut grid, [0, 0, 0], 2.0);
157 assert_eq!(vdb_active_count(&grid), 1);
158 assert!((vdb_get_voxel(&grid, [0, 0, 0]) - 2.0).abs() < 1e-6);
159 }
160
161 #[test]
162 fn test_clear() {
163 let mut grid = new_vdb_grid(default_vdb_config());
164 vdb_set_voxel(&mut grid, [0, 0, 0], 1.0);
165 vdb_clear(&mut grid);
166 assert_eq!(vdb_active_count(&grid), 0);
167 }
168
169 #[test]
170 fn test_stats() {
171 let mut grid = new_vdb_grid(default_vdb_config());
172 vdb_set_voxel(&mut grid, [0, 0, 0], 0.2);
173 vdb_set_voxel(&mut grid, [1, 0, 0], 0.8);
174 let stats = vdb_stats(&grid);
175 assert!((stats.min_value - 0.2).abs() < 1e-5);
176 assert!((stats.max_value - 0.8).abs() < 1e-5);
177 }
178
179 #[test]
180 fn test_export_bytes() {
181 let mut grid = new_vdb_grid(default_vdb_config());
182 vdb_set_voxel(&mut grid, [0, 0, 0], 1.0);
183 let bytes = vdb_export_to_bytes(&grid);
184 assert_eq!(bytes.len(), 16); }
186
187 #[test]
188 fn test_to_json() {
189 let grid = new_vdb_grid(default_vdb_config());
190 let j = vdb_to_json(&grid);
191 assert!(j.contains("grid_name"));
192 }
193}