forked from prusa3d/PrusaSlicer
-
Notifications
You must be signed in to change notification settings - Fork 0
Ch. 5 ‐ Print Statistics
Alex Petsiuk edited this page Aug 19, 2024
·
4 revisions
Updating print statistics is necessary to analyze information about the material used (thread length) and production time (see image below).
The data structure for printing statistics is in the Print.hpp file.
struct PrintStatistics
struct PrintStatistics
{
PrintStatistics() { clear(); }
std::string estimated_normal_print_time;
std::string estimated_silent_print_time;
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;
std::vector<unsigned int> printing_extruders;
unsigned int initial_extruder_id;
std::string initial_filament_type;
std::string printing_filament_types;
std::map<size_t, double> filament_stats;
// 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() {
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.;
initial_extruder_id = 0;
initial_filament_type.clear();
printing_filament_types.clear();
filament_stats.clear();
printing_extruders.clear();
}
};
To update print statistics in PrusaSlicer, it is necessary to modify the GCode.cpp file.
GCode::DoExport::update_print_estimated_stats
GCode.cpp
// functions called by GCode::_do_export() namespace DoExport {
952 DoExport::update_print_estimated_stats(m_processor, m_writer.extruders(), print->m_print_statistics);
static void update_print_estimated_stats(const GCodeProcessor& processor, const std::vector<Extruder>& extruders, PrintStatistics& print_statistics)
{
const GCodeProcessorResult& result = processor.get_result();
print_statistics.estimated_normal_print_time = get_time_dhms(result.print_statistics.modes[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].time);
print_statistics.estimated_silent_print_time = processor.is_stealth_time_estimator_enabled() ?
get_time_dhms(result.print_statistics.modes[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Stealth)].time) : "N/A";
// update filament statictics
double total_extruded_volume = 0.0;
double total_used_filament = 0.0;
double total_weight = 0.0;
double total_cost = 0.0;
for (auto volume : result.print_statistics.volumes_per_extruder) {
total_extruded_volume += volume.second;
size_t extruder_id = volume.first;
auto extruder = std::find_if(extruders.begin(), extruders.end(), [extruder_id](const Extruder& extr) { return extr.id() == extruder_id; });
if (extruder == extruders.end())
continue;
double s = PI * sqr(0.5* extruder->filament_diameter());
double weight = volume.second * extruder->filament_density() * 0.001;
total_used_filament += volume.second/s;
total_weight += weight;
total_cost += weight * extruder->filament_cost() * 0.001;
}
print_statistics.total_extruded_volume = total_extruded_volume;
print_statistics.total_used_filament = total_used_filament;
print_statistics.total_weight = total_weight;
print_statistics.total_cost = total_cost;
print_statistics.filament_stats = result.print_statistics.volumes_per_extruder;
}
string update_print_stats_and_format_filament_stats
// Fill in print_statistics and return formatted string containing filament statistics to be inserted into G-code comment section.
static std::string update_print_stats_and_format_filament_stats(
const bool has_wipe_tower,
const WipeTowerData &wipe_tower_data,
const FullPrintConfig &config,
const std::vector<Extruder> &extruders,
unsigned int initial_extruder_id,
PrintStatistics &print_statistics)
{
std::string filament_stats_string_out;
print_statistics.clear();
print_statistics.total_toolchanges = std::max(0, wipe_tower_data.number_of_toolchanges);
print_statistics.initial_extruder_id = initial_extruder_id;
std::vector<std::string> filament_types;
if (! extruders.empty()) {
std::pair<std::string, unsigned int> out_filament_used_mm ("; filament used [mm] = ", 0);
std::pair<std::string, unsigned int> out_filament_used_cm3("; filament used [cm3] = ", 0);
std::pair<std::string, unsigned int> out_filament_used_g ("; filament used [g] = ", 0);
std::pair<std::string, unsigned int> out_filament_cost ("; filament cost = ", 0);
for (const Extruder &extruder : extruders) {
print_statistics.printing_extruders.emplace_back(extruder.id());
filament_types.emplace_back(config.filament_type.get_at(extruder.id()));
double used_filament = extruder.used_filament() + (has_wipe_tower ? wipe_tower_data.used_filament[extruder.id()] : 0.f);
double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? wipe_tower_data.used_filament[extruder.id()] * 2.4052f : 0.f); // assumes 1.75mm filament diameter
double filament_weight = extruded_volume * extruder.filament_density() * 0.001;
double filament_cost = filament_weight * extruder.filament_cost() * 0.001;
auto append = [&extruder](std::pair<std::string, unsigned int> &dst, const char *tmpl, double value) {
assert(is_decimal_separator_point());
while (dst.second < extruder.id()) {
// Fill in the non-printing extruders with zeros.
dst.first += (dst.second > 0) ? ", 0" : "0";
++ dst.second;
}
if (dst.second > 0)
dst.first += ", ";
char buf[64];
sprintf(buf, tmpl, value);
dst.first += buf;
++ dst.second;
};
append(out_filament_used_mm, "%.2lf", used_filament);
append(out_filament_used_cm3, "%.2lf", extruded_volume * 0.001);
if (filament_weight > 0.) {
print_statistics.total_weight = print_statistics.total_weight + filament_weight;
append(out_filament_used_g, "%.2lf", filament_weight);
if (filament_cost > 0.) {
print_statistics.total_cost = print_statistics.total_cost + filament_cost;
append(out_filament_cost, "%.2lf", filament_cost);
}
}
print_statistics.total_used_filament += used_filament;
print_statistics.total_extruded_volume += extruded_volume;
print_statistics.total_wipe_tower_filament += has_wipe_tower ? used_filament - extruder.used_filament() : 0.;
print_statistics.total_wipe_tower_cost += has_wipe_tower ? (extruded_volume - extruder.extruded_volume())* extruder.filament_density() * 0.001 * extruder.filament_cost() * 0.001 : 0.;
}
filament_stats_string_out += out_filament_used_mm.first;
filament_stats_string_out += "\n" + out_filament_used_cm3.first;
if (out_filament_used_g.second)
filament_stats_string_out += "\n" + out_filament_used_g.first;
if (out_filament_cost.second)
filament_stats_string_out += "\n" + out_filament_cost.first;
print_statistics.initial_filament_type = config.filament_type.get_at(initial_extruder_id);
std::sort(filament_types.begin(), filament_types.end());
print_statistics.printing_filament_types = filament_types.front();
for (size_t i = 1; i < filament_types.size(); ++ i) {
print_statistics.printing_filament_types += ",";
print_statistics.printing_filament_types += filament_types[i];
}
}
return filament_stats_string_out;
}