Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Introduced option to control amount of internal bridging, fixing internal bridge missing for some sloped surfaces #3319

Merged
merged 20 commits into from Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6f75bee
ENH: Improve internal bridge detection for sloped surfaces
igiannakas Dec 27, 2023
67474dc
Moved lightning detection out of the parallel threads
igiannakas Dec 27, 2023
720fd46
Naming conventions
igiannakas Dec 28, 2023
bb25d33
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Dec 28, 2023
75f0316
Revised approach - use reduced expansion multipliers
igiannakas Dec 28, 2023
f1f2101
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Dec 29, 2023
1128551
Further reduce filtering, flagged option as experimental
igiannakas Dec 29, 2023
e5027af
Corrected code comment
igiannakas Dec 29, 2023
a84447b
Updated tool tip
igiannakas Dec 29, 2023
1c3ed98
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Dec 29, 2023
9171250
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Dec 30, 2023
e896d29
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Dec 30, 2023
0d32a3d
Merge branch 'SoftFever:main' into ENH-Dont-filter-internal-bridges
igiannakas Dec 31, 2023
255bffa
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Jan 1, 2024
505ca0d
Merge remote-tracking branch 'upstream/main' into ENH-Dont-filter-int…
igiannakas Jan 1, 2024
856e601
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Jan 2, 2024
9dae228
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Jan 2, 2024
fd9cac7
Merge branch 'main' into ENH-Dont-filter-internal-bridges
igiannakas Jan 6, 2024
e14783e
Introduced filtering drop down option
igiannakas Jan 9, 2024
6c7500f
Merge branch 'SoftFever:main' into ENH-Dont-filter-internal-bridges
igiannakas Jan 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libslic3r/Preset.cpp
Expand Up @@ -786,7 +786,7 @@ static std::vector<std::string> s_Preset_print_options {
"independent_support_layer_height",
"support_angle", "support_interface_top_layers", "support_interface_bottom_layers",
"support_interface_pattern", "support_interface_spacing", "support_interface_loop_pattern",
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "thick_internal_bridges", "max_bridge_length", "print_sequence", "support_remove_small_overhang",
"support_top_z_distance", "support_on_build_plate_only","support_critical_regions_only", "bridge_no_support", "thick_bridges", "thick_internal_bridges","dont_filter_internal_bridges", "max_bridge_length", "print_sequence", "support_remove_small_overhang",
"filename_format", "wall_filament", "support_bottom_z_distance",
"sparse_infill_filament", "solid_infill_filament", "support_filament", "support_interface_filament","support_interface_not_for_body",
"ooze_prevention", "standby_temperature_delta", "interface_shells", "line_width", "initial_layer_line_width",
Expand Down
7 changes: 7 additions & 0 deletions src/libslic3r/PrintConfig.cpp
Expand Up @@ -1219,6 +1219,13 @@ void PrintConfigDef::init_fff_params()
"consider turning it off if you are using large nozzles.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(true));

def = this->add("dont_filter_internal_bridges", coBool);
def->label = L("Don't filter out small internal bridges");
def->category = L("Quality");
def->tooltip = L("This option can help reducing pillowing on top surfaces in heavily slanted or curved models.\n\nBy default, small internal bridges are filtered out and the internal solid infill is printed directly over the sparse infill. This works well in most cases, speeding up printing without too much compromise in top surface quality. \n\nHowever, in heavily slanted or curved models or where too low sparse infill density is used this may result in curling of the unsupported solid infill, causing pillowing.\n\n Enabling this option will always print a bridge layer over sparse infill.");
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));


def = this->add("max_bridge_length", coFloat);
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/PrintConfig.hpp
Expand Up @@ -744,6 +744,7 @@ PRINT_CONFIG_CLASS_DEFINE(
// Orca internal thick bridge
((ConfigOptionBool, thick_bridges))
((ConfigOptionBool, thick_internal_bridges))
((ConfigOptionBool, dont_filter_internal_bridges))
// Overhang angle threshold.
((ConfigOptionInt, support_threshold_angle))
((ConfigOptionFloat, support_object_xy_distance))
Expand Down
40 changes: 22 additions & 18 deletions src/libslic3r/PrintObject.cpp
Expand Up @@ -1967,7 +1967,6 @@ template<typename T> void debug_draw(std::string name, const T& a, const T& b, c
void PrintObject::bridge_over_infill()
{
BOOST_LOG_TRIVIAL(info) << "Bridge over infill - Start" << log_memory_info();

struct CandidateSurface
{
CandidateSurface(const Surface *original_surface,
Expand All @@ -1989,12 +1988,20 @@ void PrintObject::bridge_over_infill()
};

std::map<size_t, std::vector<CandidateSurface>> surfaces_by_layer;
// Ioannis Giannakas:
igiannakas marked this conversation as resolved.
Show resolved Hide resolved
// Detect use of lightning infill. Moved earlier in the function to pass to the gather and filter surfaces threads.
bool has_lightning_infill = false;
for (size_t i = 0; i < this->num_printing_regions(); i++) {
if (this->printing_region(i).config().sparse_infill_pattern == ipLightning) {
has_lightning_infill = true;
break;
}
}

// SECTION to gather and filter surfaces for expanding, and then cluster them by layer
{
tbb::concurrent_vector<CandidateSurface> candidate_surfaces;
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = static_cast<const PrintObject *>(this),
&candidate_surfaces](tbb::blocked_range<size_t> r) {
tbb::parallel_for(tbb::blocked_range<size_t>(0, this->layers().size()), [po = static_cast<const PrintObject *>(this), &candidate_surfaces, has_lightning_infill](tbb::blocked_range<size_t> r) {
PRINT_OBJECT_TIME_LIMIT_MILLIS(PRINT_OBJECT_TIME_LIMIT_DEFAULT);
for (size_t lidx = r.begin(); lidx < r.end(); lidx++) {
const Layer *layer = po->get_layer(lidx);
Expand All @@ -2017,14 +2024,18 @@ void PrintObject::bridge_over_infill()
}
}
unsupported_area = closing(unsupported_area, float(SCALED_EPSILON));
// By expanding the lower layer solids, we avoid making bridges from the tiny internal overhangs that are (very likely) supported by previous layer solids
// NOTE that we cannot filter out polygons worth bridging by their area, because sometimes there is a very small internal island that will grow into large hole
lower_layer_solids = shrink(lower_layer_solids, 1 * spacing); // first remove thin regions that will not support anything
lower_layer_solids = expand(lower_layer_solids, (1 + 3) * spacing); // then expand back (opening), and further for parts supported by internal solids
// By shrinking the unsupported area, we avoid making bridges from narrow ensuring region along perimeters.
unsupported_area = shrink(unsupported_area, 3 * spacing);
unsupported_area = diff(unsupported_area, lower_layer_solids);


// Ioannis Giannakas:
// Lightning infill benefits from always having a bridge layer so don't filter out small unsupported areas. Also, don't filter small internal unsupported areas if the user has requested so.
if(!has_lightning_infill && !po->config().dont_filter_internal_bridges){
igiannakas marked this conversation as resolved.
Show resolved Hide resolved
// By expanding the lower layer solids, we avoid making bridges from the tiny internal overhangs that are (very likely) supported by previous layer solids
// NOTE that we cannot filter out polygons worth bridging by their area, because sometimes there is a very small internal island that will grow into large hole
lower_layer_solids = shrink(lower_layer_solids, 1 * spacing); // first remove thin regions that will not support anything
lower_layer_solids = expand(lower_layer_solids, (1 + 3) * spacing); // then expand back (opening), and further for parts supported by internal solids
// By shrinking the unsupported area, we avoid making bridges from narrow ensuring region along perimeters.
unsupported_area = shrink(unsupported_area, 3 * spacing);
unsupported_area = diff(unsupported_area, lower_layer_solids);
}
for (const LayerRegion *region : layer->regions()) {
SurfacesPtr region_internal_solids = region->fill_surfaces.filter_by_type(stInternalSolid);
for (const Surface *s : region_internal_solids) {
Expand Down Expand Up @@ -2069,13 +2080,6 @@ void PrintObject::bridge_over_infill()
// LIGHTNING INFILL SECTION - If lightning infill is used somewhere, we check the areas that are going to be bridges, and those that rely on the
// lightning infill under them get expanded. This somewhat helps to ensure that most of the extrusions are anchored to the lightning infill at the ends.
// It requires modifying this instance of print object in a specific way, so that we do not invalidate the pointers in our surfaces_by_layer structure.
bool has_lightning_infill = false;
for (size_t i = 0; i < this->num_printing_regions(); i++) {
if (this->printing_region(i).config().sparse_infill_pattern == ipLightning) {
has_lightning_infill = true;
break;
}
}
if (has_lightning_infill) {
// Prepare backup data for the Layer Region infills. Before modfiyng the layer region, we backup its fill surfaces by moving! them into this map.
// then a copy is created, modifiyed and passed to lightning infill generator. After generator is created, we restore the original state of the fills
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/Tab.cpp
Expand Up @@ -1976,6 +1976,7 @@ void TabPrint::build()
optgroup->append_single_option_line("bridge_density");
optgroup->append_single_option_line("thick_bridges");
optgroup->append_single_option_line("thick_internal_bridges");
optgroup->append_single_option_line("dont_filter_internal_bridges");

optgroup = page->new_optgroup(L("Overhangs"), L"param_advanced");
optgroup->append_single_option_line("detect_overhang_wall");
Expand Down