mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 08:41:11 -06:00
Ported the G-code generator from Perl to C++.
Removed GCode.pm Removed the Perl bindigns for AvoidCrossingPerimeters, OozePrevention, SpiralVase, Wipe Changed the std::set of extruder IDs to vector of IDs. Removed some MSVC compiler warnings, removed obnoxious compiler warnings when compiling the Perl bindings.
This commit is contained in:
parent
72ae3585e4
commit
e90279c513
52 changed files with 1362 additions and 1632 deletions
|
@ -90,7 +90,7 @@ static inline int parse_int(const char *&line)
|
|||
char *endptr = NULL;
|
||||
long result = strtol(line, &endptr, 10);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing an int");
|
||||
throw std::runtime_error("GCodeAnalyzer: Error parsing an int");
|
||||
line = endptr;
|
||||
return int(result);
|
||||
};
|
||||
|
@ -102,7 +102,7 @@ static inline float parse_float(const char *&line)
|
|||
char *endptr = NULL;
|
||||
float result = strtof(line, &endptr);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing a float");
|
||||
throw std::runtime_error("GCodeAnalyzer: Error parsing a float");
|
||||
line = endptr;
|
||||
return result;
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ bool GCodeAnalyzer::process_line(const char *line, const size_t len)
|
|||
assert(false);
|
||||
}
|
||||
if (i == -1)
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Invalid axis for G0/G1: ") + axis);
|
||||
throw std::runtime_error(std::string("GCodeAnalyzer: Invalid axis for G0/G1: ") + axis);
|
||||
buf.pos_provided[i] = true;
|
||||
new_pos[i] = parse_float(line);
|
||||
if (i == 3 && m_config->use_relative_e_distances.value)
|
||||
|
@ -235,7 +235,7 @@ bool GCodeAnalyzer::process_line(const char *line, const size_t len)
|
|||
set = true;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
throw std::runtime_error(std::string("GCodeAnalyzer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
}
|
||||
eatws(line);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "../GCode.hpp"
|
||||
#include "CoolingBuffer.hpp"
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
@ -5,28 +6,26 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
std::string
|
||||
CoolingBuffer::append(const std::string &gcode, std::string obj_id, size_t layer_id, float print_z)
|
||||
std::string CoolingBuffer::append(const std::string &gcode, size_t object_id, size_t layer_id, bool is_support)
|
||||
{
|
||||
std::string out;
|
||||
if (this->_last_z.find(obj_id) != this->_last_z.end()) {
|
||||
// A layer was finished, Z of the object's layer changed. Process the layer.
|
||||
size_t signature = object_id * 2 + is_support ? 1 : 0;
|
||||
if (m_object_ids_visited.find(signature) != m_object_ids_visited.end())
|
||||
// For a single print_z, a combination of (object_id, is_support) could repeat once only.
|
||||
// If the combination of (object_id, is_support) reappears, this must be for another print_z,
|
||||
// therefore a layer has to be finalized.
|
||||
out = this->flush();
|
||||
}
|
||||
|
||||
this->_layer_id = layer_id;
|
||||
this->_last_z[obj_id] = print_z;
|
||||
this->_gcode += gcode;
|
||||
|
||||
m_object_ids_visited.insert(signature);
|
||||
m_layer_id = layer_id;
|
||||
m_gcode += gcode;
|
||||
// This is a very rough estimate of the print time,
|
||||
// not taking into account the acceleration curves generated by the printer firmware.
|
||||
this->_elapsed_time += this->_gcodegen->elapsed_time;
|
||||
this->_gcodegen->elapsed_time = 0;
|
||||
|
||||
m_elapsed_time += m_gcodegen.get_reset_elapsed_time();
|
||||
return out;
|
||||
}
|
||||
|
||||
void
|
||||
apply_speed_factor(std::string &line, float speed_factor, float min_print_speed)
|
||||
void apply_speed_factor(std::string &line, float speed_factor, float min_print_speed)
|
||||
{
|
||||
// find pos of F
|
||||
size_t pos = line.find_first_of('F');
|
||||
|
@ -51,36 +50,34 @@ apply_speed_factor(std::string &line, float speed_factor, float min_print_speed)
|
|||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
CoolingBuffer::flush()
|
||||
std::string CoolingBuffer::flush()
|
||||
{
|
||||
GCode &gg = *this->_gcodegen;
|
||||
const FullPrintConfig &config = m_gcodegen.config();
|
||||
|
||||
std::string gcode = this->_gcode;
|
||||
float elapsed = this->_elapsed_time;
|
||||
this->_gcode = "";
|
||||
this->_elapsed_time = 0;
|
||||
this->_last_z.clear(); // reset the whole table otherwise we would compute overlapping times
|
||||
|
||||
int fan_speed = gg.config.fan_always_on ? gg.config.min_fan_speed.value : 0;
|
||||
std::string gcode = m_gcode;
|
||||
float elapsed = m_elapsed_time;
|
||||
m_gcode.clear();
|
||||
m_elapsed_time = 0.;
|
||||
|
||||
int fan_speed = config.fan_always_on ? config.min_fan_speed.value : 0;
|
||||
|
||||
float speed_factor = 1.0;
|
||||
|
||||
if (gg.config.cooling) {
|
||||
if (config.cooling) {
|
||||
#ifdef SLIC3R_DEBUG
|
||||
printf("Layer %zu estimated printing time: %f seconds\n", this->_layer_id, elapsed);
|
||||
printf("Layer %zu estimated printing time: %f seconds\n", m_layer_id, elapsed);
|
||||
#endif
|
||||
if (elapsed < (float)gg.config.slowdown_below_layer_time) {
|
||||
if (elapsed < (float)config.slowdown_below_layer_time) {
|
||||
// Layer time very short. Enable the fan to a full throttle and slow down the print
|
||||
// (stretch the layer print time to slowdown_below_layer_time).
|
||||
fan_speed = gg.config.max_fan_speed;
|
||||
speed_factor = elapsed / (float)gg.config.slowdown_below_layer_time;
|
||||
} else if (elapsed < (float)gg.config.fan_below_layer_time) {
|
||||
fan_speed = config.max_fan_speed;
|
||||
speed_factor = elapsed / (float)config.slowdown_below_layer_time;
|
||||
} else if (elapsed < (float)config.fan_below_layer_time) {
|
||||
// Layer time quite short. Enable the fan proportionally according to the current layer time.
|
||||
fan_speed = gg.config.max_fan_speed
|
||||
- (gg.config.max_fan_speed - gg.config.min_fan_speed)
|
||||
* (elapsed - (float)gg.config.slowdown_below_layer_time)
|
||||
/ (gg.config.fan_below_layer_time - gg.config.slowdown_below_layer_time);
|
||||
fan_speed = config.max_fan_speed
|
||||
- (config.max_fan_speed - config.min_fan_speed)
|
||||
* (elapsed - (float)config.slowdown_below_layer_time)
|
||||
/ (config.fan_below_layer_time - config.slowdown_below_layer_time);
|
||||
}
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
|
@ -94,13 +91,14 @@ CoolingBuffer::flush()
|
|||
std::string new_gcode;
|
||||
std::istringstream ss(gcode);
|
||||
std::string line;
|
||||
bool bridge_fan_start = false;
|
||||
bool bridge_fan_start = false;
|
||||
float min_print_speed = float(config.min_print_speed * 60.);
|
||||
while (std::getline(ss, line)) {
|
||||
if (boost::starts_with(line, "G1")
|
||||
&& boost::contains(line, ";_EXTRUDE_SET_SPEED")
|
||||
&& !boost::contains(line, ";_WIPE")
|
||||
&& !bridge_fan_start) {
|
||||
apply_speed_factor(line, speed_factor, this->_min_print_speed);
|
||||
apply_speed_factor(line, speed_factor, min_print_speed);
|
||||
boost::replace_first(line, ";_EXTRUDE_SET_SPEED", "");
|
||||
}
|
||||
bridge_fan_start = boost::contains(line, ";_BRIDGE_FAN_START");
|
||||
|
@ -109,22 +107,23 @@ CoolingBuffer::flush()
|
|||
gcode = new_gcode;
|
||||
}
|
||||
}
|
||||
if (this->_layer_id < gg.config.disable_fan_first_layers)
|
||||
if (m_layer_id < config.disable_fan_first_layers)
|
||||
fan_speed = 0;
|
||||
|
||||
gcode = gg.writer.set_fan(fan_speed) + gcode;
|
||||
gcode = m_gcodegen.writer().set_fan(fan_speed) + gcode;
|
||||
|
||||
// bridge fan speed
|
||||
if (!gg.config.cooling || gg.config.bridge_fan_speed == 0 || this->_layer_id < gg.config.disable_fan_first_layers) {
|
||||
if (!config.cooling || config.bridge_fan_speed == 0 || m_layer_id < config.disable_fan_first_layers) {
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_START", "");
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_END", "");
|
||||
} else {
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_START", gg.writer.set_fan(gg.config.bridge_fan_speed, true));
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_END", gg.writer.set_fan(fan_speed, true));
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_START", m_gcodegen.writer().set_fan(config.bridge_fan_speed, true));
|
||||
boost::replace_all(gcode, ";_BRIDGE_FAN_END", m_gcodegen.writer().set_fan(fan_speed, true));
|
||||
}
|
||||
boost::replace_all(gcode, ";_WIPE", "");
|
||||
boost::replace_all(gcode, ";_EXTRUDE_SET_SPEED", "");
|
||||
|
||||
m_object_ids_visited.clear();
|
||||
return gcode;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#define slic3r_CoolingBuffer_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "GCode.hpp"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GCode;
|
||||
class Layer;
|
||||
|
||||
/*
|
||||
A standalone G-code filter, to control cooling of the print.
|
||||
The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
|
||||
|
@ -15,23 +17,20 @@ and the print is modified to stretch over a minimum layer time.
|
|||
*/
|
||||
|
||||
class CoolingBuffer {
|
||||
public:
|
||||
CoolingBuffer(GCode &gcodegen)
|
||||
: _gcodegen(&gcodegen), _elapsed_time(0.), _layer_id(0)
|
||||
{
|
||||
this->_min_print_speed = this->_gcodegen->config.min_print_speed * 60;
|
||||
};
|
||||
std::string append(const std::string &gcode, std::string obj_id, size_t layer_id, float print_z);
|
||||
public:
|
||||
CoolingBuffer(GCode &gcodegen) : m_gcodegen(gcodegen), m_elapsed_time(0.), m_layer_id(0) {}
|
||||
std::string append(const std::string &gcode, size_t object_id, size_t layer_id, bool is_support);
|
||||
std::string flush();
|
||||
GCode* gcodegen() { return this->_gcodegen; };
|
||||
GCode* gcodegen() { return &m_gcodegen; };
|
||||
|
||||
private:
|
||||
GCode* _gcodegen;
|
||||
std::string _gcode;
|
||||
float _elapsed_time;
|
||||
size_t _layer_id;
|
||||
std::map<std::string,float> _last_z;
|
||||
float _min_print_speed;
|
||||
private:
|
||||
CoolingBuffer& operator=(const CoolingBuffer&);
|
||||
|
||||
GCode& m_gcodegen;
|
||||
std::string m_gcode;
|
||||
float m_elapsed_time;
|
||||
size_t m_layer_id;
|
||||
std::set<size_t> m_object_ids_visited;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -9,17 +9,17 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
GCodePressureEqualizer::GCodePressureEqualizer(const Slic3r::GCodeConfig *config) :
|
||||
PressureEqualizer::PressureEqualizer(const Slic3r::GCodeConfig *config) :
|
||||
m_config(config)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
GCodePressureEqualizer::~GCodePressureEqualizer()
|
||||
PressureEqualizer::~PressureEqualizer()
|
||||
{
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::reset()
|
||||
void PressureEqualizer::reset()
|
||||
{
|
||||
circular_buffer_pos = 0;
|
||||
circular_buffer_size = 100;
|
||||
|
@ -69,7 +69,7 @@ void GCodePressureEqualizer::reset()
|
|||
line_idx = 0;
|
||||
}
|
||||
|
||||
const char* GCodePressureEqualizer::process(const char *szGCode, bool flush)
|
||||
const char* PressureEqualizer::process(const char *szGCode, bool flush)
|
||||
{
|
||||
// Reset length of the output_buffer.
|
||||
output_buffer_length = 0;
|
||||
|
@ -147,7 +147,7 @@ static inline int parse_int(const char *&line)
|
|||
char *endptr = NULL;
|
||||
long result = strtol(line, &endptr, 10);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing an int");
|
||||
throw std::runtime_error("PressureEqualizer: Error parsing an int");
|
||||
line = endptr;
|
||||
return int(result);
|
||||
};
|
||||
|
@ -159,13 +159,13 @@ static inline float parse_float(const char *&line)
|
|||
char *endptr = NULL;
|
||||
float result = strtof(line, &endptr);
|
||||
if (endptr == NULL || !is_ws_or_eol(*endptr))
|
||||
throw std::runtime_error("GCodePressureEqualizer: Error parsing a float");
|
||||
throw std::runtime_error("PressureEqualizer: Error parsing a float");
|
||||
line = endptr;
|
||||
return result;
|
||||
};
|
||||
|
||||
#define EXTRUSION_ROLE_TAG ";_EXTRUSION_ROLE:"
|
||||
bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GCodeLine &buf)
|
||||
bool PressureEqualizer::process_line(const char *line, const size_t len, GCodeLine &buf)
|
||||
{
|
||||
if (strncmp(line, EXTRUSION_ROLE_TAG, strlen(EXTRUSION_ROLE_TAG)) == 0) {
|
||||
line += strlen(EXTRUSION_ROLE_TAG);
|
||||
|
@ -228,7 +228,7 @@ bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GC
|
|||
assert(false);
|
||||
}
|
||||
if (i == -1)
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Invalid axis for G0/G1: ") + axis);
|
||||
throw std::runtime_error(std::string("GCode::PressureEqualizer: Invalid axis for G0/G1: ") + axis);
|
||||
buf.pos_provided[i] = true;
|
||||
new_pos[i] = parse_float(line);
|
||||
if (i == 3 && m_config->use_relative_e_distances.value)
|
||||
|
@ -297,7 +297,7 @@ bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GC
|
|||
set = true;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(std::string("GCodePressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
throw std::runtime_error(std::string("GCode::PressureEqualizer: Incorrect axis in a G92 G-code: ") + axis);
|
||||
}
|
||||
eatws(line);
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ bool GCodePressureEqualizer::process_line(const char *line, const size_t len, GC
|
|||
return true;
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::output_gcode_line(GCodeLine &line)
|
||||
void PressureEqualizer::output_gcode_line(GCodeLine &line)
|
||||
{
|
||||
if (! line.modified) {
|
||||
push_to_output(line.raw.data(), line.raw_length, true);
|
||||
|
@ -453,7 +453,7 @@ void GCodePressureEqualizer::output_gcode_line(GCodeLine &line)
|
|||
}
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::adjust_volumetric_rate()
|
||||
void PressureEqualizer::adjust_volumetric_rate()
|
||||
{
|
||||
if (circular_buffer_items < 2)
|
||||
return;
|
||||
|
@ -563,7 +563,7 @@ void GCodePressureEqualizer::adjust_volumetric_rate()
|
|||
}
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::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];
|
||||
int len = sprintf(buf,
|
||||
|
@ -572,7 +572,7 @@ void GCodePressureEqualizer::push_axis_to_output(const char axis, const float va
|
|||
push_to_output(buf, len, add_eol);
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::push_to_output(const char *text, const size_t len, bool add_eol)
|
||||
void PressureEqualizer::push_to_output(const char *text, const size_t len, bool add_eol)
|
||||
{
|
||||
// New length of the output buffer content.
|
||||
size_t len_new = output_buffer_length + len + 1;
|
||||
|
@ -604,7 +604,7 @@ void GCodePressureEqualizer::push_to_output(const char *text, const size_t len,
|
|||
output_buffer[output_buffer_length] = 0;
|
||||
}
|
||||
|
||||
void GCodePressureEqualizer::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("G1", 2, false);
|
||||
for (char i = 0; i < 3; ++ i)
|
||||
|
|
|
@ -9,11 +9,11 @@ namespace Slic3r {
|
|||
|
||||
// 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 GCodePressureEqualizer
|
||||
class PressureEqualizer
|
||||
{
|
||||
public:
|
||||
GCodePressureEqualizer(const Slic3r::GCodeConfig *config);
|
||||
~GCodePressureEqualizer();
|
||||
PressureEqualizer(const Slic3r::GCodeConfig *config);
|
||||
~PressureEqualizer();
|
||||
|
||||
void reset();
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "SpiralVase.hpp"
|
||||
#include "GCode.hpp"
|
||||
#include <sstream>
|
||||
|
||||
namespace Slic3r {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define slic3r_SpiralVase_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "GCode.hpp"
|
||||
#include "GCodeReader.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue