Prototype for exporting estimated remaining time into gcode for default and silent mode
This commit is contained in:
parent
e4aff5b08a
commit
5a8d1ffdba
@ -472,7 +472,8 @@ sub new {
|
|||||||
fil_mm3 => L("Used Filament (mm³)"),
|
fil_mm3 => L("Used Filament (mm³)"),
|
||||||
fil_g => L("Used Filament (g)"),
|
fil_g => L("Used Filament (g)"),
|
||||||
cost => L("Cost"),
|
cost => L("Cost"),
|
||||||
time => L("Estimated printing time"),
|
default_time => L("Estimated printing time (default mode)"),
|
||||||
|
silent_time => L("Estimated printing time (silent mode)"),
|
||||||
);
|
);
|
||||||
while (my $field = shift @info) {
|
while (my $field = shift @info) {
|
||||||
my $label = shift @info;
|
my $label = shift @info;
|
||||||
@ -1542,7 +1543,8 @@ sub on_export_completed {
|
|||||||
$self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost));
|
$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_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight));
|
||||||
$self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume));
|
$self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume));
|
||||||
$self->{"print_info_time"}->SetLabel($self->{print}->estimated_print_time);
|
$self->{"print_info_default_time"}->SetLabel($self->{print}->estimated_default_print_time);
|
||||||
|
$self->{"print_info_silent_time"}->SetLabel($self->{print}->estimated_silent_print_time);
|
||||||
$self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000));
|
$self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000));
|
||||||
$self->{"print_info_box_show"}->(1);
|
$self->{"print_info_box_show"}->(1);
|
||||||
|
|
||||||
|
@ -374,6 +374,9 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_
|
|||||||
throw std::runtime_error(std::string("G-code export to ") + path + " failed\nIs the disk full?\n");
|
throw std::runtime_error(std::string("G-code export to ") + path + " failed\nIs the disk full?\n");
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
GCodeTimeEstimator::post_process_elapsed_times(path_tmp, m_default_time_estimator.get_time(), m_silent_time_estimator.get_time());
|
||||||
|
|
||||||
if (! this->m_placeholder_parser_failed_templates.empty()) {
|
if (! this->m_placeholder_parser_failed_templates.empty()) {
|
||||||
// G-code export proceeded, but some of the PlaceholderParser substitutions failed.
|
// G-code export proceeded, but some of the PlaceholderParser substitutions failed.
|
||||||
std::string msg = std::string("G-code export to ") + path + " failed due to invalid custom G-code sections:\n\n";
|
std::string msg = std::string("G-code export to ") + path + " failed due to invalid custom G-code sections:\n\n";
|
||||||
@ -403,9 +406,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
|||||||
{
|
{
|
||||||
PROFILE_FUNC();
|
PROFILE_FUNC();
|
||||||
|
|
||||||
// resets time estimator
|
// resets time estimators
|
||||||
m_time_estimator.reset();
|
m_default_time_estimator.reset();
|
||||||
m_time_estimator.set_dialect(print.config.gcode_flavor);
|
m_default_time_estimator.set_dialect(print.config.gcode_flavor);
|
||||||
|
m_silent_time_estimator.reset();
|
||||||
|
m_silent_time_estimator.set_dialect(print.config.gcode_flavor);
|
||||||
|
|
||||||
// resets analyzer
|
// resets analyzer
|
||||||
m_analyzer.reset();
|
m_analyzer.reset();
|
||||||
@ -596,6 +601,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
|||||||
_writeln(file, buf);
|
_writeln(file, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// before start gcode time estimation
|
||||||
|
_write(file, m_default_time_estimator.get_elapsed_time_string().c_str());
|
||||||
|
_write(file, m_silent_time_estimator.get_elapsed_time_string().c_str());
|
||||||
|
|
||||||
// Write the custom start G-code
|
// Write the custom start G-code
|
||||||
_writeln(file, start_gcode);
|
_writeln(file, start_gcode);
|
||||||
// Process filament-specific gcode in extruder order.
|
// Process filament-specific gcode in extruder order.
|
||||||
@ -800,13 +809,17 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
|||||||
for (const std::string &end_gcode : print.config.end_filament_gcode.values)
|
for (const std::string &end_gcode : print.config.end_filament_gcode.values)
|
||||||
_writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()), &config));
|
_writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()), &config));
|
||||||
}
|
}
|
||||||
|
// before end gcode time estimation
|
||||||
|
_write(file, m_default_time_estimator.get_elapsed_time_string().c_str());
|
||||||
|
_write(file, m_silent_time_estimator.get_elapsed_time_string().c_str());
|
||||||
_writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id(), &config));
|
_writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id(), &config));
|
||||||
}
|
}
|
||||||
_write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
|
_write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
|
||||||
_write(file, m_writer.postamble());
|
_write(file, m_writer.postamble());
|
||||||
|
|
||||||
// calculates estimated printing time
|
// calculates estimated printing time
|
||||||
m_time_estimator.calculate_time();
|
m_default_time_estimator.calculate_time();
|
||||||
|
m_silent_time_estimator.calculate_time();
|
||||||
|
|
||||||
// Get filament stats.
|
// Get filament stats.
|
||||||
print.filament_stats.clear();
|
print.filament_stats.clear();
|
||||||
@ -814,7 +827,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
|||||||
print.total_extruded_volume = 0.;
|
print.total_extruded_volume = 0.;
|
||||||
print.total_weight = 0.;
|
print.total_weight = 0.;
|
||||||
print.total_cost = 0.;
|
print.total_cost = 0.;
|
||||||
print.estimated_print_time = m_time_estimator.get_time_hms();
|
print.estimated_default_print_time = m_default_time_estimator.get_time_dhms();
|
||||||
|
print.estimated_silent_print_time = m_silent_time_estimator.get_time_dhms();
|
||||||
for (const Extruder &extruder : m_writer.extruders()) {
|
for (const Extruder &extruder : m_writer.extruders()) {
|
||||||
double used_filament = extruder.used_filament();
|
double used_filament = extruder.used_filament();
|
||||||
double extruded_volume = extruder.extruded_volume();
|
double extruded_volume = extruder.extruded_volume();
|
||||||
@ -834,7 +848,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
|||||||
print.total_extruded_volume = print.total_extruded_volume + extruded_volume;
|
print.total_extruded_volume = print.total_extruded_volume + extruded_volume;
|
||||||
}
|
}
|
||||||
_write_format(file, "; total filament cost = %.1lf\n", print.total_cost);
|
_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().c_str());
|
_write_format(file, "; estimated printing time (default mode) = %s\n", m_default_time_estimator.get_time_dhms().c_str());
|
||||||
|
_write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str());
|
||||||
|
|
||||||
// Append full config.
|
// Append full config.
|
||||||
_write(file, "\n");
|
_write(file, "\n");
|
||||||
@ -1401,6 +1416,10 @@ void GCode::process_layer(
|
|||||||
// printf("G-code after filter:\n%s\n", out.c_str());
|
// printf("G-code after filter:\n%s\n", out.c_str());
|
||||||
|
|
||||||
_write(file, gcode);
|
_write(file, gcode);
|
||||||
|
|
||||||
|
// after layer time estimation
|
||||||
|
_write(file, m_default_time_estimator.get_elapsed_time_string().c_str());
|
||||||
|
_write(file, m_silent_time_estimator.get_elapsed_time_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCode::apply_print_config(const PrintConfig &print_config)
|
void GCode::apply_print_config(const PrintConfig &print_config)
|
||||||
@ -2059,7 +2078,8 @@ void GCode::_write(FILE* file, const char *what)
|
|||||||
// writes string to file
|
// writes string to file
|
||||||
fwrite(gcode, 1, ::strlen(gcode), file);
|
fwrite(gcode, 1, ::strlen(gcode), file);
|
||||||
// updates time estimator and gcode lines vector
|
// updates time estimator and gcode lines vector
|
||||||
m_time_estimator.add_gcode_block(gcode);
|
m_default_time_estimator.add_gcode_block(gcode);
|
||||||
|
m_silent_time_estimator.add_gcode_block(gcode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,8 @@ public:
|
|||||||
m_last_height(GCodeAnalyzer::Default_Height),
|
m_last_height(GCodeAnalyzer::Default_Height),
|
||||||
m_brim_done(false),
|
m_brim_done(false),
|
||||||
m_second_layer_things_done(false),
|
m_second_layer_things_done(false),
|
||||||
|
m_default_time_estimator(GCodeTimeEstimator::Default),
|
||||||
|
m_silent_time_estimator(GCodeTimeEstimator::Silent),
|
||||||
m_last_obj_copy(nullptr, Point(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max()))
|
m_last_obj_copy(nullptr, Point(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max()))
|
||||||
{}
|
{}
|
||||||
~GCode() {}
|
~GCode() {}
|
||||||
@ -289,8 +291,9 @@ protected:
|
|||||||
// Index of a last object copy extruded.
|
// Index of a last object copy extruded.
|
||||||
std::pair<const PrintObject*, Point> m_last_obj_copy;
|
std::pair<const PrintObject*, Point> m_last_obj_copy;
|
||||||
|
|
||||||
// Time estimator
|
// Time estimators
|
||||||
GCodeTimeEstimator m_time_estimator;
|
GCodeTimeEstimator m_default_time_estimator;
|
||||||
|
GCodeTimeEstimator m_silent_time_estimator;
|
||||||
|
|
||||||
// Analyzer
|
// Analyzer
|
||||||
GCodeAnalyzer m_analyzer;
|
GCodeAnalyzer m_analyzer;
|
||||||
|
@ -4,9 +4,14 @@
|
|||||||
|
|
||||||
#include <Shiny/Shiny.h>
|
#include <Shiny/Shiny.h>
|
||||||
|
|
||||||
|
#include <boost/nowide/fstream.hpp>
|
||||||
|
#include <boost/nowide/cstdio.hpp>
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
static const float MMMIN_TO_MMSEC = 1.0f / 60.0f;
|
static const float MMMIN_TO_MMSEC = 1.0f / 60.0f;
|
||||||
static const float MILLISEC_TO_SEC = 0.001f;
|
static const float MILLISEC_TO_SEC = 0.001f;
|
||||||
static const float INCHES_TO_MM = 25.4f;
|
static const float INCHES_TO_MM = 25.4f;
|
||||||
|
|
||||||
static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp)
|
static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp)
|
||||||
static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
|
static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
|
||||||
static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
|
static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
|
||||||
@ -17,8 +22,31 @@ static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Conf
|
|||||||
static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
|
static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
|
||||||
static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent
|
static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent
|
||||||
|
|
||||||
|
static const float SILENT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp)
|
||||||
|
static const float SILENT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full
|
||||||
|
static const float SILENT_RETRACT_ACCELERATION = 1250.0f; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full
|
||||||
|
static const float SILENT_AXIS_MAX_FEEDRATE[] = { 200.0f, 200.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full
|
||||||
|
static const float SILENT_AXIS_MAX_ACCELERATION[] = { 1000.0f, 1000.0f, 200.0f, 5000.0f }; // Prusa Firmware 1_75mm_MK25-RAMBo13a-E3Dv6full
|
||||||
|
static const float SILENT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // from Prusa Firmware (Configuration.h)
|
||||||
|
static const float SILENT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
|
||||||
|
static const float SILENT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
|
||||||
|
static const float SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent
|
||||||
|
|
||||||
static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f;
|
static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f;
|
||||||
|
|
||||||
|
static const std::string ELAPSED_TIME_TAG_DEFAULT = ";_ELAPSED_TIME_DEFAULT: ";
|
||||||
|
static const std::string ELAPSED_TIME_TAG_SILENT = ";_ELAPSED_TIME_SILENT: ";
|
||||||
|
|
||||||
|
#define REMAINING_TIME_USE_SINGLE_GCODE_COMMAND 1
|
||||||
|
#if REMAINING_TIME_USE_SINGLE_GCODE_COMMAND
|
||||||
|
static const std::string REMAINING_TIME_CMD = "M998";
|
||||||
|
#else
|
||||||
|
static const std::string REMAINING_TIME_CMD_DEFAULT = "M998";
|
||||||
|
static const std::string REMAINING_TIME_CMD_SILENT = "M999";
|
||||||
|
#endif // REMAINING_TIME_USE_SINGLE_GCODE_COMMAND
|
||||||
|
|
||||||
|
static const std::string REMAINING_TIME_COMMENT = " ; estimated remaining time";
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
#if ENABLE_MOVE_STATS
|
||||||
static const std::string MOVE_TYPE_STR[Slic3r::GCodeTimeEstimator::Block::Num_Types] =
|
static const std::string MOVE_TYPE_STR[Slic3r::GCodeTimeEstimator::Block::Num_Types] =
|
||||||
{
|
{
|
||||||
@ -73,6 +101,11 @@ namespace Slic3r {
|
|||||||
return ::sqrt(value);
|
return ::sqrt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GCodeTimeEstimator::Block::Block()
|
||||||
|
: st_synchronized(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
float GCodeTimeEstimator::Block::move_length() const
|
float GCodeTimeEstimator::Block::move_length() const
|
||||||
{
|
{
|
||||||
float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
|
float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
|
||||||
@ -159,63 +192,13 @@ namespace Slic3r {
|
|||||||
}
|
}
|
||||||
#endif // ENABLE_MOVE_STATS
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
|
||||||
GCodeTimeEstimator::GCodeTimeEstimator()
|
GCodeTimeEstimator::GCodeTimeEstimator(EMode mode)
|
||||||
|
: _mode(mode)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
set_default();
|
set_default();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
|
|
||||||
_parser.parse_buffer(gcode,
|
|
||||||
[this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
|
|
||||||
{ this->_process_gcode_line(reader, line); });
|
|
||||||
|
|
||||||
_calculate_time();
|
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
|
||||||
_log_moves_stats();
|
|
||||||
#endif // ENABLE_MOVE_STATS
|
|
||||||
|
|
||||||
_reset_blocks();
|
|
||||||
_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GCodeTimeEstimator::calculate_time_from_file(const std::string& file)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
|
|
||||||
_parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2));
|
|
||||||
_calculate_time();
|
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
|
||||||
_log_moves_stats();
|
|
||||||
#endif // ENABLE_MOVE_STATS
|
|
||||||
|
|
||||||
_reset_blocks();
|
|
||||||
_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GCodeTimeEstimator::calculate_time_from_lines(const std::vector<std::string>& gcode_lines)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
|
|
||||||
auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
|
|
||||||
{ this->_process_gcode_line(reader, line); };
|
|
||||||
for (const std::string& line : gcode_lines)
|
|
||||||
_parser.parse_line(line, action);
|
|
||||||
_calculate_time();
|
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
|
||||||
_log_moves_stats();
|
|
||||||
#endif // ENABLE_MOVE_STATS
|
|
||||||
|
|
||||||
_reset_blocks();
|
|
||||||
_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line)
|
void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line)
|
||||||
{
|
{
|
||||||
PROFILE_FUNC();
|
PROFILE_FUNC();
|
||||||
@ -239,14 +222,157 @@ namespace Slic3r {
|
|||||||
void GCodeTimeEstimator::calculate_time()
|
void GCodeTimeEstimator::calculate_time()
|
||||||
{
|
{
|
||||||
PROFILE_FUNC();
|
PROFILE_FUNC();
|
||||||
|
_reset_time();
|
||||||
|
_set_blocks_st_synchronize(false);
|
||||||
_calculate_time();
|
_calculate_time();
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
#if ENABLE_MOVE_STATS
|
||||||
_log_moves_stats();
|
_log_moves_stats();
|
||||||
#endif // ENABLE_MOVE_STATS
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
}
|
||||||
|
|
||||||
_reset_blocks();
|
void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode)
|
||||||
_reset();
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
_parser.parse_buffer(gcode,
|
||||||
|
[this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
|
||||||
|
{ this->_process_gcode_line(reader, line); });
|
||||||
|
|
||||||
|
_calculate_time();
|
||||||
|
|
||||||
|
#if ENABLE_MOVE_STATS
|
||||||
|
_log_moves_stats();
|
||||||
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeTimeEstimator::calculate_time_from_file(const std::string& file)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
_parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2));
|
||||||
|
_calculate_time();
|
||||||
|
|
||||||
|
#if ENABLE_MOVE_STATS
|
||||||
|
_log_moves_stats();
|
||||||
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeTimeEstimator::calculate_time_from_lines(const std::vector<std::string>& gcode_lines)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
|
||||||
|
{ this->_process_gcode_line(reader, line); };
|
||||||
|
for (const std::string& line : gcode_lines)
|
||||||
|
_parser.parse_line(line, action);
|
||||||
|
_calculate_time();
|
||||||
|
|
||||||
|
#if ENABLE_MOVE_STATS
|
||||||
|
_log_moves_stats();
|
||||||
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GCodeTimeEstimator::get_elapsed_time_string()
|
||||||
|
{
|
||||||
|
calculate_time();
|
||||||
|
switch (_mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case Default:
|
||||||
|
return ELAPSED_TIME_TAG_DEFAULT + std::to_string(get_time()) + "\n";
|
||||||
|
case Silent:
|
||||||
|
return ELAPSED_TIME_TAG_SILENT + std::to_string(get_time()) + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GCodeTimeEstimator::post_process_elapsed_times(const std::string& filename, float default_time, float silent_time)
|
||||||
|
{
|
||||||
|
boost::nowide::ifstream in(filename);
|
||||||
|
if (!in.good())
|
||||||
|
throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for reading.\n"));
|
||||||
|
|
||||||
|
std::string path_tmp = filename + ".times";
|
||||||
|
|
||||||
|
FILE* out = boost::nowide::fopen(path_tmp.c_str(), "wb");
|
||||||
|
if (out == nullptr)
|
||||||
|
throw std::runtime_error(std::string("Remaining times estimation failed.\nCannot open file for writing.\n"));
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(in, line))
|
||||||
|
{
|
||||||
|
if (!in.good())
|
||||||
|
{
|
||||||
|
fclose(out);
|
||||||
|
throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if REMAINING_TIME_USE_SINGLE_GCODE_COMMAND
|
||||||
|
// this function expects elapsed time for default and silent mode to be into two consecutive lines inside the gcode
|
||||||
|
if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT))
|
||||||
|
{
|
||||||
|
std::string default_elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length());
|
||||||
|
line = REMAINING_TIME_CMD + " D:" + _get_time_dhms(default_time - (float)atof(default_elapsed_time_str.c_str()));
|
||||||
|
|
||||||
|
std::string next_line;
|
||||||
|
std::getline(in, next_line);
|
||||||
|
if (!in.good())
|
||||||
|
{
|
||||||
|
fclose(out);
|
||||||
|
throw std::runtime_error(std::string("Remaining times estimation failed.\nError while reading from file.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boost::contains(next_line, ELAPSED_TIME_TAG_SILENT))
|
||||||
|
{
|
||||||
|
std::string silent_elapsed_time_str = next_line.substr(ELAPSED_TIME_TAG_SILENT.length());
|
||||||
|
line += " S:" + _get_time_dhms(silent_time - (float)atof(silent_elapsed_time_str.c_str())) + REMAINING_TIME_COMMENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// found horphaned default elapsed time, skip the remaining time line output
|
||||||
|
line = next_line;
|
||||||
|
}
|
||||||
|
else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT))
|
||||||
|
// found horphaned silent elapsed time, skip the remaining time line output
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
|
bool processed = false;
|
||||||
|
if (boost::contains(line, ELAPSED_TIME_TAG_DEFAULT))
|
||||||
|
{
|
||||||
|
std::string elapsed_time_str = line.substr(ELAPSED_TIME_TAG_DEFAULT.length());
|
||||||
|
line = REMAINING_TIME_CMD_DEFAULT + " " + _get_time_dhms(default_time - (float)atof(elapsed_time_str.c_str()));
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
else if (boost::contains(line, ELAPSED_TIME_TAG_SILENT))
|
||||||
|
{
|
||||||
|
std::string elapsed_time_str = line.substr(ELAPSED_TIME_TAG_SILENT.length());
|
||||||
|
line = REMAINING_TIME_CMD_SILENT + " " + _get_time_dhms(silent_time - (float)atof(elapsed_time_str.c_str()));
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processed)
|
||||||
|
line += REMAINING_TIME_COMMENT;
|
||||||
|
#endif // REMAINING_TIME_USE_SINGLE_GCODE_COMMAND
|
||||||
|
|
||||||
|
line += "\n";
|
||||||
|
fwrite((const void*)line.c_str(), 1, line.length(), out);
|
||||||
|
if (ferror(out))
|
||||||
|
{
|
||||||
|
in.close();
|
||||||
|
fclose(out);
|
||||||
|
boost::nowide::remove(path_tmp.c_str());
|
||||||
|
throw std::runtime_error(std::string("Remaining times estimation failed.\nIs the disk full?\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(out);
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
boost::nowide::remove(filename.c_str());
|
||||||
|
if (boost::nowide::rename(path_tmp.c_str(), filename.c_str()) != 0)
|
||||||
|
throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + filename + '\n' +
|
||||||
|
"Is " + path_tmp + " locked?" + '\n');
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeTimeEstimator::set_axis_position(EAxis axis, float position)
|
void GCodeTimeEstimator::set_axis_position(EAxis axis, float position)
|
||||||
@ -411,6 +537,66 @@ namespace Slic3r {
|
|||||||
set_global_positioning_type(Absolute);
|
set_global_positioning_type(Absolute);
|
||||||
set_e_local_positioning_type(Absolute);
|
set_e_local_positioning_type(Absolute);
|
||||||
|
|
||||||
|
switch (_mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case Default:
|
||||||
|
{
|
||||||
|
_set_default_as_default();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Silent:
|
||||||
|
{
|
||||||
|
_set_default_as_silent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeTimeEstimator::reset()
|
||||||
|
{
|
||||||
|
_reset_time();
|
||||||
|
#if ENABLE_MOVE_STATS
|
||||||
|
_moves_stats.clear();
|
||||||
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
_reset_blocks();
|
||||||
|
_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
float GCodeTimeEstimator::get_time() const
|
||||||
|
{
|
||||||
|
return _time;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GCodeTimeEstimator::get_time_dhms() const
|
||||||
|
{
|
||||||
|
return _get_time_dhms(get_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeTimeEstimator::_reset()
|
||||||
|
{
|
||||||
|
_curr.reset();
|
||||||
|
_prev.reset();
|
||||||
|
|
||||||
|
set_axis_position(X, 0.0f);
|
||||||
|
set_axis_position(Y, 0.0f);
|
||||||
|
set_axis_position(Z, 0.0f);
|
||||||
|
|
||||||
|
set_additional_time(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeTimeEstimator::_reset_time()
|
||||||
|
{
|
||||||
|
_time = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeTimeEstimator::_reset_blocks()
|
||||||
|
{
|
||||||
|
_blocks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GCodeTimeEstimator::_set_default_as_default()
|
||||||
|
{
|
||||||
set_feedrate(DEFAULT_FEEDRATE);
|
set_feedrate(DEFAULT_FEEDRATE);
|
||||||
set_acceleration(DEFAULT_ACCELERATION);
|
set_acceleration(DEFAULT_ACCELERATION);
|
||||||
set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION);
|
set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION);
|
||||||
@ -427,55 +613,30 @@ namespace Slic3r {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeTimeEstimator::reset()
|
void GCodeTimeEstimator::_set_default_as_silent()
|
||||||
{
|
{
|
||||||
_time = 0.0f;
|
set_feedrate(SILENT_FEEDRATE);
|
||||||
#if ENABLE_MOVE_STATS
|
set_acceleration(SILENT_ACCELERATION);
|
||||||
_moves_stats.clear();
|
set_retract_acceleration(SILENT_RETRACT_ACCELERATION);
|
||||||
#endif // ENABLE_MOVE_STATS
|
set_minimum_feedrate(SILENT_MINIMUM_FEEDRATE);
|
||||||
_reset_blocks();
|
set_minimum_travel_feedrate(SILENT_MINIMUM_TRAVEL_FEEDRATE);
|
||||||
_reset();
|
set_extrude_factor_override_percentage(SILENT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE);
|
||||||
|
|
||||||
|
for (unsigned char a = X; a < Num_Axis; ++a)
|
||||||
|
{
|
||||||
|
EAxis axis = (EAxis)a;
|
||||||
|
set_axis_max_feedrate(axis, SILENT_AXIS_MAX_FEEDRATE[a]);
|
||||||
|
set_axis_max_acceleration(axis, SILENT_AXIS_MAX_ACCELERATION[a]);
|
||||||
|
set_axis_max_jerk(axis, SILENT_AXIS_MAX_JERK[a]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float GCodeTimeEstimator::get_time() const
|
void GCodeTimeEstimator::_set_blocks_st_synchronize(bool state)
|
||||||
{
|
{
|
||||||
return _time;
|
for (Block& block : _blocks)
|
||||||
}
|
{
|
||||||
|
block.st_synchronized = state;
|
||||||
std::string GCodeTimeEstimator::get_time_hms() const
|
}
|
||||||
{
|
|
||||||
float timeinsecs = get_time();
|
|
||||||
int hours = (int)(timeinsecs / 3600.0f);
|
|
||||||
timeinsecs -= (float)hours * 3600.0f;
|
|
||||||
int minutes = (int)(timeinsecs / 60.0f);
|
|
||||||
timeinsecs -= (float)minutes * 60.0f;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GCodeTimeEstimator::_reset()
|
|
||||||
{
|
|
||||||
_curr.reset();
|
|
||||||
_prev.reset();
|
|
||||||
|
|
||||||
set_axis_position(X, 0.0f);
|
|
||||||
set_axis_position(Y, 0.0f);
|
|
||||||
set_axis_position(Z, 0.0f);
|
|
||||||
|
|
||||||
set_additional_time(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GCodeTimeEstimator::_reset_blocks()
|
|
||||||
{
|
|
||||||
_blocks.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeTimeEstimator::_calculate_time()
|
void GCodeTimeEstimator::_calculate_time()
|
||||||
@ -488,6 +649,9 @@ namespace Slic3r {
|
|||||||
|
|
||||||
for (const Block& block : _blocks)
|
for (const Block& block : _blocks)
|
||||||
{
|
{
|
||||||
|
if (block.st_synchronized)
|
||||||
|
continue;
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
#if ENABLE_MOVE_STATS
|
||||||
float block_time = 0.0f;
|
float block_time = 0.0f;
|
||||||
block_time += block.acceleration_time();
|
block_time += block.acceleration_time();
|
||||||
@ -1043,7 +1207,7 @@ namespace Slic3r {
|
|||||||
void GCodeTimeEstimator::_simulate_st_synchronize()
|
void GCodeTimeEstimator::_simulate_st_synchronize()
|
||||||
{
|
{
|
||||||
_calculate_time();
|
_calculate_time();
|
||||||
_reset_blocks();
|
_set_blocks_st_synchronize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeTimeEstimator::_forward_pass()
|
void GCodeTimeEstimator::_forward_pass()
|
||||||
@ -1052,6 +1216,9 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i)
|
for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i)
|
||||||
{
|
{
|
||||||
|
if (_blocks[i].st_synchronized || _blocks[i + 1].st_synchronized)
|
||||||
|
continue;
|
||||||
|
|
||||||
_planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]);
|
_planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1063,6 +1230,9 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
for (int i = (int)_blocks.size() - 1; i >= 1; --i)
|
for (int i = (int)_blocks.size() - 1; i >= 1; --i)
|
||||||
{
|
{
|
||||||
|
if (_blocks[i - 1].st_synchronized || _blocks[i].st_synchronized)
|
||||||
|
continue;
|
||||||
|
|
||||||
_planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]);
|
_planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1115,6 +1285,9 @@ namespace Slic3r {
|
|||||||
|
|
||||||
for (Block& b : _blocks)
|
for (Block& b : _blocks)
|
||||||
{
|
{
|
||||||
|
if (b.st_synchronized)
|
||||||
|
continue;
|
||||||
|
|
||||||
curr = next;
|
curr = next;
|
||||||
next = &b;
|
next = &b;
|
||||||
|
|
||||||
@ -1144,6 +1317,28 @@ namespace Slic3r {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GCodeTimeEstimator::_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;
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
#if ENABLE_MOVE_STATS
|
||||||
void GCodeTimeEstimator::_log_moves_stats() const
|
void GCodeTimeEstimator::_log_moves_stats() const
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,12 @@ namespace Slic3r {
|
|||||||
class GCodeTimeEstimator
|
class GCodeTimeEstimator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum EMode : unsigned char
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Silent
|
||||||
|
};
|
||||||
|
|
||||||
enum EUnits : unsigned char
|
enum EUnits : unsigned char
|
||||||
{
|
{
|
||||||
Millimeters,
|
Millimeters,
|
||||||
@ -135,6 +141,10 @@ namespace Slic3r {
|
|||||||
FeedrateProfile feedrate;
|
FeedrateProfile feedrate;
|
||||||
Trapezoid trapezoid;
|
Trapezoid trapezoid;
|
||||||
|
|
||||||
|
bool st_synchronized;
|
||||||
|
|
||||||
|
Block();
|
||||||
|
|
||||||
// Returns the length of the move covered by this block, in mm
|
// Returns the length of the move covered by this block, in mm
|
||||||
float move_length() const;
|
float move_length() const;
|
||||||
|
|
||||||
@ -188,18 +198,29 @@ namespace Slic3r {
|
|||||||
#endif // ENABLE_MOVE_STATS
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
EMode _mode;
|
||||||
GCodeReader _parser;
|
GCodeReader _parser;
|
||||||
State _state;
|
State _state;
|
||||||
Feedrates _curr;
|
Feedrates _curr;
|
||||||
Feedrates _prev;
|
Feedrates _prev;
|
||||||
BlocksList _blocks;
|
BlocksList _blocks;
|
||||||
float _time; // s
|
float _time; // s
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
#if ENABLE_MOVE_STATS
|
||||||
MovesStatsMap _moves_stats;
|
MovesStatsMap _moves_stats;
|
||||||
#endif // ENABLE_MOVE_STATS
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GCodeTimeEstimator();
|
explicit GCodeTimeEstimator(EMode mode);
|
||||||
|
|
||||||
|
// Adds the given gcode line
|
||||||
|
void add_gcode_line(const std::string& gcode_line);
|
||||||
|
|
||||||
|
void add_gcode_block(const char *ptr);
|
||||||
|
void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); }
|
||||||
|
|
||||||
|
// Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block()
|
||||||
|
void calculate_time();
|
||||||
|
|
||||||
// Calculates the time estimate from the given gcode in string format
|
// Calculates the time estimate from the given gcode in string format
|
||||||
void calculate_time_from_text(const std::string& gcode);
|
void calculate_time_from_text(const std::string& gcode);
|
||||||
@ -210,14 +231,12 @@ namespace Slic3r {
|
|||||||
// Calculates the time estimate from the gcode contained in given list of gcode lines
|
// 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);
|
void calculate_time_from_lines(const std::vector<std::string>& gcode_lines);
|
||||||
|
|
||||||
// Adds the given gcode line
|
// Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block()
|
||||||
void add_gcode_line(const std::string& gcode_line);
|
// and returns it in a formatted string
|
||||||
|
std::string get_elapsed_time_string();
|
||||||
|
|
||||||
void add_gcode_block(const char *ptr);
|
// Converts elapsed time lines, contained in the gcode saved with the given filename, into remaining time commands
|
||||||
void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); }
|
static bool post_process_elapsed_times(const std::string& filename, float default_time, float silent_time);
|
||||||
|
|
||||||
// Calculates the time estimate from the gcode lines added using add_gcode_line()
|
|
||||||
void calculate_time();
|
|
||||||
|
|
||||||
// Set current position on the given axis with the given value
|
// Set current position on the given axis with the given value
|
||||||
void set_axis_position(EAxis axis, float position);
|
void set_axis_position(EAxis axis, float position);
|
||||||
@ -275,13 +294,19 @@ namespace Slic3r {
|
|||||||
// Returns the estimated time, in seconds
|
// Returns the estimated time, in seconds
|
||||||
float get_time() const;
|
float get_time() const;
|
||||||
|
|
||||||
// Returns the estimated time, in format HHh MMm SSs
|
// Returns the estimated time, in format DDd HHh MMm SSs
|
||||||
std::string get_time_hms() const;
|
std::string get_time_dhms() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _reset();
|
void _reset();
|
||||||
|
void _reset_time();
|
||||||
void _reset_blocks();
|
void _reset_blocks();
|
||||||
|
|
||||||
|
void _set_default_as_default();
|
||||||
|
void _set_default_as_silent();
|
||||||
|
|
||||||
|
void _set_blocks_st_synchronize(bool state);
|
||||||
|
|
||||||
// Calculates the time estimate
|
// Calculates the time estimate
|
||||||
void _calculate_time();
|
void _calculate_time();
|
||||||
|
|
||||||
@ -353,6 +378,9 @@ namespace Slic3r {
|
|||||||
|
|
||||||
void _recalculate_trapezoids();
|
void _recalculate_trapezoids();
|
||||||
|
|
||||||
|
// Returns the given time is seconds in format DDd HHh MMm SSs
|
||||||
|
static std::string _get_time_dhms(float time_in_secs);
|
||||||
|
|
||||||
#if ENABLE_MOVE_STATS
|
#if ENABLE_MOVE_STATS
|
||||||
void _log_moves_stats() const;
|
void _log_moves_stats() const;
|
||||||
#endif // ENABLE_MOVE_STATS
|
#endif // ENABLE_MOVE_STATS
|
||||||
|
@ -233,7 +233,8 @@ public:
|
|||||||
PrintRegionPtrs regions;
|
PrintRegionPtrs regions;
|
||||||
PlaceholderParser placeholder_parser;
|
PlaceholderParser placeholder_parser;
|
||||||
// TODO: status_cb
|
// TODO: status_cb
|
||||||
std::string estimated_print_time;
|
std::string estimated_default_print_time;
|
||||||
|
std::string estimated_silent_print_time;
|
||||||
double total_used_filament, total_extruded_volume, total_cost, total_weight;
|
double total_used_filament, total_extruded_volume, total_cost, total_weight;
|
||||||
std::map<size_t, float> filament_stats;
|
std::map<size_t, float> filament_stats;
|
||||||
PrintState<PrintStep, psCount> state;
|
PrintState<PrintStep, psCount> state;
|
||||||
|
@ -152,8 +152,10 @@ _constant()
|
|||||||
%code%{ RETVAL = &THIS->skirt; %};
|
%code%{ RETVAL = &THIS->skirt; %};
|
||||||
Ref<ExtrusionEntityCollection> brim()
|
Ref<ExtrusionEntityCollection> brim()
|
||||||
%code%{ RETVAL = &THIS->brim; %};
|
%code%{ RETVAL = &THIS->brim; %};
|
||||||
std::string estimated_print_time()
|
std::string estimated_default_print_time()
|
||||||
%code%{ RETVAL = THIS->estimated_print_time; %};
|
%code%{ RETVAL = THIS->estimated_default_print_time; %};
|
||||||
|
std::string estimated_silent_print_time()
|
||||||
|
%code%{ RETVAL = THIS->estimated_silent_print_time; %};
|
||||||
|
|
||||||
PrintObjectPtrs* objects()
|
PrintObjectPtrs* objects()
|
||||||
%code%{ RETVAL = &THIS->objects; %};
|
%code%{ RETVAL = &THIS->objects; %};
|
||||||
|
Loading…
Reference in New Issue
Block a user