mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-30 21:36:57 +00:00
added option to limit polyhole edges (#12349)
Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
This commit is contained in:
@@ -1279,6 +1279,7 @@ static std::vector<std::string> s_Preset_print_options{
|
|||||||
"hole_to_polyhole",
|
"hole_to_polyhole",
|
||||||
"hole_to_polyhole_threshold",
|
"hole_to_polyhole_threshold",
|
||||||
"hole_to_polyhole_twisted",
|
"hole_to_polyhole_twisted",
|
||||||
|
"hole_to_polyhole_max_edges",
|
||||||
"mmu_segmented_region_max_width",
|
"mmu_segmented_region_max_width",
|
||||||
"mmu_segmented_region_interlocking_depth",
|
"mmu_segmented_region_interlocking_depth",
|
||||||
"small_area_infill_flow_compensation",
|
"small_area_infill_flow_compensation",
|
||||||
|
|||||||
@@ -7137,6 +7137,15 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionBool(true));
|
def->set_default_value(new ConfigOptionBool(true));
|
||||||
|
|
||||||
|
def = this->add("hole_to_polyhole_max_edges", coInt);
|
||||||
|
def->label = L("Maximum Polyhole edge count");
|
||||||
|
def->category = L("Quality");
|
||||||
|
def->tooltip = L("Maximum number of polyhole edges"
|
||||||
|
"\nThis setting limits the amount of edges a polyhole can have");
|
||||||
|
def->mode = comExpert;
|
||||||
|
def->min = 3;
|
||||||
|
def->set_default_value(new ConfigOptionInt(50));
|
||||||
|
|
||||||
def = this->add("thumbnails", coString);
|
def = this->add("thumbnails", coString);
|
||||||
def->label = L("G-code thumbnails");
|
def->label = L("G-code thumbnails");
|
||||||
def->tooltip = L("Picture sizes to be stored into a .gcode and .sl1 / .sl1s files, in the following format: \"XxY, XxY, ...\"");
|
def->tooltip = L("Picture sizes to be stored into a .gcode and .sl1 / .sl1s files, in the following format: \"XxY, XxY, ...\"");
|
||||||
|
|||||||
@@ -1225,6 +1225,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionBool, hole_to_polyhole))
|
((ConfigOptionBool, hole_to_polyhole))
|
||||||
((ConfigOptionFloatOrPercent, hole_to_polyhole_threshold))
|
((ConfigOptionFloatOrPercent, hole_to_polyhole_threshold))
|
||||||
((ConfigOptionBool, hole_to_polyhole_twisted))
|
((ConfigOptionBool, hole_to_polyhole_twisted))
|
||||||
|
((ConfigOptionInt, hole_to_polyhole_max_edges))
|
||||||
|
|
||||||
((ConfigOptionBool, overhang_reverse))
|
((ConfigOptionBool, overhang_reverse))
|
||||||
((ConfigOptionBool, overhang_reverse_internal_only))
|
((ConfigOptionBool, overhang_reverse_internal_only))
|
||||||
((ConfigOptionFloatOrPercent, overhang_reverse_threshold))
|
((ConfigOptionFloatOrPercent, overhang_reverse_threshold))
|
||||||
|
|||||||
@@ -157,10 +157,10 @@ std::vector<std::reference_wrapper<const PrintRegion>> PrintObject::all_regions(
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons create_polyholes(const Point center, const coord_t radius, const coord_t nozzle_diameter, bool multiple)
|
Polygons create_polyholes(const Point center, const coord_t radius, const coord_t nozzle_diameter, bool multiple, int max_edges)
|
||||||
{
|
{
|
||||||
// n = max(round(2 * d), 3); // for 0.4mm nozzle
|
// n = max(round(2 * d), 3); // for 0.4mm nozzle
|
||||||
size_t nb_edges = (int)std::max(3, (int)std::round(4.0 * unscaled(radius) * 0.4 / unscaled(nozzle_diameter)));
|
size_t nb_edges = (int)std::min(max_edges, std::max(3, (int)std::round(4.0 * unscaled(radius) * 0.4 / unscaled(nozzle_diameter))));
|
||||||
// cylinder(h = h, r = d / cos (180 / n), $fn = n);
|
// cylinder(h = h, r = d / cos (180 / n), $fn = n);
|
||||||
//create x polyholes by rotation if multiple
|
//create x polyholes by rotation if multiple
|
||||||
int nb_polyhole = 1;
|
int nb_polyhole = 1;
|
||||||
@@ -190,8 +190,8 @@ void PrintObject::_transform_hole_to_polyholes()
|
|||||||
{
|
{
|
||||||
// get all circular holes for each layer
|
// get all circular holes for each layer
|
||||||
// the id is center-diameter-extruderid
|
// the id is center-diameter-extruderid
|
||||||
//the tuple is Point center; float diameter_max; int extruder_id; coord_t max_variation; bool twist;
|
//the tuple is Point center; float diameter_max; int extruder_id; coord_t max_variation; bool twist; int max_edges;
|
||||||
std::vector<std::vector<std::pair<std::tuple<Point, float, int, coord_t, bool>, Polygon*>>> layerid2center;
|
std::vector<std::vector<std::pair<std::tuple<Point, float, int, coord_t, bool, int>, Polygon*>>> layerid2center;
|
||||||
for (size_t i = 0; i < this->m_layers.size(); i++) layerid2center.emplace_back();
|
for (size_t i = 0; i < this->m_layers.size(); i++) layerid2center.emplace_back();
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||||
@@ -230,9 +230,10 @@ void PrintObject::_transform_hole_to_polyholes()
|
|||||||
// SCALED_EPSILON was a bit too harsh. Now using a config, as some may want some harsh setting and some don't.
|
// SCALED_EPSILON was a bit too harsh. Now using a config, as some may want some harsh setting and some don't.
|
||||||
coord_t max_variation = std::max(SCALED_EPSILON, scale_(this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_threshold.get_abs_value(unscaled(diameter_sum / hole.points.size()))));
|
coord_t max_variation = std::max(SCALED_EPSILON, scale_(this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_threshold.get_abs_value(unscaled(diameter_sum / hole.points.size()))));
|
||||||
bool twist = this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_twisted.value;
|
bool twist = this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_twisted.value;
|
||||||
|
int max_edges = this->m_layers[layer_idx]->m_regions[region_idx]->region().config().hole_to_polyhole_max_edges.value;
|
||||||
if (diameter_max - diameter_min < max_variation * 2 && diameter_line_max - diameter_line_min < max_variation * 2) {
|
if (diameter_max - diameter_min < max_variation * 2 && diameter_line_max - diameter_line_min < max_variation * 2) {
|
||||||
layerid2center[layer_idx].emplace_back(
|
layerid2center[layer_idx].emplace_back(
|
||||||
std::tuple<Point, float, int, coord_t, bool>{center, diameter_max, layer->m_regions[region_idx]->region().config().outer_wall_filament_id.value, max_variation, twist}, & hole);
|
std::tuple<Point, float, int, coord_t, bool, int>{center, diameter_max, layer->m_regions[region_idx]->region().config().outer_wall_filament_id.value, max_variation, twist, max_edges}, & hole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,14 +244,14 @@ void PrintObject::_transform_hole_to_polyholes()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
//sort holes per center-diameter
|
//sort holes per center-diameter
|
||||||
std::map<std::tuple<Point, float, int, coord_t, bool>, std::vector<std::pair<Polygon*, int>>> id2layerz2hole;
|
std::map<std::tuple<Point, float, int, coord_t, bool, int>, std::vector<std::pair<Polygon*, int>>> id2layerz2hole;
|
||||||
|
|
||||||
//search & find hole that span at least X layers
|
//search & find hole that span at least X layers
|
||||||
const size_t min_nb_layers = 2;
|
const size_t min_nb_layers = 2;
|
||||||
for (size_t layer_idx = 0; layer_idx < this->m_layers.size(); ++layer_idx) {
|
for (size_t layer_idx = 0; layer_idx < this->m_layers.size(); ++layer_idx) {
|
||||||
for (size_t hole_idx = 0; hole_idx < layerid2center[layer_idx].size(); ++hole_idx) {
|
for (size_t hole_idx = 0; hole_idx < layerid2center[layer_idx].size(); ++hole_idx) {
|
||||||
//get all other same polygons
|
//get all other same polygons
|
||||||
std::tuple<Point, float, int, coord_t, bool>& id = layerid2center[layer_idx][hole_idx].first;
|
std::tuple<Point, float, int, coord_t, bool, int>& id = layerid2center[layer_idx][hole_idx].first;
|
||||||
float max_z = layers()[layer_idx]->print_z;
|
float max_z = layers()[layer_idx]->print_z;
|
||||||
std::vector<std::pair<Polygon*, int>> holes;
|
std::vector<std::pair<Polygon*, int>> holes;
|
||||||
holes.emplace_back(layerid2center[layer_idx][hole_idx].second, layer_idx);
|
holes.emplace_back(layerid2center[layer_idx][hole_idx].second, layer_idx);
|
||||||
@@ -258,7 +259,7 @@ void PrintObject::_transform_hole_to_polyholes()
|
|||||||
if (layers()[search_layer_idx]->print_z - layers()[search_layer_idx]->height - max_z > EPSILON) break;
|
if (layers()[search_layer_idx]->print_z - layers()[search_layer_idx]->height - max_z > EPSILON) break;
|
||||||
//search an other polygon with same id
|
//search an other polygon with same id
|
||||||
for (size_t search_hole_idx = 0; search_hole_idx < layerid2center[search_layer_idx].size(); ++search_hole_idx) {
|
for (size_t search_hole_idx = 0; search_hole_idx < layerid2center[search_layer_idx].size(); ++search_hole_idx) {
|
||||||
std::tuple<Point, float, int, coord_t, bool>& search_id = layerid2center[search_layer_idx][search_hole_idx].first;
|
std::tuple<Point, float, int, coord_t, bool, int>& search_id = layerid2center[search_layer_idx][search_hole_idx].first;
|
||||||
if (std::get<2>(id) == std::get<2>(search_id)
|
if (std::get<2>(id) == std::get<2>(search_id)
|
||||||
&& std::get<0>(id).distance_to(std::get<0>(search_id)) < std::get<3>(id)
|
&& std::get<0>(id).distance_to(std::get<0>(search_id)) < std::get<3>(id)
|
||||||
&& std::abs(std::get<1>(id) - std::get<1>(search_id)) < std::get<3>(id)
|
&& std::abs(std::get<1>(id) - std::get<1>(search_id)) < std::get<3>(id)
|
||||||
@@ -279,7 +280,7 @@ void PrintObject::_transform_hole_to_polyholes()
|
|||||||
}
|
}
|
||||||
//create a polyhole per id and replace holes points by it.
|
//create a polyhole per id and replace holes points by it.
|
||||||
for (auto entry : id2layerz2hole) {
|
for (auto entry : id2layerz2hole) {
|
||||||
Polygons polyholes = create_polyholes(std::get<0>(entry.first), std::get<1>(entry.first), scale_(print()->config().nozzle_diameter.get_at(std::get<2>(entry.first) - 1)), std::get<4>(entry.first));
|
Polygons polyholes = create_polyholes(std::get<0>(entry.first), std::get<1>(entry.first), scale_(print()->config().nozzle_diameter.get_at(std::get<2>(entry.first) - 1)), std::get<4>(entry.first), std::get<5>(entry.first));
|
||||||
for (auto& poly_to_replace : entry.second) {
|
for (auto& poly_to_replace : entry.second) {
|
||||||
Polygon polyhole = polyholes[poly_to_replace.second % polyholes.size()];
|
Polygon polyhole = polyholes[poly_to_replace.second % polyholes.size()];
|
||||||
//search the clone in layers->slices
|
//search the clone in layers->slices
|
||||||
@@ -1205,6 +1206,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||||||
|| opt_key == "hole_to_polyhole"
|
|| opt_key == "hole_to_polyhole"
|
||||||
|| opt_key == "hole_to_polyhole_threshold"
|
|| opt_key == "hole_to_polyhole_threshold"
|
||||||
|| opt_key == "hole_to_polyhole_twisted"
|
|| opt_key == "hole_to_polyhole_twisted"
|
||||||
|
|| opt_key == "hole_to_polyhole_max_edges"
|
||||||
) {
|
) {
|
||||||
steps.emplace_back(posSlice);
|
steps.emplace_back(posSlice);
|
||||||
} else if (opt_key == "enable_support") {
|
} else if (opt_key == "enable_support") {
|
||||||
|
|||||||
@@ -980,7 +980,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in
|
|||||||
|
|
||||||
toggle_line("min_width_top_surface", config->opt_bool("only_one_wall_top") || ((config->opt_float("min_length_factor") > 0.5f) && have_arachne)); // 0.5 is default value
|
toggle_line("min_width_top_surface", config->opt_bool("only_one_wall_top") || ((config->opt_float("min_length_factor") > 0.5f) && have_arachne)); // 0.5 is default value
|
||||||
|
|
||||||
for (auto el : { "hole_to_polyhole_threshold", "hole_to_polyhole_twisted" })
|
for (auto el : { "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "hole_to_polyhole_max_edges" })
|
||||||
toggle_line(el, config->opt_bool("hole_to_polyhole"));
|
toggle_line(el, config->opt_bool("hole_to_polyhole"));
|
||||||
|
|
||||||
bool has_detect_overhang_wall = config->opt_bool("detect_overhang_wall");
|
bool has_detect_overhang_wall = config->opt_bool("detect_overhang_wall");
|
||||||
|
|||||||
@@ -2647,6 +2647,7 @@ void TabPrint::build()
|
|||||||
optgroup->append_single_option_line("hole_to_polyhole", "quality_settings_precision#polyholes");
|
optgroup->append_single_option_line("hole_to_polyhole", "quality_settings_precision#polyholes");
|
||||||
optgroup->append_single_option_line("hole_to_polyhole_threshold", "quality_settings_precision#polyholes");
|
optgroup->append_single_option_line("hole_to_polyhole_threshold", "quality_settings_precision#polyholes");
|
||||||
optgroup->append_single_option_line("hole_to_polyhole_twisted", "quality_settings_precision#polyholes");
|
optgroup->append_single_option_line("hole_to_polyhole_twisted", "quality_settings_precision#polyholes");
|
||||||
|
optgroup->append_single_option_line("hole_to_polyhole_max_edges", "quality_settings_precision#polyholes");
|
||||||
|
|
||||||
optgroup = page->new_optgroup(L("Ironing"), L"param_ironing");
|
optgroup = page->new_optgroup(L("Ironing"), L"param_ironing");
|
||||||
optgroup->append_single_option_line("ironing_type", "quality_settings_ironing#type");
|
optgroup->append_single_option_line("ironing_type", "quality_settings_ironing#type");
|
||||||
|
|||||||
Reference in New Issue
Block a user