Attempted to reenable the old pressure equalizer and fix its issues.

This commit is contained in:
Lukáš Hejl 2022-04-05 11:56:10 +02:00
parent 9be524b01b
commit 0463518dc3
10 changed files with 178 additions and 142 deletions

View File

@ -104,8 +104,8 @@ add_library(libslic3r STATIC
GCode/FindReplace.hpp GCode/FindReplace.hpp
GCode/PostProcessor.cpp GCode/PostProcessor.cpp
GCode/PostProcessor.hpp GCode/PostProcessor.hpp
# GCode/PressureEqualizer.cpp GCode/PressureEqualizer.cpp
# GCode/PressureEqualizer.hpp GCode/PressureEqualizer.hpp
GCode/PrintExtents.cpp GCode/PrintExtents.cpp
GCode/PrintExtents.hpp GCode/PrintExtents.hpp
GCode/SpiralVase.cpp GCode/SpiralVase.cpp

View File

@ -1108,14 +1108,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
if (print.config().spiral_vase.value) if (print.config().spiral_vase.value)
m_spiral_vase = make_unique<SpiralVase>(print.config()); m_spiral_vase = make_unique<SpiralVase>(print.config());
#ifdef HAS_PRESSURE_EQUALIZER
if (print.config().max_volumetric_extrusion_rate_slope_positive.value > 0 || if (print.config().max_volumetric_extrusion_rate_slope_positive.value > 0 ||
print.config().max_volumetric_extrusion_rate_slope_negative.value > 0) print.config().max_volumetric_extrusion_rate_slope_negative.value > 0)
m_pressure_equalizer = make_unique<PressureEqualizer>(&print.config()); m_pressure_equalizer = make_unique<PressureEqualizer>(print.config());
m_enable_extrusion_role_markers = (bool)m_pressure_equalizer; m_enable_extrusion_role_markers = (bool)m_pressure_equalizer;
#else /* HAS_PRESSURE_EQUALIZER */
m_enable_extrusion_role_markers = false;
#endif /* HAS_PRESSURE_EQUALIZER */
// Write information on the generator. // Write information on the generator.
file.write_format("; %s\n\n", Slic3r::header_slic3r_generated().c_str()); file.write_format("; %s\n\n", Slic3r::header_slic3r_generated().c_str());
@ -1364,10 +1361,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
// and export G-code into file. // and export G-code into file.
this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file); this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file);
#ifdef HAS_PRESSURE_EQUALIZER
if (m_pressure_equalizer)
file.write(m_pressure_equalizer->process("", true));
#endif /* HAS_PRESSURE_EQUALIZER */
++ finished_objects; ++ finished_objects;
// Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed. // Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
// Reset it when starting another object from 1st layer. // Reset it when starting another object from 1st layer.
@ -1424,10 +1417,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
// and export G-code into file. // and export G-code into file.
this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file); this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file);
#ifdef HAS_PRESSURE_EQUALIZER
if (m_pressure_equalizer)
file.write(m_pressure_equalizer->process("", true));
#endif /* HAS_PRESSURE_EQUALIZER */
if (m_wipe_tower) if (m_wipe_tower)
// Purge the extruder, pull out the active filament. // Purge the extruder, pull out the active filament.
file.write(m_wipe_tower->finalize(*this)); file.write(m_wipe_tower->finalize(*this));
@ -1555,16 +1544,20 @@ void GCode::process_layers(
} }
}); });
const auto spiral_vase = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order, const auto spiral_vase = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&spiral_vase = *this->m_spiral_vase.get()](GCode::LayerResult in) -> GCode::LayerResult { [&spiral_vase = *this->m_spiral_vase](GCode::LayerResult in) -> GCode::LayerResult {
spiral_vase.enable(in.spiral_vase_enable); spiral_vase.enable(in.spiral_vase_enable);
return { spiral_vase.process_layer(std::move(in.gcode)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush }; return { spiral_vase.process_layer(std::move(in.gcode)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush, in.pressure_equalizer_buffer_flush };
});
const auto pressure_equalizer = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&pressure_equalizer = *this->m_pressure_equalizer](GCode::LayerResult in) -> GCode::LayerResult {
return { std::string(pressure_equalizer.process_layer(std::move(in.gcode.c_str()), in.pressure_equalizer_buffer_flush)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush, in.pressure_equalizer_buffer_flush };
}); });
const auto cooling = tbb::make_filter<GCode::LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order, const auto cooling = tbb::make_filter<GCode::LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&cooling_buffer = *this->m_cooling_buffer.get()](GCode::LayerResult in) -> std::string { [&cooling_buffer = *this->m_cooling_buffer](GCode::LayerResult in) -> std::string {
return cooling_buffer.process_layer(std::move(in.gcode), in.layer_id, in.cooling_buffer_flush); return cooling_buffer.process_layer(std::move(in.gcode), in.layer_id, in.cooling_buffer_flush);
}); });
const auto find_replace = tbb::make_filter<std::string, std::string>(slic3r_tbb_filtermode::serial_in_order, const auto find_replace = tbb::make_filter<std::string, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&self = *this->m_find_replace.get()](std::string s) -> std::string { [&self = *this->m_find_replace](std::string s) -> std::string {
return self.process_layer(std::move(s)); return self.process_layer(std::move(s));
}); });
const auto output = tbb::make_filter<std::string, void>(slic3r_tbb_filtermode::serial_in_order, const auto output = tbb::make_filter<std::string, void>(slic3r_tbb_filtermode::serial_in_order,
@ -1577,14 +1570,22 @@ void GCode::process_layers(
// The pipeline elements are joined using const references, thus no copying is performed. // The pipeline elements are joined using const references, thus no copying is performed.
output_stream.find_replace_supress(); output_stream.find_replace_supress();
if (m_spiral_vase && m_find_replace) if (m_spiral_vase && m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output); tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase && m_find_replace)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
else if (m_spiral_vase && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & output);
else if (m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase) else if (m_spiral_vase)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output); tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
else if (m_find_replace) else if (m_find_replace)
tbb::parallel_pipeline(12, generator & cooling & find_replace & output); tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
else if (m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & output);
else else
tbb::parallel_pipeline(12, generator & cooling & output); tbb::parallel_pipeline(12, generator & cooling & output);
output_stream.find_replace_enable(); output_stream.find_replace_enable();
} }
@ -1612,16 +1613,20 @@ void GCode::process_layers(
} }
}); });
const auto spiral_vase = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order, const auto spiral_vase = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&spiral_vase = *this->m_spiral_vase.get()](GCode::LayerResult in)->GCode::LayerResult { [&spiral_vase = *this->m_spiral_vase](GCode::LayerResult in)->GCode::LayerResult {
spiral_vase.enable(in.spiral_vase_enable); spiral_vase.enable(in.spiral_vase_enable);
return { spiral_vase.process_layer(std::move(in.gcode)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush }; return { spiral_vase.process_layer(std::move(in.gcode)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush, in.pressure_equalizer_buffer_flush };
});
const auto pressure_equalizer = tbb::make_filter<GCode::LayerResult, GCode::LayerResult>(slic3r_tbb_filtermode::serial_in_order,
[&pressure_equalizer = *this->m_pressure_equalizer](GCode::LayerResult in) -> GCode::LayerResult {
return { std::string(pressure_equalizer.process_layer(std::move(in.gcode.c_str()), in.pressure_equalizer_buffer_flush)), in.layer_id, in.spiral_vase_enable, in.cooling_buffer_flush, in.pressure_equalizer_buffer_flush };
}); });
const auto cooling = tbb::make_filter<GCode::LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order, const auto cooling = tbb::make_filter<GCode::LayerResult, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&cooling_buffer = *this->m_cooling_buffer.get()](GCode::LayerResult in)->std::string { [&cooling_buffer = *this->m_cooling_buffer](GCode::LayerResult in)->std::string {
return cooling_buffer.process_layer(std::move(in.gcode), in.layer_id, in.cooling_buffer_flush); return cooling_buffer.process_layer(std::move(in.gcode), in.layer_id, in.cooling_buffer_flush);
}); });
const auto find_replace = tbb::make_filter<std::string, std::string>(slic3r_tbb_filtermode::serial_in_order, const auto find_replace = tbb::make_filter<std::string, std::string>(slic3r_tbb_filtermode::serial_in_order,
[&self = *this->m_find_replace.get()](std::string s) -> std::string { [&self = *this->m_find_replace](std::string s) -> std::string {
return self.process_layer(std::move(s)); return self.process_layer(std::move(s));
}); });
const auto output = tbb::make_filter<std::string, void>(slic3r_tbb_filtermode::serial_in_order, const auto output = tbb::make_filter<std::string, void>(slic3r_tbb_filtermode::serial_in_order,
@ -1634,14 +1639,22 @@ void GCode::process_layers(
// The pipeline elements are joined using const references, thus no copying is performed. // The pipeline elements are joined using const references, thus no copying is performed.
output_stream.find_replace_supress(); output_stream.find_replace_supress();
if (m_spiral_vase && m_find_replace) if (m_spiral_vase && m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output); tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase && m_find_replace)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & find_replace & output);
else if (m_spiral_vase && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & spiral_vase & pressure_equalizer & cooling & output);
else if (m_find_replace && m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & find_replace & output);
else if (m_spiral_vase) else if (m_spiral_vase)
tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output); tbb::parallel_pipeline(12, generator & spiral_vase & cooling & output);
else if (m_find_replace) else if (m_find_replace)
tbb::parallel_pipeline(12, generator & cooling & find_replace & output); tbb::parallel_pipeline(12, generator & cooling & find_replace & output);
else if (m_pressure_equalizer)
tbb::parallel_pipeline(12, generator & pressure_equalizer & cooling & output);
else else
tbb::parallel_pipeline(12, generator & cooling & output); tbb::parallel_pipeline(12, generator & cooling & output);
output_stream.find_replace_enable(); output_stream.find_replace_enable();
} }
@ -2097,7 +2110,7 @@ GCode::LayerResult GCode::process_layer(
} }
} }
const Layer &layer = (object_layer != nullptr) ? *object_layer : *support_layer; const Layer &layer = (object_layer != nullptr) ? *object_layer : *support_layer;
GCode::LayerResult result { {}, layer.id(), false, last_layer }; GCode::LayerResult result { {}, layer.id(), false, last_layer, last_layer};
if (layer_tools.extruders.empty()) if (layer_tools.extruders.empty())
// Nothing to extrude. // Nothing to extrude.
return result; return result;
@ -2480,13 +2493,11 @@ GCode::LayerResult GCode::process_layer(
// Flush the cooling buffer at each object layer or possibly at the last layer, even if it contains just supports (This should not happen). // Flush the cooling buffer at each object layer or possibly at the last layer, even if it contains just supports (This should not happen).
object_layer || last_layer); object_layer || last_layer);
#ifdef HAS_PRESSURE_EQUALIZER
// Apply pressure equalization if enabled; // Apply pressure equalization if enabled;
// printf("G-code before filter:\n%s\n", gcode.c_str()); // printf("G-code before filter:\n%s\n", gcode.c_str());
if (m_pressure_equalizer) if (m_pressure_equalizer)
gcode = m_pressure_equalizer->process(gcode.c_str(), false); gcode = m_pressure_equalizer->process(gcode.c_str(), false);
// printf("G-code after filter:\n%s\n", out.c_str()); // printf("G-code after filter:\n%s\n", out.c_str());
#endif /* HAS_PRESSURE_EQUALIZER */
file.write(gcode); file.write(gcode);
#endif #endif

View File

@ -23,9 +23,7 @@
#include <map> #include <map>
#include <string> #include <string>
#ifdef HAS_PRESSURE_EQUALIZER
#include "GCode/PressureEqualizer.hpp" #include "GCode/PressureEqualizer.hpp"
#endif /* HAS_PRESSURE_EQUALIZER */
namespace Slic3r { namespace Slic3r {
@ -235,6 +233,8 @@ private:
bool spiral_vase_enable { false }; bool spiral_vase_enable { false };
// Should the cooling buffer content be flushed at the end of this layer? // Should the cooling buffer content be flushed at the end of this layer?
bool cooling_buffer_flush { false }; bool cooling_buffer_flush { false };
// Should the PressureEqualizer buffer content be flushed at the end of this layer?
bool pressure_equalizer_buffer_flush { false };
}; };
LayerResult process_layer( LayerResult process_layer(
const Print &print, const Print &print,
@ -406,9 +406,7 @@ private:
std::unique_ptr<CoolingBuffer> m_cooling_buffer; std::unique_ptr<CoolingBuffer> m_cooling_buffer;
std::unique_ptr<SpiralVase> m_spiral_vase; std::unique_ptr<SpiralVase> m_spiral_vase;
std::unique_ptr<GCodeFindReplace> m_find_replace; std::unique_ptr<GCodeFindReplace> m_find_replace;
#ifdef HAS_PRESSURE_EQUALIZER
std::unique_ptr<PressureEqualizer> m_pressure_equalizer; std::unique_ptr<PressureEqualizer> m_pressure_equalizer;
#endif /* HAS_PRESSURE_EQUALIZER */
std::unique_ptr<WipeTowerIntegration> m_wipe_tower; std::unique_ptr<WipeTowerIntegration> m_wipe_tower;
// Heights (print_z) at which the skirt has already been extruded. // Heights (print_z) at which the skirt has already been extruded.

View File

@ -7,19 +7,24 @@
#include "../LocalesUtils.hpp" #include "../LocalesUtils.hpp"
#include "PressureEqualizer.hpp" #include "PressureEqualizer.hpp"
#include "fast_float/fast_float.h"
namespace Slic3r { namespace Slic3r {
PressureEqualizer::PressureEqualizer(const Slic3r::GCodeConfig *config) : static constexpr const std::array<char, 18> EXTRUSION_ROLE_TAG = {";_EXTRUSION_ROLE:"};
m_config(config) static constexpr const size_t EXTRUSION_ROLE_TAG_LENGTH = EXTRUSION_ROLE_TAG.size() - 1;
static constexpr const std::array<char, 14> EXTRUDE_END_TAG = {";_EXTRUDE_END"};
static constexpr const size_t EXTRUDE_END_TAG_LENGTH = EXTRUDE_END_TAG.size() - 1;
static constexpr const std::array<char, 20> EXTRUDE_SET_SPEED_TAG = {";_EXTRUDE_SET_SPEED"};
static constexpr const size_t EXTRUDE_SET_SPEED_TAG_LENGTH = EXTRUDE_SET_SPEED_TAG.size() - 1;
static constexpr const std::array<char, 21> EXTERNAL_PERIMETER_TAG = {";_EXTERNAL_PERIMETER"};
static constexpr const size_t EXTERNAL_PERIMETER_TAG_LENGTH = EXTERNAL_PERIMETER_TAG.size() - 1;
PressureEqualizer::PressureEqualizer(const Slic3r::GCodeConfig &config) : m_config(config)
{ {
reset(); reset();
} }
PressureEqualizer::~PressureEqualizer()
{
}
void PressureEqualizer::reset() void PressureEqualizer::reset()
{ {
circular_buffer_pos = 0; circular_buffer_pos = 0;
@ -40,9 +45,8 @@ void PressureEqualizer::reset()
// Calculate filamet crossections for the multiple extruders. // Calculate filamet crossections for the multiple extruders.
m_filament_crossections.clear(); m_filament_crossections.clear();
for (size_t i = 0; i < m_config->filament_diameter.values.size(); ++ i) { for (double r : m_config.filament_diameter.values) {
double r = m_config->filament_diameter.values[i]; double a = 0.25f * M_PI * r * r;
double a = 0.25f*M_PI*r*r;
m_filament_crossections.push_back(float(a)); m_filament_crossections.push_back(float(a));
} }
@ -50,10 +54,8 @@ void PressureEqualizer::reset()
// Volumetric rate of a 0.45mm x 0.2mm extrusion at 60mm/s XY movement: 0.45*0.2*60*60=5.4*60 = 324 mm^3/min // Volumetric rate of a 0.45mm x 0.2mm extrusion at 60mm/s XY movement: 0.45*0.2*60*60=5.4*60 = 324 mm^3/min
// Volumetric rate of a 0.45mm x 0.2mm extrusion at 20mm/s XY movement: 0.45*0.2*20*60=1.8*60 = 108 mm^3/min // Volumetric rate of a 0.45mm x 0.2mm extrusion at 20mm/s XY movement: 0.45*0.2*20*60=1.8*60 = 108 mm^3/min
// Slope of the volumetric rate, changing from 20mm/s to 60mm/s over 2 seconds: (5.4-1.8)*60*60/2=60*60*1.8 = 6480 mm^3/min^2 = 1.8 mm^3/s^2 // Slope of the volumetric rate, changing from 20mm/s to 60mm/s over 2 seconds: (5.4-1.8)*60*60/2=60*60*1.8 = 6480 mm^3/min^2 = 1.8 mm^3/s^2
m_max_volumetric_extrusion_rate_slope_positive = (m_config == NULL) ? 6480.f : m_max_volumetric_extrusion_rate_slope_positive = float(m_config.max_volumetric_extrusion_rate_slope_positive.value) * 60.f * 60.f;
m_config->max_volumetric_extrusion_rate_slope_positive.value * 60.f * 60.f; m_max_volumetric_extrusion_rate_slope_negative = float(m_config.max_volumetric_extrusion_rate_slope_negative.value) * 60.f * 60.f;
m_max_volumetric_extrusion_rate_slope_negative = (m_config == NULL) ? 6480.f :
m_config->max_volumetric_extrusion_rate_slope_negative.value * 60.f * 60.f;
for (size_t i = 0; i < numExtrusionRoles; ++ i) { for (size_t i = 0; i < numExtrusionRoles; ++ i) {
m_max_volumetric_extrusion_rate_slopes[i].negative = m_max_volumetric_extrusion_rate_slope_negative; m_max_volumetric_extrusion_rate_slopes[i].negative = m_max_volumetric_extrusion_rate_slope_negative;
@ -67,16 +69,19 @@ void PressureEqualizer::reset()
m_max_volumetric_extrusion_rate_slopes[erGapFill].negative = 0; m_max_volumetric_extrusion_rate_slopes[erGapFill].negative = 0;
m_max_volumetric_extrusion_rate_slopes[erGapFill].positive = 0; m_max_volumetric_extrusion_rate_slopes[erGapFill].positive = 0;
#ifdef PRESSURE_EQUALIZER_STATISTIC
m_stat.reset(); m_stat.reset();
#endif
line_idx = 0; line_idx = 0;
} }
const char* PressureEqualizer::process(const char *szGCode, bool flush) const char* PressureEqualizer::process_layer(const char *szGCode, bool flush)
{ {
// Reset length of the output_buffer. // Reset length of the output_buffer.
output_buffer_length = 0; output_buffer_length = 0;
if (szGCode != 0) { if (szGCode != nullptr) {
const char *p = szGCode; const char *p = szGCode;
while (*p != 0) { while (*p != 0) {
// Find end of the line. // Find end of the line.
@ -91,7 +96,7 @@ const char* PressureEqualizer::process(const char *szGCode, bool flush)
// Process a G-code line, store it into the provided GCodeLine object. // Process a G-code line, store it into the provided GCodeLine object.
size_t idx_tail = circular_buffer_pos; size_t idx_tail = circular_buffer_pos;
circular_buffer_pos = circular_buffer_idx_next(circular_buffer_pos); circular_buffer_pos = circular_buffer_idx_next(circular_buffer_pos);
if (! process_line(p, endl - p, circular_buffer[idx_tail])) { if (! process_line(p, endl, circular_buffer[idx_tail])) {
// The line has to be forgotten. It contains comment marks, which shall be // The line has to be forgotten. It contains comment marks, which shall be
// filtered out of the target g-code. // filtered out of the target g-code.
circular_buffer_pos = idx_tail; circular_buffer_pos = idx_tail;
@ -114,8 +119,8 @@ const char* PressureEqualizer::process(const char *szGCode, bool flush)
assert(circular_buffer_items == 0); assert(circular_buffer_items == 0);
circular_buffer_pos = 0; circular_buffer_pos = 0;
#if 1 #ifdef PRESSURE_EQUALIZER_STATISTIC
printf("Statistics: \n"); printf("Statistics: \n");
printf("Minimum volumetric extrusion rate: %f\n", m_stat.volumetric_extrusion_rate_min); printf("Minimum volumetric extrusion rate: %f\n", m_stat.volumetric_extrusion_rate_min);
printf("Maximum volumetric extrusion rate: %f\n", m_stat.volumetric_extrusion_rate_max); printf("Maximum volumetric extrusion rate: %f\n", m_stat.volumetric_extrusion_rate_max);
if (m_stat.extrusion_length > 0) if (m_stat.extrusion_length > 0)
@ -125,7 +130,10 @@ const char* PressureEqualizer::process(const char *szGCode, bool flush)
#endif #endif
} }
return output_buffer.data(); if (output_buffer_length > 0)
return output_buffer.data();
return "\0";
} }
// Is a white space? // Is a white space?
@ -146,32 +154,41 @@ static void eatws(const char *&line)
// If succeeded, the line pointer is advanced. // If succeeded, the line pointer is advanced.
static inline int parse_int(const char *&line) static inline int parse_int(const char *&line)
{ {
char *endptr = NULL; char *endptr = nullptr;
long result = strtol(line, &endptr, 10); long result = strtol(line, &endptr, 10);
if (endptr == NULL || !is_ws_or_eol(*endptr)) if (endptr == nullptr || !is_ws_or_eol(*endptr))
throw Slic3r::RuntimeError("PressureEqualizer: Error parsing an int"); throw Slic3r::RuntimeError("PressureEqualizer: Error parsing an int");
line = endptr; line = endptr;
return int(result); return int(result);
}; };
float string_to_float_decimal_point(const char *line, const size_t str_len, size_t* pos)
{
float out;
size_t p = fast_float::from_chars(line, line + str_len, out).ptr - line;
if (pos)
*pos = p;
return out;
}
// Parse an int starting at the current position of a line. // Parse an int starting at the current position of a line.
// If succeeded, the line pointer is advanced. // If succeeded, the line pointer is advanced.
static inline float parse_float(const char *&line) static inline float parse_float(const char *&line, const size_t line_length)
{ {
char *endptr = NULL; size_t endptr = 0;
float result = string_to_double_decimal_point(line, &endptr); auto result = string_to_float_decimal_point(line, line_length, &endptr);
if (endptr == NULL || !is_ws_or_eol(*endptr)) if (endptr == 0 || !is_ws_or_eol(*(line + endptr)))
throw Slic3r::RuntimeError("PressureEqualizer: Error parsing a float"); throw Slic3r::RuntimeError("PressureEqualizer: Error parsing a float");
line = endptr; line = line + endptr;
return result; return result;
}; };
bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLine &buf) bool PressureEqualizer::process_line(const char *line, const char *line_end, GCodeLine &buf)
{ {
static constexpr const char *EXTRUSION_ROLE_TAG = ";_EXTRUSION_ROLE:"; const size_t len = line_end - line;
if (strncmp(line, EXTRUSION_ROLE_TAG, strlen(EXTRUSION_ROLE_TAG)) == 0) { if (strncmp(line, EXTRUSION_ROLE_TAG.data(), EXTRUSION_ROLE_TAG_LENGTH) == 0) {
line += strlen(EXTRUSION_ROLE_TAG); line += EXTRUSION_ROLE_TAG_LENGTH;
int role = atoi(line); int role = atoi(line);
m_current_extrusion_role = ExtrusionRole(role); m_current_extrusion_role = ExtrusionRole(role);
++ line_idx; ++ line_idx;
@ -233,8 +250,8 @@ bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLi
if (i == -1) if (i == -1)
throw Slic3r::RuntimeError(std::string("GCode::PressureEqualizer: Invalid axis for G0/G1: ") + axis); throw Slic3r::RuntimeError(std::string("GCode::PressureEqualizer: Invalid axis for G0/G1: ") + axis);
buf.pos_provided[i] = true; buf.pos_provided[i] = true;
new_pos[i] = parse_float(line); new_pos[i] = parse_float(line, line_end - line);
if (i == 3 && m_config->use_relative_e_distances.value) if (i == 3 && m_config.use_relative_e_distances.value)
new_pos[i] += m_current_pos[i]; new_pos[i] += m_current_pos[i];
changed[i] = new_pos[i] != m_current_pos[i]; changed[i] = new_pos[i] != m_current_pos[i];
eatws(line); eatws(line);
@ -263,15 +280,17 @@ bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLi
buf.volumetric_extrusion_rate = rate; buf.volumetric_extrusion_rate = rate;
buf.volumetric_extrusion_rate_start = rate; buf.volumetric_extrusion_rate_start = rate;
buf.volumetric_extrusion_rate_end = rate; buf.volumetric_extrusion_rate_end = rate;
#ifdef PRESSURE_EQUALIZER_STATISTIC
m_stat.update(rate, sqrt(len2)); m_stat.update(rate, sqrt(len2));
#endif
#ifdef PRESSURE_EQUALIZER_DEBUG
if (rate < 40.f) { if (rate < 40.f) {
printf("Extremely low flow rate: %f. Line %d, Length: %f, extrusion: %f Old position: (%f, %f, %f), new position: (%f, %f, %f)\n", printf("Extremely low flow rate: %f. Line %d, Length: %f, extrusion: %f Old position: (%f, %f, %f), new position: (%f, %f, %f)\n",
rate, rate, int(line_idx), sqrt(len2), sqrt((diff[3] * diff[3]) / len2), m_current_pos[0], m_current_pos[1], m_current_pos[2],
int(line_idx), new_pos[0], new_pos[1], new_pos[2]);
sqrt(len2), sqrt((diff[3]*diff[3])/len2),
m_current_pos[0], m_current_pos[1], m_current_pos[2],
new_pos[0], new_pos[1], new_pos[2]);
} }
#endif
} }
} else if (changed[0] || changed[1] || changed[2]) { } else if (changed[0] || changed[1] || changed[2]) {
// Moving without extrusion. // Moving without extrusion.
@ -292,11 +311,11 @@ bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLi
case 'X': case 'X':
case 'Y': case 'Y':
case 'Z': case 'Z':
m_current_pos[axis - 'X'] = (!is_ws_or_eol(*line)) ? parse_float(line) : 0.f; m_current_pos[axis - 'X'] = (!is_ws_or_eol(*line)) ? parse_float(line, line_end - line) : 0.f;
set = true; set = true;
break; break;
case 'E': case 'E':
m_current_pos[3] = (!is_ws_or_eol(*line)) ? parse_float(line) : 0.f; m_current_pos[3] = (!is_ws_or_eol(*line)) ? parse_float(line, line_end - line) : 0.f;
set = true; set = true;
break; break;
default: default:
@ -360,7 +379,7 @@ bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLi
void PressureEqualizer::output_gcode_line(GCodeLine &line) void PressureEqualizer::output_gcode_line(GCodeLine &line)
{ {
if (! line.modified) { if (!line.modified) {
push_to_output(line.raw.data(), line.raw_length, true); push_to_output(line.raw.data(), line.raw_length, true);
return; return;
} }
@ -370,14 +389,11 @@ void PressureEqualizer::output_gcode_line(GCodeLine &line)
const char *comment = line.raw.data(); const char *comment = line.raw.data();
while (*comment != ';' && *comment != 0) ++comment; while (*comment != ';' && *comment != 0) ++comment;
if (*comment != ';') if (*comment != ';')
comment = NULL; comment = nullptr;
// Emit the line with lowered extrusion rates. // Emit the line with lowered extrusion rates.
float l2 = line.dist_xyz2(); float l = line.dist_xyz();
float l = sqrt(l2); if (auto nSegments = size_t(ceil(l / m_max_segment_length)); nSegments == 1) { // Just update this segment.
size_t nSegments = size_t(ceil(l / m_max_segment_length));
if (nSegments == 1) {
// Just update this segment.
push_line_to_output(line, line.feedrate() * line.volumetric_correction_avg(), comment); push_line_to_output(line, line.feedrate() * line.volumetric_correction_avg(), comment);
} else { } else {
bool accelerating = line.volumetric_extrusion_rate_start < line.volumetric_extrusion_rate_end; bool accelerating = line.volumetric_extrusion_rate_start < line.volumetric_extrusion_rate_end;
@ -386,8 +402,8 @@ void PressureEqualizer::output_gcode_line(GCodeLine &line)
line.pos_end [4] = line.volumetric_extrusion_rate_end * line.pos_end[4] / line.volumetric_extrusion_rate; line.pos_end [4] = line.volumetric_extrusion_rate_end * line.pos_end[4] / line.volumetric_extrusion_rate;
float feed_avg = 0.5f * (line.pos_start[4] + line.pos_end[4]); float feed_avg = 0.5f * (line.pos_start[4] + line.pos_end[4]);
// Limiting volumetric extrusion rate slope for this segment. // Limiting volumetric extrusion rate slope for this segment.
float max_volumetric_extrusion_rate_slope = accelerating ? float max_volumetric_extrusion_rate_slope = accelerating ? line.max_volumetric_extrusion_rate_slope_positive :
line.max_volumetric_extrusion_rate_slope_positive : line.max_volumetric_extrusion_rate_slope_negative; line.max_volumetric_extrusion_rate_slope_negative;
// Total time for the segment, corrected for the possibly lowered volumetric feed rate, // Total time for the segment, corrected for the possibly lowered volumetric feed rate,
// if accelerating / decelerating over the complete segment. // if accelerating / decelerating over the complete segment.
float t_total = line.dist_xyz() / feed_avg; float t_total = line.dist_xyz() / feed_avg;
@ -398,8 +414,8 @@ void PressureEqualizer::output_gcode_line(GCodeLine &line)
float l_steady = 0.f; float l_steady = 0.f;
if (t_acc < t_total) { if (t_acc < t_total) {
// One may achieve higher print speeds if part of the segment is not speed limited. // One may achieve higher print speeds if part of the segment is not speed limited.
float l_acc = t_acc * feed_avg; l_acc = t_acc * feed_avg;
float l_steady = l - l_acc; l_steady = l - l_acc;
if (l_steady < 0.5f * m_max_segment_length) { if (l_steady < 0.5f * m_max_segment_length) {
l_acc = l; l_acc = l;
l_steady = 0.f; l_steady = 0.f;
@ -407,10 +423,10 @@ void PressureEqualizer::output_gcode_line(GCodeLine &line)
nSegments = size_t(ceil(l_acc / m_max_segment_length)); nSegments = size_t(ceil(l_acc / m_max_segment_length));
} }
float pos_start[5]; float pos_start[5];
float pos_end [5]; float pos_end[5];
float pos_end2 [4]; float pos_end2[4];
memcpy(pos_start, line.pos_start, sizeof(float)*5); memcpy(pos_start, line.pos_start, sizeof(float) * 5);
memcpy(pos_end , line.pos_end , sizeof(float)*5); memcpy(pos_end, line.pos_end, sizeof(float) * 5);
if (l_steady > 0.f) { if (l_steady > 0.f) {
// There will be a steady feed segment emitted. // There will be a steady feed segment emitted.
if (accelerating) { if (accelerating) {
@ -429,9 +445,15 @@ void PressureEqualizer::output_gcode_line(GCodeLine &line)
line.pos_provided[i] = true; line.pos_provided[i] = true;
} }
push_line_to_output(line, pos_start[4], comment); push_line_to_output(line, pos_start[4], comment);
comment = NULL; comment = nullptr;
float new_pos_start_feedrate = pos_start[4];
memcpy(line.pos_start, line.pos_end, sizeof(float)*5); memcpy(line.pos_start, line.pos_end, sizeof(float)*5);
memcpy(pos_start, line.pos_end, sizeof(float)*5); memcpy(pos_start, line.pos_end, sizeof(float)*5);
line.pos_start[4] = new_pos_start_feedrate;
pos_start[4] = new_pos_start_feedrate;
} }
} }
// Split the segment into pieces. // Split the segment into pieces.
@ -443,7 +465,7 @@ void PressureEqualizer::output_gcode_line(GCodeLine &line)
} }
// Interpolate the feed rate at the center of the segment. // Interpolate the feed rate at the center of the segment.
push_line_to_output(line, pos_start[4] + (pos_end[4] - pos_start[4]) * (float(i) - 0.5f) / float(nSegments), comment); push_line_to_output(line, pos_start[4] + (pos_end[4] - pos_start[4]) * (float(i) - 0.5f) / float(nSegments), comment);
comment = NULL; comment = nullptr;
memcpy(line.pos_start, line.pos_end, sizeof(float)*5); memcpy(line.pos_start, line.pos_end, sizeof(float)*5);
} }
if (l_steady > 0.f && accelerating) { if (l_steady > 0.f && accelerating) {
@ -452,6 +474,12 @@ void PressureEqualizer::output_gcode_line(GCodeLine &line)
line.pos_provided[i] = true; line.pos_provided[i] = true;
} }
push_line_to_output(line, pos_end[4], comment); push_line_to_output(line, pos_end[4], comment);
} else {
for (int i = 0; i < 4; ++ i) {
line.pos_end[i] = pos_end[i];
line.pos_provided[i] = true;
}
push_line_to_output(line, pos_end[4], comment);
} }
} }
} }
@ -477,9 +505,9 @@ void PressureEqualizer::adjust_volumetric_rate()
bool modified = true; bool modified = true;
while (modified && idx != idx_head) { while (modified && idx != idx_head) {
size_t idx_prev = circular_buffer_idx_prev(idx); size_t idx_prev = circular_buffer_idx_prev(idx);
for (; ! circular_buffer[idx_prev].extruding() && idx_prev != idx_head; idx_prev = circular_buffer_idx_prev(idx_prev)) ; for (; !circular_buffer[idx_prev].extruding() && idx_prev != idx_head; idx_prev = circular_buffer_idx_prev(idx_prev));
if (! circular_buffer[idx_prev].extruding()) if (!circular_buffer[idx_prev].extruding())
break; break;
// Volumetric extrusion rate at the start of the succeding segment. // Volumetric extrusion rate at the start of the succeding segment.
float rate_succ = circular_buffer[idx].volumetric_extrusion_rate_start; float rate_succ = circular_buffer[idx].volumetric_extrusion_rate_start;
// What is the gradient of the extrusion rate between idx_prev and idx? // What is the gradient of the extrusion rate between idx_prev and idx?
@ -496,6 +524,7 @@ void PressureEqualizer::adjust_volumetric_rate()
rate_end = rate_succ; rate_end = rate_succ;
if (line.volumetric_extrusion_rate_end > rate_end) { if (line.volumetric_extrusion_rate_end > rate_end) {
line.volumetric_extrusion_rate_end = rate_end; line.volumetric_extrusion_rate_end = rate_end;
line.max_volumetric_extrusion_rate_slope_negative = rate_slope;
line.modified = true; line.modified = true;
} else if (iRole == line.extrusion_role) { } else if (iRole == line.extrusion_role) {
rate_end = line.volumetric_extrusion_rate_end; rate_end = line.volumetric_extrusion_rate_end;
@ -508,7 +537,7 @@ void PressureEqualizer::adjust_volumetric_rate()
// modified = false; // modified = false;
float rate_start = rate_end + rate_slope * line.time_corrected(); float rate_start = rate_end + rate_slope * line.time_corrected();
if (rate_start < line.volumetric_extrusion_rate_start) { if (rate_start < line.volumetric_extrusion_rate_start) {
// Limit the volumetric extrusion rate at the start of this segment due to a segment // Limit the volumetric extrusion rate at the start of this segment due to a segment
// of ExtrusionType iRole, which will be extruded in the future. // of ExtrusionType iRole, which will be extruded in the future.
line.volumetric_extrusion_rate_start = rate_start; line.volumetric_extrusion_rate_start = rate_start;
line.max_volumetric_extrusion_rate_slope_negative = rate_slope; line.max_volumetric_extrusion_rate_slope_negative = rate_slope;
@ -520,16 +549,16 @@ void PressureEqualizer::adjust_volumetric_rate()
} }
// Go forward and adjust the feedrate to decrease the slope of the extrusion rate changes. // Go forward and adjust the feedrate to decrease the slope of the extrusion rate changes.
for (size_t i = 0; i < numExtrusionRoles; ++ i) for (size_t i = 0; i < numExtrusionRoles; ++i)
feedrate_per_extrusion_role[i] = FLT_MAX; feedrate_per_extrusion_role[i] = FLT_MAX;
feedrate_per_extrusion_role[circular_buffer[idx].extrusion_role] = circular_buffer[idx].volumetric_extrusion_rate_end; feedrate_per_extrusion_role[circular_buffer[idx].extrusion_role] = circular_buffer[idx].volumetric_extrusion_rate_end;
assert(circular_buffer[idx].extruding()); assert(circular_buffer[idx].extruding());
while (idx != idx_tail) { while (idx != idx_tail) {
size_t idx_next = circular_buffer_idx_next(idx); size_t idx_next = circular_buffer_idx_next(idx);
for (; ! circular_buffer[idx_next].extruding() && idx_next != idx_tail; idx_next = circular_buffer_idx_next(idx_next)) ; for (; !circular_buffer[idx_next].extruding() && idx_next != idx_tail; idx_next = circular_buffer_idx_next(idx_next));
if (! circular_buffer[idx_next].extruding()) if (!circular_buffer[idx_next].extruding())
break; break;
float rate_prec = circular_buffer[idx].volumetric_extrusion_rate_end; float rate_prec = circular_buffer[idx].volumetric_extrusion_rate_end;
// What is the gradient of the extrusion rate between idx_prev and idx? // What is the gradient of the extrusion rate between idx_prev and idx?
idx = idx_next; idx = idx_next;
@ -544,6 +573,7 @@ void PressureEqualizer::adjust_volumetric_rate()
rate_start = rate_prec; rate_start = rate_prec;
if (line.volumetric_extrusion_rate_start > rate_start) { if (line.volumetric_extrusion_rate_start > rate_start) {
line.volumetric_extrusion_rate_start = rate_start; line.volumetric_extrusion_rate_start = rate_start;
line.max_volumetric_extrusion_rate_slope_positive = rate_slope;
line.modified = true; line.modified = true;
} else if (iRole == line.extrusion_role) { } else if (iRole == line.extrusion_role) {
rate_start = line.volumetric_extrusion_rate_start; rate_start = line.volumetric_extrusion_rate_start;
@ -555,7 +585,7 @@ void PressureEqualizer::adjust_volumetric_rate()
} }
float rate_end = (rate_slope == 0) ? FLT_MAX : rate_start + rate_slope * line.time_corrected(); float rate_end = (rate_slope == 0) ? FLT_MAX : rate_start + rate_slope * line.time_corrected();
if (rate_end < line.volumetric_extrusion_rate_end) { if (rate_end < line.volumetric_extrusion_rate_end) {
// Limit the volumetric extrusion rate at the start of this segment due to a segment // Limit the volumetric extrusion rate at the start of this segment due to a segment
// of ExtrusionType iRole, which was extruded before. // of ExtrusionType iRole, which was extruded before.
line.volumetric_extrusion_rate_end = rate_end; line.volumetric_extrusion_rate_end = rate_end;
line.max_volumetric_extrusion_rate_slope_positive = rate_slope; line.max_volumetric_extrusion_rate_slope_positive = rate_slope;
@ -569,9 +599,7 @@ void PressureEqualizer::adjust_volumetric_rate()
void PressureEqualizer::push_axis_to_output(const char axis, const float value, bool add_eol) void PressureEqualizer::push_axis_to_output(const char axis, const float value, bool add_eol)
{ {
char buf[2048]; char buf[2048];
int len = sprintf(buf, int len = sprintf(buf, (axis == 'E') ? " %c%.3f" : " %c%.5f", axis, value);
(axis == 'E') ? " %c%.3f" : " %c%.5f",
axis, value);
push_to_output(buf, len, add_eol); push_to_output(buf, len, add_eol);
} }
@ -609,15 +637,23 @@ void PressureEqualizer::push_to_output(const char *text, const size_t len, bool
void PressureEqualizer::push_line_to_output(const GCodeLine &line, const float new_feedrate, const char *comment) void PressureEqualizer::push_line_to_output(const GCodeLine &line, const float new_feedrate, const char *comment)
{ {
push_to_output(EXTRUDE_END_TAG.data(), EXTRUDE_END_TAG_LENGTH, true);
push_to_output("G1", 2, false);
push_axis_to_output('F', new_feedrate);
push_to_output(EXTRUDE_SET_SPEED_TAG.data(), EXTRUDE_SET_SPEED_TAG_LENGTH, line.extrusion_role != erExternalPerimeter);
if (line.extrusion_role == erExternalPerimeter)
push_to_output(EXTERNAL_PERIMETER_TAG.data(), EXTERNAL_PERIMETER_TAG_LENGTH, true);
push_to_output("G1", 2, false); push_to_output("G1", 2, false);
for (char i = 0; i < 3; ++ i) for (char i = 0; i < 3; ++ i)
if (line.pos_provided[i]) if (line.pos_provided[i])
push_axis_to_output('X'+i, line.pos_end[i]); push_axis_to_output('X'+i, line.pos_end[i]);
push_axis_to_output('E', m_config->use_relative_e_distances.value ? (line.pos_end[3] - line.pos_start[3]) : line.pos_end[3]); push_axis_to_output('E', m_config.use_relative_e_distances.value ? (line.pos_end[3] - line.pos_start[3]) : line.pos_end[3]);
// if (line.pos_provided[4] || fabs(line.feedrate() - new_feedrate) > 1e-5)
push_axis_to_output('F', new_feedrate);
// output comment and EOL // output comment and EOL
push_to_output(comment, (comment == NULL) ? 0 : strlen(comment), true); push_to_output(comment, (comment == nullptr) ? 0 : strlen(comment), true);
} }
} // namespace Slic3r } // namespace Slic3r

View File

@ -7,18 +7,21 @@
namespace Slic3r { namespace Slic3r {
//#define PRESSURE_EQUALIZER_STATISTIC
//#define PRESSURE_EQUALIZER_DEBUG
// Processes a G-code. Finds changes in the volumetric extrusion speed and adjusts the transitions // Processes a G-code. Finds changes in the volumetric extrusion speed and adjusts the transitions
// between these paths to limit fast changes in the volumetric extrusion speed. // between these paths to limit fast changes in the volumetric extrusion speed.
class PressureEqualizer class PressureEqualizer
{ {
public: public:
PressureEqualizer(const Slic3r::GCodeConfig *config); explicit PressureEqualizer(const Slic3r::GCodeConfig &config);
~PressureEqualizer(); ~PressureEqualizer() = default;
void reset(); void reset();
// Process a next batch of G-code lines. Flush the internal buffers if asked for. // Process a next batch of G-code lines. Flush the internal buffers if asked for.
const char* process(const char *szGCode, bool flush); const char* process_layer(const char *szGCode, bool flush);
size_t get_output_buffer_length() const { return output_buffer_length; } size_t get_output_buffer_length() const { return output_buffer_length; }
@ -43,10 +46,12 @@ private:
float extrusion_length; float extrusion_length;
}; };
#ifdef PRESSURE_EQUALIZER_STATISTIC
struct Statistics m_stat; struct Statistics m_stat;
#endif
// Keeps the reference, does not own the config. // Keeps the reference, does not own the config.
const Slic3r::GCodeConfig *m_config; const Slic3r::GCodeConfig &m_config;
// Private configuration values // Private configuration values
// How fast could the volumetric extrusion rate increase / decrase? mm^3/sec^2 // How fast could the volumetric extrusion rate increase / decrase? mm^3/sec^2
@ -72,8 +77,7 @@ private:
ExtrusionRole m_current_extrusion_role; ExtrusionRole m_current_extrusion_role;
bool m_retracted; bool m_retracted;
enum GCodeLineType enum GCodeLineType {
{
GCODELINETYPE_INVALID, GCODELINETYPE_INVALID,
GCODELINETYPE_NOOP, GCODELINETYPE_NOOP,
GCODELINETYPE_OTHER, GCODELINETYPE_OTHER,
@ -170,7 +174,7 @@ private:
// For debugging purposes. Index of the G-code line processed. // For debugging purposes. Index of the G-code line processed.
size_t line_idx; size_t line_idx;
bool process_line(const char *line, const size_t len, GCodeLine &buf); bool process_line(const char *line, const char *line_end, GCodeLine &buf);
void output_gcode_line(GCodeLine &buf); void output_gcode_line(GCodeLine &buf);
// Go back from the current circular_buffer_pos and lower the feedtrate to decrease the slope of the extrusion rate changes. // Go back from the current circular_buffer_pos and lower the feedtrate to decrease the slope of the extrusion rate changes.
@ -178,11 +182,11 @@ private:
void adjust_volumetric_rate(); void adjust_volumetric_rate();
// Push the text to the end of the output_buffer. // Push the text to the end of the output_buffer.
void push_to_output(const char *text, const size_t len, bool add_eol = true); void push_to_output(const char *text, size_t len, bool add_eol = true);
// Push an axis assignment to the end of the output buffer. // Push an axis assignment to the end of the output buffer.
void push_axis_to_output(const char axis, const float value, bool add_eol = false); void push_axis_to_output(char axis, float value, bool add_eol = false);
// Push a G-code line to the output, // Push a G-code line to the output,
void push_line_to_output(const GCodeLine &line, const float new_feedrate, const char *comment); void push_line_to_output(const GCodeLine &line, float new_feedrate, const char *comment);
size_t circular_buffer_idx_head() const { size_t circular_buffer_idx_head() const {
size_t idx = circular_buffer_pos + circular_buffer_size - circular_buffer_items; size_t idx = circular_buffer_pos + circular_buffer_size - circular_buffer_items;

View File

@ -427,9 +427,7 @@ static std::vector<std::string> s_Preset_print_options {
"ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing", "ironing", "ironing_type", "ironing_flowrate", "ironing_speed", "ironing_spacing",
"max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour", "max_print_speed", "max_volumetric_speed", "avoid_crossing_perimeters_max_detour",
"fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist", "fuzzy_skin", "fuzzy_skin_thickness", "fuzzy_skin_point_dist",
#ifdef HAS_PRESSURE_EQUALIZER
"max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed", "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed", "top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration", "bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "travel_speed_z", "first_layer_speed", "first_layer_speed_over_raft", "perimeter_acceleration", "infill_acceleration",

View File

@ -103,10 +103,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
"min_print_speed", "min_print_speed",
"max_print_speed", "max_print_speed",
"max_volumetric_speed", "max_volumetric_speed",
#ifdef HAS_PRESSURE_EQUALIZER
"max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_positive",
"max_volumetric_extrusion_rate_slope_negative", "max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
"notes", "notes",
"only_retract_when_crossing_perimeters", "only_retract_when_crossing_perimeters",
"output_filename_format", "output_filename_format",

View File

@ -1802,7 +1802,6 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert; def->mode = comExpert;
def->set_default_value(new ConfigOptionFloat(0)); def->set_default_value(new ConfigOptionFloat(0));
#ifdef HAS_PRESSURE_EQUALIZER
def = this->add("max_volumetric_extrusion_rate_slope_positive", coFloat); def = this->add("max_volumetric_extrusion_rate_slope_positive", coFloat);
def->label = L("Max volumetric slope positive"); def->label = L("Max volumetric slope positive");
def->tooltip = L("This experimental setting is used to limit the speed of change in extrusion rate. " def->tooltip = L("This experimental setting is used to limit the speed of change in extrusion rate. "
@ -1824,7 +1823,6 @@ void PrintConfigDef::init_fff_params()
def->min = 0; def->min = 0;
def->mode = comExpert; def->mode = comExpert;
def->set_default_value(new ConfigOptionFloat(0)); def->set_default_value(new ConfigOptionFloat(0));
#endif /* HAS_PRESSURE_EQUALIZER */
def = this->add("min_fan_speed", coInts); def = this->add("min_fan_speed", coInts);
def->label = L("Min"); def->label = L("Min");
@ -4008,9 +4006,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
"start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start", "start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start",
"seal_position", "vibration_limit", "bed_size", "seal_position", "vibration_limit", "bed_size",
"print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe" "print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe"
#ifndef HAS_PRESSURE_EQUALIZER
, "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative", , "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
#endif /* HAS_PRESSURE_EQUALIZER */
"serial_port", "serial_speed", "serial_port", "serial_speed",
// Introduced in some PrusaSlicer 2.3.1 alpha, later renamed or removed. // Introduced in some PrusaSlicer 2.3.1 alpha, later renamed or removed.
"fuzzy_skin_perimeter_mode", "fuzzy_skin_shape", "fuzzy_skin_perimeter_mode", "fuzzy_skin_shape",

View File

@ -27,8 +27,6 @@
#include <boost/preprocessor/tuple/elem.hpp> #include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/to_seq.hpp> #include <boost/preprocessor/tuple/to_seq.hpp>
// #define HAS_PRESSURE_EQUALIZER
namespace Slic3r { namespace Slic3r {
enum GCodeFlavor : unsigned char { enum GCodeFlavor : unsigned char {
@ -670,10 +668,8 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionString, layer_gcode)) ((ConfigOptionString, layer_gcode))
((ConfigOptionFloat, max_print_speed)) ((ConfigOptionFloat, max_print_speed))
((ConfigOptionFloat, max_volumetric_speed)) ((ConfigOptionFloat, max_volumetric_speed))
//#ifdef HAS_PRESSURE_EQUALIZER ((ConfigOptionFloat, max_volumetric_extrusion_rate_slope_positive))
// ((ConfigOptionFloat, max_volumetric_extrusion_rate_slope_positive)) ((ConfigOptionFloat, max_volumetric_extrusion_rate_slope_negative))
// ((ConfigOptionFloat, max_volumetric_extrusion_rate_slope_negative))
//#endif
((ConfigOptionPercents, retract_before_wipe)) ((ConfigOptionPercents, retract_before_wipe))
((ConfigOptionFloats, retract_length)) ((ConfigOptionFloats, retract_length))
((ConfigOptionFloats, retract_length_toolchange)) ((ConfigOptionFloats, retract_length_toolchange))

View File

@ -1611,10 +1611,9 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Autospeed (advanced)")); optgroup = page->new_optgroup(L("Autospeed (advanced)"));
optgroup->append_single_option_line("max_print_speed", "max-volumetric-speed_127176"); optgroup->append_single_option_line("max_print_speed", "max-volumetric-speed_127176");
optgroup->append_single_option_line("max_volumetric_speed", "max-volumetric-speed_127176"); optgroup->append_single_option_line("max_volumetric_speed", "max-volumetric-speed_127176");
#ifdef HAS_PRESSURE_EQUALIZER
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive"); optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_positive");
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative"); optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative");
#endif /* HAS_PRESSURE_EQUALIZER */
page = add_options_page(L("Multiple Extruders"), "funnel"); page = add_options_page(L("Multiple Extruders"), "funnel");
optgroup = page->new_optgroup(L("Extruders")); optgroup = page->new_optgroup(L("Extruders"));