diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index dd3601883..717b0780c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -6409,7 +6409,7 @@ bool GLCanvas3D::_init_main_toolbar() item.tooltip = _utf8(L("Auto orient")); item.sprite_id++; item.left.render_callback = nullptr; - item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_do_ui_job(); }; item.left.toggable = false; // allow right mouse click //BBS: GUI refactor: adjust the main toolbar position item.left.action_callback = [this]() { @@ -6436,7 +6436,7 @@ bool GLCanvas3D::_init_main_toolbar() if (agent) agent->track_update_property("auto_arrange", std::to_string(++auto_arrange_count)); } }; - item.enabling_callback = []()->bool { return wxGetApp().plater()->can_arrange(); }; + item.enabling_callback = []()->bool { return wxGetApp().plater()->can_do_ui_job(); }; item.left.toggable = true; //BBS: GUI refactor: adjust the main toolbar position item.left.render_callback = [this](float left, float right, float bottom, float top) { diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 615b883d6..062416eed 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -93,6 +93,7 @@ void ArrangeJob::clear_input() m_locked.clear(); m_unarranged.clear(); m_uncompatible_plates.clear(); + is_plate_locked.clear(); m_selected.reserve(count + 1 /* for optional wti */); m_unselected.reserve(count + 1 /* for optional wti */); m_unprintable.reserve(cunprint /* for optional wti */); @@ -423,6 +424,46 @@ void ArrangeJob::prepare_partplate() { plate_list.preprocess_exclude_areas(m_unselected, current_plate_index + 1); } +void ArrangeJob::prepare_outside_plate() { + clear_input(); + + Model &model = m_plater->model(); + PartPlateList &plate_list = m_plater->get_partplate_list(); + is_plate_locked.resize(plate_list.get_plate_count()); + for (int plate_idx = 0; plate_idx < plate_list.get_plate_count(); plate_idx++) { + PartPlate *plate = plate_list.get_plate(plate_idx); + assert(plate != nullptr); + if (plate->empty()) { + // no instances on this plate + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << format(": no instances in plate %d!", plate_idx); + continue; + } + + is_plate_locked[plate_idx] = plate->is_locked(); + plate->lock(true); + + // Go through the objects and select the outside ones + for (auto obj_and_inst : plate->get_obj_and_inst_set()) { + int oidx = obj_and_inst.first; + size_t inst_idx = obj_and_inst.second; + ModelObject *mo = model.objects[oidx]; + bool outside_plate = plate->check_outside(oidx, inst_idx); + ArrangePolygon &&ap = prepare_arrange_polygon(mo->instances[inst_idx]); + ArrangePolygons &cont = mo->instances[inst_idx]->printable ? (outside_plate ? m_selected : m_locked) : m_unprintable; + ap.itemid = cont.size(); + cont.emplace_back(std::move(ap)); + } + } + // BBS + if (auto wti = get_wipe_tower(*m_plater, current_plate_index)) { + ArrangePolygon &&ap = get_wipetower_arrange_poly(&wti); + m_unselected.emplace_back(std::move(ap)); + } + + // add the virtual object into unselect list if has + plate_list.preprocess_exclude_areas(m_unselected, current_plate_index + 1); +} + //BBS: add partplate logic void ArrangeJob::prepare() { @@ -449,6 +490,9 @@ void ArrangeJob::prepare() else if (state == Job::JobPrepareState::PREPARE_STATE_MENU) { only_on_partplate = true; // only arrange items on current plate prepare_partplate(); + } else if (state == Job::JobPrepareState::PREPARE_STATE_OUTSIDE_BED) { + only_on_partplate = false; + prepare_outside_plate(); } @@ -730,6 +774,11 @@ void ArrangeJob::finalize() { NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Arranging canceled.")); } Job::finalize(); + + // restore lock status + for (int i = 0; i < is_plate_locked.size(); i++) + m_plater->get_partplate_list().get_plate(i)->lock(is_plate_locked[i]); + m_plater->m_arrange_running.store(false); } diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.hpp b/src/slic3r/GUI/Jobs/ArrangeJob.hpp index 7df2d344f..933606e1f 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.hpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.hpp @@ -22,6 +22,7 @@ class ArrangeJob : public PlaterJob std::vector m_unarranged; std::map m_selected_groups; // groups of selected items for sequential printing std::vector m_uncompatible_plates; // plate indices with different printing sequence than global + std::vector is_plate_locked; arrangement::ArrangeParams params; int current_plate_index = 0; @@ -38,6 +39,10 @@ class ArrangeJob : public PlaterJob //BBS:prepare the items from current selected partplate void prepare_partplate(); + + // prepare the items which are selected and not on the current partplate + void prepare_outside_plate(); + void prepare_wipe_tower(); ArrangePolygon prepare_arrange_polygon(void* instance); diff --git a/src/slic3r/GUI/Jobs/Job.hpp b/src/slic3r/GUI/Jobs/Job.hpp index a92dfbfbd..005a80787 100644 --- a/src/slic3r/GUI/Jobs/Job.hpp +++ b/src/slic3r/GUI/Jobs/Job.hpp @@ -71,7 +71,8 @@ protected: public: enum JobPrepareState { PREPARE_STATE_DEFAULT = 0, - PREPARE_STATE_MENU = 1, + PREPARE_STATE_MENU = 1, + PREPARE_STATE_OUTSIDE_BED = 2, }; Job(std::shared_ptr pri); diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index 216f9dac6..7d1405241 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -280,6 +280,7 @@ public: Vec2d get_size() const { return Vec2d(m_width, m_depth); } ModelObjectPtrs get_objects() { return m_model->objects; } ModelObjectPtrs get_objects_on_this_plate(); + std::set>& get_obj_and_inst_set() { return obj_to_instance_set; } ModelInstance* get_instance(int obj_id, int instance_id); BoundingBoxf3 get_objects_bounding_box(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cd1876cfe..cdfdda7cd 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2618,7 +2618,7 @@ struct Plater::priv bool can_decrease_instances() const; bool can_split_to_objects() const; bool can_split_to_volumes() const; - bool can_arrange() const; + bool can_do_ui_job() const; bool can_layers_editing() const; bool can_fix_through_netfabb() const; bool can_simplify() const; @@ -6484,6 +6484,10 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) view3D->center_selected_plate(i); } + take_snapshot("Arrange after bed size changes"); + q->set_prepare_state(Job::PREPARE_STATE_OUTSIDE_BED); + q->arrange(); + view3D->deselect_all(); } #if 0 // do not toggle auto calc when change printer @@ -8063,7 +8067,7 @@ bool Plater::priv::can_split_to_volumes() const return (printer_technology != ptSLA) && q->can_split(false); } -bool Plater::priv::can_arrange() const +bool Plater::priv::can_do_ui_job() const { return !model.objects.empty() && !m_ui_jobs.is_any_running() && !q->is_background_process_slicing(); } @@ -13474,7 +13478,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi } else if ((action == 2)&&(!right_click)) { - if (!p->partplate_list.get_plate(plate_index)->get_objects().empty() && !is_background_process_slicing()) + if (p->can_do_ui_job()) { //arrange the plate //take_snapshot("select_orient partplate"); @@ -13493,7 +13497,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi } else if ((action == 3)&&(!right_click)) { - if (!p->partplate_list.get_plate(plate_index)->get_objects().empty() && !is_background_process_slicing()) + if (p->can_do_ui_job()) { //arrange the plate //take_snapshot("select_arrange partplate"); @@ -13893,7 +13897,7 @@ bool Plater::can_fix_through_netfabb() const { return p->can_fix_through_netfabb bool Plater::can_simplify() const { return p->can_simplify(); } bool Plater::can_split_to_objects() const { return p->can_split_to_objects(); } bool Plater::can_split_to_volumes() const { return p->can_split_to_volumes(); } -bool Plater::can_arrange() const { return p->can_arrange(); } +bool Plater::can_do_ui_job() const { return p->can_do_ui_job(); } bool Plater::can_layers_editing() const { return p->can_layers_editing(); } bool Plater::can_paste_from_clipboard() const { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index f56bc6272..0874fa003 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -513,7 +513,7 @@ public: bool can_simplify() const; bool can_split_to_objects() const; bool can_split_to_volumes() const; - bool can_arrange() const; + bool can_do_ui_job() const; //BBS bool can_cut_to_clipboard() const; bool can_layers_editing() const;