Merge branch 'lm_wipe_tower_weight' into master_27x

This commit is contained in:
Lukas Matena 2024-02-07 09:59:24 +01:00
commit 7fa632f8ef
6 changed files with 69 additions and 44 deletions

View File

@ -236,7 +236,7 @@ void GCodeGenerator::PlaceholderParserIntegration::init(const GCodeWriter &write
this->parser.set("zhop", this->opt_zhop);
}
void GCodeGenerator::PlaceholderParserIntegration::update_from_gcodewriter(const GCodeWriter &writer)
void GCodeGenerator::PlaceholderParserIntegration::update_from_gcodewriter(const GCodeWriter &writer, const WipeTowerData& wipe_tower_data)
{
memcpy(this->position.data(), writer.get_position().data(), sizeof(double) * 3);
this->opt_position->values = this->position;
@ -253,7 +253,19 @@ void GCodeGenerator::PlaceholderParserIntegration::update_from_gcodewriter(const
for (const Extruder &e : extruders) {
this->e_retracted[e.id()] = e.retracted();
this->e_restart_extra[e.id()] = e.restart_extra();
double v = e.extruded_volume();
// Wipe tower filament consumption has to be added separately, because that gcode is not generated by GCodeWriter.
double wt_vol = 0.;
const std::vector<std::pair<float, std::vector<float>>>& wtuf = wipe_tower_data.used_filament_until_layer;
if (!wtuf.empty()) {
auto it = std::lower_bound(wtuf.begin(), wtuf.end(), writer.get_position().z(),
[](const auto& a, const float& val) { return a.first < val; });
if (it == wtuf.end())
it = wtuf.end() - 1;
wt_vol = it->second[e.id()] * e.filament_crossection();
}
double v = e.extruded_volume() + wt_vol;
double w = v * e.filament_density() * 0.001;
this->opt_extruded_volume->values[e.id()] = v;
this->opt_extruded_weight->values[e.id()] = w;
@ -545,6 +557,29 @@ namespace DoExport {
}
} // namespace DoExport
GCodeGenerator::GCodeGenerator(const Print* print) :
m_origin(Vec2d::Zero()),
m_enable_loop_clipping(true),
m_enable_cooling_markers(false),
m_enable_extrusion_role_markers(false),
m_last_processor_extrusion_role(GCodeExtrusionRole::None),
m_layer_count(0),
m_layer_index(-1),
m_layer(nullptr),
m_object_layer_over_raft(false),
m_volumetric_speed(0),
m_last_extrusion_role(GCodeExtrusionRole::None),
m_last_width(0.0f),
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
m_last_mm3_per_mm(0.0),
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
m_brim_done(false),
m_second_layer_things_done(false),
m_silent_time_estimator_enabled(false),
m_current_instance({nullptr, -1}),
m_print(print)
{}
void GCodeGenerator::do_export(Print* print, const char* path, GCodeProcessorResult* result, ThumbnailsGeneratorCallback thumbnail_cb)
{
CNumericLocalesSetter locales_setter;
@ -742,8 +777,8 @@ namespace DoExport {
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 used_filament = extruder.used_filament() + (has_wipe_tower ? wipe_tower_data.used_filament_until_layer.back().second[extruder.id()] : 0.f);
double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? wipe_tower_data.used_filament_until_layer.back().second[extruder.id()] * extruder.filament_crossection() : 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) {
@ -896,7 +931,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
binary_data.file_metadata.raw_data.emplace_back("Producer", std::string(SLIC3R_APP_NAME) + " " + std::string(SLIC3R_VERSION));
// config data
encode_full_config(print, binary_data.slicer_metadata.raw_data);
encode_full_config(*m_print, binary_data.slicer_metadata.raw_data);
// printer data - this section contains duplicates from the slicer metadata
// that we just created. Find and copy the entries that we want to duplicate.
@ -1384,7 +1419,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
{
file.write("\n; prusaslicer_config = begin\n");
std::string full_config;
append_full_config(print, full_config);
append_full_config(*m_print, full_config);
if (!full_config.empty())
file.write(full_config);
file.write("; prusaslicer_config = end\n");
@ -1634,7 +1669,7 @@ std::string GCodeGenerator::placeholder_parser_process(
PlaceholderParserIntegration &ppi = m_placeholder_parser_integration;
try {
ppi.update_from_gcodewriter(m_writer);
ppi.update_from_gcodewriter(m_writer, m_print->wipe_tower_data());
std::string output = ppi.parser.process(templ, current_extruder_id, config_override, &ppi.output_config, &ppi.context);
ppi.validate_output_vector_variables();
@ -1740,7 +1775,7 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc
// Print the machine envelope G-code for the Marlin firmware based on the "machine_max_xxx" parameters.
// Do not process this piece of G-code by the time estimator, it already knows the values through another sources.
void GCodeGenerator::print_machine_envelope(GCodeOutputStream &file, Print &print)
void GCodeGenerator::print_machine_envelope(GCodeOutputStream &file, const Print &print)
{
const GCodeFlavor flavor = print.config().gcode_flavor.value;
if ( (flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware || flavor == gcfRepRapFirmware)
@ -1801,7 +1836,7 @@ void GCodeGenerator::print_machine_envelope(GCodeOutputStream &file, Print &prin
// Only do that if the start G-code does not already contain any M-code controlling an extruder temperature.
// M140 - Set Extruder Temperature
// M190 - Set Extruder Temperature and Wait
void GCodeGenerator::_print_first_layer_bed_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait)
void GCodeGenerator::_print_first_layer_bed_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait)
{
bool autoemit = print.config().autoemit_temperature_commands;
// Initial bed temperature based on the first extruder.
@ -1823,7 +1858,7 @@ void GCodeGenerator::_print_first_layer_bed_temperature(GCodeOutputStream &file,
// M104 - Set Extruder Temperature
// M109 - Set Extruder Temperature and Wait
// RepRapFirmware: G10 Sxx
void GCodeGenerator::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait)
void GCodeGenerator::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait)
{
bool autoemit = print.config().autoemit_temperature_commands;
// Is the bed temperature set by the provided custom G-code?
@ -2630,7 +2665,7 @@ void GCodeGenerator::apply_print_config(const PrintConfig &print_config)
m_scaled_resolution = scaled<double>(print_config.gcode_resolution.value);
}
void GCodeGenerator::append_full_config(const Print &print, std::string &str)
void GCodeGenerator::append_full_config(const Print& print, std::string &str)
{
std::vector<std::pair<std::string, std::string>> config;
encode_full_config(print, config);

View File

@ -53,6 +53,7 @@ namespace Slic3r {
// Forward declarations.
class GCodeGenerator;
struct WipeTowerData;
namespace { struct Item; }
struct PrintInstance;
@ -116,28 +117,8 @@ struct PrintObjectInstance
class GCodeGenerator {
public:
GCodeGenerator() :
m_origin(Vec2d::Zero()),
m_enable_loop_clipping(true),
m_enable_cooling_markers(false),
m_enable_extrusion_role_markers(false),
m_last_processor_extrusion_role(GCodeExtrusionRole::None),
m_layer_count(0),
m_layer_index(-1),
m_layer(nullptr),
m_object_layer_over_raft(false),
m_volumetric_speed(0),
m_last_extrusion_role(GCodeExtrusionRole::None),
m_last_width(0.0f),
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
m_last_mm3_per_mm(0.0),
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
m_brim_done(false),
m_second_layer_things_done(false),
m_silent_time_estimator_enabled(false),
m_current_instance({nullptr, -1})
{}
public:
GCodeGenerator(const Print* print = nullptr); // The default value is only used in unit tests.
~GCodeGenerator() = default;
// throws std::runtime_exception on error,
@ -376,7 +357,7 @@ private:
struct PlaceholderParserIntegration {
void reset();
void init(const GCodeWriter &config);
void update_from_gcodewriter(const GCodeWriter &writer);
void update_from_gcodewriter(const GCodeWriter &writer, const WipeTowerData& wipe_tower_data);
void validate_output_vector_variables();
PlaceholderParser parser;
@ -468,11 +449,14 @@ private:
// Processor
GCodeProcessor m_processor;
// Back-pointer to Print (const).
const Print* m_print;
std::string _extrude(
const ExtrusionAttributes &attribs, const Geometry::ArcWelder::Path &path, const std::string_view description, double speed = -1);
void print_machine_envelope(GCodeOutputStream &file, Print &print);
void _print_first_layer_bed_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
void print_machine_envelope(GCodeOutputStream &file, const Print &print);
void _print_first_layer_bed_temperature(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, const Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
// On the first printing layer. This flag triggers first layer speeds.
bool on_first_layer() const { return m_layer != nullptr && m_layer->id() == 0; }
// To control print speed of 1st object layer over raft interface.

View File

@ -1569,8 +1569,9 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
}
}
for (auto& used : m_used_filament_length) // reset used filament stats
used = 0.f;
m_used_filament_length.assign(m_used_filament_length.size(), 0.f); // reset used filament stats
assert(m_used_filament_length_until_layer.empty());
m_used_filament_length_until_layer.emplace_back(0.f, m_used_filament_length);
m_old_temperature = -1; // reset last temperature written in the gcode
@ -1613,6 +1614,10 @@ void WipeTower::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &
}
result.emplace_back(std::move(layer_result));
if (m_used_filament_length_until_layer.empty() || m_used_filament_length_until_layer.back().first != layer.z)
m_used_filament_length_until_layer.emplace_back();
m_used_filament_length_until_layer.back() = std::make_pair(layer.z, m_used_filament_length);
}
}

View File

@ -223,7 +223,7 @@ public:
return m_current_layer_finished;
}
std::vector<float> get_used_filament() const { return m_used_filament_length; }
std::vector<std::pair<float, std::vector<float>>> get_used_filament_until_layer() const { return m_used_filament_length_until_layer; }
int get_number_of_toolchanges() const { return m_num_tool_changes; }
struct FilamentParameters {
@ -384,6 +384,7 @@ private:
// Stores information about used filament length per extruder:
std::vector<float> m_used_filament_length;
std::vector<std::pair<float, std::vector<float>>> m_used_filament_length_until_layer;
// Return index of first toolchange that switches to non-soluble extruder
// ot -1 if there is no such toolchange.

View File

@ -1055,7 +1055,7 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor
this->set_status(90, message);
// Create GCode on heap, it has quite a lot of data.
std::unique_ptr<GCodeGenerator> gcode(new GCodeGenerator);
std::unique_ptr<GCodeGenerator> gcode(new GCodeGenerator(const_cast<const Print*>(this)));
gcode->do_export(this, path.c_str(), result, thumbnail_cb);
if (m_conflict_result.has_value())
@ -1581,7 +1581,7 @@ void Print::_make_wipe_tower()
m_wipe_tower_data.final_purge = Slic3r::make_unique<WipeTower::ToolChangeResult>(
wipe_tower.tool_change((unsigned int)(-1)));
m_wipe_tower_data.used_filament = wipe_tower.get_used_filament();
m_wipe_tower_data.used_filament_until_layer = wipe_tower.get_used_filament_until_layer();
m_wipe_tower_data.number_of_toolchanges = wipe_tower.get_number_of_toolchanges();
m_wipe_tower_data.width = wipe_tower.width();
m_wipe_tower_data.first_layer_height = config().first_layer_height;

View File

@ -451,7 +451,7 @@ struct WipeTowerData
std::unique_ptr<std::vector<WipeTower::ToolChangeResult>> priming;
std::vector<std::vector<WipeTower::ToolChangeResult>> tool_changes;
std::unique_ptr<WipeTower::ToolChangeResult> final_purge;
std::vector<float> used_filament;
std::vector<std::pair<float, std::vector<float>>> used_filament_until_layer;
int number_of_toolchanges;
// Depth of the wipe tower to pass to GLCanvas3D for exact bounding box:
@ -471,7 +471,7 @@ struct WipeTowerData
priming.reset(nullptr);
tool_changes.clear();
final_purge.reset(nullptr);
used_filament.clear();
used_filament_until_layer.clear();
number_of_toolchanges = -1;
depth = 0.f;
z_and_depth_pairs.clear();