mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-08-05 16:50:37 +08:00
FIX: modify the behavior of wipe tower
The prime tower is not allowed to extend beyond the plate boundary when moving it. jira: STUDIO-11817 & STUDIO-12313 Change-Id: Icbb85dad26531b0ac01f088fc086b4ff499ac423
This commit is contained in:
parent
8a22fab6d7
commit
8f4d5f44d7
@ -75,7 +75,6 @@ static constexpr double INSET_OVERLAP_TOLERANCE = 0.4;
|
||||
static constexpr double EXTERNAL_INFILL_MARGIN = 3;
|
||||
static constexpr double BRIDGE_INFILL_MARGIN = 1;
|
||||
static constexpr double WIPE_TOWER_MARGIN = 0.2;
|
||||
static constexpr double MIN_WIPE_TOWER_SIZE = 5;
|
||||
//FIXME Better to use an inline function with an explicit return type.
|
||||
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
|
||||
#define scale_(val) ((val) / SCALING_FACTOR)
|
||||
|
@ -3198,34 +3198,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
coordf_t plate_bbox_y_max_local_coord = plate_bbox_2d.max(1) - plate_origin(1);
|
||||
|
||||
if (!current_print->is_step_done(psWipeTower) || !current_print->wipe_tower_data().wipe_tower_mesh_data) {
|
||||
Vec2d min_wipe_tower_size(MIN_WIPE_TOWER_SIZE, MIN_WIPE_TOWER_SIZE);
|
||||
// update for wipe tower position
|
||||
{
|
||||
bool need_update = false;
|
||||
if (x + margin + min_wipe_tower_size(0) > plate_bbox_x_max_local_coord) {
|
||||
x = plate_bbox_x_max_local_coord - min_wipe_tower_size(0) - margin;
|
||||
need_update = true;
|
||||
} else if (x < margin + plate_bbox_x_min_local_coord) {
|
||||
x = margin + plate_bbox_x_min_local_coord;
|
||||
need_update = true;
|
||||
}
|
||||
if (need_update) {
|
||||
ConfigOptionFloat wt_x_opt(x);
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_x"))->set_at(&wt_x_opt, plate_id, 0);
|
||||
need_update = false;
|
||||
}
|
||||
|
||||
if (y + margin + min_wipe_tower_size(1) > plate_bbox_y_max_local_coord) {
|
||||
y = plate_bbox_y_max_local_coord - min_wipe_tower_size(1) - margin;
|
||||
need_update = true;
|
||||
} else if (y < margin) {
|
||||
y = margin;
|
||||
need_update = true;
|
||||
}
|
||||
if (need_update) {
|
||||
ConfigOptionFloat wt_y_opt(y);
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_y"))->set_at(&wt_y_opt, plate_id, 0);
|
||||
}
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(1000 + plate_id, x + plate_origin(0), y + plate_origin(1),
|
||||
(float) wipe_tower_size(0), (float) wipe_tower_size(1), (float) wipe_tower_size(2),
|
||||
a,
|
||||
@ -3241,15 +3215,7 @@ 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));
|
||||
if (!is_approx(offset[0], 0.f)) {
|
||||
ConfigOptionFloat wt_x_opt(x + offset[0]);
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_x"))->set_at(&wt_x_opt, plate_id, 0);
|
||||
}
|
||||
if (!is_approx(offset[1], 0.f)) {
|
||||
ConfigOptionFloat wt_y_opt(y + offset[1]);
|
||||
dynamic_cast<ConfigOptionFloats *>(proj_cfg.option("wipe_tower_y"))->set_at(&wt_y_opt, plate_id, 0);
|
||||
}
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_real_wipe_tower_preview(1000 + plate_id, x + plate_origin(0) + offset[0], y + plate_origin(1) + offset[1],
|
||||
int volume_idx_wipe_tower_new = m_volumes.load_real_wipe_tower_preview(1000 + plate_id, x + plate_origin(0), 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);
|
||||
@ -3284,10 +3250,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
|
||||
//BBS:exclude the assmble view
|
||||
if (m_canvas_type != ECanvasType::CanvasAssembleView) {
|
||||
_set_warning_notification_if_needed(EWarning::GCodeConflict);
|
||||
_set_warning_notification(EWarning::FilamentUnPrintableOnFirstLayer, false);
|
||||
_set_warning_notification_if_needed(EWarning::MultiExtruderPrintableError);
|
||||
_set_warning_notification_if_needed(EWarning::MultiExtruderHeightOutside);
|
||||
_update_slice_error_status();
|
||||
// checks for geometry outside the print volume to render it accordingly
|
||||
if (!m_volumes.empty()) {
|
||||
ModelInstanceEPrintVolumeState state;
|
||||
@ -3297,8 +3260,10 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
const bool fullyOut = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Fully_Outside);
|
||||
// const bool objectLimited = (state == ModelInstanceEPrintVolumeState::ModelInstancePVS_Limited);
|
||||
|
||||
bool show_read_wipe_tower = wxGetApp().plater()->get_partplate_list().get_selected_plate()->fff_print()->is_step_done(psWipeTower);
|
||||
bool wipe_tower_outside = m_volumes.check_wipe_tower_outside_state(m_bed.build_volume());
|
||||
_set_warning_notification(EWarning::PrimeTowerOutside, !wipe_tower_outside);
|
||||
bool show_wipe_tower_outside_error = show_read_wipe_tower ? !wipe_tower_outside : false;
|
||||
_set_warning_notification(EWarning::PrimeTowerOutside, show_wipe_tower_outside_error);
|
||||
|
||||
auto clash_flag = construct_error_string(object_results, get_object_clashed_text());
|
||||
auto unprintable_flag= construct_extruder_unprintable_error(object_results, get_left_extruder_unprintable_text(), get_right_extruder_unprintable_text());
|
||||
@ -3322,7 +3287,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
||||
bool mix_pla_and_petg = cur_plate->check_mixture_of_pla_and_petg(wxGetApp().preset_bundle->full_config());
|
||||
_set_warning_notification(EWarning::MixUsePLAAndPETG, !mix_pla_and_petg);
|
||||
|
||||
bool model_fits = contained_min_one && !m_model->objects.empty() && !partlyOut && object_results.filaments.empty() && tpu_valid && filament_printable;
|
||||
bool model_fits = contained_min_one && !m_model->objects.empty() && !partlyOut && object_results.filaments.empty() && tpu_valid && filament_printable && !show_wipe_tower_outside_error;
|
||||
post_event(Event<bool>(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, model_fits));
|
||||
ppl.get_curr_plate()->update_slice_ready_status(model_fits);
|
||||
}
|
||||
@ -3450,13 +3415,7 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, co
|
||||
|
||||
if (wxGetApp().is_editor()) {
|
||||
//BBS: always load shell at preview, do this in load_shells
|
||||
//m_gcode_viewer.update_shells_color_by_extruder(m_config);
|
||||
_set_warning_notification_if_needed(EWarning::ToolHeightOutside);
|
||||
_set_warning_notification_if_needed(EWarning::ToolpathOutside);
|
||||
_set_warning_notification_if_needed(EWarning::GCodeConflict);
|
||||
_set_warning_notification_if_needed(EWarning::MultiExtruderPrintableError);
|
||||
_set_warning_notification_if_needed(EWarning::MultiExtruderHeightOutside);
|
||||
_set_warning_notification_if_needed(EWarning::FilamentUnPrintableOnFirstLayer);
|
||||
_update_slice_error_status();
|
||||
}
|
||||
|
||||
m_gcode_viewer.refresh(gcode_result, str_tool_colors);
|
||||
@ -6529,6 +6488,16 @@ void GLCanvas3D::render_thumbnail_framebuffer(const std::shared_ptr<OpenGLManage
|
||||
|
||||
//BBS: GUI refractor
|
||||
|
||||
void GLCanvas3D::_update_slice_error_status()
|
||||
{
|
||||
_set_warning_notification_if_needed(EWarning::ToolHeightOutside);
|
||||
_set_warning_notification_if_needed(EWarning::ToolpathOutside);
|
||||
_set_warning_notification_if_needed(EWarning::GCodeConflict);
|
||||
_set_warning_notification_if_needed(EWarning::MultiExtruderPrintableError);
|
||||
_set_warning_notification_if_needed(EWarning::MultiExtruderHeightOutside);
|
||||
_set_warning_notification_if_needed(EWarning::FilamentUnPrintableOnFirstLayer);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_switch_toolbars_icon_filename()
|
||||
{
|
||||
BackgroundTexture::Metadata background_data;
|
||||
@ -10868,7 +10837,8 @@ void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
||||
text = _u8L("PLA and PETG filaments detected in the mixture. Adjust parameters according to the Wiki to ensure print quality.");
|
||||
break;
|
||||
case EWarning::PrimeTowerOutside:
|
||||
text = _u8L("The prime tower extends beyond the plate boundary, which may cause part of the prime tower to lie outside the printable area after slicing.");
|
||||
text = _u8L("The prime tower extends beyond the plate boundary.");
|
||||
error = ErrorType::SLICING_ERROR;
|
||||
break;
|
||||
case EWarning::AsemblyInvalid:
|
||||
{
|
||||
|
@ -1181,6 +1181,8 @@ public:
|
||||
private:
|
||||
bool _is_shown_on_screen() const;
|
||||
|
||||
void _update_slice_error_status();
|
||||
|
||||
void _switch_toolbars_icon_filename();
|
||||
bool _init_toolbars();
|
||||
bool _init_main_toolbar();
|
||||
|
@ -1214,13 +1214,15 @@ void Selection::translate(const Vec3d &displacement, TransformationType transfor
|
||||
Vec3d tower_origin = m_cache.volumes_data[i].get_volume_position();
|
||||
Vec3d actual_displacement = displacement;
|
||||
bool show_read_wipe_tower = wxGetApp().plater()->get_partplate_list().get_plate(plate_idx)->fff_print()->is_step_done(psWipeTower);
|
||||
const double margin = WIPE_TOWER_MARGIN;
|
||||
float brim_width = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("prime_tower_brim_width");
|
||||
|
||||
const double margin = show_read_wipe_tower ? WIPE_TOWER_MARGIN : brim_width + 0.5; // 0.5 is the line width of wipe tower
|
||||
|
||||
actual_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() *
|
||||
m_cache.volumes_data[i].get_instance_mirror_matrix())
|
||||
.inverse() *
|
||||
displacement;
|
||||
BoundingBoxf3 tower_bbox = show_read_wipe_tower ? v.bounding_box() : BoundingBoxf3(Vec3d(0, 0, 0), Vec3d(MIN_WIPE_TOWER_SIZE, MIN_WIPE_TOWER_SIZE, MIN_WIPE_TOWER_SIZE));
|
||||
BoundingBoxf3 tower_bbox = v.bounding_box();
|
||||
tower_bbox.translate(actual_displacement + tower_origin);
|
||||
BoundingBox tower_bbox2d = BoundingBox(scaled(Vec2f(tower_bbox.min[0], tower_bbox.min[1])), scaled(Vec2f(tower_bbox.max[0], tower_bbox.max[1])));
|
||||
Vec2f offset = WipeTower::move_box_inside_box(tower_bbox2d, plate_bbox2d,scaled(margin));
|
||||
|
Loading…
x
Reference in New Issue
Block a user