diff --git a/src/libslic3r/Fill/FillLightning.cpp b/src/libslic3r/Fill/FillLightning.cpp index 447fd8057..2ba6fe017 100644 --- a/src/libslic3r/Fill/FillLightning.cpp +++ b/src/libslic3r/Fill/FillLightning.cpp @@ -21,9 +21,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 &throw_on_cancel_callback) { - return GeneratorPtr(new Generator(print_object)); + return GeneratorPtr(new Generator(print_object, throw_on_cancel_callback)); } } // namespace Slic3r::FillAdaptive diff --git a/src/libslic3r/Fill/FillLightning.hpp b/src/libslic3r/Fill/FillLightning.hpp index b4e7e35f1..941392103 100644 --- a/src/libslic3r/Fill/FillLightning.hpp +++ b/src/libslic3r/Fill/FillLightning.hpp @@ -14,7 +14,7 @@ class Generator; struct GeneratorDeleter { void operator()(Generator *p); }; using GeneratorPtr = std::unique_ptr; -GeneratorPtr build_generator(const PrintObject &print_object); +GeneratorPtr build_generator(const PrintObject &print_object, const std::function &throw_on_cancel_callback); class Filler : public Slic3r::Fill { diff --git a/src/libslic3r/Fill/Lightning/Generator.cpp b/src/libslic3r/Fill/Lightning/Generator.cpp index 0bdd1c7e8..b4c07a338 100644 --- a/src/libslic3r/Fill/Lightning/Generator.cpp +++ b/src/libslic3r/Fill/Lightning/Generator.cpp @@ -25,7 +25,7 @@ namespace Slic3r::FillLightning { -Generator::Generator(const PrintObject &print_object) +Generator::Generator(const PrintObject &print_object, const std::function &throw_on_cancel_callback) { const PrintConfig &print_config = print_object.print()->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_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); } -void Generator::generateInitialInternalOverhangs(const PrintObject &print_object) +void Generator::generateInitialInternalOverhangs(const PrintObject &print_object, const std::function &throw_on_cancel_callback) { m_overhang_per_layer.resize(print_object.layers().size()); // 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; //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; for (const LayerRegion* layerm : print_object.get_layer(layer_nr)->regions()) 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]; } -void Generator::generateTrees(const PrintObject &print_object) +void Generator::generateTrees(const PrintObject &print_object, const std::function &throw_on_cancel_callback) { m_lightning_layers.resize(print_object.layers().size()); // 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 infill_outlines(print_object.layers().size(), Polygons()); // 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 Surface &surface : layerm->fill_surfaces.surfaces) 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)); + } // For various operations its beneficial to quickly locate nearby features on the polygon: 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 (int layer_id = int(top_layer_id); layer_id >= 0; layer_id--) { + throw_on_cancel_callback(); Layer ¤t_lightning_layer = m_lightning_layers[layer_id]; const Polygons ¤t_outlines = infill_outlines[layer_id]; const BoundingBox ¤t_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 std::vector 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. diff --git a/src/libslic3r/Fill/Lightning/Generator.hpp b/src/libslic3r/Fill/Lightning/Generator.hpp index b538c4dbe..d7e5f63f9 100644 --- a/src/libslic3r/Fill/Lightning/Generator.hpp +++ b/src/libslic3r/Fill/Lightning/Generator.hpp @@ -43,9 +43,8 @@ public: * This generator will pre-compute things in preparation of generating * Lightning Infill for the infill areas in that mesh. The infill areas must * 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 &throw_on_cancel_callback); /*! * 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 * generate overhang areas for the inside of the model. */ - void generateInitialInternalOverhangs(const PrintObject &print_object); + void generateInitialInternalOverhangs(const PrintObject &print_object, const std::function &throw_on_cancel_callback); /*! * Calculate the tree structure of all layers. */ - void generateTrees(const PrintObject &print_object); + void generateTrees(const PrintObject &print_object, const std::function &throw_on_cancel_callback); float m_infill_extrusion_width; diff --git a/src/libslic3r/Fill/Lightning/Layer.cpp b/src/libslic3r/Fill/Lightning/Layer.cpp index c996b9b7b..c381d5505 100644 --- a/src/libslic3r/Fill/Lightning/Layer.cpp +++ b/src/libslic3r/Fill/Lightning/Layer.cpp @@ -44,10 +44,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 &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); @@ -56,6 +58,7 @@ void Layer::generateNewTrees // Determine next point from tree/outline areas via distance-field Point unsupported_location; while (distance_field.tryGetNextPoint(&unsupported_location)) { + 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); diff --git a/src/libslic3r/Fill/Lightning/Layer.hpp b/src/libslic3r/Fill/Lightning/Layer.hpp index cc79c15b5..87431fb1c 100644 --- a/src/libslic3r/Fill/Lightning/Layer.hpp +++ b/src/libslic3r/Fill/Lightning/Layer.hpp @@ -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 &throw_on_cancel_callback ); /*! Determine & connect to connection point in tree/outline. diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 9c6178f8b..eeaf1b13c 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -464,7 +464,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()