1use hyperwood::{Model, Point, Slat, Variant, Vector};
2use serde::{Deserialize, Serialize};
3
4#[derive(Serialize, Deserialize, Default)]
5pub struct TroughParameters {
6 width: isize,
7 depth: isize,
8 height: isize,
9}
10
11impl TroughParameters {
12 pub fn new(width: isize, depth: isize, height: isize) -> Self {
13 assert!(height >= 3, "Depth must be equal or greater than 3");
14 Self {
17 width,
18 depth,
19 height,
20 }
21 }
22}
23
24#[derive(Serialize, Deserialize, Default)]
25pub struct TroughProperties {
26 width: f32,
27 depth: f32,
28 height: f32,
29 volume: f32,
30}
31
32pub fn build_model(
33 parameters: TroughParameters,
34 variant: Variant,
35) -> Model<TroughParameters, TroughProperties> {
36 let depth = parameters.depth - 1;
37 let kurve_stop = 0;
38
39 let d = f32::sin(-std::f32::consts::PI * 1.0 / (parameters.height - kurve_stop) as f32);
41
42 let mut slats = vec![];
43
44 let mut width: f32 = 0.0;
45 let mut height: f32 = 0.0;
46 let mut volume = 0.0;
47
48 slats.push(Slat {
50 name: "Skid".to_string(),
51 layer: 0,
52 origin: Point {
53 x: -d,
54 y: -d,
55 z: 0.0,
56 },
57 vector: Vector {
58 x: 0.0,
59 y: depth as f32 + 2.0 * d,
60 z: 0.0,
61 },
62 });
63 slats.push(Slat {
64 name: "Skid".to_string(),
65 layer: 0,
66 origin: Point {
67 x: (parameters.width - 1) as f32 + d,
68 y: -d,
69 z: 0.0,
70 },
71 vector: Vector {
72 x: 0.0,
73 y: depth as f32 + 2.0 * d,
74 z: 0.0,
75 },
76 });
77
78 for y in 0..depth + 1 {
80 slats.push(Slat {
81 name: "Floor".to_string(),
82 layer: 1,
83 origin: Point {
84 x: 0.0,
85 y: y as f32,
86 z: 1.0,
87 },
88 vector: Vector {
89 x: (parameters.width - 1) as f32,
90 y: 0.0,
91 z: 0.0,
92 },
93 });
94 }
95
96 for z in 2..parameters.height {
98 let d = f32::sin(
99 std::f32::consts::PI * (z - 1) as f32 / (parameters.height - kurve_stop) as f32,
100 );
101 let w = parameters.width as f32 + 2.0 * d;
102 let h = parameters.height as f32 + d;
103
104 width = width.max(w + 1.0);
105 height = height.max(h + 1.0);
106 volume += (h - 1.0) * (w - 1.0);
107
108 if z % 2 == 0 {
109 slats.push(Slat {
111 name: "Wall side even".to_string(),
112 layer: z,
113 origin: Point {
114 x: -d,
115 y: -d,
116 z: z as f32,
117 },
118 vector: Vector {
119 x: 0.0,
120 y: depth as f32 + 2.0 * d,
121 z: 0.0,
122 },
123 });
124
125 slats.push(Slat {
127 name: "Wall side even".to_string(),
128 layer: z,
129 origin: Point {
130 x: (parameters.width - 1) as f32 + d,
131 y: -d,
132 z: z as f32,
133 },
134 vector: Vector {
135 x: 0.0,
136 y: depth as f32 + 2.0 * d,
137 z: 0.0,
138 },
139 });
140
141 slats.push(Slat {
143 name: "Wall even".to_string(),
144 layer: z,
145 origin: Point {
146 x: 1.0 - d,
147 y: -d,
148 z: z as f32,
149 },
150 vector: Vector {
151 x: (parameters.width - 1) as f32 - 2.0 + 2.0 * d,
152 y: 0.0,
153 z: 0.0,
154 },
155 });
156
157 slats.push(Slat {
159 name: "Wall even".to_string(),
160 layer: z,
161 origin: Point {
162 x: 1.0 - d,
163 y: depth as f32 + d,
164 z: z as f32,
165 },
166 vector: Vector {
167 x: (parameters.width - 1) as f32 - 2.0 + 2.0 * d,
168 y: 0.0,
169 z: 0.0,
170 },
171 });
172 } else {
173 slats.push(Slat {
175 name: "Wall side odd".to_string(),
176 layer: z,
177 origin: Point {
178 x: -d,
179 y: 1.0 - d,
180 z: z as f32,
181 },
182 vector: Vector {
183 x: 0.0,
184 y: depth as f32 - 2.0 + 2.0 * d,
185 z: 0.0,
186 },
187 });
188
189 slats.push(Slat {
191 name: "Wall side odd".to_string(),
192 layer: z,
193 origin: Point {
194 x: (parameters.width - 1) as f32 + d,
195 y: 1.0 - d,
196 z: z as f32,
197 },
198 vector: Vector {
199 x: 0.0,
200 y: depth as f32 - 2.0 + 2.0 * d,
201 z: 0.0,
202 },
203 });
204
205 slats.push(Slat {
207 name: "Wall odd".to_string(),
208 layer: z,
209 origin: Point {
210 x: -d,
211 y: -d,
212 z: z as f32,
213 },
214 vector: Vector {
215 x: (parameters.width - 1) as f32 + 2.0 * d,
216 y: 0.0,
217 z: 0.0,
218 },
219 });
220
221 slats.push(Slat {
223 name: "Wall odd".to_string(),
224 layer: z,
225 origin: Point {
226 x: -d,
227 y: depth as f32 + d,
228 z: z as f32,
229 },
230 vector: Vector {
231 x: (parameters.width - 1) as f32 + 2.0 * d,
232 y: 0.0,
233 z: 0.0,
234 },
235 });
236 }
237 }
238
239 let properties = TroughProperties {
240 width: width * variant.x,
241 depth: parameters.depth as f32 * variant.y,
242 height: height * variant.z,
243 volume: volume * variant.x * variant.y * variant.z,
244 };
245
246 Model {
247 parameters,
248 properties,
249 name: "Trough".to_owned(),
250 variant,
251 slats,
252 }
253}