diff --git a/src/libslic3r/libslic3r.h b/src/libslic3r/libslic3r.h index 4dbe46d3c..c3f220098 100644 --- a/src/libslic3r/libslic3r.h +++ b/src/libslic3r/libslic3r.h @@ -74,7 +74,8 @@ static constexpr double INSET_OVERLAP_TOLERANCE = 0.4; //FIXME This is quite a lot. static constexpr double EXTERNAL_INFILL_MARGIN = 3; static constexpr double BRIDGE_INFILL_MARGIN = 1; -static constexpr double WIPE_TOWER_MARGIN = 15.; +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) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 11fea8c27..c5cde2e8b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3188,11 +3188,12 @@ 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 + wipe_tower_size(0) > plate_bbox_x_max_local_coord) { - x = plate_bbox_x_max_local_coord - wipe_tower_size(0) - margin; + 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; @@ -3204,8 +3205,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re need_update = false; } - if (y + margin + wipe_tower_size(1) > plate_bbox_y_max_local_coord) { - y = plate_bbox_y_max_local_coord - wipe_tower_size(1) - margin; + 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; @@ -3223,7 +3224,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (volume_idx_wipe_tower_old != -1) map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new; } } else { - const float margin = 2.f; auto tower_bottom = current_print->wipe_tower_data().wipe_tower_mesh_data->bottom; tower_bottom.translate(scaled(Vec2d{x, y})); tower_bottom.translate(scaled(Vec2d{plate_origin[0], plate_origin[1]})); diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 205ceb276..c126db6f9 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -1232,7 +1232,7 @@ std::vector PartPlate::get_extruders_under_cli(bool conside_custom_gcode, D bool PartPlate::check_objects_empty_and_gcode3mf(std::vector &result) const { if (m_model->objects.empty()) {//objects is empty - if (wxGetApp().plater()->is_gcode_3mf()) { // if gcode.3mf file + if (wxGetApp().plater() && wxGetApp().plater()->is_gcode_3mf()) { // if gcode.3mf file for (int i = 0; i < slice_filaments_info.size(); i++) { result.push_back(slice_filaments_info[i].id + 1); } @@ -3192,11 +3192,6 @@ void PartPlateList::init() m_plate_cols = 1; m_current_plate = 0; - if (m_plater) { - // In GUI mode - set_default_wipe_tower_pos_for_plate(0); - } - select_plate(0); unprintable_plate.set_index(1); @@ -3753,7 +3748,7 @@ void PartPlateList::release_icon_textures() } } -void PartPlateList::set_default_wipe_tower_pos_for_plate(int plate_idx) +void PartPlateList::set_default_wipe_tower_pos_for_plate(int plate_idx, bool init_pos) { DynamicConfig & proj_cfg = wxGetApp().preset_bundle->project_config; ConfigOptionFloats *wipe_tower_x = proj_cfg.opt("wipe_tower_x"); @@ -3763,12 +3758,56 @@ void PartPlateList::set_default_wipe_tower_pos_for_plate(int plate_idx) auto printer_structure_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option>("printer_structure"); // set the default position, the same with print config(left top) - ConfigOptionFloat wt_x_opt(WIPE_TOWER_DEFAULT_X_POS); - ConfigOptionFloat wt_y_opt(WIPE_TOWER_DEFAULT_Y_POS); + float x = WIPE_TOWER_DEFAULT_X_POS; + float y = WIPE_TOWER_DEFAULT_Y_POS; if (printer_structure_opt && printer_structure_opt->value == PrinterStructure::psI3) { - wt_x_opt = ConfigOptionFloat(I3_WIPE_TOWER_DEFAULT_X_POS); - wt_y_opt = ConfigOptionFloat(I3_WIPE_TOWER_DEFAULT_Y_POS); + x = I3_WIPE_TOWER_DEFAULT_X_POS; + y = I3_WIPE_TOWER_DEFAULT_Y_POS; } + + const float margin = 15; // old WIPE_TOWER_MARGIN, keep the same value + PartPlate* part_plate = get_plate(plate_idx); + Vec3d plate_origin = part_plate->get_origin(); + BoundingBoxf3 plate_bbox = part_plate->get_bounding_box(); + BoundingBoxf plate_bbox_2d(Vec2d(plate_bbox.min(0), plate_bbox.min(1)), Vec2d(plate_bbox.max(0), plate_bbox.max(1))); + const std::vector &extruder_areas = part_plate->get_extruder_areas(); + for (Pointfs points : extruder_areas) { + BoundingBoxf bboxf(points); + plate_bbox_2d.min = plate_bbox_2d.min(0) >= bboxf.min(0) ? plate_bbox_2d.min : bboxf.min; + plate_bbox_2d.max = plate_bbox_2d.max(0) <= bboxf.max(0) ? plate_bbox_2d.max : bboxf.max; + } + + coordf_t plate_bbox_x_min_local_coord = plate_bbox_2d.min(0) - plate_origin(0); + 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); + + std::vector filament_maps = part_plate->get_real_filament_maps(proj_cfg); + DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(false, filament_maps); + const DynamicPrintConfig &print_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config; + float w = dynamic_cast(print_cfg.option("prime_tower_width"))->value; + std::vector v = dynamic_cast(full_config.option("filament_prime_volume"))->values; + int nozzle_nums = wxGetApp().preset_bundle->get_printer_extruder_count(); + double wipe_vol = get_max_element(v); + Vec3d wipe_tower_size = part_plate->estimate_wipe_tower_size(print_cfg, w, wipe_vol, nozzle_nums, init_pos ? 2 : 0); + // update for wipe tower position + { + bool need_update = false; + if (x + margin + wipe_tower_size(0) > plate_bbox_x_max_local_coord) { + x = plate_bbox_x_max_local_coord - wipe_tower_size(0) - margin; + } else if (x < margin + plate_bbox_x_min_local_coord) { + x = margin + plate_bbox_x_min_local_coord; + } + + if (y + margin + wipe_tower_size(1) > plate_bbox_y_max_local_coord) { + y = plate_bbox_y_max_local_coord - wipe_tower_size(1) - margin; + } else if (y < margin) { + y = margin; + } + } + + ConfigOptionFloat wt_x_opt(x); + ConfigOptionFloat wt_y_opt(y); + dynamic_cast(proj_cfg.option("wipe_tower_x"))->set_at(&wt_x_opt, plate_idx, 0); dynamic_cast(proj_cfg.option("wipe_tower_y"))->set_at(&wt_y_opt, plate_idx, 0); } @@ -3879,6 +3918,11 @@ void PartPlateList::reinit() //re-calc the bounding boxes calc_bounding_boxes(); + if (m_plater) { + // In GUI mode + set_default_wipe_tower_pos_for_plate(0, true); + } + return; } @@ -3947,7 +3991,7 @@ int PartPlateList::create_plate(bool adjust_position) // update wipe tower config if (m_plater) { // In GUI mode - set_default_wipe_tower_pos_for_plate(new_index); + set_default_wipe_tower_pos_for_plate(new_index, true); } unprintable_plate.set_index(new_index+1); @@ -4341,11 +4385,6 @@ void PartPlateList::update_all_plates_pos_and_size(bool adjust_position, bool wi //compute origin1 for PartPlate origin1 = compute_origin(i, m_plate_cols); plate->set_pos_and_size(origin1, m_plate_width, m_plate_depth, m_plate_height, adjust_position, do_clear); - - // set default wipe pos when switch plate - if (switch_plate_type && m_plater/* && plate->get_used_extruders().size() <= 0*/) { - set_default_wipe_tower_pos_for_plate(i); - } } origin2 = compute_origin_for_unprintable(); diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index e8af6fbf9..bbf4ab586 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -603,8 +603,6 @@ class PartPlateList : public ObjectBase void generate_icon_textures(); void release_icon_textures(); - void set_default_wipe_tower_pos_for_plate(int plate_idx); - friend class cereal::access; friend class UndoRedo::StackImpl; friend class PartPlate; @@ -763,6 +761,7 @@ public: std::vector get_nonempty_plate_list(); std::vector get_nonempty_plates_slice_results(); + void set_default_wipe_tower_pos_for_plate(int plate_idx, bool init_pos = false); //compute the origin for printable plate with index i Vec3d get_current_plate_origin() { return compute_origin(m_current_plate, m_plate_cols); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9db510d74..125afcf0d 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -9826,8 +9826,14 @@ void Plater::priv::update_objects_position_when_select_preset(const std::functio wxGetApp().obj_list()->update_object_list_by_printer_technology(); - // BBS:Model reset by plate center + // set default wipe tower pos PartPlateList &cur_plate_list = this->partplate_list; + for (size_t plate_id = 0; plate_id < cur_plate_list.get_plate_list().size(); ++plate_id) { + cur_plate_list.set_default_wipe_tower_pos_for_plate(plate_id); + } + update(); + + // BBS:Model reset by plate center PartPlate *cur_plate = cur_plate_list.get_curr_plate(); Vec3d cur_plate_pos = cur_plate->get_center_origin(); Vec3d cur_plate_size = cur_plate->get_bounding_box().size(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 65554f1ef..7af4fedef 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1213,13 +1213,14 @@ void Selection::translate(const Vec3d &displacement, TransformationType transfor Vec3d tower_size = v.bounding_box().size(); Vec3d tower_origin = m_cache.volumes_data[i].get_volume_position(); Vec3d actual_displacement = displacement; - const double margin = wxGetApp().plater()->get_partplate_list().get_plate(plate_idx)->fff_print()->is_step_done(psWipeTower)?2.:WIPE_TOWER_MARGIN; + 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; 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 = v.bounding_box(); + 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)); 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));