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

Various infill improvements #2716

Merged
merged 3 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions src/libslic3r/LayerRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,24 @@ void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Poly
RegionExpansionParameters::build(expansion_top, expansion_step, max_nr_expansion_steps),
sparse, expansion_params_into_sparse_infill, closing_radius);

// turn too small internal regions into solid regions according to the user setting
if (!this->layer()->object()->print()->config().spiral_mode && this->region().config().sparse_infill_density.value > 0) {
// scaling an area requires two calls!
double min_area = scale_(scale_(this->region().config().minimum_sparse_infill_area.value));
ExPolygons small_regions{};
sparse.erase(std::remove_if(sparse.begin(), sparse.end(), [min_area, &small_regions](ExPolygon& ex_polygon) {
if (ex_polygon.area() <= min_area) {
small_regions.push_back(ex_polygon);
return true;
}
return false;
}), sparse.end());

if (!small_regions.empty()) {
shells = union_ex(shells, small_regions);
}
}

// m_fill_surfaces.remove_types({ stBottomBridge, stBottom, stTop, stInternal, stInternalSolid });
this->fill_surfaces.clear();
reserve_more(this->fill_surfaces.surfaces, shells.size() + sparse.size() + bridges.size() + bottoms.size() + tops.size());
Expand Down Expand Up @@ -790,12 +808,10 @@ void LayerRegion::prepare_fill_surfaces()
surface.surface_type = stInternal;
}

// turn too small internal regions into solid regions according to the user setting
if (! spiral_mode && this->region().config().sparse_infill_density.value > 0) {
// scaling an area requires two calls!
double min_area = scale_(scale_(this->region().config().minimum_sparse_infill_area.value));
if (!spiral_mode && fabs(this->region().config().sparse_infill_density.value - 100.) < EPSILON) {
// Turn all internal sparse infill into solid infill, if sparse_infill_density is 100%
for (Surface &surface : this->fill_surfaces.surfaces)
if (surface.surface_type == stInternal && surface.area() <= min_area)
if (surface.surface_type == stInternal)
surface.surface_type = stInternalSolid;
}

Expand Down
8 changes: 1 addition & 7 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1710,7 +1710,7 @@ def = this->add("filament_loading_speed", coFloats);
def = this->add("sparse_infill_density", coPercent);
def->label = L("Sparse infill density");
def->category = L("Strength");
def->tooltip = L("Density of internal sparse infill, 100% means solid throughout");
def->tooltip = L("Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used");
def->sidetext = L("%");
def->min = 0;
def->max = 100;
Expand Down Expand Up @@ -5688,12 +5688,6 @@ std::map<std::string, std::string> validate(const FullPrintConfig &cfg, bool und
error_message.emplace("internal_solid_infill_pattern", L("invalid value ") + cfg.internal_solid_infill_pattern.serialize());
}

// --fill-density
if (fabs(cfg.sparse_infill_density.value - 100.) < EPSILON &&
! print_config_def.get("top_surface_pattern")->has_enum_value(cfg.sparse_infill_pattern.serialize())) {
error_message.emplace("sparse_infill_pattern", cfg.sparse_infill_pattern.serialize() + L(" doesn't work at 100%% density "));
}

// --skirt-height
if (cfg.skirt_height < 0) {
error_message.emplace("skirt_height", L("invalid value ") + std::to_string(cfg.skirt_height));
Expand Down
29 changes: 18 additions & 11 deletions src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3313,6 +3313,13 @@ void PrintObject::combine_infill()
const bool enable_combine_infill = region.config().infill_combination.value;
if (enable_combine_infill == false || region.config().sparse_infill_density == 0.)
continue;

// Support internal solid infill when sparse_infill_density is 100%
const bool use_solid_infill = fabs(region.config().sparse_infill_density.value - 100.) < EPSILON;
const SurfaceType surface_type = use_solid_infill ? stInternalSolid : stInternal;
const InfillPattern infill_pattern = use_solid_infill ? region.config().internal_solid_infill_pattern :
region.config().sparse_infill_pattern;

// Limit the number of combined layers to the maximum height allowed by this regions' nozzle.
//FIXME limit the layer height to max_layer_height
double nozzle_diameter = std::min(
Expand Down Expand Up @@ -3359,10 +3366,10 @@ void PrintObject::combine_infill()
layerms.emplace_back(m_layers[i]->regions()[region_id]);
// We need to perform a multi-layer intersection, so let's split it in pairs.
// Initialize the intersection with the candidates of the lowest layer.
ExPolygons intersection = to_expolygons(layerms.front()->fill_surfaces.filter_by_type(stInternal));
ExPolygons intersection = to_expolygons(layerms.front()->fill_surfaces.filter_by_type(surface_type));
// Start looping from the second layer and intersect the current intersection with it.
for (size_t i = 1; i < layerms.size(); ++ i)
intersection = intersection_ex(layerms[i]->fill_surfaces.filter_by_type(stInternal), intersection);
intersection = intersection_ex(layerms[i]->fill_surfaces.filter_by_type(surface_type), intersection);
double area_threshold = layerms.front()->infill_area_threshold();
if (! intersection.empty() && area_threshold > 0.)
intersection.erase(std::remove_if(intersection.begin(), intersection.end(),
Expand All @@ -3382,21 +3389,21 @@ void PrintObject::combine_infill()
0.5f * layerms.back()->flow(frPerimeter).scaled_width() +
// Because fill areas for rectilinear and honeycomb are grown
// later to overlap perimeters, we need to counteract that too.
((region.config().sparse_infill_pattern == ipRectilinear ||
region.config().sparse_infill_pattern == ipMonotonic ||
region.config().sparse_infill_pattern == ipGrid ||
region.config().sparse_infill_pattern == ipLine ||
region.config().sparse_infill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
((infill_pattern == ipRectilinear ||
infill_pattern == ipMonotonic ||
infill_pattern == ipGrid ||
infill_pattern == ipLine ||
infill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
layerms.back()->flow(frSolidInfill).scaled_width();
for (ExPolygon &expoly : intersection)
polygons_append(intersection_with_clearance, offset(expoly, clearance_offset));
for (LayerRegion *layerm : layerms) {
Polygons internal = to_polygons(std::move(layerm->fill_surfaces.filter_by_type(stInternal)));
layerm->fill_surfaces.remove_type(stInternal);
layerm->fill_surfaces.append(diff_ex(internal, intersection_with_clearance), stInternal);
Polygons internal = to_polygons(std::move(layerm->fill_surfaces.filter_by_type(surface_type)));
layerm->fill_surfaces.remove_type(surface_type);
layerm->fill_surfaces.append(diff_ex(internal, intersection_with_clearance), surface_type);
if (layerm == layerms.back()) {
// Apply surfaces back with adjusted depth to the uppermost layer.
Surface templ(stInternal, ExPolygon());
Surface templ(surface_type, ExPolygon());
templ.thickness = 0.;
for (LayerRegion *layerm2 : layerms)
templ.thickness += layerm2->layer()->height;
Expand Down
37 changes: 0 additions & 37 deletions src/slic3r/GUI/ConfigManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,43 +419,6 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
}
}

if (config->option<ConfigOptionPercent>("sparse_infill_density")->value == 100) {
std::string sparse_infill_pattern = config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->serialize();
const auto &top_fill_pattern_values = config->def()->get("top_surface_pattern")->enum_values;
bool correct_100p_fill = std::find(top_fill_pattern_values.begin(), top_fill_pattern_values.end(), sparse_infill_pattern) != top_fill_pattern_values.end();
if (!correct_100p_fill) {
// get sparse_infill_pattern name from enum_labels for using this one at dialog_msg
const ConfigOptionDef *fill_pattern_def = config->def()->get("sparse_infill_pattern");
assert(fill_pattern_def != nullptr);
auto it_pattern = std::find(fill_pattern_def->enum_values.begin(), fill_pattern_def->enum_values.end(), sparse_infill_pattern);
assert(it_pattern != fill_pattern_def->enum_values.end());
if (it_pattern != fill_pattern_def->enum_values.end()) {
wxString msg_text = GUI::format_wxstr(_L("%1% infill pattern doesn't support 100%% density."),
_(fill_pattern_def->enum_labels[it_pattern - fill_pattern_def->enum_values.begin()]));
if (is_global_config)
msg_text += "\n" + _L("Switch to rectilinear pattern?\n"
"Yes - switch to rectilinear pattern automaticlly\n"
"No - reset density to default non 100% value automaticlly") + "\n";
MessageDialog dialog(m_msg_dlg_parent, msg_text, "",
wxICON_WARNING | (is_global_config ? wxYES | wxNO : wxOK) );
DynamicPrintConfig new_conf = *config;
is_msg_dlg_already_exist = true;
auto answer = dialog.ShowModal();
if (!is_global_config || answer == wxID_YES) {
new_conf.set_key_value("sparse_infill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
sparse_infill_density = 100;
}
else
sparse_infill_density = wxGetApp().preset_bundle->prints.get_selected_preset().config.option<ConfigOptionPercent>("sparse_infill_density")->value;
new_conf.set_key_value("sparse_infill_density", new ConfigOptionPercent(sparse_infill_density));
apply(config, &new_conf);
if (cb_value_change)
cb_value_change("sparse_infill_density", sparse_infill_density);
is_msg_dlg_already_exist = false;
}
}
}

// BBS
static const char* keys[] = { "support_filament", "support_interface_filament"};
for (int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1925,13 +1925,13 @@ void TabPrint::build()
optgroup->append_single_option_line("bottom_surface_pattern", "fill-patterns#Infill of the top surface and bottom surface");
optgroup->append_single_option_line("bottom_shell_layers");
optgroup->append_single_option_line("bottom_shell_thickness");
optgroup->append_single_option_line("internal_solid_infill_pattern");

optgroup = page->new_optgroup(L("Infill"), L"param_infill");
optgroup->append_single_option_line("sparse_infill_density");
optgroup->append_single_option_line("sparse_infill_pattern", "fill-patterns#infill types and their properties of sparse");
optgroup->append_single_option_line("infill_anchor");
optgroup->append_single_option_line("infill_anchor_max");
optgroup->append_single_option_line("internal_solid_infill_pattern");

optgroup->append_single_option_line("filter_out_gap_fill");

Expand Down