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(); m_filament_extruders.clear();
//ORCA: Reset current extruder ID and clear pointers to prevent dangling pointers when extruders are recreated. //ORCA: Reset current extruder ID and clear pointers to prevent dangling pointers when extruders are recreated.
m_curr_extruder_id = -1; m_curr_extruder_id = -1;
m_cached_extruder_idx = 0;
std::fill(m_curr_filament_extruder.begin(), m_curr_filament_extruder.end(), nullptr); std::fill(m_curr_filament_extruder.begin(), m_curr_filament_extruder.end(), nullptr);
m_filament_extruders.reserve(extruder_ids.size()); m_filament_extruders.reserve(extruder_ids.size());
for (unsigned int extruder_id : extruder_ids) 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); 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_extruder_id = filament_extruder_iter->extruder_id();
m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter; 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 // return the toolchange command
// if we are running a single-extruder setup, just set the extruder and return nothing // 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; GCodeG1Formatter w;
w.emit_xy(point_on_plate); w.emit_xy(point_on_plate);
auto speed = m_is_first_layer 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); w.emit_f(speed * 60.0);
//BBS //BBS
w.emit_comment(GCodeWriter::full_gcode_comment, comment); 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 // BBS
Vec3d dest_point = point; Vec3d dest_point = point;
auto travel_speed = 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 //BBS: a z_hop need to be handle when travel
if (std::abs(m_to_lift) > EPSILON) { if (std::abs(m_to_lift) > EPSILON) {
assert(std::abs(m_lifted) < 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 //force to move xy first then z after filament change
w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y())); 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); w.emit_comment(GCodeWriter::full_gcode_comment, comment);
out_string = w.string() + _travel_to_z(point_on_plate.z(), comment); out_string = w.string() + _travel_to_z(point_on_plate.z(), comment);
} else { } else {
GCodeG1Formatter w; GCodeG1Formatter w;
w.emit_xyz(point_on_plate); 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); w.emit_comment(GCodeWriter::full_gcode_comment, comment);
out_string = w.string(); out_string = w.string();
} }
@@ -880,10 +882,10 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
{ {
m_pos(2) = z; 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.) { 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())) 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(get_extruder_index(this->config, filament()->id())); : this->config.travel_speed.get_at(m_cached_extruder_idx);
} }
GCodeG1Formatter w; 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 GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment)
{ {
std::string output; 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.) { 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())) 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(get_extruder_index(this->config, filament()->id())); : 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 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); 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_extruder_id = filament_extruder_iter->extruder_id();
m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter; 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() : GCodeWriter() :
multiple_extruders(false), m_curr_filament_extruder(MAXIMUM_EXTRUDER_NUMBER, nullptr), multiple_extruders(false), m_curr_filament_extruder(MAXIMUM_EXTRUDER_NUMBER, nullptr),
m_curr_extruder_id (-1), m_curr_extruder_id (-1),
m_cached_extruder_idx(0),
m_single_extruder_multi_material(false), 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_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), 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; bool m_single_extruder_multi_material;
std::vector<Extruder*> m_curr_filament_extruder; std::vector<Extruder*> m_curr_filament_extruder;
int m_curr_extruder_id; 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_acceleration;
unsigned int m_last_travel_acceleration; unsigned int m_last_travel_acceleration;
std::vector<unsigned int> m_max_travel_acceleration; std::vector<unsigned int> m_max_travel_acceleration;