mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-07 23:17:35 -06:00
Porting of Pressure Equalizer feature from Prusa Slicer 2.6.x (#2161)
* Overhang perimeter handling
Updated code to handle overhang perimeters as an overhang and not as a bridge.
* Preparing to add curled extrusions identification
* Porting curling calculations from Prusa Slier 2.6.1
* Prototype 1 - slowdown extended to detect curled edges and further reduce speed
First prototype of the code submitted.
* Working prototype - 2
Code is now finally working - external perimeters are slowed down as needed when there is likelyhood of curling up.
ToDo:
1. Reslicing the model causes the algorithm not to run - need to find where this fails to trigger the call for this.
2. Slowdown of internal perimeters not working yet.
* Updated to use overhang wall speed instead of bridging speed for this algorithm
* Fixed bug in speed calculation and tweaked parameters for high speed printer
Fixed bug in speed calculation and tweaked parameters for high speed printer
* Attempting to fix "set started" not being set
* Parameter tweak after print tests
* Fixed estimation not running when model is re-sliced.
* Removing debug printf statements and fixed threading flag.
* Fixed threading
* Parameter tweaks following print tests
* Made this as an option in the GUI
* Reintroduced handling of bridges as per original design
* UI line toggling when option makes sense to be visible.
* Fixed bug in field visibility & made it default to off
* Code optimisation
* Initial commit of code from Prusa Slicer 2.6.1
* Ported ExtrusionRole from Prusa Slicer 2.6.1
* fix compile errors
* Update GCode.hpp
* code changes to invoke pressure equalizer
* attempting to trigger pressure equalizer
(Not compiling)
* Update Fill.cpp
* Update Fill.cpp
* Pressure equaliser layer result update
* Further commits
* Merged PR https://github.com/prusa3d/PrusaSlicer/pull/9622
* First complete working version
* Update PressureEqualizer.cpp
* Implemented parameter in GUI
* Toggle fields according to compatibility
* Updated UI toggles between extrusion rate slope and arc fitting.
* Updated tooltip
* Introduced parameter smoothing segment length
This parameter influences the number of division a line will undergo in response to the requirement to adhere to the extrusion rate flow adjustment.
* Internal parameter and tool tip tweaking
* Parameter and tool tip tweaking
* Updated parameters and tooltip following testing.
* Sync PressureEq with latest PrusaSlicer
* Revert "Sync PressureEq with latest PrusaSlicer"
This reverts commit 131fb94c6b
.
---------
Co-authored-by: MGunlogson <MGunlogson@users.noreply.github.com>
Co-authored-by: Vojtech Bubnik <bubnikv@gmail.com>
This commit is contained in:
parent
78a8bad6f4
commit
cf846195cc
14 changed files with 824 additions and 431 deletions
|
@ -1,41 +1,59 @@
|
|||
///|/ Copyright (c) Prusa Research 2016 - 2023 Vojtěch Bubník @bubnikv, Lukáš Hejl @hejllukas
|
||||
///|/ Copyright (c) SuperSlicer 2023 Remi Durand @supermerill
|
||||
///|/
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
#ifndef slic3r_GCode_PressureEqualizer_hpp_
|
||||
#define slic3r_GCode_PressureEqualizer_hpp_
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../PrintConfig.hpp"
|
||||
#include "../ExtrusionEntity.hpp"
|
||||
#include "../ExtrusionRole.hpp"
|
||||
|
||||
#include <queue>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
struct LayerResult;
|
||||
|
||||
class GCodeG1Formatter;
|
||||
|
||||
//#define PRESSURE_EQUALIZER_STATISTIC
|
||||
//#define PRESSURE_EQUALIZER_DEBUG
|
||||
|
||||
// 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.
|
||||
class PressureEqualizer
|
||||
{
|
||||
public:
|
||||
PressureEqualizer(const Slic3r::GCodeConfig *config);
|
||||
~PressureEqualizer();
|
||||
|
||||
void reset();
|
||||
|
||||
// Process a next batch of G-code lines. Flush the internal buffers if asked for.
|
||||
const char* process(const char *szGCode, bool flush);
|
||||
|
||||
size_t get_output_buffer_length() const { return output_buffer_length; }
|
||||
PressureEqualizer() = delete;
|
||||
explicit PressureEqualizer(const Slic3r::GCodeConfig &config);
|
||||
~PressureEqualizer() = default;
|
||||
|
||||
// Process a next batch of G-code lines.
|
||||
// The last LayerResult must be LayerResult::make_nop_layer_result() because it always returns GCode for the previous layer.
|
||||
// When process_layer is called for the first layer, then LayerResult::make_nop_layer_result() is returned.
|
||||
LayerResult process_layer(LayerResult &&input);
|
||||
private:
|
||||
|
||||
void process_layer(const std::string &gcode);
|
||||
|
||||
#ifdef PRESSURE_EQUALIZER_STATISTIC
|
||||
struct Statistics
|
||||
{
|
||||
void reset() {
|
||||
volumetric_extrusion_rate_min = std::numeric_limits<float>::max();
|
||||
void reset()
|
||||
{
|
||||
volumetric_extrusion_rate_min = std::numeric_limits<float>::max();
|
||||
volumetric_extrusion_rate_max = 0.f;
|
||||
volumetric_extrusion_rate_avg = 0.f;
|
||||
extrusion_length = 0.f;
|
||||
extrusion_length = 0.f;
|
||||
}
|
||||
void update(float volumetric_extrusion_rate, float length) {
|
||||
volumetric_extrusion_rate_min = std::min(volumetric_extrusion_rate_min, volumetric_extrusion_rate);
|
||||
volumetric_extrusion_rate_max = std::max(volumetric_extrusion_rate_max, volumetric_extrusion_rate);
|
||||
void update(float volumetric_extrusion_rate, float length)
|
||||
{
|
||||
volumetric_extrusion_rate_min = std::min(volumetric_extrusion_rate_min, volumetric_extrusion_rate);
|
||||
volumetric_extrusion_rate_max = std::max(volumetric_extrusion_rate_max, volumetric_extrusion_rate);
|
||||
volumetric_extrusion_rate_avg += volumetric_extrusion_rate * length;
|
||||
extrusion_length += length;
|
||||
extrusion_length += length;
|
||||
}
|
||||
float volumetric_extrusion_rate_min;
|
||||
float volumetric_extrusion_rate_max;
|
||||
|
@ -44,9 +62,7 @@ private:
|
|||
};
|
||||
|
||||
struct Statistics m_stat;
|
||||
|
||||
// Keeps the reference, does not own the config.
|
||||
const Slic3r::GCodeConfig *m_config;
|
||||
#endif
|
||||
|
||||
// Private configuration values
|
||||
// How fast could the volumetric extrusion rate increase / decrase? mm^3/sec^2
|
||||
|
@ -54,12 +70,9 @@ private:
|
|||
float positive;
|
||||
float negative;
|
||||
};
|
||||
enum { numExtrusionRoles = erSupportMaterialInterface + 1 };
|
||||
ExtrusionRateSlope m_max_volumetric_extrusion_rate_slopes[numExtrusionRoles];
|
||||
ExtrusionRateSlope m_max_volumetric_extrusion_rate_slopes[size_t(GCodeExtrusionRole::Count)];
|
||||
float m_max_volumetric_extrusion_rate_slope_positive;
|
||||
float m_max_volumetric_extrusion_rate_slope_negative;
|
||||
// Maximum segment length to split a long segment, if the initial and the final flow rate differ.
|
||||
float m_max_segment_length;
|
||||
|
||||
// Configuration extracted from config.
|
||||
// Area of the crossestion of each filament. Necessary to calculate the volumetric flow rate.
|
||||
|
@ -69,11 +82,19 @@ private:
|
|||
// X,Y,Z,E,F
|
||||
float m_current_pos[5];
|
||||
size_t m_current_extruder;
|
||||
ExtrusionRole m_current_extrusion_role;
|
||||
GCodeExtrusionRole m_current_extrusion_role;
|
||||
bool m_retracted;
|
||||
bool m_use_relative_e_distances;
|
||||
|
||||
enum GCodeLineType
|
||||
{
|
||||
// Maximum segment length to split a long segment if the initial and the final flow rate differ.
|
||||
// Smaller value means a smoother transition between two different flow rates.
|
||||
float m_max_segment_length;
|
||||
|
||||
// Indicate if extrude set speed block was opened using the tag ";_EXTRUDE_SET_SPEED"
|
||||
// or not (not opened, or it was closed using the tag ";_EXTRUDE_END").
|
||||
bool opened_extrude_set_speed_block = false;
|
||||
|
||||
enum GCodeLineType {
|
||||
GCODELINETYPE_INVALID,
|
||||
GCODELINETYPE_NOOP,
|
||||
GCODELINETYPE_OTHER,
|
||||
|
@ -128,18 +149,16 @@ private:
|
|||
// or maybe the line needs to be split into multiple lines.
|
||||
bool modified;
|
||||
|
||||
// float timeStart;
|
||||
// float timeEnd;
|
||||
// X,Y,Z,E,F. Storing the state of the currently active extruder only.
|
||||
float pos_start[5];
|
||||
float pos_end[5];
|
||||
// Was the axis found on the G-code line? X,Y,Z,F
|
||||
// Was the axis found on the G-code line? X,Y,Z,E,F
|
||||
bool pos_provided[5];
|
||||
|
||||
// Index of the active extruder.
|
||||
size_t extruder_id;
|
||||
// Extrusion role of this segment.
|
||||
ExtrusionRole extrusion_role;
|
||||
GCodeExtrusionRole extrusion_role;
|
||||
|
||||
// Current volumetric extrusion rate.
|
||||
float volumetric_extrusion_rate;
|
||||
|
@ -152,59 +171,42 @@ private:
|
|||
// If set to zero, the slope is unlimited.
|
||||
float max_volumetric_extrusion_rate_slope_positive;
|
||||
float max_volumetric_extrusion_rate_slope_negative;
|
||||
};
|
||||
|
||||
// Circular buffer of GCode lines. The circular buffer size will be limited to circular_buffer_size.
|
||||
std::vector<GCodeLine> circular_buffer;
|
||||
// Current position of the circular buffer (index, where to write the next line to, the line has to be pushed out before it is overwritten).
|
||||
size_t circular_buffer_pos;
|
||||
// Circular buffer size, configuration value.
|
||||
size_t circular_buffer_size;
|
||||
// Number of valid lines in the circular buffer. Lower or equal to circular_buffer_size.
|
||||
size_t circular_buffer_items;
|
||||
bool adjustable_flow = false;
|
||||
|
||||
bool extrude_set_speed_tag = false;
|
||||
bool extrude_end_tag = false;
|
||||
};
|
||||
|
||||
// Output buffer will only grow. It will not be reallocated over and over.
|
||||
std::vector<char> output_buffer;
|
||||
size_t output_buffer_length;
|
||||
size_t output_buffer_prev_length;
|
||||
|
||||
#ifdef PRESSURE_EQUALIZER_DEBUG
|
||||
// For debugging purposes. Index of the G-code line processed.
|
||||
size_t line_idx;
|
||||
#endif
|
||||
|
||||
bool process_line(const char *line, const size_t len, GCodeLine &buf);
|
||||
void output_gcode_line(GCodeLine &buf);
|
||||
bool process_line(const char *line, const char *line_end, GCodeLine &buf);
|
||||
long advance_segment_beyond_small_gap(long idx_cur_pos);
|
||||
void output_gcode_line(size_t line_idx);
|
||||
|
||||
// Go back from the current circular_buffer_pos and lower the feedtrate to decrease the slope of the extrusion rate changes.
|
||||
// Then go forward and adjust the feedrate to decrease the slope of the extrusion rate changes.
|
||||
void adjust_volumetric_rate();
|
||||
void adjust_volumetric_rate(size_t first_line_idx, size_t last_line_idx);
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
// Push a G-code line to the output,
|
||||
void push_line_to_output(const GCodeLine &line, const float new_feedrate, const char *comment);
|
||||
inline void push_to_output(GCodeG1Formatter &formatter);
|
||||
inline void push_to_output(const std::string &text, bool add_eol);
|
||||
inline void push_to_output(const char *text, size_t len, bool add_eol = true);
|
||||
// Push a G-code line to the output.
|
||||
void push_line_to_output(size_t line_idx, float new_feedrate, const char *comment);
|
||||
|
||||
size_t circular_buffer_idx_head() const {
|
||||
size_t idx = circular_buffer_pos + circular_buffer_size - circular_buffer_items;
|
||||
if (idx >= circular_buffer_size)
|
||||
idx -= circular_buffer_size;
|
||||
return idx;
|
||||
}
|
||||
public:
|
||||
std::queue<LayerResult*> m_layer_results;
|
||||
|
||||
size_t circular_buffer_idx_tail() const { return circular_buffer_pos; }
|
||||
|
||||
size_t circular_buffer_idx_prev(size_t idx) const {
|
||||
idx += circular_buffer_size - 1;
|
||||
if (idx >= circular_buffer_size)
|
||||
idx -= circular_buffer_size;
|
||||
return idx;
|
||||
}
|
||||
|
||||
size_t circular_buffer_idx_next(size_t idx) const {
|
||||
if (++ idx >= circular_buffer_size)
|
||||
idx -= circular_buffer_size;
|
||||
return idx;
|
||||
}
|
||||
std::vector<GCodeLine> m_gcode_lines;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue