mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-09-22 05:53:14 +08:00
NEW: auto arrange after bed size changes
1. auto arrange after bed size changes When the bed size changes from big to small, auto arrange items outside beds, while keeping the inside ones still. This action can be undoed with ctrl+z. 2. Fix the issue that double clicking the orient button of plate causes a never disappearing busy cursor. jira: STUDIO-7978 Change-Id: I5ee1f73b80735777c21438a01cbc4649d8cce3fa (cherry picked from commit f67fd877ea7b07148dc9539938ba319a4f960d0e)
This commit is contained in:
parent
d1d60d0af2
commit
45386c862f
@ -6409,7 +6409,7 @@ bool GLCanvas3D::_init_main_toolbar()
|
|||||||
item.tooltip = _utf8(L("Auto orient"));
|
item.tooltip = _utf8(L("Auto orient"));
|
||||||
item.sprite_id++;
|
item.sprite_id++;
|
||||||
item.left.render_callback = nullptr;
|
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
|
item.left.toggable = false; // allow right mouse click
|
||||||
//BBS: GUI refactor: adjust the main toolbar position
|
//BBS: GUI refactor: adjust the main toolbar position
|
||||||
item.left.action_callback = [this]() {
|
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));
|
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;
|
item.left.toggable = true;
|
||||||
//BBS: GUI refactor: adjust the main toolbar position
|
//BBS: GUI refactor: adjust the main toolbar position
|
||||||
item.left.render_callback = [this](float left, float right, float bottom, float top) {
|
item.left.render_callback = [this](float left, float right, float bottom, float top) {
|
||||||
|
@ -93,6 +93,7 @@ void ArrangeJob::clear_input()
|
|||||||
m_locked.clear();
|
m_locked.clear();
|
||||||
m_unarranged.clear();
|
m_unarranged.clear();
|
||||||
m_uncompatible_plates.clear();
|
m_uncompatible_plates.clear();
|
||||||
|
is_plate_locked.clear();
|
||||||
m_selected.reserve(count + 1 /* for optional wti */);
|
m_selected.reserve(count + 1 /* for optional wti */);
|
||||||
m_unselected.reserve(count + 1 /* for optional wti */);
|
m_unselected.reserve(count + 1 /* for optional wti */);
|
||||||
m_unprintable.reserve(cunprint /* 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);
|
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
|
//BBS: add partplate logic
|
||||||
void ArrangeJob::prepare()
|
void ArrangeJob::prepare()
|
||||||
{
|
{
|
||||||
@ -449,6 +490,9 @@ void ArrangeJob::prepare()
|
|||||||
else if (state == Job::JobPrepareState::PREPARE_STATE_MENU) {
|
else if (state == Job::JobPrepareState::PREPARE_STATE_MENU) {
|
||||||
only_on_partplate = true; // only arrange items on current plate
|
only_on_partplate = true; // only arrange items on current plate
|
||||||
prepare_partplate();
|
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."));
|
NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Arranging canceled."));
|
||||||
}
|
}
|
||||||
Job::finalize();
|
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);
|
m_plater->m_arrange_running.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ class ArrangeJob : public PlaterJob
|
|||||||
std::vector<ModelInstance*> m_unarranged;
|
std::vector<ModelInstance*> m_unarranged;
|
||||||
std::map<int, ArrangePolygons> m_selected_groups; // groups of selected items for sequential printing
|
std::map<int, ArrangePolygons> m_selected_groups; // groups of selected items for sequential printing
|
||||||
std::vector<int> m_uncompatible_plates; // plate indices with different printing sequence than global
|
std::vector<int> m_uncompatible_plates; // plate indices with different printing sequence than global
|
||||||
|
std::vector<bool> is_plate_locked;
|
||||||
|
|
||||||
arrangement::ArrangeParams params;
|
arrangement::ArrangeParams params;
|
||||||
int current_plate_index = 0;
|
int current_plate_index = 0;
|
||||||
@ -38,6 +39,10 @@ class ArrangeJob : public PlaterJob
|
|||||||
|
|
||||||
//BBS:prepare the items from current selected partplate
|
//BBS:prepare the items from current selected partplate
|
||||||
void prepare_partplate();
|
void prepare_partplate();
|
||||||
|
|
||||||
|
// prepare the items which are selected and not on the current partplate
|
||||||
|
void prepare_outside_plate();
|
||||||
|
|
||||||
void prepare_wipe_tower();
|
void prepare_wipe_tower();
|
||||||
|
|
||||||
ArrangePolygon prepare_arrange_polygon(void* instance);
|
ArrangePolygon prepare_arrange_polygon(void* instance);
|
||||||
|
@ -71,7 +71,8 @@ protected:
|
|||||||
public:
|
public:
|
||||||
enum JobPrepareState {
|
enum JobPrepareState {
|
||||||
PREPARE_STATE_DEFAULT = 0,
|
PREPARE_STATE_DEFAULT = 0,
|
||||||
PREPARE_STATE_MENU = 1,
|
PREPARE_STATE_MENU = 1,
|
||||||
|
PREPARE_STATE_OUTSIDE_BED = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
Job(std::shared_ptr<ProgressIndicator> pri);
|
Job(std::shared_ptr<ProgressIndicator> pri);
|
||||||
|
@ -280,6 +280,7 @@ public:
|
|||||||
Vec2d get_size() const { return Vec2d(m_width, m_depth); }
|
Vec2d get_size() const { return Vec2d(m_width, m_depth); }
|
||||||
ModelObjectPtrs get_objects() { return m_model->objects; }
|
ModelObjectPtrs get_objects() { return m_model->objects; }
|
||||||
ModelObjectPtrs get_objects_on_this_plate();
|
ModelObjectPtrs get_objects_on_this_plate();
|
||||||
|
std::set<std::pair<int, int>>& get_obj_and_inst_set() { return obj_to_instance_set; }
|
||||||
ModelInstance* get_instance(int obj_id, int instance_id);
|
ModelInstance* get_instance(int obj_id, int instance_id);
|
||||||
BoundingBoxf3 get_objects_bounding_box();
|
BoundingBoxf3 get_objects_bounding_box();
|
||||||
|
|
||||||
|
@ -2618,7 +2618,7 @@ struct Plater::priv
|
|||||||
bool can_decrease_instances() const;
|
bool can_decrease_instances() const;
|
||||||
bool can_split_to_objects() const;
|
bool can_split_to_objects() const;
|
||||||
bool can_split_to_volumes() const;
|
bool can_split_to_volumes() const;
|
||||||
bool can_arrange() const;
|
bool can_do_ui_job() const;
|
||||||
bool can_layers_editing() const;
|
bool can_layers_editing() const;
|
||||||
bool can_fix_through_netfabb() const;
|
bool can_fix_through_netfabb() const;
|
||||||
bool can_simplify() const;
|
bool can_simplify() const;
|
||||||
@ -6484,6 +6484,10 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt)
|
|||||||
view3D->center_selected_plate(i);
|
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();
|
view3D->deselect_all();
|
||||||
}
|
}
|
||||||
#if 0 // do not toggle auto calc when change printer
|
#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);
|
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();
|
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))
|
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
|
//arrange the plate
|
||||||
//take_snapshot("select_orient partplate");
|
//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))
|
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
|
//arrange the plate
|
||||||
//take_snapshot("select_arrange partplate");
|
//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_simplify() const { return p->can_simplify(); }
|
||||||
bool Plater::can_split_to_objects() const { return p->can_split_to_objects(); }
|
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_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_layers_editing() const { return p->can_layers_editing(); }
|
||||||
bool Plater::can_paste_from_clipboard() const
|
bool Plater::can_paste_from_clipboard() const
|
||||||
{
|
{
|
||||||
|
@ -513,7 +513,7 @@ public:
|
|||||||
bool can_simplify() const;
|
bool can_simplify() const;
|
||||||
bool can_split_to_objects() const;
|
bool can_split_to_objects() const;
|
||||||
bool can_split_to_volumes() const;
|
bool can_split_to_volumes() const;
|
||||||
bool can_arrange() const;
|
bool can_do_ui_job() const;
|
||||||
//BBS
|
//BBS
|
||||||
bool can_cut_to_clipboard() const;
|
bool can_cut_to_clipboard() const;
|
||||||
bool can_layers_editing() const;
|
bool can_layers_editing() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user