From 64f471c2cceb9c08ff8b5f6af10ca95771ccaf57 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 6 Sep 2024 15:36:33 +0800 Subject: [PATCH] FIX: limit the wipe tower to common areas for multi_extruder jira: none Change-Id: I58d061904610a5e33679e7254721bc43dcc22e64 --- src/slic3r/GUI/GLCanvas3D.cpp | 68 ++++++++++++++++------------- src/slic3r/GUI/Selection.cpp | 81 +++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index afda07b04..7151f9f72 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2745,36 +2745,46 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re const DynamicPrintConfig &print_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config; Vec3d wipe_tower_size = ppl.get_plate(plate_id)->estimate_wipe_tower_size(print_cfg, w, v); - const float margin = WIPE_TOWER_MARGIN; - BoundingBoxf3 plate_bbox = wxGetApp().plater()->get_partplate_list().get_plate(plate_id)->get_bounding_box(); - coordf_t plate_bbox_x_max_local_coord = plate_bbox.max(0) - plate_origin(0); - coordf_t plate_bbox_y_max_local_coord = plate_bbox.max(1) - plate_origin(1); - 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; - need_update = true; - } - else if (x < margin) { - x = margin; - need_update = true; - } - if (need_update) { - ConfigOptionFloat wt_x_opt(x); - dynamic_cast(proj_cfg.option("wipe_tower_x"))->set_at(&wt_x_opt, plate_id, 0); - need_update = false; - } + { // update for wipe tower position + part_plate->get_extruder_areas(); + const float margin = WIPE_TOWER_MARGIN; + 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; + } - 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; - need_update = true; - } - else if (y < margin) { - y = margin; - need_update = true; - } - if (need_update) { - ConfigOptionFloat wt_y_opt(y); - dynamic_cast(proj_cfg.option("wipe_tower_y"))->set_at(&wt_y_opt, plate_id, 0); + 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); + 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; + 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(proj_cfg.option("wipe_tower_x"))->set_at(&wt_x_opt, plate_id, 0); + 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; + need_update = true; + } else if (y < margin) { + y = margin; + need_update = true; + } + if (need_update) { + ConfigOptionFloat wt_y_opt(y); + dynamic_cast(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( diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index f93677a99..72d692aec 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1177,6 +1177,87 @@ void Selection::setup_cache() set_caches(); } +void Selection::translate(const Vec3d &displacement, bool local) +{ + if (!m_valid) + return; + + EMode translation_type = m_mode; + //BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": %1%, displacement {%2%, %3%, %4%}") % __LINE__ % displacement(X) % displacement(Y) % displacement(Z); + + for (unsigned int i : m_list) { + GLVolume& v = *(*m_volumes)[i]; + if (v.is_wipe_tower) { + int plate_idx = v.object_idx() - 1000; + + PartPlate* part_plate = wxGetApp().plater()->get_partplate_list().get_plate(plate_idx); + 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; + } + + 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 = WIPE_TOWER_MARGIN; + + if (!local) + 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; + + if (tower_origin(0) + actual_displacement(0) - margin < plate_bbox_2d.min(0)) { + actual_displacement(0) = plate_bbox_2d.min(0) - tower_origin(0) + margin; + } + else if (tower_origin(0) + actual_displacement(0) + tower_size(0) + margin > plate_bbox_2d.max(0)) { + actual_displacement(0) = plate_bbox_2d.max(0) - tower_origin(0) - tower_size(0) - margin; + } + + if (tower_origin(1) + actual_displacement(1) - margin < plate_bbox_2d.min(1)) { + actual_displacement(1) = plate_bbox_2d.min(1) - tower_origin(1) + margin; + } + else if (tower_origin(1) + actual_displacement(1) + tower_size(1) + margin > plate_bbox_2d.max(1)) { + actual_displacement(1) = plate_bbox_2d.max(1) - tower_origin(1) - tower_size(1) - margin; + } + + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + actual_displacement); + } + else if (m_mode == Volume || v.is_wipe_tower) { + if (local) + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + displacement); + else { + const Vec3d local_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; + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); + } + } + else if (m_mode == Instance) { + if (is_from_fully_selected_instance(i)) + v.set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement); + else { + const Vec3d local_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; + v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement); + translation_type = Volume; + } + } + } + +#if !DISABLE_INSTANCES_SYNCH + if (translation_type == Instance) + synchronize_unselected_instances(SYNC_ROTATION_NONE); + else if (translation_type == Volume) + synchronize_unselected_volumes(); +#endif // !DISABLE_INSTANCES_SYNCH + if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) { + ensure_not_below_bed(); + } + set_bounding_boxes_dirty(); + if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) { + wxGetApp().plater()->canvas3D()->requires_check_outside_state(); + } +} + void Selection::translate(const Vec3d &displacement, TransformationType transformation_type) { if (!m_valid) return;