mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 00:45:57 +08:00
Completely removed Bounded Rectilinear infill
Improved bridge over sparse infill logic - now does not bridge the whole area but only neede part Filtered out tiny regions of ensuring created after bridge_over_sparse infill expanded the regions
This commit is contained in:
parent
b90e8eb6ec
commit
a3430a5b51
@ -14,8 +14,6 @@ ThickPolylines FillEnsuring::fill_surface_arachne(const Surface *surface, const
|
|||||||
assert(this->print_config != nullptr && this->print_object_config != nullptr && this->print_region_config != nullptr);
|
assert(this->print_config != nullptr && this->print_object_config != nullptr && this->print_region_config != nullptr);
|
||||||
|
|
||||||
const coord_t scaled_spacing = scaled<coord_t>(this->spacing);
|
const coord_t scaled_spacing = scaled<coord_t>(this->spacing);
|
||||||
const EnsuringInfillPattern infill_patter = this->print_object_config->ensure_vertical_shell_infill;
|
|
||||||
const bool is_bounded_rectilinear = infill_patter == EnsuringInfillPattern::eipBoundedRectilinear;
|
|
||||||
|
|
||||||
// Perform offset.
|
// Perform offset.
|
||||||
Slic3r::ExPolygons expp = this->overlap != 0. ? offset_ex(surface->expolygon, scaled<float>(this->overlap)) : ExPolygons{surface->expolygon};
|
Slic3r::ExPolygons expp = this->overlap != 0. ? offset_ex(surface->expolygon, scaled<float>(this->overlap)) : ExPolygons{surface->expolygon};
|
||||||
@ -23,7 +21,7 @@ ThickPolylines FillEnsuring::fill_surface_arachne(const Surface *surface, const
|
|||||||
ThickPolylines thick_polylines_out;
|
ThickPolylines thick_polylines_out;
|
||||||
for (ExPolygon &ex_poly : expp) {
|
for (ExPolygon &ex_poly : expp) {
|
||||||
Point bbox_size = ex_poly.contour.bounding_box().size();
|
Point bbox_size = ex_poly.contour.bounding_box().size();
|
||||||
coord_t loops_count = is_bounded_rectilinear ? 1 : std::max(bbox_size.x(), bbox_size.y()) / scaled_spacing + 1;
|
coord_t loops_count = std::max(bbox_size.x(), bbox_size.y()) / scaled_spacing + 1;
|
||||||
Polygons polygons = to_polygons(ex_poly);
|
Polygons polygons = to_polygons(ex_poly);
|
||||||
Arachne::WallToolPaths wall_tool_paths(polygons, scaled_spacing, scaled_spacing, loops_count, 0, params.layer_height, *this->print_object_config, *this->print_config);
|
Arachne::WallToolPaths wall_tool_paths(polygons, scaled_spacing, scaled_spacing, loops_count, 0, params.layer_height, *this->print_object_config, *this->print_config);
|
||||||
if (std::vector<Arachne::VariableWidthLines> loops = wall_tool_paths.getToolPaths(); !loops.empty()) {
|
if (std::vector<Arachne::VariableWidthLines> loops = wall_tool_paths.getToolPaths(); !loops.empty()) {
|
||||||
@ -77,28 +75,6 @@ ThickPolylines FillEnsuring::fill_surface_arachne(const Surface *surface, const
|
|||||||
if (j < thick_polylines_out.size())
|
if (j < thick_polylines_out.size())
|
||||||
thick_polylines_out.erase(thick_polylines_out.begin() + int(j), thick_polylines_out.end());
|
thick_polylines_out.erase(thick_polylines_out.begin() + int(j), thick_polylines_out.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_bounded_rectilinear) {
|
|
||||||
// Remaining infill area will be filled with classic Rectilinear infill.
|
|
||||||
ExPolygons infill_contour = union_ex(wall_tool_paths.getInnerContour());
|
|
||||||
if (offset_ex(infill_contour, -float(scaled_spacing / 2.)).empty())
|
|
||||||
infill_contour.clear(); // Infill region is too small, so let's filter it out.
|
|
||||||
|
|
||||||
Polygons pp;
|
|
||||||
for (ExPolygon &ex : infill_contour)
|
|
||||||
ex.simplify_p(scaled<double>(params.resolution), &pp);
|
|
||||||
|
|
||||||
// Collapse too narrow infill areas and append them to thick_polylines_out.
|
|
||||||
const auto min_perimeter_infill_spacing = coord_t(scaled_spacing * (1. - INSET_OVERLAP_TOLERANCE));
|
|
||||||
const auto infill_overlap = coord_t(scale_(this->print_region_config->get_abs_value("infill_overlap", this->spacing)));
|
|
||||||
for (ExPolygon &ex_poly : offset2_ex(union_ex(pp), float(-min_perimeter_infill_spacing / 2.), float(infill_overlap + min_perimeter_infill_spacing / 2.))) {
|
|
||||||
Polylines polylines;
|
|
||||||
if (Surface new_surface(*surface, std::move(ex_poly)); !fill_surface_by_lines(&new_surface, params, 0.f, 0.f, polylines))
|
|
||||||
BOOST_LOG_TRIVIAL(error) << "FillBoundedRectilinear::fill_surface() failed to fill a region.";
|
|
||||||
append(thick_polylines_out, to_thick_polylines(std::move(polylines), scaled<coord_t>(this->spacing)));
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
assert(infill_patter == EnsuringInfillPattern::eipConcentric);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return thick_polylines_out;
|
return thick_polylines_out;
|
||||||
|
@ -463,7 +463,7 @@ static std::vector<std::string> s_Preset_print_options {
|
|||||||
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
|
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
|
||||||
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits",
|
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||||
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
|
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
|
||||||
"wall_distribution_count", "min_feature_size", "min_bead_width", "ensure_vertical_shell_infill"
|
"wall_distribution_count", "min_feature_size", "min_bead_width"
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<std::string> s_Preset_filament_options {
|
static std::vector<std::string> s_Preset_filament_options {
|
||||||
|
@ -222,12 +222,6 @@ static t_config_enum_values s_keys_map_PerimeterGeneratorType {
|
|||||||
};
|
};
|
||||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType)
|
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType)
|
||||||
|
|
||||||
static t_config_enum_values s_keys_map_EnsuringInfillPattern {
|
|
||||||
{ "bounded_rectilinear", int(EnsuringInfillPattern::eipBoundedRectilinear) },
|
|
||||||
{ "concentric", int(EnsuringInfillPattern::eipConcentric) }
|
|
||||||
};
|
|
||||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(EnsuringInfillPattern)
|
|
||||||
|
|
||||||
static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology)
|
static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology)
|
||||||
{
|
{
|
||||||
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options)
|
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options)
|
||||||
@ -3220,17 +3214,6 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->set_default_value(new ConfigOptionFloatOrPercent(85, true));
|
def->set_default_value(new ConfigOptionFloatOrPercent(85, true));
|
||||||
|
|
||||||
def = this->add("ensure_vertical_shell_infill", coEnum);
|
|
||||||
def->label = L("Ensure vertical shell infill");
|
|
||||||
def->category = L("Layers and Perimeters");
|
|
||||||
def->tooltip = L("Ensure vertical shell infill.");
|
|
||||||
def->set_enum<EnsuringInfillPattern>({
|
|
||||||
{ "bounded_rectilinear", L("Bounded Rectilinear") },
|
|
||||||
{ "concentric", L("Concentric") }
|
|
||||||
});
|
|
||||||
def->mode = comAdvanced;
|
|
||||||
def->set_default_value(new ConfigOptionEnum<EnsuringInfillPattern>(EnsuringInfillPattern::eipBoundedRectilinear));
|
|
||||||
|
|
||||||
// Declare retract values for filament profile, overriding the printer's extruder profile.
|
// Declare retract values for filament profile, overriding the printer's extruder profile.
|
||||||
for (const char *opt_key : {
|
for (const char *opt_key : {
|
||||||
// floats
|
// floats
|
||||||
|
@ -133,11 +133,6 @@ enum class PerimeterGeneratorType
|
|||||||
Arachne
|
Arachne
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EnsuringInfillPattern {
|
|
||||||
eipBoundedRectilinear,
|
|
||||||
eipConcentric
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class GCodeThumbnailsFormat {
|
enum class GCodeThumbnailsFormat {
|
||||||
PNG, JPG, QOI
|
PNG, JPG, QOI
|
||||||
};
|
};
|
||||||
@ -167,7 +162,6 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(DraftShield)
|
|||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(GCodeThumbnailsFormat)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(GCodeThumbnailsFormat)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ForwardCompatibilitySubstitutionRule)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ForwardCompatibilitySubstitutionRule)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType)
|
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType)
|
||||||
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(EnsuringInfillPattern)
|
|
||||||
|
|
||||||
|
|
||||||
#undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS
|
#undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS
|
||||||
@ -497,7 +491,6 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionFloat, brim_width))
|
((ConfigOptionFloat, brim_width))
|
||||||
((ConfigOptionBool, dont_support_bridges))
|
((ConfigOptionBool, dont_support_bridges))
|
||||||
((ConfigOptionFloat, elefant_foot_compensation))
|
((ConfigOptionFloat, elefant_foot_compensation))
|
||||||
((ConfigOptionEnum<EnsuringInfillPattern>, ensure_vertical_shell_infill))
|
|
||||||
((ConfigOptionFloatOrPercent, extrusion_width))
|
((ConfigOptionFloatOrPercent, extrusion_width))
|
||||||
((ConfigOptionFloat, first_layer_acceleration_over_raft))
|
((ConfigOptionFloat, first_layer_acceleration_over_raft))
|
||||||
((ConfigOptionFloatOrPercent, first_layer_speed_over_raft))
|
((ConfigOptionFloatOrPercent, first_layer_speed_over_raft))
|
||||||
|
@ -774,8 +774,7 @@ bool PrintObject::invalidate_state_by_config_options(
|
|||||||
|| opt_key == "wall_transition_angle"
|
|| opt_key == "wall_transition_angle"
|
||||||
|| opt_key == "wall_distribution_count"
|
|| opt_key == "wall_distribution_count"
|
||||||
|| opt_key == "min_feature_size"
|
|| opt_key == "min_feature_size"
|
||||||
|| opt_key == "min_bead_width"
|
|| opt_key == "min_bead_width") {
|
||||||
|| opt_key == "ensure_vertical_shell_infill") {
|
|
||||||
steps.emplace_back(posSlice);
|
steps.emplace_back(posSlice);
|
||||||
} else if (
|
} else if (
|
||||||
opt_key == "seam_position"
|
opt_key == "seam_position"
|
||||||
@ -1774,6 +1773,20 @@ void PrintObject::bridge_over_infill()
|
|||||||
return a.min.x() < b.min.x();
|
return a.min.x() < b.min.x();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::unordered_map<const LayerRegion *, std::pair<Polygons, Polygons>> infill_and_deep_infill_polygons_per_region;
|
||||||
|
for (const auto &surface_region : surface_to_region) {
|
||||||
|
const LayerRegion *r = surface_region.second;
|
||||||
|
if (infill_and_deep_infill_polygons_per_region.find(r) == infill_and_deep_infill_polygons_per_region.end()) {
|
||||||
|
const Flow &flow = r->bridging_flow(frSolidInfill, true);
|
||||||
|
Polygons infill_region = to_polygons(r->fill_expolygons());
|
||||||
|
Polygons deep_infill_area = closing(infill_region, scale_(0.01), scale_(0.01) + 4.0 * flow.scaled_spacing());
|
||||||
|
Polygons solid_supported_area = expand(not_sparse_infill, 4.0 * flow.scaled_spacing());
|
||||||
|
infill_and_deep_infill_polygons_per_region[r] = {closing(infill_region, scale_(0.1)),
|
||||||
|
intersection(lower_layers_sparse_infill,
|
||||||
|
diff(deep_infill_area, solid_supported_area))};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Lower layers sparse infill sections gathered
|
// Lower layers sparse infill sections gathered
|
||||||
// now we can intersected them with bridging surface candidates to get actual areas that need and can accumulate
|
// now we can intersected them with bridging surface candidates to get actual areas that need and can accumulate
|
||||||
// bridging. These areas we then expand (within the surrounding sparse infill only!)
|
// bridging. These areas we then expand (within the surrounding sparse infill only!)
|
||||||
@ -1781,25 +1794,16 @@ void PrintObject::bridge_over_infill()
|
|||||||
for (const Surface *candidate : candidates.second) {
|
for (const Surface *candidate : candidates.second) {
|
||||||
const Flow &flow = surface_to_region[candidate]->bridging_flow(frSolidInfill, true);
|
const Flow &flow = surface_to_region[candidate]->bridging_flow(frSolidInfill, true);
|
||||||
assert(candidate->surface_type == stInternalSolid);
|
assert(candidate->surface_type == stInternalSolid);
|
||||||
Polygons bridged_area = expand(to_polygons(candidate->expolygon), flow.scaled_spacing());
|
|
||||||
Polygons infill_region = to_polygons(surface_to_region[candidate]->fill_expolygons());
|
|
||||||
|
|
||||||
bridged_area =
|
Polygons bridged_area = intersection(expand(to_polygons(candidate->expolygon), flow.scaled_spacing()),
|
||||||
intersection(bridged_area,
|
infill_and_deep_infill_polygons_per_region[surface_to_region[candidate]].first);
|
||||||
lower_layers_sparse_infill); // cut off parts which are not over sparse infill - material overflow
|
// cut off parts which are not over sparse infill - material overflow
|
||||||
|
Polygons worth_bridging = intersection(bridged_area,
|
||||||
{
|
infill_and_deep_infill_polygons_per_region[surface_to_region[candidate]].second);
|
||||||
Polygons area_without_perimeter_boundary_sections = intersection(bridged_area,
|
if (worth_bridging.empty()) {
|
||||||
closing(infill_region, flow.scaled_width(),
|
|
||||||
flow.scaled_width() +
|
|
||||||
4.0 * flow.scaled_spacing()));
|
|
||||||
Polygons and_further_without_solid_supported_sections = diff(area_without_perimeter_boundary_sections,
|
|
||||||
expand(not_sparse_infill, 4.0 * flow.scaled_spacing()));
|
|
||||||
|
|
||||||
if (and_further_without_solid_supported_sections.empty()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
bridged_area = intersection(bridged_area, expand(worth_bridging, 5.0 * flow.scaled_spacing()));
|
||||||
|
|
||||||
Polygons max_area = expand_area;
|
Polygons max_area = expand_area;
|
||||||
max_area.insert(max_area.end(), bridged_area.begin(), bridged_area.end());
|
max_area.insert(max_area.end(), bridged_area.begin(), bridged_area.end());
|
||||||
@ -2133,8 +2137,10 @@ void PrintObject::bridge_over_infill()
|
|||||||
if (s.original_surface == &surface) {
|
if (s.original_surface == &surface) {
|
||||||
Surface tmp(surface, {});
|
Surface tmp(surface, {});
|
||||||
for (const ExPolygon &expoly : diff_ex(surface.expolygon, s.new_polys)) {
|
for (const ExPolygon &expoly : diff_ex(surface.expolygon, s.new_polys)) {
|
||||||
|
if (expoly.area() > region->flow(frSolidInfill).scaled_width() * scale_(4.0)) {
|
||||||
new_surfaces.emplace_back(tmp, expoly);
|
new_surfaces.emplace_back(tmp, expoly);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
tmp.surface_type = stInternalBridge;
|
tmp.surface_type = stInternalBridge;
|
||||||
tmp.bridge_angle = s.bridge_angle;
|
tmp.bridge_angle = s.bridge_angle;
|
||||||
for (const ExPolygon &expoly : union_ex(s.new_polys)) {
|
for (const ExPolygon &expoly : union_ex(s.new_polys)) {
|
||||||
|
@ -1428,7 +1428,6 @@ void TabPrint::build()
|
|||||||
optgroup->append_single_option_line("extra_perimeters", category_path + "extra-perimeters-if-needed");
|
optgroup->append_single_option_line("extra_perimeters", category_path + "extra-perimeters-if-needed");
|
||||||
optgroup->append_single_option_line("extra_perimeters_on_overhangs", category_path + "extra-perimeters-on-overhangs");
|
optgroup->append_single_option_line("extra_perimeters_on_overhangs", category_path + "extra-perimeters-on-overhangs");
|
||||||
optgroup->append_single_option_line("ensure_vertical_shell_thickness", category_path + "ensure-vertical-shell-thickness");
|
optgroup->append_single_option_line("ensure_vertical_shell_thickness", category_path + "ensure-vertical-shell-thickness");
|
||||||
optgroup->append_single_option_line("ensure_vertical_shell_infill");
|
|
||||||
optgroup->append_single_option_line("avoid_crossing_curled_overhangs", category_path + "avoid-crossing-curled-overhangs");
|
optgroup->append_single_option_line("avoid_crossing_curled_overhangs", category_path + "avoid-crossing-curled-overhangs");
|
||||||
optgroup->append_single_option_line("avoid_crossing_perimeters", category_path + "avoid-crossing-perimeters");
|
optgroup->append_single_option_line("avoid_crossing_perimeters", category_path + "avoid-crossing-perimeters");
|
||||||
optgroup->append_single_option_line("avoid_crossing_perimeters_max_detour", category_path + "avoid_crossing_perimeters_max_detour");
|
optgroup->append_single_option_line("avoid_crossing_perimeters_max_detour", category_path + "avoid_crossing_perimeters_max_detour");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user