GCode: hold the writer by value again

Belt printing turned GCode::m_writer into a unique_ptr so BeltGCode could
swap in a freshly built writer carrying the belt kinematics. Nothing
subclasses GCodeWriter: the machine mapping lives in its MachineKinematics,
which set_kinematics() installs on an existing writer. A GCode is built for
every export and the only state on the writer when init_belt_writer() runs
is the plate offset, which the swap had to copy across by hand.

Install the belt kinematics on the writer in place, drop the copied offset,
and drop the virtual markers on GCodeWriter that the old subclass needed.
Every m_writer-> in GCode.cpp goes back to m_writer., which is most of the
belt diff in that file and most of its conflicts with main.

The pressure-advance pattern keeps its shared_ptr writer: the unique_ptr
kinematics make GCodeWriter move-only and that class must stay copyable.
This commit is contained in:
harrierpigeon
2026-10-04 19:16:59 -05:00
parent b22384a559
commit ee88b3f0b0
4 changed files with 251 additions and 258 deletions
+2 -6
View File
@@ -8,14 +8,10 @@ namespace Slic3r {
void BeltGCode::init_belt_writer(Print &print)
{
auto belt_writer = std::make_unique<GCodeWriter>();
// Axis remap and build volume max are set by base GCode after init_belt_writer
// returns; set_kinematics() replays them, so install order does not matter.
install_belt_kinematics(*belt_writer, print.config());
belt_writer->set_force_normal_lift(true);
// The plate origin was stored on the writer this one replaces.
belt_writer->set_xy_offset(m_gcode_offset.x(), m_gcode_offset.y());
m_writer = std::move(belt_writer);
install_belt_kinematics(m_writer, print.config());
m_writer.set_force_normal_lift(true);
}
void BeltGCode::write_belt_header(GCodeOutputStream &file, const Print &print)
+235 -235
View File
File diff suppressed because it is too large Load Diff
+7 -9
View File
@@ -218,8 +218,7 @@ public:
m_last_obj_copy(nullptr, Point(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max())),
// BBS
m_toolchange_count(0),
m_nominal_z(0.),
m_writer(std::make_unique<GCodeWriter>())
m_nominal_z(0.)
{}
virtual ~GCode() = default;
@@ -229,7 +228,7 @@ public:
void do_export(Print* print, const char* path, GCodeProcessorResult* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr);
void export_layer_filaments(GCodeProcessorResult* result);
//BBS: set offset for gcode writer
void set_gcode_offset(double x, double y) { m_gcode_offset = Vec2d(x, y); m_writer->set_xy_offset(x, y); m_processor.set_xy_offset(x, y);}
void set_gcode_offset(double x, double y) { m_writer.set_xy_offset(x, y); m_processor.set_xy_offset(x, y);}
// Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests.
const Vec2d& origin() const { return m_origin; }
@@ -243,8 +242,8 @@ public:
Vec3d point_to_gcode_quantized(const Point3& point) const;
const FullPrintConfig &config() const { return m_config; }
const Layer* layer() const { return m_layer; }
GCodeWriter& writer() { return *m_writer; }
const GCodeWriter& writer() const { return *m_writer; }
GCodeWriter& writer() { return m_writer; }
const GCodeWriter& writer() const { return m_writer; }
PlaceholderParser& placeholder_parser() { return m_placeholder_parser_integration.parser; }
const PlaceholderParser& placeholder_parser() const { return m_placeholder_parser_integration.parser; }
// Process a template through the placeholder parser, collect error messages to be reported
@@ -267,7 +266,7 @@ public:
bool needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type);
std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::NormalLift, bool apply_instantly = false, ExtrusionRole role = erNone);
// extra_retract forwards a PETG pre-extrusion over-extrusion; default 0 -> identical to the plain deretract.
std::string unretract(float extra_retract = 0.f) { return m_writer->unlift() + m_writer->unretract(extra_retract); }
std::string unretract(float extra_retract = 0.f) { return m_writer.unlift() + m_writer.unretract(extra_retract); }
std::string set_extruder(unsigned int extruder_id, double print_z, bool by_object=false, int toolchange_temp_override = -1, bool defer_temp_wait = false);
bool is_BBL_Printer();
WipeTowerType wipe_tower_type();
@@ -384,7 +383,7 @@ protected:
// represent a G2/G3 arc. Belt printers get this through BeltKinematics
// rather than through an override of their own.
virtual bool should_disable_arc_fitting() const
{ return ! m_writer->kinematics().supports_arc_moves(); }
{ return ! m_writer.kinematics().supports_arc_moves(); }
void _do_export(Print &print, GCodeOutputStream &file, ThumbnailsGeneratorCallback thumbnail_cb);
@@ -660,7 +659,7 @@ protected:
DynamicConfig m_calib_config;
// scaled G-code resolution
double m_scaled_resolution;
std::unique_ptr<GCodeWriter> m_writer;
GCodeWriter m_writer;
struct PlaceholderParserIntegration {
void reset();
@@ -786,7 +785,6 @@ protected:
// checks short-circuit to the legacy Layer::id() == 0 path.
std::unique_ptr<FirstLayerPlane> m_first_layer_plane;
// Plate origin, kept so a writer replaced during export can be given it again.
Vec2d m_gcode_offset{ Vec2d::Zero() };
std::unique_ptr<PressureEqualizer> m_pressure_equalizer;
+7 -8
View File
@@ -17,7 +17,6 @@ class FirstLayerPlane;
class GCodeWriter {
public:
virtual ~GCodeWriter() = default;
GCodeConfig config;
bool multiple_extruders;
@@ -84,27 +83,27 @@ public:
std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string());
// SoftFever NOTE: the returned speed is mm/minute
double get_current_speed() const { return m_current_speed;}
virtual std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string());
virtual std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string(), bool force_z = false);
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::string travel_to_z(double z, const std::string &comment = std::string(), bool force = false);
bool will_move_z(double z) const;
virtual std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false);
std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false);
//BBS: generate G2 or G3 extrude which moves by arc
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);
// Linear approximation of an arc, used when the machine mapping cannot
// express a G2/G3. Must be called before m_pos is updated: center_offset is
// relative to the current position.
std::string extrude_arc_as_polyline(const Vec2d &point, const Vec2d &center_offset, double dE, const bool is_ccw, const std::string &comment = std::string(), bool force_no_extrusion = false);
virtual std::string extrude_to_xyz(const Vec3d &point, double dE, 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);
std::string retract(bool before_wipe = false, double retract_length = 0);
std::string retract_for_toolchange(bool before_wipe = false, double retract_length = 0);
// extra_retract adds a small over-extrusion to the deretract move (PETG pre-extrusion).
// Default 0 -> byte-identical to the plain deretract.
std::string unretract(float extra_retract = 0.f);
// do lift instantly
virtual std::string eager_lift(const LiftType type);
std::string eager_lift(const LiftType type);
// record a lift request, do realy lift in next travel
virtual std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
std::string lazy_lift(LiftType lift_type = LiftType::NormalLift, bool spiral_vase = false);
std::string unlift();
const Vec3d& get_position() const { return m_pos; }
Vec3d& get_position() { return m_pos; }
@@ -184,7 +183,7 @@ protected:
bool m_is_current_pos_clear = false;
double m_current_speed;
virtual std::string _travel_to_z(double z, const std::string &comment);
std::string _travel_to_z(double z, const std::string &comment);
// Whether a destination gets first-layer treatment. With an active plane
// evaluator, distance from the plane decides; otherwise the layer-coarse