From e9011e100dafe478fa8dd089bb048bf38c1328f8 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Fri, 6 Dec 2024 15:00:12 +0100 Subject: [PATCH] Add support for peninsulas --- .../SLA/SupportIslands/SampleConfig.hpp | 23 +++- .../SupportIslands/UniformSupportIsland.cpp | 130 +++++++++++------- .../SupportIslands/UniformSupportIsland.hpp | 9 ++ src/libslic3r/SLA/SupportPointGenerator.cpp | 122 +++++++++++----- src/libslic3r/SLA/SupportPointGenerator.hpp | 27 ++-- src/libslic3r/SLAPrintSteps.cpp | 34 ++--- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 4 +- tests/sla_print/sla_test_utils.cpp | 18 +-- 8 files changed, 235 insertions(+), 132 deletions(-) diff --git a/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp b/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp index 0eb6a0f65e..6f4401844b 100644 --- a/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp +++ b/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp @@ -6,6 +6,25 @@ #define OPTION_TO_STORE_ISLAND namespace Slic3r::sla { + +/// +/// Configure how to prepare data for SupportPointGenerator +/// +struct PrepareSupportConfig +{ + // Size of the steps between discretized samples on the overhanging part of layer + // Smaller value means more point to investigate in support process, + // but smaller divergence of support distances + double discretize_overhang_step = 2.; // [in mm] + + // Detection of peninsula(half island) + // Peninsula contain wider one layer overhang than this value + float peninsula_min_width = scale_(2); // [in scaled mm] + + // Distance from previous layer part to still supported + float peninsula_self_supported_width = scale_(1.5); // [in scaled mm] +}; + /// /// Configuration DTO /// Define where is neccessary to put support point on island @@ -83,8 +102,8 @@ struct SampleConfig std::string path = ""; // when set to empty string, no debug output is generated #endif // OPTION_TO_STORE_ISLAND - // Only for debug it should not be here !! - double discretize_overhang_sample_in_mm = 2.; + // Configuration for data preparation + PrepareSupportConfig prepare_config; }; } // namespace Slic3r::sla #endif // slic3r_SLA_SuppotstIslands_SampleConfig_hpp_ diff --git a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp index b7565606be..91d7732bce 100644 --- a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp +++ b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp @@ -447,7 +447,8 @@ coord_t align_once( cell_svg.draw(island_cell_center, "black", config.head_radius);} #endif //SLA_SAMPLE_ISLAND_UTILS_DEBUG_CELL_DISTANCE_PATH // Check that still points do not have bigger distance from each other - assert(is_points_in_distance(island_cell_center, island_cell->points, config.max_distance)); + assert(is_points_in_distance(island_cell_center, island_cell->points, + std::max(std::max(config.thick_inner_max_distance, config.thick_outline_max_distance), config.thin_max_distance))); #ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG_PATH svg.draw(cell_polygon, color_point_cell); @@ -874,12 +875,9 @@ struct Field // border of field created by source lines and closing of tiny island ExPolygon border; - // same size as polygon.points.size() - // indexes to source island lines - // in case (index > lines.size()) it means fill the gap from tiny part of island - std::vector source_indices; - // value for source index of change from wide to tiny part of island - size_t source_index_for_change; + // Flag for each line in border whether this line needs to support + // same size as to_points(border).size() + std::vector is_outline; // inner part of field ExPolygon inner; @@ -900,10 +898,10 @@ void draw(SVG &svg, const Field &field, bool draw_border_line_indexes = false, b for (auto &line : border_lines) { size_t index = &line - &border_lines.front(); // start of holes - if (index >= field.source_indices.size()) + if (index >= field.is_outline.size()) break; Point middle_point = LineUtils::middle(line); - std::string text = std::to_string(field.source_indices[index]); + std::string text = std::to_string(field.is_outline[index]); auto item = field.field_2_inner.find(index); if (item != field.field_2_inner.end()) { text += " inner " + std::to_string(item->second); @@ -1100,8 +1098,9 @@ Field create_thick_field(const ThickPart& part, const Lines &lines, const Sample // Set largest polygon as contour set_biggest_hole_as_contour(field.border, source_indices); } - field.source_index_for_change = source_index_for_change; - field.source_indices = std::move(source_indices); + field.is_outline.reserve(source_indices.size()); + for (size_t source_index : source_indices) + field.is_outline.push_back(source_index != source_index_for_change); std::tie(field.inner, field.field_2_inner) = outline_offset(field.border, (float)config.minimal_distance_from_outline); #ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_FIELD_TO_SVG_PATH @@ -1245,7 +1244,7 @@ Slic3r::Points sample_expolygon_with_centering(const ExPolygon &expoly, coord_t SupportIslandPoints sample_outline(const Field &field, const SampleConfig &config){ const ExPolygon &border = field.border; const Polygon &contour = border.contour; - assert(field.source_indices.size() >= contour.size()); + assert(field.is_outline.size() >= contour.size()); coord_t max_align_distance = config.max_align_distance; coord_t sample_distance = config.thick_outline_max_distance; SupportIslandPoints result; @@ -1330,8 +1329,7 @@ SupportIslandPoints sample_outline(const Field &field, const SampleConfig &confi // convert map from field index to inner(line index) auto sample_polygon = [&add_circle_sample, &add_lines_samples, &field] (const Polygon &polygon, const Polygon &inner_polygon, size_t index_offset) { - const std::vector &source_indices = field.source_indices; - const size_t& change_index = field.source_index_for_change; + const std::vector &is_outline = field.is_outline; const std::map &field_2_inner = field.field_2_inner; if (inner_polygon.empty()) return; // nothing to sample @@ -1340,9 +1338,8 @@ SupportIslandPoints sample_outline(const Field &field, const SampleConfig &confi size_t first_change_index = polygon.size(); for (size_t polygon_index = 0; polygon_index < polygon.size(); ++polygon_index) { size_t index = polygon_index + index_offset; - assert(index < source_indices.size()); - size_t source_index = source_indices[index]; - if (source_index == change_index) { + assert(index < is_outline.size()); + if (!is_outline[index]) { // found change from wide to tiny part first_change_index = polygon_index; break; @@ -1350,41 +1347,50 @@ SupportIslandPoints sample_outline(const Field &field, const SampleConfig &confi } // is polygon without change - if (first_change_index == polygon.size()) { - add_circle_sample(inner_polygon); - } else { // exist change create line sequences - // initialize with non valid values - Lines inner_lines = to_lines(inner_polygon); - size_t inner_invalid = inner_lines.size(); - // first and last index to inner lines - size_t inner_first = inner_invalid; - size_t inner_last = inner_invalid; - size_t stop_index = first_change_index; - if (stop_index == 0) - stop_index = polygon.size(); - for (size_t polygon_index = first_change_index + 1; - polygon_index != stop_index; ++polygon_index) { - if (polygon_index == polygon.size()) polygon_index = 0; - size_t index = polygon_index + index_offset; - assert(index < source_indices.size()); - size_t source_index = source_indices[index]; - if (source_index == change_index) { - if (inner_first == inner_invalid) continue; - // create Restriction object - add_lines_samples(inner_lines, inner_first, inner_last); - inner_first = inner_invalid; - inner_last = inner_invalid; - continue; - } - auto convert_index_item = field_2_inner.find(index); - // check if exist inner line - if (convert_index_item == field_2_inner.end()) continue; - inner_last = convert_index_item->second - index_offset; - // initialize first index - if (inner_first == inner_invalid) inner_first = inner_last; + if (first_change_index == polygon.size()) + return add_circle_sample(inner_polygon); + + // exist change create line sequences + // initialize with non valid values + Lines inner_lines = to_lines(inner_polygon); + size_t inner_invalid = inner_lines.size(); + // first and last index to inner lines + size_t inner_first = inner_invalid; + size_t inner_last = inner_invalid; + size_t stop_index = first_change_index; + if (stop_index == 0) + stop_index = polygon.size(); + size_t polygon_index = first_change_index; + do { // search for first outline index after change + ++polygon_index; + if (polygon_index == polygon.size()) { + polygon_index = 0; + // Detect that whole polygon is not peninsula outline(coast) + if (first_change_index == 0) + return; // Polygon do not contain edge to support. } - add_lines_samples(inner_lines, inner_first, inner_last); + } while (!is_outline[polygon_index + index_offset]); + for (;polygon_index != stop_index; ++polygon_index) { + if (polygon_index == polygon.size()) polygon_index = 0; + size_t index = polygon_index + index_offset; + assert(index < is_outline.size()); + if (!is_outline[index]) { + if (inner_first == inner_invalid) continue; + // create Restriction object + add_lines_samples(inner_lines, inner_first, inner_last); + inner_first = inner_invalid; + inner_last = inner_invalid; + continue; + } + auto convert_index_item = field_2_inner.find(index); + // check if exist inner line + if (convert_index_item == field_2_inner.end()) continue; + inner_last = convert_index_item->second - index_offset; + // initialize first index + if (inner_first == inner_invalid) inner_first = inner_last; } + if (inner_first != inner_invalid) + add_lines_samples(inner_lines, inner_first, inner_last); }; // No inner space to sample @@ -2219,7 +2225,6 @@ void draw(SVG &svg, const SupportIslandPoints &supportIslandPoints, coord_t radi } } } - } // namespace ////////////////////////////// @@ -2348,6 +2353,29 @@ SupportIslandPoints uniform_support_island(const ExPolygon &island, const Sample return supports; } +// Follow implementation "create_supports_for_thick_part(" +SupportIslandPoints uniform_support_peninsula(const Peninsula &peninsula, const SampleConfig &config){ + // create_peninsula_field + Field field; + field.border = peninsula.unsuported_area; + field.is_outline = peninsula.is_outline; + std::tie(field.inner, field.field_2_inner) = + outline_offset(field.border, (float) config.minimal_distance_from_outline); + assert(!field.inner.empty()); + if (field.inner.empty()) + return {}; // no inner part + + SupportIslandPoints results = sample_outline(field, config); + // Inner must survive after sample field for aligning supports(move along outline) + auto inner = std::make_shared(field.inner); + Points inner_points = sample_expolygon_with_centering(*inner, config.thick_inner_max_distance); + std::transform(inner_points.begin(), inner_points.end(), std::back_inserter(results), + [&inner](const Point &point) { return std::make_unique( + point, inner, SupportIslandPoint::Type::thick_part_inner);}); + align_samples(results, peninsula.unsuported_area, config); + return results; +} + bool is_uniform_support_island_visualization_disabled() { #ifndef NDEBUG return false; diff --git a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.hpp b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.hpp index fb0cf2309a..b2b55d26f5 100644 --- a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.hpp +++ b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.hpp @@ -4,6 +4,7 @@ #include #include "SampleConfig.hpp" #include "SupportIslandPoint.hpp" +#include "libslic3r/SLA/SupportPointGenerator.hpp" // Peninsula namespace Slic3r::sla { @@ -15,6 +16,14 @@ namespace Slic3r::sla { /// Support points laying inside of island SupportIslandPoints uniform_support_island(const ExPolygon &island, const SampleConfig &config); +/// +/// Distribute support points across peninsula +/// +/// half island with anotation of the coast and land outline +/// Density distribution parameters +/// +SupportIslandPoints uniform_support_peninsula(const Peninsula &peninsula, const SampleConfig &config); + /// /// Check for tests that developer do not forget disable visualization after debuging. /// diff --git a/src/libslic3r/SLA/SupportPointGenerator.cpp b/src/libslic3r/SLA/SupportPointGenerator.cpp index 6b7fbe7ae6..43824ce1b3 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.cpp +++ b/src/libslic3r/SLA/SupportPointGenerator.cpp @@ -277,7 +277,6 @@ void support_part_overhangs( void support_island(const LayerPart &part, NearPoints& near_points, float part_z, const SupportPointGeneratorConfig &cfg) { SupportIslandPoints samples = uniform_support_island(*part.shape, cfg.island_configuration); - //samples = {std::make_unique(island.contour.centroid())}; for (const SupportIslandPointPtr &sample : samples) near_points.add(LayerSupportPoint{ SupportPoint{ @@ -296,6 +295,30 @@ void support_island(const LayerPart &part, NearPoints& near_points, float part_z }); } +void support_peninsulas(const Peninsulas& peninsulas, NearPoints& near_points, float part_z, + const SupportPointGeneratorConfig &cfg) { + for (const Peninsula& peninsula: peninsulas) { + SupportIslandPoints peninsula_supports = + uniform_support_peninsula(peninsula, cfg.island_configuration); + for (const SupportIslandPointPtr &support : peninsula_supports) + near_points.add(LayerSupportPoint{ + SupportPoint{ + Vec3f{ + unscale(support->point.x()), + unscale(support->point.y()), + part_z + }, + /* head_front_radius */ cfg.head_diameter / 2, + SupportPointType::island + }, + /* position_on_layer */ support->point, + /* direction_to_mass */ Point(0, 0), // direction from bottom + /* radius_curve_index */ 0, + /* current_radius */ static_cast(scale_(cfg.support_curve.front().x())) + }); + } +} + /// /// Copy parts from link to output /// @@ -503,19 +526,22 @@ void remove_supports_out_of_part(NearPoints& near_points, const LayerPart &part, /// /// IN/OUT island part containing peninsulas /// minimal width of overhang to become peninsula -void create_peninsulas(LayerPart &part, float min_peninsula_width) { +/// supported distance from mainland +void create_peninsulas(LayerPart &part, const PrepareSupportConfig &config) { + assert(config.peninsula_min_width > config.peninsula_self_supported_width); const Polygons below_polygons = get_polygons(part.prev_parts); - const Polygons below_expanded = expand(below_polygons, min_peninsula_width, ClipperLib::jtSquare); + const Polygons below_expanded = expand(below_polygons, config.peninsula_min_width, ClipperLib::jtSquare); const ExPolygon &part_shape = *part.shape; ExPolygons over_peninsula = diff_ex(part_shape, below_expanded); if (over_peninsula.empty()) return; // only tiny overhangs + Polygons below_self_supported = expand(below_polygons, config.peninsula_self_supported_width, ClipperLib::jtSquare); // exist layer part over peninsula limit - ExPolygons peninsulas_shape = diff_ex(part_shape, below_polygons); + ExPolygons peninsulas_shape = diff_ex(part_shape, below_self_supported); // IMPROVE: Anotate source of diff by ClipperLib_Z - Lines below_lines = to_lines(below_polygons); + Lines below_lines = to_lines(below_self_supported); auto get_angle = [](const Line &l) { Point diff = l.b - l.a; if (diff.x() < 0) // Only positive direction X @@ -532,11 +558,14 @@ void create_peninsulas(LayerPart &part, float min_peninsula_width) { return belowe_line_angle[i1] < belowe_line_angle[i2]; }; std::sort(idx.begin(), idx.end(), is_lower); - auto is_overlap = [&get_angle, &idx, &is_lower, &below_lines, &belowe_line_angle] + // Check, wheather line exist in set of belowe lines + // True .. line exist in previous layer (or partialy overlap previous line), connection to land + // False .. line is made by border of current layer part(peninsula coast) + auto exist_belowe = [&get_angle, &idx, &is_lower, &below_lines, &belowe_line_angle] (const Line &l) { // allowed angle epsilon - const double angle_epsilon = 1e-3; - const double paralel_epsilon = scale_(1e-2); + const double angle_epsilon = 1e-3; // < 0.06 DEG + const double paralel_epsilon = scale_(1e-2); // 10 um double angle = get_angle(l); double low_angle = angle - angle_epsilon; bool is_over = false; @@ -559,24 +588,35 @@ void create_peninsulas(LayerPart &part, float min_peninsula_width) { if (low > high) std::swap(low, high); - auto it_idx = std::lower_bound(idx.begin(), idx.end(), low_angle, is_lower); - if (is_over && it_idx == idx.end()) { - it_idx = idx.begin(); - is_over = false; + auto is_lower_angle = [&belowe_line_angle](size_t index, double angle) { + return belowe_line_angle[index] < angle; }; + auto it_idx = std::lower_bound(idx.begin(), idx.end(), low_angle, is_lower_angle); + if (it_idx == idx.end()) { + if (is_over) { + it_idx = idx.begin(); + is_over = false; + } else { + return false; + } } - while (is_over || it_idx != idx.end() || belowe_line_angle[*it_idx] < hi_angle) { + while (is_over || belowe_line_angle[*it_idx] < hi_angle) { const Line &l2 = below_lines[*it_idx]; coord_t l2_low = l2.a[mayorit_idx]; coord_t l2_high = l2.b[mayorit_idx]; if (low > high) std::swap(low, high); - if ((l2_high >= low && l2_low <= high) && - l.distance_to(l2.a) < paralel_epsilon) + if ((l2_high >= low && l2_low <= high) && ( + ((l2.a == l.a && l2.b == l.b) ||(l2.a == l.b && l2.b == l.a)) || // speed up - same line + l.perp_distance_to(l2.a) < paralel_epsilon)) // check distance of parallel lines return true; ++it_idx; - if (is_over && it_idx == idx.end()) { - it_idx = idx.begin(); - is_over = false; + if (it_idx == idx.end()){ + if (is_over) { + it_idx = idx.begin(); + is_over = false; + } else { + break; + } } } return false; @@ -584,23 +624,26 @@ void create_peninsulas(LayerPart &part, float min_peninsula_width) { // anotate source of peninsula: overhang VS previous layer for (const ExPolygon &peninsula : peninsulas_shape) { + // Check that peninsula is wide enough(min_peninsula_width) + if (intersection_ex(ExPolygons{peninsula}, over_peninsula).empty()) + continue; + // need to know shape and edges of peninsula Lines lines = to_lines(peninsula); std::vector is_outline(lines.size()); // when line overlap with belowe lines it is not outline for (size_t i = 0; i < lines.size(); i++) - is_outline[i] = is_overlap(lines[i]); + is_outline[i] = !exist_belowe(lines[i]); part.peninsulas.push_back(Peninsula{peninsula, is_outline}); } } - } // namespace #include "libslic3r/Execution/ExecutionSeq.hpp" SupportPointGeneratorData Slic3r::sla::prepare_generator_data( std::vector &&slices, const std::vector &heights, - double discretize_overhang_sample_in_mm, + const PrepareSupportConfig &config, ThrowOnCancel throw_on_cancel, StatusFunction statusfn ) { @@ -638,7 +681,7 @@ SupportPointGeneratorData Slic3r::sla::prepare_generator_data( } }, 32 /*gransize*/); - double sample_distance_in_um = scale_(discretize_overhang_sample_in_mm); + double sample_distance_in_um = scale_(config.discretize_overhang_step); double sample_distance_in_um2 = sample_distance_in_um * sample_distance_in_um; // Link parts by intersections @@ -678,15 +721,17 @@ SupportPointGeneratorData Slic3r::sla::prepare_generator_data( }, 8 /* gransize */); // Detect peninsula - float min_peninsula_width = scale_(2); // [in scaled mm] - execution::for_each(ex_seq, size_t(1), result.slices.size(), - [&layers = result.layers, &min_peninsula_width, throw_on_cancel](size_t layer_id) { - if ((layer_id % 2) == 0) + execution::for_each(ex_tbb, size_t(1), result.slices.size(), + [&layers = result.layers, &config, throw_on_cancel](size_t layer_id) { + if ((layer_id % 16) == 0) // Don't call the following function too often as it flushes CPU write caches due to synchronization primitves. throw_on_cancel(); LayerParts &parts = layers[layer_id].parts; - for (auto it_part = parts.begin(); it_part < parts.end(); ++it_part) - create_peninsulas(*it_part, min_peninsula_width); + for (auto it_part = parts.begin(); it_part < parts.end(); ++it_part) { + if (it_part->prev_parts.empty()) + continue; // island + create_peninsulas(*it_part, config); + } }, 8 /* gransize */); return result; } @@ -766,20 +811,23 @@ LayerSupportPoints Slic3r::sla::generate_support_points( grids.reserve(layer.parts.size()); for (const LayerPart &part : layer.parts) { - if (part.prev_parts.empty()) { + if (part.prev_parts.empty()) { // Island ? // only island add new grid grids.emplace_back(&result); // new island - needs support no doubt support_island(part, grids.back(), layer.print_z, config); - } else { - // first layer should have empty prev_part - assert(layer_id != 0); - const LayerParts &prev_layer_parts = layers[layer_id - 1].parts; - NearPoints near_points = create_near_points(prev_layer_parts, part, prev_grids); - remove_supports_out_of_part(near_points, part, config); - support_part_overhangs(part, config, near_points, layer.print_z, maximal_radius); - grids.push_back(std::move(near_points)); + continue; } + + // first layer should have empty prev_part + assert(layer_id != 0); + const LayerParts &prev_layer_parts = layers[layer_id - 1].parts; + NearPoints near_points = create_near_points(prev_layer_parts, part, prev_grids); + remove_supports_out_of_part(near_points, part, config); + if (!part.peninsulas.empty()) + support_peninsulas(part.peninsulas, near_points, layer.print_z, config); + support_part_overhangs(part, config, near_points, layer.print_z, maximal_radius); + grids.push_back(std::move(near_points)); } prev_grids = std::move(grids); diff --git a/src/libslic3r/SLA/SupportPointGenerator.hpp b/src/libslic3r/SLA/SupportPointGenerator.hpp index 53f53eab95..bae7bb3ba3 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.hpp +++ b/src/libslic3r/SLA/SupportPointGenerator.hpp @@ -80,11 +80,15 @@ using PartLinks = std::vector; // Large one layer overhang that needs to be supported on the overhanging side struct Peninsula{ - // shape of peninsula some of edges are overhang - ExPolygon shape; + // shape of peninsula + //ExPolygon shape; - // same size as shape lines count - // convert shape to lines by to_lines(shape) + // Prev layer is extended by self support const and subtracted from current one. + // This part of layer is supported as island + ExPolygon unsuported_area; + + // Flag for unsuported_area line about source + // Same size as Slic3r::to_lines(unsuported_area) // True .. peninsula outline(coast) // False .. connection to land(already supported by previous layer) std::vector is_outline; @@ -191,17 +195,16 @@ struct PrepareGeneratorDataConfig /// /// Countour cut from mesh /// Heights of the slices - Same size as slices -/// Discretization of overhangs outline, -/// smaller will slow down the process but will be more precise +/// Preparation parameters /// Call in meanwhile to check cancel event /// Say progress of generation into gui /// Data prepared for generate support points SupportPointGeneratorData prepare_generator_data( std::vector &&slices, const std::vector &heights, - double discretize_overhang_sample_in_mm, - ThrowOnCancel throw_on_cancel, - StatusFunction statusfn + const PrepareSupportConfig &config = {}, + ThrowOnCancel throw_on_cancel = []() {}, + StatusFunction statusfn = [](int) {} ); /// @@ -215,8 +218,8 @@ SupportPointGeneratorData prepare_generator_data( LayerSupportPoints generate_support_points( const SupportPointGeneratorData &data, const SupportPointGeneratorConfig &config, - ThrowOnCancel throw_on_cancel, - StatusFunction statusfn + ThrowOnCancel throw_on_cancel = []() {}, + StatusFunction statusfn = [](int) {} ); } // namespace Slic3r::sla @@ -235,7 +238,7 @@ SupportPoints move_on_mesh_surface( const LayerSupportPoints &points, const AABBMesh &mesh, double allowed_move, - ThrowOnCancel throw_on_cancel + ThrowOnCancel throw_on_cancel = []() {} ); }} diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp index 8adc94040f..14e2cfacbd 100644 --- a/src/libslic3r/SLAPrintSteps.cpp +++ b/src/libslic3r/SLAPrintSteps.cpp @@ -610,6 +610,7 @@ static void filter_support_points_by_modifiers(sla::SupportPoints &pts, // support points. Then we sprinkle the rest of the mesh. void SLAPrint::Steps::support_points(SLAPrintObject &po) { + using namespace sla; // If supports are disabled, we can skip the model scan. if(!po.m_config.supports_enable.getBool()) return; @@ -628,7 +629,7 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po) BOOST_LOG_TRIVIAL(debug) << "Support point count " << mo.sla_support_points.size(); - if (mo.sla_points_status == sla::PointsStatus::UserModified) { + if (mo.sla_points_status == PointsStatus::UserModified) { // There are either some points on the front-end, or the user // removed them on purpose. No calculation will be done. po.m_supportdata->input.pts = po.transformed_support_points(); @@ -637,27 +638,27 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po) // Unless the user modified the points or we already did the calculation, // we will do the autoplacement. Otherwise we will just blindly copy the // frontend data into the backend cache. - // if (mo.sla_points_status != sla::PointsStatus::UserModified) + // if (mo.sla_points_status != PointsStatus::UserModified) throw_if_canceled(); const SLAPrintObjectConfig& cfg = po.config(); // the density config value is in percents: - sla::SupportPointGeneratorConfig config; + SupportPointGeneratorConfig config; config.density_relative = float(cfg.support_points_density_relative / 100.f); switch (cfg.support_tree_type) { - case sla::SupportTreeType::Default: - case sla::SupportTreeType::Organic: + case SupportTreeType::Default: + case SupportTreeType::Organic: config.head_diameter = float(cfg.support_head_front_diameter); break; - case sla::SupportTreeType::Branching: + case SupportTreeType::Branching: config.head_diameter = float(cfg.branchingsupport_head_front_diameter); break; } // copy current configuration for sampling islands - config.island_configuration = sla::SampleConfigFactory::get_sample_config(); // copy + config.island_configuration = SampleConfigFactory::get_sample_config(); // copy // scaling for the sub operations double d = objectstep_scale * OBJ_STEP_LEVELS[slaposSupportPoints] / 100.0; @@ -678,14 +679,15 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po) std::vector slices = po.get_model_slices(); // copy const std::vector& heights = po.m_model_height_levels; - sla::ThrowOnCancel cancel = [this]() { throw_if_canceled(); }; - sla::StatusFunction status = statuscb; - double discretize = config.island_configuration.discretize_overhang_sample_in_mm; - sla::SupportPointGeneratorData data = - sla::prepare_generator_data(std::move(slices), heights, discretize, cancel, status); + ThrowOnCancel cancel = [this]() { throw_if_canceled(); }; + StatusFunction status = statuscb; - sla::LayerSupportPoints layer_support_points = - sla::generate_support_points(data, config, cancel, status); + const PrepareSupportConfig &prepare_cfg = config.island_configuration.prepare_config; + SupportPointGeneratorData data = + prepare_generator_data(std::move(slices), heights, prepare_cfg, cancel, status); + + LayerSupportPoints layer_support_points = + generate_support_points(data, config, cancel, status); const AABBMesh& emesh = po.m_supportdata->input.emesh; // Maximal move of support point to mesh surface, @@ -693,8 +695,8 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po) assert(po.m_model_height_levels.size() > 1); double allowed_move = (po.m_model_height_levels[1] - po.m_model_height_levels[0]) + std::numeric_limits::epsilon(); - sla::SupportPoints support_points = - sla::move_on_mesh_surface(layer_support_points, emesh, allowed_move, cancel); + SupportPoints support_points = + move_on_mesh_surface(layer_support_points, emesh, allowed_move, cancel); throw_if_canceled(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 4cdd4c0e02..cdff7e9fe2 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -687,9 +687,9 @@ RENDER_AGAIN: } sla::SampleConfig &sample_config = sla::SampleConfigFactory::get_sample_config(); - if (float overhang_sample_distance = sample_config.discretize_overhang_sample_in_mm; + if (float overhang_sample_distance = sample_config.prepare_config.discretize_overhang_step; m_imgui->slider_float("overhang discretization", &overhang_sample_distance, 2e-5f, 10.f, "%.2f mm")){ - sample_config.discretize_overhang_sample_in_mm = overhang_sample_distance; + sample_config.prepare_config.discretize_overhang_step = overhang_sample_distance; } else if (ImGui::IsItemHovered()) ImGui::SetTooltip("Smaller will slow down. Step for discretization overhang outline for test of support need"); diff --git a/tests/sla_print/sla_test_utils.cpp b/tests/sla_print/sla_test_utils.cpp index 8cf2af99e9..01eb222969 100644 --- a/tests/sla_print/sla_test_utils.cpp +++ b/tests/sla_print/sla_test_utils.cpp @@ -129,14 +129,11 @@ void test_supports(const std::string &obj_filename, // Create the support point generator sla::SupportPointGeneratorConfig autogencfg; - autogencfg.head_diameter = 2 * supportcfg.head_front_radius_mm; - sla::ThrowOnCancel cancel = []() {}; - sla::StatusFunction status = [](int) {}; - sla::SupportPointGeneratorData gen_data = sla::prepare_generator_data(std::move(out.model_slices), out.slicegrid, 2., cancel, status); - sla::LayerSupportPoints layer_support_points = sla::generate_support_points(gen_data, autogencfg, cancel, status); + sla::SupportPointGeneratorData gen_data = sla::prepare_generator_data(std::move(out.model_slices), out.slicegrid); + sla::LayerSupportPoints layer_support_points = sla::generate_support_points(gen_data, autogencfg); double allowed_move = (out.slicegrid[1] - out.slicegrid[0]) + std::numeric_limits::epsilon(); // Get the calculated support points. - sm.pts = sla::move_on_mesh_surface(layer_support_points, sm.emesh, allowed_move, cancel); + sm.pts = sla::move_on_mesh_surface(layer_support_points, sm.emesh, allowed_move); out.model_slices = std::move(gen_data.slices); // return ownership int validityflags = ASSUME_NO_REPAIR; @@ -474,14 +471,11 @@ sla::SupportPoints calc_support_pts( std::vector slices = slice_mesh_ex(mesh.its, heights, CLOSING_RADIUS); // Prepare the support point calculator - - sla::ThrowOnCancel cancel = []() {}; - sla::StatusFunction status = [](int) {}; - sla::SupportPointGeneratorData gen_data = sla::prepare_generator_data(std::move(slices), heights, 2., cancel, status); - sla::LayerSupportPoints layer_support_points = sla::generate_support_points(gen_data, cfg, cancel, status); + sla::SupportPointGeneratorData gen_data = sla::prepare_generator_data(std::move(slices), heights); + sla::LayerSupportPoints layer_support_points = sla::generate_support_points(gen_data, cfg); AABBMesh emesh{mesh}; double allowed_move = (heights[1] - heights[0]) + std::numeric_limits::epsilon(); // Get the calculated support points. - return sla::move_on_mesh_surface(layer_support_points, emesh, allowed_move, cancel); + return sla::move_on_mesh_surface(layer_support_points, emesh, allowed_move); }