diff --git a/src/libslic3r/Arachne/BeadingStrategy/BeadingStrategyFactory.cpp b/src/libslic3r/Arachne/BeadingStrategy/BeadingStrategyFactory.cpp index 37d3d4ebaa..853facb213 100644 --- a/src/libslic3r/Arachne/BeadingStrategy/BeadingStrategyFactory.cpp +++ b/src/libslic3r/Arachne/BeadingStrategy/BeadingStrategyFactory.cpp @@ -9,29 +9,31 @@ #include "RedistributeBeadingStrategy.hpp" #include "OuterWallInsetBeadingStrategy.hpp" -#include #include -namespace Slic3r::Arachne -{ +namespace Slic3r::Arachne { -BeadingStrategyPtr BeadingStrategyFactory::makeStrategy( - const coord_t preferred_bead_width_outer, - const coord_t preferred_bead_width_inner, - const coord_t preferred_transition_length, - const float transitioning_angle, - const bool print_thin_walls, - const coord_t min_bead_width, - const coord_t min_feature_size, - const double wall_split_middle_threshold, - const double wall_add_middle_threshold, - const coord_t max_bead_count, - const coord_t outer_wall_offset, - const int inward_distributed_center_wall_count, - const double minimum_variable_line_ratio -) +BeadingStrategyPtr BeadingStrategyFactory::makeStrategy(const coord_t preferred_bead_width_outer, + const coord_t preferred_bead_width_inner, + const coord_t preferred_transition_length, + const float transitioning_angle, + const bool print_thin_walls, + const coord_t min_bead_width, + const coord_t min_feature_size, + const double wall_split_middle_threshold, + const double wall_add_middle_threshold, + const coord_t max_bead_count, + const coord_t outer_wall_offset, + const int inward_distributed_center_wall_count, + const double minimum_variable_line_ratio) { - BeadingStrategyPtr ret = std::make_unique(preferred_bead_width_inner, preferred_transition_length, transitioning_angle, wall_split_middle_threshold, wall_add_middle_threshold, inward_distributed_center_wall_count); + // Handle a special case when there is just one external perimeter. + // Because big differences in bead width for inner and other perimeters cause issues with current beading strategies. + const coord_t optimal_width = max_bead_count <= 2 ? preferred_bead_width_outer : preferred_bead_width_inner; + BeadingStrategyPtr ret = std::make_unique(optimal_width, preferred_transition_length, transitioning_angle, + wall_split_middle_threshold, wall_add_middle_threshold, + inward_distributed_center_wall_count); + BOOST_LOG_TRIVIAL(trace) << "Applying the Redistribute meta-strategy with outer-wall width = " << preferred_bead_width_outer << ", inner-wall width = " << preferred_bead_width_inner << "."; ret = std::make_unique(preferred_bead_width_outer, minimum_variable_line_ratio, std::move(ret)); @@ -39,12 +41,13 @@ BeadingStrategyPtr BeadingStrategyFactory::makeStrategy( BOOST_LOG_TRIVIAL(trace) << "Applying the Widening Beading meta-strategy with minimum input width " << min_feature_size << " and minimum output width " << min_bead_width << "."; ret = std::make_unique(std::move(ret), min_feature_size, min_bead_width); } + if (outer_wall_offset > 0) { BOOST_LOG_TRIVIAL(trace) << "Applying the OuterWallOffset meta-strategy with offset = " << outer_wall_offset << "."; ret = std::make_unique(outer_wall_offset, std::move(ret)); } - //Apply the LimitedBeadingStrategy last, since that adds a 0-width marker wall which other beading strategies shouldn't touch. + // Apply the LimitedBeadingStrategy last, since that adds a 0-width marker wall which other beading strategies shouldn't touch. BOOST_LOG_TRIVIAL(trace) << "Applying the Limited Beading meta-strategy with maximum bead count = " << max_bead_count << "."; ret = std::make_unique(max_bead_count, std::move(ret)); return ret; diff --git a/tests/libslic3r/test_arachne.cpp b/tests/libslic3r/test_arachne.cpp index 61792c37f9..c5b2f35a9b 100644 --- a/tests/libslic3r/test_arachne.cpp +++ b/tests/libslic3r/test_arachne.cpp @@ -743,4 +743,24 @@ TEST_CASE("Arachne - #10034 - Degenerated Voronoi diagram - That wasn't fixed by #ifdef ARACHNE_DEBUG_OUT export_perimeters_to_svg(debug_out_path("arachne-degenerated-diagram-10034-rotation-not-works.svg"), polygons, perimeters, union_ex(wall_tool_paths.getInnerContour())); #endif -} \ No newline at end of file +} + +TEST_CASE("Arachne - SPE-1837 - No perimeters generated", "[ArachneNoPerimetersGeneratedSPE1837]") { + Polygon poly_0 = { + Point( 10000000, 10000000), + Point(-10000000, 10000000), + Point(-10000000, -10000000), + Point( 10000000, -10000000) + }; + + Polygons polygons = {poly_0}; + coord_t ext_perimeter_spacing = 300000; + coord_t perimeter_spacing = 700000; + coord_t inset_count = 1; + + Arachne::WallToolPaths wall_tool_paths(polygons, ext_perimeter_spacing, perimeter_spacing, inset_count, 0, 0.2, PrintObjectConfig::defaults(), PrintConfig::defaults()); + wall_tool_paths.generate(); + std::vector perimeters = wall_tool_paths.getToolPaths(); + + REQUIRE(!perimeters.empty()); +}