mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	FIX: auto-arrange unable to arrage a large number of small items
1. Should start from bottom left if there is excluded regions 2. avoid exclusion regions in fixed_overfit_topright_sliding Jira: STUDIO-1422 Change-Id: If88ecf86a0485bd478a77df8cfd4942df8ca27ac (cherry picked from commit a8393de51bd178b731ef4c7201a5fe3247d97a1f)
This commit is contained in:
		
							parent
							
								
									d152b4d235
								
							
						
					
					
						commit
						f6fed97b9d
					
				
					 2 changed files with 32 additions and 17 deletions
				
			
		|  | @ -84,7 +84,7 @@ const double BIG_ITEM_TRESHOLD = 0.02; | |||
| template<class PConf> | ||||
| 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<double, Box>& result, const Box &bi | |||
| } | ||||
| 
 | ||||
| // useful for arranging big circle objects
 | ||||
| static double fixed_overfit_topright_sliding(const std::tuple<double, Box>& result, const Box& binbb) | ||||
| template<class PConf>  | ||||
| static double fixed_overfit_topright_sliding(const std::tuple<double, Box> &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<double, Box>& 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); | ||||
|                 } | ||||
|             }; | ||||
|         }; | ||||
|  |  | |||
|  | @ -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<const GLCanvas3D*>(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<double>(selected.translation(X)) << ","<< unscale<double>(selected.translation(Y)); | ||||
|         BOOST_LOG_TRIVIAL(debug) << "items unselected after arrange: "; | ||||
|         for (auto item : m_unselected) | ||||
|             if (!item.is_virt_object) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Arthur
						Arthur