diff --git a/src/libslic3r/Fill/FillLightning.cpp b/src/libslic3r/Fill/FillLightning.cpp index b50694e95b..dd2189e6b9 100644 --- a/src/libslic3r/Fill/FillLightning.cpp +++ b/src/libslic3r/Fill/FillLightning.cpp @@ -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 &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 9c36e01577..6e672783a1 100644 --- a/src/libslic3r/Fill/FillLightning.hpp +++ b/src/libslic3r/Fill/FillLightning.hpp @@ -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; -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/DistanceField.cpp b/src/libslic3r/Fill/Lightning/DistanceField.cpp index 7c7eae448f..65da94b839 100644 --- a/src/libslic3r/Fill/Lightning/DistanceField.cpp +++ b/src/libslic3r/Fill/Lightning/DistanceField.cpp @@ -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(); auto l2 = v.squaredNorm(); Vec2d extent = Vec2d(-v.y(), v.x()) * m_supporting_radius / sqrt(l2); diff --git a/src/libslic3r/Fill/Lightning/Generator.cpp b/src/libslic3r/Fill/Lightning/Generator.cpp index 3a23896947..fb00cbe6e2 100644 --- a/src/libslic3r/Fill/Lightning/Generator.cpp +++ b/src/libslic3r/Fill/Lightning/Generator.cpp @@ -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 &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& contours, std::vector& overhangs, float density) +Generator::Generator(PrintObject* m_object, std::vector& contours, std::vector& overhangs, const std::function &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& 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& contours, std //} } -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()); 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 &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 ¤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); @@ -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 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& contours) +void Generator::generateTreesforSupport(std::vector& contours, const std::function &throw_on_cancel_callback) { if (contours.empty()) return; @@ -225,6 +228,7 @@ void Generator::generateTreesforSupport(std::vector& 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& contours) // 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 0b25fd513c..79110fb8dd 100644 --- a/src/libslic3r/Fill/Lightning/Generator.hpp +++ b/src/libslic3r/Fill/Lightning/Generator.hpp @@ -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 &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& contours, std::vector& overhangs, float density = 0.15); + Generator(PrintObject* m_object, std::vector& contours, std::vector& overhangs, const std::function &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 &throw_on_cancel_callback); /*! * Calculate the tree structure of all layers. */ - void generateTrees(const PrintObject &print_object); - void generateTreesforSupport(std::vector& contours); + void generateTrees(const PrintObject &print_object, const std::function &throw_on_cancel_callback); + void generateTreesforSupport(std::vector& contours, 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 5aa217d8f2..354623e519 100644 --- a/src/libslic3r/Fill/Lightning/Layer.cpp +++ b/src/libslic3r/Fill/Lightning/Layer.cpp @@ -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 &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); diff --git a/src/libslic3r/Fill/Lightning/Layer.hpp b/src/libslic3r/Fill/Lightning/Layer.hpp index c0b91ad1f8..e8c0a38b4d 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 c9ceae6884..05330140d2 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -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() diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 7673497b71..935c5236e9 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -1954,7 +1954,8 @@ ExPolygons avoid_object_remove_extra_small_parts(ExPolygons &expolys, const ExPo void TreeSupport::draw_circles(const std::vector>& 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>& 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>& contact_no #endif } - generator = std::make_unique(m_object, contours, overhangs, support_density); + generator = std::make_unique(m_object, contours, overhangs, []() {}, support_density); } else if (!has_infill) {