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

SupportTree.hpp « SLA « libslic3r « src - github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: acf6c10f5e8ed869e5766fab53e0841ad8b4c9e7 (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifndef SLA_SUPPORTTREE_HPP
#define SLA_SUPPORTTREE_HPP

#include <vector>
#include <memory>
#include <Eigen/Geometry>

#include <libslic3r/SLA/Common.hpp>
#include <libslic3r/SLA/Pad.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp>
#include <libslic3r/SLA/SupportPoint.hpp>
#include <libslic3r/SLA/JobController.hpp>

namespace Slic3r {

class TriangleMesh;
class Model;
class ModelInstance;
class ModelObject;
class Polygon;
class ExPolygon;

using Polygons = std::vector<Polygon>;
using ExPolygons = std::vector<ExPolygon>;

namespace sla {

enum class PillarConnectionMode
{
    zigzag,
    cross,
    dynamic
};

struct SupportConfig
{
    bool   enabled = true;
    
    // Radius in mm of the pointing side of the head.
    double head_front_radius_mm = 0.2;

    // How much the pinhead has to penetrate the model surface
    double head_penetration_mm = 0.5;

    // Radius of the back side of the 3d arrow.
    double head_back_radius_mm = 0.5;

    // Width in mm from the back sphere center to the front sphere center.
    double head_width_mm = 1.0;

    // How to connect pillars
    PillarConnectionMode pillar_connection_mode = PillarConnectionMode::dynamic;

    // Only generate pillars that can be routed to ground
    bool ground_facing_only = false;

    // TODO: unimplemented at the moment. This coefficient will have an impact
    // when bridges and pillars are merged. The resulting pillar should be a bit
    // thicker than the ones merging into it. How much thicker? I don't know
    // but it will be derived from this value.
    double pillar_widening_factor = 0.5;

    // Radius in mm of the pillar base.
    double base_radius_mm = 2.0;

    // The height of the pillar base cone in mm.
    double base_height_mm = 1.0;

    // The default angle for connecting support sticks and junctions.
    double bridge_slope = M_PI/4;

    // The max length of a bridge in mm
    double max_bridge_length_mm = 10.0;

    // The max distance of a pillar to pillar link.
    double max_pillar_link_distance_mm = 10.0;

    // The elevation in Z direction upwards. This is the space between the pad
    // and the model object's bounding box bottom.
    double object_elevation_mm = 10;
    
    // The shortest distance between a pillar base perimeter from the model
    // body. This is only useful when elevation is set to zero.
    double pillar_base_safety_distance_mm = 0.5;
    
    double head_fullwidth() const {
        return 2 * head_front_radius_mm + head_width_mm +
               2 * head_back_radius_mm - head_penetration_mm;
    }

    // /////////////////////////////////////////////////////////////////////////
    // Compile time configuration values (candidates for runtime)
    // /////////////////////////////////////////////////////////////////////////

    // The max Z angle for a normal at which it will get completely ignored.
    static const double normal_cutoff_angle;

    // The shortest distance of any support structure from the model surface
    static const double safety_distance_mm;

    static const double max_solo_pillar_height_mm;
    static const double max_dual_pillar_height_mm;
    static const double   optimizer_rel_score_diff;
    static const unsigned optimizer_max_iterations;
    static const unsigned pillar_cascade_neighbors;
    static const unsigned max_bridges_on_pillar;
};

enum class MeshType { Support, Pad };

struct SupportableMesh
{
    EigenMesh3D   emesh;
    SupportPoints pts;
    SupportConfig cfg;

    explicit SupportableMesh(const TriangleMesh & trmsh,
                             const SupportPoints &sp,
                             const SupportConfig &c)
        : emesh{trmsh}, pts{sp}, cfg{c}
    {}
    
    explicit SupportableMesh(const EigenMesh3D   &em,
                             const SupportPoints &sp,
                             const SupportConfig &c)
        : emesh{em}, pts{sp}, cfg{c}
    {}
};

/// The class containing mesh data for the generated supports.
class SupportTree
{
    JobController m_ctl;
public:
    using UPtr = std::unique_ptr<SupportTree>;
    
    static UPtr create(const SupportableMesh &input,
                       const JobController &ctl = {});

    virtual ~SupportTree() = default;

    virtual const TriangleMesh &retrieve_mesh(MeshType meshtype) const = 0;

    /// Adding the "pad" under the supports.
    /// modelbase will be used according to the embed_object flag in PoolConfig.
    /// If set, the plate will be interpreted as the model's intrinsic pad. 
    /// Otherwise, the modelbase will be unified with the base plate calculated
    /// from the supports.
    virtual const TriangleMesh &add_pad(const ExPolygons &modelbase,
                                        const PadConfig & pcfg) = 0;
    
    virtual void remove_pad() = 0;
    
    std::vector<ExPolygons> slice(const std::vector<float> &,
                                  float closing_radius) const;
    
    void retrieve_full_mesh(TriangleMesh &outmesh) const;
    
    const JobController &ctl() const { return m_ctl; }
};

}

}

#endif // SLASUPPORTTREE_HPP