Couple more improvements / fixes:

- 'Tilt profiles' renamed to 'Profiles settings'
- Area fill and delay before/after exposure are now showed in Normal mode
- Fixed and refactored calculation of time estimates
- Changed '+ / -' to the respective unicode character
- Tolerance added into print statistics
This commit is contained in:
Lukas Matena 2024-05-20 11:53:22 +02:00
parent 9c365a9f91
commit 569a28c45e
6 changed files with 1232 additions and 117 deletions

View File

@ -3907,7 +3907,7 @@ void PrintConfigDef::init_sla_params()
"Otherwise 'Above area fill parameters are used."); "Otherwise 'Above area fill parameters are used.");
def->sidetext = L("%"); def->sidetext = L("%");
def->min = 0; def->min = 0;
def->mode = comExpert; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(35.)); def->set_default_value(new ConfigOptionFloat(35.));
def = this->add("relative_correction", coFloats); def = this->add("relative_correction", coFloats);
@ -4432,7 +4432,7 @@ void PrintConfigDef::init_sla_tilt_params()
def->sidetext = L("s"); def->sidetext = L("s");
def->min = 0; def->min = 0;
def->max = 30; def->max = 30;
def->mode = comExpert; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats({ 3., 3.})); def->set_default_value(new ConfigOptionFloats({ 3., 3.}));
def = this->add("delay_after_exposure", coFloats); def = this->add("delay_after_exposure", coFloats);
@ -4441,7 +4441,7 @@ void PrintConfigDef::init_sla_tilt_params()
def->sidetext = L("s"); def->sidetext = L("s");
def->min = 0; def->min = 0;
def->max = 30; def->max = 30;
def->mode = comExpert; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloats({ 0., 0.})); def->set_default_value(new ConfigOptionFloats({ 0., 0.}));
def = this->add("tower_hop_height", coInts); def = this->add("tower_hop_height", coInts);

View File

@ -406,6 +406,7 @@ struct SLAPrintStatistics
{ {
SLAPrintStatistics() { clear(); } SLAPrintStatistics() { clear(); }
double estimated_print_time; double estimated_print_time;
double estimated_print_time_tolerance;
double objects_used_material; double objects_used_material;
double support_used_material; double support_used_material;
size_t slow_layers_count; size_t slow_layers_count;
@ -424,6 +425,7 @@ struct SLAPrintStatistics
void clear() { void clear() {
estimated_print_time = 0.; estimated_print_time = 0.;
estimated_print_time_tolerance = 0.;
objects_used_material = 0.; objects_used_material = 0.;
support_used_material = 0.; support_used_material = 0.;
slow_layers_count = 0; slow_layers_count = 0;

View File

@ -1130,20 +1130,10 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
double supports_volume(0.0); double supports_volume(0.0);
double models_volume(0.0); double models_volume(0.0);
double estim_time(0.0); std::vector<std::tuple<double, double, bool, double, double>> layers_info; // time, area, is_fast, models_volume, supports_volume
std::vector<std::pair<coord_t, double>> layers_times; // level and time layers_info.resize(printer_input.size());
std::vector<std::pair<coord_t, double>> layers_areas; // level and area
layers_times.reserve(printer_input.size());
layers_areas.reserve(printer_input.size());
size_t slow_layers = 0;
size_t fast_layers = 0;
const double delta_fade_time = (init_exp_time - exp_time) / (fade_layers_cnt + 1); const double delta_fade_time = (init_exp_time - exp_time) / (fade_layers_cnt + 1);
double fade_layer_time = init_exp_time;
execution::SpinningMutex<ExecutionTBB> mutex;
using Lock = std::lock_guard<decltype(mutex)>;
// Going to parallel: // Going to parallel:
auto printlayerfn = [this, auto printlayerfn = [this,
@ -1151,8 +1141,7 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, hv_tilt, material_config, delta_fade_time, is_prusa_print, first_slow_layers, below, above, area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, hv_tilt, material_config, delta_fade_time, is_prusa_print, first_slow_layers, below, above,
// write vars // write vars
&mutex, &models_volume, &supports_volume, &estim_time, &slow_layers, &layers_info](size_t sliced_layer_cnt)
&fast_layers, &fade_layer_time, &layers_times, &layers_areas](size_t sliced_layer_cnt)
{ {
PrintLayer &layer = m_print->m_printer_input[sliced_layer_cnt]; PrintLayer &layer = m_print->m_printer_input[sliced_layer_cnt];
@ -1202,9 +1191,7 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
for (const ExPolygon& polygon : model_polygons) for (const ExPolygon& polygon : model_polygons)
layer_model_area += area(polygon); layer_model_area += area(polygon);
if (layer_model_area < 0 || layer_model_area > 0) { const double models_volume = (layer_model_area < 0 || layer_model_area > 0) ? layer_model_area * l_height : 0.;
Lock lck(mutex); models_volume += layer_model_area * l_height;
}
if(!supports_polygons.empty()) { if(!supports_polygons.empty()) {
if(model_polygons.empty()) supports_polygons = union_ex(supports_polygons); if(model_polygons.empty()) supports_polygons = union_ex(supports_polygons);
@ -1216,11 +1203,8 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
for (const ExPolygon& polygon : supports_polygons) for (const ExPolygon& polygon : supports_polygons)
layer_support_area += area(polygon); layer_support_area += area(polygon);
if (layer_support_area < 0 || layer_support_area > 0) { const double supports_volume = (layer_support_area < 0 || layer_support_area > 0) ? layer_support_area * l_height : 0.;
Lock lck(mutex); supports_volume += layer_support_area * l_height; const double layer_area = layer_model_area + layer_support_area;
}
double layer_area = layer_model_area + layer_support_area;
// Here we can save the expensively calculated polygons for printing // Here we can save the expensively calculated polygons for printing
ExPolygons trslices; ExPolygons trslices;
@ -1233,63 +1217,29 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
// Calculation of the printing time // Calculation of the printing time
// + Calculation of the slow and fast layers to the future controlling those values on FW // + Calculation of the slow and fast layers to the future controlling those values on FW
double layer_times = 0.0; double layer_times = 0.0;
bool is_fast_layer = false;
if (is_prusa_print) { if (is_prusa_print) {
const bool is_fast_layer = sliced_layer_cnt < first_slow_layers || layer_area <= display_area * area_fill; is_fast_layer = sliced_layer_cnt < first_slow_layers || layer_area <= display_area * area_fill;
{ Lock lck(mutex);
const int l_height_nm = 1000000 * l_height; const int l_height_nm = 1000000 * l_height;
if (is_fast_layer) { layer_times = layer_peel_move_time(l_height_nm, is_fast_layer ? below : above) +
fast_layers++; (is_fast_layer ? below : above).delay_before_exposure_ms +
layer_times = layer_peel_move_time(l_height_nm, below) + (is_fast_layer ? below : above).delay_after_exposure_ms +
below.delay_before_exposure_ms +
below.delay_after_exposure_ms +
refresh_delay_ms * 5 + // ~ 5x frame display wait refresh_delay_ms * 5 + // ~ 5x frame display wait
124; // Magical constant to compensate remaining computation delay in exposure thread 124; // Magical constant to compensate remaining computation delay in exposure thread
layer_times *= 0.001; // All before calculations are made in ms, but we need it in s
} }
else { else {
slow_layers++; is_fast_layer = layer_area <= display_area*area_fill;
layer_times = layer_peel_move_time(l_height_nm, above) +
above.delay_before_exposure_ms +
above.delay_after_exposure_ms +
refresh_delay_ms * 5 + // ~ 5x frame display wait
124; // Magical constant to compensate remaining computation delay in exposure thread
}
// All before calculations are made in ms, but we need it in s
layer_times *= 0.001;
layers_times.emplace_back(layer.level(), layer_times);
estim_time += layer_times;
layers_areas.emplace_back(layer.level(), layer_area * SCALING_FACTOR * SCALING_FACTOR);
}
}
else {
const bool is_fast_layer = layer_area <= display_area*area_fill;
const double tilt_time = material_config.material_print_speed == slamsSlow ? slow_tilt : const double tilt_time = material_config.material_print_speed == slamsSlow ? slow_tilt :
material_config.material_print_speed == slamsHighViscosity ? hv_tilt : material_config.material_print_speed == slamsHighViscosity ? hv_tilt :
is_fast_layer ? fast_tilt : slow_tilt; is_fast_layer ? fast_tilt : slow_tilt;
{ Lock lck(mutex);
if (is_fast_layer)
fast_layers++;
else
slow_layers++;
if (sliced_layer_cnt < 3)
layer_times += init_exp_time;
else if (fade_layer_time > exp_time) {
fade_layer_time -= delta_fade_time;
layer_times += fade_layer_time;
}
else
layer_times += exp_time;
layer_times += tilt_time; layer_times += tilt_time;
//// Per layer times (magical constants cuclulated from FW) //// Per layer times (magical constants cuclulated from FW)
static double exposure_safe_delay_before{ 3.0 }; static double exposure_safe_delay_before{ 3.0 };
static double exposure_high_viscosity_delay_before{ 3.5 }; static double exposure_high_viscosity_delay_before{ 3.5 };
static double exposure_slow_move_delay_before{ 1.0 }; static double exposure_slow_move_delay_before{ 1.0 };
@ -1306,13 +1256,13 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
l_height * 5 // tower move l_height * 5 // tower move
+ 120 / 1000 // Magical constant to compensate remaining computation delay in exposure thread + 120 / 1000 // Magical constant to compensate remaining computation delay in exposure thread
); );
layers_times.emplace_back(layer.level(), layer_times);
estim_time += layer_times;
layers_areas.emplace_back(layer.level(), layer_area * SCALING_FACTOR * SCALING_FACTOR);
} }
} // We are done with tilt time, but we haven't added the exposure time yet.
layer_times += std::max(exp_time, init_exp_time - sliced_layer_cnt * delta_fade_time);
// Collect values for this layer.
layers_info[sliced_layer_cnt] = std::make_tuple(layer_times, layer_area * SCALING_FACTOR * SCALING_FACTOR, is_fast_layer, models_volume, supports_volume);
}; };
// sequential version for debugging: // sequential version for debugging:
@ -1320,31 +1270,26 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
execution::for_each(ex_tbb, size_t(0), printer_input.size(), printlayerfn, execution::for_each(ex_tbb, size_t(0), printer_input.size(), printlayerfn,
execution::max_concurrency(ex_tbb)); execution::max_concurrency(ex_tbb));
auto SCALING2 = SCALING_FACTOR * SCALING_FACTOR; print_statistics.clear();
print_statistics.support_used_material = supports_volume * SCALING2;
print_statistics.objects_used_material = models_volume * SCALING2;
// Estimated printing time
// A layers count o the highest object
if (printer_input.size() == 0) if (printer_input.size() == 0)
print_statistics.estimated_print_time = NaNd; print_statistics.estimated_print_time = NaNd;
else { else {
print_statistics.estimated_print_time = estim_time; size_t i=0;
for (const auto& [time, area, is_fast, models_volume, supports_volume] : layers_info) {
// Times and areas vectors were filled in parallel, they need to be sorted first. print_statistics.fast_layers_count += int(is_fast);
// The print statistics will contain only the values (in the correct order). print_statistics.slow_layers_count += int(! is_fast);
std::sort(layers_times.begin(), layers_times.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
std::sort(layers_areas.begin(), layers_areas.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
print_statistics.layers_times_running_total.clear();
for (size_t i=0; i<layers_times.size(); ++i)
print_statistics.layers_times_running_total.emplace_back(layers_times[i].second + (i==0 ? 0. : print_statistics.layers_times_running_total[i-1]));
print_statistics.layers_areas.clear();
for (const auto& [level, area] : layers_areas)
print_statistics.layers_areas.emplace_back(area); print_statistics.layers_areas.emplace_back(area);
print_statistics.estimated_print_time += time;
print_statistics.layers_times_running_total.emplace_back(time + (i==0 ? 0. : print_statistics.layers_times_running_total[i-1]));
print_statistics.objects_used_material += models_volume * SCALING_FACTOR * SCALING_FACTOR;
print_statistics.support_used_material += supports_volume * SCALING_FACTOR * SCALING_FACTOR;
++i;
}
if (is_prusa_print)
// For our SLA printers, we add an error of the estimate:
print_statistics.estimated_print_time_tolerance = 0.03 * print_statistics.estimated_print_time;
} }
print_statistics.fast_layers_count = fast_layers;
print_statistics.slow_layers_count = slow_layers;
report_status(-2, "", SlicingStatus::RELOAD_SLA_PREVIEW); report_status(-2, "", SlicingStatus::RELOAD_SLA_PREVIEW);
} }

View File

@ -1455,7 +1455,12 @@ void Sidebar::update_sliced_info_sizer()
} }
p->sliced_info->SetTextAndShow(siCost, str_total_cost, "Cost"); p->sliced_info->SetTextAndShow(siCost, str_total_cost, "Cost");
wxString t_est = std::isnan(ps.estimated_print_time) ? "N/A" : from_u8(short_time_ui(get_time_dhms(float(ps.estimated_print_time)))); wxString t_est = "N/A";
if (! std::isnan(ps.estimated_print_time)) {
t_est = from_u8(short_time_ui(get_time_dhms(float(ps.estimated_print_time))));
if (ps.estimated_print_time_tolerance > 0.)
t_est += from_u8(" \u00B1 ") + from_u8(short_time_ui(get_time_dhms(float(ps.estimated_print_time_tolerance))));
}
p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _L("Estimated printing time") + ":"); p->sliced_info->SetTextAndShow(siEstimatedTime, t_est, _L("Estimated printing time") + ":");
p->plater->get_notification_manager()->set_slicing_complete_print_time(_u8L("Estimated printing time") + ": " + boost::nowide::narrow(t_est), p->plater->is_sidebar_collapsed()); p->plater->get_notification_manager()->set_slicing_complete_print_time(_u8L("Estimated printing time") + ": " + boost::nowide::narrow(t_est), p->plater->is_sidebar_collapsed());

1163
src/slic3r/GUI/Sidebar.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5456,12 +5456,12 @@ void TabSLAMaterial::build_tilt_group(Slic3r::GUI::PageShp page)
{ {
// Legend // Legend
std::vector<std::pair<std::string, std::string>> legend_columns = { std::vector<std::pair<std::string, std::string>> legend_columns = {
{L("Below"), L("Values in this column are for ???")}, {L("Below"), L("Values in this column are applied when layer area is smaller than area_fill.")},
{L("Above"), L("Values in this column are for ???")}, {L("Above"), L("Values in this column are applied when layer area is larger than area_fill.")},
}; };
create_legend(page, legend_columns, comExpert/*, true*/); create_legend(page, legend_columns, comExpert/*, true*/);
auto optgroup = page->new_optgroup(L("Tilt profiles")); auto optgroup = page->new_optgroup(L("Profile settings"));
optgroup->m_on_change = [this, optgroup](const t_config_option_key& key, boost::any value) optgroup->m_on_change = [this, optgroup](const t_config_option_key& key, boost::any value)
{ {
if (key.find_first_of("use_tilt") == 0) if (key.find_first_of("use_tilt") == 0)
@ -5525,7 +5525,7 @@ void TabSLAMaterial::toggle_tilt_options(bool is_above)
if (m_active_page && m_active_page->title() == "Material printing profile") if (m_active_page && m_active_page->title() == "Material printing profile")
{ {
int column_id = is_above ? 0 : 1; int column_id = is_above ? 0 : 1;
auto optgroup = m_active_page->get_optgroup("Tilt profiles"); auto optgroup = m_active_page->get_optgroup("Profile settings");
bool use_tilt = boost::any_cast<bool>(optgroup->get_config_value(*m_config, "use_tilt", column_id)); bool use_tilt = boost::any_cast<bool>(optgroup->get_config_value(*m_config, "use_tilt", column_id));
for (const std::string& opt_key : disable_tilt_options) { for (const std::string& opt_key : disable_tilt_options) {
@ -5564,11 +5564,11 @@ void TabSLAMaterial::update()
void TabSLAMaterial::update_sla_prusa_specific_visibility() void TabSLAMaterial::update_sla_prusa_specific_visibility()
{ {
if (m_active_page && m_active_page->title() == "Material printing profile") { if (m_active_page && m_active_page->title() == "Material printing profile") {
for (auto& title : { "", "Tilt profiles" }) { for (auto& title : { "", "Profile settings" }) {
auto og_it = std::find_if(m_active_page->m_optgroups.begin(), m_active_page->m_optgroups.end(), auto og_it = std::find_if(m_active_page->m_optgroups.begin(), m_active_page->m_optgroups.end(),
[title](const ConfigOptionsGroupShp og) { return og->title == title; }); [title](const ConfigOptionsGroupShp og) { return og->title == title; });
if (og_it != m_active_page->m_optgroups.end()) if (og_it != m_active_page->m_optgroups.end())
og_it->get()->Show(m_mode == comExpert && is_prusa_printer()); og_it->get()->Show(m_mode >= comAdvanced && is_prusa_printer());
} }
auto og_it = std::find_if(m_active_page->m_optgroups.begin(), m_active_page->m_optgroups.end(), auto og_it = std::find_if(m_active_page->m_optgroups.begin(), m_active_page->m_optgroups.end(),