mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-22 16:21:24 -06:00
Removed a broken Arc Fitting feature.
Removed the questionable Pressure Advance feature. It is better to use the Pressure Advance implemented into a firmware. Added a C++ implementation of GCodeReader and SpiralVase, thanks to @alexrj Added a C++ implementation of GCodeTimeEstimator, thanks to @lordofhyphens
This commit is contained in:
parent
e918ea9c65
commit
72ae3585e4
28 changed files with 459 additions and 1001 deletions
|
@ -78,11 +78,6 @@ AvoidCrossingPerimeters::travel_to(GCode &gcodegen, Point point)
|
|||
}
|
||||
}
|
||||
|
||||
OozePrevention::OozePrevention()
|
||||
: enable(false)
|
||||
{
|
||||
}
|
||||
|
||||
std::string
|
||||
OozePrevention::pre_toolchange(GCode &gcodegen)
|
||||
{
|
||||
|
@ -114,16 +109,11 @@ OozePrevention::pre_toolchange(GCode &gcodegen)
|
|||
return gcode;
|
||||
}
|
||||
|
||||
std::string
|
||||
OozePrevention::post_toolchange(GCode &gcodegen)
|
||||
std::string OozePrevention::post_toolchange(GCode &gcodegen)
|
||||
{
|
||||
std::string gcode;
|
||||
|
||||
if (gcodegen.config.standby_temperature_delta.value != 0) {
|
||||
gcode += gcodegen.writer.set_temperature(this->_get_temp(gcodegen), true);
|
||||
}
|
||||
|
||||
return gcode;
|
||||
return (gcodegen.config.standby_temperature_delta.value != 0) ?
|
||||
gcodegen.writer.set_temperature(this->_get_temp(gcodegen), true) :
|
||||
std::string();
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -134,23 +124,6 @@ OozePrevention::_get_temp(GCode &gcodegen)
|
|||
: gcodegen.config.temperature.get_at(gcodegen.writer.extruder()->id);
|
||||
}
|
||||
|
||||
Wipe::Wipe()
|
||||
: enable(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Wipe::has_path()
|
||||
{
|
||||
return !this->path.points.empty();
|
||||
}
|
||||
|
||||
void
|
||||
Wipe::reset_path()
|
||||
{
|
||||
this->path = Polyline();
|
||||
}
|
||||
|
||||
std::string
|
||||
Wipe::wipe(GCode &gcodegen, bool toolchange)
|
||||
{
|
||||
|
|
|
@ -41,26 +41,26 @@ class AvoidCrossingPerimeters {
|
|||
};
|
||||
|
||||
class OozePrevention {
|
||||
public:
|
||||
public:
|
||||
bool enable;
|
||||
Points standby_points;
|
||||
|
||||
OozePrevention();
|
||||
OozePrevention() : enable(false) {}
|
||||
std::string pre_toolchange(GCode &gcodegen);
|
||||
std::string post_toolchange(GCode &gcodegen);
|
||||
|
||||
private:
|
||||
private:
|
||||
int _get_temp(GCode &gcodegen);
|
||||
};
|
||||
|
||||
class Wipe {
|
||||
public:
|
||||
public:
|
||||
bool enable;
|
||||
Polyline path;
|
||||
|
||||
Wipe();
|
||||
bool has_path();
|
||||
void reset_path();
|
||||
Wipe() : enable(false) {}
|
||||
bool has_path() const { return !this->path.points.empty(); }
|
||||
void reset_path() { this->path = Polyline(); }
|
||||
std::string wipe(GCode &gcodegen, bool toolchange = false);
|
||||
};
|
||||
|
||||
|
|
95
xs/src/libslic3r/GCode/SpiralVase.cpp
Normal file
95
xs/src/libslic3r/GCode/SpiralVase.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include "SpiralVase.hpp"
|
||||
#include <sstream>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
std::string
|
||||
_format_z(float z)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << std::fixed << std::setprecision(3)
|
||||
<< z;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
SpiralVase::process_layer(const std::string &gcode)
|
||||
{
|
||||
/* This post-processor relies on several assumptions:
|
||||
- all layers are processed through it, including those that are not supposed
|
||||
to be transformed, in order to update the reader with the XY positions
|
||||
- each call to this method includes a full layer, with a single Z move
|
||||
at the beginning
|
||||
- each layer is composed by suitable geometry (i.e. a single complete loop)
|
||||
- loops were not clipped before calling this method */
|
||||
|
||||
// If we're not going to modify G-code, just feed it to the reader
|
||||
// in order to update positions.
|
||||
if (!this->enable) {
|
||||
this->_reader.parse(gcode, {});
|
||||
return gcode;
|
||||
}
|
||||
|
||||
// Get total XY length for this layer by summing all extrusion moves.
|
||||
float total_layer_length = 0;
|
||||
float layer_height = 0;
|
||||
float z;
|
||||
bool set_z = false;
|
||||
|
||||
{
|
||||
GCodeReader r = this->_reader; // clone
|
||||
r.parse(gcode, [&total_layer_length, &layer_height, &z, &set_z]
|
||||
(GCodeReader &, const GCodeReader::GCodeLine &line) {
|
||||
if (line.cmd == "G1") {
|
||||
if (line.extruding()) {
|
||||
total_layer_length += line.dist_XY();
|
||||
} else if (line.has('Z')) {
|
||||
layer_height += line.dist_Z();
|
||||
if (!set_z) {
|
||||
z = line.new_Z();
|
||||
set_z = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Remove layer height from initial Z.
|
||||
z -= layer_height;
|
||||
|
||||
std::string new_gcode;
|
||||
this->_reader.parse(gcode, [&new_gcode, &z, &layer_height, &total_layer_length]
|
||||
(GCodeReader &, GCodeReader::GCodeLine line) {
|
||||
if (line.cmd == "G1") {
|
||||
if (line.has('Z')) {
|
||||
// If this is the initial Z move of the layer, replace it with a
|
||||
// (redundant) move to the last Z of previous layer.
|
||||
line.set('Z', _format_z(z));
|
||||
new_gcode += line.raw + '\n';
|
||||
return;
|
||||
} else {
|
||||
float dist_XY = line.dist_XY();
|
||||
if (dist_XY > 0) {
|
||||
// horizontal move
|
||||
if (line.extruding()) {
|
||||
z += dist_XY * layer_height / total_layer_length;
|
||||
line.set('Z', _format_z(z));
|
||||
new_gcode += line.raw + '\n';
|
||||
}
|
||||
return;
|
||||
|
||||
/* Skip travel moves: the move to first perimeter point will
|
||||
cause a visible seam when loops are not aligned in XY; by skipping
|
||||
it we blend the first loop move in the XY plane (although the smoothness
|
||||
of such blend depend on how long the first segment is; maybe we should
|
||||
enforce some minimum length?). */
|
||||
}
|
||||
}
|
||||
}
|
||||
new_gcode += line.raw + '\n';
|
||||
});
|
||||
|
||||
return new_gcode;
|
||||
}
|
||||
|
||||
}
|
29
xs/src/libslic3r/GCode/SpiralVase.hpp
Normal file
29
xs/src/libslic3r/GCode/SpiralVase.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef slic3r_SpiralVase_hpp_
|
||||
#define slic3r_SpiralVase_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "GCode.hpp"
|
||||
#include "GCodeReader.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class SpiralVase {
|
||||
public:
|
||||
bool enable;
|
||||
|
||||
SpiralVase(const PrintConfig &config)
|
||||
: enable(false), _config(&config)
|
||||
{
|
||||
this->_reader.Z = this->_config->z_offset;
|
||||
this->_reader.apply_config(*this->_config);
|
||||
};
|
||||
std::string process_layer(const std::string &gcode);
|
||||
|
||||
private:
|
||||
const PrintConfig* _config;
|
||||
GCodeReader _reader;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
109
xs/src/libslic3r/GCodeReader.cpp
Normal file
109
xs/src/libslic3r/GCodeReader.cpp
Normal file
|
@ -0,0 +1,109 @@
|
|||
#include "GCodeReader.hpp"
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void
|
||||
GCodeReader::apply_config(const PrintConfigBase &config)
|
||||
{
|
||||
this->_config.apply(config, true);
|
||||
this->_extrusion_axis = this->_config.get_extrusion_axis()[0];
|
||||
}
|
||||
|
||||
void
|
||||
GCodeReader::parse(const std::string &gcode, callback_t callback)
|
||||
{
|
||||
std::istringstream ss(gcode);
|
||||
std::string line;
|
||||
while (std::getline(ss, line))
|
||||
this->parse_line(line, callback);
|
||||
}
|
||||
|
||||
void
|
||||
GCodeReader::parse_line(std::string line, callback_t callback)
|
||||
{
|
||||
GCodeLine gline(this);
|
||||
gline.raw = line;
|
||||
if (this->verbose)
|
||||
std::cout << line << std::endl;
|
||||
|
||||
// strip comment
|
||||
{
|
||||
size_t pos = line.find(';');
|
||||
if (pos != std::string::npos) {
|
||||
gline.comment = line.substr(pos+1);
|
||||
line.erase(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// command and args
|
||||
{
|
||||
std::vector<std::string> args;
|
||||
boost::split(args, line, boost::is_any_of(" "));
|
||||
|
||||
// first one is cmd
|
||||
gline.cmd = args.front();
|
||||
args.erase(args.begin());
|
||||
|
||||
for (std::string &arg : args) {
|
||||
if (arg.size() < 2) continue;
|
||||
gline.args.insert(std::make_pair(arg[0], arg.substr(1)));
|
||||
}
|
||||
}
|
||||
|
||||
// convert extrusion axis
|
||||
if (this->_extrusion_axis != 'E') {
|
||||
const auto it = gline.args.find(this->_extrusion_axis);
|
||||
if (it != gline.args.end()) {
|
||||
std::swap(gline.args['E'], it->second);
|
||||
gline.args.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
if (gline.has('E') && this->_config.use_relative_e_distances)
|
||||
this->E = 0;
|
||||
|
||||
if (callback) callback(*this, gline);
|
||||
|
||||
// update coordinates
|
||||
if (gline.cmd == "G0" || gline.cmd == "G1" || gline.cmd == "G92") {
|
||||
this->X = gline.new_X();
|
||||
this->Y = gline.new_Y();
|
||||
this->Z = gline.new_Z();
|
||||
this->E = gline.new_E();
|
||||
this->F = gline.new_F();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GCodeReader::parse_file(const std::string &file, callback_t callback)
|
||||
{
|
||||
std::ifstream f(file);
|
||||
std::string line;
|
||||
while (std::getline(f, line))
|
||||
this->parse_line(line, callback);
|
||||
}
|
||||
|
||||
void
|
||||
GCodeReader::GCodeLine::set(char arg, std::string value)
|
||||
{
|
||||
const std::string space(" ");
|
||||
if (this->has(arg)) {
|
||||
size_t pos = this->raw.find(space + arg)+2;
|
||||
size_t end = this->raw.find(' ', pos+1);
|
||||
this->raw = this->raw.replace(pos, end-pos, value);
|
||||
} else {
|
||||
size_t pos = this->raw.find(' ');
|
||||
if (pos == std::string::npos) {
|
||||
this->raw += space + arg + value;
|
||||
} else {
|
||||
this->raw = this->raw.replace(pos, 0, space + arg + value);
|
||||
}
|
||||
}
|
||||
this->args[arg] = value;
|
||||
}
|
||||
|
||||
}
|
65
xs/src/libslic3r/GCodeReader.hpp
Normal file
65
xs/src/libslic3r/GCodeReader.hpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
#ifndef slic3r_GCodeReader_hpp_
|
||||
#define slic3r_GCodeReader_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include "PrintConfig.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GCodeReader {
|
||||
public:
|
||||
class GCodeLine {
|
||||
public:
|
||||
GCodeReader* reader;
|
||||
std::string raw;
|
||||
std::string cmd;
|
||||
std::string comment;
|
||||
std::map<char,std::string> args;
|
||||
|
||||
GCodeLine(GCodeReader* _reader) : reader(_reader) {};
|
||||
|
||||
bool has(char arg) const { return this->args.count(arg) > 0; };
|
||||
float get_float(char arg) const { return atof(this->args.at(arg).c_str()); };
|
||||
float new_X() const { return this->has('X') ? atof(this->args.at('X').c_str()) : this->reader->X; };
|
||||
float new_Y() const { return this->has('Y') ? atof(this->args.at('Y').c_str()) : this->reader->Y; };
|
||||
float new_Z() const { return this->has('Z') ? atof(this->args.at('Z').c_str()) : this->reader->Z; };
|
||||
float new_E() const { return this->has('E') ? atof(this->args.at('E').c_str()) : this->reader->E; };
|
||||
float new_F() const { return this->has('F') ? atof(this->args.at('F').c_str()) : this->reader->F; };
|
||||
float dist_X() const { return this->new_X() - this->reader->X; };
|
||||
float dist_Y() const { return this->new_Y() - this->reader->Y; };
|
||||
float dist_Z() const { return this->new_Z() - this->reader->Z; };
|
||||
float dist_E() const { return this->new_E() - this->reader->E; };
|
||||
float dist_XY() const {
|
||||
float x = this->dist_X();
|
||||
float y = this->dist_Y();
|
||||
return sqrt(x*x + y*y);
|
||||
};
|
||||
bool extruding() const { return this->cmd == "G1" && this->dist_E() > 0; };
|
||||
bool retracting() const { return this->cmd == "G1" && this->dist_E() < 0; };
|
||||
bool travel() const { return this->cmd == "G1" && !this->has('E'); };
|
||||
void set(char arg, std::string value);
|
||||
};
|
||||
typedef std::function<void(GCodeReader&, const GCodeLine&)> callback_t;
|
||||
|
||||
float X, Y, Z, E, F;
|
||||
bool verbose;
|
||||
callback_t callback;
|
||||
|
||||
GCodeReader() : X(0), Y(0), Z(0), E(0), F(0), verbose(false), _extrusion_axis('E') {};
|
||||
void apply_config(const PrintConfigBase &config);
|
||||
void parse(const std::string &gcode, callback_t callback);
|
||||
void parse_line(std::string line, callback_t callback);
|
||||
void parse_file(const std::string &file, callback_t callback);
|
||||
|
||||
private:
|
||||
GCodeConfig _config;
|
||||
char _extrusion_axis;
|
||||
};
|
||||
|
||||
} /* namespace Slic3r */
|
||||
|
||||
#endif /* slic3r_GCodeReader_hpp_ */
|
78
xs/src/libslic3r/GCodeTimeEstimator.cpp
Normal file
78
xs/src/libslic3r/GCodeTimeEstimator.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "GCodeTimeEstimator.hpp"
|
||||
#include <boost/bind.hpp>
|
||||
#include <cmath>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void
|
||||
GCodeTimeEstimator::parse(const std::string &gcode)
|
||||
{
|
||||
GCodeReader::parse(gcode, boost::bind(&GCodeTimeEstimator::_parser, this, _1, _2));
|
||||
}
|
||||
|
||||
void
|
||||
GCodeTimeEstimator::parse_file(const std::string &file)
|
||||
{
|
||||
GCodeReader::parse_file(file, boost::bind(&GCodeTimeEstimator::_parser, this, _1, _2));
|
||||
}
|
||||
|
||||
void
|
||||
GCodeTimeEstimator::_parser(GCodeReader&, const GCodeReader::GCodeLine &line)
|
||||
{
|
||||
// std::cout << "[" << this->time << "] " << line.raw << std::endl;
|
||||
if (line.cmd == "G1") {
|
||||
const float dist_XY = line.dist_XY();
|
||||
const float new_F = line.new_F();
|
||||
|
||||
if (dist_XY > 0) {
|
||||
//this->time += dist_XY / new_F * 60;
|
||||
this->time += _accelerated_move(dist_XY, new_F/60, this->acceleration);
|
||||
} else {
|
||||
//this->time += std::abs(line.dist_E()) / new_F * 60;
|
||||
this->time += _accelerated_move(std::abs(line.dist_E()), new_F/60, this->acceleration);
|
||||
}
|
||||
//this->time += std::abs(line.dist_Z()) / new_F * 60;
|
||||
this->time += _accelerated_move(std::abs(line.dist_Z()), new_F/60, this->acceleration);
|
||||
} else if (line.cmd == "M204" && line.has('S')) {
|
||||
this->acceleration = line.get_float('S');
|
||||
} else if (line.cmd == "G4") { // swell
|
||||
if (line.has('S')) {
|
||||
this->time += line.get_float('S');
|
||||
} else if (line.has('P')) {
|
||||
this->time += line.get_float('P')/1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wildly optimistic acceleration "bell" curve modeling.
|
||||
// Returns an estimate of how long the move with a given accel
|
||||
// takes in seconds.
|
||||
// It is assumed that the movement is smooth and uniform.
|
||||
float
|
||||
GCodeTimeEstimator::_accelerated_move(double length, double v, double acceleration)
|
||||
{
|
||||
// for half of the move, there are 2 zones, where the speed is increasing/decreasing and
|
||||
// where the speed is constant.
|
||||
// Since the slowdown is assumed to be uniform, calculate the average velocity for half of the
|
||||
// expected displacement.
|
||||
// final velocity v = a*t => a * (dx / 0.5v) => v^2 = 2*a*dx
|
||||
// v_avg = 0.5v => 2*v_avg = v
|
||||
// d_x = v_avg*t => t = d_x / v_avg
|
||||
acceleration = (acceleration == 0.0 ? 4000.0 : acceleration); // Set a default accel to use for print time in case it's 0 somehow.
|
||||
auto half_length = length / 2.0;
|
||||
auto t_init = v / acceleration; // time to final velocity
|
||||
auto dx_init = (0.5*v*t_init); // Initial displacement for the time to get to final velocity
|
||||
auto t = 0.0;
|
||||
if (half_length >= dx_init) {
|
||||
half_length -= (0.5*v*t_init);
|
||||
t += t_init;
|
||||
t += (half_length / v); // rest of time is at constant speed.
|
||||
} else {
|
||||
// If too much displacement for the expected final velocity, we don't hit the max, so reduce
|
||||
// the average velocity to fit the displacement we actually are looking for.
|
||||
t += std::sqrt(std::abs(length) * 2.0 * acceleration) / acceleration;
|
||||
}
|
||||
return 2.0*t; // cut in half before, so double to get full time spent.
|
||||
}
|
||||
|
||||
}
|
24
xs/src/libslic3r/GCodeTimeEstimator.hpp
Normal file
24
xs/src/libslic3r/GCodeTimeEstimator.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef slic3r_GCodeTimeEstimator_hpp_
|
||||
#define slic3r_GCodeTimeEstimator_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "GCodeReader.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class GCodeTimeEstimator : public GCodeReader {
|
||||
public:
|
||||
float time = 0; // in seconds
|
||||
|
||||
void parse(const std::string &gcode);
|
||||
void parse_file(const std::string &file);
|
||||
|
||||
protected:
|
||||
float acceleration = 9000;
|
||||
void _parser(GCodeReader&, const GCodeReader::GCodeLine &line);
|
||||
static float _accelerated_move(double length, double v, double acceleration);
|
||||
};
|
||||
|
||||
} /* namespace Slic3r */
|
||||
|
||||
#endif /* slic3r_GCodeTimeEstimator_hpp_ */
|
|
@ -152,7 +152,6 @@ Print::invalidate_state_by_config_options(const std::vector<t_config_option_key>
|
|||
|| *opt_key == "first_layer_bed_temperature"
|
||||
|| *opt_key == "first_layer_speed"
|
||||
|| *opt_key == "first_layer_temperature"
|
||||
|| *opt_key == "gcode_arcs"
|
||||
|| *opt_key == "gcode_comments"
|
||||
|| *opt_key == "gcode_flavor"
|
||||
|| *opt_key == "infill_acceleration"
|
||||
|
@ -166,7 +165,6 @@ Print::invalidate_state_by_config_options(const std::vector<t_config_option_key>
|
|||
|| *opt_key == "output_filename_format"
|
||||
|| *opt_key == "perimeter_acceleration"
|
||||
|| *opt_key == "post_process"
|
||||
|| *opt_key == "pressure_advance"
|
||||
|| *opt_key == "retract_before_travel"
|
||||
|| *opt_key == "retract_layer_change"
|
||||
|| *opt_key == "retract_length"
|
||||
|
|
|
@ -514,12 +514,6 @@ PrintConfigDef::PrintConfigDef()
|
|||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(20);
|
||||
|
||||
def = this->add("gcode_arcs", coBool);
|
||||
def->label = "Use native G-code arcs";
|
||||
def->tooltip = "This experimental feature tries to detect arcs from segments and generates G2/G3 arc commands instead of multiple straight G1 commands.";
|
||||
def->cli = "gcode-arcs!";
|
||||
def->default_value = new ConfigOptionBool(0);
|
||||
|
||||
def = this->add("gcode_comments", coBool);
|
||||
def->label = "Verbose G-code";
|
||||
def->tooltip = "Enable this to get a commented G-code file, with each line explained by a descriptive text. If you print from SD card, the additional weight of the file could make your firmware slow down.";
|
||||
|
@ -853,13 +847,6 @@ PrintConfigDef::PrintConfigDef()
|
|||
def = this->add("printer_settings_id", coString);
|
||||
def->default_value = new ConfigOptionString("");
|
||||
|
||||
def = this->add("pressure_advance", coFloat);
|
||||
def->label = "Pressure advance";
|
||||
def->tooltip = "When set to a non-zero value, this experimental option enables pressure regulation. It's the K constant for the advance algorithm that pushes more or less filament upon speed changes. It's useful for Bowden-tube extruders. Reasonable values are in range 0-10.";
|
||||
def->cli = "pressure-advance=f";
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(0);
|
||||
|
||||
def = this->add("raft_layers", coInt);
|
||||
def->label = "Raft layers";
|
||||
def->category = "Support material";
|
||||
|
|
|
@ -313,7 +313,6 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||
ConfigOptionFloat max_volumetric_speed;
|
||||
ConfigOptionFloat max_volumetric_extrusion_rate_slope_positive;
|
||||
ConfigOptionFloat max_volumetric_extrusion_rate_slope_negative;
|
||||
ConfigOptionFloat pressure_advance;
|
||||
ConfigOptionFloats retract_length;
|
||||
ConfigOptionFloats retract_length_toolchange;
|
||||
ConfigOptionFloats retract_lift;
|
||||
|
@ -351,7 +350,6 @@ class GCodeConfig : public virtual StaticPrintConfig
|
|||
OPT_PTR(max_volumetric_speed);
|
||||
OPT_PTR(max_volumetric_extrusion_rate_slope_positive);
|
||||
OPT_PTR(max_volumetric_extrusion_rate_slope_negative);
|
||||
OPT_PTR(pressure_advance);
|
||||
OPT_PTR(retract_length);
|
||||
OPT_PTR(retract_length_toolchange);
|
||||
OPT_PTR(retract_lift);
|
||||
|
@ -409,7 +407,6 @@ class PrintConfig : public GCodeConfig
|
|||
ConfigOptionFloatOrPercent first_layer_extrusion_width;
|
||||
ConfigOptionFloatOrPercent first_layer_speed;
|
||||
ConfigOptionInts first_layer_temperature;
|
||||
ConfigOptionBool gcode_arcs;
|
||||
ConfigOptionFloat infill_acceleration;
|
||||
ConfigOptionBool infill_first;
|
||||
ConfigOptionInt max_fan_speed;
|
||||
|
@ -468,7 +465,6 @@ class PrintConfig : public GCodeConfig
|
|||
OPT_PTR(first_layer_extrusion_width);
|
||||
OPT_PTR(first_layer_speed);
|
||||
OPT_PTR(first_layer_temperature);
|
||||
OPT_PTR(gcode_arcs);
|
||||
OPT_PTR(infill_acceleration);
|
||||
OPT_PTR(infill_first);
|
||||
OPT_PTR(max_fan_speed);
|
||||
|
|
|
@ -17,6 +17,7 @@ REGISTER_CLASS(Flow, "Flow");
|
|||
REGISTER_CLASS(AvoidCrossingPerimeters, "GCode::AvoidCrossingPerimeters");
|
||||
REGISTER_CLASS(CoolingBuffer, "GCode::CoolingBuffer");
|
||||
REGISTER_CLASS(OozePrevention, "GCode::OozePrevention");
|
||||
REGISTER_CLASS(SpiralVase, "GCode::SpiralVase");
|
||||
REGISTER_CLASS(Wipe, "GCode::Wipe");
|
||||
REGISTER_CLASS(GCode, "GCode");
|
||||
REGISTER_CLASS(GCodeSender, "GCode::Sender");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue