mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 23:46:24 -06:00
FIX: make fill in bed arrange parameters same as normal arrange
Change-Id: Iec9d4e9c145ea75fc06d096e9c6905b3e412940c
This commit is contained in:
parent
739732ec18
commit
33c69cdb4f
4 changed files with 131 additions and 85 deletions
|
@ -392,20 +392,7 @@ void ArrangeJob::prepare()
|
||||||
NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Arranging..."));
|
NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("Arranging..."));
|
||||||
m_plater->get_notification_manager()->bbl_close_plateinfo_notification();
|
m_plater->get_notification_manager()->bbl_close_plateinfo_notification();
|
||||||
|
|
||||||
{
|
params = init_arrange_params(*m_plater);
|
||||||
const GLCanvas3D::ArrangeSettings &settings = static_cast<const GLCanvas3D *>(m_plater->canvas3D())->get_arrange_settings();
|
|
||||||
auto & print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
|
||||||
|
|
||||||
params.clearance_height_to_rod = print.config().extruder_clearance_height_to_rod.value;
|
|
||||||
params.clearance_height_to_lid = print.config().extruder_clearance_height_to_lid.value;
|
|
||||||
params.cleareance_radius = print.config().extruder_clearance_max_radius.value;
|
|
||||||
params.printable_height = print.config().printable_height.value;
|
|
||||||
params.allow_rotations = settings.enable_rotation;
|
|
||||||
params.allow_multi_materials_on_same_plate = settings.allow_multi_materials_on_same_plate;
|
|
||||||
params.avoid_extrusion_cali_region = settings.avoid_extrusion_cali_region;
|
|
||||||
params.is_seq_print = settings.is_seq_print;
|
|
||||||
params.min_obj_distance = scaled(settings.distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
//BBS update extruder params and speed table before arranging
|
//BBS update extruder params and speed table before arranging
|
||||||
Plater::setExtruderParams(Model::extruderParamsMap);
|
Plater::setExtruderParams(Model::extruderParamsMap);
|
||||||
|
@ -510,79 +497,18 @@ void ArrangeJob::process()
|
||||||
auto & partplate_list = m_plater->get_partplate_list();
|
auto & partplate_list = m_plater->get_partplate_list();
|
||||||
auto& print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
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 + 0.001)); // +0.001mm to avoid clearance check fail due to rounding error
|
|
||||||
|
|
||||||
if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer"))
|
if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer"))
|
||||||
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;
|
update_arrange_params(params, *m_plater, m_selected);
|
||||||
double brim_max = 0;
|
update_selected_items_inflation(m_selected, *m_plater, params);
|
||||||
std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.brim_width); });
|
update_unselected_items_inflation(m_unselected, *m_plater, params);
|
||||||
|
|
||||||
// Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt.
|
Points bedpts = get_shrink_bedpts(*m_plater,params);
|
||||||
// So we can't do max but do adding instead.
|
|
||||||
params.brim_skirt_distance = skirt_distance + brim_max;
|
|
||||||
params.bed_shrink_x = settings.bed_shrink_x + params.brim_skirt_distance;
|
|
||||||
params.bed_shrink_y = settings.bed_shrink_y + params.brim_skirt_distance;
|
|
||||||
// for sequential print, we need to inflate the bed because cleareance_radius is so large
|
|
||||||
if (params.is_seq_print) {
|
|
||||||
float shift_dist = params.cleareance_radius / 2 - 5;
|
|
||||||
params.bed_shrink_x -= shift_dist;
|
|
||||||
params.bed_shrink_y -= shift_dist;
|
|
||||||
// dont forget to move the excluded region
|
|
||||||
for (auto& region : m_unselected) {
|
|
||||||
if (region.is_virt_object)
|
|
||||||
region.poly.translate(-scaled(shift_dist), -scaled(shift_dist));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (print.full_print_config().opt_bool("enable_support")) {
|
|
||||||
params.bed_shrink_x = std::max(5.f, params.bed_shrink_x);
|
|
||||||
params.bed_shrink_y = std::max(5.f, params.bed_shrink_y);
|
|
||||||
params.min_obj_distance = std::max(scaled(10.0), params.min_obj_distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not inflate brim_width. Objects are allowed to have overlapped brim.
|
|
||||||
Points bedpts = get_bed_shape(*m_plater->config());
|
|
||||||
BoundingBox bedbb = Polygon(bedpts).bounding_box();
|
|
||||||
std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon &ap) {
|
|
||||||
ap.inflation = params.min_obj_distance / 2;
|
|
||||||
BoundingBox apbb = ap.poly.contour.bounding_box();
|
|
||||||
auto diffx = bedbb.size().x() - apbb.size().x() - 5;
|
|
||||||
auto diffy = bedbb.size().y() - apbb.size().y() - 5;
|
|
||||||
if (diffx > 0 && diffy > 0) {
|
|
||||||
auto min_diff = std::min(diffx, diffy);
|
|
||||||
ap.inflation = std::min(min_diff / 2, ap.inflation);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// For occulusion regions, inflation should be larger to prevent genrating brim on them.
|
|
||||||
// However, extrusion cali regions are exceptional, since we can allow brim overlaps them.
|
|
||||||
// 屏蔽区域只需要膨胀brim宽度,防止brim长过去;挤出标定区域不需要膨胀,brim可以长过去。
|
|
||||||
// 以前我们认为还需要膨胀clearance_radius/2,这其实是不需要的,因为这些区域并不会真的摆放物体,
|
|
||||||
// 其他物体的膨胀轮廓是可以跟它们重叠的。
|
|
||||||
double scaled_exclusion_gap = scale_(1);
|
double scaled_exclusion_gap = scale_(1);
|
||||||
std::for_each(m_unselected.begin(), m_unselected.end(), [&](auto &ap) {
|
|
||||||
ap.inflation = !ap.is_virt_object ?
|
|
||||||
params.min_obj_distance / 2 :
|
|
||||||
(ap.is_extrusion_cali_object ? 0 : scaled_exclusion_gap);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
partplate_list.preprocess_exclude_areas(params.excluded_regions, 1, scaled_exclusion_gap);
|
partplate_list.preprocess_exclude_areas(params.excluded_regions, 1, scaled_exclusion_gap);
|
||||||
|
|
||||||
// shrink bed by moving to center by dist
|
|
||||||
auto shrinkFun = [](Points& bedpts, double dist, int direction) {
|
|
||||||
#define SGN(x) ((x)>=0?1:-1)
|
|
||||||
Point center = Polygon(bedpts).bounding_box().center();
|
|
||||||
for (auto& pt : bedpts)
|
|
||||||
pt[direction] += dist * SGN(center[direction] - pt[direction]);
|
|
||||||
};
|
|
||||||
shrinkFun(bedpts, scaled(params.bed_shrink_x), 0);
|
|
||||||
shrinkFun(bedpts, scaled(params.bed_shrink_y), 1);
|
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "arrange bed_shrink_x=" << params.bed_shrink_x
|
BOOST_LOG_TRIVIAL(debug) << "arrange bed_shrink_x=" << params.bed_shrink_x
|
||||||
<< ", brim_max= "<<brim_max<<", "
|
|
||||||
<< "; bedpts:" << bedpts[0].transpose() << ", " << bedpts[1].transpose() << ", " << bedpts[2].transpose() << ", " << bedpts[3].transpose();
|
<< "; bedpts:" << bedpts[0].transpose() << ", " << bedpts[1].transpose() << ", " << bedpts[2].transpose() << ", " << bedpts[3].transpose();
|
||||||
|
|
||||||
params.stopcondition = [this]() { return was_canceled(); };
|
params.stopcondition = [this]() { return was_canceled(); };
|
||||||
|
@ -800,4 +726,108 @@ arrangement::ArrangeParams get_arrange_params(Plater *p)
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call before get selected and unselected
|
||||||
|
arrangement::ArrangeParams init_arrange_params(const Plater &p)
|
||||||
|
{
|
||||||
|
arrangement::ArrangeParams params;
|
||||||
|
const GLCanvas3D::ArrangeSettings &settings = static_cast<const GLCanvas3D *>(p.canvas3D())->get_arrange_settings();
|
||||||
|
auto & print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
||||||
|
|
||||||
|
params.clearance_height_to_rod = print.config().extruder_clearance_height_to_rod.value;
|
||||||
|
params.clearance_height_to_lid = print.config().extruder_clearance_height_to_lid.value;
|
||||||
|
params.cleareance_radius = print.config().extruder_clearance_max_radius.value;
|
||||||
|
params.printable_height = print.config().printable_height.value;
|
||||||
|
params.allow_rotations = settings.enable_rotation;
|
||||||
|
params.allow_multi_materials_on_same_plate = settings.allow_multi_materials_on_same_plate;
|
||||||
|
params.avoid_extrusion_cali_region = settings.avoid_extrusion_cali_region;
|
||||||
|
params.is_seq_print = settings.is_seq_print;
|
||||||
|
params.min_obj_distance = scaled(settings.distance);
|
||||||
|
params.bed_shrink_x = settings.bed_shrink_x;
|
||||||
|
params.bed_shrink_y = settings.bed_shrink_y;
|
||||||
|
|
||||||
|
if (params.is_seq_print)
|
||||||
|
params.min_obj_distance = std::max(params.min_obj_distance, scaled(params.cleareance_radius + 0.001)); // +0.001mm to avoid clearance check fail due to rounding error
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
//after get selected.call this to update bed_shrink
|
||||||
|
void update_arrange_params(arrangement::ArrangeParams ¶ms, const Plater &p, const arrangement::ArrangePolygons &selected)
|
||||||
|
{
|
||||||
|
const GLCanvas3D::ArrangeSettings &settings = static_cast<const GLCanvas3D *>(p.canvas3D())->get_arrange_settings();
|
||||||
|
auto & print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
||||||
|
double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0;
|
||||||
|
double brim_max = 0;
|
||||||
|
std::for_each(selected.begin(), selected.end(), [&](const ArrangePolygon &ap) { brim_max = std::max(brim_max, ap.brim_width); });
|
||||||
|
// Note: skirt_distance is now defined between outermost brim and skirt, not the object and skirt.
|
||||||
|
// So we can't do max but do adding instead.
|
||||||
|
params.brim_skirt_distance = skirt_distance + brim_max;
|
||||||
|
params.bed_shrink_x = settings.bed_shrink_x + params.brim_skirt_distance;
|
||||||
|
params.bed_shrink_y = settings.bed_shrink_y + params.brim_skirt_distance;
|
||||||
|
// for sequential print, we need to inflate the bed because cleareance_radius is so large
|
||||||
|
if (params.is_seq_print) {
|
||||||
|
float shift_dist = params.cleareance_radius / 2 - 5;
|
||||||
|
params.bed_shrink_x -= shift_dist;
|
||||||
|
params.bed_shrink_y -= shift_dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For by-layer printing, need to shrink bed a little, so the support won't go outside bed.
|
||||||
|
// We set it to 5mm because that's how much a normal support will grow by default.
|
||||||
|
// But for by-object printing, it's not needed since the clerance distance is already very large.
|
||||||
|
if (print.full_print_config().opt_bool("enable_support") && !params.is_seq_print) {
|
||||||
|
params.bed_shrink_x = std::max(5.f, params.bed_shrink_x);
|
||||||
|
params.bed_shrink_y = std::max(5.f, params.bed_shrink_y);
|
||||||
|
params.min_obj_distance = std::max(scaled(10.0), params.min_obj_distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//it will bed accurate after call update_params
|
||||||
|
Points get_shrink_bedpts(const Plater &plater, const arrangement::ArrangeParams ¶ms)
|
||||||
|
{
|
||||||
|
Points bedpts = get_bed_shape(*plater.config());
|
||||||
|
// shrink bed by moving to center by dist
|
||||||
|
auto shrinkFun = [](Points &bedpts, double dist, int direction) {
|
||||||
|
#define SGN(x) ((x) >= 0 ? 1 : -1)
|
||||||
|
Point center = Polygon(bedpts).bounding_box().center();
|
||||||
|
for (auto &pt : bedpts) pt[direction] += dist * SGN(center[direction] - pt[direction]);
|
||||||
|
};
|
||||||
|
shrinkFun(bedpts, scaled(params.bed_shrink_x), 0);
|
||||||
|
shrinkFun(bedpts, scaled(params.bed_shrink_y), 1);
|
||||||
|
return bedpts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_selected_items_inflation(arrangement::ArrangePolygons &selected, const Plater &p, const arrangement::ArrangeParams ¶ms) {
|
||||||
|
// do not inflate brim_width. Objects are allowed to have overlapped brim.
|
||||||
|
Points bedpts = get_shrink_bedpts(p, params);
|
||||||
|
BoundingBox bedbb = Polygon(bedpts).bounding_box();
|
||||||
|
std::for_each(selected.begin(), selected.end(), [&](ArrangePolygon &ap) {
|
||||||
|
ap.inflation = params.min_obj_distance / 2;
|
||||||
|
BoundingBox apbb = ap.poly.contour.bounding_box();
|
||||||
|
auto diffx = bedbb.size().x() - apbb.size().x() - 5;
|
||||||
|
auto diffy = bedbb.size().y() - apbb.size().y() - 5;
|
||||||
|
if (diffx > 0 && diffy > 0) {
|
||||||
|
auto min_diff = std::min(diffx, diffy);
|
||||||
|
ap.inflation = std::min(min_diff / 2, ap.inflation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_unselected_items_inflation(arrangement::ArrangePolygons &unselected, const Plater &p, const arrangement::ArrangeParams ¶ms)
|
||||||
|
{
|
||||||
|
if (params.is_seq_print) {
|
||||||
|
float shift_dist = params.cleareance_radius / 2 - 5;
|
||||||
|
// dont forget to move the excluded region
|
||||||
|
for (auto ®ion : unselected) {
|
||||||
|
if (region.is_virt_object) region.poly.translate(-scaled(shift_dist), -scaled(shift_dist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For occulusion regions, inflation should be larger to prevent genrating brim on them.
|
||||||
|
// However, extrusion cali regions are exceptional, since we can allow brim overlaps them.
|
||||||
|
// 屏蔽区域只需要膨胀brim宽度,防止brim长过去;挤出标定区域不需要膨胀,brim可以长过去。
|
||||||
|
// 以前我们认为还需要膨胀clearance_radius/2,这其实是不需要的,因为这些区域并不会真的摆放物体,
|
||||||
|
// 其他物体的膨胀轮廓是可以跟它们重叠的。
|
||||||
|
double scaled_exclusion_gap = scale_(1);
|
||||||
|
std::for_each(unselected.begin(), unselected.end(),
|
||||||
|
[&](auto &ap) { ap.inflation = !ap.is_virt_object ? params.min_obj_distance / 2 : (ap.is_extrusion_cali_object ? 0 : scaled_exclusion_gap); });
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace Slic3r::GUI
|
}} // namespace Slic3r::GUI
|
||||||
|
|
|
@ -78,6 +78,16 @@ double bed_stride_y(const Plater* plater);
|
||||||
|
|
||||||
arrangement::ArrangeParams get_arrange_params(Plater *p);
|
arrangement::ArrangeParams get_arrange_params(Plater *p);
|
||||||
|
|
||||||
|
arrangement::ArrangeParams init_arrange_params(const Plater &p);
|
||||||
|
|
||||||
|
Points get_shrink_bedpts(const Plater& plater,const arrangement::ArrangeParams& params);
|
||||||
|
|
||||||
|
void update_arrange_params(arrangement::ArrangeParams ¶ms, const Plater &p, const arrangement::ArrangePolygons &selected);
|
||||||
|
|
||||||
|
void update_selected_items_inflation(arrangement::ArrangePolygons &selected, const Plater &p, const arrangement::ArrangeParams ¶ms);
|
||||||
|
|
||||||
|
void update_unselected_items_inflation(arrangement::ArrangePolygons &unselected, const Plater &p, const arrangement::ArrangeParams ¶ms);
|
||||||
|
|
||||||
}} // namespace Slic3r::GUI
|
}} // namespace Slic3r::GUI
|
||||||
|
|
||||||
#endif // ARRANGEJOB_HPP
|
#endif // ARRANGEJOB_HPP
|
||||||
|
|
|
@ -23,6 +23,8 @@ void FillBedJob::prepare()
|
||||||
m_unselected.clear();
|
m_unselected.clear();
|
||||||
m_bedpts.clear();
|
m_bedpts.clear();
|
||||||
|
|
||||||
|
params = init_arrange_params(*m_plater);
|
||||||
|
|
||||||
m_object_idx = m_plater->get_selected_object_idx();
|
m_object_idx = m_plater->get_selected_object_idx();
|
||||||
if (m_object_idx == -1)
|
if (m_object_idx == -1)
|
||||||
return;
|
return;
|
||||||
|
@ -118,6 +120,8 @@ void FillBedJob::prepare()
|
||||||
if (m_selected.empty()) return;
|
if (m_selected.empty()) return;
|
||||||
|
|
||||||
//add the virtual object into unselect list if has
|
//add the virtual object into unselect list if has
|
||||||
|
double scaled_exclusion_gap = scale_(1);
|
||||||
|
plate_list.preprocess_exclude_areas(params.excluded_regions, 1, scaled_exclusion_gap);
|
||||||
plate_list.preprocess_exclude_areas(m_unselected);
|
plate_list.preprocess_exclude_areas(m_unselected);
|
||||||
|
|
||||||
m_bedpts = get_bed_shape(*m_plater->config());
|
m_bedpts = get_bed_shape(*m_plater->config());
|
||||||
|
@ -200,16 +204,16 @@ void FillBedJob::process()
|
||||||
const GLCanvas3D::ArrangeSettings &settings =
|
const GLCanvas3D::ArrangeSettings &settings =
|
||||||
static_cast<const GLCanvas3D*>(m_plater->canvas3D())->get_arrange_settings();
|
static_cast<const GLCanvas3D*>(m_plater->canvas3D())->get_arrange_settings();
|
||||||
|
|
||||||
arrangement::ArrangeParams params;
|
update_arrange_params(params, *m_plater, m_selected);
|
||||||
params.allow_rotations = settings.enable_rotation;
|
m_bedpts = get_shrink_bedpts(*m_plater, params);
|
||||||
params.min_obj_distance = scaled(settings.distance);
|
|
||||||
params.avoid_extrusion_cali_region = settings.avoid_extrusion_cali_region;
|
|
||||||
auto &partplate_list = m_plater->get_partplate_list();
|
auto &partplate_list = m_plater->get_partplate_list();
|
||||||
auto &print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
auto &print = wxGetApp().plater()->get_partplate_list().get_current_fff_print();
|
||||||
if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer"))
|
if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer"))
|
||||||
partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES);
|
partplate_list.preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES);
|
||||||
|
|
||||||
for (auto &ap : m_selected) { ap.inflation = params.min_obj_distance / 2; }
|
update_selected_items_inflation(m_selected, *m_plater, params);
|
||||||
|
update_unselected_items_inflation(m_unselected, *m_plater, params);
|
||||||
|
|
||||||
bool do_stop = false;
|
bool do_stop = false;
|
||||||
params.stopcondition = [this, &do_stop]() {
|
params.stopcondition = [this, &do_stop]() {
|
||||||
|
|
|
@ -21,6 +21,8 @@ class FillBedJob : public PlaterJob
|
||||||
|
|
||||||
Points m_bedpts;
|
Points m_bedpts;
|
||||||
|
|
||||||
|
arrangement::ArrangeParams params;
|
||||||
|
|
||||||
int m_status_range = 0;
|
int m_status_range = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue