Modify GUI for searching support generator configuration

Rename config params.
This commit is contained in:
Filip Sykala - NTB T15p 2024-12-03 09:34:52 +01:00 committed by Lukas Matena
parent fc6b8a4b65
commit 08ee5524d5
10 changed files with 198 additions and 130 deletions

View File

@ -13,9 +13,18 @@ namespace Slic3r::sla {
/// </summary>
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<coord_t>(scale_(5.));
coord_t thin_max_distance = static_cast<coord_t>(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<coord_t>(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<coord_t>(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<coord_t>(scale_(1.));
// Must be greater or equal to thick_min_width
coord_t thin_max_width = static_cast<coord_t>(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<coord_t>(scale_(1.));
// Must be smaller or equal to thin_max_width
coord_t thick_min_width = static_cast<coord_t>(scale_(1.));
// Minimal length of island's part to create tiny&thick interface
coord_t min_part_length = static_cast<coord_t>(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<coord_t>(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_

View File

@ -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<coord_t>(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;

View File

@ -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<SupportIn>;
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<SupportOutlineIslandPoint::Restriction>;
@ -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<ExPolygon>(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<SupportIslandInnerPoint>(
@ -1490,7 +1494,7 @@ using ProcessItems = std::vector<ProcessItem>;
/// <param name="part_index">Source part index</param>
/// <param name="to_type">Type for new added part</param>
/// <param name="neighbor">Edge where appear change from one state to another</param>
/// <param name="limit">min or max(min_width_for_outline_support, max_width_for_center_support_line)</param>
/// <param name="limit">min or max(thick_min_width, thin_max_width)</param>
/// <param name="lines">Island border</param>
/// <param name="config">Minimal Island part length</param>
/// <returns>index of new part inside island_parts</returns>
@ -1548,8 +1552,8 @@ size_t add_part(
/// <returns>Next part index</returns>
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

View File

@ -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);

View File

@ -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<ExPolygons> &&slices,
const std::vector<float> &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;

View File

@ -164,12 +164,15 @@ using StatusFunction= std::function<void(int)>;
/// </summary>
/// <param name="slices">Countour cut from mesh</param>
/// <param name="heights">Heights of the slices - Same size as slices</param>
/// <param name="discretize_overhang_sample_in_mm">Discretization of overhangs outline,
/// smaller will slow down the process but will be more precise</param>
/// <param name="throw_on_cancel">Call in meanwhile to check cancel event</param>
/// <param name="statusfn">Say progress of generation into gui</param>
/// <returns>Data prepared for generate support points</returns>
SupportPointGeneratorData prepare_generator_data(
std::vector<ExPolygons> &&slices,
const std::vector<float> &heights,
double discretize_overhang_sample_in_mm,
ThrowOnCancel throw_on_cancel,
StatusFunction statusfn
);

View File

@ -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<float>& 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);

View File

@ -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<float>(sample_config.head_radius));
bool exist_change = false;
if (float max_for_one = unscale<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<int>(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<float>(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<<order>>.svg";
else
sample_config.path.clear();
} else if (ImGui::IsItemHovered())
ImGui::SetTooltip("Store islands in file\n<<order>> is replaced by island order number");
ImGui::SetTooltip("Store islands into files\n<<order>> 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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(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<float>(sample_config.head_radius));
ImGui::Text("Alignment stop criteria: min_move(%.0f um), iter(%d x), max_VD_move(%.2f mm)", unscale<float>(sample_config.minimal_move)*1000, (int)sample_config.count_iteration,
unscale<float>(sample_config.max_align_distance)
);
if (exist_change){
sla::SampleConfigFactory::verify(sample_config);
}
// end of tree node
ImGui::TreePop();
}

View File

@ -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<double> 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<coord_t>(size/30);
cfg.count_iteration = 100;
cfg.max_align_distance = 0;
return cfg;
//cfg.minimal_move = static_cast<coord_t>(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<<order>>.svg";
//cfg.path = "C:/data/temp/islands/<<order>>.svg";
ExPolygons islands = createTestIslands(7 * scale_(head_diameter));
for (ExPolygon &island : islands) {
// information for debug which island cause problem

View File

@ -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<float>::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};