mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
FIX: 2 auto-arrange bugss with per-object printing
1. use strict ordering to ensure the printing order is right 2. reduce height-to-lid to 100mm considering towline is lower than lid and may collid with objects TODO: printing brim may still collide, need to subtract inflated boundary of others during brim generation Change-Id: Icf0cba10c579d28fabd97764c1b3abec267ebd9b (cherry picked from commit 46c6f5ff94488b2f4481bf1d34555f4a7c45e135)
This commit is contained in:
parent
66f38fbb81
commit
f16f5afec5
2 changed files with 46 additions and 28 deletions
|
@ -114,7 +114,7 @@
|
||||||
"extruder_clearance_radius": "57",
|
"extruder_clearance_radius": "57",
|
||||||
"extruder_clearance_max_radius": "68",
|
"extruder_clearance_max_radius": "68",
|
||||||
"extruder_clearance_height_to_rod": "36",
|
"extruder_clearance_height_to_rod": "36",
|
||||||
"extruder_clearance_height_to_lid": "140",
|
"extruder_clearance_height_to_lid": "100",
|
||||||
"nozzle_volume": "118",
|
"nozzle_volume": "118",
|
||||||
"nozzle_diameter": [
|
"nozzle_diameter": [
|
||||||
"0.4"
|
"0.4"
|
||||||
|
|
|
@ -486,15 +486,22 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
||||||
}
|
}
|
||||||
|
|
||||||
// calc sort order
|
// calc sort order
|
||||||
double hc1 = scale_(print.config().extruder_clearance_height_to_lid);
|
double hc1 = scale_(print.config().extruder_clearance_height_to_lid); // height to lid
|
||||||
double hc2 = scale_(print.config().extruder_clearance_height_to_rod);
|
double hc2 = scale_(print.config().extruder_clearance_height_to_rod); // height to rod
|
||||||
double printable_height = scale_(print.config().printable_height);
|
double printable_height = scale_(print.config().printable_height);
|
||||||
|
|
||||||
auto bed_points = get_bed_shape(print_config);
|
auto bed_points = get_bed_shape(print_config);
|
||||||
float bed_width = bed_points[1].x() - bed_points[0].x();
|
float bed_width = bed_points[1].x() - bed_points[0].x();
|
||||||
// 如果扩大以后的多边形的距离小于这个值,就需要严格保证从左到右的打印顺序,否则会撞工具头右侧
|
// 如果扩大以后的多边形的距离小于这个值,就需要严格保证从左到右的打印顺序,否则会撞工具头右侧
|
||||||
float unsafe_dist = scale_(print_config.extruder_clearance_max_radius.value - print_config.extruder_clearance_radius.value);
|
float unsafe_dist = scale_(print_config.extruder_clearance_max_radius.value - print_config.extruder_clearance_radius.value);
|
||||||
std::vector<Vec2i> left_right_pair; // pairs in this vector must strictly obey the left-right order
|
struct VecHash
|
||||||
|
{
|
||||||
|
size_t operator()(const Vec2i &n1) const
|
||||||
|
{
|
||||||
|
return std::hash<coord_t>()(int(n1(0) * 100 + 100)) + std::hash<coord_t>()(int(n1(1) * 100 + 100)) * 101;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::unordered_set<Vec2i, VecHash> left_right_pair; // pairs in this vector must strictly obey the left-right order
|
||||||
for (size_t i = 0; i < print_instance_with_bounding_box.size();i++) {
|
for (size_t i = 0; i < print_instance_with_bounding_box.size();i++) {
|
||||||
auto &inst = print_instance_with_bounding_box[i];
|
auto &inst = print_instance_with_bounding_box[i];
|
||||||
inst.index = i;
|
inst.index = i;
|
||||||
|
@ -523,27 +530,29 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
||||||
auto inter_x = inter_max - inter_min;
|
auto inter_x = inter_max - inter_min;
|
||||||
|
|
||||||
// 如果y方向的重合超过轮廓的膨胀量,说明两个物体在一行,应该先打左边的物体,即先比较二者的x坐标。
|
// 如果y方向的重合超过轮廓的膨胀量,说明两个物体在一行,应该先打左边的物体,即先比较二者的x坐标。
|
||||||
if (inter_y > scale_(0.5 * print.config().extruder_clearance_radius.value)) {
|
if (inter_y > scale_(1)) {
|
||||||
if (std::max(rx1 - lx2, lx1 - rx2) < unsafe_dist) {
|
if (std::max(rx1 - lx2, lx1 - rx2) < unsafe_dist) {
|
||||||
std::string dir = "left";
|
|
||||||
if (lx1 > rx1) {
|
if (lx1 > rx1) {
|
||||||
left_right_pair.emplace_back(j, i);
|
left_right_pair.insert({j, i});
|
||||||
l.arrange_score = std::max(l.arrange_score, r.arrange_score + bed_width);
|
BOOST_LOG_TRIVIAL(debug) << "in-a-row, print_instance " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")"
|
||||||
|
<< " -> " << l.print_instance->model_instance->get_object()->name << "(" << l.arrange_score << ")";
|
||||||
} else {
|
} else {
|
||||||
left_right_pair.emplace_back(i, j);
|
left_right_pair.insert({i, j});
|
||||||
r.arrange_score = std::max(r.arrange_score, l.arrange_score + bed_width);
|
BOOST_LOG_TRIVIAL(debug) << "in-a-row, print_instance " << l.print_instance->model_instance->get_object()->name << "(" << l.arrange_score << ")"
|
||||||
dir = "right";
|
<< " -> " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")";
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(debug) << "print_instance " << inst.print_instance->model_instance->get_object()->name
|
|
||||||
<< ", right=" << r.print_instance->model_instance->get_object()->name << ", l.score: " << l.arrange_score
|
|
||||||
<< ", r.score: " << r.arrange_score << ", dist:" << std::max(rx1 - lx2, lx1 - rx2) << ", dir: " << dir;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (l.height>hc2) {
|
if (l.height > hc1 && r.height < hc1) {
|
||||||
// 如果当前物体的高度超过滑杆,且比r高,就给它加一点代价
|
// 当前物体超过了顶盖高度,必须后打
|
||||||
if (l.height > r.height)
|
left_right_pair.insert({j, i});
|
||||||
l.arrange_score = std::max(l.arrange_score, r.arrange_score + bed_width);
|
BOOST_LOG_TRIVIAL(debug) << "height>hc1, print_instance " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")"
|
||||||
BOOST_LOG_TRIVIAL(debug) << "height print_instance " << inst.print_instance->model_instance->get_object()->name
|
<< " -> " << l.print_instance->model_instance->get_object()->name << "(" << l.arrange_score << ")";
|
||||||
|
}
|
||||||
|
else if (l.height > hc2 && l.height > r.height && l.arrange_score<r.arrange_score) {
|
||||||
|
// 如果当前物体的高度超过滑杆,且比r高,就给它加一点代价,尽量让高的物体后打(只有物体高度超过滑杆时才有必要按高度来)
|
||||||
|
l.arrange_score = std::max(l.arrange_score, r.arrange_score + bed_width/2);
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "height>hc2, print_instance " << inst.print_instance->model_instance->get_object()->name
|
||||||
<< ", right=" << r.print_instance->model_instance->get_object()->name << ", l.score: " << l.arrange_score
|
<< ", right=" << r.print_instance->model_instance->get_object()->name << ", l.score: " << l.arrange_score
|
||||||
<< ", r.score: " << r.arrange_score;
|
<< ", r.score: " << r.arrange_score;
|
||||||
}
|
}
|
||||||
|
@ -551,17 +560,25 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_LOG_TRIVIAL(debug) << "bed width: " << bed_width << ", unsafe_dist:" << unsafe_dist;
|
BOOST_LOG_TRIVIAL(debug) << "bed width: " << bed_width << ", unsafe_dist:" << unsafe_dist;
|
||||||
for (auto& inst:print_instance_with_bounding_box) {
|
// 多做几次代价传播,因为前一次有些值没有更新。
|
||||||
BOOST_LOG_TRIVIAL(debug) << "print_instance " << inst.print_instance->model_instance->get_object()->name
|
// TODO 更好的办法是建立一颗树,一步到位。不过我暂时没精力搞,先就这样吧
|
||||||
<< ", score: " << inst.arrange_score;
|
for (int k=0;k<5;k++)
|
||||||
|
for (auto p : left_right_pair) {
|
||||||
|
auto &l = print_instance_with_bounding_box[p(0)];
|
||||||
|
auto &r = print_instance_with_bounding_box[p(1)];
|
||||||
|
if(r.arrange_score<l.arrange_score)
|
||||||
|
r.arrange_score = l.arrange_score + bed_width/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto p : left_right_pair) {
|
||||||
|
auto &l = print_instance_with_bounding_box[p(0)];
|
||||||
|
auto &r = print_instance_with_bounding_box[p(1)];
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << "print_instance " << l.print_instance->model_instance->get_object()->name << "(" << l.arrange_score << ")"
|
||||||
|
<< " -> " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")";
|
||||||
}
|
}
|
||||||
// sort the print instance
|
// sort the print instance
|
||||||
std::sort(print_instance_with_bounding_box.begin(), print_instance_with_bounding_box.end(),
|
std::sort(print_instance_with_bounding_box.begin(), print_instance_with_bounding_box.end(),
|
||||||
[&left_right_pair](print_instance_info& l, print_instance_info& r) {
|
[](print_instance_info& l, print_instance_info& r) {return l.arrange_score < r.arrange_score;});
|
||||||
if (std::find(left_right_pair.begin(),left_right_pair.end(), Vec2i(l.index, r.index)) != left_right_pair.end())
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return l.arrange_score < r.arrange_score;});
|
|
||||||
|
|
||||||
for (auto &inst : print_instance_with_bounding_box)
|
for (auto &inst : print_instance_with_bounding_box)
|
||||||
BOOST_LOG_TRIVIAL(debug) << "after sorting print_instance " << inst.print_instance->model_instance->get_object()->name << ", score: " << inst.arrange_score
|
BOOST_LOG_TRIVIAL(debug) << "after sorting print_instance " << inst.print_instance->model_instance->get_object()->name << ", score: " << inst.arrange_score
|
||||||
|
@ -603,7 +620,8 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print
|
||||||
for (int k = 0; k < print_instance_count; k++)
|
for (int k = 0; k < print_instance_count; k++)
|
||||||
{
|
{
|
||||||
auto inst = print_instance_with_bounding_box[k].print_instance;
|
auto inst = print_instance_with_bounding_box[k].print_instance;
|
||||||
auto bbox = print_instance_with_bounding_box[k].bounding_box;
|
// 只需要考虑喷嘴到滑杆的偏移量,这个比整个工具头的碰撞半径要小得多
|
||||||
|
auto bbox = print_instance_with_bounding_box[k].bounding_box.inflated(-scale_(0.5 * print.config().extruder_clearance_radius.value));
|
||||||
auto iy1 = bbox.min.y();
|
auto iy1 = bbox.min.y();
|
||||||
auto iy2 = bbox.max.y();
|
auto iy2 = bbox.max.y();
|
||||||
(const_cast<ModelInstance*>(inst->model_instance))->arrange_order = k+1;
|
(const_cast<ModelInstance*>(inst->model_instance))->arrange_order = k+1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue