sla_test_utils.hpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #ifndef SLA_TEST_UTILS_HPP
  2. #define SLA_TEST_UTILS_HPP
  3. #include <catch2/catch.hpp>
  4. #include <test_utils.hpp>
  5. // Debug
  6. #include <fstream>
  7. #include <unordered_set>
  8. #include "libslic3r/libslic3r.h"
  9. #include "libslic3r/Format/OBJ.hpp"
  10. #include "libslic3r/SLAPrint.hpp"
  11. #include "libslic3r/TriangleMesh.hpp"
  12. #include "libslic3r/SLA/Pad.hpp"
  13. #include "libslic3r/SLA/SupportTreeBuilder.hpp"
  14. #include "libslic3r/SLA/SupportTreeBuildsteps.hpp"
  15. #include "libslic3r/SLA/SupportPointGenerator.hpp"
  16. #include "libslic3r/SLA/AGGRaster.hpp"
  17. #include "libslic3r/SLA/ConcaveHull.hpp"
  18. #include "libslic3r/MTUtils.hpp"
  19. #include "libslic3r/SVG.hpp"
  20. #include "libslic3r/Format/OBJ.hpp"
  21. using namespace Slic3r;
  22. enum e_validity {
  23. ASSUME_NO_EMPTY = 1,
  24. ASSUME_MANIFOLD = 2,
  25. ASSUME_NO_REPAIR = 4
  26. };
  27. void check_validity(const TriangleMesh &input_mesh,
  28. int flags = ASSUME_NO_EMPTY | ASSUME_MANIFOLD |
  29. ASSUME_NO_REPAIR);
  30. struct PadByproducts
  31. {
  32. ExPolygons model_contours;
  33. ExPolygons support_contours;
  34. TriangleMesh mesh;
  35. };
  36. void test_concave_hull(const ExPolygons &polys);
  37. void test_pad(const std::string & obj_filename,
  38. const sla::PadConfig &padcfg,
  39. PadByproducts & out);
  40. inline void test_pad(const std::string & obj_filename,
  41. const sla::PadConfig &padcfg = {})
  42. {
  43. PadByproducts byproducts;
  44. test_pad(obj_filename, padcfg, byproducts);
  45. }
  46. struct SupportByproducts
  47. {
  48. std::string obj_fname;
  49. std::vector<float> slicegrid;
  50. std::vector<ExPolygons> model_slices;
  51. sla::SupportTreeBuilder supporttree;
  52. TriangleMesh input_mesh;
  53. };
  54. const constexpr float CLOSING_RADIUS = 0.005f;
  55. void check_support_tree_integrity(const sla::SupportTreeBuilder &stree,
  56. const sla::SupportTreeConfig &cfg);
  57. void test_supports(const std::string &obj_filename,
  58. const sla::SupportTreeConfig &supportcfg,
  59. const sla::HollowingConfig &hollowingcfg,
  60. const sla::DrainHoles &drainholes,
  61. SupportByproducts &out);
  62. inline void test_supports(const std::string &obj_filename,
  63. const sla::SupportTreeConfig &supportcfg,
  64. SupportByproducts &out)
  65. {
  66. sla::HollowingConfig hcfg;
  67. hcfg.enabled = false;
  68. test_supports(obj_filename, supportcfg, hcfg, {}, out);
  69. }
  70. inline void test_supports(const std::string &obj_filename,
  71. const sla::SupportTreeConfig &supportcfg = {})
  72. {
  73. SupportByproducts byproducts;
  74. test_supports(obj_filename, supportcfg, byproducts);
  75. }
  76. void export_failed_case(const std::vector<ExPolygons> &support_slices,
  77. const SupportByproducts &byproducts);
  78. void test_support_model_collision(
  79. const std::string &obj_filename,
  80. const sla::SupportTreeConfig &input_supportcfg,
  81. const sla::HollowingConfig &hollowingcfg,
  82. const sla::DrainHoles &drainholes);
  83. inline void test_support_model_collision(
  84. const std::string &obj_filename,
  85. const sla::SupportTreeConfig &input_supportcfg = {})
  86. {
  87. sla::HollowingConfig hcfg;
  88. hcfg.enabled = false;
  89. test_support_model_collision(obj_filename, input_supportcfg, hcfg, {});
  90. }
  91. // Test pair hash for 'nums' random number pairs.
  92. template <class I, class II> void test_pairhash()
  93. {
  94. const constexpr size_t nums = 1000;
  95. I A[nums] = {0}, B[nums] = {0};
  96. std::unordered_set<I> CH;
  97. std::unordered_map<II, std::pair<I, I>> ints;
  98. std::random_device rd;
  99. std::mt19937 gen(rd());
  100. const I Ibits = int(sizeof(I) * CHAR_BIT);
  101. const II IIbits = int(sizeof(II) * CHAR_BIT);
  102. int bits = IIbits / 2 < Ibits ? Ibits / 2 : Ibits;
  103. if (std::is_signed<I>::value) bits -= 1;
  104. const I Imin = 0;
  105. const I Imax = I(std::pow(2., bits) - 1);
  106. std::uniform_int_distribution<I> dis(Imin, Imax);
  107. for (size_t i = 0; i < nums;) {
  108. I a = dis(gen);
  109. if (CH.find(a) == CH.end()) { CH.insert(a); A[i] = a; ++i; }
  110. }
  111. for (size_t i = 0; i < nums;) {
  112. I b = dis(gen);
  113. if (CH.find(b) == CH.end()) { CH.insert(b); B[i] = b; ++i; }
  114. }
  115. for (size_t i = 0; i < nums; ++i) {
  116. I a = A[i], b = B[i];
  117. REQUIRE(a != b);
  118. II hash_ab = sla::pairhash<I, II>(a, b);
  119. II hash_ba = sla::pairhash<I, II>(b, a);
  120. REQUIRE(hash_ab == hash_ba);
  121. auto it = ints.find(hash_ab);
  122. if (it != ints.end()) {
  123. REQUIRE((
  124. (it->second.first == a && it->second.second == b) ||
  125. (it->second.first == b && it->second.second == a)
  126. ));
  127. } else
  128. ints[hash_ab] = std::make_pair(a, b);
  129. }
  130. }
  131. // SLA Raster test utils:
  132. using TPixel = uint8_t;
  133. static constexpr const TPixel FullWhite = 255;
  134. static constexpr const TPixel FullBlack = 0;
  135. template <class A, int N> constexpr int arraysize(const A (&)[N]) { return N; }
  136. void check_raster_transformations(sla::RasterBase::Orientation o,
  137. sla::RasterBase::TMirroring mirroring);
  138. ExPolygon square_with_hole(double v);
  139. inline double pixel_area(TPixel px, const sla::RasterBase::PixelDim &pxdim)
  140. {
  141. return (pxdim.h_mm * pxdim.w_mm) * px * 1. / (FullWhite - FullBlack);
  142. }
  143. double raster_white_area(const sla::RasterGrayscaleAA &raster);
  144. long raster_pxsum(const sla::RasterGrayscaleAA &raster);
  145. double predict_error(const ExPolygon &p, const sla::RasterBase::PixelDim &pd);
  146. sla::SupportPoints calc_support_pts(
  147. const TriangleMesh & mesh,
  148. const sla::SupportPointGenerator::Config &cfg = {});
  149. #endif // SLA_TEST_UTILS_HPP