Fix wipe tower loaded outside of plate boundaries (#12191)

* Add checks to snap wipe tower back to origin when it was loaded outside the plate boundary

* Fix Wipe Tower preview outside plate boundary and warning notification

- snaps wipe tower preview to nearest edge if it was loaded outside of plate boundary.
- Added warning notification to notify position change
This commit is contained in:
Derrick
2026-02-09 22:25:41 +08:00
committed by GitHub
parent 9604b01656
commit e14e186bb7
2 changed files with 31 additions and 5 deletions

View File

@@ -38,6 +38,7 @@
#include "slic3r/Utils/UndoRedo.hpp"
#include "slic3r/Utils/MacDarkMode.hpp"
#include <libslic3r/BoundingBox.hpp>
#include <slic3r/GUI/GUI_Utils.hpp>
#if ENABLE_RETINA_GL
@@ -2831,6 +2832,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
float y = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_y"))->get_at(plate_id);
float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("prime_tower_width"))->value;
float a = dynamic_cast<const ConfigOptionFloat*>(proj_cfg.option("wipe_tower_rotation_angle"))->value;
// BBS
float v = dynamic_cast<const ConfigOptionFloat*>(m_config->option("prime_volume"))->value;
Vec3d plate_origin = ppl.get_plate(plate_id)->get_origin();
@@ -2857,9 +2859,29 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
}
coordf_t plate_bbox_x_min_local_coord = plate_bbox_2d.min(0) - plate_origin(0);
coordf_t plate_bbox_y_min_local_coord = plate_bbox_2d.min(1) - plate_origin(1);
coordf_t plate_bbox_x_max_local_coord = plate_bbox_2d.max(0) - plate_origin(0);
coordf_t plate_bbox_y_max_local_coord = plate_bbox_2d.max(1) - plate_origin(1);
const float tower_w = (float) wipe_tower_size(0);
const float tower_h = (float) wipe_tower_size(1);
const float min_x = (float) plate_bbox_x_min_local_coord + margin;
const float max_x = (float) plate_bbox_x_max_local_coord - margin;
const float min_y = (float) plate_bbox_y_min_local_coord + margin;
const float max_y = (float) plate_bbox_y_max_local_coord - margin;
// snap wipe tower back to nearest edge if it was initially loaded outside the plate boundary
float new_x = (x < min_x) ? min_x : ((x + tower_w > max_x) ? (max_x - tower_w) : x);
float new_y = (y < min_y) ? min_y : ((y + tower_h > max_y) ? (max_y - tower_h) : y);
if (new_x != x || new_y != y) {
// do notification
_set_warning_notification(EWarning::PreviewPrimeTowerOutside, true);
x = new_x;
y = new_y;
}
if (!current_print->is_step_done(psWipeTower) || !current_print->wipe_tower_data().wipe_tower_mesh_data) {
// update for wipe tower position
{
@@ -9625,6 +9647,9 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
case EWarning::PrimeTowerOutside:
text = _u8L("The prime tower extends beyond the plate boundary.");
break;
case EWarning::PreviewPrimeTowerOutside:
text = _u8L("Prime tower position exceeded build plate boundaries and was repositioned to the nearest valid edge.");
break;
case EWarning::NozzleFilamentIncompatible: {
text = _u8L(get_nozzle_filament_incompatible_text());
break;

View File

@@ -381,13 +381,14 @@ class GLCanvas3D
ToolHeightOutside,
TPUPrintableError,
FilamentPrintableError,
LeftExtruderPrintableError, // before slice
RightExtruderPrintableError, // before slice
MultiExtruderPrintableError, // after slice
MultiExtruderHeightOutside, // after slice
LeftExtruderPrintableError, // before slice
RightExtruderPrintableError, // before slice
MultiExtruderPrintableError, // after slice
MultiExtruderHeightOutside, // after slice
FilamentUnPrintableOnFirstLayer,
MixUsePLAAndPETG,
PrimeTowerOutside,
PrimeTowerOutside, // after slice
PreviewPrimeTowerOutside, // before slice
NozzleFilamentIncompatible,
MixtureFilamentIncompatible,
FlushingVolumeZero