diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 4dffcf39f9..5d4812022a 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -84,7 +84,7 @@ const double BIG_ITEM_TRESHOLD = 0.02; template void fill_config(PConf& pcfg, const ArrangeParams ¶ms) { - if (params.is_seq_print) { + if (params.is_seq_print || params.excluded_regions.empty()==false) { // Align the arranged pile into the center of the bin pcfg.alignment = PConf::Alignment::CENTER; // Start placing the items from the center of the print bed @@ -137,7 +137,8 @@ static double fixed_overfit(const std::tuple& result, const Box &bi } // useful for arranging big circle objects -static double fixed_overfit_topright_sliding(const std::tuple& result, const Box& binbb) +template +static double fixed_overfit_topright_sliding(const std::tuple &result, const Box &binbb, const PConf &config) { double score = std::get<0>(result); Box pilebb = std::get<1>(result); @@ -152,6 +153,18 @@ static double fixed_overfit_topright_sliding(const std::tuple& resu auto diff = double(fullbb.area()) - binbb.area(); if (diff > 0) score += diff; + // excluded regions and nonprefered regions should not intersect the translated pilebb + for (auto ®ion : config.m_excluded_regions) { + Box bb = region.boundingBox(); + auto area_ = bb.intersection(pilebb).area(); + if (area_ > 0) score += area_; + } + for (auto ®ion : config.m_nonprefered_regions) { + Box bb = region.boundingBox(); + auto area_ = bb.intersection(pilebb).area(); + if (area_ > 0) score += area_; + } + return score; } @@ -545,7 +558,7 @@ public: } } - cfg.object_function = [this, binbb, starting_point](const Item& item, const ItemGroup& packed_items) { + cfg.object_function = [this, binbb, starting_point, &cfg](const Item &item, const ItemGroup &packed_items) { // 在我们的摆盘中,没有天然的固定对象。固定对象只有:屏蔽区域、挤出补偿区域、料塔。 // 对于屏蔽区域,摆入的对象仍然是可以向右上滑动的; // 对挤出料塔,摆入的对象不能滑动(必须围绕料塔) @@ -553,7 +566,7 @@ public: if(pack_around_wipe_tower) return fixed_overfit(objfunc(item, starting_point), binbb); else { - return fixed_overfit_topright_sliding(objfunc(item, starting_point), binbb); + return fixed_overfit_topright_sliding(objfunc(item, starting_point), binbb, cfg); } }; }; diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 3d290447f3..04ac925c5f 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -157,7 +157,7 @@ void ArrangeJob::prepare_selected() { m_locked.emplace_back(std::move(ap)); if (inst_sel[i]) selected_is_locked = true; - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % i; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%, name %3%") % oidx % i % mo->name; } } } @@ -235,6 +235,9 @@ void ArrangeJob::prepare_all() { } prepare_wipe_tower(); + + // add the virtual object into unselect list if has + plate_list.preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES); } // 准备料塔。逻辑如下: @@ -346,17 +349,18 @@ void ArrangeJob::prepare_partplate() { ArrangePolygons& cont = mo->instances[inst_idx]->printable ? (in_plate ? m_selected : m_unselected) : m_unprintable; - ap.itemid = cont.size(); bool locked = plate_list.preprocess_arrange_polygon_other_locked(oidx, inst_idx, ap, in_plate); if (!locked) { + ap.itemid = cont.size(); cont.emplace_back(std::move(ap)); } else { //skip this object due to be not in current plate, treated as locked + ap.itemid = m_locked.size(); m_locked.emplace_back(std::move(ap)); - BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, instance_id %2%") % oidx % inst_idx; + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(": skip locked instance, obj_id %1%, name %2%") % oidx % mo->name; } } } @@ -367,11 +371,8 @@ void ArrangeJob::prepare_partplate() { m_unselected.emplace_back(std::move(ap)); } - // The strides have to be removed from the fixed items. For the - // arrangeable (selected) items bed_idx is ignored and the - // translation is irrelevant. - //BBS: remove logic for unselected object - //for (auto& p : m_unselected) p.translation(X) -= p.bed_idx * stride; + // add the virtual object into unselect list if has + plate_list.preprocess_exclude_areas(m_unselected, current_plate_index + 1); } //BBS: add partplate logic @@ -410,8 +411,6 @@ void ArrangeJob::prepare() prepare_partplate(); } - //add the virtual object into unselect list if has - m_plater->get_partplate_list().preprocess_exclude_areas(m_unselected, MAX_NUM_PLATES); #if SAVE_ARRANGE_POLY if (1) @@ -498,13 +497,14 @@ void ArrangeJob::process() { const GLCanvas3D::ArrangeSettings &settings = static_cast(m_plater->canvas3D())->get_arrange_settings(); + auto & partplate_list = m_plater->get_partplate_list(); auto& print = wxGetApp().plater()->get_partplate_list().get_current_fff_print(); if (params.is_seq_print) params.min_obj_distance = std::max(params.min_obj_distance, scaled(params.cleareance_radius)); if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer")) - m_plater->get_partplate_list().preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); + partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0; double brim_max = 0; @@ -547,7 +547,8 @@ void ArrangeJob::process() }); - m_plater->get_partplate_list().preprocess_exclude_areas(params.excluded_regions, 1); + partplate_list.preprocess_exclude_areas(params.excluded_regions, 1); + partplate_list.preprocess_exclude_areas(params.nonprefered_regions, 1); // shrink bed by moving to center by dist Points bedpts = get_bed_shape(*m_plater->config()); @@ -589,7 +590,8 @@ void ArrangeJob::process() BOOST_LOG_TRIVIAL(debug) << "items selected after arrange: "; for (auto selected : m_selected) BOOST_LOG_TRIVIAL(debug) << selected.name << ", extruder: " << selected.extrude_ids.back() << ", bed: " << selected.bed_idx - << ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp; + << ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp + << ", trans: " << unscale(selected.translation(X)) << ","<< unscale(selected.translation(Y)); BOOST_LOG_TRIVIAL(debug) << "items unselected after arrange: "; for (auto item : m_unselected) if (!item.is_virt_object)