Welcome to mirror list, hosted at ThFree Co, Russian Federation.

SeamPlacer.hpp « GCode « libslic3r « src - github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d7b1cf0a78232d94fce0797ab6ec2abdde0755a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#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, coord_t layer_z, 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;
    coord_t m_layer_z;
};



class SeamPlacer {
public:
    void init(const Print& print);

    Point get_seam(const Layer& layer, 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;
    
    // if it's expected, we need to randomized at the external periemter.
    bool external_perimeters_first;

    // 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_