Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_plater_thumbnail

This commit is contained in:
Enrico Turri 2019-11-05 13:58:13 +01:00
commit d8dca69d60
7 changed files with 201 additions and 9 deletions

View file

@ -267,6 +267,99 @@ static inline void smooth_compensation(std::vector<float> &compensation, float s
}
}
template<typename INDEX_TYPE, typename CONTAINER>
static inline INDEX_TYPE prev_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container)
{
if (idx == 0)
idx = INDEX_TYPE(container.size());
return -- idx;
}
template<typename INDEX_TYPE, typename CONTAINER>
static inline INDEX_TYPE next_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container)
{
if (++ idx == INDEX_TYPE(container.size()))
idx = 0;
return idx;
}
template<class T, class U = T>
static inline T exchange(T& obj, U&& new_value)
{
T old_value = std::move(obj);
obj = std::forward<U>(new_value);
return old_value;
}
static inline void smooth_compensation_banded(const Points &contour, float band, std::vector<float> &compensation, float strength, size_t num_iterations)
{
assert(contour.size() == compensation.size());
assert(contour.size() > 2);
std::vector<float> out(compensation);
float dist_min2 = band * band;
static constexpr bool use_min = false;
for (size_t iter = 0; iter < num_iterations; ++ iter) {
for (int i = 0; i < int(compensation.size()); ++ i) {
const Vec2f pthis = contour[i].cast<float>();
int j = prev_idx_cyclic(i, contour);
Vec2f pprev = contour[j].cast<float>();
float prev = compensation[j];
float l2 = (pthis - pprev).squaredNorm();
if (l2 < dist_min2) {
float l = sqrt(l2);
int jprev = exchange(j, prev_idx_cyclic(j, contour));
while (j != i) {
const Vec2f pp = contour[j].cast<float>();
const float lthis = (pp - pprev).norm();
const float lnext = l + lthis;
if (lnext > band) {
// Interpolate the compensation value.
prev = use_min ?
std::min(prev, lerp(compensation[jprev], compensation[j], (band - l) / lthis)) :
lerp(compensation[jprev], compensation[j], (band - l) / lthis);
break;
}
prev = use_min ? std::min(prev, compensation[j]) : compensation[j];
pprev = pp;
l = lnext;
jprev = exchange(j, prev_idx_cyclic(j, contour));
}
}
j = next_idx_cyclic(i, contour);
pprev = contour[j].cast<float>();
float next = compensation[j];
l2 = (pprev - pthis).squaredNorm();
if (l2 < dist_min2) {
float l = sqrt(l2);
int jprev = exchange(j, next_idx_cyclic(j, contour));
while (j != i) {
const Vec2f pp = contour[j].cast<float>();
const float lthis = (pp - pprev).norm();
const float lnext = l + lthis;
if (lnext > band) {
// Interpolate the compensation value.
next = use_min ?
std::min(next, lerp(compensation[jprev], compensation[j], (band - l) / lthis)) :
lerp(compensation[jprev], compensation[j], (band - l) / lthis);
break;
}
next = use_min ? std::min(next, compensation[j]) : compensation[j];
pprev = pp;
l = lnext;
jprev = exchange(j, next_idx_cyclic(j, contour));
}
}
float laplacian = compensation[i] * (1.f - strength) + 0.5f * strength * (prev + next);
// Compensations are negative. Only apply the laplacian if it leads to lower compensation.
out[i] = std::max(laplacian, compensation[i]);
}
out.swap(compensation);
}
}
ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow &external_perimeter_flow, const double compensation)
{
// The contour shall be wide enough to apply the external perimeter plus compensation on both sides.
@ -285,10 +378,11 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow &
std::vector<std::vector<float>> deltas;
deltas.reserve(simplified.holes.size() + 1);
ExPolygon resampled(simplified);
double resample_interval = scale_(0.5);
for (size_t idx_contour = 0; idx_contour <= simplified.holes.size(); ++ idx_contour) {
Polygon &poly = (idx_contour == 0) ? resampled.contour : resampled.holes[idx_contour - 1];
std::vector<ResampledPoint> resampled_point_parameters;
poly.points = resample_polygon(poly.points, scale_(0.5), resampled_point_parameters);
poly.points = resample_polygon(poly.points, resample_interval, resampled_point_parameters);
std::vector<float> dists = contour_distance(grid, idx_contour, poly.points, resampled_point_parameters, search_radius);
for (float &d : dists) {
// printf("Point %d, Distance: %lf\n", int(&d - dists.data()), unscale<double>(d));
@ -301,7 +395,8 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow &
d = - (d - float(min_contour_width)) / 2.f;
assert(d >= - float(scaled_compensation) && d <= 0.f);
}
smooth_compensation(dists, 0.4f, 10);
// smooth_compensation(dists, 0.4f, 10);
smooth_compensation_banded(poly.points, float(0.8 * resample_interval), dists, 0.3f, 3);
deltas.emplace_back(dists);
}

View file

@ -1068,6 +1068,9 @@ void GCode::_do_export(Print &print, FILE *file)
_writeln(file, GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag);
}
// Hold total number of print toolchanges. Check for negative toolchanges (single extruder mode) and set to 0 (no tool change).
int total_toolchanges = std::max(0, print.wipe_tower_data().number_of_toolchanges);
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
m_placeholder_parser = print.placeholder_parser();
m_placeholder_parser.update_timestamp();
@ -1130,6 +1133,7 @@ void GCode::_do_export(Print &print, FILE *file)
// For the start / end G-code to do the priming and final filament pull in case there is no wipe tower provided.
m_placeholder_parser.set("has_wipe_tower", has_wipe_tower);
m_placeholder_parser.set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
m_placeholder_parser.set("total_toolchanges", total_toolchanges);
std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id);
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);
@ -1380,7 +1384,7 @@ void GCode::_do_export(Print &print, FILE *file)
print.m_print_statistics.estimated_normal_color_print_times = m_normal_time_estimator.get_color_times_dhms(true);
if (m_silent_time_estimator_enabled)
print.m_print_statistics.estimated_silent_color_print_times = m_silent_time_estimator.get_color_times_dhms(true);
print.m_print_statistics.total_toolchanges = total_toolchanges;
std::vector<Extruder> extruders = m_writer.extruders();
if (! extruders.empty()) {
std::pair<std::string, unsigned int> out_filament_used_mm ("; filament used [mm] = ", 0);
@ -1430,6 +1434,8 @@ void GCode::_do_export(Print &print, FILE *file)
}
_write_format(file, "; total filament used [g] = %.1lf\n", print.m_print_statistics.total_weight);
_write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost);
if (print.m_print_statistics.total_toolchanges > 0)
_write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
_write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str());
if (m_silent_time_estimator_enabled)
_write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str());

View file

@ -2064,6 +2064,7 @@ DynamicConfig PrintStatistics::config() const
config.set_key_value("used_filament", new ConfigOptionFloat (this->total_used_filament / 1000.));
config.set_key_value("extruded_volume", new ConfigOptionFloat (this->total_extruded_volume));
config.set_key_value("total_cost", new ConfigOptionFloat (this->total_cost));
config.set_key_value("total_toolchanges", new ConfigOptionInt(this->total_toolchanges));
config.set_key_value("total_weight", new ConfigOptionFloat (this->total_weight));
config.set_key_value("total_wipe_tower_cost", new ConfigOptionFloat (this->total_wipe_tower_cost));
config.set_key_value("total_wipe_tower_filament", new ConfigOptionFloat (this->total_wipe_tower_filament));
@ -2076,7 +2077,7 @@ DynamicConfig PrintStatistics::placeholders()
for (const std::string &key : {
"print_time", "normal_print_time", "silent_print_time",
"used_filament", "extruded_volume", "total_cost", "total_weight",
"total_wipe_tower_cost", "total_wipe_tower_filament"})
"total_toolchanges", "total_wipe_tower_cost", "total_wipe_tower_filament"})
config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}"));
return config;
}

View file

@ -253,6 +253,7 @@ struct PrintStatistics
double total_used_filament;
double total_extruded_volume;
double total_cost;
int total_toolchanges;
double total_weight;
double total_wipe_tower_cost;
double total_wipe_tower_filament;
@ -273,6 +274,7 @@ struct PrintStatistics
total_used_filament = 0.;
total_extruded_volume = 0.;
total_cost = 0.;
total_toolchanges = 0;
total_weight = 0.;
total_wipe_tower_cost = 0.;
total_wipe_tower_filament = 0.;