mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-16 20:25:54 +08:00
add hole_to_polyhole_threshold to allow user-defined margin
supermerill/SuperSlicer#924
This commit is contained in:
parent
612c049660
commit
43d0d22532
@ -94,10 +94,13 @@ group:Modifying slices
|
|||||||
setting:width$6:first_layer_size_compensation
|
setting:width$6:first_layer_size_compensation
|
||||||
end_line
|
end_line
|
||||||
line:Vertical Hole shrinking compensation
|
line:Vertical Hole shrinking compensation
|
||||||
setting:hole_to_polyhole
|
|
||||||
setting:width$6:hole_size_compensation
|
setting:width$6:hole_size_compensation
|
||||||
setting:width$6:hole_size_threshold
|
setting:width$6:hole_size_threshold
|
||||||
end_line
|
end_line
|
||||||
|
line:Convert round vertical holes to polyholes
|
||||||
|
setting:label$:hole_to_polyhole
|
||||||
|
setting:hole_to_polyhole_threshold
|
||||||
|
end_line
|
||||||
group:Other
|
group:Other
|
||||||
setting:clip_multipart_objects
|
setting:clip_multipart_objects
|
||||||
setting:allow_empty_layers
|
setting:allow_empty_layers
|
||||||
|
@ -565,6 +565,7 @@ const std::vector<std::string>& Preset::print_options()
|
|||||||
"hole_size_compensation",
|
"hole_size_compensation",
|
||||||
"hole_size_threshold",
|
"hole_size_threshold",
|
||||||
"hole_to_polyhole",
|
"hole_to_polyhole",
|
||||||
|
"hole_to_polyhole_threshold",
|
||||||
"threads", "resolution",
|
"threads", "resolution",
|
||||||
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging",
|
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging",
|
||||||
"wipe_tower_brim",
|
"wipe_tower_brim",
|
||||||
|
@ -4270,6 +4270,18 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionBool(false));
|
def->set_default_value(new ConfigOptionBool(false));
|
||||||
|
|
||||||
|
def = this->add("hole_to_polyhole_threshold", coFloatOrPercent);
|
||||||
|
def->label = L("Roundness margin");
|
||||||
|
def->full_label = L("Polyhole detection margin");
|
||||||
|
def->category = OptionCategory::slicing;
|
||||||
|
def->tooltip = L("Maximum defection of a point to the estimated radius of the circle."
|
||||||
|
"\nAs cylinder are often exported as triangles of varying size, point may not be on the circle circumference."
|
||||||
|
" This setting allow you some leway to browden the detection."
|
||||||
|
"\nIn mm or in % of the radius.");
|
||||||
|
def->sidetext = L("mm²");
|
||||||
|
def->mode = comExpert;
|
||||||
|
def->set_default_value(new ConfigOptionFloatOrPercent(0.01, false));
|
||||||
|
|
||||||
def = this->add("z_offset", coFloat);
|
def = this->add("z_offset", coFloat);
|
||||||
def->label = L("Z offset");
|
def->label = L("Z offset");
|
||||||
def->category = OptionCategory::general;
|
def->category = OptionCategory::general;
|
||||||
@ -5406,6 +5418,7 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
|
|||||||
"hole_size_compensation",
|
"hole_size_compensation",
|
||||||
"hole_size_threshold",
|
"hole_size_threshold",
|
||||||
"hole_to_polyhole",
|
"hole_to_polyhole",
|
||||||
|
"hole_to_polyhole_threshold",
|
||||||
"z_step",
|
"z_step",
|
||||||
"milling_cutter",
|
"milling_cutter",
|
||||||
"milling_diameter",
|
"milling_diameter",
|
||||||
|
@ -776,6 +776,7 @@ public:
|
|||||||
ConfigOptionFloatOrPercent infill_anchor;
|
ConfigOptionFloatOrPercent infill_anchor;
|
||||||
ConfigOptionFloatOrPercent infill_anchor_max;
|
ConfigOptionFloatOrPercent infill_anchor_max;
|
||||||
ConfigOptionBool hole_to_polyhole;
|
ConfigOptionBool hole_to_polyhole;
|
||||||
|
ConfigOptionFloatOrPercent hole_to_polyhole_threshold;
|
||||||
ConfigOptionInt infill_extruder;
|
ConfigOptionInt infill_extruder;
|
||||||
ConfigOptionFloatOrPercent infill_extrusion_width;
|
ConfigOptionFloatOrPercent infill_extrusion_width;
|
||||||
ConfigOptionInt infill_every_layers;
|
ConfigOptionInt infill_every_layers;
|
||||||
@ -888,6 +889,7 @@ protected:
|
|||||||
OPT_PTR(infill_anchor);
|
OPT_PTR(infill_anchor);
|
||||||
OPT_PTR(infill_anchor_max);
|
OPT_PTR(infill_anchor_max);
|
||||||
OPT_PTR(hole_to_polyhole);
|
OPT_PTR(hole_to_polyhole);
|
||||||
|
OPT_PTR(hole_to_polyhole_threshold);
|
||||||
OPT_PTR(infill_extruder);
|
OPT_PTR(infill_extruder);
|
||||||
OPT_PTR(infill_extrusion_width);
|
OPT_PTR(infill_extrusion_width);
|
||||||
OPT_PTR(infill_every_layers);
|
OPT_PTR(infill_every_layers);
|
||||||
|
@ -169,7 +169,7 @@ namespace Slic3r {
|
|||||||
{
|
{
|
||||||
// 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
|
||||||
std::vector<std::vector<std::pair<std::tuple<Point, float, int>, Polygon*>>> layerid2center;
|
std::vector<std::vector<std::pair<std::tuple<Point, float, int, coord_t>, 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()),
|
||||||
@ -185,27 +185,20 @@ namespace Slic3r {
|
|||||||
//test if convex (as it's clockwise bc it's a hole, we have to do the opposite)
|
//test if convex (as it's clockwise bc it's a hole, we have to do the opposite)
|
||||||
if (hole.convex_points().empty() && hole.points.size() > 8) {
|
if (hole.convex_points().empty() && hole.points.size() > 8) {
|
||||||
// Computing circle center
|
// Computing circle center
|
||||||
double center_x = 0, center_y = 0;
|
Point center = hole.centroid();
|
||||||
double lines_length = 0;
|
|
||||||
for (Line l : hole.lines()) {
|
|
||||||
center_x += l.a.x() * l.length();
|
|
||||||
center_x += l.b.x() * l.length();
|
|
||||||
center_y += l.a.y() * l.length();
|
|
||||||
center_y += l.b.y() * l.length();
|
|
||||||
lines_length += l.length() + l.length();
|
|
||||||
}
|
|
||||||
Point center{ center_x / lines_length, center_y / lines_length };
|
|
||||||
// check for roundeness
|
|
||||||
double diameter_min = std::numeric_limits<float>::max(), diameter_max = 0;
|
double diameter_min = std::numeric_limits<float>::max(), diameter_max = 0;
|
||||||
|
double diameter_sum = 0;
|
||||||
for (int i = 0; i < hole.points.size(); ++i) {
|
for (int i = 0; i < hole.points.size(); ++i) {
|
||||||
double dist = hole.points[i].distance_to(center);
|
double dist = hole.points[i].distance_to(center);
|
||||||
diameter_min = std::min(diameter_min, dist);
|
diameter_min = std::min(diameter_min, dist);
|
||||||
diameter_max = std::max(diameter_max, dist);
|
diameter_max = std::max(diameter_max, dist);
|
||||||
|
diameter_sum += dist;
|
||||||
}
|
}
|
||||||
// SCALED_EPSILON was a bit too harsh.
|
// SCALED_EPSILON was a bit too harsh. Now using a config, as some may want some harsh setting and some don't.
|
||||||
if (diameter_max - diameter_min < 1000) {
|
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()))));
|
||||||
|
if (diameter_max - diameter_min < max_variation * 2) {
|
||||||
layerid2center[layer_idx].emplace_back(
|
layerid2center[layer_idx].emplace_back(
|
||||||
std::tuple<Point, float, int>{center, diameter_max, layer->m_regions[region_idx]->region()->config().perimeter_extruder.value}, & hole);
|
std::tuple<Point, float, int, coord_t>{center, diameter_max, layer->m_regions[region_idx]->region()->config().perimeter_extruder.value, max_variation}, & hole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +209,7 @@ namespace Slic3r {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
//sort holes per center-diameter
|
//sort holes per center-diameter
|
||||||
std::map<std::tuple<Point, float, int>, std::vector<std::pair<Polygon*, int>>> id2layerz2hole;
|
std::map<std::tuple<Point, float, int, coord_t>, 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;
|
||||||
@ -224,7 +217,7 @@ namespace Slic3r {
|
|||||||
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>& id = layerid2center[layer_idx][hole_idx].first;
|
std::tuple<Point, float, int, coord_t>& 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);
|
||||||
@ -232,10 +225,11 @@ namespace Slic3r {
|
|||||||
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>& search_id = layerid2center[search_layer_idx][search_hole_idx].first;
|
std::tuple<Point, float, int, coord_t>& search_id = layerid2center[search_layer_idx][search_hole_idx].first;
|
||||||
if (std::get<0>(id).distance_to(std::get<0>(search_id)) < SCALED_EPSILON
|
if (std::get<2>(id) == std::get<2>(search_id)
|
||||||
&& std::abs(std::get<1>(id) - std::get<1>(search_id)) < SCALED_EPSILON
|
&& std::get<0>(id).distance_to(std::get<0>(search_id)) < std::get<3>(id)
|
||||||
&& std::get<2>(id) == std::get<2>(search_id)) {
|
&& std::abs(std::get<1>(id) - std::get<1>(search_id)) < std::get<3>(id)
|
||||||
|
) {
|
||||||
max_z = layers()[search_layer_idx]->print_z;
|
max_z = layers()[search_layer_idx]->print_z;
|
||||||
holes.emplace_back(layerid2center[search_layer_idx][search_hole_idx].second, search_layer_idx);
|
holes.emplace_back(layerid2center[search_layer_idx][search_hole_idx].second, search_layer_idx);
|
||||||
layerid2center[search_layer_idx].erase(layerid2center[search_layer_idx].begin() + search_hole_idx);
|
layerid2center[search_layer_idx].erase(layerid2center[search_layer_idx].begin() + search_hole_idx);
|
||||||
@ -721,6 +715,7 @@ namespace Slic3r {
|
|||||||
|| opt_key == "hole_size_compensation"
|
|| opt_key == "hole_size_compensation"
|
||||||
|| opt_key == "hole_size_threshold"
|
|| opt_key == "hole_size_threshold"
|
||||||
|| opt_key == "hole_to_polyhole"
|
|| opt_key == "hole_to_polyhole"
|
||||||
|
|| opt_key == "hole_to_polyhole_threshold"
|
||||||
|| opt_key == "z_step") {
|
|| opt_key == "z_step") {
|
||||||
steps.emplace_back(posSlice);
|
steps.emplace_back(posSlice);
|
||||||
} else if (opt_key == "support_material") {
|
} else if (opt_key == "support_material") {
|
||||||
|
@ -88,9 +88,9 @@ void PrintRegion::collect_object_printing_extruders(std::vector<uint16_t> &objec
|
|||||||
// If not, then there must be something wrong with the Print::apply() function.
|
// If not, then there must be something wrong with the Print::apply() function.
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
auto num_extruders = (int)print()->config().nozzle_diameter.size();
|
auto num_extruders = (int)print()->config().nozzle_diameter.size();
|
||||||
assert(this->config().perimeter_extruder <= num_extruders);
|
assert(this->config().perimeter_extruder.value <= num_extruders);
|
||||||
assert(this->config().infill_extruder <= num_extruders);
|
assert(this->config().infill_extruder.value <= num_extruders);
|
||||||
assert(this->config().solid_infill_extruder <= num_extruders);
|
assert(this->config().solid_infill_extruder.value <= num_extruders);
|
||||||
#endif
|
#endif
|
||||||
for(const PrintObject * obj : this->m_print->objects())
|
for(const PrintObject * obj : this->m_print->objects())
|
||||||
collect_object_printing_extruders(print()->config(), obj->config(), this->config(), object_extruders);
|
collect_object_printing_extruders(print()->config(), obj->config(), this->config(), object_extruders);
|
||||||
|
@ -429,6 +429,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
|||||||
for (auto el : { "solid_fill_pattern", "infill_connection_solid" })
|
for (auto el : { "solid_fill_pattern", "infill_connection_solid" })
|
||||||
toggle_field(el, has_solid_infill); // should be top_solid_layers") > 1 || bottom_solid_layers") > 1
|
toggle_field(el, has_solid_infill); // should be top_solid_layers") > 1 || bottom_solid_layers") > 1
|
||||||
|
|
||||||
|
toggle_field("hole_to_polyhole_threshold", config->opt_bool("hole_to_polyhole"));
|
||||||
|
|
||||||
bool have_default_acceleration = config->option<ConfigOptionFloatOrPercent>("default_acceleration")->value > 0;
|
bool have_default_acceleration = config->option<ConfigOptionFloatOrPercent>("default_acceleration")->value > 0;
|
||||||
for (auto el : { "perimeter_acceleration", "infill_acceleration",
|
for (auto el : { "perimeter_acceleration", "infill_acceleration",
|
||||||
"bridge_acceleration", "first_layer_acceleration" })
|
"bridge_acceleration", "first_layer_acceleration" })
|
||||||
|
Loading…
x
Reference in New Issue
Block a user