mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-07 01:57:38 +00:00
Fix: correct axis-remap G-code emission and belt first-layer travel speed (B2, B3)
- BeltGCodeWriter::travel_to_xyz final branch used config.travel_speed instead of the computed first-layer-aware travel_speed. - extrude_to_xyz decided emit_xyz vs emit_xy from pre-remap Z; emit full XYZ whenever an axis remap is active so remapped machine-Z is never dropped. - base travel_to_xyz now applies apply_axis_remap() on all emitted destinations (standalone remap on non-belt printers was unremapped). - spiral/arc travels fall back to normal linear lift under active remap (endpoint-only remap can't preserve arc plane/I-J). - set_axis_remap() is now synced unconditionally each export to avoid a reused writer retaining a stale non-identity mapping.
This commit is contained in:
@@ -264,7 +264,9 @@ std::string BeltGCodeWriter::travel_to_xyz(const Vec3d &point, const std::string
|
||||
// Belt mode: always emit full XYZ
|
||||
GCodeG1Formatter w;
|
||||
w.emit_xyz(point_on_plate);
|
||||
w.emit_f(this->config.travel_speed.get_at(m_cached_extruder_idx) * 60.0);
|
||||
// Use the first-layer-aware travel_speed computed at the top of this function,
|
||||
// not the raw config travel_speed, so initial-layer travels are correctly slowed.
|
||||
w.emit_f(travel_speed * 60.0);
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
|
||||
m_pos = dest_point;
|
||||
|
||||
@@ -2952,16 +2952,18 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
this->init_belt_writer(print, is_bbl_printers);
|
||||
|
||||
// Standalone axis remap (works with or without belt mode).
|
||||
// Sync the writer's remap state to the current export UNCONDITIONALLY — even at
|
||||
// the identity mapping (0,1,2) — so a reused writer never retains a stale
|
||||
// non-identity mapping from a prior export. has_axis_remap() returns false at
|
||||
// identity, so identity/default output stays unchanged.
|
||||
{
|
||||
int rx = int(print.config().gcode_remap_x.value);
|
||||
int ry = int(print.config().gcode_remap_y.value);
|
||||
int rz = int(print.config().gcode_remap_z.value);
|
||||
if (rx != 0 || ry != 1 || rz != 2) {
|
||||
m_writer->set_axis_remap(rx, ry, rz);
|
||||
BoundingBoxf bbox_bed(print.config().printable_area.values);
|
||||
m_writer->set_build_volume_max(Vec3d(bbox_bed.max.x(), bbox_bed.max.y(),
|
||||
print.config().printable_height.value));
|
||||
}
|
||||
m_writer->set_axis_remap(rx, ry, rz);
|
||||
BoundingBoxf bbox_bed(print.config().printable_area.values);
|
||||
m_writer->set_build_volume_max(Vec3d(bbox_bed.max.x(), bbox_bed.max.y(),
|
||||
print.config().printable_height.value));
|
||||
}
|
||||
|
||||
// Build the FirstLayerPlane evaluator. When inactive (non-belt printers
|
||||
|
||||
@@ -936,7 +936,10 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
Vec2d temp = delta_no_z.normalized() * delta(2) / tan(this->filament()->travel_slope());
|
||||
Vec3d slope_top_point = Vec3d(temp(0), temp(1), delta(2)) + source;
|
||||
GCodeG1Formatter w0;
|
||||
w0.emit_xyz(slope_top_point);
|
||||
// A slope lift is a straight (linear) diagonal move, so remapping its
|
||||
// endpoint is exact. Route the destination through apply_axis_remap()
|
||||
// when a remap is active (no-op at identity).
|
||||
w0.emit_xyz(has_axis_remap() ? apply_axis_remap(slope_top_point) : slope_top_point);
|
||||
w0.emit_f(travel_speed * 60.0);
|
||||
//BBS
|
||||
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
@@ -950,7 +953,14 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
std::string xy_z_move;
|
||||
{
|
||||
GCodeG1Formatter w0;
|
||||
if (this->is_current_position_clear()) {
|
||||
if (has_axis_remap()) {
|
||||
// Remap may couple XY with Z; emit full XYZ in machine coordinates.
|
||||
w0.emit_xyz(apply_axis_remap(target));
|
||||
w0.emit_f(travel_speed * 60.0);
|
||||
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
xy_z_move = w0.string();
|
||||
}
|
||||
else if (this->is_current_position_clear()) {
|
||||
w0.emit_xyz(target);
|
||||
w0.emit_f(travel_speed * 60.0);
|
||||
w0.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
@@ -988,7 +998,13 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
Vec3d point_on_plate = { dest_point(0) - m_x_offset, dest_point(1) - m_y_offset, dest_point(2) };
|
||||
std::string out_string;
|
||||
GCodeG1Formatter w;
|
||||
if (!this->is_current_position_clear())
|
||||
if (has_axis_remap()) {
|
||||
// Remap may couple XY with Z; emit full XYZ in machine coordinates.
|
||||
w.emit_xyz(apply_axis_remap(point_on_plate));
|
||||
w.emit_f(this->config.travel_speed.get_at(m_cached_extruder_idx) * 60.0);
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
out_string = w.string();
|
||||
} else if (!this->is_current_position_clear())
|
||||
{
|
||||
//force to move xy first then z after filament change
|
||||
w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y()));
|
||||
@@ -1053,6 +1069,14 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
|
||||
|
||||
std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment)
|
||||
{
|
||||
// A circular XY arc / spiral lift cannot be correctly axis-remapped by
|
||||
// transforming only its endpoint: the arc plane (G17/XY) and the I-J center
|
||||
// would change under the remap. When an axis remap is active, fall back to a
|
||||
// plain linear lift instead of emitting a possibly-wrong spiral/arc. This
|
||||
// single guard covers every spiral call site (lazy/eager lift and travel_to_xyz).
|
||||
if (has_axis_remap())
|
||||
return _travel_to_z(z, comment);
|
||||
|
||||
std::string output;
|
||||
double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx);
|
||||
|
||||
@@ -1199,14 +1223,19 @@ std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std
|
||||
//BBS: take plate offset into consider
|
||||
Vec3d point_on_plate = { point(0) - m_x_offset, point(1) - m_y_offset, point(2) };
|
||||
|
||||
if (has_axis_remap())
|
||||
point_on_plate = apply_axis_remap(point_on_plate);
|
||||
|
||||
GCodeG1Formatter w;
|
||||
if (z_changed)
|
||||
if (has_axis_remap()) {
|
||||
// z_changed was computed from the ORIGINAL slicing Z, but an axis remap can
|
||||
// make machine-Z depend on slicing X/Y. An X/Y-only move (slicing-Z
|
||||
// unchanged) would then drop the required machine-Z word, so always emit
|
||||
// full XYZ whenever a remap is active.
|
||||
point_on_plate = apply_axis_remap(point_on_plate);
|
||||
w.emit_xyz(point_on_plate);
|
||||
else
|
||||
} else if (z_changed) {
|
||||
w.emit_xyz(point_on_plate);
|
||||
} else {
|
||||
w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y()));
|
||||
}
|
||||
if (!force_no_extrusion)
|
||||
w.emit_e(filament()->E());
|
||||
//BBS
|
||||
|
||||
Reference in New Issue
Block a user