From 826f27089ec07ef56f7ffc3a9ae3d6b11ff23e3b Mon Sep 17 00:00:00 2001 From: Arthur Date: Tue, 9 May 2023 19:52:58 +0800 Subject: [PATCH] ENH: improve multi-material arranging Multi-material arranging is more compact by redefining same_color_with_previous_items: if the colors of previous items are a subset of current object's colors, or vice versa. Either of the two cases will not increase the total number of colors of the plate. Jira: STUDIO-2871 Change-Id: I7cbe0835408d306084490b4849d03bb9fb617d2b (cherry picked from commit d58702e9c0db54bcd123739298ce6dc03f5ca1a5) --- src/libslic3r/Arrange.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index eeb385676..cf27977d5 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -452,27 +452,25 @@ protected: } std::set extruder_ids; - int non_virt_cnt = 0; - std::set first_object_extruder_ids; for (int i = 0; i < m_items.size(); i++) { Item& p = m_items[i]; if (p.is_virt_object) continue; extruder_ids.insert(p.extrude_ids.begin(),p.extrude_ids.end()); - non_virt_cnt++; - if (non_virt_cnt == 1) { first_object_extruder_ids.insert(p.extrude_ids.begin(), p.extrude_ids.end()); } } - extruder_ids.insert(item.extrude_ids.begin(),item.extrude_ids.end()); // add a large cost if not multi materials on same plate is not allowed if (!params.allow_multi_materials_on_same_plate) { - bool first_object = non_virt_cnt == 0; - bool same_color_with_first_object = std::all_of(item.extrude_ids.begin(), item.extrude_ids.end(), - [&](int color) { return first_object_extruder_ids.find(color) != first_object_extruder_ids.end(); }); - // non_virt_cnt==0 means it's the first object, which can be multi-color - if (!(first_object || same_color_with_first_object)) score += LARGE_COST_TO_REJECT * 1.3; + // it's the first object, which can be multi-color + bool first_object = extruder_ids.empty(); + // the two objects (previously packed items and the current item) are considered having same color if either one's colors are a subset of the other + std::set item_extruder_ids(item.extrude_ids.begin(), item.extrude_ids.end()); + bool same_color_with_previous_items = std::includes(item_extruder_ids.begin(), item_extruder_ids.end(), extruder_ids.begin(), extruder_ids.end()) + || std::includes(extruder_ids.begin(), extruder_ids.end(), item_extruder_ids.begin(), item_extruder_ids.end()); + if (!(first_object || same_color_with_previous_items)) score += LARGE_COST_TO_REJECT * 1.3; } // for layered printing, we want extruder change as few as possible // this has very weak effect, CAN NOT use a large weight + extruder_ids.insert(item.extrude_ids.begin(), item.extrude_ids.end()); if (!params.is_seq_print) { score += 1 * std::max(0, ((int) extruder_ids.size() - 1)); }