yt_tools/
fixed_resolution_buffer.rs

1extern crate wasm_bindgen;
2use wasm_bindgen::prelude::*;
3use variable_mesh::VariableMesh;
4
5#[wasm_bindgen]
6pub struct FixedResolutionBuffer {
7    width: usize,
8    height: usize,
9    x_low: f64,
10    x_high: f64,
11    y_low: f64,
12    y_high: f64,
13    ipdx: f64,
14    ipdy: f64,
15}
16
17#[wasm_bindgen]
18impl FixedResolutionBuffer {
19    #[wasm_bindgen(constructor)]
20    pub fn new(
21        width: usize,
22        height: usize,
23        x_low: f64,
24        x_high: f64,
25        y_low: f64,
26        y_high: f64,
27    ) -> FixedResolutionBuffer {
28        let ipdx = width as f64 / (x_high - x_low);
29        let ipdy = height as f64 / (y_high - y_low);
30
31        FixedResolutionBuffer {
32            width,
33            height,
34            x_low,
35            x_high,
36            y_low,
37            y_high,
38            ipdx,
39            ipdy,
40        }
41    }
42
43    pub fn deposit(&mut self, vmesh: &VariableMesh, buffer: &mut [f64]) -> u32 {
44        let mut count: u32 = 0;
45
46        // We do need to clear the buffer -- in cases where the buffer is completely filled this
47        // will result in extra work being done, but the alternate is to allocate a bunch of memory
48        // and do filling of values anyway, so it may be the best we can do.
49        for val in buffer.iter_mut() {
50            *val = 0.0;
51        }
52        let mut image_buffer: Vec<&mut [f64]> = buffer.chunks_exact_mut( self.height ).rev().collect();
53
54        for pixel in vmesh.iter() {
55            // Compute our left edge pixel
56            if pixel.px + pixel.pdx < self.x_low ||
57               pixel.py + pixel.pdy < self.y_low ||
58               pixel.px - pixel.pdx > self.x_high ||
59               pixel.py - pixel.pdy > self.y_high {
60                continue;
61            }
62            let lc: usize = ((pixel.px - pixel.pdx - self.x_low) * self.ipdx - 1.0)
63                .floor().max(0.0) as usize;
64            let lr: usize = ((pixel.py - pixel.pdy - self.y_low) * self.ipdy - 1.0)
65                .floor().max(0.0) as usize;
66            let rc: usize = ((pixel.px + pixel.pdx - self.x_low) * self.ipdx + 1.0)
67                .floor().min(self.width as f64) as usize;
68            let rr: usize = ((pixel.py + pixel.pdy - self.y_low) * self.ipdy + 1.0)
69                .floor().min(self.height as f64) as usize;
70
71            for i in lc..rc {
72                for j in lr..rr {
73                    image_buffer[j][i] = pixel.val;
74                    count += 1;
75                }
76            }
77        }
78        count
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85    use variable_mesh;
86    #[test]
87    fn create_fixed_res_buffer() {
88        let _frb_test = FixedResolutionBuffer::new(256, 256, 0.0, 1.0, 0.0, 1.0);
89        assert_eq!(_frb_test.ipdx, 256.0);
90        assert_eq!(_frb_test.ipdy, 256.0);
91        let _frb_test = FixedResolutionBuffer::new(256, 259, 0.0, 2.0, 0.2, 2.5);
92        assert_eq!(_frb_test.ipdx, 128.0);
93        assert_eq!(_frb_test.ipdy, 259.0 / 2.3);
94    }
95
96}