1use crate::point::Point;
2use crate::triangle::Triangle;
3
4pub struct Mesh {
37 pub coordinates: Vec<f64>,
39 pub indices: Vec<usize>,
41}
42
43impl PartialEq for Mesh {
44 fn eq(&self, other: &Self) -> bool {
45
46 if self.coordinates.len() != other.coordinates.len() {
47 return false;
48 }
49 for i in 0..self.coordinates.len() {
50 if self.coordinates[i] != other.coordinates[i] {
51 return false;
52 }
53 }
54 if self.indices.len() != other.indices.len() {
55 return false;
56 }
57 for i in 0..self.indices.len() {
58 if self.indices[i] != other.indices[i] {
59 return false;
60 }
61 }
62
63 true
64 }
65}
66
67impl Mesh {
68 pub fn new(coordinates: Vec<f64>, indices: Vec<usize>) -> Mesh {Mesh {coordinates, indices}}
84
85 pub fn to_points(&self) -> Vec<Point> {
109 let mut points = Vec::<Point>::new();
110 let coordinates_length: usize = self.coordinates.len();
111 let mut i = 0;
112 while i < coordinates_length {
113 points.push(Point::new(self.coordinates[i], self.coordinates[i+1], self.coordinates[i+2]));
114 i = i + 3;
115 }
116 points
117 }
118
119 pub fn to_triangles(&self) -> Vec<Triangle> {
145 let mut triangles = Vec::<Triangle>::new();
146 let indices_length: usize = self.indices.len();
147 let mut i = 0;
148 while i < indices_length {
149 let offset0 = self.indices[i] * 3;
150 let index00 = usize::try_from(offset0).unwrap();
151 let index01 = usize::try_from(offset0 + 1).unwrap();
152 let index02 = usize::try_from(offset0 + 2).unwrap();
153 let point0: Point = Point::new(self.coordinates[index00], self.coordinates[index01], self.coordinates[index02]);
154
155 let offset1 = self.indices[i+1] * 3;
156 let index10 = usize::try_from(offset1).unwrap();
157 let index11 = usize::try_from(offset1 + 1).unwrap();
158 let index12 = usize::try_from(offset1 + 2).unwrap();
159 let point1: Point = Point::new(self.coordinates[index10], self.coordinates[index11], self.coordinates[index12]);
160
161 let offset2 = self.indices[i+2] * 3;
162 let index20 = usize::try_from(offset2).unwrap();
163 let index21 = usize::try_from(offset2 + 1).unwrap();
164 let index22 = usize::try_from(offset2 + 2).unwrap();
165 let point2: Point = Point::new(self.coordinates[index20], self.coordinates[index21], self.coordinates[index22]);
166
167 triangles.push(Triangle::new(point0, point1, point2));
168 i = i + 3;
169 }
170
171 triangles
172 }
173
174 pub fn from_triangles(triangles: Vec<Triangle>) -> Mesh {
197 let number_of_triangles: usize = triangles.len();
198 let number_of_indices: usize = number_of_triangles * 3;
199 let mut indices: Vec<usize> = Vec::<usize>::new();
200 for i in 0..number_of_indices {
201 indices.push(i);
202 }
203 let mut coordinates: Vec<f64> = Vec::<f64>::new();
204 for i in 0..number_of_triangles {
205 let current_triangle = &triangles[i];
206 coordinates.push(current_triangle.first_point.x);
207 coordinates.push(current_triangle.first_point.y);
208 coordinates.push(current_triangle.first_point.z);
209
210 coordinates.push(current_triangle.second_point.x);
211 coordinates.push(current_triangle.second_point.y);
212 coordinates.push(current_triangle.second_point.z);
213
214 coordinates.push(current_triangle.third_point.x);
215 coordinates.push(current_triangle.third_point.y);
216 coordinates.push(current_triangle.third_point.z);
217 }
218
219 Mesh::new(coordinates, indices)
220 }
221}
222
223#[cfg(test)]
224mod tests {
225 use super::*;
226
227 #[test]
228 fn test_new() {
229 let result = Mesh::new(vec![0.0, 0.0, 0.0,
230 10.0, 0.0, 0.0,
231 10.0, -15.0, 0.0],
232 vec![0, 1, 2]);
233 assert_eq!(result.coordinates, vec![0.0, 0.0, 0.0,
234 10.0, 0.0, 0.0,
235 10.0, -15.0, 0.0]);
236 assert_eq!(result.indices, vec![0, 1, 2]);
237 }
238
239 #[test]
240 fn test_to_points() {
241 let input = Mesh::new(vec![0.0, 0.0, 0.0,
242 10.0, 0.0, 0.0,
243 10.0, -15.0, 0.0],
244 vec![0, 1, 2]);
245 let actual = input.to_points();
246 let expected = vec![Point::new(0.0, 0.0, 0.0),
247 Point::new(10.0, 0.0, 0.0),
248 Point::new(10.0, -15.0, 0.0)];
249 assert_eq!(expected.len(), actual.len());
250 for i in 0..expected.len() {
251 assert_eq!(expected[i].eq(&actual[i]), true);
252 }
253 }
254
255 #[test]
256 fn test_to_triangles_1face() {
257 let input = Mesh::new(vec![0.0, 0.0, 0.0,
258 10.0, 0.0, 0.0,
259 10.0, -15.0, 0.0],
260 vec![0, 1, 2]);
261 let actual = input.to_triangles();
262 let expected = vec![Triangle::new(
263 Point::new(0.0, 0.0, 0.0),
264 Point::new(10.0, 0.0, 0.0),
265 Point::new(10.0, -15.0, 0.0))];
266 assert_eq!(expected.len(), actual.len());
267 for i in 0..expected.len() {
268 assert_eq!(expected[i].eq(&actual[i]), true);
269 }
270 }
271
272 #[test]
273 fn test_to_triangles_pyramid() {
274 let input = Mesh::new(
275 vec![
276 0.0,0.0,0.0,
278 10.0,0.0,0.0,
279 10.0,10.0,0.0,
280 0.0,10.0,0.0,
281
282 5.0,5.0,4.0
284 ],
285 vec![
286 0,1,2,
288 0,2,3,
289
290 0,1,4,
292 1,2,4,
293 2,3,4,
294 3,0,4
295 ]
296 );
297 let actual = input.to_triangles();
298 let expected = vec![
299 Triangle::new(
300 Point::new(0.0, 0.0, 0.0),
301 Point::new(10.0, 0.0, 0.0),
302 Point::new(10.0,10.0,0.0)),
303 Triangle::new(
304 Point::new(0.0, 0.0, 0.0),
305 Point::new(10.0,10.0,0.0),
306 Point::new(0.0,10.0,0.0)),
307
308 Triangle::new(
309 Point::new(0.0, 0.0, 0.0),
310 Point::new(10.0, 0.0, 0.0),
311 Point::new(5.0,5.0,4.0)),
312 Triangle::new(
313 Point::new(10.0, 0.0, 0.0),
314 Point::new(10.0,10.0,0.0),
315 Point::new(5.0,5.0,4.0)),
316 Triangle::new(
317 Point::new(10.0,10.0,0.0),
318 Point::new(0.0,10.0,0.0),
319 Point::new(5.0,5.0,4.0)),
320 Triangle::new(
321 Point::new(0.0,10.0,0.0),
322 Point::new(0.0,0.0,0.0),
323 Point::new(5.0,5.0,4.0)),
324 ];
325 assert_eq!(expected.len(), actual.len());
326 for i in 0..expected.len() {
327 assert_eq!(expected[i].eq(&actual[i]), true);
328 }
329 }
330
331 #[test]
332 fn test_from_triangles_1face() {
333 let input = vec![Triangle::new(
334 Point::new(0.0, 0.0, 0.0),
335 Point::new(10.0, 0.0, 0.0),
336 Point::new(10.0, -15.0, 0.0))];
337 let actual = Mesh::from_triangles(input);
338 let expected = Mesh::new(vec![0.0, 0.0, 0.0,
339 10.0, 0.0, 0.0,
340 10.0, -15.0, 0.0],
341 vec![0, 1, 2]);
342 assert_eq!(expected.eq(&actual), true);
343 }
344
345 #[test]
346 fn test_from_triangles_pyramid() {
347 let input = vec![
348 Triangle::new(
349 Point::new(0.0, 0.0, 0.0),
350 Point::new(10.0, 0.0, 0.0),
351 Point::new(10.0,10.0,0.0)),
352 Triangle::new(
353 Point::new(0.0, 0.0, 0.0),
354 Point::new(10.0,10.0,0.0),
355 Point::new(0.0,10.0,0.0)),
356
357 Triangle::new(
358 Point::new(0.0, 0.0, 0.0),
359 Point::new(10.0, 0.0, 0.0),
360 Point::new(5.0,5.0,4.0)),
361 Triangle::new(
362 Point::new(10.0, 0.0, 0.0),
363 Point::new(10.0,10.0,0.0),
364 Point::new(5.0,5.0,4.0)),
365 Triangle::new(
366 Point::new(10.0,10.0,0.0),
367 Point::new(0.0,10.0,0.0),
368 Point::new(5.0,5.0,4.0)),
369 Triangle::new(
370 Point::new(0.0,10.0,0.0),
371 Point::new(0.0,0.0,0.0),
372 Point::new(5.0,5.0,4.0)),
373 ];
374
375 let actual = Mesh::from_triangles(input);
376 let expected= Mesh::new(
377 vec![
378 0.0, 0.0, 0.0,
379 10.0, 0.0, 0.0,
380 10.0,10.0,0.0,
381
382 0.0, 0.0, 0.0,
383 10.0,10.0,0.0,
384 0.0,10.0,0.0,
385
386
387 0.0, 0.0, 0.0,
388 10.0, 0.0, 0.0,
389 5.0,5.0,4.0,
390
391 10.0, 0.0, 0.0,
392 10.0,10.0,0.0,
393 5.0,5.0,4.0,
394
395 10.0,10.0,0.0,
396 0.0,10.0,0.0,
397 5.0,5.0,4.0,
398
399 0.0,10.0,0.0,
400 0.0,0.0,0.0,
401 5.0,5.0,4.0,
402 ],
403 vec![
404 0,1,2,
406 3,4,5,
407
408 6,7,8,
410 9,10,11,
411 12,13,14,
412 15,16,17
413 ]
414 );
415
416 assert_eq!(expected.eq(&actual), true);
417 }
418
419 #[test]
420 fn test_partialeq_true() {
421 let a = Mesh::new(vec![0.0, 0.0, 0.0,
422 10.0, 0.0, 0.0,
423 10.0, -15.0, 0.0],
424 vec![0, 1, 2]);
425 let b = Mesh::new(vec![0.0, 0.0, 0.0,
426 10.0, 0.0, 0.0,
427 10.0, -15.0, 0.0],
428 vec![0, 1, 2]);
429 assert_eq!(a.eq(&b), true);
430 assert_eq!(b.eq(&a), true);
431 }
432
433 #[test]
434 fn test_partialeq_coordinates_count_false() {
435 let a = Mesh::new(vec![0.0, 0.0, 0.0,
436 10.0, 0.0, 0.0,
437 10.0, -15.0, 0.0,
438 5.0, 1.0, 0.0],
439 vec![0, 1, 2]);
440 let b = Mesh::new(vec![0.0, 0.0, 0.0,
441 10.0, 0.0, 0.0,
442 10.0, -15.0, 0.0],
443 vec![0, 1, 2]);
444 assert_eq!(a.eq(&b), false);
445 assert_eq!(b.eq(&a), false);
446 }
447
448 #[test]
449 fn test_partialeq_different_coordinates_false() {
450 let a = Mesh::new(vec![0.0, 0.0, 0.0,
451 10.0, 2.0, 0.0,
452 10.0, -15.0, 0.0],
453 vec![0, 1, 2]);
454 let b = Mesh::new(vec![0.0, 0.0, 0.0,
455 10.0, 0.0, 0.0,
456 10.0, -15.0, 0.0],
457 vec![0, 1, 2]);
458 assert_eq!(a.eq(&b), false);
459 assert_eq!(b.eq(&a), false);
460 }
461
462 #[test]
463 fn test_partialeq_indices_count_false() {
464 let a = Mesh::new(vec![0.0, 0.0, 0.0,
465 10.0, 0.0, 0.0,
466 10.0, -15.0, 0.0],
467 vec![0, 1, 2, 2, 1, 0]);
468 let b = Mesh::new(vec![0.0, 0.0, 0.0,
469 10.0, 0.0, 0.0,
470 10.0, -15.0, 0.0],
471 vec![0, 1, 2]);
472 assert_eq!(a.eq(&b), false);
473 assert_eq!(b.eq(&a), false);
474 }
475
476 #[test]
477 fn test_partialeq_different_indices_false() {
478 let a = Mesh::new(vec![0.0, 0.0, 0.0,
479 10.0, 0.0, 0.0,
480 10.0, -15.0, 0.0],
481 vec![0, 2, 1]);
482 let b = Mesh::new(vec![0.0, 0.0, 0.0,
483 10.0, 0.0, 0.0,
484 10.0, -15.0, 0.0],
485 vec![0, 1, 2]);
486 assert_eq!(a.eq(&b), false);
487 assert_eq!(b.eq(&a), false);
488 }
489}