quantized_density_fields/lod/mod.rs
1pub mod level;
2mod tests;
3
4pub use self::level::*;
5use error::*;
6use id::*;
7use petgraph::algo::astar;
8use petgraph::graphmap::UnGraphMap;
9use qdf::*;
10use rayon::prelude::*;
11use std::collections::{HashMap, HashSet};
12
13/// Object that represents space level of details.
14/// This gives you the ability to sample space area states at different zoom levels (LOD mechanism).
15#[derive(Debug)]
16pub struct LOD<S>
17where
18 S: State,
19{
20 id: ID,
21 graph: UnGraphMap<ID, ()>,
22 levels: HashMap<ID, Level<S>>,
23 platonic_levels: HashSet<ID>,
24 root: ID,
25 dimensions: usize,
26 count: usize,
27}
28
29impl<S> LOD<S>
30where
31 S: State,
32{
33 /// Creates new LOD information universe.
34 ///
35 /// # Arguments
36 /// * `dimensions` - Number of dimensions which space contains.
37 /// * `count` - Number of levels.
38 /// * `root_state` - State of root level.
39 ///
40 /// # Examples
41 /// ```
42 /// use quantized_density_fields::LOD;
43 ///
44 /// // Create 2D space with 1 level of details and `16` as root space.
45 /// let lod = LOD::new(2, 1, 16);
46 /// assert_eq!(*lod.state(), 16);
47 /// // LOD has 4 children level objects.
48 /// assert_eq!(lod.level(lod.root()).sublevels().len(), 4);
49 /// // sampled state at level 1 equals to `4` (`16 / 4`).
50 /// assert_eq!(*lod.level(lod.level(lod.root()).sublevels()[0]).state(), 4);
51 /// ```
52 pub fn new(dimensions: usize, count: usize, root_state: S) -> Self {
53 let mut graph = UnGraphMap::new();
54 let mut levels = HashMap::new();
55 let mut platonic_levels = HashSet::new();
56 let root = ID::new();
57 let main = Level::new(root, None, 0, 0, root_state);
58 levels.insert(root, main);
59 graph.add_node(root);
60 Self::subdivide_level(root, &mut graph, &mut levels, dimensions + 2, count);
61 Self::connect_clusters(root, &mut graph, &levels);
62 Self::collect_platonic_levels(root, &levels, &mut platonic_levels);
63 Self {
64 id: ID::new(),
65 graph,
66 levels,
67 platonic_levels,
68 root,
69 dimensions,
70 count,
71 }
72 }
73
74 /// Gets LOD id.
75 #[inline]
76 pub fn id(&self) -> ID {
77 self.id
78 }
79
80 /// Gets LOD root level node id.
81 #[inline]
82 pub fn root(&self) -> ID {
83 self.root
84 }
85
86 /// Gets LOD dimensions number.
87 ///
88 /// # Examples
89 /// ```
90 /// use quantized_density_fields::LOD;
91 ///
92 /// let lod = LOD::new(2, 1, 16);
93 /// assert_eq!(lod.dimensions(), 2);
94 /// ```
95 #[inline]
96 pub fn dimensions(&self) -> usize {
97 self.dimensions
98 }
99
100 /// Gets LOD zoom levels number.
101 ///
102 /// # Examples
103 /// ```
104 /// use quantized_density_fields::LOD;
105 ///
106 /// let lod = LOD::new(2, 1, 16);
107 /// assert_eq!(lod.levels_count(), 1);
108 /// ```
109 #[inline]
110 pub fn levels_count(&self) -> usize {
111 self.count
112 }
113
114 /// Gets LOD root level state.
115 /// # Examples
116 /// ```
117 /// use quantized_density_fields::LOD;
118 ///
119 /// let lod = LOD::new(2, 1, 16);
120 /// assert_eq!(*lod.state(), 16);
121 /// ```
122 #[inline]
123 pub fn state(&self) -> &S {
124 self.levels[&self.root].state()
125 }
126
127 /// Tells if space level with given id exists in LOD.
128 ///
129 /// # Arguments
130 /// * `id` - level id.
131 ///
132 /// # Examples
133 /// ```
134 /// use quantized_density_fields::LOD;
135 ///
136 /// let lod = LOD::new(2, 1, 16);
137 /// assert!(lod.level_exists(lod.root()));
138 /// ```
139 #[inline]
140 pub fn level_exists(&self, id: ID) -> bool {
141 self.levels.contains_key(&id)
142 }
143
144 /// Try to get reference to given space level.
145 ///
146 /// # Arguments
147 /// * `id` - level id.
148 ///
149 /// # Examples
150 /// ```
151 /// use quantized_density_fields::LOD;
152 ///
153 /// let lod = LOD::new(2, 1, 16);
154 /// if let Some(level) = lod.try_get_level(lod.root()) {
155 /// assert_eq!(*level.state(), 16);
156 /// }
157 /// ```
158 #[inline]
159 pub fn try_get_level(&self, id: ID) -> Option<&Level<S>> {
160 self.levels.get(&id)
161 }
162
163 /// Gets reference to given space level and throws error if level does not exists.
164 ///
165 /// # Arguments
166 /// * `id` - level id.
167 ///
168 /// # Examples
169 /// ```
170 /// use quantized_density_fields::LOD;
171 ///
172 /// let lod = LOD::new(2, 1, 16);
173 /// if let Ok(level) = lod.get_level(lod.root()) {
174 /// assert_eq!(*level.state(), 16);
175 /// }
176 /// ```
177 #[inline]
178 pub fn get_level(&self, id: ID) -> Result<&Level<S>> {
179 if let Some(level) = self.levels.get(&id) {
180 Ok(level)
181 } else {
182 Err(QDFError::LevelDoesNotExists(id))
183 }
184 }
185
186 /// Gets reference to given space level and panics if level does not exists.
187 ///
188 /// # Arguments
189 /// * `id` - level id.
190 ///
191 /// # Examples
192 /// ```
193 /// use quantized_density_fields::LOD;
194 ///
195 /// let lod = LOD::new(2, 1, 16);
196 /// assert_eq!(*lod.level(lod.root()).state(), 16);
197 /// ```
198 #[inline]
199 pub fn level(&self, id: ID) -> &Level<S> {
200 &self.levels[&id]
201 }
202
203 /// Try to set given level state.
204 ///
205 /// # Arguments
206 /// * `id` - level id.
207 /// * `state` - state.
208 ///
209 /// # Examples
210 /// ```
211 /// use quantized_density_fields::LOD;
212 ///
213 /// let mut lod = LOD::new(2, 1, 9);
214 /// let id = lod.root();
215 /// assert!(lod.try_set_level_state(id, 3));
216 /// ```
217 #[inline]
218 pub fn try_set_level_state(&mut self, id: ID, state: S) -> bool {
219 self.set_level_state(id, state).is_ok()
220 }
221
222 /// Set given level state or throw error if level does not exists.
223 ///
224 /// # Arguments
225 /// * `id` - level id.
226 /// * `state` - state.
227 ///
228 /// # Examples
229 /// ```
230 /// use quantized_density_fields::LOD;
231 ///
232 /// let mut lod = LOD::new(2, 1, 9);
233 /// let id = lod.root();
234 /// assert!(lod.set_level_state(id, 3).is_ok());
235 /// ```
236 #[inline]
237 pub fn set_level_state(&mut self, id: ID, state: S) -> Result<()> {
238 if self.level_exists(id) {
239 self.levels.get_mut(&id).unwrap().apply_state(state);
240 self.recalculate_children_states(id);
241 self.recalculate_parent_state(id);
242 Ok(())
243 } else {
244 Err(QDFError::LevelDoesNotExists(id))
245 }
246 }
247
248 /// Gets list of space level neighbors IDs or throws error if level does not exists.
249 ///
250 /// # Arguments
251 /// * `id` - Level id.
252 ///
253 /// # Examples
254 /// ```
255 /// use quantized_density_fields::LOD;
256 ///
257 /// let lod = LOD::new(2, 1, 16);
258 /// let subs = lod.level(lod.root()).sublevels();
259 /// assert_eq!(lod.find_level_neighbors(subs[0]).unwrap(), vec![subs[1], subs[2], subs[3]]);
260 /// ```
261 #[inline]
262 pub fn find_level_neighbors(&self, id: ID) -> Result<Vec<ID>> {
263 if self.graph.contains_node(id) {
264 Ok(self.graph.neighbors(id).collect())
265 } else {
266 Err(QDFError::LevelDoesNotExists(id))
267 }
268 }
269
270 /// Gets list of space level IDs that defines shortest path between two space levels,
271 /// or throws error if level does not exists. Levels must lay on the same zoom level!
272 ///
273 /// # Arguments
274 /// * `from` - source level id.
275 /// * `to` - target level id.
276 ///
277 /// # Examples
278 /// ```
279 /// use quantized_density_fields::LOD;
280 ///
281 /// let lod = LOD::new(2, 1, 16);
282 /// let subs = lod.level(lod.root()).sublevels();
283 /// assert_eq!(lod.find_path(subs[1], subs[3]).unwrap(), vec![subs[1], subs[0], subs[3]]);
284 /// ```
285 pub fn find_path(&self, from: ID, to: ID) -> Result<Vec<ID>> {
286 if !self.level_exists(from) {
287 return Err(QDFError::LevelDoesNotExists(from));
288 }
289 if !self.level_exists(to) {
290 return Err(QDFError::LevelDoesNotExists(to));
291 }
292 if let Some((_, levels)) = astar(&self.graph, from, |f| f == to, |_| 0, |_| 0) {
293 Ok(levels)
294 } else {
295 Ok(vec![])
296 }
297 }
298
299 /// Performs simulation step (go through all platonic spaces and modifies its states based on
300 /// neighbor states). Actual state simulation is performed by your struct that implements
301 /// `Simulation` trait.
302 pub fn simulation_step<M>(&mut self)
303 where
304 M: Simulate<S>,
305 {
306 let states = self.simulate_states::<M>();
307 for (id, state) in states {
308 self.levels.get_mut(&id).unwrap().apply_state(state);
309 }
310 let root = self.root;
311 self.recalculate_states(root);
312 }
313
314 /// Does the same as `simulation_step()` but in parallel manner (it may or may not increase
315 /// simulation performance if simulation is very complex).
316 pub fn simulation_step_parallel<M>(&mut self)
317 where
318 M: Simulate<S>,
319 {
320 let states = self.simulate_states_parallel::<M>();
321 for (id, state) in states {
322 self.levels.get_mut(&id).unwrap().apply_state(state);
323 }
324 let root = self.root;
325 self.recalculate_states(root);
326 }
327
328 /// Performs simulation on LOD like `simulation_step()` but instead of applying results to LOD,
329 /// it returns simulated platonic level states along with their level ID.
330 pub fn simulate_states<M>(&self) -> Vec<(ID, S)>
331 where
332 M: Simulate<S>,
333 {
334 self.platonic_levels
335 .iter()
336 .map(|id| {
337 let neighbor_states = self
338 .graph
339 .neighbors(*id)
340 .map(|i| self.levels[&i].state())
341 .collect::<Vec<&S>>();
342 (*id, M::simulate(self.levels[id].state(), &neighbor_states))
343 }).collect()
344 }
345
346 /// Performs simulation on LOD like `simulation_step_parallel()` but instead of applying
347 /// results to LOD, it returns simulated platonic level states along with their level ID.
348 pub fn simulate_states_parallel<M>(&self) -> Vec<(ID, S)>
349 where
350 M: Simulate<S>,
351 {
352 self.platonic_levels
353 .par_iter()
354 .map(|id| {
355 let neighbor_states = self
356 .graph
357 .neighbors(*id)
358 .map(|i| self.levels[&i].state())
359 .collect::<Vec<&S>>();
360 (*id, M::simulate(self.levels[id].state(), &neighbor_states))
361 }).collect()
362 }
363
364 fn subdivide_level(
365 id: ID,
366 graph: &mut UnGraphMap<ID, ()>,
367 levels: &mut HashMap<ID, Level<S>>,
368 subdivisions: usize,
369 count: usize,
370 ) {
371 // TODO: optimize!
372 let mut level = levels[&id].clone();
373 if level.level() < count {
374 let substates = level.state().subdivide(subdivisions);
375 let sublevels = substates
376 .iter()
377 .enumerate()
378 .map(|(idx, substate)| {
379 let i = ID::new();
380 graph.add_node(i);
381 Level::new(i, Some(id), level.level() + 1, idx, substate.clone())
382 }).collect::<Vec<Level<S>>>();
383 let first = sublevels[0].id();
384 for l in sublevels.iter().skip(1) {
385 graph.add_edge(first, l.id(), ());
386 }
387 level.apply_sublevels(sublevels.iter().map(|l| l.id()).collect());
388 for l in sublevels {
389 let i = l.id();
390 levels.insert(i, l);
391 Self::subdivide_level(i, graph, levels, subdivisions, count);
392 }
393 levels.insert(id, level);
394 }
395 }
396
397 fn connect_clusters(id: ID, graph: &mut UnGraphMap<ID, ()>, levels: &HashMap<ID, Level<S>>) {
398 let sublevels = levels[&id].sublevels();
399 if !sublevels.is_empty() {
400 let neighbors = graph
401 .neighbors(id)
402 .map(|i| (i, levels[&i].index()))
403 .collect::<Vec<(ID, usize)>>();
404 for (i, l) in sublevels.iter().enumerate().skip(1) {
405 for (nl, ni) in &neighbors {
406 if i != *ni {
407 graph.add_edge(*l, levels[&nl].sublevels()[i], ());
408 }
409 }
410 }
411 for l in sublevels.iter().skip(1) {
412 Self::connect_clusters(*l, graph, levels);
413 }
414 }
415 }
416
417 fn collect_platonic_levels(
418 id: ID,
419 levels: &HashMap<ID, Level<S>>,
420 platonic_levels: &mut HashSet<ID>,
421 ) {
422 let sublevels = levels[&id].sublevels();
423 if sublevels.is_empty() {
424 platonic_levels.insert(id);
425 } else {
426 for id in sublevels {
427 Self::collect_platonic_levels(*id, levels, platonic_levels);
428 }
429 }
430 }
431
432 fn recalculate_states(&mut self, id: ID) -> S {
433 let level = self.levels[&id].clone();
434 if level.sublevels().is_empty() {
435 level.state().clone()
436 } else {
437 let states = level
438 .sublevels()
439 .iter()
440 .map(|i| self.recalculate_states(*i))
441 .collect::<Vec<S>>();
442 let state = State::merge(&states);
443 self.levels.get_mut(&id).unwrap().apply_state(state.clone());
444 state
445 }
446 }
447
448 fn recalculate_children_states(&mut self, id: ID) {
449 let level = self.levels[&id].clone();
450 let states = level.state().subdivide(self.dimensions + 2);
451 for (id, state) in level.sublevels().iter().zip(states.into_iter()) {
452 self.levels.get_mut(&id).unwrap().apply_state(state);
453 self.recalculate_children_states(*id);
454 }
455 }
456
457 fn recalculate_parent_state(&mut self, id: ID) {
458 if let Some(id) = self.levels[&id].parent() {
459 let level = self.levels[&id].clone();
460 let states = level
461 .sublevels()
462 .iter()
463 .map(|i| self.levels[i].state().clone())
464 .collect::<Vec<S>>();
465 self.levels
466 .get_mut(&id)
467 .unwrap()
468 .apply_state(State::merge(&states));
469 self.recalculate_parent_state(id);
470 }
471 }
472}