From 08ee5524d508f225836b4153af177b669110b60c Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Tue, 3 Dec 2024 09:34:52 +0100 Subject: [PATCH] Modify GUI for searching support generator configuration Rename config params. --- .../SLA/SupportIslands/SampleConfig.hpp | 28 ++- .../SupportIslands/SampleConfigFactory.cpp | 31 ++- .../SupportIslands/UniformSupportIsland.cpp | 20 +- .../SLA/SupportIslands/VoronoiGraphUtils.cpp | 12 +- src/libslic3r/SLA/SupportPointGenerator.cpp | 10 +- src/libslic3r/SLA/SupportPointGenerator.hpp | 3 + src/libslic3r/SLAPrintSteps.cpp | 5 +- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 177 ++++++++++++------ tests/sla_print/sla_supptgen_tests.cpp | 38 ++-- tests/sla_print/sla_test_utils.cpp | 4 +- 10 files changed, 198 insertions(+), 130 deletions(-) diff --git a/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp b/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp index ce502a08b1..0eb6a0f65e 100644 --- a/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp +++ b/src/libslic3r/SLA/SupportIslands/SampleConfig.hpp @@ -13,9 +13,18 @@ namespace Slic3r::sla { /// struct SampleConfig { - // Every point on island has at least one support point in maximum distance + // Maximal distance of support points on thin island's part // MUST be bigger than zero - coord_t max_distance = static_cast(scale_(5.)); + coord_t thin_max_distance = static_cast(scale_(5.)); + + // Maximal distance of support points inside of thick island's part + // MUST be bigger than zero + coord_t thick_inner_max_distance = static_cast(scale_(5.)); + + // Maximal distance of support points on outline of thick island's part + // Sample outline of Field by this value + // MUST be bigger than zero + coord_t thick_outline_max_distance = static_cast(scale_(5 * 3 / 4.)); // Support point head radius // MUST be bigger than zero @@ -44,12 +53,12 @@ struct SampleConfig float max_length_ratio_for_two_support_points = 0.25; // |--25%--Sup----50%----Sup--25%--| // Maximal width of line island supported in the middle of line - // Must be greater or equal to min_width_for_outline_support - coord_t max_width_for_center_support_line = static_cast(scale_(1.)); + // Must be greater or equal to thick_min_width + coord_t thin_max_width = static_cast(scale_(1.)); // Minimal width to be supported by outline - // Must be smaller or equal to max_width_for_center_support_line - coord_t min_width_for_outline_support = static_cast(scale_(1.)); + // Must be smaller or equal to thin_max_width + coord_t thick_min_width = static_cast(scale_(1.)); // Minimal length of island's part to create tiny&thick interface coord_t min_part_length = static_cast(scale_(1.)); @@ -61,10 +70,6 @@ struct SampleConfig // Maximal count of align iteration size_t count_iteration = 100; - // Sample outline of Field by this value - // Less than max_distance - coord_t outline_sample_distance = static_cast(scale_(5 *3/4.)); - // Maximal distance over Voronoi diagram edges to find closest point during aligning Support point coord_t max_align_distance = 0; // [scaled mm -> nanometers] @@ -77,6 +82,9 @@ struct SampleConfig // Only for debug purposes 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.; }; } // namespace Slic3r::sla #endif // slic3r_SLA_SuppotstIslands_SampleConfig_hpp_ diff --git a/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.cpp b/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.cpp index a669b76c20..057236b263 100644 --- a/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.cpp +++ b/src/libslic3r/SLA/SupportIslands/SampleConfigFactory.cpp @@ -33,21 +33,21 @@ bool SampleConfigFactory::verify(SampleConfig &cfg) { }; bool res = true; res &= verify_min_max(cfg.max_length_for_one_support_point, cfg.max_length_for_two_support_points); - res &= verify_min_max(cfg.min_width_for_outline_support, cfg.max_width_for_center_support_line); // check histeresis + res &= verify_min_max(cfg.thick_min_width, cfg.thin_max_width); // check histeresis res &= verify_max(cfg.max_length_for_one_support_point, - 2 * cfg.max_distance + + 2 * cfg.thin_max_distance + 2 * cfg.head_radius + 2 * cfg.minimal_distance_from_outline); res &= verify_min(cfg.max_length_for_one_support_point, 2 * cfg.head_radius + 2 * cfg.minimal_distance_from_outline); res &= verify_max(cfg.max_length_for_two_support_points, - 2 * cfg.max_distance + + 2 * cfg.thin_max_distance + 2 * 2 * cfg.head_radius + 2 * cfg.minimal_distance_from_outline); - res &= verify_min(cfg.max_width_for_center_support_line, + res &= verify_min(cfg.thin_max_width, 2 * cfg.head_radius + 2 * cfg.minimal_distance_from_outline); - res &= verify_max(cfg.max_width_for_center_support_line, - 2 * cfg.max_distance + 2 * cfg.head_radius); + res &= verify_max(cfg.thin_max_width, + 2 * cfg.thin_max_distance + 2 * cfg.head_radius); if (!res) while (!verify(cfg)); return res; } @@ -55,16 +55,16 @@ bool SampleConfigFactory::verify(SampleConfig &cfg) { SampleConfig SampleConfigFactory::create(float support_head_diameter_in_mm) { coord_t head_diameter = static_cast(scale_(support_head_diameter_in_mm)); - coord_t minimal_distance = head_diameter * 7; - coord_t min_distance = head_diameter / 2 + minimal_distance; - coord_t max_distance = 3 * min_distance; + coord_t max_distance = head_diameter * 22.5; // 0.4 * 22.5 = 9mm // TODO: find valid params !!!! SampleConfig result; - result.max_distance = max_distance; + result.thin_max_distance = max_distance; + result.thick_inner_max_distance = max_distance; + result.thick_outline_max_distance = (max_distance / 4) * 3; result.head_radius = head_diameter / 2; result.minimal_distance_from_outline = result.head_radius; - result.maximal_distance_from_outline = result.max_distance/3; + result.maximal_distance_from_outline = max_distance/3; assert(result.minimal_distance_from_outline < result.maximal_distance_from_outline); result.max_length_for_one_support_point = max_distance / 3 + @@ -72,19 +72,18 @@ SampleConfig SampleConfigFactory::create(float support_head_diameter_in_mm) head_diameter; result.max_length_for_two_support_points = result.max_length_for_one_support_point + max_distance / 2; - result.max_width_for_center_support_line = + result.thin_max_width = 2 * head_diameter + 2 * result.minimal_distance_from_outline + max_distance / 2; - result.min_width_for_outline_support = result.max_width_for_center_support_line - 2 * head_diameter; - result.outline_sample_distance = 3 * result.max_distance/4; - result.min_part_length = result.max_distance; + result.thick_min_width = result.thin_max_width - 2 * head_diameter; + result.min_part_length = max_distance; // Align support points // TODO: propagate print resolution result.minimal_move = scale_(0.1); // 0.1 mm is enough // [in nanometers --> 0.01mm ], devide from print resolution to quater pixel is too strict result.count_iteration = 30; // speed VS precission - result.max_align_distance = result.max_distance / 2; + result.max_align_distance = max_distance / 2; verify(result); return result; diff --git a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp index 1af884330d..b7565606be 100644 --- a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp +++ b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp @@ -368,7 +368,11 @@ coord_t align_once( // IMPROVE1: add accessor to point coordinate do not copy points // IMPROVE2: add filter for create cell polygon only for moveable samples Points points = to_points(supports); - Polygons cell_polygons = create_voronoi_cells_cgal(points, config.max_distance); + coord_t max_distance = std::max(std::max( + config.thin_max_distance, + config.thick_inner_max_distance), + config.thick_outline_max_distance); + Polygons cell_polygons = create_voronoi_cells_cgal(points, max_distance); #ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG_PATH std::string color_of_island = "#FF8080"; // LightRed. Should not be visible - cell color should overlap @@ -569,7 +573,7 @@ void create_supports_for_thin_part( }; using SupportIns = std::vector; - coord_t support_distance = config.max_distance; + coord_t support_distance = config.thin_max_distance; coord_t half_support_distance = support_distance / 2; // Current neighbor @@ -1243,7 +1247,7 @@ SupportIslandPoints sample_outline(const Field &field, const SampleConfig &confi const Polygon &contour = border.contour; assert(field.source_indices.size() >= contour.size()); coord_t max_align_distance = config.max_align_distance; - coord_t sample_distance = config.outline_sample_distance; + coord_t sample_distance = config.thick_outline_max_distance; SupportIslandPoints result; using RestrictionPtr = std::shared_ptr; @@ -1424,7 +1428,7 @@ void create_supports_for_thick_part(const ThickPart &part, SupportIslandPoints & std::move_iterator(outline_support.end())); // 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.max_distance); + 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), [&](const Point &point) { return std::make_unique( @@ -1490,7 +1494,7 @@ using ProcessItems = std::vector; /// Source part index /// Type for new added part /// Edge where appear change from one state to another -/// min or max(min_width_for_outline_support, max_width_for_center_support_line) +/// min or max(thick_min_width, thin_max_width) /// Island border /// Minimal Island part length /// index of new part inside island_parts @@ -1548,8 +1552,8 @@ size_t add_part( /// Next part index size_t detect_interface(IslandParts &island_parts, size_t part_index, const Neighbor *neighbor, const Lines &lines, const SampleConfig &config) { // Range for of hysterezis between thin and thick part of island - coord_t min = config.min_width_for_outline_support; - coord_t max = config.max_width_for_center_support_line; + coord_t min = config.thick_min_width; + coord_t max = config.thin_max_width; size_t next_part_index = part_index; switch (island_parts[part_index].type) { @@ -2281,7 +2285,7 @@ SupportIslandPoints uniform_support_island(const ExPolygon &island, const Sample } // 2) Two support points have to stretch island even if haed is not fully under island. - if (VoronoiGraphUtils::get_max_width(longest_path) < config.max_width_for_center_support_line && + if (VoronoiGraphUtils::get_max_width(longest_path) < config.thin_max_width && longest_path.length < config.max_length_for_two_support_points) { SupportIslandPoints supports = create_side_points(longest_path, lines, config); #ifdef OPTION_TO_STORE_ISLAND diff --git a/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp b/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp index 871ee2f1a8..78d89dbdec 100644 --- a/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp +++ b/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp @@ -1323,16 +1323,16 @@ void VoronoiGraphUtils::draw(SVG & svg, "darkgreen" // thick (min+max above thick) }; auto get_color = [&](const VoronoiGraph::Node::Neighbor &n) { - if (n.min_width() > config.max_width_for_center_support_line){ + if (n.min_width() > config.thin_max_width){ return skeleton_colors[4]; - } else if (n.max_width() < config.min_width_for_outline_support){ + } else if (n.max_width() < config.thick_min_width){ return skeleton_colors[0]; - } else if (n.min_width() < config.max_width_for_center_support_line && - n.max_width() > config.min_width_for_outline_support){ + } else if (n.min_width() < config.thin_max_width && + n.max_width() > config.thick_min_width){ return skeleton_colors[2]; - } else if (n.min_width() < config.min_width_for_outline_support){ + } else if (n.min_width() < config.thick_min_width){ return skeleton_colors[1]; - } else if (n.max_width() > config.max_width_for_center_support_line) { + } else if (n.max_width() > config.thin_max_width) { return skeleton_colors[3]; } assert(false); diff --git a/src/libslic3r/SLA/SupportPointGenerator.cpp b/src/libslic3r/SLA/SupportPointGenerator.cpp index a01d29a971..7cf559d80e 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.cpp +++ b/src/libslic3r/SLA/SupportPointGenerator.cpp @@ -501,10 +501,10 @@ void remove_supports_out_of_part(NearPoints& near_points, const LayerPart &part, } // 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, ThrowOnCancel throw_on_cancel, StatusFunction statusfn ) { @@ -542,12 +542,12 @@ SupportPointGeneratorData Slic3r::sla::prepare_generator_data( } }, 32 /*gransize*/); - const double sample_distance_in_mm = scale_(2); - const double sample_distance_in_mm2 = sample_distance_in_mm * sample_distance_in_mm; + double sample_distance_in_um = scale_(discretize_overhang_sample_in_mm); + double sample_distance_in_um2 = sample_distance_in_um * sample_distance_in_um; // Link parts by intersections execution::for_each(ex_seq, size_t(1), result.slices.size(), - [&result, sample_distance_in_mm2, throw_on_cancel](size_t layer_id) { + [&result, sample_distance_in_um2, throw_on_cancel](size_t layer_id) { if ((layer_id % 2) == 0) // Don't call the following function too often as it flushes CPU write caches due to synchronization primitves. throw_on_cancel(); @@ -577,7 +577,7 @@ SupportPointGeneratorData Slic3r::sla::prepare_generator_data( // IMPROVE: overhangs could be calculated with Z coordninate // soo one will know source shape of point and do not have to search this information // Get inspiration at https://github.com/Prusa-Development/PrusaSlicerPrivate/blob/e00c46f070ec3d6fc325640b0dd10511f8acf5f7/src/libslic3r/PerimeterGenerator.cpp#L399 - it_above->samples = sample_overhangs(*it_above, sample_distance_in_mm2); + it_above->samples = sample_overhangs(*it_above, sample_distance_in_um2); } }, 8 /* gransize */); return result; diff --git a/src/libslic3r/SLA/SupportPointGenerator.hpp b/src/libslic3r/SLA/SupportPointGenerator.hpp index 63f6ae56b1..86f69c3742 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.hpp +++ b/src/libslic3r/SLA/SupportPointGenerator.hpp @@ -164,12 +164,15 @@ using StatusFunction= std::function; /// /// 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 /// 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 ); diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp index 5cf8f98aaf..8adc94040f 100644 --- a/src/libslic3r/SLAPrintSteps.cpp +++ b/src/libslic3r/SLAPrintSteps.cpp @@ -657,7 +657,7 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po) } // copy current configuration for sampling islands - config.island_configuration = sla::SampleConfigFactory::get_sample_config(); + config.island_configuration = sla::SampleConfigFactory::get_sample_config(); // copy // scaling for the sub operations double d = objectstep_scale * OBJ_STEP_LEVELS[slaposSupportPoints] / 100.0; @@ -680,8 +680,9 @@ void SLAPrint::Steps::support_points(SLAPrintObject &po) 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, cancel, status); + sla::prepare_generator_data(std::move(slices), heights, discretize, cancel, status); sla::LayerSupportPoints layer_support_points = sla::generate_support_points(data, config, cancel, status); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 58fce55160..4cdd4c0e02 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -686,6 +686,13 @@ RENDER_AGAIN: ImGui::SetTooltip("Divider for the supported radius\nSmaller mean less point(75% -> supported radius is enlaged to 133%, for 50% it is 200% of radius)\nLarger mean more points(125% -> supported radius is reduced to 80%, for value 150% it is 66% of radius, for 200% -> 50%)"); } + sla::SampleConfig &sample_config = sla::SampleConfigFactory::get_sample_config(); + if (float overhang_sample_distance = sample_config.discretize_overhang_sample_in_mm; + 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; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Smaller will slow down. Step for discretization overhang outline for test of support need"); + draw_island_config(); @@ -814,13 +821,121 @@ void GLGizmoSlaSupports::draw_island_config() { return; // no need to draw configuration for islands sla::SampleConfig &sample_config = sla::SampleConfigFactory::get_sample_config(); + ImGui::SameLine(); + ImGui::Text("head radius %.2f mm", unscale(sample_config.head_radius)); + + bool exist_change = false; + + if (float max_for_one = unscale(sample_config.max_length_for_one_support_point); // [in mm] + ImGui::InputFloat("One support", &max_for_one, .1f, 1.f, "%.2f mm")) { + sample_config.max_length_for_one_support_point = scale_(max_for_one); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Maximal island length (longest voronoi path)\n" + "for support island by exactly one point.\n" + "Point will be on the longest path center"); + + if (float max_for_two = unscale(sample_config.max_length_for_two_support_points); // [in mm] + ImGui::InputFloat("Two supports", &max_for_two, .1f, 1.f, "%.2f mm")) { + sample_config.max_length_for_two_support_points = scale_(max_for_two); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Maximal island length (longest voronoi path)\n" + "for support by 2 points on path sides\n" + "To stretch the island."); + if (float thin_max_width = unscale(sample_config.thin_max_width); // [in mm] + ImGui::InputFloat("Thin max width", &thin_max_width, .1f, 1.f, "%.2f mm")) { + sample_config.thin_max_width = scale_(thin_max_width); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Maximal width of line island supported in the middle of line\n" + "Must be greater than thick min width(to make hysteresis)"); + if (float thick_min_width = unscale(sample_config.thick_min_width); // [in mm] + ImGui::InputFloat("Thick min width", &thick_min_width, .1f, 1.f, "%.2f mm")) { + sample_config.thick_min_width = scale_(thick_min_width); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Minimal width to be supported by outline\n" + "Must be smaller than thin max width(to make hysteresis)"); + if (float max_distance = unscale(sample_config.thin_max_distance); // [in mm] + ImGui::InputFloat("Thin max distance", &max_distance, .1f, 1.f, "%.2f mm")) { + sample_config.thin_max_distance = scale_(max_distance); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Maximal distance of supports on thin island's part"); + if (float max_distance = unscale(sample_config.thick_inner_max_distance); // [in mm] + ImGui::InputFloat("Thick inner max distance", &max_distance, .1f, 1.f, "%.2f mm")) { + sample_config.thick_inner_max_distance = scale_(max_distance); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Maximal distance of supports inside thick island's part"); + if (float max_distance = unscale(sample_config.thick_outline_max_distance); // [in mm] + ImGui::InputFloat("Thick outline max distance", &max_distance, .1f, 1.f, "%.2f mm")) { + sample_config.thick_outline_max_distance = scale_(max_distance); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Maximal distance of supports on thick island's part outline"); + + if (float minimal_distance_from_outline = unscale(sample_config.minimal_distance_from_outline); // [in mm] + ImGui::InputFloat("From outline", &minimal_distance_from_outline, .1f, 1.f, "%.2f mm")) { + sample_config.minimal_distance_from_outline = scale_(minimal_distance_from_outline); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("When it is possible, there will be this minimal distance from outline.\n" + "ZERO mean head center will lay on island outline\n" + "IMHO value should be bigger than head radius"); + ImGui::SameLine(); + if (float maximal_distance_from_outline = unscale(sample_config.maximal_distance_from_outline); // [in mm] + ImGui::InputFloat("Max", &maximal_distance_from_outline, .1f, 1.f, "%.2f mm")) { + sample_config.maximal_distance_from_outline = scale_(maximal_distance_from_outline); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Measured as sum of VD edge length from outline\n" + "Used only when there is no space for outline offset on first/last point\n" + "Must be bigger than value 'From outline'"); + + if (float simplification_tolerance = unscale(sample_config.simplification_tolerance); // [in mm] + ImGui::InputFloat("Simplify", &simplification_tolerance, .1f, 1.f, "%.2f mm")) { + sample_config.simplification_tolerance = scale_(simplification_tolerance); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("There is no need to calculate with precisse island Voronoi\n" + "NOTE: Slice of Cylinder bottom has tip of trinagles on contour\n" + "(neighbor coordinate -> create issue in boost::voronoi)\n" + "Bigger value will speed up"); + ImGui::Text("Aligning termination criteria:"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("After initial support placement on island, supports are aligned\n" + "to more uniformly support area of irregular island shape"); + if (int count = static_cast(sample_config.count_iteration); + ImGui::SliderInt("max iteration", &count, 0, 100, "%d loops" )){ + sample_config.count_iteration = count; + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Align termination condition, max count of aligning calls"); + if (float minimal_move = unscale(sample_config.minimal_move); // [in mm] + ImGui::InputFloat("minimal move", &minimal_move, .1f, 1.f, "%.2f mm")) { + sample_config.minimal_move = scale_(minimal_move); + exist_change = true; + } else if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Align termination condition, when support points after align did not change their position more,\n" + "than this distance it is deduce that supports are aligned enough.\n" + "Bigger value mean speed up of aligning"); + + if (exist_change){ + sla::SampleConfigFactory::verify(sample_config); + } + + #ifdef OPTION_TO_STORE_ISLAND bool store_islands = !sample_config.path.empty(); if (ImGui::Checkbox("StoreIslands", &store_islands)) { if (store_islands == true) sample_config.path = "C:/data/temp/island<>.svg"; + else + sample_config.path.clear(); } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Store islands in file\n<> is replaced by island order number"); + ImGui::SetTooltip("Store islands into files\n<> is replaced by island order number"); if (store_islands) { ImGui::SameLine(); std::string path; @@ -828,66 +943,6 @@ void GLGizmoSlaSupports::draw_island_config() { } #endif // OPTION_TO_STORE_ISLAND - bool exist_change = false; - if (float simplification_tolerance = unscale(sample_config.simplification_tolerance); // [in mm] - ImGui::InputFloat("input simplify", &simplification_tolerance, .1f, 1.f, "%.2f mm")) { - sample_config.simplification_tolerance = scale_(simplification_tolerance); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("There is no need to calculate with precisse island\nNOTE: Slice of Cylinder bottom has tip of trinagles on contour\n(neighbor coordinate -> create issue in boost::voronoi)"); - if (float max_distance = unscale(sample_config.max_distance); // [in mm] - ImGui::InputFloat("Max dist", &max_distance, .1f, 1.f, "%.2f mm")) { - sample_config.max_distance = scale_(max_distance); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Every support point on island has at least one support point in maximum distance\nMUST be bigger than zero"); - if (float minimal_distance_from_outline = unscale(sample_config.minimal_distance_from_outline); // [in mm] - ImGui::InputFloat("from outline", &minimal_distance_from_outline, .1f, 1.f, "%.2f mm")) { - sample_config.minimal_distance_from_outline = scale_(minimal_distance_from_outline); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("When it is possible, there will be this minimal distance from outline.\nZERO when head center should be on outline\nSHOULD be positive number"); - ImGui::SameLine(); - if (float maximal_distance_from_outline = unscale(sample_config.maximal_distance_from_outline); // [in mm] - ImGui::InputFloat("max from outline", &maximal_distance_from_outline, .1f, 1.f, "%.2f mm")) { - sample_config.maximal_distance_from_outline = scale_(maximal_distance_from_outline); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Measured as sum of VD edge length from outline\nUsed only when there is no space for outline offset on first/last point\nMust be bigger than minimal_distance_from_outline"); - if (float max_for_one = unscale(sample_config.max_length_for_one_support_point); // [in mm] - ImGui::InputFloat("Max len for one", &max_for_one, .1f, 1.f, "%.2f mm")) { - sample_config.max_length_for_one_support_point = scale_(max_for_one); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Maximal island length (longest voronoi path) for support by point in path center"); - if (float max_for_two = unscale(sample_config.max_length_for_two_support_points); // [in mm] - ImGui::InputFloat("Max len for two", &max_for_two, .1f, 1.f, "%.2f mm")) { - sample_config.max_length_for_two_support_points = scale_(max_for_two); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Maximal island length (longest voronoi path)\n for support by 2 points on path sides"); - if (float max_width_for_center_support_line = unscale(sample_config.max_width_for_center_support_line); // [in mm] - ImGui::InputFloat("thin max width", &max_width_for_center_support_line, .1f, 1.f, "%.2f mm")) { - sample_config.max_width_for_center_support_line = scale_(max_width_for_center_support_line); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Maximal width of line island supported in the middle of line\nMust be greater or equal to thick min width(to make hysteresis)"); - if (float min_width_for_outline_support = unscale(sample_config.min_width_for_outline_support); // [in mm] - ImGui::InputFloat("thick min width", &min_width_for_outline_support, .1f, 1.f, "%.2f mm")) { - sample_config.min_width_for_outline_support = scale_(min_width_for_outline_support); - exist_change = true; - } else if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Minimal width to be supported by outline\nMust be smaller or equal to thin max width(to make hysteresis)"); - - ImGui::Text("head radius is set to %.2f", unscale(sample_config.head_radius)); - ImGui::Text("Alignment stop criteria: min_move(%.0f um), iter(%d x), max_VD_move(%.2f mm)", unscale(sample_config.minimal_move)*1000, (int)sample_config.count_iteration, - unscale(sample_config.max_align_distance) - ); - - if (exist_change){ - sla::SampleConfigFactory::verify(sample_config); - } - // end of tree node ImGui::TreePop(); } diff --git a/tests/sla_print/sla_supptgen_tests.cpp b/tests/sla_print/sla_supptgen_tests.cpp index 7fe30a6085..167af98a05 100644 --- a/tests/sla_print/sla_supptgen_tests.cpp +++ b/tests/sla_print/sla_supptgen_tests.cpp @@ -357,8 +357,6 @@ ExPolygons createTestIslands(double size) bool useFrogLeg = false; // need post reorganization of longest path ExPolygons result = { - // debug - // one support point ExPolygon(PolygonUtils::create_equilateral_triangle(size)), ExPolygon(PolygonUtils::create_square(size)), @@ -456,7 +454,7 @@ SupportIslandPoints test_island_sampling(const ExPolygon & island, Points chck_points = rasterize(island, config.head_radius); // TODO: Use resolution of printer bool is_ok = true; - double max_distance = config.max_distance; + double max_distance = config.thick_inner_max_distance; std::vector point_distances(chck_points.size(), {max_distance + 1}); for (size_t index = 0; index < chck_points.size(); ++index) { @@ -505,24 +503,24 @@ SupportIslandPoints test_island_sampling(const ExPolygon & island, } SampleConfig create_sample_config(double size) { - //SupportPointGenerator::Config spg_config; - //return SampleConfigFactory::create(spg_config); + float head_diameter = .4f; + return SampleConfigFactory::create(head_diameter); - SampleConfig cfg; - cfg.max_distance = 3 * size + 0.1; - cfg.head_radius = size / 4; - cfg.minimal_distance_from_outline = cfg.head_radius; - cfg.maximal_distance_from_outline = cfg.max_distance/4; - cfg.max_length_for_one_support_point = 2*size; - cfg.max_length_for_two_support_points = 4*size; - cfg.max_width_for_center_support_line = size; - cfg.min_width_for_outline_support = cfg.max_width_for_center_support_line; - cfg.outline_sample_distance = cfg.max_distance; + //coord_t max_distance = 3 * size + 0.1; + //SampleConfig cfg; + //cfg.head_radius = size / 4; + //cfg.minimal_distance_from_outline = cfg.head_radius; + //cfg.maximal_distance_from_outline = max_distance/4; + //cfg.max_length_for_one_support_point = 2*size; + //cfg.max_length_for_two_support_points = 4*size; + //cfg.thin_max_width = size; + //cfg.thick_min_width = cfg.thin_max_width; + //cfg.thick_outline_max_distance = max_distance; - cfg.minimal_move = static_cast(size/30); - cfg.count_iteration = 100; - cfg.max_align_distance = 0; - return cfg; + //cfg.minimal_move = static_cast(size/30); + //cfg.count_iteration = 100; + //cfg.max_align_distance = 0; + //return cfg; } #ifdef STORE_SAMPLE_INTO_SVG_FILES @@ -559,7 +557,7 @@ TEST_CASE("Uniform sample test islands", "[SupGen], [VoronoiSkeleton]") { float head_diameter = .4f; SampleConfig cfg = SampleConfigFactory::create(head_diameter); - //cfg.path = "C:/data/temp/island<>.svg"; + //cfg.path = "C:/data/temp/islands/<>.svg"; ExPolygons islands = createTestIslands(7 * scale_(head_diameter)); for (ExPolygon &island : islands) { // information for debug which island cause problem diff --git a/tests/sla_print/sla_test_utils.cpp b/tests/sla_print/sla_test_utils.cpp index 17331335da..8cf2af99e9 100644 --- a/tests/sla_print/sla_test_utils.cpp +++ b/tests/sla_print/sla_test_utils.cpp @@ -132,7 +132,7 @@ void test_supports(const std::string &obj_filename, 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, cancel, status); + 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); double allowed_move = (out.slicegrid[1] - out.slicegrid[0]) + std::numeric_limits::epsilon(); // Get the calculated support points. @@ -477,7 +477,7 @@ sla::SupportPoints calc_support_pts( sla::ThrowOnCancel cancel = []() {}; sla::StatusFunction status = [](int) {}; - sla::SupportPointGeneratorData gen_data = sla::prepare_generator_data(std::move(slices), heights, cancel, status); + 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); AABBMesh emesh{mesh};