diff options
Diffstat (limited to 'src/libslic3r/GCode/SeamPlacer.hpp')
-rw-r--r-- | src/libslic3r/GCode/SeamPlacer.hpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/libslic3r/GCode/SeamPlacer.hpp b/src/libslic3r/GCode/SeamPlacer.hpp new file mode 100644 index 000000000..0bae7af5a --- /dev/null +++ b/src/libslic3r/GCode/SeamPlacer.hpp @@ -0,0 +1,109 @@ +#ifndef libslic3r_SeamPlacer_hpp_ +#define libslic3r_SeamPlacer_hpp_ + +#include <optional> + +#include "libslic3r/Polygon.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/BoundingBox.hpp" +#include "libslic3r/AABBTreeIndirect.hpp" + +namespace Slic3r { + +class PrintObject; +class ExtrusionLoop; +class Print; +class Layer; +namespace EdgeGrid { class Grid; } + + +class SeamHistory { +public: + SeamHistory() { clear(); } + std::optional<Point> get_last_seam(const PrintObject* po, size_t layer_id, const BoundingBox& island_bb); + void add_seam(const PrintObject* po, const Point& pos, const BoundingBox& island_bb); + void clear(); + +private: + struct SeamPoint { + Point m_pos; + BoundingBox m_island_bb; + }; + + std::map<const PrintObject*, std::vector<SeamPoint>> m_data_last_layer; + std::map<const PrintObject*, std::vector<SeamPoint>> m_data_this_layer; + size_t m_layer_id; +}; + + + +class SeamPlacer { +public: + void init(const Print& print); + + Point get_seam(const Layer& layer, const SeamPosition seam_position, + const ExtrusionLoop& loop, Point last_pos, + coordf_t nozzle_diameter, const PrintObject* po, + bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid); + + using TreeType = AABBTreeIndirect::Tree<2, coord_t>; + using AlignedBoxType = Eigen::AlignedBox<TreeType::CoordType, TreeType::NumDimensions>; + +private: + + struct CustomTrianglesPerLayer { + Polygons polys; + TreeType tree; + }; + + // Just a cache to save some lookups. + const Layer* m_last_layer_po = nullptr; + coordf_t m_last_print_z = -1.; + const PrintObject* m_last_po = nullptr; + + bool m_last_loop_was_external = true; + + std::vector<std::vector<CustomTrianglesPerLayer>> m_enforcers; + std::vector<std::vector<CustomTrianglesPerLayer>> m_blockers; + std::vector<const PrintObject*> m_po_list; + + //std::map<const PrintObject*, Point> m_last_seam_position; + SeamHistory m_seam_history; + + // Get indices of points inside enforcers and blockers. + void get_enforcers_and_blockers(size_t layer_id, + const Polygon& polygon, + size_t po_id, + std::vector<size_t>& enforcers_idxs, + std::vector<size_t>& blockers_idxs) const; + + // Apply penalties to points inside enforcers/blockers. + void apply_custom_seam(const Polygon& polygon, size_t po_id, + std::vector<float>& penalties, + const std::vector<float>& lengths, + int layer_id, SeamPosition seam_position) const; + + // Return random point of a polygon. The distribution will be uniform + // along the contour and account for enforcers and blockers. + Point get_random_seam(size_t layer_idx, const Polygon& polygon, size_t po_id, + bool* saw_custom = nullptr) const; + + // Is there any enforcer/blocker on this layer? + bool is_custom_seam_on_layer(size_t layer_id, size_t po_idx) const { + return is_custom_enforcer_on_layer(layer_id, po_idx) + || is_custom_blocker_on_layer(layer_id, po_idx); + } + + bool is_custom_enforcer_on_layer(size_t layer_id, size_t po_idx) const { + return (! m_enforcers.at(po_idx).empty() && ! m_enforcers.at(po_idx)[layer_id].polys.empty()); + } + + bool is_custom_blocker_on_layer(size_t layer_id, size_t po_idx) const { + return (! m_blockers.at(po_idx).empty() && ! m_blockers.at(po_idx)[layer_id].polys.empty()); + } +}; + + +} + +#endif // libslic3r_SeamPlacer_hpp_ |