1 // Based on implementation by @platsch
2
3 #ifndef slic3r_Slicing_hpp_
4 #define slic3r_Slicing_hpp_
5
6 #include <cstring>
7 #include <map>
8 #include <set>
9 #include <type_traits>
10 #include <vector>
11
12 #include "libslic3r.h"
13 #include "Utils.hpp"
14
15 namespace Slic3r
16 {
17
18 class PrintConfig;
19 class PrintObjectConfig;
20 class ModelConfig;
21 class ModelObject;
22 class DynamicPrintConfig;
23
24 // Parameters to guide object slicing and support generation.
25 // The slicing parameters account for a raft and whether the 1st object layer is printed with a normal or a bridging flow
26 // (using a normal flow over a soluble support, using a bridging flow over a non-soluble support).
27 struct SlicingParameters
28 {
SlicingParametersSlic3r::SlicingParameters29 SlicingParameters() { memset(this, 0, sizeof(SlicingParameters)); }
30
31 static SlicingParameters create_from_config(
32 const PrintConfig &print_config,
33 const PrintObjectConfig &object_config,
34 coordf_t object_height,
35 const std::vector<unsigned int> &object_extruders);
36
37 // Has any raft layers?
has_raftSlic3r::SlicingParameters38 bool has_raft() const { return raft_layers() > 0; }
raft_layersSlic3r::SlicingParameters39 size_t raft_layers() const { return base_raft_layers + interface_raft_layers; }
40
41 // Is the 1st object layer height fixed, or could it be varied?
first_object_layer_height_fixedSlic3r::SlicingParameters42 bool first_object_layer_height_fixed() const { return ! has_raft() || first_object_layer_bridging; }
43
44 // Height of the object to be printed. This value does not contain the raft height.
object_print_z_heightSlic3r::SlicingParameters45 coordf_t object_print_z_height() const { return object_print_z_max - object_print_z_min; }
46
47 bool valid;
48
49 // Number of raft layers.
50 size_t base_raft_layers;
51 // Number of interface layers including the contact layer.
52 size_t interface_raft_layers;
53
54 // Layer heights of the raft (base, interface and a contact layer).
55 coordf_t base_raft_layer_height;
56 coordf_t interface_raft_layer_height;
57 coordf_t contact_raft_layer_height;
58 bool contact_raft_layer_height_bridging;
59
60 // The regular layer height, applied for all but the first layer, if not overridden by layer ranges
61 // or by the variable layer thickness table.
62 coordf_t layer_height;
63 // Minimum / maximum layer height, to be used for the automatic adaptive layer height algorithm,
64 // or by an interactive layer height editor.
65 coordf_t min_layer_height;
66 coordf_t max_layer_height;
67 coordf_t max_suport_layer_height;
68
69 // First layer height of the print, this may be used for the first layer of the raft
70 // or for the first layer of the print.
71 coordf_t first_print_layer_height;
72
73 // Thickness of the first layer. This is either the first print layer thickness if printed without a raft,
74 // or a bridging flow thickness if printed over a non-soluble raft,
75 // or a normal layer height if printed over a soluble raft.
76 coordf_t first_object_layer_height;
77
78 // If the object is printed over a non-soluble raft, the first layer may be printed with a briding flow.
79 bool first_object_layer_bridging;
80
81 // Soluble interface? (PLA soluble in water, HIPS soluble in lemonen)
82 // otherwise the interface must be broken off.
83 bool soluble_interface;
84 // Gap when placing object over raft.
85 coordf_t gap_raft_object;
86 // Gap when placing support over object.
87 coordf_t gap_object_support;
88 // Gap when placing object over support.
89 coordf_t gap_support_object;
90
91 // Bottom and top of the printed object.
92 // If printed without a raft, object_print_z_min = 0 and object_print_z_max = object height.
93 // Otherwise object_print_z_min is equal to the raft height.
94 coordf_t raft_base_top_z;
95 coordf_t raft_interface_top_z;
96 coordf_t raft_contact_top_z;
97 // In case of a soluble interface, object_print_z_min == raft_contact_top_z, otherwise there is a gap between the raft and the 1st object layer.
98 coordf_t object_print_z_min;
99 coordf_t object_print_z_max;
100 };
101 static_assert(IsTriviallyCopyable<SlicingParameters>::value, "SlicingParameters class is not POD (and it should be - see constructor).");
102
103 // The two slicing parameters lead to the same layering as long as the variable layer thickness is not in action.
equal_layering(const SlicingParameters & sp1,const SlicingParameters & sp2)104 inline bool equal_layering(const SlicingParameters &sp1, const SlicingParameters &sp2)
105 {
106 assert(sp1.valid);
107 assert(sp2.valid);
108 return sp1.base_raft_layers == sp2.base_raft_layers &&
109 sp1.interface_raft_layers == sp2.interface_raft_layers &&
110 sp1.base_raft_layer_height == sp2.base_raft_layer_height &&
111 sp1.interface_raft_layer_height == sp2.interface_raft_layer_height &&
112 sp1.contact_raft_layer_height == sp2.contact_raft_layer_height &&
113 sp1.contact_raft_layer_height_bridging == sp2.contact_raft_layer_height_bridging &&
114 sp1.layer_height == sp2.layer_height &&
115 sp1.min_layer_height == sp2.min_layer_height &&
116 sp1.max_layer_height == sp2.max_layer_height &&
117 // sp1.max_suport_layer_height == sp2.max_suport_layer_height &&
118 sp1.first_print_layer_height == sp2.first_print_layer_height &&
119 sp1.first_object_layer_height == sp2.first_object_layer_height &&
120 sp1.first_object_layer_bridging == sp2.first_object_layer_bridging &&
121 sp1.soluble_interface == sp2.soluble_interface &&
122 sp1.gap_raft_object == sp2.gap_raft_object &&
123 sp1.gap_object_support == sp2.gap_object_support &&
124 sp1.gap_support_object == sp2.gap_support_object &&
125 sp1.raft_base_top_z == sp2.raft_base_top_z &&
126 sp1.raft_interface_top_z == sp2.raft_interface_top_z &&
127 sp1.raft_contact_top_z == sp2.raft_contact_top_z &&
128 sp1.object_print_z_min == sp2.object_print_z_min;
129 }
130
131 typedef std::pair<coordf_t,coordf_t> t_layer_height_range;
132 typedef std::map<t_layer_height_range, ModelConfig> t_layer_config_ranges;
133
134 extern std::vector<coordf_t> layer_height_profile_from_ranges(
135 const SlicingParameters &slicing_params,
136 const t_layer_config_ranges &layer_config_ranges);
137
138 extern std::vector<double> layer_height_profile_adaptive(
139 const SlicingParameters& slicing_params,
140 const ModelObject& object, float quality_factor);
141
142 struct HeightProfileSmoothingParams
143 {
144 unsigned int radius;
145 bool keep_min;
146
HeightProfileSmoothingParamsSlic3r::HeightProfileSmoothingParams147 HeightProfileSmoothingParams() : radius(5), keep_min(false) {}
HeightProfileSmoothingParamsSlic3r::HeightProfileSmoothingParams148 HeightProfileSmoothingParams(unsigned int radius, bool keep_min) : radius(radius), keep_min(keep_min) {}
149 };
150
151 extern std::vector<double> smooth_height_profile(
152 const std::vector<double>& profile, const SlicingParameters& slicing_params,
153 const HeightProfileSmoothingParams& smoothing_params);
154
155 enum LayerHeightEditActionType : unsigned int {
156 LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0,
157 LAYER_HEIGHT_EDIT_ACTION_DECREASE = 1,
158 LAYER_HEIGHT_EDIT_ACTION_REDUCE = 2,
159 LAYER_HEIGHT_EDIT_ACTION_SMOOTH = 3
160 };
161
162 extern void adjust_layer_height_profile(
163 const SlicingParameters &slicing_params,
164 std::vector<coordf_t> &layer_height_profile,
165 coordf_t z,
166 coordf_t layer_thickness_delta,
167 coordf_t band_width,
168 LayerHeightEditActionType action);
169
170 // Produce object layers as pairs of low / high layer boundaries, stored into a linear vector.
171 // The object layers are based at z=0, ignoring the raft layers.
172 extern std::vector<coordf_t> generate_object_layers(
173 const SlicingParameters &slicing_params,
174 const std::vector<coordf_t> &layer_height_profile);
175
176 // Produce a 1D texture packed into a 2D texture describing in the RGBA format
177 // the planned object layers.
178 // Returns number of cells used by the texture of the 0th LOD level.
179 extern int generate_layer_height_texture(
180 const SlicingParameters &slicing_params,
181 const std::vector<coordf_t> &layers,
182 void *data, int rows, int cols, bool level_of_detail_2nd_level);
183
184 namespace Slicing {
185 // Minimum layer height for the variable layer height algorithm. Nozzle index is 1 based.
186 coordf_t min_layer_height_from_nozzle(const DynamicPrintConfig &print_config, int idx_nozzle);
187
188 // Maximum layer height for the variable layer height algorithm, 3/4 of a nozzle dimaeter by default,
189 // it should not be smaller than the minimum layer height.
190 // Nozzle index is 1 based.
191 coordf_t max_layer_height_from_nozzle(const DynamicPrintConfig &print_config, int idx_nozzle);
192 } // namespace Slicing
193
194 } // namespace Slic3r
195
196 namespace cereal
197 {
serialize(Archive & archive,Slic3r::t_layer_height_range & lhr)198 template<class Archive> void serialize(Archive& archive, Slic3r::t_layer_height_range &lhr) { archive(lhr.first, lhr.second); }
199 }
200
201 #endif /* slic3r_Slicing_hpp_ */
202