Implemented estimated printing time for the SLA printing

This commit is contained in:
YuSanka 2019-02-12 16:34:42 +01:00
parent f0cee79170
commit c04be58648
5 changed files with 196 additions and 2 deletions

View file

@ -1863,7 +1863,7 @@ std::string Print::output_filename() const
DynamicConfig config = this->finished() ? this->print_statistics().config() : this->print_statistics().placeholders();
return this->PrintBase::output_filename(m_config.output_filename_format.value, "gcode", &config);
}
/*
// Shorten the dhms time by removing the seconds, rounding the dhm to full minutes
// and removing spaces.
static std::string short_time(const std::string &time)
@ -1903,7 +1903,7 @@ static std::string short_time(const std::string &time)
::sprintf(buffer, "%ds", seconds);
return buffer;
}
*/
DynamicConfig PrintStatistics::config() const
{
DynamicConfig config;

View file

@ -966,6 +966,9 @@ void SLAPrint::process()
st += unsigned(PRINT_STEP_LEVELS[currentstep] * pstd);
}
// Fill statistics
fill_statistics();
// If everything vent well
report_status(*this, 100, L("Slicing done"));
}
@ -1027,6 +1030,46 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector<t_config_opt
return invalidated;
}
void SLAPrint::fill_statistics()
{
int max_layers_cnt = 0;
for (SLAPrintObject * po : m_objects) {
if (max_layers_cnt < po->get_slice_index().size())
max_layers_cnt = po->get_slice_index().size();
}
if (max_layers_cnt == 0)
return;
float init_exp_time = m_material_config.initial_exposure_time.getFloat();//35;
float exp_time = m_material_config.exposure_time.getFloat();//8;
// TODO : fade_layers_cnt should be filled in the future
// This variable will be a part of the print(material) preset
const int fade_layers_cnt = 10; // [3;20]
// TODO : tilt_delay_before_time & tilt_delay_after_time should be filled in the future
// These values are received from the printer after a printing start
const float tilt_delay_before_time = 0.0;
const float tilt_delay_after_time = 0.0;
if (tilt_delay_before_time + tilt_delay_after_time > 0.0)
{
init_exp_time += tilt_delay_before_time + tilt_delay_after_time;
exp_time += tilt_delay_before_time + tilt_delay_after_time;
}
float estim_time = init_exp_time * 3 + exp_time * (max_layers_cnt - 3 - fade_layers_cnt);
const float delta_time = (init_exp_time - exp_time) / (fade_layers_cnt+1);
double fade_layer_time = init_exp_time;
while (fade_layer_time > exp_time)
{
fade_layer_time -= delta_time;
estim_time += fade_layer_time;
}
m_print_statistics.estimated_print_time = get_time_dhms(estim_time);
}
// Returns true if an object step is done on all objects and there's at least one object.
bool SLAPrint::is_step_done(SLAPrintObjectStep step) const
{
@ -1257,4 +1300,41 @@ std::vector<Vec3d> SLAPrintObject::transformed_support_points() const
return ret;
}
DynamicConfig SLAPrintStatistics::config() const
{
DynamicConfig config;
const std::string print_time = Slic3r::short_time(this->estimated_print_time);
config.set_key_value("print_time", new ConfigOptionString(print_time));
config.set_key_value("used_material", new ConfigOptionFloat(this->total_used_material/* / 1000.*/));
config.set_key_value("total_cost", new ConfigOptionFloat(this->total_cost));
config.set_key_value("total_weight", new ConfigOptionFloat(this->total_weight));
return config;
}
DynamicConfig SLAPrintStatistics::placeholders()
{
DynamicConfig config;
for (const std::string &key : {
"print_time", "used_material", "total_cost", "total_weight" })
config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}"));
return config;
}
std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in) const
{
std::string final_path;
try {
boost::filesystem::path path(path_in);
DynamicConfig cfg = this->config();
PlaceholderParser pp;
std::string new_stem = pp.process(path.stem().string(), 0, &cfg);
final_path = (path.parent_path() / (new_stem + path.extension().string())).string();
}
catch (const std::exception &ex) {
BOOST_LOG_TRIVIAL(error) << "Failed to apply the print statistics to the export file name: " << ex.what();
final_path = path_in;
}
return final_path;
}
} // namespace Slic3r

View file

@ -171,6 +171,29 @@ using PrintObjects = std::vector<SLAPrintObject*>;
class TriangleMesh;
struct SLAPrintStatistics
{
SLAPrintStatistics() { clear(); }
std::string estimated_print_time;
double total_used_material;
double total_cost;
double total_weight;
// Config with the filled in print statistics.
DynamicConfig config() const;
// Config with the statistics keys populated with placeholder strings.
static DynamicConfig placeholders();
// Replace the print statistics placeholders in the path.
std::string finalize_output_path(const std::string &path_in) const;
void clear() {
estimated_print_time.clear();
total_used_material = 0.;
total_cost = 0.;
total_weight = 0.;
}
};
/**
* @brief This class is the high level FSM for the SLA printing process.
*
@ -208,6 +231,8 @@ public:
std::string output_filename() const override
{ return this->PrintBase::output_filename(m_print_config.output_filename_format.value, "zip"); }
const SLAPrintStatistics& print_statistics() const { return m_print_statistics; }
private:
using SLAPrinter = FilePrinter<FilePrinterFormat::SLA_PNGZIP>;
using SLAPrinterPtr = std::unique_ptr<SLAPrinter>;
@ -215,6 +240,8 @@ private:
// Invalidate steps based on a set of parameters changed.
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
void fill_statistics();
SLAPrintConfig m_print_config;
SLAPrinterConfig m_printer_config;
SLAMaterialConfig m_material_config;
@ -246,6 +273,9 @@ private:
// The printer itself
SLAPrinterPtr m_printer;
// Estimated print time, material consumed.
SLAPrintStatistics m_print_statistics;
friend SLAPrintObject;
};

View file

@ -206,6 +206,69 @@ public:
void reset() { closure = Closure(); }
};
// Shorten the dhms time by removing the seconds, rounding the dhm to full minutes
// and removing spaces.
static std::string short_time(const std::string &time)
{
// Parse the dhms time format.
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
if (time.find('d') != std::string::npos)
::sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds);
else if (time.find('h') != std::string::npos)
::sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds);
else if (time.find('m') != std::string::npos)
::sscanf(time.c_str(), "%dm %ds", &minutes, &seconds);
else if (time.find('s') != std::string::npos)
::sscanf(time.c_str(), "%ds", &seconds);
// Round to full minutes.
if (days + hours + minutes > 0 && seconds >= 30) {
if (++minutes == 60) {
minutes = 0;
if (++hours == 24) {
hours = 0;
++days;
}
}
}
// Format the dhm time.
char buffer[64];
if (days > 0)
::sprintf(buffer, "%dd%dh%dm", days, hours, minutes);
else if (hours > 0)
::sprintf(buffer, "%dh%dm", hours, minutes);
else if (minutes > 0)
::sprintf(buffer, "%dm", minutes);
else
::sprintf(buffer, "%ds", seconds);
return buffer;
}
// Returns the given time is seconds in format DDd HHh MMm SSs
static std::string get_time_dhms(float time_in_secs)
{
int days = (int)(time_in_secs / 86400.0f);
time_in_secs -= (float)days * 86400.0f;
int hours = (int)(time_in_secs / 3600.0f);
time_in_secs -= (float)hours * 3600.0f;
int minutes = (int)(time_in_secs / 60.0f);
time_in_secs -= (float)minutes * 60.0f;
char buffer[64];
if (days > 0)
::sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs);
else if (hours > 0)
::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs);
else if (minutes > 0)
::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs);
else
::sprintf(buffer, "%ds", (int)time_in_secs);
return buffer;
}
} // namespace Slic3r
#if WIN32

View file

@ -153,6 +153,7 @@ enum SlisedInfoIdx
siFilament_m,
siFilament_mm3,
siFilament_g,
siMateril_unit,
siCost,
siEstimatedTime,
siWTNumbetOfToolchanges,
@ -193,6 +194,7 @@ SlicedInfo::SlicedInfo(wxWindow *parent) :
init_info_label(_(L("Used Filament (m)")));
init_info_label(_(L("Used Filament (mm³)")));
init_info_label(_(L("Used Filament (g)")));
init_info_label(_(L("Used Material (unit)")));
init_info_label(_(L("Cost")));
init_info_label(_(L("Estimated printing time")));
init_info_label(_(L("Number of tool changes")));
@ -817,6 +819,21 @@ void Sidebar::show_sliced_info_sizer(const bool show)
p->sliced_info->Show(show);
if (show) {
if (p->plater->printer_technology() == ptSLA)
{
const SLAPrintStatistics& ps = p->plater->sla_print().print_statistics();
p->sliced_info->SetTextAndShow(siMateril_unit, wxString::Format("%.2f", ps.total_used_material));
p->sliced_info->SetTextAndShow(siCost, wxString::Format("%.2f", ps.total_cost));
p->sliced_info->SetTextAndShow(siEstimatedTime, ps.estimated_print_time, _(L("Estimated printing time")) + " :");
// Hide non-SLA sliced info parameters
p->sliced_info->SetTextAndShow(siFilament_m, "N/A");
p->sliced_info->SetTextAndShow(siFilament_mm3, "N/A");
p->sliced_info->SetTextAndShow(siFilament_g, "N/A");
p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, "N/A");
}
else
{
const PrintStatistics& ps = p->plater->fff_print().print_statistics();
const bool is_wipe_tower = ps.total_wipe_tower_filament > 0;
@ -864,6 +881,10 @@ void Sidebar::show_sliced_info_sizer(const bool show)
// if there is a wipe tower, insert number of toolchanges info into the array:
p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", p->plater->fff_print().wipe_tower_data().number_of_toolchanges) : "N/A");
// Hide non-FFF sliced info parameters
p->sliced_info->SetTextAndShow(siMateril_unit, "N/A");
}
}
Layout();