Skip to main content

hyperwood_bench/
lib.rs

1use hyperwood::{Model, Point, Slat, Variant, Vector};
2use serde::{Deserialize, Serialize};
3
4#[derive(Serialize, Deserialize, Default)]
5pub struct BenchParameters {
6    width: isize,
7    depth: isize,
8    height: isize,
9}
10
11impl BenchParameters {
12    pub fn new(width: isize, depth: isize, height: isize) -> Self {
13        assert!(depth % 2 != 0, "Depth must be uneval");
14        assert!(depth >= 9, "Depth must be equal or greater than 9");
15
16        Self {
17            width,
18            depth,
19            height,
20        }
21    }
22}
23
24#[derive(Serialize, Deserialize, Default)]
25pub struct BenchProperties {
26    width: f32,
27    depth: f32,
28    height: f32,
29}
30
31/// Generate a model from given parameters and variant.
32pub fn build_model(
33    parameters: BenchParameters,
34    variant: Variant,
35) -> Model<BenchParameters, BenchProperties> {
36    let middle = parameters.depth / 2;
37    let distance_leg_to_edge = 3;
38
39    let mut slats = vec![];
40
41    // keel
42    slats.push(Slat {
43        name: "Keel".to_string(),
44        layer: middle,
45        origin: Point {
46            x: distance_leg_to_edge as f32,
47            y: middle as f32,
48            z: 1.0,
49        },
50        vector: Vector {
51            x: parameters.width as f32 - 2.0 * distance_leg_to_edge as f32,
52            y: 0.0,
53            z: 0.0,
54        },
55    });
56
57    // seat
58    for y in 0..parameters.depth {
59        if y % 2 == 0 {
60            slats.push(Slat {
61                name: "Seat".to_string(),
62                layer: y,
63                origin: Point {
64                    x: 0.0,
65                    y: y as f32,
66                    z: parameters.height as f32,
67                },
68                vector: Vector {
69                    x: parameters.width as f32,
70                    y: 0.0,
71                    z: 0.0,
72                },
73            });
74        }
75    }
76
77    // shelf
78    for y in 1..parameters.depth - 1 {
79        if y % 2 == 0 {
80            slats.push(Slat {
81                name: "Shelf".to_string(),
82                layer: y,
83                origin: Point {
84                    x: distance_leg_to_edge as f32 - 1.0,
85                    y: y as f32,
86                    z: 2.0,
87                },
88                vector: Vector {
89                    x: parameters.width as f32 - 2.0 * distance_leg_to_edge as f32 + 2.0,
90                    y: 0.0,
91                    z: 0.0,
92                },
93            });
94        }
95    }
96
97    // legs
98    for y in 0..parameters.depth {
99        if y % 2 != 0 {
100            // outer legs reach the floor
101            let z = match y == 1 || y == parameters.depth - 2 {
102                true => 0.0,
103                // or surround the keel
104                false => match y == middle + 1 || y == middle - 1 {
105                    true => 1.0,
106                    // or otherwise end at the shelf
107                    false => 2.0,
108                },
109            };
110
111            // left
112            slats.push(Slat {
113                name: "Leg".to_string(),
114                layer: y,
115                origin: Point {
116                    x: distance_leg_to_edge as f32,
117                    y: y as f32,
118                    z,
119                },
120                vector: Vector {
121                    x: 0.0,
122                    y: 0.0,
123                    z: parameters.height as f32 - z,
124                },
125            });
126
127            // right
128            slats.push(Slat {
129                name: "Leg".to_string(),
130                layer: y,
131                origin: Point {
132                    x: parameters.width as f32 - distance_leg_to_edge as f32,
133                    y: y as f32,
134                    z,
135                },
136                vector: Vector {
137                    x: 0.0,
138                    y: 0.0,
139                    z: parameters.height as f32 - z,
140                },
141            });
142        }
143    }
144
145    let properties = BenchProperties {
146        width: parameters.width as f32 * variant.x,
147        depth: parameters.depth as f32 * variant.y,
148        height: parameters.height as f32 * variant.z,
149    };
150
151    Model {
152        parameters,
153        properties,
154        name: "Bench".to_owned(),
155        variant,
156        slats,
157    }
158}