PerimeterGenerator.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #ifndef slic3r_PerimeterGenerator_hpp_
  2. #define slic3r_PerimeterGenerator_hpp_
  3. #include "libslic3r.h"
  4. #include <vector>
  5. #include "ExPolygonCollection.hpp"
  6. #include "Flow.hpp"
  7. #include "Layer.hpp"
  8. #include "Polygon.hpp"
  9. #include "PrintConfig.hpp"
  10. #include "SurfaceCollection.hpp"
  11. #include "ExtrusionEntityCollection.hpp"
  12. namespace Slic3r {
  13. struct PerimeterIntersectionPoint {
  14. size_t idx_children;
  15. Point child_best;
  16. Point outter_best;
  17. size_t idx_polyline_outter;
  18. coord_t distance;
  19. };
  20. // Hierarchy of perimeters.
  21. class PerimeterGeneratorLoop {
  22. public:
  23. // Polygon of this contour.
  24. Polygon polygon;
  25. // Is it a contour or a hole?
  26. // Contours are CCW oriented, holes are CW oriented.
  27. bool is_contour;
  28. //overhang may need to be reversed
  29. bool is_steep_overhang;
  30. // Depth in the hierarchy. External perimeter has depth = 0. An external perimeter could be both a contour and a hole.
  31. unsigned short depth;
  32. // Children contour, may be both CCW and CW oriented (outer contours or holes).
  33. std::vector<PerimeterGeneratorLoop> children;
  34. PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour) :
  35. polygon(polygon), is_contour(is_contour), depth(depth), is_steep_overhang(false) {}
  36. PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour, bool is_steep_overhang) :
  37. polygon(polygon), is_contour(is_contour), depth(depth), is_steep_overhang(is_steep_overhang) {}
  38. // External perimeter. It may be CCW or CW oriented (outer contour or hole contour).
  39. bool is_external() const { return this->depth == 0; }
  40. // it's the last loop of the contour (not hol), so the first to be printed (if all goes well)
  41. bool is_internal_contour() const;
  42. };
  43. typedef std::vector<PerimeterGeneratorLoop> PerimeterGeneratorLoops;
  44. class PerimeterGenerator {
  45. public:
  46. // Inputs:
  47. const SurfaceCollection *slices;
  48. const ExPolygons *upper_slices;
  49. const ExPolygons *lower_slices;
  50. Layer *layer;
  51. Flow perimeter_flow;
  52. Flow ext_perimeter_flow;
  53. Flow overhang_flow;
  54. Flow solid_infill_flow;
  55. const PrintRegionConfig *config;
  56. const PrintObjectConfig *object_config;
  57. const PrintConfig *print_config;
  58. // Outputs:
  59. ExtrusionEntityCollection *loops;
  60. ExtrusionEntityCollection *gap_fill;
  61. SurfaceCollection *fill_surfaces;
  62. ExPolygons fill_no_overlap;
  63. PerimeterGenerator(
  64. // Input:
  65. const SurfaceCollection* slices,
  66. Flow flow,
  67. const PrintRegionConfig* config,
  68. const PrintObjectConfig* object_config,
  69. const PrintConfig* print_config,
  70. const bool spiral_vase,
  71. // Output:
  72. // Loops with the external thin walls
  73. ExtrusionEntityCollection* loops,
  74. // Gaps without the thin walls
  75. ExtrusionEntityCollection* gap_fill,
  76. // Infills without the gap fills
  77. SurfaceCollection* fill_surfaces)
  78. : slices(slices), lower_slices(nullptr), upper_slices(nullptr), layer(nullptr),
  79. perimeter_flow(flow), ext_perimeter_flow(flow),
  80. overhang_flow(flow), solid_infill_flow(flow),
  81. config(config), object_config(object_config), print_config(print_config),
  82. m_spiral_vase(spiral_vase),
  83. loops(loops), gap_fill(gap_fill), fill_surfaces(fill_surfaces),
  84. _ext_mm3_per_mm(-1), _mm3_per_mm(-1), _mm3_per_mm_overhang(-1)
  85. {};
  86. void process();
  87. private:
  88. bool m_spiral_vase;
  89. double _ext_mm3_per_mm;
  90. double _mm3_per_mm;
  91. double _mm3_per_mm_overhang;
  92. Polygons _lower_slices_bridge_flow_small;
  93. Polygons _lower_slices_bridge_flow_big;
  94. Polygons _lower_slices_bridge_speed_small;
  95. Polygons _lower_slices_bridge_speed_big;
  96. ExtrusionPaths create_overhangs(const Polyline& loop_polygons, ExtrusionRole role, bool is_external) const;
  97. // transform loops into ExtrusionEntityCollection, adding also thin walls into it.
  98. ExtrusionEntityCollection _traverse_loops(const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls) const;
  99. // try to merge thin walls to a current periemter exrusion or just add it to the end of the list.
  100. void _merge_thin_walls(ExtrusionEntityCollection &extrusions, ThickPolylines &thin_walls) const;
  101. // like _traverse_loops but with merging all periemter into one continuous loop
  102. ExtrusionLoop _traverse_and_join_loops(const PerimeterGeneratorLoop &loop, const PerimeterGeneratorLoops &childs, const Point entryPoint) const;
  103. // sub-function of _traverse_and_join_loops, transform a single loop as a cut extrusion to be merged with an other one.
  104. ExtrusionLoop _extrude_and_cut_loop(const PerimeterGeneratorLoop& loop, const Point entryPoint, const Line& direction = Line(Point(0, 0), Point(0, 0)), bool enforce_loop = false) const;
  105. // sub-function of _traverse_and_join_loops, find the good splot to cut a loop to be able to join it with an other one
  106. PerimeterIntersectionPoint _get_nearest_point(const PerimeterGeneratorLoops &children, ExtrusionLoop &myPolylines, const coord_t dist_cut, const coord_t max_dist) const;
  107. };
  108. }
  109. #endif