Skip to content

Commit 8ca1488

Browse files
committed
feat: fill bed with object instances
(cherry picked from commit d8a8592)
1 parent 7c12f6b commit 8ca1488

5 files changed

Lines changed: 113 additions & 22 deletions

File tree

src/slic3r/GUI/GUI_Factories.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,8 +2504,26 @@ void MenuFactory::append_menu_item_locked(wxMenu* menu)
25042504
void MenuFactory::append_menu_item_fill_bed(wxMenu *menu)
25052505
{
25062506
append_menu_item(
2507-
menu, wxID_ANY, _L("Fill bed with copies"), _L("Fill the remaining area of bed with copies of the selected object"),
2508-
[](wxCommandEvent &) { plater()->fill_bed_with_instances(); }, "", nullptr, []() { return plater()->can_increase_instances(); }, m_parent);
2507+
menu,
2508+
wxID_ANY,
2509+
_L("Fill bed with copies"),
2510+
_L("Fill the remaining area of bed with copies of the selected object"),
2511+
[](wxCommandEvent &) { plater()->fill_bed_with_copies(); },
2512+
"",
2513+
nullptr,
2514+
[]() { return plater()->can_increase_instances(); },
2515+
m_parent);
2516+
2517+
append_menu_item(
2518+
menu,
2519+
wxID_ANY,
2520+
_L("Fill bed with instances"),
2521+
_L("Fill the remaining area of bed with instances of the selected object"),
2522+
[](wxCommandEvent &) { plater()->fill_bed_with_instances(); },
2523+
"",
2524+
nullptr,
2525+
[]() { return plater()->can_increase_instances(); },
2526+
m_parent);
25092527
}
25102528

25112529
void MenuFactory::append_menu_item_plate_name(wxMenu *menu)

src/slic3r/GUI/Jobs/FillBedJob.cpp

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,33 @@ void FillBedJob::prepare()
167167
ap.bed_idx = PartPlateList::MAX_PLATES_COUNT;
168168
ap.height = 1;
169169
ap.itemid = -1;
170-
ap.setter = [this, mi_orig_trafo](const ArrangePolygon &p) {
170+
ap.setter = [this, sel_id, mi_orig_trafo](const ArrangePolygon &p) {
171171
ModelObject *mo = m_plater->model().objects[m_object_idx];
172-
ModelObject* newObj = m_plater->model().add_object(*mo);
173-
newObj->name = mo->name +" "+ std::to_string(p.itemid);
174-
for (ModelInstance *newInst : newObj->instances) {
175-
newInst->set_transformation(mi_orig_trafo);
176-
newInst->apply_arrange_result(p.translation.cast<double>(), p.rotation);
172+
173+
if (m_instances) {
174+
ModelInstance *new_instance =
175+
mo->add_instance(*mo->instances[sel_id]);
176+
177+
new_instance->set_transformation(mi_orig_trafo);
178+
new_instance->apply_arrange_result(
179+
p.translation.cast<double>(),
180+
p.rotation);
181+
} else {
182+
ModelObject *new_object =
183+
m_plater->model().add_object(*mo);
184+
185+
new_object->name =
186+
mo->name + " " + std::to_string(p.itemid);
187+
188+
for (ModelInstance *new_instance : new_object->instances) {
189+
new_instance->set_transformation(mi_orig_trafo);
190+
new_instance->apply_arrange_result(
191+
p.translation.cast<double>(),
192+
p.rotation);
193+
}
194+
195+
m_plater->model().set_assembly_pos(new_object);
177196
}
178-
m_plater->model().set_assembly_pos(newObj);
179197
};
180198
m_selected.emplace_back(ap);
181199
}
@@ -396,7 +414,7 @@ void FillBedJob::finalize()
396414
return s + int(ap.priority == 0 && ap.bed_idx == 0);
397415
});
398416

399-
int oldSize = m_plater->model().objects.size();
417+
const size_t old_size = m_plater->model().objects.size();
400418

401419
if (added_cnt > 0) {
402420
for (ArrangePolygon& ap : m_selected) {
@@ -418,14 +436,42 @@ void FillBedJob::finalize()
418436
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(":selected: bed_id %1%, trans {%2%,%3%}") % ap.bed_idx % unscale<double>(ap.translation(X)) % unscale<double>(ap.translation(Y));
419437
}
420438

421-
int newSize = m_plater->model().objects.size();
422-
auto obj_list = m_plater->sidebar().obj_list();
423-
for (size_t i = oldSize; i < newSize; i++) {
424-
obj_list->add_object_to_list(i, true, true, false);
425-
obj_list->update_printable_state(i, 0);
426-
}
439+
auto *obj_list = m_plater->sidebar().obj_list();
427440

428-
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ": paste_objects_into_list";
441+
if (m_instances) {
442+
const size_t new_inst_cnt = model_object->instances.size();
443+
444+
if (new_inst_cnt > inst_cnt) {
445+
// A single instance has no separate child node in the object
446+
// list. When transitioning to multiple instances, add nodes
447+
// for both the original instance and the newly created ones.
448+
const size_t list_items_to_add =
449+
inst_cnt == 1
450+
? new_inst_cnt
451+
: new_inst_cnt - inst_cnt;
452+
453+
obj_list->increase_object_instances(
454+
m_object_idx,
455+
list_items_to_add);
456+
}
457+
458+
BOOST_LOG_TRIVIAL(debug)
459+
<< __FUNCTION__
460+
<< ": added "
461+
<< (new_inst_cnt - inst_cnt)
462+
<< " instances";
463+
} else {
464+
const size_t new_size = m_plater->model().objects.size();
465+
466+
for (size_t i = old_size; i < new_size; ++i) {
467+
obj_list->add_object_to_list(i, true, true, false);
468+
obj_list->update_printable_state(i, 0);
469+
}
470+
471+
BOOST_LOG_TRIVIAL(debug)
472+
<< __FUNCTION__
473+
<< ": paste_objects_into_list";
474+
}
429475

430476
m_plater->update();
431477
}

src/slic3r/GUI/Jobs/FillBedJob.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,21 @@ class FillBedJob : public PlaterJob
2323

2424
arrangement::ArrangeParams params;
2525

26-
int m_status_range = 0;
26+
int m_status_range = 0;
27+
bool m_instances = false;
2728

2829
protected:
2930

3031
void prepare() override;
3132
void process() override;
3233

3334
public:
34-
FillBedJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
35+
FillBedJob(
36+
std::shared_ptr<ProgressIndicator> pri,
37+
Plater *plater,
38+
bool instances = false)
3539
: PlaterJob{std::move(pri), plater}
40+
, m_instances{instances}
3641
{}
3742

3843
int status_range() const override

src/slic3r/GUI/Plater.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6355,7 +6355,12 @@ struct Plater::priv
63556355
class Jobs: public ExclusiveJobGroup
63566356
{
63576357
priv *m;
6358-
size_t m_arrange_id, m_fill_bed_id, m_rotoptimize_id, m_sla_import_id, m_orient_id;
6358+
size_t m_arrange_id;
6359+
size_t m_fill_bed_id;
6360+
size_t m_fill_bed_instances_id;
6361+
size_t m_rotoptimize_id;
6362+
size_t m_sla_import_id;
6363+
size_t m_orient_id;
63596364
std::shared_ptr<NotificationProgressIndicator> m_pri;
63606365
//BBS
63616366
size_t m_print_id;
@@ -6369,7 +6374,11 @@ struct Plater::priv
63696374
{
63706375
m_arrange_id = add_job(std::make_unique<ArrangeJob>(m_pri, m->q));
63716376
m_orient_id = add_job(std::make_unique<OrientJob>(m_pri, m->q));
6372-
m_fill_bed_id = add_job(std::make_unique<FillBedJob>(m_pri, m->q));
6377+
m_fill_bed_id =
6378+
add_job(std::make_unique<FillBedJob>(m_pri, m->q));
6379+
6380+
m_fill_bed_instances_id =
6381+
add_job(std::make_unique<FillBedJob>(m_pri, m->q, true));
63736382
m_rotoptimize_id = add_job(std::make_unique<RotoptimizeJob>(m_pri, m->q));
63746383
m_sla_import_id = add_job(std::make_unique<SLAImportJob>(m_pri, m->q));
63756384
//BBS add print id
@@ -6394,6 +6403,12 @@ struct Plater::priv
63946403
start(m_fill_bed_id);
63956404
}
63966405

6406+
void fill_bed_with_instances()
6407+
{
6408+
m->take_snapshot("Fill bed with instances");
6409+
start(m_fill_bed_instances_id);
6410+
}
6411+
63976412
void optimize_rotation()
63986413
{
63996414
m->take_snapshot("Optimize Rotation");
@@ -20367,12 +20382,18 @@ void Plater::set_number_of_copies(/*size_t num*/)
2036720382
decrease_instances(-diff);
2036820383
}
2036920384

20370-
void Plater::fill_bed_with_instances()
20385+
void Plater::fill_bed_with_copies()
2037120386
{
2037220387
if (!p->m_ui_jobs.is_any_running())
2037320388
p->m_ui_jobs.fill_bed();
2037420389
}
2037520390

20391+
void Plater::fill_bed_with_instances()
20392+
{
20393+
if (!p->m_ui_jobs.is_any_running())
20394+
p->m_ui_jobs.fill_bed_with_instances();
20395+
}
20396+
2037620397
bool Plater::is_selection_empty() const
2037720398
{
2037820399
return p->get_selection().is_empty() || p->get_selection().is_wipe_tower();

src/slic3r/GUI/Plater.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ class Plater: public wxPanel
482482
void increase_instances(size_t num = 1);
483483
void decrease_instances(size_t num = 1);
484484
void set_number_of_copies(/*size_t num*/);
485+
void fill_bed_with_copies();
485486
void fill_bed_with_instances();
486487
bool is_selection_empty() const;
487488
void scale_selection_to_fit_print_volume();

0 commit comments

Comments
 (0)