Time estimate shown in GUI as formatted string / Write to file made by class GCode's private methods
This commit is contained in:
parent
20234c94ee
commit
0fe855cd6d
7 changed files with 146 additions and 141 deletions
|
@ -434,7 +434,7 @@ sub new {
|
|||
fil_mm3 => "Used Filament (mm^3)",
|
||||
fil_g => "Used Filament (g)",
|
||||
cost => "Cost",
|
||||
time => "Estimated printing time (min)",
|
||||
time => "Estimated printing time",
|
||||
);
|
||||
while (my $field = shift @info) {
|
||||
my $label = shift @info;
|
||||
|
@ -1428,7 +1428,7 @@ sub on_export_completed {
|
|||
$self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost));
|
||||
$self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight));
|
||||
$self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume));
|
||||
$self->{"print_info_time"}->SetLabel(sprintf("%.2f" , $self->{print}->estimated_print_time));
|
||||
$self->{"print_info_time"}->SetLabel($self->{print}->estimated_print_time);
|
||||
$self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000));
|
||||
$self->{"print_info_box_show"}->(1);
|
||||
|
||||
|
|
|
@ -267,72 +267,6 @@ std::string WipeTowerIntegration::finalize(GCode &gcodegen)
|
|||
|
||||
#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id())
|
||||
|
||||
// Helper class for writing to file with/without time estimation
|
||||
class Write
|
||||
{
|
||||
static GCodeTimeEstimator* s_time_estimator;
|
||||
|
||||
public:
|
||||
static void set_time_estimator(GCodeTimeEstimator* time_estimator)
|
||||
{
|
||||
s_time_estimator = time_estimator;
|
||||
}
|
||||
|
||||
static void write(FILE* file, const std::string& what)
|
||||
{
|
||||
if (!what.empty())
|
||||
{
|
||||
fwrite(what.data(), 1, what.size(), file);
|
||||
|
||||
if (s_time_estimator != nullptr)
|
||||
{
|
||||
const char endLine = '\n';
|
||||
std::string::size_type beginPos = 0;
|
||||
std::string::size_type endPos = what.find_first_of(endLine, beginPos);
|
||||
while (endPos != std::string::npos)
|
||||
{
|
||||
s_time_estimator->add_gcode_line(what.substr(beginPos, endPos - beginPos + 1));
|
||||
|
||||
beginPos = endPos + 1;
|
||||
endPos = what.find_first_of(endLine, beginPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//std::string Write::s_cache = "";
|
||||
GCodeTimeEstimator* Write::s_time_estimator = nullptr;
|
||||
|
||||
inline void write(FILE *file, const std::string &what)
|
||||
{
|
||||
Write::write(file, what);
|
||||
}
|
||||
|
||||
inline void write_format(FILE* file, const char* format, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int res = ::vsnprintf(buffer, 1024, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (res >= 0)
|
||||
write(file, buffer);
|
||||
}
|
||||
|
||||
// Write a string into a file. Add a newline, if the string does not end with a newline already.
|
||||
// Used to export a custom G-code section processed by the PlaceholderParser.
|
||||
inline void writeln(FILE *file, const std::string &what)
|
||||
{
|
||||
if (! what.empty()) {
|
||||
if (what.back() != '\n')
|
||||
write_format(file, "%s\n", what.c_str());
|
||||
else
|
||||
write(file, what);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect pairs of object_layer + support_layer sorted by print_z.
|
||||
// object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON.
|
||||
std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject &object)
|
||||
|
@ -456,7 +390,6 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
{
|
||||
// resets time estimator
|
||||
m_time_estimator.reset();
|
||||
Write::set_time_estimator(&m_time_estimator);
|
||||
|
||||
// How many times will be change_layer() called?
|
||||
// change_layer() in turn increments the progress bar status.
|
||||
|
@ -541,7 +474,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
m_enable_extrusion_role_markers = (bool)m_pressure_equalizer;
|
||||
|
||||
// Write information on the generator.
|
||||
fprintf(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str());
|
||||
_write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str());
|
||||
// Write notes (content of the Print Settings tab -> Notes)
|
||||
{
|
||||
std::list<std::string> lines;
|
||||
|
@ -550,10 +483,10 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
// Remove the trailing '\r' from the '\r\n' sequence.
|
||||
if (! line.empty() && line.back() == '\r')
|
||||
line.pop_back();
|
||||
fprintf(file, "; %s\n", line.c_str());
|
||||
_write_format(file, "; %s\n", line.c_str());
|
||||
}
|
||||
if (! lines.empty())
|
||||
fprintf(file, "\n");
|
||||
_write(file, "\n");
|
||||
}
|
||||
// Write some terse information on the slicing parameters.
|
||||
{
|
||||
|
@ -562,16 +495,17 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
const double first_layer_height = first_object->config.first_layer_height.get_abs_value(layer_height);
|
||||
for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) {
|
||||
auto region = print.regions[region_id];
|
||||
fprintf(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width);
|
||||
fprintf(file, "; perimeters extrusion width = %.2fmm\n", region->flow(frPerimeter, layer_height, false, false, -1., *first_object).width);
|
||||
fprintf(file, "; infill extrusion width = %.2fmm\n", region->flow(frInfill, layer_height, false, false, -1., *first_object).width);
|
||||
fprintf(file, "; solid infill extrusion width = %.2fmm\n", region->flow(frSolidInfill, layer_height, false, false, -1., *first_object).width);
|
||||
fprintf(file, "; top infill extrusion width = %.2fmm\n", region->flow(frTopSolidInfill, layer_height, false, false, -1., *first_object).width);
|
||||
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width);
|
||||
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(frPerimeter, layer_height, false, false, -1., *first_object).width);
|
||||
_write_format(file, "; infill extrusion width = %.2fmm\n", region->flow(frInfill, layer_height, false, false, -1., *first_object).width);
|
||||
_write_format(file, "; solid infill extrusion width = %.2fmm\n", region->flow(frSolidInfill, layer_height, false, false, -1., *first_object).width);
|
||||
_write_format(file, "; top infill extrusion width = %.2fmm\n", region->flow(frTopSolidInfill, layer_height, false, false, -1., *first_object).width);
|
||||
if (print.has_support_material())
|
||||
fprintf(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width);
|
||||
_write_format(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width);
|
||||
if (print.config.first_layer_extrusion_width.value > 0)
|
||||
fprintf(file, "; first layer extrusion width = %.2fmm\n", region->flow(frPerimeter, first_layer_height, false, true, -1., *first_object).width);
|
||||
fprintf(file, "\n");
|
||||
_write_format(file, "; first layer extrusion width = %.2fmm\n", region->flow(frPerimeter, first_layer_height, false, true, -1., *first_object).width);
|
||||
|
||||
_write(file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,7 +549,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
|
||||
// Disable fan.
|
||||
if (! print.config.cooling.get_at(initial_extruder_id) || print.config.disable_fan_first_layers.get_at(initial_extruder_id))
|
||||
write(file, m_writer.set_fan(0, true));
|
||||
_write(file, m_writer.set_fan(0, true));
|
||||
|
||||
// Let the start-up script prime the 1st printing tool.
|
||||
m_placeholder_parser.set("initial_tool", initial_extruder_id);
|
||||
|
@ -632,24 +566,24 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
// Set extruder(s) temperature before and after start G-code.
|
||||
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false);
|
||||
// Write the custom start G-code
|
||||
writeln(file, start_gcode);
|
||||
_writeln(file, start_gcode);
|
||||
// Process filament-specific gcode in extruder order.
|
||||
if (print.config.single_extruder_multi_material) {
|
||||
if (has_wipe_tower) {
|
||||
// Wipe tower will control the extruder switching, it will call the start_filament_gcode.
|
||||
} else {
|
||||
// Only initialize the initial extruder.
|
||||
writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config.start_filament_gcode.values[initial_extruder_id], initial_extruder_id));
|
||||
_writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config.start_filament_gcode.values[initial_extruder_id], initial_extruder_id));
|
||||
}
|
||||
} else {
|
||||
for (const std::string &start_gcode : print.config.start_filament_gcode.values)
|
||||
writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front())));
|
||||
_writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front())));
|
||||
}
|
||||
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true);
|
||||
|
||||
// Set other general things.
|
||||
write(file, this->preamble());
|
||||
|
||||
_write(file, this->preamble());
|
||||
|
||||
// Initialize a motion planner for object-to-object travel moves.
|
||||
if (print.config.avoid_crossing_perimeters.value) {
|
||||
// Collect outer contours of all objects over all layers.
|
||||
|
@ -697,7 +631,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
}
|
||||
|
||||
// Set initial extruder only after custom start G-code.
|
||||
write(file, this->set_extruder(initial_extruder_id));
|
||||
_write(file, this->set_extruder(initial_extruder_id));
|
||||
|
||||
// Do all objects for each layer.
|
||||
if (print.config.complete_objects.value) {
|
||||
|
@ -727,8 +661,8 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
// This happens before Z goes down to layer 0 again, so that no collision happens hopefully.
|
||||
m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer
|
||||
m_avoid_crossing_perimeters.use_external_mp_once = true;
|
||||
write(file, this->retract());
|
||||
write(file, this->travel_to(Point(0, 0), erNone, "move to origin position for next object"));
|
||||
_write(file, this->retract());
|
||||
_write(file, this->travel_to(Point(0, 0), erNone, "move to origin position for next object"));
|
||||
m_enable_cooling_markers = true;
|
||||
// Disable motion planner when traveling to first object point.
|
||||
m_avoid_crossing_perimeters.disable_once = true;
|
||||
|
@ -740,7 +674,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
// Set first layer bed and extruder temperatures, don't wait for it to reach the temperature.
|
||||
this->_print_first_layer_bed_temperature(file, print, between_objects_gcode, initial_extruder_id, false);
|
||||
this->_print_first_layer_extruder_temperatures(file, print, between_objects_gcode, initial_extruder_id, false);
|
||||
writeln(file, between_objects_gcode);
|
||||
_writeln(file, between_objects_gcode);
|
||||
}
|
||||
// Reset the cooling buffer internal state (the current position, feed rate, accelerations).
|
||||
m_cooling_buffer->reset();
|
||||
|
@ -753,8 +687,9 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), © - object._shifted_copies.data());
|
||||
}
|
||||
if (m_pressure_equalizer)
|
||||
write(file, m_pressure_equalizer->process("", true));
|
||||
++ finished_objects;
|
||||
_write(file, m_pressure_equalizer->process("", true));
|
||||
|
||||
++finished_objects;
|
||||
// Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
|
||||
// Reset it when starting another object from 1st layer.
|
||||
m_second_layer_things_done = false;
|
||||
|
@ -773,7 +708,7 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
// Prusa Multi-Material wipe tower.
|
||||
if (has_wipe_tower && ! layers_to_print.empty()) {
|
||||
m_wipe_tower.reset(new WipeTowerIntegration(print.config, *print.m_wipe_tower_priming.get(), print.m_wipe_tower_tool_changes, *print.m_wipe_tower_final_purge.get()));
|
||||
write(file, m_wipe_tower->prime(*this));
|
||||
_write(file, m_wipe_tower->prime(*this));
|
||||
// Verify, whether the print overaps the priming extrusions.
|
||||
BoundingBoxf bbox_print(get_print_extrusions_extents(print));
|
||||
coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first + EPSILON;
|
||||
|
@ -783,16 +718,17 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
BoundingBoxf bbox_prime(get_wipe_tower_priming_extrusions_extents(print));
|
||||
bbox_prime.offset(0.5f);
|
||||
// Beep for 500ms, tone 800Hz. Yet better, play some Morse.
|
||||
write(file, this->retract());
|
||||
write(file, "M300 S800 P500\n");
|
||||
_write(file, this->retract());
|
||||
_write(file, "M300 S800 P500\n");
|
||||
if (bbox_prime.overlap(bbox_print)) {
|
||||
// Wait for the user to remove the priming extrusions, otherwise they would
|
||||
// get covered by the print.
|
||||
write(file, "M1 Remove priming towers and click button.\n");
|
||||
} else {
|
||||
_write(file, "M1 Remove priming towers and click button.\n");
|
||||
}
|
||||
else {
|
||||
// Just wait for a bit to let the user check, that the priming succeeded.
|
||||
//TODO Add a message explaining what the printer is waiting for. This needs a firmware fix.
|
||||
write(file, "M1 S10\n");
|
||||
_write(file, "M1 S10\n");
|
||||
}
|
||||
}
|
||||
// Extrude the layers.
|
||||
|
@ -803,26 +739,27 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
this->process_layer(file, print, layer.second, layer_tools, size_t(-1));
|
||||
}
|
||||
if (m_pressure_equalizer)
|
||||
write(file, m_pressure_equalizer->process("", true));
|
||||
_write(file, m_pressure_equalizer->process("", true));
|
||||
if (m_wipe_tower)
|
||||
// Purge the extruder, pull out the active filament.
|
||||
write(file, m_wipe_tower->finalize(*this));
|
||||
_write(file, m_wipe_tower->finalize(*this));
|
||||
}
|
||||
|
||||
// Write end commands to file.
|
||||
write(file, this->retract());
|
||||
write(file, m_writer.set_fan(false));
|
||||
_write(file, this->retract());
|
||||
_write(file, m_writer.set_fan(false));
|
||||
// Process filament-specific gcode in extruder order.
|
||||
if (print.config.single_extruder_multi_material) {
|
||||
// Process the end_filament_gcode for the active filament only.
|
||||
writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id()));
|
||||
} else {
|
||||
for (const std::string &end_gcode : print.config.end_filament_gcode.values)
|
||||
writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front())));
|
||||
_writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id()));
|
||||
}
|
||||
writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id()));
|
||||
write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
|
||||
write(file, m_writer.postamble());
|
||||
else {
|
||||
for (const std::string &end_gcode : print.config.end_filament_gcode.values)
|
||||
_writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front())));
|
||||
}
|
||||
_writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id()));
|
||||
_write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
|
||||
_write(file, m_writer.postamble());
|
||||
|
||||
// calculates estimated printing time
|
||||
m_time_estimator.calculate_time();
|
||||
|
@ -833,37 +770,37 @@ void GCode::_do_export(Print &print, FILE *file)
|
|||
print.total_extruded_volume = 0.;
|
||||
print.total_weight = 0.;
|
||||
print.total_cost = 0.;
|
||||
print.estimated_print_time = (double)m_time_estimator.get_time() / 60.0;
|
||||
print.estimated_print_time = m_time_estimator.get_time_hms();
|
||||
for (const Extruder &extruder : m_writer.extruders()) {
|
||||
double used_filament = extruder.used_filament();
|
||||
double extruded_volume = extruder.extruded_volume();
|
||||
double filament_weight = extruded_volume * extruder.filament_density() * 0.001;
|
||||
double filament_cost = filament_weight * extruder.filament_cost() * 0.001;
|
||||
print.filament_stats.insert(std::pair<size_t,float>(extruder.id(), used_filament));
|
||||
fprintf(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001);
|
||||
_write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001);
|
||||
if (filament_weight > 0.) {
|
||||
print.total_weight = print.total_weight + filament_weight;
|
||||
fprintf(file, "; filament used = %.1lf\n", filament_weight);
|
||||
_write_format(file, "; filament used = %.1lf\n", filament_weight);
|
||||
if (filament_cost > 0.) {
|
||||
print.total_cost = print.total_cost + filament_cost;
|
||||
fprintf(file, "; filament cost = %.1lf\n", filament_cost);
|
||||
_write_format(file, "; filament cost = %.1lf\n", filament_cost);
|
||||
}
|
||||
}
|
||||
print.total_used_filament = print.total_used_filament + used_filament;
|
||||
print.total_used_filament = print.total_used_filament + used_filament;
|
||||
print.total_extruded_volume = print.total_extruded_volume + extruded_volume;
|
||||
}
|
||||
fprintf(file, "; total filament cost = %.1lf\n", print.total_cost);
|
||||
fprintf(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms());
|
||||
_write_format(file, "; total filament cost = %.1lf\n", print.total_cost);
|
||||
_write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms());
|
||||
|
||||
// Append full config.
|
||||
fprintf(file, "\n");
|
||||
_write(file, "\n");
|
||||
{
|
||||
StaticPrintConfig *configs[] = { &print.config, &print.default_object_config, &print.default_region_config };
|
||||
for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++ i) {
|
||||
StaticPrintConfig *cfg = configs[i];
|
||||
for (const std::string &key : cfg->keys())
|
||||
if (key != "compatible_printers")
|
||||
fprintf(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str());
|
||||
_write_format(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -954,7 +891,7 @@ void GCode::_print_first_layer_bed_temperature(FILE *file, Print &print, const s
|
|||
// the custom start G-code emited these.
|
||||
std::string set_temp_gcode = m_writer.set_bed_temperature(temp, wait);
|
||||
if (! temp_set_by_gcode)
|
||||
write(file, set_temp_gcode);
|
||||
_write(file, set_temp_gcode);
|
||||
}
|
||||
|
||||
// Write 1st layer extruder temperatures into the G-code.
|
||||
|
@ -977,15 +914,16 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c
|
|||
// Set temperature of the first printing extruder only.
|
||||
int temp = print.config.first_layer_temperature.get_at(first_printing_extruder_id);
|
||||
if (temp > 0)
|
||||
write(file, m_writer.set_temperature(temp, wait, first_printing_extruder_id));
|
||||
} else {
|
||||
_write(file, m_writer.set_temperature(temp, wait, first_printing_extruder_id));
|
||||
}
|
||||
else {
|
||||
// Set temperatures of all the printing extruders.
|
||||
for (unsigned int tool_id : print.extruders()) {
|
||||
int temp = print.config.first_layer_temperature.get_at(tool_id);
|
||||
if (print.config.ooze_prevention.value)
|
||||
temp += print.config.standby_temperature_delta.value;
|
||||
if (temp > 0)
|
||||
write(file, m_writer.set_temperature(temp, wait, tool_id));
|
||||
_write(file, m_writer.set_temperature(temp, wait, tool_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1419,7 +1357,7 @@ void GCode::process_layer(
|
|||
gcode = m_pressure_equalizer->process(gcode.c_str(), false);
|
||||
// printf("G-code after filter:\n%s\n", out.c_str());
|
||||
|
||||
write(file, gcode);
|
||||
_write(file, gcode);
|
||||
}
|
||||
|
||||
void GCode::apply_print_config(const PrintConfig &print_config)
|
||||
|
@ -2054,6 +1992,51 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
|
|||
return gcode;
|
||||
}
|
||||
|
||||
void GCode::_write(FILE* file, const std::string& what)
|
||||
{
|
||||
if (!what.empty())
|
||||
{
|
||||
// writes string to file
|
||||
fwrite(what.data(), 1, what.size(), file);
|
||||
|
||||
// updates time estimator and gcode lines vector
|
||||
const char endLine = '\n';
|
||||
std::string::size_type beginPos = 0;
|
||||
std::string::size_type endPos = what.find_first_of(endLine, beginPos);
|
||||
while (endPos != std::string::npos)
|
||||
{
|
||||
std::string line = what.substr(beginPos, endPos - beginPos + 1);
|
||||
m_time_estimator.add_gcode_line(line);
|
||||
|
||||
beginPos = endPos + 1;
|
||||
endPos = what.find_first_of(endLine, beginPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GCode::_writeln(FILE* file, const std::string& what)
|
||||
{
|
||||
if (!what.empty())
|
||||
{
|
||||
if (what.back() != '\n')
|
||||
_write_format(file, "%s\n", what.c_str());
|
||||
else
|
||||
_write(file, what);
|
||||
}
|
||||
}
|
||||
|
||||
void GCode::_write_format(FILE* file, const char* format, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int res = ::vsnprintf(buffer, 1024, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (res >= 0)
|
||||
_writeln(file, buffer);
|
||||
}
|
||||
|
||||
std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed)
|
||||
{
|
||||
std::string gcode;
|
||||
|
|
|
@ -277,6 +277,17 @@ protected:
|
|||
// Time estimator
|
||||
GCodeTimeEstimator m_time_estimator;
|
||||
|
||||
// Write a string into a file.
|
||||
void _write(FILE* file, const std::string& what);
|
||||
|
||||
// Write a string into a file.
|
||||
// Add a newline, if the string does not end with a newline already.
|
||||
// Used to export a custom G-code section processed by the PlaceholderParser.
|
||||
void _writeln(FILE* file, const std::string& what);
|
||||
|
||||
// Formats and write into a file the given data.
|
||||
void _write_format(FILE* file, const char* format, ...);
|
||||
|
||||
std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1);
|
||||
void _print_first_layer_bed_temperature(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
|
||||
void _print_first_layer_extruder_temperatures(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
|
||||
|
|
|
@ -157,6 +157,16 @@ namespace Slic3r {
|
|||
reset();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::calculate_time_from_lines(const std::vector<std::string>& gcode_lines)
|
||||
{
|
||||
for (const std::string& line : gcode_lines)
|
||||
{
|
||||
_parser.parse_line(line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2));
|
||||
}
|
||||
_calculate_time();
|
||||
reset();
|
||||
}
|
||||
|
||||
void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line)
|
||||
{
|
||||
_parser.parse_line(gcode_line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2));
|
||||
|
@ -354,8 +364,14 @@ namespace Slic3r {
|
|||
int minutes = (int)(timeinsecs / 60.0f);
|
||||
timeinsecs -= (float)minutes * 60.0f;
|
||||
|
||||
char buffer[16];
|
||||
::sprintf(buffer, "%02d:%02d:%02d", hours, minutes, (int)timeinsecs);
|
||||
char buffer[64];
|
||||
if (hours > 0)
|
||||
::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)timeinsecs);
|
||||
else if (minutes > 0)
|
||||
::sprintf(buffer, "%dm %ds", minutes, (int)timeinsecs);
|
||||
else
|
||||
::sprintf(buffer, "%ds", (int)timeinsecs);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -393,7 +409,7 @@ namespace Slic3r {
|
|||
{
|
||||
if (line.cmd.length() > 1)
|
||||
{
|
||||
switch (line.cmd[0])
|
||||
switch (::toupper(line.cmd[0]))
|
||||
{
|
||||
case 'G':
|
||||
{
|
||||
|
|
|
@ -184,6 +184,9 @@ namespace Slic3r {
|
|||
// Calculates the time estimate from the gcode contained in the file with the given filename
|
||||
void calculate_time_from_file(const std::string& file);
|
||||
|
||||
// Calculates the time estimate from the gcode contained in given list of gcode lines
|
||||
void calculate_time_from_lines(const std::vector<std::string>& gcode_lines);
|
||||
|
||||
// Adds the given gcode line
|
||||
void add_gcode_line(const std::string& gcode_line);
|
||||
|
||||
|
@ -252,7 +255,7 @@ namespace Slic3r {
|
|||
// Calculates the time estimate
|
||||
void _calculate_time();
|
||||
|
||||
// Processes GCode line
|
||||
// Processes the given gcode line
|
||||
void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line);
|
||||
|
||||
// Move
|
||||
|
|
|
@ -233,14 +233,15 @@ public:
|
|||
PrintRegionPtrs regions;
|
||||
PlaceholderParser placeholder_parser;
|
||||
// TODO: status_cb
|
||||
double total_used_filament, total_extruded_volume, total_cost, total_weight, estimated_print_time;
|
||||
std::string estimated_print_time;
|
||||
double total_used_filament, total_extruded_volume, total_cost, total_weight;
|
||||
std::map<size_t, float> filament_stats;
|
||||
PrintState<PrintStep, psCount> state;
|
||||
|
||||
// ordered collections of extrusion paths to build skirt loops and brim
|
||||
ExtrusionEntityCollection skirt, brim;
|
||||
|
||||
Print() : total_used_filament(0), total_extruded_volume(0), estimated_print_time(0) { restart(); }
|
||||
Print() : total_used_filament(0), total_extruded_volume(0) { restart(); }
|
||||
~Print() { clear_objects(); }
|
||||
|
||||
// methods for handling objects
|
||||
|
|
|
@ -153,6 +153,8 @@ _constant()
|
|||
%code%{ RETVAL = &THIS->skirt; %};
|
||||
Ref<ExtrusionEntityCollection> brim()
|
||||
%code%{ RETVAL = &THIS->brim; %};
|
||||
std::string estimated_print_time()
|
||||
%code%{ RETVAL = THIS->estimated_print_time; %};
|
||||
|
||||
PrintObjectPtrs* objects()
|
||||
%code%{ RETVAL = &THIS->objects; %};
|
||||
|
@ -281,17 +283,6 @@ Print::total_cost(...)
|
|||
}
|
||||
RETVAL = THIS->total_cost;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
double
|
||||
Print::estimated_print_time(...)
|
||||
CODE:
|
||||
if (items > 1) {
|
||||
THIS->estimated_print_time = (double)SvNV(ST(1));
|
||||
}
|
||||
RETVAL = THIS->estimated_print_time;
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
RETVAL
|
||||
%}
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue