Added cancellation to Lightning infill.

This commit is contained in:
Lukáš Hejl 2022-05-12 09:49:07 +02:00
parent 78f62bfddc
commit 11004b4bbd
7 changed files with 25 additions and 18 deletions

View File

@ -21,9 +21,9 @@ void GeneratorDeleter::operator()(Generator *p) {
delete 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 } // namespace Slic3r::FillAdaptive

View File

@ -14,7 +14,7 @@ class Generator;
struct GeneratorDeleter { void operator()(Generator *p); }; struct GeneratorDeleter { void operator()(Generator *p); };
using GeneratorPtr = std::unique_ptr<Generator, GeneratorDeleter>; 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 class Filler : public Slic3r::Fill
{ {

View File

@ -25,7 +25,7 @@
namespace Slic3r::FillLightning { 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 PrintConfig &print_config = print_object.print()->config();
const PrintObjectConfig &object_config = print_object.config(); const PrintObjectConfig &object_config = print_object.config();
@ -47,11 +47,11 @@ Generator::Generator(const PrintObject &print_object)
m_prune_length = coord_t(layer_thickness * std::tan(lightning_infill_prune_angle)); 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)); m_straightening_max_distance = coord_t(layer_thickness * std::tan(lightning_infill_straightening_angle));
generateInitialInternalOverhangs(print_object); generateInitialInternalOverhangs(print_object, throw_on_cancel_callback);
generateTrees(print_object); generateTrees(print_object, throw_on_cancel_callback);
} }
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()); m_overhang_per_layer.resize(print_object.layers().size());
// FIXME: It can be adjusted to improve bonding between infill and perimeters. // FIXME: It can be adjusted to improve bonding between infill and perimeters.
@ -59,7 +59,8 @@ void Generator::generateInitialInternalOverhangs(const PrintObject &print_object
Polygons infill_area_above; 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. //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--) { for (int layer_nr = int(print_object.layers().size()) - 1; layer_nr >= 0; --layer_nr) {
throw_on_cancel_callback();
Polygons infill_area_here; Polygons infill_area_here;
for (const LayerRegion* layerm : print_object.get_layer(layer_nr)->regions()) for (const LayerRegion* layerm : print_object.get_layer(layer_nr)->regions())
for (const Surface& surface : layerm->fill_surfaces.surfaces) for (const Surface& surface : layerm->fill_surfaces.surfaces)
@ -80,7 +81,7 @@ const Layer& Generator::getTreesForLayer(const size_t& layer_id) const
return m_lightning_layers[layer_id]; 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()); m_lightning_layers.resize(print_object.layers().size());
// FIXME: It can be adjusted to improve bonding between infill and perimeters. // FIXME: It can be adjusted to improve bonding between infill and perimeters.
@ -89,11 +90,13 @@ void Generator::generateTrees(const PrintObject &print_object)
std::vector<Polygons> infill_outlines(print_object.layers().size(), Polygons()); std::vector<Polygons> infill_outlines(print_object.layers().size(), Polygons());
// For-each layer from top to bottom: // For-each layer from top to bottom:
for (int layer_id = int(print_object.layers().size()) - 1; layer_id >= 0; layer_id--) 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 LayerRegion *layerm : print_object.get_layer(layer_id)->regions())
for (const Surface &surface : layerm->fill_surfaces.surfaces) for (const Surface &surface : layerm->fill_surfaces.surfaces)
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid) if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
append(infill_outlines[layer_id], infill_wall_offset == 0 ? surface.expolygon : offset(surface.expolygon, infill_wall_offset)); append(infill_outlines[layer_id], infill_wall_offset == 0 ? surface.expolygon : offset(surface.expolygon, infill_wall_offset));
}
// For various operations its beneficial to quickly locate nearby features on the polygon: // For various operations its beneficial to quickly locate nearby features on the polygon:
const size_t top_layer_id = print_object.layers().size() - 1; const size_t top_layer_id = print_object.layers().size() - 1;
@ -102,6 +105,7 @@ void Generator::generateTrees(const PrintObject &print_object)
// For-each layer from top to bottom: // For-each layer from top to bottom:
for (int layer_id = int(top_layer_id); layer_id >= 0; layer_id--) { 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]; Layer &current_lightning_layer = m_lightning_layers[layer_id];
const Polygons &current_outlines = infill_outlines[layer_id]; const Polygons &current_outlines = infill_outlines[layer_id];
const BoundingBox &current_outlines_bbox = get_extents(current_outlines); const BoundingBox &current_outlines_bbox = get_extents(current_outlines);
@ -109,7 +113,7 @@ void Generator::generateTrees(const PrintObject &print_object)
// register all trees propagated from the previous layer as to-be-reconnected // 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; 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); 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. // Initialize trees for next lower layer from the current one.

View File

@ -43,9 +43,8 @@ public:
* This generator will pre-compute things in preparation of generating * This generator will pre-compute things in preparation of generating
* Lightning Infill for the infill areas in that mesh. The infill areas must * Lightning Infill for the infill areas in that mesh. The infill areas must
* already be calculated at this point. * already be calculated at this point.
* \param mesh The mesh to generate infill for.
*/ */
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. * Get a tree of paths generated for a certain layer of the mesh.
@ -69,12 +68,12 @@ protected:
* only when support is generated. For this pattern, we also need to * only when support is generated. For this pattern, we also need to
* generate overhang areas for the inside of the model. * 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. * Calculate the tree structure of all layers.
*/ */
void generateTrees(const PrintObject &print_object); void generateTrees(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback);
float m_infill_extrusion_width; float m_infill_extrusion_width;

View File

@ -44,10 +44,12 @@ void Layer::generateNewTrees
const BoundingBox& current_outlines_bbox, const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outlines_locator, const EdgeGrid::Grid& outlines_locator,
const coord_t supporting_radius, 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); DistanceField distance_field(supporting_radius, current_outlines, current_outlines_bbox, current_overhang);
throw_on_cancel_callback();
SparseNodeGrid tree_node_locator; SparseNodeGrid tree_node_locator;
fillLocator(tree_node_locator, current_outlines_bbox); fillLocator(tree_node_locator, current_outlines_bbox);
@ -56,6 +58,7 @@ void Layer::generateNewTrees
// Determine next point from tree/outline areas via distance-field // Determine next point from tree/outline areas via distance-field
Point unsupported_location; Point unsupported_location;
while (distance_field.tryGetNextPoint(&unsupported_location)) { while (distance_field.tryGetNextPoint(&unsupported_location)) {
throw_on_cancel_callback();
GroundingLocation grounding_loc = getBestGroundingLocation( GroundingLocation grounding_loc = getBestGroundingLocation(
unsupported_location, current_outlines, current_outlines_bbox, outlines_locator, supporting_radius, wall_supporting_radius, tree_node_locator); 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 BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outline_locator, const EdgeGrid::Grid& outline_locator,
coord_t supporting_radius, 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. /*! Determine & connect to connection point in tree/outline.

View File

@ -464,7 +464,7 @@ FillLightning::GeneratorPtr PrintObject::prepare_lightning_infill_data()
break; 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() void PrintObject::clear_layers()