FIX: lightning infill may fail for some cases

Change-Id: Ibc6e4e4262ef9fc0b36a936acc52a3b60dca2cb4
(cherry picked from commit e3b7c5c3404aa200c4b852b3963a7a0aae8837d2)
This commit is contained in:
Arthur 2022-12-07 10:54:43 +08:00 committed by Lane.Wei
parent 8375c73ac9
commit 6a644c271c
9 changed files with 34 additions and 36 deletions

View file

@ -26,9 +26,9 @@ void GeneratorDeleter::operator()(Generator *p) {
delete p;
}
GeneratorPtr build_generator(const PrintObject &print_object)
GeneratorPtr build_generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{
return GeneratorPtr(new Generator(print_object));
return GeneratorPtr(new Generator(print_object, throw_on_cancel_callback));
}
} // namespace Slic3r::FillAdaptive

View file

@ -3,13 +3,6 @@
#include "FillBase.hpp"
/*
* A few modifications based on dba1179(2022.06.10) from Prusa, mainly in Generator.hpp and .cpp:
* 1. delete the second parameter(a throw back function) of Generator(), since I didnt find corresponding throw back function in BBS code
* 2. those codes that call the functions above
* 3. add codes of generating lightning in TreeSupport.cpp
*/
namespace Slic3r {
class PrintObject;
@ -21,7 +14,7 @@ class Generator;
struct GeneratorDeleter { void operator()(Generator *p); };
using GeneratorPtr = std::unique_ptr<Generator, GeneratorDeleter>;
GeneratorPtr build_generator(const PrintObject &print_object);
GeneratorPtr build_generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
class Filler : public Slic3r::Fill
{

View file

@ -43,7 +43,8 @@ DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outl
m_supporting_radius2 = Slic3r::sqr(int64_t(radius));
// Sample source polygons with a regular grid sampling pattern.
const BoundingBox overhang_bbox = get_extents(current_overhang);
for (const ExPolygon &expoly : union_ex(current_overhang)) {
ExPolygons expolys = offset2_ex(union_ex(current_overhang), -m_cell_size / 2, m_cell_size / 2); // remove dangling lines which causes sample_grid_pattern crash (fails the OUTER_LOW assertions)
for (const ExPolygon &expoly : expolys) {
const Points sampled_points = sample_grid_pattern(expoly, m_cell_size, overhang_bbox);
const size_t unsupported_points_prev_size = m_unsupported_points.size();
m_unsupported_points.resize(unsupported_points_prev_size + sampled_points.size());
@ -94,10 +95,6 @@ DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outl
void DistanceField::update(const Point& to_node, const Point& added_leaf)
{
std::ofstream out1("z:/misc/lightning.txt", std::ios::app);
out1 << m_unsupported_points.size() << std::endl;
out1.close();
Vec2d v = (added_leaf - to_node).cast<double>();
auto l2 = v.squaredNorm();
Vec2d extent = Vec2d(-v.y(), v.x()) * m_supporting_radius / sqrt(l2);

View file

@ -63,7 +63,7 @@ Slic3r::SVG draw_two_overhangs_to_svg(size_t ts_layer, const ExPolygons& overhan
namespace Slic3r::FillLightning {
Generator::Generator(const PrintObject &print_object)
Generator::Generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{
const PrintConfig &print_config = print_object.print()->config();
const PrintObjectConfig &object_config = print_object.config();
@ -87,11 +87,11 @@ Generator::Generator(const PrintObject &print_object)
m_prune_length = coord_t(layer_thickness * std::tan(lightning_infill_prune_angle));
m_straightening_max_distance = coord_t(layer_thickness * std::tan(lightning_infill_straightening_angle));
generateInitialInternalOverhangs(print_object);
generateTrees(print_object);
generateInitialInternalOverhangs(print_object, throw_on_cancel_callback);
generateTrees(print_object, throw_on_cancel_callback);
}
Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, float density)
Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, const std::function<void()> &throw_on_cancel_callback, float density)
{
const PrintConfig &print_config = m_object->print()->config();
const PrintObjectConfig &object_config = m_object->config();
@ -120,7 +120,7 @@ Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std
m_overhang_per_layer = overhangs;
generateTreesforSupport(contours);
generateTreesforSupport(contours, throw_on_cancel_callback);
//for (size_t i = 0; i < overhangs.size(); i++)
//{
@ -130,13 +130,14 @@ Generator::Generator(PrintObject* m_object, std::vector<Polygons>& contours, std
//}
}
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object)
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{
m_overhang_per_layer.resize(print_object.layers().size());
Polygons infill_area_above;
//Iterate from top to bottom, to subtract the overhang areas above from the overhang areas on the layer below, to get only overhang in the top layer where it is overhanging.
for (int layer_nr = int(print_object.layers().size()) - 1; layer_nr >= 0; --layer_nr) {
throw_on_cancel_callback();
Polygons infill_area_here;
for (const LayerRegion* layerm : print_object.get_layer(layer_nr)->regions())
for (const Surface& surface : layerm->fill_surfaces.surfaces)
@ -157,7 +158,7 @@ const Layer& Generator::getTreesForLayer(const size_t& layer_id) const
return m_lightning_layers[layer_id];
}
void Generator::generateTrees(const PrintObject &print_object)
void Generator::generateTrees(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{
m_lightning_layers.resize(print_object.layers().size());
bboxs.resize(print_object.layers().size());
@ -165,6 +166,7 @@ void Generator::generateTrees(const PrintObject &print_object)
// For-each layer from top to bottom:
for (int layer_id = int(print_object.layers().size()) - 1; layer_id >= 0; layer_id--) {
throw_on_cancel_callback();
for (const LayerRegion *layerm : print_object.get_layer(layer_id)->regions())
for (const Surface &surface : layerm->fill_surfaces.surfaces)
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
@ -178,6 +180,7 @@ void Generator::generateTrees(const PrintObject &print_object)
// For-each layer from top to bottom:
for (int layer_id = int(top_layer_id); layer_id >= 0; layer_id--) {
throw_on_cancel_callback();
Layer &current_lightning_layer = m_lightning_layers[layer_id];
const Polygons &current_outlines = infill_outlines[layer_id];
const BoundingBox &current_outlines_bbox = get_extents(current_outlines);
@ -187,7 +190,7 @@ void Generator::generateTrees(const PrintObject &print_object)
// register all trees propagated from the previous layer as to-be-reconnected
std::vector<NodeSPtr> to_be_reconnected_tree_roots = current_lightning_layer.tree_roots;
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius, throw_on_cancel_callback);
current_lightning_layer.reconnectRoots(to_be_reconnected_tree_roots, current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
// Initialize trees for next lower layer from the current one.
@ -211,7 +214,7 @@ void Generator::generateTrees(const PrintObject &print_object)
}
}
void Generator::generateTreesforSupport(std::vector<Polygons>& contours)
void Generator::generateTreesforSupport(std::vector<Polygons>& contours, const std::function<void()> &throw_on_cancel_callback)
{
if (contours.empty()) return;
@ -225,6 +228,7 @@ void Generator::generateTreesforSupport(std::vector<Polygons>& contours)
// For-each layer from top to bottom:
for (int layer_id = int(top_layer_id); layer_id >= 0; layer_id--) {
throw_on_cancel_callback();
Layer& current_lightning_layer = m_lightning_layers[layer_id];
const Polygons& current_outlines = contours[layer_id];
const BoundingBox& current_outlines_bbox = get_extents(current_outlines);
@ -234,7 +238,7 @@ void Generator::generateTreesforSupport(std::vector<Polygons>& contours)
// register all trees propagated from the previous layer as to-be-reconnected
std::vector<NodeSPtr> to_be_reconnected_tree_roots = current_lightning_layer.tree_roots;
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius, throw_on_cancel_callback);
current_lightning_layer.reconnectRoots(to_be_reconnected_tree_roots, current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
// Initialize trees for next lower layer from the current one.

View file

@ -44,7 +44,7 @@ public:
* Lightning Infill for the infill areas in that mesh. The infill areas must
* already be calculated at this point.
*/
explicit Generator(const PrintObject &print_object);
explicit Generator(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
/*!
* Get a tree of paths generated for a certain layer of the mesh.
@ -61,7 +61,7 @@ public:
float infilll_extrusion_width() const { return m_infill_extrusion_width; }
Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, float density = 0.15);
Generator(PrintObject* m_object, std::vector<Polygons>& contours, std::vector<Polygons>& overhangs, const std::function<void()> &throw_on_cancel_callback, float density = 0.15);
protected:
/*!
@ -72,13 +72,13 @@ protected:
* only when support is generated. For this pattern, we also need to
* generate overhang areas for the inside of the model.
*/
void generateInitialInternalOverhangs(const PrintObject &print_object);
void generateInitialInternalOverhangs(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
/*!
* Calculate the tree structure of all layers.
*/
void generateTrees(const PrintObject &print_object);
void generateTreesforSupport(std::vector<Polygons>& contours);
void generateTrees(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
void generateTreesforSupport(std::vector<Polygons>& contours, const std::function<void()> &throw_on_cancel_callback);
float m_infill_extrusion_width;

View file

@ -48,10 +48,12 @@ void Layer::generateNewTrees
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outlines_locator,
const coord_t supporting_radius,
const coord_t wall_supporting_radius
const coord_t wall_supporting_radius,
const std::function<void()> &throw_on_cancel_callback
)
{
DistanceField distance_field(supporting_radius, current_outlines, current_outlines_bbox, current_overhang);
throw_on_cancel_callback();
SparseNodeGrid tree_node_locator;
fillLocator(tree_node_locator, current_outlines_bbox);
@ -61,6 +63,7 @@ void Layer::generateNewTrees
size_t unsupported_cell_idx = 0;
Point unsupported_location;
while (distance_field.tryGetNextPoint(&unsupported_location, &unsupported_cell_idx, unsupported_cell_idx)) {
throw_on_cancel_callback();
GroundingLocation grounding_loc = getBestGroundingLocation(
unsupported_location, current_outlines, current_outlines_bbox, outlines_locator, supporting_radius, wall_supporting_radius, tree_node_locator);

View file

@ -44,7 +44,8 @@ public:
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outline_locator,
coord_t supporting_radius,
coord_t wall_supporting_radius
coord_t wall_supporting_radius,
const std::function<void()> &throw_on_cancel_callback
);
/*! Determine & connect to connection point in tree/outline.

View file

@ -546,7 +546,7 @@ FillLightning::GeneratorPtr PrintObject::prepare_lightning_infill_data()
break;
}
return has_lightning_infill ? FillLightning::build_generator(std::as_const(*this)) : FillLightning::GeneratorPtr();
return has_lightning_infill ? FillLightning::build_generator(std::as_const(*this), [this]() -> void { this->throw_if_canceled(); }) : FillLightning::GeneratorPtr();
}
void PrintObject::clear_layers()

View file

@ -1954,7 +1954,8 @@ ExPolygons avoid_object_remove_extra_small_parts(ExPolygons &expolys, const ExPo
void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_nodes)
{
const PrintObjectConfig &config = m_object->config();
bool has_brim = m_object->print()->has_brim();
const Print* print = m_object->print();
bool has_brim = print->has_brim();
bool has_infill = config.support_base_pattern.value != smpNone && config.support_base_pattern != smpDefault;
int bottom_gap_layers = round(m_slicing_params.gap_object_support / m_slicing_params.layer_height);
const coordf_t branch_radius = config.tree_support_branch_diameter.value / 2;
@ -1979,7 +1980,6 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
// Performance optimization. Only generate lslices for brim and skirt.
size_t brim_skirt_layers = has_brim ? 1 : 0;
const Print* print = m_object->print();
const PrintConfig& print_config = print->config();
for (const PrintObject* object : print->objects())
{
@ -2256,7 +2256,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
#endif
}
generator = std::make_unique<FillLightning::Generator>(m_object, contours, overhangs, support_density);
generator = std::make_unique<FillLightning::Generator>(m_object, contours, overhangs, []() {}, support_density);
}
else if (!has_infill) {