mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2026-03-21 02:42:16 -06:00
Fix wipe tower placed outside bed boundary on first slice (#12777)
Some checks are pending
Build all / build_linux (push) Waiting to run
Build all / build_windows (push) Waiting to run
Build all / build_macos_arch (arm64) (push) Waiting to run
Build all / build_macos_arch (x86_64) (push) Waiting to run
Build all / Build macOS Universal (push) Blocked by required conditions
Build all / Unit Tests (push) Blocked by required conditions
Build all / Flatpak (push) Waiting to run
Some checks are pending
Build all / build_linux (push) Waiting to run
Build all / build_windows (push) Waiting to run
Build all / build_macos_arch (arm64) (push) Waiting to run
Build all / build_macos_arch (x86_64) (push) Waiting to run
Build all / Build macOS Universal (push) Blocked by required conditions
Build all / Unit Tests (push) Blocked by required conditions
Build all / Flatpak (push) Waiting to run
# Description The wipe tower config position (wipe_tower_x/y) could be outside the plate boundary (e.g. default y=250 on a 200mm printer). No constraint was applied at slice time, so the tower was generated out-of-bounds. issue reported in #12731 # Screenshots/Recordings/Graphs <!-- > Please attach relevant screenshots to showcase the UI changes. > Please attach images that can help explain the changes. --> ## Tests <!-- > Please describe the tests that you have conducted to verify the changes made in this PR. -->
This commit is contained in:
commit
494601eea5
2 changed files with 22 additions and 1 deletions
|
|
@ -2835,6 +2835,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
DynamicPrintConfig& proj_cfg = wxGetApp().preset_bundle->project_config;
|
||||
float x = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_x"))->get_at(plate_id);
|
||||
float y = dynamic_cast<const ConfigOptionFloats*>(proj_cfg.option("wipe_tower_y"))->get_at(plate_id);
|
||||
// Helper: persist corrected wipe tower position to config so the next slice uses valid coords.
|
||||
auto persist_wipe_tower_pos = [&](float nx, float ny) {
|
||||
ConfigOptionFloat cx(nx), cy(ny);
|
||||
proj_cfg.option<ConfigOptionFloats>("wipe_tower_x")->set_at(&cx, plate_id, 0);
|
||||
proj_cfg.option<ConfigOptionFloats>("wipe_tower_y")->set_at(&cy, plate_id, 0);
|
||||
};
|
||||
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;
|
||||
|
||||
|
|
@ -2884,6 +2890,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
_set_warning_notification(EWarning::PreviewPrimeTowerOutside, true);
|
||||
x = new_x;
|
||||
y = new_y;
|
||||
// Persist the correction to config so the next slice uses the valid position
|
||||
persist_wipe_tower_pos(new_x, new_y);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2906,7 +2914,13 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
BoundingBoxf3 plate_bbox = wxGetApp().plater()->get_partplate_list().get_plate(plate_id)->get_build_volume(true);
|
||||
BoundingBox plate_bbox2d = BoundingBox(scaled(Vec2f(plate_bbox.min[0], plate_bbox.min[1])), scaled(Vec2f(plate_bbox.max[0], plate_bbox.max[1])));
|
||||
Vec2f offset = WipeTower::move_box_inside_box(tower_bottom_bbox, plate_bbox2d, scaled(margin));
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_real_wipe_tower_preview(1000 + plate_id, x + plate_origin(0), y + plate_origin(1),
|
||||
// move_box_inside_box returns mm (already unscaled); apply directly.
|
||||
// If the actual brim polygon is outside bounds, persist the correction to config.
|
||||
float display_x = x + offset[0];
|
||||
float display_y = y + offset[1];
|
||||
if (offset.norm() > float(EPSILON))
|
||||
persist_wipe_tower_pos(display_x, display_y);
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_real_wipe_tower_preview(1000 + plate_id, display_x + plate_origin(0), display_y + plate_origin(1),
|
||||
current_print->wipe_tower_data().wipe_tower_mesh_data->real_wipe_tower_mesh,
|
||||
current_print->wipe_tower_data().wipe_tower_mesh_data->real_brim_mesh,
|
||||
true,a,/*!print->is_step_done(psWipeTower)*/ true, m_initialized);
|
||||
|
|
|
|||
|
|
@ -4074,6 +4074,13 @@ void PartPlateList::set_default_wipe_tower_pos_for_plate(int plate_idx)
|
|||
wt_x_opt = ConfigOptionFloat(I3_WIPE_TOWER_DEFAULT_X_POS);
|
||||
wt_y_opt = ConfigOptionFloat(I3_WIPE_TOWER_DEFAULT_Y_POS);
|
||||
}
|
||||
// Clamp default position to fit within the actual plate dimensions so the wipe tower
|
||||
// doesn't start outside the bed for printers smaller than the hardcoded defaults.
|
||||
const double wt_default_margin = 2.;
|
||||
const double wt_estimated_width = 60.; // conservative estimate matching prime_tower_width default
|
||||
const double wt_estimated_depth = 20.; // conservative depth estimate
|
||||
wt_x_opt.value = std::max(wt_default_margin, std::min(wt_x_opt.value, m_plate_width - wt_estimated_width - wt_default_margin));
|
||||
wt_y_opt.value = std::max(wt_default_margin, std::min(wt_y_opt.value, m_plate_depth - wt_estimated_depth - wt_default_margin));
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_x"))->set_at(&wt_x_opt, plate_idx, 0);
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_y"))->set_at(&wt_y_opt, plate_idx, 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue