OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GCodeWriter Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/GCodeWriter.hpp>

Collaboration diagram for Slic3r::GCodeWriter:

Public Types

using FirstLayerPointTest = std::function<bool(const Vec3d &point_logical)>

Public Member Functions

 GCodeWriter ()
Extruder * filament (size_t extruder_id)
const Extruder * filament (size_t extruder_id) const
Extruder * filament ()
const Extruder * filament () const
void apply_print_config (const PrintConfig &print_config)
void set_extruders (std::vector< unsigned int > extruder_ids)
const std::vector< Extruder > & extruders () const
std::vector< unsigned int > extruder_ids () const
std::string preamble ()
std::string postamble () const
std::string set_temperature (unsigned int temperature, bool wait=false, int tool=-1) const
std::string set_bed_temperature (int temperature, bool wait=false)
std::string set_chamber_temperature (int temperature, bool wait=false)
std::string set_print_acceleration (unsigned int acceleration)
std::string set_travel_acceleration (unsigned int acceleration)
std::string set_jerk_xy (double jerk)
std::string set_accel_and_jerk (unsigned int acceleration, double jerk)
std::string set_junction_deviation (double junction_deviation)
std::string set_pressure_advance (double pa, int tool=-1) const
std::string set_input_shaping (char axis, float damp, float freq, std::string type) const
std::string reset_e (bool force=false)
std::string update_progress (unsigned int num, unsigned int tot, bool allow_100=false) const
std::string enable_power_loss_recovery (PowerLossRecoveryMode mode)
bool need_toolchange (unsigned int filament_id) const
std::string set_extruder (unsigned int filament_id)
void init_extruder (unsigned int filament_id)
double get_extruder_retracted_length (const int filament_id)
std::string toolchange_prefix () const
std::string toolchange (unsigned int filament_id, int nozzle_id)
std::string set_speed (double F, const std::string &comment=std::string(), const std::string &cooling_marker=std::string())
double get_current_speed () const
std::string travel_to_xy (const Vec2d &point, const std::string &comment=std::string())
std::string travel_to_xyz (const Vec3d &point, const std::string &comment=std::string(), bool force_z=false)
std::pair< double, double > planned_travel_z (const Vec3d &point, bool force_z=false) const
std::string travel_to_z (double z, const std::string &comment=std::string(), bool force=false)
bool will_move_z (double z) const
std::string extrude_to_xy (const Vec2d &point, double dE, const std::string &comment=std::string(), bool force_no_extrusion=false)
std::string extrude_arc_to_xy (const Vec2d &point, const Vec2d &center_offset, double dE, const bool is_ccw, const std::string &comment=std::string(), bool force_no_extrusion=false)
void extrude_arc_as_polyline (std::string &out, const Vec2d &point, const Vec2d &center_offset, double dE, const bool is_ccw, const std::string &comment=std::string(), bool force_no_extrusion=false)
std::string extrude_to_xyz (const Vec3d &point, double dE, const std::string &comment=std::string(), bool force_no_extrusion=false)
void set_speed (std::string &out, double F, const std::string &comment=std::string(), const std::string &cooling_marker=std::string())
void extrude_to_xy (std::string &out, const Vec2d &point, double dE, const std::string &comment=std::string(), bool force_no_extrusion=false)
void extrude_arc_to_xy (std::string &out, const Vec2d &point, const Vec2d &center_offset, double dE, const bool is_ccw, const std::string &comment=std::string(), bool force_no_extrusion=false)
void extrude_to_xyz (std::string &out, const Vec3d &point, double dE, const std::string &comment=std::string(), bool force_no_extrusion=false)
std::string retract (bool before_wipe=false, double retract_length=0)
std::string retract_for_toolchange (bool before_wipe=false, double retract_length=0)
std::string unretract (float extra_retract=0.f)
std::string eager_lift (const LiftType type)
std::string lazy_lift (LiftType lift_type=LiftType::NormalLift, bool spiral_vase=false)
std::string unlift ()
const Vec3d & get_position () const
Vec3d & get_position ()
void set_position (const Vec3d &in)
double get_zhop () const
void set_xy_offset (double x, double y)
Vec2f get_xy_offset ()
std::string set_fan (unsigned int speed) const
void set_object_start_str (std::string start_string)
bool is_object_start_str_empty ()
void set_object_end_str (std::string end_string)
bool is_object_end_str_empty ()
void add_object_start_labels (std::string &gcode)
void add_object_end_labels (std::string &gcode)
void add_object_change_labels (std::string &gcode)
void set_current_position_clear (bool clear)
bool is_current_position_clear () const
void set_is_bbl_machine (bool bval)
const bool is_bbl_printers () const
void set_is_first_layer (bool bval)
GCodeFlavor get_gcode_flavor () const
void invalidate_acceleration ()
void invalidate_jerk ()
void set_axis_remap (int rx, int ry, int rz)
void set_build_volume_max (const Vec3d &max)
bool has_axis_remap () const
void set_kinematics (std::unique_ptr< MachineKinematics > kinematics)
const MachineKinematics & kinematics () const
void set_first_layer_point_test (FirstLayerPointTest test)
void set_force_normal_lift (bool force)
bool high_precision () const
bool force_standard_precision (bool force)

Static Public Member Functions

static std::string set_temperature (unsigned int temperature, GCodeFlavor flavor, bool wait=false, int tool=-1, std::string comment=std::string())
static void append_klipper_accel_to_decel (std::string &gcode, unsigned int acceleration, double accel_to_decel_factor)
static std::string set_fan (const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm=0)
static std::string set_additional_fan (unsigned int speed)
static std::string set_exhaust_fan (int speed)
static bool supports_separate_travel_acceleration (GCodeFlavor flavor)

Public Attributes

GCodeConfig config
bool multiple_extruders

Static Public Attributes

static bool full_gcode_comment = true

Protected Member Functions

std::string _travel_to_z (double z, const std::string &comment)
bool point_on_first_layer (const Vec3d &point_logical) const
bool must_skip_lift_now () const
bool uses_pointwise_travel_speed () const
Vec3d apply_axis_remap (const Vec3d &pos) const

Protected Attributes

Vec3d m_pos = Vec3d::Zero()
double m_x_offset { 0 }
double m_y_offset { 0 }
double m_lifted
double m_to_lift
LiftType m_to_lift_type
bool m_is_first_layer = true
bool m_is_current_pos_clear = false
double m_current_speed
FirstLayerPointTest m_first_layer_point_test
bool m_force_normal_lift = false
bool m_force_standard_precision = false
std::unique_ptr< MachineKinematics > m_kinematics
int m_remap_x = 0
int m_remap_y = 1
int m_remap_z = 2
Vec3d m_build_vol_max = Vec3d::Zero()
size_t m_cached_extruder_idx

Private Types

enum class  Acceleration { Travel , Print }

Private Member Functions

std::string _spiral_travel_to_z (double z, const Vec2d &ij_offset, const std::string &comment)
const Polygon * active_printable_area () const
bool spiral_lift_fits_printable_area (const Vec2d &center, double radius) const
std::string _retract (double length, double restart_extra, const std::string &comment)
std::string set_acceleration_internal (Acceleration type, unsigned int acceleration)

Private Attributes

std::vector< Extruder > m_filament_extruders
bool m_single_extruder_multi_material
std::vector< Extruder * > m_curr_filament_extruder
int m_curr_extruder_id
unsigned int m_last_acceleration
unsigned int m_last_travel_acceleration
std::vector< unsigned int > m_max_travel_acceleration
std::vector< unsigned int > m_max_acceleration
std::vector< double > m_max_jerk_x
std::vector< double > m_max_jerk_y
double m_last_jerk
std::vector< double > m_max_jerk_z
std::vector< double > m_max_jerk_e
std::vector< double > m_max_junction_deviation
int m_last_bed_temperature
bool m_last_bed_temperature_reached
double m_resolution = 0.01
Polygon m_bed_printable_area
std::vector< Polygon > m_extruder_printable_areas
std::string m_gcode_label_objects_start
std::string m_gcode_label_objects_end
bool m_is_bbl_printers = false

Detailed Description

Member Typedef Documentation

◆ FirstLayerPointTest

using Slic3r::GCodeWriter::FirstLayerPointTest = std::function<bool(const Vec3d &point_logical)>

Member Enumeration Documentation

◆ Acceleration

enum class Slic3r::GCodeWriter::Acceleration
strongprivate
Enumerator
Travel 
Print 
303 {
304 Travel,
305 Print
306 };
@ Travel
Definition ExclusionVolumePathCheck.hpp:17

Constructor & Destructor Documentation

◆ GCodeWriter()

Slic3r::GCodeWriter::GCodeWriter ( )
inline
31 :
32 multiple_extruders(false),
33 m_lifted(0),
34 m_to_lift(0),
37 m_kinematics(std::make_unique<CartesianKinematics>()),
45 {}
bool m_is_first_layer
Definition GCodeWriter.hpp:209
double m_last_jerk
Definition GCodeWriter.hpp:273
int m_curr_extruder_id
Definition GCodeWriter.hpp:263
size_t m_cached_extruder_idx
Definition GCodeWriter.hpp:256
std::vector< unsigned int > m_max_travel_acceleration
Definition GCodeWriter.hpp:266
int m_last_bed_temperature
Definition GCodeWriter.hpp:283
std::vector< double > m_max_jerk_x
Definition GCodeWriter.hpp:271
LiftType m_to_lift_type
Definition GCodeWriter.hpp:208
double m_to_lift
Definition GCodeWriter.hpp:207
std::unique_ptr< MachineKinematics > m_kinematics
Definition GCodeWriter.hpp:240
bool m_last_bed_temperature_reached
Definition GCodeWriter.hpp:284
std::vector< unsigned int > m_max_acceleration
Definition GCodeWriter.hpp:270
bool m_single_extruder_multi_material
Definition GCodeWriter.hpp:261
std::vector< double > m_max_jerk_y
Definition GCodeWriter.hpp:272
double m_current_speed
Definition GCodeWriter.hpp:211
double m_lifted
Definition GCodeWriter.hpp:206
unsigned int m_last_acceleration
Definition GCodeWriter.hpp:264
std::vector< Extruder * > m_curr_filament_extruder
Definition GCodeWriter.hpp:262
unsigned int m_last_travel_acceleration
Definition GCodeWriter.hpp:265
bool multiple_extruders
Definition GCodeWriter.hpp:29
static constexpr size_t MAXIMUM_EXTRUDER_NUMBER
Definition libslic3r.h:70
@ NormalLift
Definition PrintConfig.hpp:430

References m_cached_extruder_idx, m_curr_extruder_id, m_curr_filament_extruder, m_current_speed, m_is_first_layer, m_kinematics, m_last_acceleration, m_last_bed_temperature, m_last_bed_temperature_reached, m_last_jerk, m_last_travel_acceleration, m_lifted, m_max_acceleration, m_max_jerk_x, m_max_jerk_y, m_max_travel_acceleration, m_single_extruder_multi_material, m_to_lift, m_to_lift_type, Slic3r::make_unique(), MAXIMUM_EXTRUDER_NUMBER, multiple_extruders, and Slic3r::NormalLift.

Here is the call graph for this function:

Member Function Documentation

◆ _retract()

std::string Slic3r::GCodeWriter::_retract ( double length,
double restart_extra,
const std::string & comment )
private
1480{
1481 /* If firmware retraction is enabled, we use a fake value of 1
1482 since we ignore the actual configured retract_length which
1483 might be 0, in which case the retraction logic gets skipped. */
1484 if (this->config.use_firmware_retraction)
1485 length = 1;
1486
1487 std::string gcode;
1488 if (double dE = filament()->retract(length, restart_extra); !is_zero(dE)) {
1489 if (this->config.use_firmware_retraction) {
1490 gcode = FLAVOR_IS(gcfMachinekit) ? "G22 ; retract\n" : "G10 ; retract\n";
1491 }
1492 else {
1493 // BBS
1494 const bool high_precision = this->high_precision();
1495 GCodeG1Formatter w(high_precision);
1496 w.emit_e(filament()->E_to_emit(high_precision));
1497 w.emit_f(filament()->retract_speed() * 60.);
1498 // BBS
1499 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1500 gcode = w.string();
1501 }
1502 }
1503
1505 gcode += "M103 ; extruder off\n";
1506
1507 return gcode;
1508}
#define FLAVOR_IS(val)
Definition GCodeWriter.cpp:42
static bool full_gcode_comment
Definition GCodeWriter.hpp:159
GCodeConfig config
Definition GCodeWriter.hpp:28
bool high_precision() const
Definition GCodeWriter.hpp:195
Extruder * filament()
Definition GCodeWriter.hpp:48
std::string retract(bool before_wipe=false, double retract_length=0)
Definition GCodeWriter.cpp:1457
@ gcode
Definition Time.hpp:14
@ gcfMachinekit
Definition PrintConfig.hpp:62
@ gcfMakerWare
Definition PrintConfig.hpp:59
double length(const Points &pts)
Definition MultiPoint.hpp:181
constexpr bool is_zero(Number value)
Definition libslic3r.h:307

References config, Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_e(), Slic3r::GCodeFormatter::emit_f(), filament(), FLAVOR_IS, full_gcode_comment, Slic3r::gcfMachinekit, Slic3r::gcfMakerWare, high_precision(), Slic3r::is_zero(), Slic3r::length(), retract(), and Slic3r::GCodeFormatter::string().

Referenced by retract(), and retract_for_toolchange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _spiral_travel_to_z()

std::string Slic3r::GCodeWriter::_spiral_travel_to_z ( double z,
const Vec2d & ij_offset,
const std::string & comment )
private
1201{
1202 // A circular XY arc / spiral lift cannot be correctly axis-remapped by
1203 // transforming only its endpoint: the arc plane (G17/XY) and the I-J center
1204 // would change under the remap. When an axis remap is active, fall back to a
1205 // plain linear lift instead of emitting a possibly-wrong spiral/arc. This
1206 // single guard covers every spiral call site (lazy/eager lift and travel_to_xyz).
1207 if (has_axis_remap())
1208 return _travel_to_z(z, comment);
1209
1210 std::string output;
1211 double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx);
1212
1213 if (speed == 0.) {
1214 speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx)
1215 : this->config.travel_speed.get_at(m_cached_extruder_idx);
1216 }
1217
1218 if (this->config.enable_arc_fitting.value == ArcFittingMode::Disabled) { // Orca: if arc fitting is disabled, approximate the arc with small linear segments
1219 const double z_start = m_pos(2); // starting Z height
1220
1221 const double px = m_pos(0) - m_x_offset; // take plate offset into consideration
1222 const double py = m_pos(1) - m_y_offset; // take plate offset into consideration
1223 const double cx = px + ij_offset(0); // center x
1224 const double cy = py + ij_offset(1); // center y
1225 const double radius = ij_offset.norm(); // radius
1226
1227 // Number of linear segments approximating the circle, chosen so that a chord never deviates
1228 // from the true arc by more than the slicing resolution. A resolution of 0 means "no
1229 // simplification", which has no finite segment count, so it takes the upper bound.
1230 constexpr size_t min_segments = 8; // keep a small spiral visibly round
1231 constexpr size_t max_segments = 128; // bound the emitted G-code
1232 const int segments = int(m_resolution > 0. ?
1233 std::clamp(Geometry::ArcWelder::arc_discretization_steps(radius, 2. * M_PI, m_resolution), min_segments, max_segments) :
1234 max_segments);
1235
1236 const double a0 = std::atan2(py - cy, px - cx); // start angle
1237
1238 auto emit_point = [this, &output](const Vec3d &point) {
1239 GCodeG1Formatter w(config.high_precision_gcode.value);
1240 w.emit_xyz(point);
1241 output += w.string();
1242 };
1243
1244 output.reserve(size_t(segments) * 40); // ~40 characters per emitted G1 line
1245
1246 // set feedrate
1247 GCodeG1Formatter w(config.high_precision_gcode.value);
1248 w.emit_f(speed * 60.0);
1249 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1250 output += w.string();
1251
1252 // approximate the arc with small linear segments (without the last point which is added later to ensure exactness)
1253 for (int i = 1; i < segments; ++i) {
1254 const double t = double(i) / segments; // parametric position along arc
1255 const double a = a0 + 2. * M_PI * t; // CCW arc param, full circle
1256 emit_point(Vec3d(cx + radius * std::cos(a), // point on circle
1257 cy + radius * std::sin(a),
1258 z_start + (z - z_start) * t)); // interpolated Z height
1259 }
1260
1261 emit_point(Vec3d(px, py, z)); // final point to ensure exactness
1262 } else { // Orca: if arc fitting is enabled emit a G2/G3 command for the spiral lift
1263 output = std::string("G17") + (full_gcode_comment ? " ; XY plane for arc\n" : "\n");
1264
1265 GCodeG2G3Formatter w(true, config.high_precision_gcode.value);
1266 w.emit_z(z);
1267 w.emit_ij(ij_offset);
1268 w.emit_string(" P1 ");
1269 w.emit_f(speed * 60.0);
1270 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1271
1272 output += w.string();
1273 }
1274
1275 m_pos(2) = z;
1276 return output;
1277}
#define M_PI
Definition ExtrusionSimulator.cpp:31
double m_y_offset
Definition GCodeWriter.hpp:205
double m_x_offset
Definition GCodeWriter.hpp:204
Vec3d m_pos
Definition GCodeWriter.hpp:203
double m_resolution
Definition GCodeWriter.hpp:287
bool has_axis_remap() const
Definition GCodeWriter.cpp:90
std::string _travel_to_z(double z, const std::string &comment)
Definition GCodeWriter.cpp:1175
size_t arc_discretization_steps(const FloatType radius, const FloatType angle, const FloatType deviation)
Definition ArcWelder.hpp:50
int64_t py(const Point &pt)
Definition ClipperUtils.cpp:208
int64_t px(const Point &pt)
Definition ClipperUtils.cpp:207
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
@ Disabled
Definition PrintConfig.hpp:239

References _travel_to_z(), Slic3r::Geometry::ArcWelder::arc_discretization_steps(), config, Slic3r::Disabled, Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_f(), Slic3r::GCodeFormatter::emit_ij(), Slic3r::GCodeFormatter::emit_string(), Slic3r::GCodeFormatter::emit_xyz(), Slic3r::GCodeFormatter::emit_z(), full_gcode_comment, has_axis_remap(), m_cached_extruder_idx, m_is_first_layer, M_PI, m_pos, m_resolution, m_x_offset, m_y_offset, and Slic3r::GCodeFormatter::string().

Referenced by eager_lift(), and travel_to_xyz().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _travel_to_z()

std::string Slic3r::GCodeWriter::_travel_to_z ( double z,
const std::string & comment )
protected
1176{
1177 m_pos(2) = z;
1178
1179 double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx);
1180 if (speed == 0.) {
1181 speed = this->point_on_first_layer(Vec3d(m_pos.x() - m_x_offset, m_pos.y() - m_y_offset, z))
1182 ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx)
1183 : this->config.travel_speed.get_at(m_cached_extruder_idx);
1184 }
1185
1186 GCodeG1Formatter w(config.high_precision_gcode.value);
1187 if (has_axis_remap()) {
1188 // Remap may couple Z with other axes; emit full XYZ.
1189 Vec3d machine = apply_axis_remap(Vec3d(m_pos.x() - m_x_offset, m_pos.y() - m_y_offset, z));
1190 w.emit_xyz(machine);
1191 } else {
1192 w.emit_z(z);
1193 }
1194 w.emit_f(speed * 60.0);
1195 //BBS
1196 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1197 return w.string();
1198}
Vec3d apply_axis_remap(const Vec3d &pos) const
Definition GCodeWriter.cpp:95
bool point_on_first_layer(const Vec3d &point_logical) const
Definition GCodeWriter.cpp:58

References apply_axis_remap(), config, Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_f(), Slic3r::GCodeFormatter::emit_xyz(), Slic3r::GCodeFormatter::emit_z(), full_gcode_comment, has_axis_remap(), m_cached_extruder_idx, m_pos, m_x_offset, m_y_offset, point_on_first_layer(), and Slic3r::GCodeFormatter::string().

Referenced by _spiral_travel_to_z(), eager_lift(), lazy_lift(), travel_to_xyz(), travel_to_z(), and unlift().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ active_printable_area()

const Polygon * Slic3r::GCodeWriter::active_printable_area ( ) const
private
230{
231 if (const Extruder *e = this->filament()) {
232 size_t id = e->extruder_id();
233 if (id < m_extruder_printable_areas.size() && m_extruder_printable_areas[id].points.size() >= 3)
234 return &m_extruder_printable_areas[id];
235 }
236 if (m_bed_printable_area.points.size() >= 3)
237 return &m_bed_printable_area;
238 return nullptr;
239}
Polygon m_bed_printable_area
Definition GCodeWriter.hpp:294
std::vector< Polygon > m_extruder_printable_areas
Definition GCodeWriter.hpp:295
@ Extruder
Definition DevConfigUtil.h:34

References filament(), m_bed_printable_area, and m_extruder_printable_areas.

Referenced by spiral_lift_fits_printable_area().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_object_change_labels()

void Slic3r::GCodeWriter::add_object_change_labels ( std::string & gcode)
1652{
1653 add_object_end_labels(gcode);
1655}
void add_object_start_labels(std::string &gcode)
Definition GCodeWriter.cpp:1630
void add_object_end_labels(std::string &gcode)
Definition GCodeWriter.cpp:1638

References add_object_end_labels(), and add_object_start_labels().

Here is the call graph for this function:

◆ add_object_end_labels()

void Slic3r::GCodeWriter::add_object_end_labels ( std::string & gcode)
1639{
1640 if (!m_gcode_label_objects_end.empty()) {
1643
1644 // Orca: reset E so that e value remain correct after skipping the object
1645 // ref to: https://github.com/OrcaSlicer/OrcaSlicer/pull/205/commits/7f1fe0bd544077626080aa1a9a0576aa735da1a4#r1083470162
1646 if (!this->config.use_relative_e_distances)
1647 gcode += reset_e(true);
1648 }
1649}
std::string m_gcode_label_objects_end
Definition GCodeWriter.hpp:298
std::string reset_e(bool force=false)
Definition GCodeWriter.cpp:726

References config, m_gcode_label_objects_end, and reset_e().

Referenced by add_object_change_labels(), and Slic3r::WipeTowerIntegration::append_tcr().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_object_start_labels()

void Slic3r::GCodeWriter::add_object_start_labels ( std::string & gcode)
1631{
1632 if (!m_gcode_label_objects_start.empty()) {
1635 }
1636}
std::string m_gcode_label_objects_start
Definition GCodeWriter.hpp:297

References m_gcode_label_objects_start.

Referenced by add_object_change_labels().

Here is the caller graph for this function:

◆ append_klipper_accel_to_decel()

void Slic3r::GCodeWriter::append_klipper_accel_to_decel ( std::string & gcode,
unsigned int acceleration,
double accel_to_decel_factor )
static
476{
477 gcode += " ACCEL_TO_DECEL=";
478 gcode += float_to_string_decimal_point(acceleration * accel_to_decel_factor / 100);
479 gcode += " MINIMUM_CRUISE_RATIO=";
480 gcode += float_to_string_decimal_point(1. - accel_to_decel_factor / 100);
481}
std::string float_to_string_decimal_point(double value, int precision)
Definition LocalesUtils.cpp:108

References Slic3r::float_to_string_decimal_point().

Referenced by set_accel_and_jerk(), Slic3r::WipeTowerWriter::set_acceleration_impl(), and set_acceleration_internal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_axis_remap()

Vec3d Slic3r::GCodeWriter::apply_axis_remap ( const Vec3d & pos) const
protected
96{
97 return m_kinematics->to_machine(pos);
98}

References m_kinematics.

Referenced by _travel_to_z(), extrude_to_xy(), extrude_to_xyz(), travel_to_xy(), and travel_to_xyz().

Here is the caller graph for this function:

◆ apply_print_config()

void Slic3r::GCodeWriter::apply_print_config ( const PrintConfig & print_config)
106{
107 this->config.apply(print_config, true);
108
109 // Some machine limits are stride-2 (normal, silent) pairs, here we extract the value that will be used,
110 // which is always normal mode at the moment
111 // TODO: support silent? Any printer actually have that?
112 auto get_machine_limits = [](const std::string key, const ConfigOptionFloats& opt) -> std::vector<double> {
113 unsigned int stride = 1;
114 unsigned int offset = 0;
115 if (printer_options_with_variant_2.count(key) > 0) {
116 stride = 2;
117 // offset = <TODO: current print mode>;
118 }
119
120 std::vector<double> results;
121 results.reserve(opt.values.size() / stride);
122
123 for (unsigned int i = offset; i < opt.values.size(); i += stride) {
124 results.emplace_back(opt.values[i]);
125 }
126
127 return results;
128 };
129 auto rounded = [](std::vector<double>&& vec) -> std::vector<double>&&{
130 std::transform(vec.cbegin(), vec.cend(), vec.begin(), [](const double v) { return std::round(v); });
131 return std::move(vec);
132 };
133 auto to_uint = [](const std::vector<double>& vec) {
134 std::vector<unsigned int> r;
135 std::transform(vec.begin(), vec.end(), std::back_inserter(r), [](const double v) { return static_cast<unsigned int>(v); });
136 return r;
137 };
138#define LIMITS(OPT) get_machine_limits(#OPT, print_config.OPT)
139#define LIMITS_UINT(OPT) to_uint(rounded(LIMITS(OPT)))
140
141 m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
142 bool use_mach_limits = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware ||
143 print_config.gcode_flavor.value == gcfKlipper || print_config.gcode_flavor.value == gcfRepRapFirmware;
144 if (use_mach_limits) {
145 // For Klipper, SET_VELOCITY_LIMIT ACCEL= applies to all moves, so the effective cap
146 // is the minimum of the extruding limit and the per-axis X/Y limits.
147 // This ensures user-configured Motion Ability limits are honoured (#12244).
148 auto extruding_limit = LIMITS_UINT(machine_max_acceleration_extruding);
149 if (print_config.gcode_flavor.value == gcfKlipper) {
150 auto x_limit = LIMITS_UINT(machine_max_acceleration_x);
151 auto y_limit = LIMITS_UINT(machine_max_acceleration_y);
152
153 for (size_t i = 0; i < extruding_limit.size(); i++) {
154 if (x_limit[i] > 0) extruding_limit[i] = std::min(extruding_limit[i], x_limit[i]);
155 if (y_limit[i] > 0) extruding_limit[i] = std::min(extruding_limit[i], y_limit[i]);
156 }
157 }
158 m_max_acceleration = std::move(extruding_limit);
159 } else {
160 m_max_acceleration.clear();
161 }
162 if (use_mach_limits && supports_separate_travel_acceleration(print_config.gcode_flavor.value)) {
163 m_max_travel_acceleration = LIMITS_UINT(machine_max_acceleration_travel);
164 } else {
166 }
167 if (use_mach_limits) {
168 m_max_jerk_x = rounded(LIMITS(machine_max_jerk_x));
169 m_max_jerk_y = rounded(LIMITS(machine_max_jerk_y));
170 m_max_junction_deviation = LIMITS(machine_max_junction_deviation);
171 } else {
172 m_max_jerk_x.clear();
173 m_max_jerk_y.clear();
175 }
176 m_max_jerk_z = LIMITS(machine_max_jerk_z);
177 m_max_jerk_e = LIMITS(machine_max_jerk_e);
178 m_resolution = print_config.resolution.value;
179#undef LIMITS
180#undef LIMITS_UINT
181 // Orca: capture the printable area(s) so a spiral lift can be skipped when its
182 // circle would leave the boundary and collide with the print limits. Full polygons
183 // are stored (not a bounding box) so the check stays correct for non-rectangular
184 // beds, and per-extruder areas are kept so printers with different boundaries per
185 // extruder use the right limit for whichever extruder is active.
186 auto to_scaled_polygon = [](const Pointfs &pts) {
188 poly.points.reserve(pts.size());
189 for (const Vec2d &p : pts)
190 poly.points.emplace_back(coord_t(scale_(p.x())), coord_t(scale_(p.y())));
191 poly.make_counter_clockwise();
192 return poly;
193 };
194
195 m_bed_printable_area.points.clear();
197
198 if (print_config.printable_area.values.size() >= 3)
199 m_bed_printable_area = to_scaled_polygon(print_config.printable_area.values);
200
201 const std::vector<Pointfs> &extruder_areas = print_config.extruder_printable_area.values;
202 if (!extruder_areas.empty()) {
203 m_extruder_printable_areas.resize(extruder_areas.size());
204 for (size_t i = 0; i < extruder_areas.size(); ++i) {
205 if (extruder_areas[i].size() < 3) {
206 // No dedicated area for this extruder: it can reach the whole bed.
208 continue;
209 }
210 Polygon extruder_poly = to_scaled_polygon(extruder_areas[i]);
211 if (m_bed_printable_area.points.size() < 3) {
212 m_extruder_printable_areas[i] = std::move(extruder_poly);
213 continue;
214 }
215 // The reachable area is the extruder area clipped to the bed. Bed shapes are
216 // convex in practice, so keep the largest resulting contour.
217 Polygons clipped = intersection(extruder_poly, m_bed_printable_area);
218 const Polygon *largest = nullptr;
219 double best_area = 0.;
220 for (const Polygon &p : clipped) {
221 double a = std::abs(p.area());
222 if (a > best_area) { best_area = a; largest = &p; }
223 }
224 m_extruder_printable_areas[i] = largest ? *largest : std::move(extruder_poly);
225 }
226 }
227}
#define LIMITS_UINT(OPT)
#define LIMITS(OPT)
std::vector< double > m_max_jerk_z
Definition GCodeWriter.hpp:274
static bool supports_separate_travel_acceleration(GCodeFlavor flavor)
Definition GCodeWriter.cpp:100
std::vector< double > m_max_junction_deviation
Definition GCodeWriter.hpp:276
std::vector< double > m_max_jerk_e
Definition GCodeWriter.hpp:275
#define scale_(val)
Definition libslic3r.h:106
int64_t coord_t
Definition libslic3r.h:48
void poly(std::vector< std::pair< Vec2d, Vec2d > > &out, std::initializer_list< Vec2d > p)
Definition DesignSketchTool.cpp:7751
double rounded(double value, int decimals)
Definition GCodeStatistics.cpp:29
@ gcfMarlinFirmware
Definition PrintConfig.hpp:56
@ gcfKlipper
Definition PrintConfig.hpp:53
@ gcfRepRapFirmware
Definition PrintConfig.hpp:54
@ gcfMarlinLegacy
Definition PrintConfig.hpp:52
std::vector< Vec2d > Pointfs
Definition Point.hpp:77
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:769
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582
std::set< std::string > printer_options_with_variant_2
Definition PrintConfig.cpp:10270
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67
ConfigOptionFloatsTempl< false > ConfigOptionFloats
Definition Config.hpp:1015
Slic3r::Polygon Polygon
Definition Emboss.cpp:101

References config, Slic3r::gcfKlipper, Slic3r::gcfMarlinFirmware, Slic3r::gcfMarlinLegacy, Slic3r::gcfRepRapFirmware, Slic3r::intersection(), LIMITS, LIMITS_UINT, m_bed_printable_area, m_extruder_printable_areas, m_max_acceleration, m_max_jerk_e, m_max_jerk_x, m_max_jerk_y, m_max_jerk_z, m_max_junction_deviation, m_max_travel_acceleration, m_resolution, m_single_extruder_multi_material, Slic3r::offset(), Slic3r::printer_options_with_variant_2, scale_, and supports_separate_travel_acceleration().

Here is the call graph for this function:

◆ eager_lift()

std::string Slic3r::GCodeWriter::eager_lift ( const LiftType type)
936 {
937 const LiftType effective_type = m_force_normal_lift ? LiftType::NormalLift : type;
938 std::string lift_move;
939 double target_lift = 0;
940 {
941 //BBS
942 int extruder_id = filament()->extruder_id();
943 int filament_id = filament()->id();
944 double above = this->config.retract_lift_above.get_at(extruder_id);
945 double below = this->config.retract_lift_below.get_at(extruder_id);
946 if (m_pos.z() >= above && (m_pos.z() <= below || below == 0.))
947 target_lift = this->config.z_hop.get_at(filament_id);
948 }
949
950 // BBS: spiral lift only safe with known position
951 if (effective_type == LiftType::SpiralLift && this->is_current_position_clear()) {
952 double radius = target_lift / (2 * PI * atan(filament()->travel_slope()));
953 // static spiral alignment when no move in x,y plane.
954 // spiral centra is a radius distance to the right (y=0)
955 Vec2d ij_offset = { radius, 0 };
956 // Orca: keep the spiral inside the active extruder's printable area, otherwise
957 // fall back to a normal lift to avoid colliding with the print boundary. m_pos
958 // includes the plate offset, so remove it to match the printable area coordinates.
959 const Vec2d spiral_center = { m_pos.x() - m_x_offset + ij_offset.x(), m_pos.y() - m_y_offset + ij_offset.y() };
960 if (target_lift > 0 && this->spiral_lift_fits_printable_area(spiral_center, radius)) {
961 lift_move = this->_spiral_travel_to_z(m_pos(2) + target_lift, ij_offset, "spiral lift Z");
962 } else if (target_lift > 0) {
963 lift_move = _travel_to_z(m_pos(2) + target_lift, "normal lift Z");
964 }
965 }
966 //BBS: if position is unknown use normal lift
967 else if (target_lift > 0) {
968 if (this->must_skip_lift_now())
969 // Skipped, not deferred: leave m_lifted at zero below so unlift()
970 // does not descend from a height that was never commanded.
971 target_lift = 0.;
972 else
973 lift_move = _travel_to_z(m_pos(2) + target_lift, "normal lift Z");
974 }
975 m_lifted = target_lift;
976 m_to_lift = 0;
977 return lift_move;
978}
unsigned int extruder_id() const
Definition Extruder.cpp:39
unsigned int id() const
Definition Extruder.hpp:31
bool is_current_position_clear() const
Definition GCodeWriter.hpp:157
std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment)
Definition GCodeWriter.cpp:1200
bool spiral_lift_fits_printable_area(const Vec2d &center, double radius) const
Definition GCodeWriter.cpp:241
bool must_skip_lift_now() const
Definition GCodeWriter.cpp:53
bool m_force_normal_lift
Definition GCodeWriter.hpp:233
static constexpr double PI
Definition libslic3r.h:81
LiftType
Definition PrintConfig.hpp:429
@ SpiralLift
Definition PrintConfig.hpp:431
zaa_minimize_perimeter_height travel_slope((ConfigOptionFloats, retract_lift_above))((ConfigOptionFloats

References _spiral_travel_to_z(), _travel_to_z(), config, Slic3r::Extruder::extruder_id(), filament(), Slic3r::Extruder::id(), is_current_position_clear(), m_force_normal_lift, m_lifted, m_pos, m_to_lift, m_x_offset, m_y_offset, must_skip_lift_now(), Slic3r::NormalLift, PI, spiral_lift_fits_printable_area(), Slic3r::SpiralLift, and Slic3r::travel_slope().

Here is the call graph for this function:

◆ enable_power_loss_recovery()

std::string Slic3r::GCodeWriter::enable_power_loss_recovery ( PowerLossRecoveryMode mode)
752{
753 std::ostringstream gcode;
754
756 return std::string();
757
758 const bool enable = mode == PowerLossRecoveryMode::Enable;
759
760 if (m_is_bbl_printers) {
761 gcode << "M1003 S" << (enable ? "1" : "0");
762 }
763 else if (FLAVOR_IS(gcfMarlinFirmware)) {
764 gcode << "M413 S" << (enable ? "1" : "0");
765 } else {
766 return std::string();
767 }
768 if (GCodeWriter::full_gcode_comment) gcode << " ; set Power-loss Recovery";
769 gcode << "\n";
770 return gcode.str();
771}
bool m_is_bbl_printers
Definition GCodeWriter.hpp:301
@ Enable
Definition PrintConfig.hpp:233
@ PrinterConfiguration
Definition PrintConfig.hpp:232

References Slic3r::Enable, FLAVOR_IS, full_gcode_comment, Slic3r::gcfMarlinFirmware, m_is_bbl_printers, and Slic3r::PrinterConfiguration.

◆ extrude_arc_as_polyline()

void Slic3r::GCodeWriter::extrude_arc_as_polyline ( std::string & out,
const Vec2d & point,
const Vec2d & center_offset,
double dE,
const bool is_ccw,
const std::string & comment = std::string(),
bool force_no_extrusion = false )
1338{
1339 const Vec2d start = Vec2d(m_pos.x(), m_pos.y());
1340 const Vec2d centre = start + center_offset;
1341 const double r = (start - centre).norm();
1342 if (r < EPSILON) {
1343 // Degenerate: no arc to speak of, so a single move is exact.
1344 this->extrude_to_xy(out, point, dE, comment, force_no_extrusion);
1345 return;
1346 }
1347
1348 double a0 = std::atan2(start.y() - centre.y(), start.x() - centre.x());
1349 double a1 = std::atan2(point.y() - centre.y(), point.x() - centre.x());
1350 double sweep = a1 - a0;
1351 if (is_ccw) { while (sweep <= 0.) sweep += 2. * PI; }
1352 else { while (sweep >= 0.) sweep -= 2. * PI; }
1353
1354 // Segment count from a chord-deviation bound: r*(1-cos(dtheta/2)) <= tol.
1355 const double tol = 0.005; // mm
1356 const double dmax = (tol >= r) ? PI : 2. * std::acos(1. - tol / r);
1357 const int n = std::max(2, int(std::ceil(std::abs(sweep) / std::max(dmax, EPSILON))));
1358
1359 for (int i = 1; i <= n; ++ i) {
1360 const double a = a0 + sweep * (double(i) / double(n));
1361 const Vec2d p = (i == n) ? point
1362 : Vec2d(centre.x() + r * std::cos(a), centre.y() + r * std::sin(a));
1363 this->extrude_to_xy(out, p, dE / double(n), i == n ? comment : std::string(), force_no_extrusion);
1364 }
1365}
#define EPSILON
Definition ColorUtils.cpp:64
std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment=std::string(), bool force_no_extrusion=false)
Definition GCodeWriter.cpp:1296
static bool is_ccw(const Polygon &poly)
Definition Geometry.hpp:66

References EPSILON, extrude_to_xy(), Slic3r::Geometry::is_ccw(), m_pos, and PI.

Referenced by extrude_arc_to_xy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extrude_arc_to_xy() [1/2]

std::string Slic3r::GCodeWriter::extrude_arc_to_xy ( const Vec2d & point,
const Vec2d & center_offset,
double dE,
const bool is_ccw,
const std::string & comment = std::string(),
bool force_no_extrusion = false )
1371{
1372 std::string gcode;
1373 this->extrude_arc_to_xy(gcode, point, center_offset, dE, is_ccw, comment, force_no_extrusion);
1374 return gcode;
1375}
std::string extrude_arc_to_xy(const Vec2d &point, const Vec2d &center_offset, double dE, const bool is_ccw, const std::string &comment=std::string(), bool force_no_extrusion=false)
Definition GCodeWriter.cpp:1370

References extrude_arc_to_xy(), and Slic3r::Geometry::is_ccw().

Referenced by extrude_arc_to_xy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extrude_arc_to_xy() [2/2]

void Slic3r::GCodeWriter::extrude_arc_to_xy ( std::string & out,
const Vec2d & point,
const Vec2d & center_offset,
double dE,
const bool is_ccw,
const std::string & comment = std::string(),
bool force_no_extrusion = false )
1378{
1379 // Arcs emit only X/Y/I/J, so a mapping that moves logical X or Y cannot be
1380 // expressed as a G2/G3. GCode::should_disable_arc_fitting() normally stops
1381 // arcs being generated at all for such a mapping, but this is public API, so
1382 // define the behaviour rather than asserting.
1383 //
1384 // This check MUST precede every state mutation below: falling through to
1385 // extrude_to_xy() after filament()->extrude(dE) would advance E twice.
1386 //
1387 // A single chord is not a safe substitute either -- a semicircle would become
1388 // its diameter and a full circle a stationary blob -- so approximate the arc
1389 // with linear segments bounded by a chord tolerance, splitting dE between
1390 // them in proportion to arc length.
1391 if (! m_kinematics->supports_arc_moves()) {
1392 this->extrude_arc_as_polyline(out, point, center_offset, dE, is_ccw, comment, force_no_extrusion);
1393 return;
1394 }
1395
1396 m_pos(0) = point(0);
1397 m_pos(1) = point(1);
1398 if (!force_no_extrusion)
1399 filament()->extrude(dE);
1400
1401 Vec2d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset };
1402
1403 const bool high_precision = this->high_precision();
1404 GCodeG2G3Formatter w(is_ccw, high_precision);
1405 w.emit_xy(point_on_plate);
1406 w.emit_ij(center_offset);
1407 if (!force_no_extrusion)
1408 w.emit_e(filament()->E_to_emit(high_precision));
1409 //BBS
1410 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1411 w.append_to(out);
1412}
double extrude(double dE)
Definition Extruder.cpp:48
void extrude_arc_as_polyline(std::string &out, const Vec2d &point, const Vec2d &center_offset, double dE, const bool is_ccw, const std::string &comment=std::string(), bool force_no_extrusion=false)
Definition GCodeWriter.cpp:1335

References Slic3r::GCodeFormatter::append_to(), Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_e(), Slic3r::GCodeFormatter::emit_ij(), Slic3r::GCodeFormatter::emit_xy(), Slic3r::Extruder::extrude(), extrude_arc_as_polyline(), filament(), full_gcode_comment, high_precision(), Slic3r::Geometry::is_ccw(), m_kinematics, m_pos, m_x_offset, and m_y_offset.

Here is the call graph for this function:

◆ extrude_to_xy() [1/2]

std::string Slic3r::GCodeWriter::extrude_to_xy ( const Vec2d & point,
double dE,
const std::string & comment = std::string(),
bool force_no_extrusion = false )
1297{
1298 std::string gcode;
1299 this->extrude_to_xy(gcode, point, dE, comment, force_no_extrusion);
1300 return gcode;
1301}

References extrude_to_xy().

Referenced by Slic3r::CalibPressureAdvance::draw_digit(), Slic3r::CalibPressureAdvance::draw_line(), extrude_arc_as_polyline(), extrude_to_xy(), and Slic3r::Wipe::wipe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extrude_to_xy() [2/2]

void Slic3r::GCodeWriter::extrude_to_xy ( std::string & out,
const Vec2d & point,
double dE,
const std::string & comment = std::string(),
bool force_no_extrusion = false )
1304{
1305 m_pos(0) = point(0);
1306 m_pos(1) = point(1);
1307 if(std::abs(dE) <= std::numeric_limits<double>::epsilon())
1308 force_no_extrusion = true;
1309
1310 if (!force_no_extrusion)
1311 filament()->extrude(dE);
1312
1313 //BBS: take plate offset into consider
1314 Vec2d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset };
1315
1316 const bool high_precision = this->high_precision();
1317 GCodeG1Formatter w(high_precision);
1318 if (has_axis_remap()) {
1319 Vec3d machine = apply_axis_remap(Vec3d(point_on_plate.x(), point_on_plate.y(), m_pos.z()));
1320 w.emit_xyz(machine);
1321 } else {
1322 w.emit_xy(point_on_plate);
1323 }
1324 if (!force_no_extrusion)
1325 w.emit_e(filament()->E_to_emit(high_precision));
1326 //BBS
1327 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1328 w.append_to(out);
1329}

References Slic3r::GCodeFormatter::append_to(), apply_axis_remap(), Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_e(), Slic3r::GCodeFormatter::emit_xy(), Slic3r::GCodeFormatter::emit_xyz(), Slic3r::Extruder::extrude(), filament(), full_gcode_comment, has_axis_remap(), high_precision(), m_pos, m_x_offset, and m_y_offset.

Here is the call graph for this function:

◆ extrude_to_xyz() [1/2]

std::string Slic3r::GCodeWriter::extrude_to_xyz ( const Vec3d & point,
double dE,
const std::string & comment = std::string(),
bool force_no_extrusion = false )
1415{
1416 std::string gcode;
1417 this->extrude_to_xyz(gcode, point, dE, comment, force_no_extrusion);
1418 return gcode;
1419}
std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment=std::string(), bool force_no_extrusion=false)
Definition GCodeWriter.cpp:1414

References extrude_to_xyz().

Referenced by extrude_to_xyz().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extrude_to_xyz() [2/2]

void Slic3r::GCodeWriter::extrude_to_xyz ( std::string & out,
const Vec3d & point,
double dE,
const std::string & comment = std::string(),
bool force_no_extrusion = false )
1422{
1423 // Check if Z actually changes (at export precision) before emitting it.
1424 // ZAA sloped extrusions call this for every segment, but many consecutive
1425 // segments share the same quantized Z — emitting it every time is redundant.
1426 const bool high_precision = this->high_precision();
1428
1429 m_pos = point;
1430 m_lifted = 0;
1431 if (!force_no_extrusion)
1432 filament()->extrude(dE);
1433
1434 //BBS: take plate offset into consider
1435 Vec3d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset, point(2) };
1436
1437 GCodeG1Formatter w(high_precision);
1438 if (has_axis_remap()) {
1439 // z_changed was computed from the ORIGINAL slicing Z, but an axis remap can
1440 // make machine-Z depend on slicing X/Y. An X/Y-only move (slicing-Z
1441 // unchanged) would then drop the required machine-Z word, so always emit
1442 // full XYZ whenever a remap is active.
1443 point_on_plate = apply_axis_remap(point_on_plate);
1444 w.emit_xyz(point_on_plate);
1445 } else if (z_changed) {
1446 w.emit_xyz(point_on_plate);
1447 } else {
1448 w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y()));
1449 }
1450 if (!force_no_extrusion)
1451 w.emit_e(filament()->E_to_emit(high_precision));
1452 //BBS
1453 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1454 w.append_to(out);
1455}
static double quantize_xyz(double v, bool high_precision)
Definition GCodeWriter.hpp:342

References Slic3r::GCodeFormatter::append_to(), apply_axis_remap(), Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_e(), Slic3r::GCodeFormatter::emit_xy(), Slic3r::GCodeFormatter::emit_xyz(), Slic3r::Extruder::extrude(), filament(), full_gcode_comment, has_axis_remap(), high_precision(), m_lifted, m_pos, m_x_offset, m_y_offset, and Slic3r::GCodeFormatter::quantize_xyz().

Here is the call graph for this function:

◆ extruder_ids()

std::vector< unsigned int > Slic3r::GCodeWriter::extruder_ids ( ) const
inline
55 {
56 std::vector<unsigned int> out;
57 out.reserve(m_filament_extruders.size());
58 for (const Extruder &e : m_filament_extruders)
59 out.push_back(e.id());
60 return out;
61 }
std::vector< Extruder > m_filament_extruders
Definition GCodeWriter.hpp:260

References m_filament_extruders.

Referenced by set_extruders().

Here is the caller graph for this function:

◆ extruders()

const std::vector< Extruder > & Slic3r::GCodeWriter::extruders ( ) const
inline
54{ return m_filament_extruders; }

References m_filament_extruders.

Referenced by Slic3r::CoolingBuffer::CoolingBuffer().

Here is the caller graph for this function:

◆ filament() [1/4]

Extruder * Slic3r::GCodeWriter::filament ( )
inline
48{ if (m_curr_extruder_id == -1) return nullptr; return m_curr_filament_extruder[m_curr_extruder_id]; }

References m_curr_extruder_id, and m_curr_filament_extruder.

Referenced by _retract(), active_printable_area(), eager_lift(), extrude_arc_to_xy(), extrude_to_xy(), extrude_to_xyz(), lazy_lift(), need_toolchange(), retract(), retract_for_toolchange(), travel_to_xyz(), and unretract().

Here is the caller graph for this function:

◆ filament() [2/4]

const Extruder * Slic3r::GCodeWriter::filament ( ) const
inline

◆ filament() [3/4]

Extruder * Slic3r::GCodeWriter::filament ( size_t extruder_id)
inline
46{ assert(extruder_id < m_curr_filament_extruder.size()); return m_curr_filament_extruder[extruder_id]; }

References m_curr_filament_extruder.

Referenced by Slic3r::OozePrevention::_get_temp(), Slic3r::WipeTowerIntegration::append_tcr(), Slic3r::WipeTowerIntegration::append_tcr2(), Slic3r::Wipe::calculateWipeRetractionLengths(), Slic3r::need_wipe(), Slic3r::OozePrevention::post_toolchange(), Slic3r::OozePrevention::pre_toolchange(), and Slic3r::Wipe::wipe().

Here is the caller graph for this function:

◆ filament() [4/4]

const Extruder * Slic3r::GCodeWriter::filament ( size_t extruder_id) const
inline
47{ assert(extruder_id < m_curr_filament_extruder.size()); return m_curr_filament_extruder[extruder_id]; }

References m_curr_filament_extruder.

◆ force_standard_precision()

bool Slic3r::GCodeWriter::force_standard_precision ( bool force)
inline
197{ return std::exchange(m_force_standard_precision, force); }
bool m_force_standard_precision
Definition GCodeWriter.hpp:234

References m_force_standard_precision.

◆ get_current_speed()

double Slic3r::GCodeWriter::get_current_speed ( ) const
inline
97{ return m_current_speed;}

References m_current_speed.

Referenced by Slic3r::Wipe::wipe().

Here is the caller graph for this function:

◆ get_extruder_retracted_length()

double Slic3r::GCodeWriter::get_extruder_retracted_length ( const int filament_id)
837{
838 double res = 0.0;
839 auto filament_extruder_iter = Slic3r::lower_bound_by_predicate(m_filament_extruders.begin(), m_filament_extruders.end(),
840 [filament_id](const Extruder &e) { return (int) e.id() < filament_id; });
841 if (filament_extruder_iter == m_filament_extruders.end() || (int) filament_extruder_iter->id() != filament_id)
842 return res;
843
844 if (filament_extruder_iter->is_share_extruder())
845 res = filament_extruder_iter->get_share_retracted_length();
846 else
847 res = filament_extruder_iter->get_single_retracted_length();
848
849 return res;
850}
ForwardIt lower_bound_by_predicate(ForwardIt first, ForwardIt last, LowerThanKeyPredicate lower_than_key)
Definition libslic3r.h:246

References Slic3r::lower_bound_by_predicate(), and m_filament_extruders.

Referenced by Slic3r::WipeTowerIntegration::append_tcr().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_gcode_flavor()

GCodeFlavor Slic3r::GCodeWriter::get_gcode_flavor ( ) const
inline
164{ return config.gcode_flavor; }

References config.

◆ get_position() [1/2]

Vec3d & Slic3r::GCodeWriter::get_position ( )
inline
129{ return m_pos; }

References m_pos.

◆ get_position() [2/2]

const Vec3d & Slic3r::GCodeWriter::get_position ( ) const
inline
128{ return m_pos; }

References m_pos.

Referenced by Slic3r::CoolingBuffer::CoolingBuffer(), Slic3r::WipeTowerIntegration::append_tcr(), Slic3r::WipeTowerIntegration::append_tcr2(), Slic3r::WipeTowerIntegration::finalize(), and Slic3r::OozePrevention::pre_toolchange().

Here is the caller graph for this function:

◆ get_xy_offset()

Vec2f Slic3r::GCodeWriter::get_xy_offset ( )
inline
135{ return Vec2f{m_x_offset, m_y_offset}; };
Eigen::Matrix< float, 2, 1, Eigen::DontAlign > Vec2f
Definition Point.hpp:64

References m_x_offset, and m_y_offset.

◆ get_zhop()

double Slic3r::GCodeWriter::get_zhop ( ) const
inline
131{ return m_lifted; }

References m_lifted.

◆ has_axis_remap()

bool Slic3r::GCodeWriter::has_axis_remap ( ) const
91{
92 return m_kinematics->must_emit_all_axes();
93}

References m_kinematics.

Referenced by _spiral_travel_to_z(), _travel_to_z(), extrude_to_xy(), extrude_to_xyz(), travel_to_xy(), and travel_to_xyz().

Here is the caller graph for this function:

◆ high_precision()

bool Slic3r::GCodeWriter::high_precision ( ) const
inline
195{ return config.high_precision_gcode.value && !m_force_standard_precision; }

References config, and m_force_standard_precision.

Referenced by _retract(), extrude_arc_to_xy(), extrude_to_xy(), extrude_to_xyz(), travel_to_xy(), and unretract().

Here is the caller graph for this function:

◆ init_extruder()

void Slic3r::GCodeWriter::init_extruder ( unsigned int filament_id)
1668{
1669 if (m_curr_extruder_id == -1 && filament_id != -1) {
1670 auto filament_extruder_iter = Slic3r::lower_bound_by_predicate(m_filament_extruders.begin(), m_filament_extruders.end(), [filament_id](const Extruder &e) { return e.id() < filament_id; });
1671 assert(filament_extruder_iter != m_filament_extruders.end() && filament_extruder_iter->id() == filament_id);
1672 m_curr_extruder_id = filament_extruder_iter->extruder_id();
1673 m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter;
1674 m_cached_extruder_idx = get_extruder_index(this->config, filament_id);
1675 }
1676}
size_t get_extruder_index(const GCodeConfig &config, unsigned int filament_id)
Definition PrintConfig.cpp:140

References config, Slic3r::get_extruder_index(), Slic3r::lower_bound_by_predicate(), m_cached_extruder_idx, m_curr_extruder_id, m_curr_filament_extruder, and m_filament_extruders.

Here is the call graph for this function:

◆ invalidate_acceleration()

void Slic3r::GCodeWriter::invalidate_acceleration ( )
inline

◆ invalidate_jerk()

void Slic3r::GCodeWriter::invalidate_jerk ( )
inline
166{ m_last_jerk = 0; }

References m_last_jerk.

◆ is_bbl_printers()

const bool Slic3r::GCodeWriter::is_bbl_printers ( ) const
inline
162{return m_is_bbl_printers;}

References m_is_bbl_printers.

Referenced by toolchange().

Here is the caller graph for this function:

◆ is_current_position_clear()

bool Slic3r::GCodeWriter::is_current_position_clear ( ) const
inline
157{ return m_is_current_pos_clear; };
bool m_is_current_pos_clear
Definition GCodeWriter.hpp:210

References m_is_current_pos_clear.

Referenced by Slic3r::WipeTowerIntegration::append_tcr2(), eager_lift(), must_skip_lift_now(), planned_travel_z(), and travel_to_xyz().

Here is the caller graph for this function:

◆ is_object_end_str_empty()

bool Slic3r::GCodeWriter::is_object_end_str_empty ( )
inline
150{ return m_gcode_label_objects_end.empty(); }

References m_gcode_label_objects_end.

◆ is_object_start_str_empty()

bool Slic3r::GCodeWriter::is_object_start_str_empty ( )
inline
148{ return m_gcode_label_objects_start.empty(); }

References m_gcode_label_objects_start.

◆ kinematics()

const MachineKinematics & Slic3r::GCodeWriter::kinematics ( ) const
inline
177{ return *m_kinematics; }

References m_kinematics.

Referenced by set_kinematics().

Here is the caller graph for this function:

◆ lazy_lift()

std::string Slic3r::GCodeWriter::lazy_lift ( LiftType lift_type = LiftType::NormalLift,
bool spiral_vase = false )
902{
904 lift_type = LiftType::NormalLift;
905 // check whether the above/below conditions are met
906 double target_lift = 0;
907 {
908 //BBS
909 int extruder_id = filament()->extruder_id();
910 int filament_id = filament()->id();
911 double above = this->config.retract_lift_above.get_at(extruder_id);
912 double below = this->config.retract_lift_below.get_at(extruder_id);
913 if (m_pos.z() >= above && (m_pos.z() <= below || below == 0.))
914 target_lift = this->config.z_hop.get_at(filament_id);
915 }
916 // BBS
917 if (m_lifted == 0 && m_to_lift == 0 && target_lift > 0) {
918 if (spiral_vase) {
919 if (this->must_skip_lift_now())
920 // Record no lift, so a later unlift() does not descend from a
921 // height that was never commanded.
922 return "";
923 m_lifted = target_lift;
924 return this->_travel_to_z(m_pos(2) + target_lift, "lift Z");
925 }
926 else {
927 m_to_lift = target_lift;
928 m_to_lift_type = lift_type;
929 }
930 }
931 return "";
932}

References _travel_to_z(), config, Slic3r::Extruder::extruder_id(), filament(), Slic3r::Extruder::id(), m_force_normal_lift, m_lifted, m_pos, m_to_lift, m_to_lift_type, must_skip_lift_now(), and Slic3r::NormalLift.

Here is the call graph for this function:

◆ must_skip_lift_now()

bool Slic3r::GCodeWriter::must_skip_lift_now ( ) const
protected
54{
55 return m_kinematics->suppress_lift_at_unknown_position() && ! this->is_current_position_clear();
56}

References is_current_position_clear(), and m_kinematics.

Referenced by eager_lift(), lazy_lift(), and travel_to_xyz().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ need_toolchange()

bool Slic3r::GCodeWriter::need_toolchange ( unsigned int filament_id) const
1679{
1680 return filament()==nullptr || filament()->id()!=filament_id;
1681}

References filament(), and Slic3r::Extruder::id().

Referenced by Slic3r::WipeTowerIntegration::append_tcr(), Slic3r::WipeTowerIntegration::append_tcr2(), Slic3r::WipeTowerIntegration::is_empty_wipe_tower_gcode(), set_extruder(), and Slic3r::WipeTowerIntegration::tool_change().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ planned_travel_z()

std::pair< double, double > Slic3r::GCodeWriter::planned_travel_z ( const Vec3d & point,
bool force_z = false ) const
1144{
1145 double destination_z = point.z();
1146 if (std::abs(m_to_lift) > EPSILON) {
1147 if ((!this->is_current_position_clear() || m_pos != point) &&
1148 m_to_lift + m_pos.z() > point.z())
1149 destination_z = m_to_lift + m_pos.z();
1150 } else if (!force_z && !this->will_move_z(point.z())) {
1151 destination_z = m_pos.z();
1152 }
1153 return { m_pos.z(), destination_z };
1154}
bool will_move_z(double z) const
Definition GCodeWriter.cpp:1279

References EPSILON, is_current_position_clear(), m_pos, m_to_lift, and will_move_z().

Here is the call graph for this function:

◆ point_on_first_layer()

bool Slic3r::GCodeWriter::point_on_first_layer ( const Vec3d & point_logical) const
protected
59{
61 return m_first_layer_point_test(point_logical);
62 return m_is_first_layer;
63}
FirstLayerPointTest m_first_layer_point_test
Definition GCodeWriter.hpp:232

References m_first_layer_point_test, and m_is_first_layer.

Referenced by _travel_to_z(), travel_to_xy(), and travel_to_xyz().

Here is the caller graph for this function:

◆ postamble()

std::string Slic3r::GCodeWriter::postamble ( ) const
310{
311 std::ostringstream gcode;
313 gcode << "M2 ; end of program\n";
314 return gcode.str();
315}

References FLAVOR_IS, and Slic3r::gcfMachinekit.

◆ preamble()

std::string Slic3r::GCodeWriter::preamble ( )
282{
283 std::ostringstream gcode;
284
286 gcode << "G90\n";
287 gcode << "G21\n";
288 }
297 {
298 if (this->config.use_relative_e_distances) {
299 gcode << "M83 ; use relative distances for extrusion\n";
300 } else {
301 gcode << "M82 ; use absolute distances for extrusion\n";
302 }
303 gcode << this->reset_e(true);
304 }
305
306 return gcode.str();
307}
#define FLAVOR_IS_NOT(val)
Definition GCodeWriter.cpp:43
@ gcfTeacup
Definition PrintConfig.hpp:58
@ gcfRepetier
Definition PrintConfig.hpp:55
@ gcfSmoothie
Definition PrintConfig.hpp:63
@ gcfRepRapSprinter
Definition PrintConfig.hpp:57

References config, FLAVOR_IS, FLAVOR_IS_NOT, Slic3r::gcfKlipper, Slic3r::gcfMakerWare, Slic3r::gcfMarlinFirmware, Slic3r::gcfMarlinLegacy, Slic3r::gcfRepetier, Slic3r::gcfRepRapFirmware, Slic3r::gcfRepRapSprinter, Slic3r::gcfSmoothie, Slic3r::gcfTeacup, and reset_e().

Here is the call graph for this function:

◆ reset_e()

std::string Slic3r::GCodeWriter::reset_e ( bool force = false)
727{
731 return "";
732
735 return "";
737 }
738
739 if (! this->config.use_relative_e_distances) {
740 std::ostringstream gcode;
741 gcode << "G92 E0";
742 //BBS
743 if (GCodeWriter::full_gcode_comment) gcode << " ; reset extrusion distance";
744 gcode << "\n";
745 return gcode.str();
746 } else {
747 return "";
748 }
749}
@ gcfMach3
Definition PrintConfig.hpp:61
@ gcfSailfish
Definition PrintConfig.hpp:60
@ E
Definition libslic3r.h:144

References config, Slic3r::E, FLAVOR_IS, full_gcode_comment, Slic3r::gcfMach3, Slic3r::gcfMakerWare, Slic3r::gcfSailfish, Slic3r::is_zero(), m_curr_extruder_id, and m_curr_filament_extruder.

Referenced by add_object_end_labels(), preamble(), toolchange(), and unretract().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ retract()

std::string Slic3r::GCodeWriter::retract ( bool before_wipe = false,
double retract_length = 0 )
1458{
1459 double factor = before_wipe ? filament()->retract_before_wipe() : 1.;
1460 assert(factor >= 0. && factor <= 1. + EPSILON);
1461 return this->_retract(
1462 retract_length > EPSILON ? retract_length : factor * filament()->retraction_length(),
1463 factor * filament()->retract_restart_extra(),
1464 "retract"
1465 );
1466}
double retract_before_wipe() const
Definition Extruder.cpp:203
std::string _retract(double length, double restart_extra, const std::string &comment)
Definition GCodeWriter.cpp:1479
zaa_minimize_perimeter_height retract_restart_extra((ConfigOptionFloats, retract_restart_extra_toolchange))((ConfigOptionFloats

References _retract(), EPSILON, filament(), Slic3r::Extruder::retract_before_wipe(), and Slic3r::retract_restart_extra().

Referenced by _retract(), Slic3r::WipeTowerIntegration::append_tcr(), Slic3r::WipeTowerIntegration::append_tcr2(), and Slic3r::CalibPressureAdvance::move_to().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ retract_for_toolchange()

std::string Slic3r::GCodeWriter::retract_for_toolchange ( bool before_wipe = false,
double retract_length = 0 )
1469{
1470 double factor = before_wipe ? filament()->retract_before_wipe() : 1.;
1471 assert(factor >= 0. && factor <= 1. + EPSILON);
1472 return this->_retract(
1473 retract_length > EPSILON ? retract_length : factor * filament()->retract_length_toolchange(),
1474 factor * filament()->retract_restart_extra_toolchange(),
1475 "retract for toolchange"
1476 );
1477}
zaa_minimize_perimeter_height retract_length_toolchange((ConfigOptionInt, enable_long_retraction_when_cut))((ConfigOptionFloats

References _retract(), EPSILON, filament(), Slic3r::Extruder::retract_before_wipe(), and Slic3r::retract_length_toolchange().

Here is the call graph for this function:

◆ set_accel_and_jerk()

std::string Slic3r::GCodeWriter::set_accel_and_jerk ( unsigned int acceleration,
double jerk )
537{
538 // Only Klipper supports setting acceleration and jerk at the same time. Throw an error if we try to do this on other flavours.
540 throw std::runtime_error(_u8L("set_accel_and_jerk() is only supported by Klipper"));
541
542 // Clamp the acceleration to the allowed maximum.
544 acceleration = EXTRUDER_LIMIT(m_max_acceleration);
545
546 // Clamp the jerk to the allowed maximum.
551
552 const bool set_acceleration = acceleration != 0 && acceleration != m_last_acceleration;
553 const bool set_jerk = jerk > 0.01 && !is_approx(jerk, m_last_jerk);
554 if (!set_acceleration && !set_jerk)
555 return std::string();
556
557 std::string gcode;
558 gcode.reserve(128);
559 gcode += "SET_VELOCITY_LIMIT";
560 if (set_acceleration) {
561 gcode += " ACCEL=";
562 gcode += std::to_string(acceleration);
563 if (this->config.accel_to_decel_enable)
564 append_klipper_accel_to_decel(gcode, acceleration, this->config.accel_to_decel_factor.value);
565 m_last_acceleration = acceleration;
566 }
567 if (set_jerk) {
568 gcode += " SQUARE_CORNER_VELOCITY=";
570 m_last_jerk = jerk;
571 }
572
574 gcode += " ; adjust VELOCITY_LIMIT(accel/jerk)";
575 gcode += "\n";
576
577 return gcode;
578
579}
#define EXTRUDER_LIMIT(OPT)
Definition GCodeWriter.cpp:423
static void append_klipper_accel_to_decel(std::string &gcode, unsigned int acceleration, double accel_to_decel_factor)
Definition GCodeWriter.cpp:475
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:320
#define _u8L(s)
Definition I18N.hpp:11

References _u8L, append_klipper_accel_to_decel(), config, EXTRUDER_LIMIT, FLAVOR_IS_NOT, Slic3r::float_to_string_decimal_point(), full_gcode_comment, Slic3r::gcfKlipper, Slic3r::is_approx(), m_last_acceleration, m_last_jerk, m_max_acceleration, m_max_jerk_x, and m_max_jerk_y.

Here is the call graph for this function:

◆ set_acceleration_internal()

std::string Slic3r::GCodeWriter::set_acceleration_internal ( Acceleration type,
unsigned int acceleration )
private
429{
430 // Clamp the acceleration to the allowed maximum.
432 acceleration = EXTRUDER_LIMIT(m_max_acceleration);
435
436 // Are we setting travel acceleration for a flavour that supports separate travel and print acc?
437 bool separate_travel = (type == Acceleration::Travel && supports_separate_travel_acceleration(this->config.gcode_flavor));
438
439 auto& last_value = separate_travel ? m_last_travel_acceleration : m_last_acceleration ;
440 if (acceleration == 0 || acceleration == last_value)
441 return std::string();
442
443 last_value = acceleration;
444
445 const std::string value = std::to_string(acceleration);
446 std::string gcode;
447 if (FLAVOR_IS(gcfRepetier)) {
448 gcode += separate_travel ? "M202 X" : "M201 X";
449 gcode += value;
450 gcode += " Y";
451 gcode += value;
453 gcode += separate_travel ? "M204 T" : "M204 P";
454 gcode += value;
455 } else if (FLAVOR_IS(gcfKlipper)) {
456 gcode.reserve(128);
457 gcode += "SET_VELOCITY_LIMIT ACCEL=";
458 gcode += value;
459 if (this->config.accel_to_decel_enable) {
460 append_klipper_accel_to_decel(gcode, acceleration, this->config.accel_to_decel_factor.value);
462 gcode += " ; adjust ACCEL_TO_DECEL";
463 }
464 } else {
465 gcode += "M204 S";
466 gcode += value;
467 }
468
469 if (GCodeWriter::full_gcode_comment) gcode += " ; adjust acceleration";
470 gcode += "\n";
471
472 return gcode;
473}
@ Print
Definition GCodeWriter.hpp:305
@ Travel
Definition GCodeWriter.hpp:304

References append_klipper_accel_to_decel(), config, EXTRUDER_LIMIT, FLAVOR_IS, full_gcode_comment, Slic3r::gcfKlipper, Slic3r::gcfMarlinFirmware, Slic3r::gcfRepetier, Slic3r::gcfRepRapFirmware, m_last_acceleration, m_last_travel_acceleration, m_max_acceleration, m_max_travel_acceleration, Print, supports_separate_travel_acceleration(), and Travel.

Referenced by set_print_acceleration(), and set_travel_acceleration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_additional_fan()

std::string Slic3r::GCodeWriter::set_additional_fan ( unsigned int speed)
static
1600{
1601 std::ostringstream gcode;
1602
1603 gcode << "M106 " << "P2 " << "S" << (int)(255.0 * speed / 100.0);
1605 if (speed == 0)
1606 gcode << " ; disable additional fan ";
1607 else
1608 gcode << " ; enable additional fan ";
1609 }
1610 gcode << "\n";
1611 return gcode.str();
1612}

References full_gcode_comment.

Referenced by Slic3r::CoolingBuffer::apply_layer_cooldown().

Here is the caller graph for this function:

◆ set_axis_remap()

void Slic3r::GCodeWriter::set_axis_remap ( int rx,
int ry,
int rz )
66{
67 m_remap_x = rx;
68 m_remap_y = ry;
69 m_remap_z = rz;
70 m_kinematics->set_axis_remap(rx, ry, rz);
71}
int m_remap_x
Definition GCodeWriter.hpp:244
int m_remap_y
Definition GCodeWriter.hpp:245
int m_remap_z
Definition GCodeWriter.hpp:246

References m_kinematics, m_remap_x, m_remap_y, and m_remap_z.

◆ set_bed_temperature()

std::string Slic3r::GCodeWriter::set_bed_temperature ( int temperature,
bool wait = false )
377{
378 if (temperature == m_last_bed_temperature && (! wait || m_last_bed_temperature_reached))
379 return std::string();
380
381 m_last_bed_temperature = temperature;
383
384 std::string code, comment;
385 std::ostringstream gcode;
386
387 if (wait) {
388 code = "M190";
389 comment = "set bed temperature and wait for it to be reached";
390 }
391 else {
392 code = "M140";
393 comment = "set bed temperature";
394 }
395
396 gcode << code << " S" << temperature << " ; " << comment << "\n";
397 return gcode.str();
398}

References m_last_bed_temperature, and m_last_bed_temperature_reached.

◆ set_build_volume_max()

void Slic3r::GCodeWriter::set_build_volume_max ( const Vec3d & max)
74{
75 m_build_vol_max = max;
76 m_kinematics->set_build_volume_max(max);
77}
Vec3d m_build_vol_max
Definition GCodeWriter.hpp:247

References m_build_vol_max, and m_kinematics.

◆ set_chamber_temperature()

std::string Slic3r::GCodeWriter::set_chamber_temperature ( int temperature,
bool wait = false )
401{
402 std::string code, comment;
403 std::ostringstream gcode;
404
405 if (wait)
406 {
407 // Orca: should we let the M191 command to turn on the auxiliary fan?
408 if (config.auxiliary_fan)
409 gcode << "M106 P2 S255 \n";
410 gcode << "M191 S" << std::to_string(temperature) << " ;"
411 << "set chamber_temperature and wait for it to be reached\n";
412 if (config.auxiliary_fan)
413 gcode << "M106 P2 S0 \n";
414 }
415 else {
416 code = "M141";
417 comment = "set chamber_temperature";
418 gcode << code << " S" << temperature << ";" << comment << "\n";
419 }
420 return gcode.str();
421}

References config.

◆ set_current_position_clear()

void Slic3r::GCodeWriter::set_current_position_clear ( bool clear)
inline
156{ m_is_current_pos_clear = clear; };

References m_is_current_pos_clear.

Referenced by Slic3r::WipeTowerIntegration::append_tcr(), travel_to_xy(), and travel_to_xyz().

Here is the caller graph for this function:

◆ set_exhaust_fan()

std::string Slic3r::GCodeWriter::set_exhaust_fan ( int speed)
static
1615{
1616 std::ostringstream gcode;
1617 gcode << "M106" << " P3" << " S" << (int)(speed / 100.0 * 255);
1618
1620 if (speed == 0)
1621 gcode << " ; disable exhaust fan ";
1622 else
1623 gcode << " ; enable exhaust fan ";
1624 }
1625
1626 gcode << "\n";
1627 return gcode.str();
1628}

References full_gcode_comment.

◆ set_extruder()

std::string Slic3r::GCodeWriter::set_extruder ( unsigned int filament_id)
1658{
1659 auto filament_ext_it = Slic3r::lower_bound_by_predicate(m_filament_extruders.begin(), m_filament_extruders.end(), [filament_id](const Extruder &e) { return e.id() < filament_id; });
1660 unsigned int extruder_id = filament_ext_it->extruder_id();
1661 assert(filament_ext_it != m_filament_extruders.end() && filament_ext_it->id() == filament_id);
1662 // Orca: writer-only context (calibration paths) has no nozzle grouping; the
1663 // filament's own extruder id is the correct degenerate nozzle value.
1664 return this->need_toolchange(filament_id) ? this->toolchange(filament_id, (int) extruder_id) : "";
1665}
std::string toolchange(unsigned int filament_id, int nozzle_id)
Definition GCodeWriter.cpp:803
bool need_toolchange(unsigned int filament_id) const
Definition GCodeWriter.cpp:1678

References Slic3r::lower_bound_by_predicate(), m_filament_extruders, need_toolchange(), and toolchange().

Here is the call graph for this function:

◆ set_extruders()

void Slic3r::GCodeWriter::set_extruders ( std::vector< unsigned int > extruder_ids)
263{
264 std::sort(extruder_ids.begin(), extruder_ids.end());
265 m_filament_extruders.clear();
266 //ORCA: Reset current extruder ID and clear pointers to prevent dangling pointers when extruders are recreated.
269 std::fill(m_curr_filament_extruder.begin(), m_curr_filament_extruder.end(), nullptr);
270 m_filament_extruders.reserve(extruder_ids.size());
271 for (unsigned int extruder_id : extruder_ids)
272 m_filament_extruders.emplace_back(Extruder(extruder_id, &this->config, config.single_extruder_multi_material.value));
273
274 /* we enable support for multiple extruder if any extruder greater than 0 is used
275 (even if prints only uses that one) since we need to output Tx commands
276 first extruder has index 0 */
277 //ORCA: Fix undefined behavior by checking if the vector is empty before taking max_element.
278 this->multiple_extruders = !extruder_ids.empty() && (*std::max_element(extruder_ids.begin(), extruder_ids.end())) > 0;
279}
std::vector< unsigned int > extruder_ids() const
Definition GCodeWriter.hpp:55

References config, Slic3r::Extruder, extruder_ids(), m_cached_extruder_idx, m_curr_extruder_id, m_curr_filament_extruder, m_filament_extruders, and multiple_extruders.

Here is the call graph for this function:

◆ set_fan() [1/2]

std::string Slic3r::GCodeWriter::set_fan ( const GCodeFlavor gcode_flavor,
unsigned int speed,
unsigned int part_cooling_fan_min_pwm = 0 )
static
1553{
1554 std::ostringstream gcode;
1555 // ORCA: clamp non-zero fan commands up to the configured PWM floor so fans that can't spool at low duty
1556 // cycles still start reliably. Zero (fan off) is preserved exactly so disable-fan commands are never altered.
1557 if (speed > 0 && part_cooling_fan_min_pwm > 0 && speed < part_cooling_fan_min_pwm)
1559 if (speed == 0) {
1560 switch (gcode_flavor) {
1561 case gcfTeacup:
1562 gcode << "M106 S0"; break;
1563 case gcfMakerWare:
1564 case gcfSailfish:
1565 gcode << "M127"; break;
1566 default:
1567 gcode << "M106 S0"; break;
1568 }
1570 gcode << " ; disable fan";
1571 gcode << "\n";
1572 } else {
1573 switch (gcode_flavor) {
1574 case gcfMakerWare:
1575 case gcfSailfish:
1576 gcode << "M126"; break;
1577 case gcfMach3:
1578 case gcfMachinekit:
1579 gcode << "M106 P" << static_cast<unsigned int>(255.5 * speed / 100.0); break;
1580 default:
1581 gcode << "M106 S" << static_cast<unsigned int>(255.5 * speed / 100.0); break;
1582 }
1584 gcode << " ; enable fan";
1585 gcode << "\n";
1586 }
1587 return gcode.str();
1588}
zaa_minimize_perimeter_height gcode_flavor((ConfigOptionBool, gcode_skip_config_block))((ConfigOptionFloat
zaa_minimize_perimeter_height part_cooling_fan_min_pwm((ConfigOptionFloats, filament_diameter))((ConfigOptionBoolsNullable

References full_gcode_comment, Slic3r::gcfMach3, Slic3r::gcfMachinekit, Slic3r::gcfMakerWare, Slic3r::gcfSailfish, Slic3r::gcfTeacup, Slic3r::gcode_flavor(), and Slic3r::part_cooling_fan_min_pwm().

Referenced by Slic3r::FanMover::_set_fan(), Slic3r::CoolingBuffer::apply_layer_cooldown(), and set_fan().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_fan() [2/2]

std::string Slic3r::GCodeWriter::set_fan ( unsigned int speed) const
1591{
1592 //BBS
1593 // ORCA: pick up the per-printer PWM floor from the active config.
1594 return GCodeWriter::set_fan(this->config.gcode_flavor, speed,
1595 static_cast<unsigned int>(std::max(0, this->config.part_cooling_fan_min_pwm.value)));
1596}
static std::string set_fan(const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm=0)
Definition GCodeWriter.cpp:1552

References config, and set_fan().

Here is the call graph for this function:

◆ set_first_layer_point_test()

void Slic3r::GCodeWriter::set_first_layer_point_test ( FirstLayerPointTest test)
inline
185{ m_first_layer_point_test = std::move(test); }

References m_first_layer_point_test.

◆ set_force_normal_lift()

void Slic3r::GCodeWriter::set_force_normal_lift ( bool force)
inline
190{ m_force_normal_lift = force; }

References m_force_normal_lift.

◆ set_input_shaping()

std::string Slic3r::GCodeWriter::set_input_shaping ( char axis,
float damp,
float freq,
std::string type ) const
642{
643 bool disable = type == "Disable";
644 if (disable){
645 freq = 0.0f;
646 damp = 0.0f;
647 axis = 'A';
648 type = "Default";
649 } else if (freq < 0.0f || damp < 0.f || damp > 1.0f || (axis != 'X' && axis != 'Y' && axis != 'Z' && axis != 'A')) { // A = all axis
650 throw std::runtime_error("Invalid input shaping parameters: axis=" + std::string(1, axis) + ", freq=" + std::to_string(freq) + ", damp=" + std::to_string(damp));
651 }
652 std::ostringstream gcode;
653 std::ostringstream params;
654 switch (this->config.gcode_flavor) {
655 case gcfKlipper: {
656 if (!type.empty() && type != "Default") {
657 params << " SHAPER_TYPE=" << type;
658 }
659 if (axis != 'A')
660 {
661 if (freq > 0.0f) {
662 params << " SHAPER_FREQ_" << axis << "=" << std::fixed << std::setprecision(2) << freq;
663 }
664 if (damp > 0.0f) {
665 params << " DAMPING_RATIO_" << axis << "=" << std::fixed << std::setprecision(3) << damp;
666 }
667 } else {
668 if (freq > 0.0f || disable) {
669 params << " SHAPER_FREQ_X=" << std::fixed << std::setprecision(2) << freq << " SHAPER_FREQ_Y=" << std::fixed << std::setprecision(2) << freq;
670 }
671 if (damp > 0.0f || disable) {
672 params << " DAMPING_RATIO_X=" << std::fixed << std::setprecision(3) << damp << " DAMPING_RATIO_Y=" << std::fixed << std::setprecision(3) << damp;
673 }
674 }
675 if (!params.str().empty()) {
676 gcode << "SET_INPUT_SHAPER" << params.str();
677 }
678 break;
679 }
680 case gcfRepRapFirmware: {
681 if (!type.empty() && type != "Default" && type != "DAA") {
682 params << " P\"" << type << "\"";
683 }
684 if (freq > 0.0f || disable) {
685 params << " F" << std::fixed << std::setprecision(2) << freq;
686 }
687 if (damp > 0.0f || disable) {
688 params << " S" << std::fixed << std::setprecision(3) << damp;
689 }
690 if (!params.str().empty()) {
691 gcode << "M593" << params.str();
692 }
693 break;
694 }
695 case gcfMarlinFirmware: {
696 if (axis != 'A') {
697 params << " " << axis;
698 }
699 if (freq > 0.0f || disable) {
700 params << " F" << std::fixed << std::setprecision(2) << freq;
701 }
702 if (damp > 0.0f || disable) {
703 params << " D" << std::fixed << std::setprecision(3) << damp;
704 }
705 if (!params.str().empty()) {
706 gcode << "M593" << params.str();
707 }
708 break;
709 }
710 case gcfMarlinLegacy: {
711 throw std::runtime_error(_u8L("Input shaping is not supported by Marlin < 2.1.2.\nCheck your firmware version and update your G-code flavor to ´Marlin 2´."));
712 }
713 default:
714 throw std::runtime_error(_u8L("Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2."));
715 }
716 if (!gcode.str().empty()) {
718 gcode << " ; Override input shaping";
719 }
720 gcode << "\n";
721 }
722 return gcode.str();
723}

References _u8L, config, full_gcode_comment, Slic3r::gcfKlipper, Slic3r::gcfMarlinFirmware, Slic3r::gcfMarlinLegacy, and Slic3r::gcfRepRapFirmware.

Referenced by Slic3r::GCode::process_layer().

Here is the caller graph for this function:

◆ set_is_bbl_machine()

void Slic3r::GCodeWriter::set_is_bbl_machine ( bool bval)
inline
161{m_is_bbl_printers = bval;}

References m_is_bbl_printers.

◆ set_is_first_layer()

void Slic3r::GCodeWriter::set_is_first_layer ( bool bval)
inline
163{ m_is_first_layer = bval; }

References m_is_first_layer.

◆ set_jerk_xy()

std::string Slic3r::GCodeWriter::set_jerk_xy ( double jerk)
484{
485 if (jerk < 0.01 || is_approx(jerk, m_last_jerk))
486 return std::string();
487
488 m_last_jerk = jerk;
489
490 std::ostringstream gcode;
491 if (FLAVOR_IS(gcfKlipper)) {
492 // Clamp the jerk to the allowed maximum.
497
498 gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
499
500 } else if (FLAVOR_IS(gcfRepetier)) {
501 // Repetier uses M207 for temporary Jerk and combines X/Y into a single 'X' parameter.
502 double jerk_xy = jerk;
503
504 // Clamp against the X machine limit
506 jerk_xy = EXTRUDER_LIMIT(m_max_jerk_x);
507
508 // Clamp against the Y machine limit as well to be safe
510 jerk_xy = EXTRUDER_LIMIT(m_max_jerk_y);
511
512 // Output the lowest safe limit using ONLY the X parameter
513 gcode << "M207 X" << jerk_xy;
514 } else {
515 double jerk_x = jerk;
516 double jerk_y = jerk;
517 // Clamp the axis jerk to the allowed maximum.
522
523 gcode << "M205 X" << jerk_x << " Y" << jerk_y;
524 }
525 //the is_bbl check should be in the else statement above so that it doesn't inadverently added Z & E to klipper
527 gcode << std::setprecision(2) << " Z" << EXTRUDER_LIMIT(m_max_jerk_z) << " E" << EXTRUDER_LIMIT(m_max_jerk_e);
528
529 if (GCodeWriter::full_gcode_comment) gcode << " ; adjust jerk";
530 gcode << "\n";
531
532 return gcode.str();
533
534}

References EXTRUDER_LIMIT, FLAVOR_IS, full_gcode_comment, Slic3r::gcfKlipper, Slic3r::gcfRepetier, Slic3r::is_approx(), m_is_bbl_printers, m_last_jerk, m_max_jerk_e, m_max_jerk_x, m_max_jerk_y, and m_max_jerk_z.

Referenced by Slic3r::GCode::process_layer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_junction_deviation()

std::string Slic3r::GCodeWriter::set_junction_deviation ( double junction_deviation)
581 {
582 std::ostringstream gcode;
583 if (FLAVOR_IS(gcfMarlinFirmware) && EXTRUDER_LIMIT(m_max_junction_deviation) > 0 && junction_deviation > 0) {
584 // Clamp the junction deviation to the allowed maximum.
585 gcode << "M205 J";
586 if (junction_deviation <= EXTRUDER_LIMIT(m_max_junction_deviation)) {
587 gcode << std::fixed << std::setprecision(3) << junction_deviation;
588 } else {
589 gcode << std::fixed << std::setprecision(3) << EXTRUDER_LIMIT(m_max_junction_deviation);
590 }
592 gcode << " ; Junction Deviation";
593 }
594 gcode << "\n";
595 }
596 return gcode.str();
597}

References EXTRUDER_LIMIT, FLAVOR_IS, full_gcode_comment, Slic3r::gcfMarlinFirmware, and m_max_junction_deviation.

Referenced by Slic3r::GCode::process_layer().

Here is the caller graph for this function:

◆ set_kinematics()

void Slic3r::GCodeWriter::set_kinematics ( std::unique_ptr< MachineKinematics > kinematics)
80{
81 assert(kinematics);
82 m_kinematics = std::move(kinematics);
83 // Replay whatever was configured on the previous strategy so callers may
84 // install the kinematics before or after set_axis_remap/set_build_volume_max.
85 m_kinematics->set_axis_remap(m_remap_x, m_remap_y, m_remap_z);
86 m_kinematics->set_build_volume_max(m_build_vol_max);
87}
const MachineKinematics & kinematics() const
Definition GCodeWriter.hpp:177

References kinematics(), m_build_vol_max, m_kinematics, m_remap_x, m_remap_y, and m_remap_z.

Referenced by Slic3r::install_belt_kinematics().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_object_end_str()

void Slic3r::GCodeWriter::set_object_end_str ( std::string end_string)
inline
149{ m_gcode_label_objects_end = end_string; }

References m_gcode_label_objects_end.

◆ set_object_start_str()

void Slic3r::GCodeWriter::set_object_start_str ( std::string start_string)
inline
147{ m_gcode_label_objects_start = start_string; }

References m_gcode_label_objects_start.

◆ set_position()

void Slic3r::GCodeWriter::set_position ( const Vec3d & in)
inline
130{ m_pos = in; }

References m_pos.

Referenced by Slic3r::WipeTowerIntegration::append_tcr(), and Slic3r::WipeTowerIntegration::append_tcr2().

Here is the caller graph for this function:

◆ set_pressure_advance()

std::string Slic3r::GCodeWriter::set_pressure_advance ( double pa,
int tool = -1 ) const
600{
601 std::ostringstream gcode;
602 if (pa < 0)
603 return gcode.str();
604 if (m_is_bbl_printers) {
605 // SoftFever: set L1000 to use linear model
606 gcode << "M900 K" << std::setprecision(4) << pa << " L1000 M10 ; Override pressure advance value\n";
607 } else if (FLAVOR_IS(gcfKlipper)) {
608 // Klipper routes PA by extruder name, not active tool.
609 // Convention: first extruder is "extruder", subsequent are "extruder1", "extruder2", etc.
610 gcode << "SET_PRESSURE_ADVANCE ADVANCE=" << std::setprecision(4) << pa;
611 if (tool > 0)
612 gcode << " EXTRUDER=extruder" << tool;
613 else if (tool == 0)
614 gcode << " EXTRUDER=extruder";
615 gcode << "; Override pressure advance value\n";
616 } else if (FLAVOR_IS(gcfRepRapFirmware)) {
617 // RRF: M572 D<n> targets a specific extruder; a bare M572 applies to whatever tool is
618 // currently selected and errors when there isn't one. Callers with no tool index keep
619 // the historical D0 rather than the bare form: PA would otherwise depend on
620 // tool-selection state for every RRF user, none of whom are asking for IMEX.
621 gcode << "M572 D" << (tool >= 0 ? tool : 0)
622 << " S" << std::setprecision(4) << pa << "; Override pressure advance value\n";
623 } else if (FLAVOR_IS(gcfRepetier)) {
624 // Repetier M233: X is quadratic (K), Y is linear (L).
625 // Applying the value to both parameters simultaneously.
626 gcode << "M233 X" << std::setprecision(4) << pa << " Y" << std::setprecision(4) << pa << " ; Override pressure advance value\n";
627 } else if (FLAVOR_IS(gcfMarlinFirmware)) {
628 // Marlin 2.x supports T parameter for per-extruder LA
629 gcode << "M900 K" << std::setprecision(4) << pa;
630 if (tool >= 0)
631 gcode << " T" << tool;
632 gcode << "; Override pressure advance value\n";
633 } else {
634 // Marlin Legacy and everything else: single-extruder M900, no tool parameter
635 gcode << "M900 K" << std::setprecision(4) << pa << "; Override pressure advance value\n";
636 }
637 return gcode.str();
638}

References FLAVOR_IS, Slic3r::gcfKlipper, Slic3r::gcfMarlinFirmware, Slic3r::gcfRepetier, Slic3r::gcfRepRapFirmware, and m_is_bbl_printers.

Referenced by Slic3r::GCode::process_layer().

Here is the caller graph for this function:

◆ set_print_acceleration()

std::string Slic3r::GCodeWriter::set_print_acceleration ( unsigned int acceleration)
inline
69{ return set_acceleration_internal(Acceleration::Print, acceleration); }
std::string set_acceleration_internal(Acceleration type, unsigned int acceleration)
Definition GCodeWriter.cpp:428

References Print, and set_acceleration_internal().

Here is the call graph for this function:

◆ set_speed() [1/2]

std::string Slic3r::GCodeWriter::set_speed ( double F,
const std::string & comment = std::string(),
const std::string & cooling_marker = std::string() )
853{
854 std::string gcode;
855 this->set_speed(gcode, F, comment, cooling_marker);
856 return gcode;
857}
std::string set_speed(double F, const std::string &comment=std::string(), const std::string &cooling_marker=std::string())
Definition GCodeWriter.cpp:852
@ F
Definition libslic3r.h:145

References Slic3r::F, and set_speed().

Referenced by Slic3r::CalibPressureAdvance::draw_line(), Slic3r::CalibPressureAdvance::draw_number(), set_speed(), and Slic3r::Wipe::wipe().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_speed() [2/2]

void Slic3r::GCodeWriter::set_speed ( std::string & out,
double F,
const std::string & comment = std::string(),
const std::string & cooling_marker = std::string() )
860{
861 assert(F > 0.);
862 assert(F < 100000.);
863
865 GCodeG1Formatter w(config.high_precision_gcode.value);
866 w.emit_f(F);
867 //BBS
868 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
869 w.emit_string(cooling_marker);
870 w.append_to(out);
871}

References Slic3r::GCodeFormatter::append_to(), config, Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_f(), Slic3r::GCodeFormatter::emit_string(), Slic3r::F, full_gcode_comment, and m_current_speed.

Here is the call graph for this function:

◆ set_temperature() [1/2]

std::string Slic3r::GCodeWriter::set_temperature ( unsigned int temperature,
bool wait = false,
int tool = -1 ) const
360{
361 // set tool to -1 to make sure we won't emit T parameter for single extruder or SEMM
363 tool = -1;
364 } else {
365 // Every caller of this overload addresses filaments by LOGICAL id, but M104/M109
366 // name a physical heater -- so translate at the one point they all pass through.
367 // The static overload below is already physical-in (GCode.cpp:5952,
368 // GCode/GCodeProcessor.cpp:1410) and must not be remapped, which is why the
369 // translation lives here and not there.
370 tool = imex_physical_heater_for(this->config.is_imex.value, this->config.physical_extruder_map, tool);
371 }
372 return set_temperature(temperature, this->config.gcode_flavor, wait, tool);
373}
static std::string set_temperature(unsigned int temperature, GCodeFlavor flavor, bool wait=false, int tool=-1, std::string comment=std::string())
Definition GCodeWriter.cpp:317
int imex_physical_heater_for(bool is_imex, const ConfigOptionInts &pem, int logical_id)
Definition IMEXHelpers.cpp:88

References config, Slic3r::imex_physical_heater_for(), m_single_extruder_multi_material, multiple_extruders, and set_temperature().

Here is the call graph for this function:

◆ set_temperature() [2/2]

std::string Slic3r::GCodeWriter::set_temperature ( unsigned int temperature,
GCodeFlavor flavor,
bool wait = false,
int tool = -1,
std::string comment = std::string() )
static
317 {
318 if (wait && (flavor == gcfMakerWare || flavor == gcfSailfish))
319 return "";
320
321 std::string code;
322 if (wait && flavor != gcfTeacup && flavor != gcfRepRapFirmware) {
323 code = "M109";
324 if(comment.empty())
325 comment = "set nozzle temperature and wait for it to be reached";
326 } else {
327 if (flavor == gcfRepRapFirmware) { // M104 is deprecated on RepRapFirmware
328 code = "G10";
329 } else {
330 code = "M104";
331 }
332 if(comment.empty())
333 comment = "set nozzle temperature";
334 }
335
336 std::ostringstream gcode;
337 gcode << code << " ";
338 if (flavor == gcfMach3 || flavor == gcfMachinekit) {
339 gcode << "P";
340 } else {
341 gcode << "S";
342 }
343 gcode << temperature;
344 if (tool != -1) {
345 if (flavor == gcfRepRapFirmware) {
346 gcode << " P" << tool;
347 } else {
348 gcode << " T" << tool;
349 }
350 }
351 gcode << " ; " << comment << "\n";
352
353 if ((flavor == gcfTeacup || flavor == gcfRepRapFirmware) && wait)
354 gcode << "M116 ; wait for temperature to be reached\n";
355
356 return gcode.str();
357}

References Slic3r::gcfMach3, Slic3r::gcfMachinekit, Slic3r::gcfMakerWare, Slic3r::gcfRepRapFirmware, Slic3r::gcfSailfish, and Slic3r::gcfTeacup.

Referenced by Slic3r::OozePrevention::post_toolchange(), Slic3r::OozePrevention::pre_toolchange(), Slic3r::GCode::process_layer(), Slic3r::GCodeProcessor::run_post_process(), and set_temperature().

Here is the caller graph for this function:

◆ set_travel_acceleration()

std::string Slic3r::GCodeWriter::set_travel_acceleration ( unsigned int acceleration)
inline
70{ return set_acceleration_internal(Acceleration::Travel, acceleration); }

References set_acceleration_internal(), and Travel.

Here is the call graph for this function:

◆ set_xy_offset()

void Slic3r::GCodeWriter::set_xy_offset ( double x,
double y )
inline
134{ m_x_offset = x; m_y_offset = y; }

References m_x_offset, and m_y_offset.

◆ spiral_lift_fits_printable_area()

bool Slic3r::GCodeWriter::spiral_lift_fits_printable_area ( const Vec2d & center,
double radius ) const
private
242{
243 const Polygon *area = this->active_printable_area();
244 if (area == nullptr)
245 return true; // Boundary unknown: don't restrict (preserve previous behavior).
246
247 const Point c = Point::new_scale(center.x(), center.y());
248 const double r_scaled = scale_(radius);
249 const double r2 = r_scaled * r_scaled;
250
251 // The spiral traces a full circle of `radius` around `center`, so the center must lie
252 // inside the printable area and every edge must be at least `radius` away from it.
253 if (!area->contains(c))
254 return false;
255 const Points &pts = area->points;
256 for (size_t i = 0, n = pts.size(); i < n; ++i)
257 if (Line::distance_to_squared(c, pts[i], pts[(i + 1) % n]) < r2)
258 return false;
259 return true;
260}
const Polygon * active_printable_area() const
Definition GCodeWriter.cpp:229
double distance_to_squared(const Point &point) const
Definition Line.hpp:170
static Point new_scale(coordf_t x, coordf_t y)
Definition Point.hpp:214
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
void center(ExPolygonsWithIds &e)
Definition Emboss.cpp:1382
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:511
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73

References active_printable_area(), Slic3r::area(), Slic3r::center(), Slic3r::Line::distance_to_squared(), Slic3r::Point::new_scale(), and scale_.

Referenced by eager_lift(), and travel_to_xyz().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ supports_separate_travel_acceleration()

bool Slic3r::GCodeWriter::supports_separate_travel_acceleration ( GCodeFlavor flavor)
static
101{
102 return (flavor == gcfRepetier || flavor == gcfMarlinFirmware || flavor == gcfRepRapFirmware);
103}

References Slic3r::gcfMarlinFirmware, Slic3r::gcfRepetier, and Slic3r::gcfRepRapFirmware.

Referenced by Slic3r::GCodeProcessor::apply_config(), apply_print_config(), and set_acceleration_internal().

Here is the caller graph for this function:

◆ toolchange()

std::string Slic3r::GCodeWriter::toolchange ( unsigned int filament_id,
int nozzle_id )
804{
805 // set the new extruder
806 auto filament_extruder_iter = Slic3r::lower_bound_by_predicate(m_filament_extruders.begin(), m_filament_extruders.end(), [filament_id](const Extruder &e) { return e.id() < filament_id; });
807 assert(filament_extruder_iter != m_filament_extruders.end() && filament_extruder_iter->id() == filament_id);
808 m_curr_extruder_id = filament_extruder_iter->extruder_id();
809 m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter;
810 m_cached_extruder_idx = get_extruder_index(this->config, filament_id);
811
812 // return the toolchange command
813 // if we are running a single-extruder setup, just set the extruder and return nothing
814 std::ostringstream gcode;
815 // Orca: also emit for non-BBL single-extruder multi-filament setups (MMU-style).
816 if (this->multiple_extruders || (this->config.filament_diameter.values.size() > 1 && !is_bbl_printers())) {
817 // Orca: manual filament change keeps its tag line even on BBL machines, so the
818 // M1020 form must not shadow it. nozzle_id is signed: the null-safe nozzle
819 // lookup legitimately yields -1 ("no specific nozzle"), matching the literal
820 // H-1 the stock change templates emit; an unsigned would wrap.
821 if (m_is_bbl_printers && !config.manual_filament_change)
822 gcode << "M1020 S" << filament_id << " H" << nozzle_id;
823 else
824 gcode << this->toolchange_prefix() << filament_id;
826 gcode << " ; change extruder";
827 gcode << "\n";
828 gcode << this->reset_e(true);
829 }
830 return gcode.str();
831}
const bool is_bbl_printers() const
Definition GCodeWriter.hpp:162
std::string toolchange_prefix() const
Definition GCodeWriter.cpp:793

References config, full_gcode_comment, Slic3r::get_extruder_index(), is_bbl_printers(), Slic3r::lower_bound_by_predicate(), m_cached_extruder_idx, m_curr_extruder_id, m_curr_filament_extruder, m_filament_extruders, m_is_bbl_printers, multiple_extruders, reset_e(), and toolchange_prefix().

Referenced by Slic3r::WipeTowerIntegration::append_tcr(), and set_extruder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ toolchange_prefix()

std::string Slic3r::GCodeWriter::toolchange_prefix ( ) const
794{
795 // Orca: the manual-filament-change tag must stay ahead of the flavor selection so
796 // MMU manual-change handling keeps working.
797 if (config.manual_filament_change)
799 return FLAVOR_IS(gcfMakerWare) ? "M135 T" :
800 FLAVOR_IS(gcfSailfish) ? "M108 T" : "T";
801}
static const std::string & reserved_tag(ETags tag)
Definition GCodeProcessor.hpp:636
@ Manual_Tool_Change
Definition GCodeProcessor.hpp:617

References config, FLAVOR_IS, Slic3r::gcfMakerWare, Slic3r::gcfSailfish, Slic3r::GCodeProcessor::Manual_Tool_Change, and Slic3r::GCodeProcessor::reserved_tag().

Referenced by Slic3r::WipeTowerIntegration::append_tcr(), and toolchange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ travel_to_xy()

std::string Slic3r::GCodeWriter::travel_to_xy ( const Vec2d & point,
const std::string & comment = std::string() )
874{
875 m_pos(0) = point(0);
876 m_pos(1) = point(1);
877
878 this->set_current_position_clear(true);
879 //BBS: take plate offset into consider
880 Vec2d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset };
881
882 GCodeG1Formatter w(high_precision());
883 if (has_axis_remap()) {
884 // Axis remap may couple XY with Z; emit full XYZ in machine coordinates.
885 Vec3d machine = apply_axis_remap(Vec3d(point_on_plate.x(), point_on_plate.y(), m_pos.z()));
886 w.emit_xyz(machine);
887 } else {
888 w.emit_xy(point_on_plate);
889 }
890 auto speed = this->point_on_first_layer(Vec3d(point_on_plate.x(), point_on_plate.y(), m_pos.z()))
891 ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) : this->config.travel_speed.get_at(m_cached_extruder_idx);
892 w.emit_f(speed * 60.0);
893 //BBS
894 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
895 return w.string();
896}
void set_current_position_clear(bool clear)
Definition GCodeWriter.hpp:156

References apply_axis_remap(), config, Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_f(), Slic3r::GCodeFormatter::emit_xy(), Slic3r::GCodeFormatter::emit_xyz(), full_gcode_comment, has_axis_remap(), high_precision(), m_cached_extruder_idx, m_pos, m_x_offset, m_y_offset, point_on_first_layer(), set_current_position_clear(), and Slic3r::GCodeFormatter::string().

Referenced by Slic3r::WipeTowerIntegration::append_tcr(), Slic3r::WipeTowerIntegration::append_tcr2(), Slic3r::CalibPressureAdvance::move_to(), and travel_to_xyz().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ travel_to_xyz()

std::string Slic3r::GCodeWriter::travel_to_xyz ( const Vec3d & point,
const std::string & comment = std::string(),
bool force_z = false )
981{
982 // FIXME: This function was not being used when travel_speed_z was separated (bd6badf).
983 // Calculation of feedrate was not updated accordingly. If you want to use
984 // this function, fix it first.
985 //std::terminate();
986
987 /* If target Z is lower than current Z but higher than nominal Z we
988 don't perform the Z move but we only move in the XY plane and
989 adjust the nominal Z by reducing the lift amount that will be
990 used for unlift. */
991 // BBS
992 Vec3d dest_point = point;
993 auto travel_speed =
994 this->point_on_first_layer(Vec3d(point.x() - m_x_offset, point.y() - m_y_offset, point.z())) ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) : this->config.travel_speed.get_at(m_cached_extruder_idx);
995 // See uses_pointwise_travel_speed(): the historical path deliberately emits the
996 // raw configured speed in the final branch below, ignoring travel_speed.
997 const double final_travel_speed = this->uses_pointwise_travel_speed()
999 : this->config.travel_speed.get_at(m_cached_extruder_idx);
1000 //BBS: a z_hop need to be handle when travel
1001 if (std::abs(m_to_lift) > EPSILON) {
1002 assert(std::abs(m_lifted) < EPSILON);
1003 //BBS: don't need to do real lift if the current position is absolutely same with target.
1004 //This ususally happens when the last extrusion line is short and the end of wipe position
1005 //is same with the traget point by chance.
1006 if ((!this->is_current_position_clear() || m_pos != dest_point) &&
1007 m_to_lift + m_pos(2) > point(2)) {
1008 m_lifted = m_to_lift + m_pos(2) - point(2);
1009 dest_point(2) = m_to_lift + m_pos(2);
1010 }
1011 m_to_lift = 0.;
1012
1013 std::string slop_move;
1014 //BBS: minus plate offset
1015 Vec3d source = { m_pos(0) - m_x_offset, m_pos(1) - m_y_offset, m_pos(2) };
1016 Vec3d target = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) };
1017 Vec3d delta = target - source;
1018 Vec2d delta_no_z = { delta(0), delta(1) };
1019 //BBS: don'need slope travel because we don't know where is the source position the first time
1020 //BBS: Also don't need to do slope move or spiral lift if x-y distance is absolute zero
1021 if (delta(2) > 0 && delta_no_z.norm() != 0.0f) {
1022 //BBS: SpiralLift
1024 //BBS: todo: check the arc move all in bed area, if not, then use lazy lift
1025 double radius = delta(2) / (2 * PI * atan(this->filament()->travel_slope()));
1026 Vec2d ij_offset = radius * delta_no_z.normalized();
1027 ij_offset = { -ij_offset(1), ij_offset(0) };
1028 // Orca: only perform the spiral lift if its full circle stays inside the
1029 // printable area of the active extruder, otherwise fall back to a normal
1030 // lift to avoid colliding with the print boundary. `source` is already in
1031 // bed coordinates (plate offset removed), matching the printable area.
1032 const Vec2d spiral_center = { source.x() + ij_offset.x(), source.y() + ij_offset.y() };
1033 if (this->spiral_lift_fits_printable_area(spiral_center, radius))
1034 slop_move = this->_spiral_travel_to_z(target(2), ij_offset, "spiral lift Z");
1035 else
1036 slop_move = _travel_to_z(target.z(), "normal lift Z");
1037 }
1038 //BBS: SlopeLift
1039 else if (m_to_lift_type == LiftType::SlopeLift &&
1040 this->is_current_position_clear() &&
1041 atan2(delta(2), delta_no_z.norm()) < this->filament()->travel_slope()) {
1042 //BBS: check whether we can make a travel like
1043 // _____
1044 // / to make the z list early to avoid to hit some warping place when travel is long.
1045 Vec2d temp = delta_no_z.normalized() * delta(2) / tan(this->filament()->travel_slope());
1046 Vec3d slope_top_point = Vec3d(temp(0), temp(1), delta(2)) + source;
1047 GCodeG1Formatter w0(config.high_precision_gcode.value);
1048 // A slope lift is a straight (linear) diagonal move, so remapping its
1049 // endpoint is exact. Route the destination through apply_axis_remap()
1050 // when a remap is active (no-op at identity).
1051 w0.emit_xyz(has_axis_remap() ? apply_axis_remap(slope_top_point) : slope_top_point);
1052 w0.emit_f(travel_speed * 60.0);
1053 //BBS
1054 w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
1055 slop_move = w0.string();
1056 }
1057 else if (m_to_lift_type == LiftType::NormalLift && ! this->must_skip_lift_now()) {
1058 // Only lift in place when the current position is known, for a mapping
1059 // that makes _travel_to_z re-emit logical X/Y: at print start (and after
1060 // custom gcode) m_pos.xy is still the uninitialised origin, which would
1061 // map to a bogus machine point. The xy_z_move below then travels straight
1062 // to the destination with full XYZ and establishes the correct position.
1063 // Mappings that do not need this (the historical Cartesian behaviour)
1064 // report false and keep lifting unconditionally.
1065 slop_move = _travel_to_z(target.z(), "normal lift Z");
1066 }
1067 }
1068
1069 std::string xy_z_move;
1070 {
1071 GCodeG1Formatter w0(config.high_precision_gcode.value);
1072 if (has_axis_remap()) {
1073 // Remap may couple XY with Z; emit full XYZ in machine coordinates.
1074 w0.emit_xyz(apply_axis_remap(target));
1075 w0.emit_f(travel_speed * 60.0);
1076 w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
1077 xy_z_move = w0.string();
1078 }
1079 else if (this->is_current_position_clear()) {
1080 w0.emit_xyz(target);
1081 w0.emit_f(travel_speed * 60.0);
1082 w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
1083 xy_z_move = w0.string();
1084 }
1085 else {
1086 w0.emit_xy(Vec2d(target.x(), target.y()));
1087 w0.emit_f(travel_speed * 60.0);
1088 w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
1089 xy_z_move = w0.string() + _travel_to_z(target.z(), comment);
1090 }
1091 }
1092 m_pos = dest_point;
1093 this->set_current_position_clear(true);
1094 return slop_move + xy_z_move;
1095 }
1096 else if (!force_z && !this->will_move_z(point(2))) {
1097 double nominal_z = m_pos(2) - m_lifted;
1098 m_lifted -= (point(2) - nominal_z);
1099 // In case that z_hop == layer_height we could end up with almost zero in_m_lifted
1100 // and a retract could be skipped
1101 if (std::abs(m_lifted) < EPSILON)
1102 m_lifted = 0.;
1103 //BBS
1104 this->set_current_position_clear(true);
1105 return this->travel_to_xy(to_2d(point));
1106 }
1107 else {
1108 /* In all the other cases, we perform an actual XYZ move and cancel
1109 the lift. */
1110 m_lifted = 0;
1111 }
1112
1113 //BBS: take plate offset into consider
1114 Vec3d point_on_plate = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) };
1115 std::string out_string;
1116 GCodeG1Formatter w(config.high_precision_gcode.value);
1117 if (has_axis_remap()) {
1118 // Remap may couple XY with Z; emit full XYZ in machine coordinates.
1119 w.emit_xyz(apply_axis_remap(point_on_plate));
1120 w.emit_f(final_travel_speed * 60.0);
1121 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1122 out_string = w.string();
1123 } else if (!this->is_current_position_clear())
1124 {
1125 //force to move xy first then z after filament change
1126 w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y()));
1127 w.emit_f(final_travel_speed * 60.0);
1128 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1129 out_string = w.string() + _travel_to_z(point_on_plate.z(), comment);
1130 } else {
1131 GCodeG1Formatter w(config.high_precision_gcode.value);
1132 w.emit_xyz(point_on_plate);
1133 w.emit_f(final_travel_speed * 60.0);
1134 w.emit_comment(GCodeWriter::full_gcode_comment, comment);
1135 out_string = w.string();
1136 }
1137
1138 m_pos = dest_point;
1139 this->set_current_position_clear(true);
1140 return out_string;
1141}
bool uses_pointwise_travel_speed() const
Definition GCodeWriter.hpp:230
std::string travel_to_xy(const Vec2d &point, const std::string &comment=std::string())
Definition GCodeWriter.cpp:873
Eigen::Matrix< typename Derived::Scalar, 2, 1, Eigen::DontAlign > to_2d(const Eigen::MatrixBase< Derived > &ptN)
Definition Point.hpp:147
@ SlopeLift
Definition PrintConfig.hpp:432
zaa_minimize_perimeter_height travel_speed((ConfigOptionFloatsNullable, travel_speed_z))((ConfigOptionString

References _spiral_travel_to_z(), _travel_to_z(), apply_axis_remap(), config, Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_f(), Slic3r::GCodeFormatter::emit_xy(), Slic3r::GCodeFormatter::emit_xyz(), EPSILON, filament(), full_gcode_comment, has_axis_remap(), is_current_position_clear(), m_cached_extruder_idx, m_lifted, m_pos, m_to_lift, m_to_lift_type, m_x_offset, m_y_offset, must_skip_lift_now(), Slic3r::NormalLift, PI, point_on_first_layer(), set_current_position_clear(), Slic3r::SlopeLift, spiral_lift_fits_printable_area(), Slic3r::SpiralLift, Slic3r::GCodeFormatter::string(), Slic3r::to_2d(), Slic3r::travel_slope(), Slic3r::travel_speed(), travel_to_xy(), uses_pointwise_travel_speed(), and will_move_z().

Here is the call graph for this function:

◆ travel_to_z()

std::string Slic3r::GCodeWriter::travel_to_z ( double z,
const std::string & comment = std::string(),
bool force = false )
1157{
1158 /* If target Z is lower than current Z but higher than nominal Z
1159 we don't perform the move but we only adjust the nominal Z by
1160 reducing the lift amount that will be used for unlift. */
1161 if (!force && !this->will_move_z(z)) {
1162 double nominal_z = m_pos(2) - m_lifted;
1163 m_lifted -= (z - nominal_z);
1164 if (std::abs(m_lifted) < EPSILON)
1165 m_lifted = 0.;
1166 return "";
1167 }
1168
1169 /* In all the other cases, we perform an actual Z move and cancel
1170 the lift. */
1171 m_lifted = 0;
1172 return this->_travel_to_z(z, comment);
1173}

References _travel_to_z(), EPSILON, m_lifted, m_pos, and will_move_z().

Referenced by Slic3r::GCode::_extrude(), Slic3r::WipeTowerIntegration::append_tcr(), Slic3r::WipeTowerIntegration::append_tcr2(), and Slic3r::CalibPressureAdvance::move_to().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unlift()

std::string Slic3r::GCodeWriter::unlift ( )
1542{
1543 std::string gcode;
1544 if (m_lifted > 0) {
1545 gcode += this->_travel_to_z(m_pos(2) - m_lifted, "restore layer Z");
1546 m_lifted = 0;
1547 }
1548 m_to_lift = 0.;
1549 return gcode;
1550}

References _travel_to_z(), m_lifted, m_pos, and m_to_lift.

Referenced by Slic3r::WipeTowerIntegration::append_tcr2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unretract()

std::string Slic3r::GCodeWriter::unretract ( float extra_retract = 0.f)
1511{
1512 std::string gcode;
1513
1515 gcode = "M101 ; extruder on\n";
1516
1517 if (double dE = filament()->unretract(); !is_zero(dE)) {
1518 if (this->config.use_firmware_retraction) {
1519 gcode += FLAVOR_IS(gcfMachinekit) ? "G23 ; unretract\n" : "G11 ; unretract\n";
1520 gcode += this->reset_e();
1521 }
1522 else {
1523 //BBS
1524 // use G1 instead of G0 because G0 will blend the restart with the previous travel move
1525 const bool high_precision = this->high_precision();
1526 GCodeG1Formatter w(high_precision);
1527 // extra_retract over-extrudes for the PETG pre-extrusion; 0 by
1528 // default -> identical to the plain deretract E position.
1529 w.emit_e(filament()->E_to_emit(high_precision, extra_retract));
1530 w.emit_f(filament()->deretract_speed() * 60.);
1531 //BBS
1532 w.emit_comment(GCodeWriter::full_gcode_comment, " ; unretract");
1533 gcode += w.string();
1534 }
1535 }
1536
1537 return gcode;
1538}
std::string unretract(float extra_retract=0.f)
Definition GCodeWriter.cpp:1510

References config, Slic3r::GCodeFormatter::emit_comment(), Slic3r::GCodeFormatter::emit_e(), Slic3r::GCodeFormatter::emit_f(), filament(), FLAVOR_IS, full_gcode_comment, Slic3r::gcfMachinekit, Slic3r::gcfMakerWare, high_precision(), Slic3r::is_zero(), reset_e(), Slic3r::GCodeFormatter::string(), and unretract().

Referenced by Slic3r::WipeTowerIntegration::append_tcr(), Slic3r::WipeTowerIntegration::append_tcr2(), Slic3r::ProcessLayer::emit_custom_gcode_per_print_z(), Slic3r::CalibPressureAdvance::move_to(), and unretract().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_progress()

std::string Slic3r::GCodeWriter::update_progress ( unsigned int num,
unsigned int tot,
bool allow_100 = false ) const
774{
776 return "";
777
778 if (config.disable_m73) {
779 return "";
780 }
781
782 unsigned int percent = (unsigned int)floor(100.0 * num / tot + 0.5);
783 if (!allow_100) percent = std::min(percent, (unsigned int)99);
784
785 std::ostringstream gcode;
786 gcode << "M73 P" << percent;
787 //BBS
788 if (GCodeWriter::full_gcode_comment) gcode << " ; update progress";
789 gcode << "\n";
790 return gcode.str();
791}

References config, FLAVOR_IS_NOT, full_gcode_comment, Slic3r::gcfMakerWare, and Slic3r::gcfSailfish.

◆ uses_pointwise_travel_speed()

bool Slic3r::GCodeWriter::uses_pointwise_travel_speed ( ) const
inlineprotected
230{ return bool(m_first_layer_point_test); }

References m_first_layer_point_test.

Referenced by travel_to_xyz().

Here is the caller graph for this function:

◆ will_move_z()

bool Slic3r::GCodeWriter::will_move_z ( double z) const
1280{
1281 /* If target Z is lower than current Z but higher than nominal Z
1282 we don't perform an actual Z move. */
1283 if (m_lifted > 0) {
1284 double nominal_z = m_pos(2) - m_lifted;
1285 if (z >= nominal_z && z <= m_pos(2))
1286 return false;
1287 }
1288 // BBS.
1289 // Dont move z if it is the same as target z
1290 else if (std::abs(m_pos(2) - z) < EPSILON) {
1291 return false;
1292 }
1293 return true;
1294}

References EPSILON, m_lifted, and m_pos.

Referenced by planned_travel_z(), travel_to_xyz(), and travel_to_z().

Here is the caller graph for this function:

Member Data Documentation

◆ config

◆ full_gcode_comment

◆ m_bed_printable_area

Polygon Slic3r::GCodeWriter::m_bed_printable_area
private

◆ m_build_vol_max

Vec3d Slic3r::GCodeWriter::m_build_vol_max = Vec3d::Zero()
protected

◆ m_cached_extruder_idx

size_t Slic3r::GCodeWriter::m_cached_extruder_idx
protected

◆ m_curr_extruder_id

int Slic3r::GCodeWriter::m_curr_extruder_id
private

◆ m_curr_filament_extruder

std::vector<Extruder*> Slic3r::GCodeWriter::m_curr_filament_extruder
private

◆ m_current_speed

double Slic3r::GCodeWriter::m_current_speed
protected

◆ m_extruder_printable_areas

std::vector<Polygon> Slic3r::GCodeWriter::m_extruder_printable_areas
private

◆ m_filament_extruders

std::vector<Extruder> Slic3r::GCodeWriter::m_filament_extruders
private

◆ m_first_layer_point_test

FirstLayerPointTest Slic3r::GCodeWriter::m_first_layer_point_test
protected

◆ m_force_normal_lift

bool Slic3r::GCodeWriter::m_force_normal_lift = false
protected

◆ m_force_standard_precision

bool Slic3r::GCodeWriter::m_force_standard_precision = false
protected

◆ m_gcode_label_objects_end

std::string Slic3r::GCodeWriter::m_gcode_label_objects_end
private

◆ m_gcode_label_objects_start

std::string Slic3r::GCodeWriter::m_gcode_label_objects_start
private

◆ m_is_bbl_printers

bool Slic3r::GCodeWriter::m_is_bbl_printers = false
private

◆ m_is_current_pos_clear

bool Slic3r::GCodeWriter::m_is_current_pos_clear = false
protected

◆ m_is_first_layer

bool Slic3r::GCodeWriter::m_is_first_layer = true
protected

◆ m_kinematics

◆ m_last_acceleration

unsigned int Slic3r::GCodeWriter::m_last_acceleration
private

◆ m_last_bed_temperature

int Slic3r::GCodeWriter::m_last_bed_temperature
private

Referenced by GCodeWriter(), and set_bed_temperature().

◆ m_last_bed_temperature_reached

bool Slic3r::GCodeWriter::m_last_bed_temperature_reached
private

Referenced by GCodeWriter(), and set_bed_temperature().

◆ m_last_jerk

double Slic3r::GCodeWriter::m_last_jerk
private

◆ m_last_travel_acceleration

unsigned int Slic3r::GCodeWriter::m_last_travel_acceleration
private

◆ m_lifted

double Slic3r::GCodeWriter::m_lifted
protected

◆ m_max_acceleration

std::vector<unsigned int> Slic3r::GCodeWriter::m_max_acceleration
private

◆ m_max_jerk_e

std::vector<double> Slic3r::GCodeWriter::m_max_jerk_e
private

Referenced by apply_print_config(), and set_jerk_xy().

◆ m_max_jerk_x

std::vector<double> Slic3r::GCodeWriter::m_max_jerk_x
private

◆ m_max_jerk_y

std::vector<double> Slic3r::GCodeWriter::m_max_jerk_y
private

◆ m_max_jerk_z

std::vector<double> Slic3r::GCodeWriter::m_max_jerk_z
private

Referenced by apply_print_config(), and set_jerk_xy().

◆ m_max_junction_deviation

std::vector<double> Slic3r::GCodeWriter::m_max_junction_deviation
private

◆ m_max_travel_acceleration

std::vector<unsigned int> Slic3r::GCodeWriter::m_max_travel_acceleration
private

◆ m_pos

◆ m_remap_x

int Slic3r::GCodeWriter::m_remap_x = 0
protected

Referenced by set_axis_remap(), and set_kinematics().

◆ m_remap_y

int Slic3r::GCodeWriter::m_remap_y = 1
protected

Referenced by set_axis_remap(), and set_kinematics().

◆ m_remap_z

int Slic3r::GCodeWriter::m_remap_z = 2
protected

Referenced by set_axis_remap(), and set_kinematics().

◆ m_resolution

double Slic3r::GCodeWriter::m_resolution = 0.01
private

◆ m_single_extruder_multi_material

bool Slic3r::GCodeWriter::m_single_extruder_multi_material
private

◆ m_to_lift

double Slic3r::GCodeWriter::m_to_lift
protected

◆ m_to_lift_type

LiftType Slic3r::GCodeWriter::m_to_lift_type
protected

◆ m_x_offset

double Slic3r::GCodeWriter::m_x_offset { 0 }
protected

◆ m_y_offset

double Slic3r::GCodeWriter::m_y_offset { 0 }
protected

◆ multiple_extruders

bool Slic3r::GCodeWriter::multiple_extruders

The documentation for this class was generated from the following files: