FillBase.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #ifndef slic3r_FillBase_hpp_
  2. #define slic3r_FillBase_hpp_
  3. #include <assert.h>
  4. #include <memory.h>
  5. #include <float.h>
  6. #include <stdint.h>
  7. #include <stdexcept>
  8. #include <type_traits>
  9. #include "../libslic3r.h"
  10. #include "../BoundingBox.hpp"
  11. #include "../Utils.hpp"
  12. namespace Slic3r {
  13. class ExPolygon;
  14. class Surface;
  15. enum InfillPattern : int;
  16. namespace FillAdaptive_Internal {
  17. struct Octree;
  18. };
  19. class InfillFailedException : public std::runtime_error {
  20. public:
  21. InfillFailedException() : std::runtime_error("Infill failed") {}
  22. };
  23. struct FillParams
  24. {
  25. bool full_infill() const { return density > 0.9999f; }
  26. // Fill density, fraction in <0, 1>
  27. float density { 0.f };
  28. // Don't connect the fill lines around the inner perimeter.
  29. bool dont_connect { false };
  30. // Don't adjust spacing to fill the space evenly.
  31. bool dont_adjust { true };
  32. // Monotonous infill - strictly left to right for better surface quality of top infills.
  33. bool monotonous { false };
  34. // For Honeycomb.
  35. // we were requested to complete each loop;
  36. // in this case we don't try to make more continuous paths
  37. bool complete { false };
  38. };
  39. static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");
  40. class Fill
  41. {
  42. public:
  43. // Index of the layer.
  44. size_t layer_id;
  45. // Z coordinate of the top print surface, in unscaled coordinates
  46. coordf_t z;
  47. // in unscaled coordinates
  48. coordf_t spacing;
  49. // infill / perimeter overlap, in unscaled coordinates
  50. coordf_t overlap;
  51. // in radians, ccw, 0 = East
  52. float angle;
  53. // In scaled coordinates. Maximum lenght of a perimeter segment connecting two infill lines.
  54. // Used by the FillRectilinear2, FillGrid2, FillTriangles, FillStars and FillCubic.
  55. // If left to zero, the links will not be limited.
  56. coord_t link_max_length;
  57. // In scaled coordinates. Used by the concentric infill pattern to clip the loops to create extrusion paths.
  58. coord_t loop_clipping;
  59. // In scaled coordinates. Bounding box of the 2D projection of the object.
  60. BoundingBox bounding_box;
  61. // Octree builds on mesh for usage in the adaptive cubic infill
  62. FillAdaptive_Internal::Octree* adapt_fill_octree = nullptr;
  63. // Octree builds on mesh for usage in the support cubic infill
  64. FillAdaptive_Internal::Octree* support_fill_octree = nullptr;
  65. public:
  66. virtual ~Fill() {}
  67. static Fill* new_from_type(const InfillPattern type);
  68. static Fill* new_from_type(const std::string &type);
  69. static bool use_bridge_flow(const InfillPattern type);
  70. void set_bounding_box(const Slic3r::BoundingBox &bbox) { bounding_box = bbox; }
  71. // Use bridge flow for the fill?
  72. virtual bool use_bridge_flow() const { return false; }
  73. // Do not sort the fill lines to optimize the print head path?
  74. virtual bool no_sort() const { return false; }
  75. // Perform the fill.
  76. virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
  77. protected:
  78. Fill() :
  79. layer_id(size_t(-1)),
  80. z(0.),
  81. spacing(0.),
  82. // Infill / perimeter overlap.
  83. overlap(0.),
  84. // Initial angle is undefined.
  85. angle(FLT_MAX),
  86. link_max_length(0),
  87. loop_clipping(0),
  88. // The initial bounding box is empty, therefore undefined.
  89. bounding_box(Point(0, 0), Point(-1, -1))
  90. {}
  91. // The expolygon may be modified by the method to avoid a copy.
  92. virtual void _fill_surface_single(
  93. const FillParams & /* params */,
  94. unsigned int /* thickness_layers */,
  95. const std::pair<float, Point> & /* direction */,
  96. ExPolygon & /* expolygon */,
  97. Polylines & /* polylines_out */) {};
  98. virtual float _layer_angle(size_t idx) const { return (idx & 1) ? float(M_PI/2.) : 0; }
  99. virtual std::pair<float, Point> _infill_direction(const Surface *surface) const;
  100. public:
  101. static void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, double spacing, const FillParams &params);
  102. static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);
  103. // Align a coordinate to a grid. The coordinate may be negative,
  104. // the aligned value will never be bigger than the original one.
  105. static coord_t _align_to_grid(const coord_t coord, const coord_t spacing) {
  106. // Current C++ standard defines the result of integer division to be rounded to zero,
  107. // for both positive and negative numbers. Here we want to round down for negative
  108. // numbers as well.
  109. coord_t aligned = (coord < 0) ?
  110. ((coord - spacing + 1) / spacing) * spacing :
  111. (coord / spacing) * spacing;
  112. assert(aligned <= coord);
  113. return aligned;
  114. }
  115. static Point _align_to_grid(Point coord, Point spacing)
  116. { return Point(_align_to_grid(coord(0), spacing(0)), _align_to_grid(coord(1), spacing(1))); }
  117. static coord_t _align_to_grid(coord_t coord, coord_t spacing, coord_t base)
  118. { return base + _align_to_grid(coord - base, spacing); }
  119. static Point _align_to_grid(Point coord, Point spacing, Point base)
  120. { return Point(_align_to_grid(coord(0), spacing(0), base(0)), _align_to_grid(coord(1), spacing(1), base(1))); }
  121. };
  122. } // namespace Slic3r
  123. #endif // slic3r_FillBase_hpp_