Merge branch 'tm_sla_tests'

This commit is contained in:
tamasmeszaros 2019-10-04 18:34:08 +02:00
commit 5bf3d5aabf
69 changed files with 54707 additions and 4293 deletions

View file

@ -29,4 +29,5 @@ target_link_libraries(test_gtest_common INTERFACE GTest::GTest GTest::Main)
add_subdirectory(libnest2d)
add_subdirectory(timeutils)
add_subdirectory(sla_print)

20
tests/data/20mm_cube.obj Normal file
View file

@ -0,0 +1,20 @@
v 20.000000 20.000000 0.000000
v 20.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 20.000000 0.000000
v 20.000000 20.000000 20.000000
v 0.000000 20.000000 20.000000
v 0.000000 0.000000 20.000000
v 20.000000 0.000000 20.000000
f 1 2 3
f 1 3 4
f 5 6 7
f 5 7 8
f 1 5 8
f 1 8 2
f 2 8 7
f 2 7 3
f 3 7 6
f 3 6 4
f 5 1 4
f 5 4 6

20
tests/data/2x20x10.obj Normal file
View file

@ -0,0 +1,20 @@
v 2.000000 20.000000 0.000000
v 2.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 20.000000 0.000000
v 2.000000 20.000000 10.000000
v 0.000000 20.000000 10.000000
v 0.000000 0.000000 10.000000
v 2.000000 0.000000 10.000000
f 1 2 3
f 1 3 4
f 5 6 7
f 5 7 8
f 1 5 8
f 1 8 2
f 2 8 7
f 2 7 3
f 3 7 6
f 3 6 4
f 5 1 4
f 5 4 6

1867
tests/data/A.obj Normal file

File diff suppressed because it is too large Load diff

2504
tests/data/A_upsidedown.obj Normal file

File diff suppressed because it is too large Load diff

68
tests/data/V.obj Normal file
View file

@ -0,0 +1,68 @@
####
#
# OBJ File Generated by Meshlab
#
####
# Object V.obj
#
# Vertices: 14
# Faces: 24
#
####
vn -0.835484 -0.584839 0.000000
v 41.480000 44.020000 0.000000
vn 0.000000 0.000000 1.768192
v 51.480000 44.020000 15.000000
vn 0.000000 0.000000 0.960070
v 41.480000 44.020000 15.000000
vn 0.000000 0.000000 0.413330
v 55.480000 24.020000 15.000000
vn 0.000000 -0.982794 0.000000
v 65.480003 24.020000 15.000000
vn -0.000000 -0.000000 -2.776433
v 60.480000 31.162861 0.000000
vn -0.000000 -0.000000 -0.099828
v 79.480003 44.020000 0.000000
vn -0.000000 -0.000000 -0.265332
v 55.480000 24.020000 0.000000
vn 0.661947 0.463363 0.000000
v 51.480000 44.020000 0.000000
vn 0.624900 0.437430 0.000000
v 60.480000 31.162861 15.000000
vn -0.661947 0.463363 0.000000
v 69.480003 44.020000 15.000000
vn -1.286846 0.900793 0.000000
v 69.480003 44.020000 0.000000
vn 0.000000 0.982794 0.000000
v 79.480003 44.020000 15.000000
vn 0.451362 -0.315954 0.000000
v 65.480003 24.020000 0.000000
# 14 vertices, 0 vertices normals
f 3//3 1//1 4//4
f 4//4 1//1 8//8
f 1//1 3//3 2//2
f 9//9 1//1 2//2
f 2//2 3//3 4//4
f 10//10 2//2 4//4
f 5//5 10//10 4//4
f 13//13 11//11 5//5
f 11//11 10//10 5//5
f 4//4 8//8 5//5
f 5//5 8//8 14//14
f 1//1 9//9 8//8
f 8//8 9//9 6//6
f 6//6 12//12 7//7
f 6//6 7//7 8//8
f 8//8 7//7 14//14
f 9//9 2//2 10//10
f 6//6 9//9 10//10
f 10//10 11//11 6//6
f 6//6 11//11 12//12
f 12//12 11//11 13//13
f 7//7 12//12 13//13
f 13//13 5//5 14//14
f 7//7 13//13 14//14
# 24 faces, 0 coords texture
# End of File

38
tests/data/V_standing.obj Normal file
View file

@ -0,0 +1,38 @@
v -14.000000 0.000000 20.000000
v -14.000000 15.000000 20.000000
v 0.000000 0.000000 0.000000
v 0.000000 15.000000 0.000000
v -4.000000 0.000000 20.000000
v -4.000000 15.000000 20.000000
v 5.000000 0.000000 7.142860
v 10.000000 0.000000 0.000000
v 24.000000 0.000000 20.000000
v 14.000000 0.000000 20.000000
v 10.000000 15.000000 0.000000
v 5.000000 15.000000 7.142860
v 14.000000 15.000000 20.000000
v 24.000000 15.000000 20.000000
f 1 2 3
f 3 2 4
f 2 1 5
f 6 2 5
f 5 1 3
f 7 5 3
f 8 7 3
f 9 10 8
f 10 7 8
f 3 4 8
f 8 4 11
f 2 6 4
f 4 6 12
f 12 13 14
f 12 14 4
f 4 14 11
f 6 5 7
f 12 6 7
f 7 10 12
f 12 10 13
f 13 10 9
f 14 13 9
f 9 8 11
f 14 9 11

44
tests/data/bridge.obj Normal file
View file

@ -0,0 +1,44 @@
v 75.000000 84.500000 8.000000
v 125.000000 84.500000 8.000000
v 75.000000 94.500000 8.000000
v 120.000000 84.500000 5.000000
v 125.000000 94.500000 8.000000
v 75.000000 84.500000 0.000000
v 80.000000 84.500000 5.000000
v 125.000000 84.500000 0.000000
v 125.000000 94.500000 0.000000
v 80.000000 94.500000 5.000000
v 75.000000 94.500000 0.000000
v 120.000000 94.500000 5.000000
v 120.000000 84.500000 0.000000
v 80.000000 94.500000 0.000000
v 80.000000 84.500000 0.000000
v 120.000000 94.500000 0.000000
f 1 2 3
f 2 1 4
f 3 2 5
f 3 6 1
f 1 7 4
f 2 4 8
f 2 9 5
f 5 10 3
f 11 6 3
f 6 7 1
f 7 12 4
f 4 13 8
f 8 9 2
f 5 9 12
f 5 12 10
f 10 11 3
f 11 14 6
f 15 7 6
f 10 12 7
f 12 13 4
f 13 9 8
f 12 9 16
f 14 11 10
f 6 14 15
f 15 14 7
f 7 14 10
f 16 13 12
f 16 9 13

View file

@ -0,0 +1,72 @@
v -10.000000 -10.000000 -5.000000
v -10.000000 -10.000000 5.000000
v -10.000000 10.000000 -5.000000
v -10.000000 10.000000 5.000000
v 10.000000 -10.000000 -5.000000
v 10.000000 -10.000000 5.000000
v -5.000000 -5.000000 -5.000000
v 5.000000 -5.000000 -5.000000
v 5.000000 5.000000 -5.000000
v 5.000000 10.000000 -5.000000
v -5.000000 5.000000 -5.000000
v 0.000000 5.000000 -5.000000
v 5.000000 0.000000 -5.000000
v 0.000000 0.000000 -5.000000
v 10.000000 5.000000 -5.000000
v 5.000000 10.000000 5.000000
v -5.000000 -5.000000 5.000000
v 5.000000 0.000000 5.000000
v 5.000000 -5.000000 5.000000
v -5.000000 5.000000 5.000000
v 10.000000 5.000000 5.000000
v 5.000000 5.000000 5.000000
v 0.000000 5.000000 5.000000
v 0.000000 0.000000 5.000000
f 1 2 3
f 3 2 4
f 2 1 5
f 6 2 5
f 7 8 5
f 9 3 10
f 11 3 12
f 12 13 14
f 1 3 11
f 1 11 7
f 1 7 5
f 12 3 9
f 5 8 13
f 5 13 9
f 13 12 9
f 15 5 9
f 3 4 10
f 10 4 16
f 17 2 6
f 18 19 6
f 20 4 17
f 21 22 6
f 19 17 6
f 4 2 17
f 23 4 20
f 22 4 23
f 22 18 6
f 22 23 18
f 22 16 4
f 24 18 23
f 6 5 15
f 21 6 15
f 21 15 22
f 22 15 9
f 10 16 22
f 9 10 22
f 11 20 17
f 7 11 17
f 12 23 20
f 11 12 20
f 14 24 12
f 12 24 23
f 24 14 13
f 18 24 13
f 18 13 19
f 19 13 8
f 19 8 17
f 17 8 7

View file

@ -0,0 +1,112 @@
####
#
# OBJ File Generated by Meshlab
#
####
# Object cube_with_concave_hole_enlarged.obj
#
# Vertices: 24
# Faces: 48
#
####
vn 1.107149 0.000000 0.000000
v 76.634163 17.865837 0.000000
vn 0.000000 0.000000 0.321750
v 68.557083 25.942917 16.154167
vn 0.000000 0.000000 2.356194
v 52.402920 25.942917 16.154167
vn 0.000000 0.000000 0.321751
v 76.634163 50.174164 16.154167
vn 0.000000 0.000000 2.034444
v 68.557083 42.097084 16.154167
vn 0.000000 0.000000 0.463648
v 76.634163 17.865837 16.154167
vn 0.000000 0.000000 0.785398
v 52.402920 34.020000 16.154167
vn 0.000000 0.000000 0.321750
v 44.325836 17.865837 16.154167
vn 0.000000 0.982794 0.000000
v 52.402920 50.174164 16.154167
vn 0.000000 1.570796 0.000000
v 52.402920 50.174164 0.000000
vn 0.000000 0.000000 -0.463648
v 52.402920 34.020000 0.000000
vn 0.000000 0.000000 -0.321751
v 44.325836 17.865837 0.000000
vn 0.000000 0.000000 -0.463648
v 76.634163 50.174164 0.000000
vn 0.000000 0.000000 -1.570796
v 44.325836 42.097084 0.000000
vn -0.588003 0.000000 0.000000
v 44.325836 42.097084 16.154167
vn 0.000000 1.570796 0.000000
v 52.402920 42.097084 16.154167
vn -1.107149 0.000000 0.000000
v 52.402920 42.097084 0.000000
vn 0.000000 -0.463648 0.000000
v 60.480000 42.097084 16.154167
vn 0.000000 -1.107149 0.000000
v 68.557083 42.097084 0.000000
vn 1.570796 0.000000 0.000000
v 60.480000 42.097084 0.000000
vn 0.000000 -0.463647 0.000000
v 60.480000 34.020000 0.000000
vn 0.000000 -1.570796 0.000000
v 60.480000 34.020000 16.154167
vn 1.107149 0.000000 0.000000
v 52.402920 25.942917 0.000000
vn 0.000000 0.785398 0.000000
v 68.557083 25.942917 0.000000
# 24 vertices, 0 vertices normals
f 6//6 1//1 4//4
f 4//4 1//1 13//13
f 1//1 6//6 8//8
f 12//12 1//1 8//8
f 2//2 3//3 8//8
f 16//16 4//4 9//9
f 5//5 4//4 18//18
f 18//18 7//7 22//22
f 6//6 4//4 5//5
f 6//6 5//5 2//2
f 6//6 2//2 8//8
f 18//18 4//4 16//16
f 8//8 3//3 7//7
f 8//8 7//7 16//16
f 7//7 18//18 16//16
f 15//15 8//8 16//16
f 4//4 13//13 9//9
f 9//9 13//13 10//10
f 24//24 1//1 12//12
f 11//11 23//23 12//12
f 19//19 13//13 24//24
f 14//14 17//17 12//12
f 23//23 24//24 12//12
f 13//13 1//1 24//24
f 20//20 13//13 19//19
f 17//17 13//13 20//20
f 17//17 11//11 12//12
f 17//17 20//20 11//11
f 17//17 10//10 13//13
f 21//21 11//11 20//20
f 12//12 8//8 15//15
f 14//14 12//12 15//15
f 14//14 15//15 17//17
f 17//17 15//15 16//16
f 9//9 10//10 17//17
f 16//16 9//9 17//17
f 5//5 19//19 24//24
f 2//2 5//5 24//24
f 18//18 20//20 19//19
f 5//5 18//18 19//19
f 22//22 21//21 18//18
f 18//18 21//21 20//20
f 21//21 22//22 7//7
f 11//11 21//21 7//7
f 11//11 7//7 23//23
f 23//23 7//7 3//3
f 23//23 3//3 24//24
f 24//24 3//3 2//2
# 48 faces, 0 coords texture
# End of File

View file

@ -0,0 +1,112 @@
####
#
# OBJ File Generated by Meshlab
#
####
# Object cube_with_concave_hole_enlarged.obj
#
# Vertices: 24
# Faces: 48
#
####
vn 0.000000 0.000000 -1.570796
v 68.557083 17.865835 0.000000
vn 0.000000 0.000000 -1.107149
v 52.402916 17.865835 0.000000
vn 0.000000 -0.463648 0.000000
v 68.557083 17.865835 32.308331
vn 0.000000 -1.570796 0.000000
v 52.402916 17.865835 32.308331
vn 2.356194 0.000000 0.000000
v 68.557083 25.942917 24.231247
vn 1.570796 0.000000 0.000000
v 68.557083 50.174164 24.231247
vn 2.034444 0.000000 0.000000
v 68.557083 42.097084 8.077083
vn 2.677945 0.000000 0.000000
v 68.557083 34.020000 24.231247
vn 0.000000 1.570796 0.000000
v 68.557083 50.174164 0.000000
vn 0.000000 1.570796 0.000000
v 52.402916 50.174164 24.231247
vn -0.321750 0.000000 0.000000
v 52.402916 25.942917 8.077083
vn -1.570796 0.000000 0.000000
v 52.402916 42.097084 32.308331
vn -0.321751 0.000000 0.000000
v 52.402916 50.174164 0.000000
vn -2.356194 0.000000 0.000000
v 52.402916 42.097084 8.077083
vn -0.785398 0.000000 0.000000
v 52.402916 42.097084 16.154165
vn 0.000000 0.000000 0.588003
v 68.557083 42.097084 32.308331
vn 0.000000 1.107149 0.000000
v 52.402916 42.097084 24.231247
vn 0.000000 1.570796 0.000000
v 68.557083 42.097084 24.231247
vn 0.000000 0.000000 1.570796
v 68.557083 25.942917 8.077083
vn 0.000000 -0.463647 0.000000
v 68.557083 42.097084 16.154165
vn 0.000000 0.000000 -1.570796
v 68.557083 34.020000 16.154165
vn 0.000000 0.000000 -0.463648
v 52.402916 34.020000 16.154165
vn 0.000000 0.000000 -1.570796
v 52.402916 34.020000 24.231247
vn 0.000000 0.000000 -0.463648
v 52.402916 25.942917 24.231247
# 24 vertices, 0 vertices normals
f 1//1 2//2 9//9
f 9//9 2//2 13//13
f 2//2 1//1 3//3
f 4//4 2//2 3//3
f 19//19 5//5 3//3
f 18//18 9//9 6//6
f 7//7 9//9 20//20
f 20//20 8//8 21//21
f 1//1 9//9 7//7
f 1//1 7//7 19//19
f 1//1 19//19 3//3
f 20//20 9//9 18//18
f 3//3 5//5 8//8
f 3//3 8//8 18//18
f 8//8 20//20 18//18
f 16//16 3//3 18//18
f 9//9 13//13 6//6
f 6//6 13//13 10//10
f 11//11 2//2 4//4
f 23//23 24//24 4//4
f 14//14 13//13 11//11
f 12//12 17//17 4//4
f 24//24 11//11 4//4
f 13//13 2//2 11//11
f 15//15 13//13 14//14
f 17//17 13//13 15//15
f 17//17 23//23 4//4
f 17//17 15//15 23//23
f 17//17 10//10 13//13
f 22//22 23//23 15//15
f 4//4 3//3 16//16
f 12//12 4//4 16//16
f 12//12 16//16 17//17
f 17//17 16//16 18//18
f 6//6 10//10 17//17
f 18//18 6//6 17//17
f 7//7 14//14 11//11
f 19//19 7//7 11//11
f 20//20 15//15 14//14
f 7//7 20//20 14//14
f 21//21 22//22 20//20
f 20//20 22//22 15//15
f 22//22 21//21 8//8
f 23//23 22//22 8//8
f 23//23 8//8 24//24
f 24//24 8//8 5//5
f 24//24 5//5 11//11
f 11//11 5//5 19//19
# 48 faces, 0 coords texture
# End of File

View file

@ -0,0 +1,48 @@
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 10.000000
v 0.000000 20.000000 0.000000
v 0.000000 20.000000 10.000000
v 20.000000 0.000000 0.000000
v 20.000000 0.000000 10.000000
v 5.000000 5.000000 0.000000
v 15.000000 5.000000 0.000000
v 5.000000 15.000000 0.000000
v 20.000000 20.000000 0.000000
v 15.000000 15.000000 0.000000
v 20.000000 20.000000 10.000000
v 5.000000 5.000000 10.000000
v 5.000000 15.000000 10.000000
v 15.000000 5.000000 10.000000
v 15.000000 15.000000 10.000000
f 1 2 3
f 3 2 4
f 2 1 5
f 6 2 5
f 7 8 5
f 9 3 10
f 1 3 9
f 11 9 10
f 1 9 7
f 1 7 5
f 5 8 10
f 8 11 10
f 3 4 10
f 10 4 12
f 13 2 6
f 14 4 13
f 15 13 6
f 4 2 13
f 12 4 14
f 12 16 6
f 12 14 16
f 16 15 6
f 6 5 10
f 12 6 10
f 9 14 13
f 7 9 13
f 11 16 14
f 9 11 14
f 16 11 15
f 15 11 8
f 15 8 13
f 13 8 7

File diff suppressed because it is too large Load diff

36702
tests/data/frog_legs.obj Normal file

File diff suppressed because it is too large Load diff

86
tests/data/ipadstand.obj Normal file
View file

@ -0,0 +1,86 @@
v 17.434467 -0.000000 9.500000
v 14.281480 10.000000 9.500000
v 0.000000 0.000000 9.500000
v 31.715948 10.000000 9.500000
v 62.234474 0.000000 20.000000
v 31.715948 10.000000 20.000000
v 17.434467 -0.000000 20.000000
v 62.234474 10.000000 20.000000
v 98.207970 10.000000 0.000000
v 98.207970 0.000000 10.000000
v 98.207970 0.000000 0.000000
v 98.207970 10.000000 20.000000
v 98.207970 0.000000 20.000000
v 81.660965 -0.000000 10.000000
v 90.054985 10.000000 10.000000
v 78.507980 10.000000 10.000000
v 93.207970 0.000000 10.000000
v 14.281480 10.000000 20.000000
v 0.000000 0.000000 20.000000
v 87.434471 0.000000 20.000000
v 84.281479 10.000000 20.000000
v 0.000000 10.000000 20.000000
v 0.000000 0.000000 0.000000
v 0.000000 10.000000 0.000000
v 62.234474 0.000000 30.000000
v 66.960976 10.000000 30.000000
v 62.234474 10.000000 30.000000
v 70.113960 0.000000 30.000000
v 67.705338 10.000000 28.710720
v 71.678711 0.000000 27.289770
f 1 2 3
f 2 1 4
f 5 6 7
f 6 5 8
f 9 10 11
f 10 12 13
f 12 10 9
f 14 15 16
f 15 14 17
f 18 3 2
f 3 18 19
f 20 12 21
f 12 20 13
f 18 22 19
f 22 3 19
f 3 22 23
f 23 22 24
f 9 23 24
f 23 9 11
f 25 26 27
f 26 25 28
f 24 2 9
f 2 24 22
f 2 22 18
f 6 16 4
f 16 6 8
f 16 8 29
f 29 8 27
f 29 27 26
f 9 15 12
f 15 9 4
f 4 9 2
f 15 4 16
f 12 15 21
f 27 5 25
f 5 27 8
f 13 17 10
f 17 13 20
f 30 5 14
f 5 30 25
f 25 30 28
f 10 23 11
f 23 10 1
f 1 10 17
f 1 17 14
f 1 14 7
f 7 14 5
f 3 23 1
f 20 15 17
f 15 20 21
f 16 30 14
f 30 26 28
f 26 30 16
f 26 16 29
f 7 4 1
f 4 7 6

179
tests/data/overhang.obj Normal file
View file

@ -0,0 +1,179 @@
v 1364.685059 614.398010 20.002499
v 1389.685059 614.398010 20.002499
v 1377.185059 589.398987 20.002499
v 1389.685059 589.398987 20.002499
v 1389.685059 564.398987 20.001499
v 1364.685059 589.398987 20.002499
v 1364.685059 564.398987 20.001499
v 1360.935059 589.398987 17.001499
v 1360.935059 585.646973 17.001499
v 1357.185059 564.398987 17.001499
v 1364.685059 589.398987 17.001499
v 1364.685059 571.899963 17.001499
v 1364.685059 564.398987 17.001499
v 1348.436035 564.398987 17.001499
v 1352.809082 589.398987 17.001499
v 1357.184082 589.398987 17.001499
v 1357.183105 614.398010 17.001499
v 1364.685059 606.895996 17.001499
v 1364.685059 614.398010 17.001499
v 1352.186035 564.398987 20.001499
v 1363.654053 589.398987 23.300499
v 1359.467041 589.398987 23.300499
v 1358.371094 564.398987 23.300499
v 1385.561035 564.398987 23.300499
v 1373.063110 589.398987 23.300499
v 1368.808105 564.398987 23.300499
v 1387.623047 589.398987 23.300499
v 1387.623047 585.276001 23.300499
v 1389.685059 589.398987 23.300499
v 1389.685059 572.645996 23.300499
v 1389.685059 564.398987 23.300499
v 1367.777100 589.398987 23.300499
v 1366.747070 564.398987 23.300499
v 1354.312012 589.398987 23.300499
v 1352.186035 564.398987 23.300499
v 1389.685059 614.398010 23.300499
v 1377.317017 614.398010 23.300499
v 1381.439087 589.398987 23.300499
v 1368.807007 614.398010 23.300499
v 1368.808105 589.398987 23.300499
v 1356.439087 614.398010 23.300499
v 1357.405029 589.398987 23.300499
v 1360.562012 614.398010 23.300499
v 1348.705078 614.398010 23.300499
v 1350.445068 589.398987 23.300499
v 1389.685059 606.153015 23.300499
v 1347.352051 589.398987 23.300499
v 1346.560059 589.398987 23.300499
v 1346.560059 594.159912 17.001499
v 1346.560059 589.398987 17.001499
v 1346.560059 605.250427 23.300499
v 1346.560059 614.398010 23.300499
v 1346.560059 614.398010 20.825829
v 1346.560059 614.398010 17.001499
v 1346.560059 564.398987 19.101339
v 1346.560059 567.548584 23.300499
v 1346.560059 564.398987 17.002033
v 1346.560059 564.398987 23.001850
v 1346.560059 564.398987 23.300499
v 1346.560059 575.118958 17.001499
v 1346.560059 574.754028 23.300499
f 1 2 3
f 3 4 5
f 3 6 1
f 5 7 3
f 3 7 6
f 3 2 4
f 8 9 10
f 11 10 9
f 12 10 11
f 13 10 12
f 10 14 15
f 8 16 17
f 11 18 1
f 11 1 6
f 13 12 7
f 19 17 1
f 7 20 14
f 7 14 10
f 10 13 7
f 18 19 1
f 12 11 6
f 12 6 7
f 15 17 16
f 18 8 19
f 17 19 8
f 15 16 10
f 8 10 16
f 8 18 9
f 11 9 18
f 21 22 23
f 24 25 26
f 27 24 28
f 29 28 24
f 30 29 24
f 31 30 24
f 26 32 33
f 23 34 35
f 36 37 38
f 25 39 40
f 22 41 42
f 39 43 21
f 34 44 45
f 7 5 24
f 7 24 26
f 37 36 2
f 2 1 39
f 2 39 37
f 30 31 5
f 26 33 7
f 41 43 1
f 36 46 2
f 5 4 29
f 5 29 30
f 4 2 46
f 4 46 29
f 23 35 20
f 20 7 33
f 20 33 23
f 43 39 1
f 31 24 5
f 1 17 44
f 1 44 41
f 25 38 37
f 39 25 37
f 25 24 38
f 38 24 27
f 23 33 21
f 21 33 32
f 34 42 41
f 44 34 41
f 46 36 27
f 38 27 36
f 34 45 35
f 45 44 47
f 21 43 22
f 41 22 43
f 32 40 39
f 21 32 39
f 34 23 42
f 22 42 23
f 32 26 40
f 25 40 26
f 27 28 46
f 29 46 28
f 48 49 50
f 48 51 49
f 52 49 51
f 53 49 52
f 54 49 53
f 55 56 57
f 58 56 55
f 59 56 58
f 50 60 48
f 61 57 56
f 60 57 61
f 61 48 60
f 49 54 17
f 57 14 20
f 55 57 20
f 57 60 14
f 60 50 15
f 60 15 14
f 50 49 17
f 50 17 15
f 45 47 61
f 45 61 56
f 52 51 44
f 20 35 59
f 20 59 58
f 54 53 17
f 44 17 53
f 44 53 52
f 58 55 20
f 48 61 47
f 56 59 35
f 56 35 45
f 51 48 47
f 51 47 44

11
tests/data/pyramid.obj Normal file
View file

@ -0,0 +1,11 @@
v 10.000000 10.000000 40.000000
v 0.000000 0.000000 0.000000
v 20.000000 0.000000 0.000000
v 20.000000 20.000000 0.000000
v 0.000000 20.000000 0.000000
f 1 2 3
f 1 4 5
f 4 2 5
f 2 4 3
f 4 1 3
f 5 2 1

204
tests/data/sloping_hole.obj Normal file
View file

@ -0,0 +1,204 @@
v -20.000000 -20.000000 -5.000000
v -20.000000 -20.000000 5.000000
v -20.000000 20.000000 -5.000000
v -20.000000 20.000000 5.000000
v 20.000000 -20.000000 -5.000000
v 20.000000 -20.000000 5.000000
v 4.462940 7.431450 -5.000000
v 20.000000 20.000000 -5.000000
v -19.142099 0.000000 -5.000000
v -18.833099 -2.079120 -5.000000
v -17.919500 -4.067370 -5.000000
v -16.441200 -5.877850 -5.000000
v -14.462900 -7.431450 -5.000000
v -12.071100 -8.660250 -5.000000
v -9.370160 -9.510560 -5.000000
v -3.521740 -9.945220 -5.000000
v -6.478260 -9.945220 -5.000000
v -0.629840 -9.510560 -5.000000
v 2.071070 -8.660250 -5.000000
v 6.441230 -5.877850 -5.000000
v 4.462940 -7.431450 -5.000000
v -12.071100 8.660250 -5.000000
v -9.370160 9.510560 -5.000000
v 7.919480 -4.067370 -5.000000
v 8.833100 -2.079120 -5.000000
v -6.478260 9.945220 -5.000000
v -0.629840 9.510560 -5.000000
v 2.071070 8.660250 -5.000000
v 9.142140 0.000000 -5.000000
v 8.833100 2.079120 -5.000000
v -3.521740 9.945220 -5.000000
v 7.919480 4.067370 -5.000000
v 6.441230 5.877850 -5.000000
v -14.462900 7.431450 -5.000000
v -16.441200 5.877850 -5.000000
v -17.919500 4.067370 -5.000000
v -18.833099 2.079120 -5.000000
v 20.000000 20.000000 5.000000
v 3.521740 -9.945220 5.000000
v -8.833100 -2.079120 5.000000
v -9.142140 0.000000 5.000000
v -8.833100 2.079120 5.000000
v 6.478260 -9.945220 5.000000
v -7.919480 4.067370 5.000000
v -6.441230 5.877850 5.000000
v -4.462940 7.431450 5.000000
v -2.071070 8.660250 5.000000
v 0.629840 9.510560 5.000000
v 12.071100 -8.660250 5.000000
v 9.370160 -9.510560 5.000000
v 3.521740 9.945220 5.000000
v 6.478260 9.945220 5.000000
v 9.370160 9.510560 5.000000
v 12.071100 8.660250 5.000000
v 14.462900 7.431450 5.000000
v 16.441200 -5.877850 5.000000
v 14.462900 -7.431450 5.000000
v 16.441200 5.877850 5.000000
v 17.919500 4.067370 5.000000
v 18.833099 -2.079120 5.000000
v 17.919500 -4.067370 5.000000
v 18.833099 2.079120 5.000000
v 19.142099 0.000000 5.000000
v 0.629840 -9.510560 5.000000
v -2.071070 -8.660250 5.000000
v -4.462940 -7.431450 5.000000
v -6.441230 -5.877850 5.000000
v -7.919480 -4.067370 5.000000
f 1 2 3
f 3 2 4
f 2 1 5
f 6 2 5
f 7 3 8
f 1 3 9
f 1 9 10
f 1 10 11
f 1 11 12
f 1 12 13
f 1 13 14
f 1 14 5
f 14 15 5
f 16 5 17
f 18 5 16
f 19 5 18
f 20 5 21
f 19 21 5
f 22 3 23
f 5 20 24
f 5 24 8
f 24 25 8
f 23 3 26
f 27 3 28
f 29 30 8
f 26 3 31
f 30 32 8
f 31 3 27
f 32 33 8
f 28 3 7
f 33 7 8
f 29 8 25
f 34 3 22
f 35 3 34
f 36 3 35
f 37 3 36
f 9 3 37
f 17 5 15
f 3 4 8
f 8 4 38
f 39 2 6
f 4 2 40
f 4 40 41
f 4 41 42
f 43 39 6
f 4 42 44
f 4 44 45
f 38 4 46
f 38 46 47
f 38 47 48
f 49 50 6
f 38 48 51
f 50 43 6
f 38 51 52
f 38 52 53
f 38 53 54
f 38 54 55
f 56 57 6
f 38 55 58
f 38 58 59
f 60 61 6
f 38 59 62
f 38 63 6
f 38 62 63
f 63 60 6
f 61 56 6
f 64 2 39
f 65 2 64
f 66 2 65
f 67 2 66
f 68 2 67
f 40 2 68
f 45 46 4
f 57 49 6
f 6 5 8
f 38 6 8
f 42 41 37
f 37 41 9
f 40 10 41
f 41 10 9
f 44 42 36
f 36 42 37
f 45 44 35
f 35 44 36
f 34 46 45
f 35 34 45
f 22 47 46
f 34 22 46
f 23 48 47
f 22 23 47
f 26 51 48
f 23 26 48
f 31 52 51
f 26 31 51
f 27 53 52
f 31 27 52
f 28 54 53
f 27 28 53
f 7 55 54
f 28 7 54
f 33 58 55
f 7 33 55
f 32 59 58
f 33 32 58
f 30 62 59
f 32 30 59
f 29 63 62
f 30 29 62
f 60 63 29
f 25 60 29
f 61 60 25
f 24 61 25
f 56 61 24
f 20 56 24
f 56 20 57
f 57 20 21
f 57 21 49
f 49 21 19
f 49 19 50
f 50 19 18
f 50 18 43
f 43 18 16
f 43 16 39
f 39 16 17
f 39 17 64
f 64 17 15
f 64 15 65
f 65 15 14
f 65 14 66
f 66 14 13
f 66 13 67
f 67 13 12
f 67 12 68
f 68 12 11
f 68 11 40
f 40 11 10

View file

@ -0,0 +1,14 @@
v 6.000589 -22.998209 0.000000
v 22.001024 -49.999874 0.000000
v -9.999578 -49.999870 0.000000
v 6.000714 -32.237164 28.001925
v 11.167055 -37.972702 18.960167
v 6.000602 -26.539246 10.732185
f 1 2 3
f 4 5 6
f 3 2 5
f 3 5 4
f 3 4 6
f 3 6 1
f 6 5 2
f 6 2 1

View file

@ -0,0 +1,144 @@
v 66.713348 104.286667 0.000000
v 66.713348 95.713333 0.000000
v 65.666687 94.666672 0.000000
v 75.286682 95.713333 0.000000
v 76.333344 105.333336 0.000000
v 76.333344 94.666672 0.000000
v 65.666687 105.333328 0.000000
v 75.286682 104.286667 0.000000
v 71.106682 104.586662 2.800000
v 66.413353 104.586662 2.800000
v 75.586685 104.586662 2.800000
v 66.413353 99.893333 2.800000
v 66.413353 95.413338 2.800000
v 71.106682 95.413338 2.800000
v 75.586685 95.413338 2.800000
v 75.586685 100.106667 2.800000
v 74.540016 103.540001 2.800000
v 70.032013 103.540001 2.800000
v 67.460007 103.540001 2.800000
v 67.460007 100.968002 2.800000
v 67.460007 96.459999 2.800000
v 74.540016 99.031998 2.800000
v 74.540016 96.459999 2.800000
v 70.032013 96.459999 2.800000
v 123.666718 94.666672 0.000000
v 134.333313 94.666672 0.000000
v 124.413361 95.413338 2.800000
v 129.106674 95.413338 2.800000
v 133.586670 95.413338 2.800000
v 123.666718 105.333328 0.000000
v 124.413361 104.586662 2.800000
v 124.413361 99.893333 2.800000
v 134.333313 105.333328 0.000000
v 129.106674 104.586662 2.800000
v 133.586670 104.586662 2.800000
v 133.586670 100.106667 2.800000
v 124.713318 104.286667 0.000000
v 124.713318 95.713333 0.000000
v 133.286713 95.713333 0.000000
v 133.286713 104.286667 0.000000
v 132.540024 103.540001 2.800000
v 128.032028 103.540009 2.800000
v 125.460007 103.540001 2.800000
v 125.460007 100.968002 2.800000
v 125.460007 96.459999 2.800000
v 132.540024 99.031998 2.800000
v 132.540024 96.459999 2.800000
v 128.032028 96.459999 2.800000
f 1 2 3
f 4 5 6
f 7 5 1
f 7 1 3
f 3 2 6
f 8 5 4
f 2 4 6
f 1 5 8
f 5 7 9
f 7 10 9
f 5 9 11
f 7 3 10
f 3 12 10
f 3 13 12
f 3 6 13
f 6 14 13
f 6 15 14
f 5 11 16
f 6 5 15
f 5 16 15
f 8 17 18
f 1 8 19
f 8 18 19
f 2 20 21
f 2 1 20
f 1 19 20
f 8 4 22
f 4 23 22
f 8 22 17
f 4 24 23
f 4 2 24
f 2 21 24
f 25 26 27
f 26 28 27
f 26 29 28
f 30 25 31
f 25 32 31
f 25 27 32
f 33 30 34
f 30 31 34
f 33 34 35
f 33 35 36
f 26 33 29
f 33 36 29
f 37 38 25
f 39 33 26
f 30 33 37
f 30 37 25
f 25 38 26
f 40 33 39
f 38 39 26
f 37 33 40
f 40 41 42
f 37 40 43
f 40 42 43
f 38 44 45
f 38 37 44
f 37 43 44
f 40 39 46
f 39 47 46
f 40 46 41
f 39 48 47
f 39 38 48
f 38 45 48
f 17 9 10
f 17 11 9
f 11 17 16
f 16 17 22
f 23 16 22
f 16 23 15
f 23 24 15
f 24 21 15
f 18 17 10
f 19 18 10
f 20 19 10
f 20 10 12
f 20 12 21
f 14 15 21
f 21 12 13
f 14 21 13
f 42 41 31
f 43 42 31
f 44 43 31
f 44 31 32
f 44 32 45
f 28 29 45
f 45 32 27
f 28 45 27
f 41 34 31
f 41 35 34
f 35 41 36
f 36 41 46
f 47 36 46
f 36 47 29
f 47 48 29
f 48 45 29

View file

@ -0,0 +1,5 @@
get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp tests_main.cpp)
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES})
catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ")

View file

@ -0,0 +1,647 @@
#include <catch2/catch.hpp>
#include <unordered_set>
#include <unordered_map>
#include <random>
// Debug
#include <fstream>
#include "libslic3r/libslic3r.h"
#include "libslic3r/Format/OBJ.hpp"
#include "libslic3r/SLAPrint.hpp"
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/SLA/SLAPad.hpp"
#include "libslic3r/SLA/SLASupportTreeBuilder.hpp"
#include "libslic3r/SLA/SLASupportTreeBuildsteps.hpp"
#include "libslic3r/SLA/SLAAutoSupports.hpp"
#include "libslic3r/SLA/SLARaster.hpp"
#include "libslic3r/MTUtils.hpp"
#include "libslic3r/SVG.hpp"
#include "libslic3r/Format/OBJ.hpp"
#if defined(WIN32) || defined(_WIN32)
#define PATH_SEPARATOR R"(\)"
#else
#define PATH_SEPARATOR R"(/)"
#endif
namespace {
using namespace Slic3r;
TriangleMesh load_model(const std::string &obj_filename)
{
TriangleMesh mesh;
auto fpath = TEST_DATA_DIR PATH_SEPARATOR + obj_filename;
load_obj(fpath.c_str(), &mesh);
return mesh;
}
enum e_validity {
ASSUME_NO_EMPTY = 1,
ASSUME_MANIFOLD = 2,
ASSUME_NO_REPAIR = 4
};
void check_validity(const TriangleMesh &input_mesh,
int flags = ASSUME_NO_EMPTY | ASSUME_MANIFOLD |
ASSUME_NO_REPAIR)
{
TriangleMesh mesh{input_mesh};
if (flags & ASSUME_NO_EMPTY) {
REQUIRE_FALSE(mesh.empty());
} else if (mesh.empty())
return; // If it can be empty and it is, there is nothing left to do.
REQUIRE(stl_validate(&mesh.stl));
bool do_update_shared_vertices = false;
mesh.repair(do_update_shared_vertices);
if (flags & ASSUME_NO_REPAIR) {
REQUIRE_FALSE(mesh.needed_repair());
}
if (flags & ASSUME_MANIFOLD) {
mesh.require_shared_vertices();
if (!mesh.is_manifold()) mesh.WriteOBJFile("non_manifold.obj");
REQUIRE(mesh.is_manifold());
}
}
struct PadByproducts
{
ExPolygons model_contours;
ExPolygons support_contours;
TriangleMesh mesh;
};
void test_pad(const std::string & obj_filename,
const sla::PadConfig &padcfg,
PadByproducts & out)
{
REQUIRE(padcfg.validate().empty());
TriangleMesh mesh = load_model(obj_filename);
REQUIRE_FALSE(mesh.empty());
// Create pad skeleton only from the model
Slic3r::sla::pad_blueprint(mesh, out.model_contours);
REQUIRE_FALSE(out.model_contours.empty());
// Create the pad geometry for the model contours only
Slic3r::sla::create_pad({}, out.model_contours, out.mesh, padcfg);
check_validity(out.mesh);
auto bb = out.mesh.bounding_box();
REQUIRE(bb.max.z() - bb.min.z() == Approx(padcfg.full_height()));
}
void test_pad(const std::string & obj_filename,
const sla::PadConfig &padcfg = {})
{
PadByproducts byproducts;
test_pad(obj_filename, padcfg, byproducts);
}
struct SupportByproducts
{
std::string obj_fname;
std::vector<float> slicegrid;
std::vector<ExPolygons> model_slices;
sla::SupportTreeBuilder supporttree;
TriangleMesh input_mesh;
};
const constexpr float CLOSING_RADIUS = 0.005f;
void check_support_tree_integrity(const sla::SupportTreeBuilder &stree,
const sla::SupportConfig &cfg)
{
double gnd = stree.ground_level;
double H1 = cfg.max_solo_pillar_height_mm;
double H2 = cfg.max_dual_pillar_height_mm;
for (const sla::Head &head : stree.heads()) {
REQUIRE((!head.is_valid() || head.pillar_id != sla::ID_UNSET ||
head.bridge_id != sla::ID_UNSET));
}
for (const sla::Pillar &pillar : stree.pillars()) {
if (std::abs(pillar.endpoint().z() - gnd) < EPSILON) {
double h = pillar.height;
if (h > H1) REQUIRE(pillar.links >= 1);
else if(h > H2) { REQUIRE(pillar.links >= 2); }
}
REQUIRE(pillar.links <= cfg.pillar_cascade_neighbors);
REQUIRE(pillar.bridges <= cfg.max_bridges_on_pillar);
}
double max_bridgelen = 0.;
auto chck_bridge = [&cfg](const sla::Bridge &bridge, double &max_brlen) {
Vec3d n = bridge.endp - bridge.startp;
double d = sla::distance(n);
max_brlen = std::max(d, max_brlen);
double z = n.z();
double polar = std::acos(z / d);
double slope = -polar + PI / 2.;
REQUIRE(std::abs(slope) >= cfg.bridge_slope - EPSILON);
};
for (auto &bridge : stree.bridges()) chck_bridge(bridge, max_bridgelen);
REQUIRE(max_bridgelen <= cfg.max_bridge_length_mm);
max_bridgelen = 0;
for (auto &bridge : stree.crossbridges()) chck_bridge(bridge, max_bridgelen);
double md = cfg.max_pillar_link_distance_mm / std::cos(-cfg.bridge_slope);
REQUIRE(max_bridgelen <= md);
}
void test_supports(const std::string & obj_filename,
const sla::SupportConfig &supportcfg,
SupportByproducts & out)
{
using namespace Slic3r;
TriangleMesh mesh = load_model(obj_filename);
REQUIRE_FALSE(mesh.empty());
TriangleMeshSlicer slicer{&mesh};
auto bb = mesh.bounding_box();
double zmin = bb.min.z();
double zmax = bb.max.z();
double gnd = zmin - supportcfg.object_elevation_mm;
auto layer_h = 0.05f;
out.slicegrid = grid(float(gnd), float(zmax), layer_h);
slicer.slice(out.slicegrid , CLOSING_RADIUS, &out.model_slices, []{});
// Create the special index-triangle mesh with spatial indexing which
// is the input of the support point and support mesh generators
sla::EigenMesh3D emesh{mesh};
// Create the support point generator
sla::SLAAutoSupports::Config autogencfg;
autogencfg.head_diameter = float(2 * supportcfg.head_front_radius_mm);
sla::SLAAutoSupports point_gen{emesh, out.model_slices, out.slicegrid,
autogencfg, [] {}, [](int) {}};
// Get the calculated support points.
std::vector<sla::SupportPoint> support_points = point_gen.output();
int validityflags = ASSUME_NO_REPAIR;
// If there is no elevation, support points shall be removed from the
// bottom of the object.
if (std::abs(supportcfg.object_elevation_mm) < EPSILON) {
sla::remove_bottom_points(support_points, zmin,
supportcfg.base_height_mm);
} else {
// Should be support points at least on the bottom of the model
REQUIRE_FALSE(support_points.empty());
// Also the support mesh should not be empty.
validityflags |= ASSUME_NO_EMPTY;
}
// Generate the actual support tree
sla::SupportTreeBuilder treebuilder;
treebuilder.build(sla::SupportableMesh{emesh, support_points, supportcfg});
check_support_tree_integrity(treebuilder, supportcfg);
const TriangleMesh &output_mesh = treebuilder.retrieve_mesh();
check_validity(output_mesh, validityflags);
// Quick check if the dimensions and placement of supports are correct
auto obb = output_mesh.bounding_box();
double allowed_zmin = zmin - supportcfg.object_elevation_mm;
if (std::abs(supportcfg.object_elevation_mm) < EPSILON)
allowed_zmin = zmin - 2 * supportcfg.head_back_radius_mm;
REQUIRE(obb.min.z() >= allowed_zmin);
REQUIRE(obb.max.z() <= zmax);
// Move out the support tree into the byproducts, we can examine it further
// in various tests.
out.obj_fname = std::move(obj_filename);
out.supporttree = std::move(treebuilder);
out.input_mesh = std::move(mesh);
}
void test_supports(const std::string & obj_filename,
const sla::SupportConfig &supportcfg = {})
{
SupportByproducts byproducts;
test_supports(obj_filename, supportcfg, byproducts);
}
void export_failed_case(const std::vector<ExPolygons> &support_slices,
const SupportByproducts &byproducts)
{
for (size_t n = 0; n < support_slices.size(); ++n) {
const ExPolygons &sup_slice = support_slices[n];
const ExPolygons &mod_slice = byproducts.model_slices[n];
Polygons intersections = intersection(sup_slice, mod_slice);
std::stringstream ss;
if (!intersections.empty()) {
ss << byproducts.obj_fname << std::setprecision(4) << n << ".svg";
SVG svg(ss.str());
svg.draw(sup_slice, "green");
svg.draw(mod_slice, "blue");
svg.draw(intersections, "red");
svg.Close();
}
}
TriangleMesh m;
byproducts.supporttree.retrieve_full_mesh(m);
m.merge(byproducts.input_mesh);
m.repair();
m.require_shared_vertices();
m.WriteOBJFile(byproducts.obj_fname.c_str());
}
void test_support_model_collision(
const std::string & obj_filename,
const sla::SupportConfig &input_supportcfg = {})
{
SupportByproducts byproducts;
sla::SupportConfig supportcfg = input_supportcfg;
// Set head penetration to a small negative value which should ensure that
// the supports will not touch the model body.
supportcfg.head_penetration_mm = -0.15;
// TODO: currently, the tailheads penetrating into the model body do not
// respect the penetration parameter properly. No issues were reported so
// far but we should definitely fix this.
supportcfg.ground_facing_only = true;
test_supports(obj_filename, supportcfg, byproducts);
// Slice the support mesh given the slice grid of the model.
std::vector<ExPolygons> support_slices =
byproducts.supporttree.slice(byproducts.slicegrid, CLOSING_RADIUS);
// The slices originate from the same slice grid so the numbers must match
bool support_mesh_is_empty =
byproducts.supporttree.retrieve_mesh(sla::MeshType::Pad).empty() &&
byproducts.supporttree.retrieve_mesh(sla::MeshType::Support).empty();
if (support_mesh_is_empty)
REQUIRE(support_slices.empty());
else
REQUIRE(support_slices.size() == byproducts.model_slices.size());
bool notouch = true;
for (size_t n = 0; notouch && n < support_slices.size(); ++n) {
const ExPolygons &sup_slice = support_slices[n];
const ExPolygons &mod_slice = byproducts.model_slices[n];
Polygons intersections = intersection(sup_slice, mod_slice);
notouch = notouch && intersections.empty();
}
if (!notouch) export_failed_case(support_slices, byproducts);
REQUIRE(notouch);
}
const char * const BELOW_PAD_TEST_OBJECTS[] = {
"20mm_cube.obj",
"V.obj",
};
const char * const AROUND_PAD_TEST_OBJECTS[] = {
"20mm_cube.obj",
"V.obj",
"frog_legs.obj",
"cube_with_concave_hole_enlarged.obj",
};
const char *const SUPPORT_TEST_MODELS[] = {
"cube_with_concave_hole_enlarged_standing.obj",
"A_upsidedown.obj",
"extruder_idler.obj"
};
} // namespace
// Test pair hash for 'nums' random number pairs.
template <class I, class II> void test_pairhash()
{
const constexpr size_t nums = 1000;
I A[nums] = {0}, B[nums] = {0};
std::unordered_set<I> CH;
std::unordered_map<II, std::pair<I, I>> ints;
std::random_device rd;
std::mt19937 gen(rd());
const I Ibits = int(sizeof(I) * CHAR_BIT);
const II IIbits = int(sizeof(II) * CHAR_BIT);
const int bits = IIbits / 2 < Ibits ? Ibits / 2 : Ibits;
const I Imax = I(std::pow(2., bits) - 1);
std::uniform_int_distribution<I> dis(0, Imax);
for (size_t i = 0; i < nums;) {
I a = dis(gen);
if (CH.find(a) == CH.end()) { CH.insert(a); A[i] = a; ++i; }
}
for (size_t i = 0; i < nums;) {
I b = dis(gen);
if (CH.find(b) == CH.end()) { CH.insert(b); B[i] = b; ++i; }
}
for (size_t i = 0; i < nums; ++i) {
I a = A[i], b = B[i];
REQUIRE(a != b);
II hash_ab = sla::pairhash<I, II>(a, b);
II hash_ba = sla::pairhash<I, II>(b, a);
REQUIRE(hash_ab == hash_ba);
auto it = ints.find(hash_ab);
if (it != ints.end()) {
REQUIRE((
(it->second.first == a && it->second.second == b) ||
(it->second.first == b && it->second.second == a)
));
} else
ints[hash_ab] = std::make_pair(a, b);
}
}
TEST_CASE("Pillar pairhash should be unique", "[SLASupportGeneration]") {
test_pairhash<int, long>();
test_pairhash<unsigned, unsigned>();
test_pairhash<unsigned, unsigned long>();
}
TEST_CASE("Flat pad geometry is valid", "[SLASupportGeneration]") {
sla::PadConfig padcfg;
// Disable wings
padcfg.wall_height_mm = .0;
for (auto &fname : BELOW_PAD_TEST_OBJECTS) test_pad(fname, padcfg);
}
TEST_CASE("WingedPadGeometryIsValid", "[SLASupportGeneration]") {
sla::PadConfig padcfg;
// Add some wings to the pad to test the cavity
padcfg.wall_height_mm = 1.;
for (auto &fname : BELOW_PAD_TEST_OBJECTS) test_pad(fname, padcfg);
}
TEST_CASE("FlatPadAroundObjectIsValid", "[SLASupportGeneration]") {
sla::PadConfig padcfg;
// Add some wings to the pad to test the cavity
padcfg.wall_height_mm = 0.;
// padcfg.embed_object.stick_stride_mm = 0.;
padcfg.embed_object.enabled = true;
padcfg.embed_object.everywhere = true;
for (auto &fname : AROUND_PAD_TEST_OBJECTS) test_pad(fname, padcfg);
}
TEST_CASE("WingedPadAroundObjectIsValid", "[SLASupportGeneration]") {
sla::PadConfig padcfg;
// Add some wings to the pad to test the cavity
padcfg.wall_height_mm = 1.;
padcfg.embed_object.enabled = true;
padcfg.embed_object.everywhere = true;
for (auto &fname : AROUND_PAD_TEST_OBJECTS) test_pad(fname, padcfg);
}
TEST_CASE("ElevatedSupportGeometryIsValid", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg;
supportcfg.object_elevation_mm = 5.;
for (auto fname : SUPPORT_TEST_MODELS) test_supports(fname);
}
TEST_CASE("FloorSupportGeometryIsValid", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg;
supportcfg.object_elevation_mm = 0;
for (auto &fname: SUPPORT_TEST_MODELS) test_supports(fname, supportcfg);
}
TEST_CASE("ElevatedSupportsDoNotPierceModel", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg;
for (auto fname : SUPPORT_TEST_MODELS)
test_support_model_collision(fname, supportcfg);
}
TEST_CASE("FloorSupportsDoNotPierceModel", "[SLASupportGeneration]") {
sla::SupportConfig supportcfg;
supportcfg.object_elevation_mm = 0;
for (auto fname : SUPPORT_TEST_MODELS)
test_support_model_collision(fname, supportcfg);
}
TEST_CASE("DefaultRasterShouldBeEmpty", "[SLARasterOutput]") {
sla::Raster raster;
REQUIRE(raster.empty());
}
TEST_CASE("InitializedRasterShouldBeNONEmpty", "[SLARasterOutput]") {
// Default Prusa SL1 display parameters
sla::Raster::Resolution res{2560, 1440};
sla::Raster::PixelDim pixdim{120. / res.width_px, 68. / res.height_px};
sla::Raster raster;
raster.reset(res, pixdim);
REQUIRE_FALSE(raster.empty());
REQUIRE(raster.resolution().width_px == res.width_px);
REQUIRE(raster.resolution().height_px == res.height_px);
REQUIRE(raster.pixel_dimensions().w_mm == Approx(pixdim.w_mm));
REQUIRE(raster.pixel_dimensions().h_mm == Approx(pixdim.h_mm));
}
using TPixel = uint8_t;
static constexpr const TPixel FullWhite = 255;
static constexpr const TPixel FullBlack = 0;
template <class A, int N> constexpr int arraysize(const A (&)[N]) { return N; }
static void check_raster_transformations(sla::Raster::Orientation o,
sla::Raster::TMirroring mirroring)
{
double disp_w = 120., disp_h = 68.;
sla::Raster::Resolution res{2560, 1440};
sla::Raster::PixelDim pixdim{disp_w / res.width_px, disp_h / res.height_px};
auto bb = BoundingBox({0, 0}, {scaled(disp_w), scaled(disp_h)});
sla::Raster::Trafo trafo{o, mirroring};
trafo.origin_x = bb.center().x();
trafo.origin_y = bb.center().y();
sla::Raster raster{res, pixdim, trafo};
// create box of size 32x32 pixels (not 1x1 to avoid antialiasing errors)
coord_t pw = 32 * coord_t(std::ceil(scaled<double>(pixdim.w_mm)));
coord_t ph = 32 * coord_t(std::ceil(scaled<double>(pixdim.h_mm)));
ExPolygon box;
box.contour.points = {{-pw, -ph}, {pw, -ph}, {pw, ph}, {-pw, ph}};
double tr_x = scaled<double>(20.), tr_y = tr_x;
box.translate(tr_x, tr_y);
ExPolygon expected_box = box;
// Now calculate the position of the translated box according to output
// trafo.
if (o == sla::Raster::Orientation::roPortrait) expected_box.rotate(PI / 2.);
if (mirroring[X])
for (auto &p : expected_box.contour.points) p.x() = -p.x();
if (mirroring[Y])
for (auto &p : expected_box.contour.points) p.y() = -p.y();
raster.draw(box);
Point expected_coords = expected_box.contour.bounding_box().center();
double rx = unscaled(expected_coords.x() + bb.center().x()) / pixdim.w_mm;
double ry = unscaled(expected_coords.y() + bb.center().y()) / pixdim.h_mm;
auto w = size_t(std::floor(rx));
auto h = res.height_px - size_t(std::floor(ry));
REQUIRE((w < res.width_px && h < res.height_px));
auto px = raster.read_pixel(w, h);
if (px != FullWhite) {
sla::PNGImage img;
std::fstream outf("out.png", std::ios::out);
outf << img.serialize(raster);
}
REQUIRE(px == FullWhite);
}
TEST_CASE("MirroringShouldBeCorrect", "[SLARasterOutput]") {
sla::Raster::TMirroring mirrorings[] = {sla::Raster::NoMirror,
sla::Raster::MirrorX,
sla::Raster::MirrorY,
sla::Raster::MirrorXY};
sla::Raster::Orientation orientations[] = {sla::Raster::roLandscape,
sla::Raster::roPortrait};
for (auto orientation : orientations)
for (auto &mirror : mirrorings)
check_raster_transformations(orientation, mirror);
}
static ExPolygon square_with_hole(double v)
{
ExPolygon poly;
coord_t V = scaled(v / 2.);
poly.contour.points = {{-V, -V}, {V, -V}, {V, V}, {-V, V}};
poly.holes.emplace_back();
V = V / 2;
poly.holes.front().points = {{-V, V}, {V, V}, {V, -V}, {-V, -V}};
return poly;
}
static double pixel_area(TPixel px, const sla::Raster::PixelDim &pxdim)
{
return (pxdim.h_mm * pxdim.w_mm) * px * 1. / (FullWhite - FullBlack);
}
static double raster_white_area(const sla::Raster &raster)
{
if (raster.empty()) return std::nan("");
auto res = raster.resolution();
double a = 0;
for (size_t x = 0; x < res.width_px; ++x)
for (size_t y = 0; y < res.height_px; ++y) {
auto px = raster.read_pixel(x, y);
a += pixel_area(px, raster.pixel_dimensions());
}
return a;
}
static double predict_error(const ExPolygon &p, const sla::Raster::PixelDim &pd)
{
auto lines = p.lines();
double pix_err = pixel_area(FullWhite, pd) / 2.;
// Worst case is when a line is parallel to the shorter axis of one pixel,
// when the line will be composed of the max number of pixels
double pix_l = std::min(pd.h_mm, pd.w_mm);
double error = 0.;
for (auto &l : lines)
error += (unscaled(l.length()) / pix_l) * pix_err;
return error;
}
TEST_CASE("RasterizedPolygonAreaShouldMatch", "[SLARasterOutput]") {
double disp_w = 120., disp_h = 68.;
sla::Raster::Resolution res{2560, 1440};
sla::Raster::PixelDim pixdim{disp_w / res.width_px, disp_h / res.height_px};
sla::Raster raster{res, pixdim};
auto bb = BoundingBox({0, 0}, {scaled(disp_w), scaled(disp_h)});
ExPolygon poly = square_with_hole(10.);
poly.translate(bb.center().x(), bb.center().y());
raster.draw(poly);
double a = poly.area() / (scaled<double>(1.) * scaled(1.));
double ra = raster_white_area(raster);
double diff = std::abs(a - ra);
REQUIRE(diff <= predict_error(poly, pixdim));
raster.clear();
poly = square_with_hole(60.);
poly.translate(bb.center().x(), bb.center().y());
raster.draw(poly);
a = poly.area() / (scaled<double>(1.) * scaled(1.));
ra = raster_white_area(raster);
diff = std::abs(a - ra);
REQUIRE(diff <= predict_error(poly, pixdim));
}

View file

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>