test_data.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #ifndef SLIC3R_TEST_DATA_HPP
  2. #define SLIC3R_TEST_DATA_HPP
  3. #include "libslic3r/Config.hpp"
  4. #include "libslic3r/Format/3mf.hpp"
  5. #include "libslic3r/GCode/ModelVisibility.hpp"
  6. #include "libslic3r/GCode/SeamGeometry.hpp"
  7. #include "libslic3r/GCode/SeamPerimeters.hpp"
  8. #include "libslic3r/Geometry.hpp"
  9. #include "libslic3r/Model.hpp"
  10. #include "libslic3r/Point.hpp"
  11. #include "libslic3r/Print.hpp"
  12. #include "libslic3r/TriangleMesh.hpp"
  13. #include "libslic3r/GCode/SeamPlacer.hpp"
  14. #include "libslic3r/GCode/SeamAligned.hpp"
  15. #include <filesystem>
  16. #include <unordered_map>
  17. namespace Slic3r { namespace Test {
  18. constexpr double MM_PER_MIN = 60.0;
  19. /// Enumeration of test meshes
  20. enum class TestMesh {
  21. A,
  22. L,
  23. V,
  24. _40x10,
  25. cube_20x20x20,
  26. cube_2x20x10,
  27. sphere_50mm,
  28. bridge,
  29. bridge_with_hole,
  30. cube_with_concave_hole,
  31. cube_with_hole,
  32. gt2_teeth,
  33. ipadstand,
  34. overhang,
  35. pyramid,
  36. sloping_hole,
  37. slopy_cube,
  38. small_dorito,
  39. step,
  40. two_hollow_squares
  41. };
  42. // Neccessary for <c++17
  43. struct TestMeshHash
  44. {
  45. std::size_t operator()(TestMesh tm) const { return static_cast<std::size_t>(tm); }
  46. };
  47. /// Mesh enumeration to name mapping
  48. extern const std::unordered_map<TestMesh, const char *, TestMeshHash> mesh_names;
  49. /// Port of Slic3r::Test::mesh
  50. /// Basic cubes/boxes should call TriangleMesh::make_cube() directly and rescale/translate it
  51. TriangleMesh mesh(TestMesh m);
  52. TriangleMesh mesh(TestMesh m, Vec3d translate, Vec3d scale = Vec3d(1.0, 1.0, 1.0));
  53. TriangleMesh mesh(TestMesh m, Vec3d translate, double scale = 1.0);
  54. /// Templated function to see if two values are equivalent (+/- epsilon)
  55. template<typename T> bool _equiv(const T &a, const T &b) { return std::abs(a - b) < EPSILON; }
  56. template<typename T> bool _equiv(const T &a, const T &b, double epsilon) {
  57. return abs(a - b) < epsilon;
  58. }
  59. Slic3r::Model model(const std::string &model_name, TriangleMesh &&_mesh);
  60. void init_print(
  61. std::vector<TriangleMesh> &&meshes,
  62. Slic3r::Print &print,
  63. Slic3r::Model &model,
  64. const DynamicPrintConfig &config_in,
  65. bool comments = false,
  66. unsigned duplicate_count = 1
  67. );
  68. void init_print(
  69. std::initializer_list<TestMesh> meshes,
  70. Slic3r::Print &print,
  71. Slic3r::Model &model,
  72. const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(),
  73. bool comments = false,
  74. unsigned duplicate_count = 1
  75. );
  76. void init_print(
  77. std::initializer_list<TriangleMesh> meshes,
  78. Slic3r::Print &print,
  79. Slic3r::Model &model,
  80. const Slic3r::DynamicPrintConfig &config_in = Slic3r::DynamicPrintConfig::full_print_config(),
  81. bool comments = false,
  82. unsigned duplicate = 1
  83. );
  84. void init_print(
  85. std::initializer_list<TestMesh> meshes,
  86. Slic3r::Print &print,
  87. Slic3r::Model &model,
  88. std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
  89. bool comments = false,
  90. unsigned duplicate = 1
  91. );
  92. void init_print(
  93. std::initializer_list<TriangleMesh> meshes,
  94. Slic3r::Print &print,
  95. Slic3r::Model &model,
  96. std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
  97. bool comments = false,
  98. unsigned duplicate = 1
  99. );
  100. void init_and_process_print(
  101. std::initializer_list<TestMesh> meshes,
  102. Slic3r::Print &print,
  103. const DynamicPrintConfig &config,
  104. bool comments = false
  105. );
  106. void init_and_process_print(
  107. std::initializer_list<TriangleMesh> meshes,
  108. Slic3r::Print &print,
  109. const DynamicPrintConfig &config,
  110. bool comments = false
  111. );
  112. void init_and_process_print(
  113. std::initializer_list<TestMesh> meshes,
  114. Slic3r::Print &print,
  115. std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
  116. bool comments = false
  117. );
  118. void init_and_process_print(
  119. std::initializer_list<TriangleMesh> meshes,
  120. Slic3r::Print &print,
  121. std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
  122. bool comments = false
  123. );
  124. std::string gcode(Print &print);
  125. std::string slice(
  126. std::initializer_list<TestMesh> meshes, const DynamicPrintConfig &config, bool comments = false
  127. );
  128. std::string slice(
  129. std::initializer_list<TriangleMesh> meshes,
  130. const DynamicPrintConfig &config,
  131. bool comments = false
  132. );
  133. std::string slice(
  134. std::initializer_list<TestMesh> meshes,
  135. std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
  136. bool comments = false
  137. );
  138. std::string slice(
  139. std::initializer_list<TriangleMesh> meshes,
  140. std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
  141. bool comments = false
  142. );
  143. bool contains(const std::string &data, const std::string &pattern);
  144. bool contains_regex(const std::string &data, const std::string &pattern);
  145. inline std::unique_ptr<Print> process_3mf(const std::filesystem::path &path) {
  146. DynamicPrintConfig config;
  147. auto print{std::make_unique<Print>()};
  148. Model model;
  149. ConfigSubstitutionContext context{ForwardCompatibilitySubstitutionRule::Disable};
  150. load_3mf(path.string().c_str(), config, context, &model, false);
  151. Slic3r::Test::init_print(std::vector<TriangleMesh>{}, *print, model, config);
  152. print->process();
  153. return print;
  154. }
  155. static std::map<std::string, std::unique_ptr<Print>> prints_3mfs;
  156. // Lazy getter, to avoid processing the 3mf multiple times, it already takes ages.
  157. inline Print *get_print(const std::filesystem::path &file_path) {
  158. if (!prints_3mfs.count(file_path.string())) {
  159. prints_3mfs[file_path.string()] = process_3mf(file_path.string());
  160. }
  161. return prints_3mfs[file_path.string()].get();
  162. }
  163. inline void serialize_seam(std::ostream &output, const std::vector<std::vector<Seams::SeamPerimeterChoice>> &seam) {
  164. output << "x,y,z,layer_index" << std::endl;
  165. for (const std::vector<Seams::SeamPerimeterChoice> &layer : seam) {
  166. if (layer.empty()) {
  167. continue;
  168. }
  169. const Seams::SeamPerimeterChoice &choice{layer.front()};
  170. // clang-format off
  171. output
  172. << choice.choice.position.x() << ","
  173. << choice.choice.position.y() << ","
  174. << choice.perimeter.slice_z << ","
  175. << choice.perimeter.layer_index << std::endl;
  176. // clang-format on
  177. }
  178. }
  179. struct SeamsFixture
  180. {
  181. const std::filesystem::path file_3mf{
  182. std::filesystem::path{TEST_DATA_DIR} / std::filesystem::path{"seam_test_object.3mf"}};
  183. const Print *print{Test::get_print(file_3mf)};
  184. const PrintObject *print_object{print->objects()[0]};
  185. Seams::Params params{Seams::Placer::get_params(print->full_print_config())};
  186. const Transform3d transformation{print_object->trafo_centered()};
  187. const ModelVolumePtrs &volumes{print_object->model_object()->volumes};
  188. Seams::ModelInfo::Painting painting{transformation, volumes};
  189. const std::vector<Seams::Geometry::Extrusions> extrusions{
  190. Seams::Geometry::get_extrusions(print_object->layers())};
  191. const Seams::Perimeters::LayerInfos layer_infos{Seams::Perimeters::get_layer_infos(
  192. print_object->layers(), params.perimeter.elephant_foot_compensation
  193. )};
  194. const std::vector<Seams::Geometry::BoundedPolygons> projected{
  195. Seams::Geometry::project_to_geometry(extrusions, params.max_distance)};
  196. const ModelInfo::Visibility visibility{transformation, volumes, params.visibility, [](){}};
  197. Seams::Aligned::VisibilityCalculator
  198. visibility_calculator{visibility, params.convex_visibility_modifier, params.concave_visibility_modifier};
  199. };
  200. }} // namespace Slic3r::Test
  201. #endif // SLIC3R_TEST_DATA_HPP