ENH: should apply instance shift in is_through_overhang

Signed-off-by: salt.wei <salt.wei@bambulab.com>
Change-Id: I07ca04d459c3e98650c8e5a33f56dac20f99b9a2
This commit is contained in:
salt.wei 2023-07-05 10:21:05 +08:00 committed by Lane.Wei
parent c00719b837
commit bc0273d734
4 changed files with 53 additions and 30 deletions

View file

@ -4252,42 +4252,45 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
return false;
}
//BBS: input travel polyline must be in current plate coordinate system
auto is_through_overhang = [this](const Polyline& travel) {
BoundingBox travel_bbox = get_extents(travel);
travel_bbox.inflated(1);
const float protect_z_scaled = scale_(0.4);
std::pair<float, float> z_range;
z_range.second = m_layer ? m_layer->print_z : 0.f;
z_range.first = std::max(0.f, z_range.second - protect_z_scaled);
std::vector<LayerPtrs> layers_of_objects;
std::vector<BoundingBox> boundingBox_for_objects;
std::vector<size_t> idx_of_object_sorted = m_curr_print->layers_sorted_for_object(z_range.first, z_range.second, layers_of_objects, boundingBox_for_objects);
std::vector<Points> objects_instances_shift;
std::vector<size_t> idx_of_object_sorted = m_curr_print->layers_sorted_for_object(z_range.first, z_range.second, layers_of_objects, boundingBox_for_objects, objects_instances_shift);
for (size_t i = 0; i < idx_of_object_sorted.size();i++) {
size_t idx = idx_of_object_sorted[i];
std::vector<bool> is_layers_of_objects_sorted(layers_of_objects.size(), false);
BoundingBox obj_bbox = boundingBox_for_objects[idx];
BoundingBox travel_bbox = get_extents(travel);
obj_bbox.offset(scale_(EPSILON));
if (!obj_bbox.overlap(travel_bbox))
for (size_t idx : idx_of_object_sorted) {
for (const Point & instance_shift : objects_instances_shift[idx]) {
BoundingBox instance_bbox = boundingBox_for_objects[idx];
instance_bbox.offset(scale_(EPSILON));
instance_bbox.translate(instance_shift.x(), instance_shift.y());
if (!instance_bbox.overlap(travel_bbox))
continue;
Polygon object_box;
Polygons temp;
object_box.points.push_back(Point(obj_bbox.min(0), obj_bbox.min(1)));
object_box.points.push_back(Point(obj_bbox.max(0), obj_bbox.min(1)));
object_box.points.push_back(Point(obj_bbox.max(0), obj_bbox.max(1)));
object_box.points.push_back(Point(obj_bbox.min(0), obj_bbox.max(1)));
temp.push_back(object_box);
temp.emplace_back(std::move(instance_bbox.polygon()));
if (intersection_pl(travel, temp).empty())
continue;
std::sort(layers_of_objects[idx].begin(), layers_of_objects[idx].end(), [](auto left, auto right) { return left->loverhangs_bbox.area() > right->loverhangs_bbox.area();
});
if (!is_layers_of_objects_sorted[idx]) {
std::sort(layers_of_objects[idx].begin(), layers_of_objects[idx].end(), [](auto left, auto right) { return left->loverhangs_bbox.area() > right->loverhangs_bbox.area();});
is_layers_of_objects_sorted[idx] = true;
}
for (const auto &layer : layers_of_objects[idx]) {
for (const ExPolygon &overhang : layer->loverhangs) {
for (const auto& layer : layers_of_objects[idx]) {
for (ExPolygon overhang : layer->loverhangs) {
overhang.translate(instance_shift);
BoundingBox bbox1 = get_extents(overhang);
travel_bbox.inflated(1);
if (!bbox1.overlap(travel_bbox))
continue;
@ -4298,6 +4301,7 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
}
}
}
}
return false;
};
@ -4312,6 +4316,8 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftTyp
clipped_travel.append(Polyline(travel.points[0], travel.points[1]));
if (clipped_travel.length() > travel_len_thresh)
clipped_travel.points.back() = clipped_travel.points.front()+(clipped_travel.points.back() - clipped_travel.points.front()) * (travel_len_thresh / clipped_travel.length());
//BBS: translate to current plate coordinate system
clipped_travel.translate(Point::new_scale(double(m_origin.x() - m_writer.get_xy_offset().x()), double(m_origin.y() - m_writer.get_xy_offset().y())));
//BBS: force to retract when leave from external perimeter for a long travel
//Better way is judging whether the travel move direction is same with last extrusion move.

View file

@ -437,7 +437,7 @@ bool Print::has_brim() const
}
//BBS
std::vector<size_t> Print::layers_sorted_for_object(float start, float end, std::vector<LayerPtrs> &layers_of_objects, std::vector<BoundingBox> &boundingBox_for_objects)
std::vector<size_t> Print::layers_sorted_for_object(float start, float end, std::vector<LayerPtrs> &layers_of_objects, std::vector<BoundingBox> &boundingBox_for_objects, std::vector<Points> &objects_instances_shift)
{
std::vector<size_t> idx_of_object_sorted;
size_t idx = 0;
@ -448,6 +448,11 @@ std::vector<size_t> Print::layers_sorted_for_object(float start, float end, std:
std::sort(idx_of_object_sorted.begin(), idx_of_object_sorted.end(),
[boundingBox_for_objects](auto left, auto right) { return boundingBox_for_objects[left].area() > boundingBox_for_objects[right].area(); });
objects_instances_shift.clear();
objects_instances_shift.reserve(m_objects.size());
for (const auto& object : m_objects)
objects_instances_shift.emplace_back(object->get_instances_shift_without_plate_offset());
return idx_of_object_sorted;
};

View file

@ -424,6 +424,7 @@ public:
//BBS
BoundingBox get_first_layer_bbox(float& area, float& layer_height, std::string& name);
void get_certain_layers(float start, float end, std::vector<LayerPtrs> &out, std::vector<BoundingBox> &boundingbox_objects);
std::vector<Point> get_instances_shift_without_plate_offset();
PrintObject* get_shared_object() const { return m_shared_object; }
void set_shared_object(PrintObject *object);
void clear_shared_object();
@ -758,7 +759,7 @@ public:
// For Perl bindings.
PrintObjectPtrs& objects_mutable() { return m_objects; }
PrintRegionPtrs& print_regions_mutable() { return m_print_regions; }
std::vector<size_t> layers_sorted_for_object(float start, float end, std::vector<LayerPtrs> &layers_of_objects, std::vector<BoundingBox> &boundingBox_for_objects);
std::vector<size_t> layers_sorted_for_object(float start, float end, std::vector<LayerPtrs> &layers_of_objects, std::vector<BoundingBox> &boundingBox_for_objects, std::vector<Points>& objects_instances_shift);
const ExtrusionEntityCollection& skirt() const { return m_skirt; }
// Convex hull of the 1st layer extrusions, for bed leveling and placing the initial purge line.
// It encompasses the object extrusions, support extrusions, skirt, brim, wipe tower.

View file

@ -2045,6 +2045,17 @@ void PrintObject::get_certain_layers(float start, float end, std::vector<LayerPt
boundingbox_objects.emplace_back(std::move(temp));
out.emplace_back(std::move(out_temp));
};
std::vector<Point> PrintObject::get_instances_shift_without_plate_offset()
{
std::vector<Point> out;
out.reserve(m_instances.size());
for (const auto& instance : m_instances)
out.push_back(instance.shift_without_plate_offset());
return out;
}
// Only active if config->infill_only_where_needed. This step trims the sparse infill,
// so it acts as an internal support. It maintains all other infill types intact.
// Here the internal surfaces and perimeters have to be supported by the sparse infill.