FIX: limit the wipe tower to common areas for multi_extruder

jira: none
Change-Id: I58d061904610a5e33679e7254721bc43dcc22e64
This commit is contained in:
zhimin.zeng 2024-09-06 15:36:33 +08:00 committed by lane.wei
parent f39eabfd9f
commit 64f471c2cc
2 changed files with 120 additions and 29 deletions

View File

@ -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<ConfigOptionFloats *>(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<Pointfs>& 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<ConfigOptionFloats *>(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<ConfigOptionFloats *>(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<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(

View File

@ -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<Pointfs>& 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;