Skip to content

Commit

Permalink
Implemented FR #6994 - Set Number of Instances for multiple selected …
Browse files Browse the repository at this point in the history
…meshes
  • Loading branch information
YuSanka committed Feb 13, 2023
1 parent b71e0bf commit 4d5b85e
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 30 deletions.
8 changes: 7 additions & 1 deletion src/slic3r/GUI/GUI_Factories.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1218,9 +1218,15 @@ wxMenu* MenuFactory::multi_selection_menu()
append_menu_item_merge_to_multipart_object(menu);
if (extruders_count() > 1)
append_menu_item_change_extruder(menu);
if (list_model()->GetItemType(sels[0]) != itVolume)
if (list_model()->GetItemType(sels[0]) != itVolume) {
append_menu_item_printable(menu);

if (wxGetApp().get_mode() != comSimple)
append_menu_item(menu, wxID_ANY, _L("Set number of instances") + dots, _L("Change the number of instances of the selected objects"),
[](wxCommandEvent&) { plater()->set_number_of_copies(); }, "number_of_copies", nullptr,
[]() { return plater()->can_increase_instances(); }, m_parent);
}

return menu;
}

Expand Down
53 changes: 28 additions & 25 deletions src/slic3r/GUI/Plater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1941,7 +1941,7 @@ struct Plater::priv
bool can_delete() const;
bool can_delete_all() const;
bool can_increase_instances() const;
bool can_decrease_instances() const;
bool can_decrease_instances(int obj_idx = -1) const;
bool can_split_to_objects() const;
bool can_split_to_volumes() const;
bool can_arrange() const;
Expand Down Expand Up @@ -5004,18 +5004,18 @@ bool Plater::priv::can_increase_instances() const
// Prevent strobo effect during editing emboss parameters.
if (q->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::Emboss) return false;

const int obj_idx = get_selected_object_idx();
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) &&
!sidebar->obj_list()->has_selected_cut_object();
const auto obj_idxs = get_selection().get_object_idxs();
return !obj_idxs.empty() && !sidebar->obj_list()->has_selected_cut_object();
}

bool Plater::priv::can_decrease_instances() const
bool Plater::priv::can_decrease_instances(int obj_idx /*= -1*/) const
{
if (!m_worker.is_idle()
|| q->canvas3D()->get_gizmos_manager().is_in_editing_mode())
return false;

const int obj_idx = get_selected_object_idx();
if (obj_idx < 0)
obj_idx = get_selected_object_idx();
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) &&
(model.objects[obj_idx]->instances.size() > 1) &&
!sidebar->obj_list()->has_selected_cut_object();
Expand Down Expand Up @@ -6273,13 +6273,14 @@ void Plater::remove_selected()
p->view3D->delete_selected();
}

void Plater::increase_instances(size_t num)
void Plater::increase_instances(size_t num, int obj_idx/* = -1*/)
{
if (! can_increase_instances()) { return; }

Plater::TakeSnapshot snapshot(this, _L("Increase Instances"));

int obj_idx = p->get_selected_object_idx();
if (obj_idx < 0)
obj_idx = p->get_selected_object_idx();

ModelObject* model_object = p->model.objects[obj_idx];
ModelInstance* model_instance = model_object->instances.back();
Expand Down Expand Up @@ -6307,13 +6308,14 @@ void Plater::increase_instances(size_t num)
this->p->schedule_background_process();
}

void Plater::decrease_instances(size_t num)
void Plater::decrease_instances(size_t num, int obj_idx/* = -1*/)
{
if (! can_decrease_instances()) { return; }
if (! can_decrease_instances(obj_idx)) { return; }

Plater::TakeSnapshot snapshot(this, _L("Decrease Instances"));

int obj_idx = p->get_selected_object_idx();
if (obj_idx < 0)
obj_idx = p->get_selected_object_idx();

ModelObject* model_object = p->model.objects[obj_idx];
if (model_object->instances.size() > num) {
Expand Down Expand Up @@ -6354,26 +6356,27 @@ static long GetNumberFromUser( const wxString& msg,
#endif
}

void Plater::set_number_of_copies(/*size_t num*/)
void Plater::set_number_of_copies()
{
int obj_idx = p->get_selected_object_idx();
if (obj_idx == -1)
const auto obj_idxs = get_selection().get_object_idxs();
if (obj_idxs.empty())
return;

ModelObject* model_object = p->model.objects[obj_idx];

const size_t init_cnt = obj_idxs.size() == 1 ? p->model.objects[*obj_idxs.begin()]->instances.size() : 1;
const int num = GetNumberFromUser( " ", _L("Enter the number of copies:"),
_L("Copies of the selected object"), model_object->instances.size(), 0, 1000, this );
_L("Copies of the selected object"), init_cnt, 0, 1000, this );
if (num < 0)
return;
TakeSnapshot snapshot(this, wxString::Format(_L("Set numbers of copies to %d"), num));

Plater::TakeSnapshot snapshot(this, wxString::Format(_L("Set numbers of copies to %d"), num));

int diff = num - (int)model_object->instances.size();
if (diff > 0)
increase_instances(diff);
else if (diff < 0)
decrease_instances(-diff);
for (const auto obj_idx : obj_idxs) {
ModelObject* model_object = p->model.objects[obj_idx];
const int diff = num - (int)model_object->instances.size();
if (diff > 0)
increase_instances(diff, int(obj_idx));
else if (diff < 0)
decrease_instances(-diff, int(obj_idx));
}
}

void Plater::fill_bed_with_instances()
Expand Down Expand Up @@ -7665,7 +7668,7 @@ void Plater::init_notification_manager()
bool Plater::can_delete() const { return p->can_delete(); }
bool Plater::can_delete_all() const { return p->can_delete_all(); }
bool Plater::can_increase_instances() const { return p->can_increase_instances(); }
bool Plater::can_decrease_instances() const { return p->can_decrease_instances(); }
bool Plater::can_decrease_instances(int obj_idx/* = -1*/) const { return p->can_decrease_instances(obj_idx); }
bool Plater::can_set_instance_to_object() const { return p->can_set_instance_to_object(); }
bool Plater::can_fix_through_netfabb() const { return p->can_fix_through_netfabb(); }
bool Plater::can_simplify() const { return p->can_simplify(); }
Expand Down
8 changes: 4 additions & 4 deletions src/slic3r/GUI/Plater.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,9 @@ class Plater: public wxPanel
void reset_with_confirm();
bool delete_object_from_model(size_t obj_idx);
void remove_selected();
void increase_instances(size_t num = 1);
void decrease_instances(size_t num = 1);
void set_number_of_copies(/*size_t num*/);
void increase_instances(size_t num = 1, int obj_idx = -1);
void decrease_instances(size_t num = 1, int obj_idx = -1);
void set_number_of_copies();
void fill_bed_with_instances();
bool is_selection_empty() const;
void scale_selection_to_fit_print_volume();
Expand Down Expand Up @@ -350,7 +350,7 @@ class Plater: public wxPanel
bool can_delete() const;
bool can_delete_all() const;
bool can_increase_instances() const;
bool can_decrease_instances() const;
bool can_decrease_instances(int obj_idx = -1) const;
bool can_set_instance_to_object() const;
bool can_fix_through_netfabb() const;
bool can_simplify() const;
Expand Down
10 changes: 10 additions & 0 deletions src/slic3r/GUI/Selection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,16 @@ std::vector<unsigned int> Selection::get_unselected_volume_idxs_from(const std::
return idxs;
}

std::set<unsigned int> Selection::get_object_idxs() const
{
std::set<unsigned int> idxs;

for (unsigned int i : m_list)
idxs.emplace((*m_volumes)[i]->object_idx());

return idxs;
}

void Selection::update_valid()
{
m_valid = (m_volumes != nullptr) && (m_model != nullptr);
Expand Down
2 changes: 2 additions & 0 deletions src/slic3r/GUI/Selection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ class Selection
std::vector<unsigned int> get_missing_volume_idxs_from(const std::vector<unsigned int>& volume_idxs) const;
// returns the list of idxs of the volumes contained in the given list but not in the selection
std::vector<unsigned int> get_unselected_volume_idxs_from(const std::vector<unsigned int>& volume_idxs) const;
// returns the list of idxs of the objects which are in the selection
std::set<unsigned int> get_object_idxs() const;

#if ENABLE_WORLD_COORDINATE_DEBUG
void render_debug_window() const;
Expand Down

0 comments on commit 4d5b85e

Please sign in to comment.