Fix access violation during travel generation before initial tool selection (#14725)

This commit is contained in:
Kiss Lorand
2026-07-12 19:30:29 +03:00
committed by GitHub
parent 7e2047aa30
commit 3ae7bd04fa
2 changed files with 16 additions and 10 deletions

View File

@@ -110,6 +110,7 @@ void GCodeWriter::set_extruders(std::vector<unsigned int> extruder_ids)
m_filament_extruders.clear();
//ORCA: Reset current extruder ID and clear pointers to prevent dangling pointers when extruders are recreated.
m_curr_extruder_id = -1;
m_cached_extruder_idx = 0;
std::fill(m_curr_filament_extruder.begin(), m_curr_filament_extruder.end(), nullptr);
m_filament_extruders.reserve(extruder_ids.size());
for (unsigned int extruder_id : extruder_ids)
@@ -617,6 +618,7 @@ std::string GCodeWriter::toolchange(unsigned int filament_id)
assert(filament_extruder_iter != m_filament_extruders.end() && filament_extruder_iter->id() == filament_id);
m_curr_extruder_id = filament_extruder_iter->extruder_id();
m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter;
m_cached_extruder_idx = get_extruder_index(this->config, filament_id);
// return the toolchange command
// if we are running a single-extruder setup, just set the extruder and return nothing
@@ -658,7 +660,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
GCodeG1Formatter w;
w.emit_xy(point_on_plate);
auto speed = m_is_first_layer
? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) : this->config.travel_speed.get_at(m_cached_extruder_idx);
w.emit_f(speed * 60.0);
//BBS
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
@@ -744,7 +746,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
// BBS
Vec3d dest_point = point;
auto travel_speed =
m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) : this->config.travel_speed.get_at(m_cached_extruder_idx);
//BBS: a z_hop need to be handle when travel
if (std::abs(m_to_lift) > EPSILON) {
assert(std::abs(m_lifted) < EPSILON);
@@ -841,13 +843,13 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
{
//force to move xy first then z after filament change
w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y()));
w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0);
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() + _travel_to_z(point_on_plate.z(), comment);
} else {
GCodeG1Formatter w;
w.emit_xyz(point_on_plate);
w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0);
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();
}
@@ -880,10 +882,10 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
{
m_pos(2) = z;
double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id()));
double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx);
if (speed == 0.) {
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id()))
: this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx)
: this->config.travel_speed.get_at(m_cached_extruder_idx);
}
GCodeG1Formatter w;
@@ -897,11 +899,11 @@ 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)
{
std::string output;
double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id()));
double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx);
if (speed == 0.) {
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id()))
: this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx)
: this->config.travel_speed.get_at(m_cached_extruder_idx);
}
if (!this->config.enable_arc_fitting) { // Orca: if arc fitting is disabled, approximate the arc with small linear segments
@@ -1261,6 +1263,7 @@ void GCodeWriter::init_extruder(unsigned int filament_id)
assert(filament_extruder_iter != m_filament_extruders.end() && filament_extruder_iter->id() == filament_id);
m_curr_extruder_id = filament_extruder_iter->extruder_id();
m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter;
m_cached_extruder_idx = get_extruder_index(this->config, filament_id);
}
}

View File

@@ -19,6 +19,7 @@ public:
GCodeWriter() :
multiple_extruders(false), m_curr_filament_extruder(MAXIMUM_EXTRUDER_NUMBER, nullptr),
m_curr_extruder_id (-1),
m_cached_extruder_idx(0),
m_single_extruder_multi_material(false),
m_last_acceleration(0), m_max_acceleration(0),m_last_travel_acceleration(0), m_max_travel_acceleration(0),
m_last_jerk(0), m_max_jerk_x(0), m_max_jerk_y(0),
@@ -135,6 +136,8 @@ public:
bool m_single_extruder_multi_material;
std::vector<Extruder*> m_curr_filament_extruder;
int m_curr_extruder_id;
// Motion uses the global/base process variant until a filament becomes active.
size_t m_cached_extruder_idx;
unsigned int m_last_acceleration;
unsigned int m_last_travel_acceleration;
std::vector<unsigned int> m_max_travel_acceleration;