Skip to content

Commit

Permalink
Merge PR "Only one perimeter on top/first layer" prusa3d#10648
Browse files Browse the repository at this point in the history
  • Loading branch information
Vovodroid authored and vovodroid committed May 7, 2024
1 parent d580eb0 commit 6da0abc
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 6 deletions.
12 changes: 12 additions & 0 deletions src/libslic3r/ClipperUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,18 @@ namespace ClipperUtils {
out.end());
return out;
}
[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygons &src, const BoundingBox &bbox)
{
Polygons out;
out.reserve(number_polygons(src));
for (const ExPolygon &p : src) {
Polygons temp = clip_clipper_polygons_with_subject_bbox(p, bbox);
out.insert(out.end(), temp.begin(), temp.end());
}

out.erase(std::remove_if(out.begin(), out.end(), [](const Polygon &polygon) {return polygon.empty(); }), out.end());
return out;
}
}

static ExPolygons PolyTreeToExPolygons(ClipperLib::PolyTree &&polytree)
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/ClipperUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ namespace ClipperUtils {
[[nodiscard]] Polygon clip_clipper_polygon_with_subject_bbox(const Polygon &src, const BoundingBox &bbox);
[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const Polygons &src, const BoundingBox &bbox);
[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygon &src, const BoundingBox &bbox);
[[nodiscard]] Polygons clip_clipper_polygons_with_subject_bbox(const ExPolygons &src, const BoundingBox &bbox);
}

// offset Polygons
Expand Down
3 changes: 3 additions & 0 deletions src/libslic3r/LayerRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ void LayerRegion::make_perimeters(

// Cummulative sum of polygons over all the regions.
const ExPolygons *lower_slices = this->layer()->lower_layer ? &this->layer()->lower_layer->lslices : nullptr;
const ExPolygons *upper_slices = this->layer()->upper_layer ? &this->layer()->upper_layer->lslices : nullptr;
// Cache for offsetted lower_slices
Polygons lower_layer_polygons_cache;

Expand All @@ -124,6 +125,7 @@ void LayerRegion::make_perimeters(
params,
surface,
lower_slices,
upper_slices,
lower_layer_polygons_cache,
// output:
m_perimeters,
Expand All @@ -135,6 +137,7 @@ void LayerRegion::make_perimeters(
params,
surface,
lower_slices,
upper_slices,
lower_layer_polygons_cache,
// output:
m_perimeters,
Expand Down
222 changes: 219 additions & 3 deletions src/libslic3r/PerimeterGenerator.cpp

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/libslic3r/PerimeterGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ void process_classic(
const Parameters &params,
const Surface &surface,
const ExPolygons *lower_slices,
const ExPolygons *upper_slices,
// Cache:
Polygons &lower_slices_polygons_cache,
// Output:
Expand All @@ -91,6 +92,7 @@ void process_arachne(
const Parameters &params,
const Surface &surface,
const ExPolygons *lower_slices,
const ExPolygons *upper_slices,
// Cache:
Polygons &lower_slices_polygons_cache,
// Output:
Expand All @@ -103,6 +105,9 @@ void process_arachne(

ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, float tolerance, float merge_tolerance);

void split_top_surfaces(const Parameters &params, const ExPolygons *lower_slices,const ExPolygons *upper_slices, const ExPolygons &orig_polygons, ExPolygons &top_fills,
ExPolygons &non_top_polygons, ExPolygons &fill_clip);

} // namespace PerimeterGenerator
} // namespace Slic3r

Expand Down
5 changes: 4 additions & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config)

static std::vector<std::string> s_Preset_print_options {
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "slicing_mode",
"only_one_perimeter_first",
"top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
"extra_perimeters", "extra_perimeters_on_overhangs", "avoid_crossing_curled_overhangs", "avoid_crossing_perimeters", "thin_walls", "overhangs",
"seam_position","staggered_inner_seams", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
Expand Down Expand Up @@ -476,7 +477,9 @@ static std::vector<std::string> s_Preset_print_options {
"wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
"mmu_segmented_region_interlocking_depth", "wipe_tower_extruder", "wipe_tower_no_sparse_layers", "wipe_tower_extra_flow", "wipe_tower_extra_spacing", "compatible_printers", "compatible_printers_condition", "inherits",
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"wall_distribution_count", "min_feature_size", "min_bead_width"
"wall_distribution_count", "min_feature_size", "min_bead_width",
// SuperSlicer
"only_one_perimeter_top", "min_width_top_surface",
};

static std::vector<std::string> s_Preset_filament_options {
Expand Down
26 changes: 26 additions & 0 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,32 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(1));

def = this->add("only_one_perimeter_first", coBool);
def->label = L("on first layer");
def->category = L("Layers and Perimeters");
def->tooltip = L("Print one perimeter on first layer to leave more space for infill. Could be usefull for small details and better look.");
def->set_default_value(new ConfigOptionBool(false));

def = this->add("only_one_perimeter_top", coBool);
def->label = L("On top surfaces");
def->category = L("Layers and Perimeters");
def->tooltip = L("Use only one perimeter on flat top surface, to give more space to the top infill pattern");
def->set_default_value(new ConfigOptionBool(false));

def = this->add("min_width_top_surface", coFloatOrPercent);
def->label = L("Minimum top width for infill");
def->category = L("Layers and Perimeters");
def->tooltip = L("If a top surface has to be printed and it's partially covered by another layer, it won't be considered at a top layer where its width is below this value."
" This can be useful to not let the 'one perimeter on top' trigger on surface that should be covered only by perimeters."
" This value can be a mm or a % of the perimeter extrusion width."
"\nWarning: If enabled, artifacts can be created is you have some thin features on the next layer, like letters. Set this setting to 0 to remove these artifacts.");
def->sidetext = L("mm or %");
def->ratio_over = "perimeter_extrusion_width";
def->min = 0;
def->max_literal = 15;
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloatOrPercent(100, true));

def = this->add("bridge_speed", coFloat);
def->label = L("Bridges");
def->category = L("Speed");
Expand Down
4 changes: 4 additions & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,10 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, top_solid_min_thickness))
((ConfigOptionFloatOrPercent, top_solid_infill_speed))
((ConfigOptionBool, wipe_into_infill))
((ConfigOptionBool, only_one_perimeter_first))
// SuperSlicer
((ConfigOptionBool, only_one_perimeter_top))
((ConfigOptionFloatOrPercent, min_width_top_surface))
)

PRINT_CONFIG_CLASS_DEFINE(
Expand Down
4 changes: 4 additions & 0 deletions src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,12 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posSupportSpotsSearch);
// Brim is printed below supports, support invalidates brim and skirt.
steps.emplace_back(posSupportMaterial);
} else if (
opt_key == "only_one_perimeter_top") {
steps.emplace_back(posPerimeters);
} else if (
opt_key == "perimeters"
|| opt_key == "only_one_perimeter_first"
|| opt_key == "extra_perimeters"
|| opt_key == "extra_perimeters_on_overhangs"
|| opt_key == "first_layer_extrusion_width"
Expand Down
5 changes: 5 additions & 0 deletions src/libslic3r/libslic3r.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ static constexpr double EPSILON = 1e-4;
// int32_t fits an interval of (-2147.48mm, +2147.48mm)
// with int64_t we don't have to worry anymore about the size of the int.
static constexpr double SCALING_FACTOR = 0.000001;
static constexpr double UNSCALING_FACTOR = 1000000; // 1 / SCALING_FACTOR; <- linux has some problem compiling this constexpr
static constexpr double PI = 3.141592653589793238;
// When extruding a closed loop, the loop is interrupted and shortened a bit to reduce the seam.
static constexpr double LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER = 0.15;
Expand All @@ -77,9 +78,11 @@ static constexpr double INSET_OVERLAP_TOLERANCE = 0.4;
// 3mm ring around the top / bottom / bridging areas.
//FIXME This is quite a lot.
static constexpr double EXTERNAL_INFILL_MARGIN = 3.;
static constexpr double BRIDGE_INFILL_MARGIN = 1.;
//FIXME Better to use an inline function with an explicit return type.
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
#define scale_(val) ((val) / SCALING_FACTOR)
#define unscale_(val) ((val) * SCALING_FACTOR)

#define SCALED_EPSILON scale_(EPSILON)

Expand Down Expand Up @@ -107,6 +110,8 @@ using deque =
template<typename T, typename Q>
inline T unscale(Q v) { return T(v) * T(SCALING_FACTOR); }

inline coordf_t scale_d(double v) { return coordf_t(v * UNSCALING_FACTOR); }

enum Axis {
X=0,
Y,
Expand Down
6 changes: 5 additions & 1 deletion src/slic3r/GUI/ConfigManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,12 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
bool have_perimeters = config->opt_int("perimeters") > 0;
for (auto el : { "extra_perimeters","extra_perimeters_on_overhangs", "thin_walls", "overhangs",
"seam_position","staggered_inner_seams", "external_perimeters_first", "external_perimeter_extrusion_width",
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "enable_dynamic_overhang_speeds"})
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "enable_dynamic_overhang_speeds",
"only_one_perimeter_first", "only_one_perimeter_top"})
toggle_field(el, have_perimeters);

toggle_field("min_width_top_surface", have_perimeters && config->opt_bool("only_one_perimeter_top"));

for (size_t i = 0; i < 4; i++) {
toggle_field("overhang_speed_" + std::to_string(i), config->opt_bool("enable_dynamic_overhang_speeds"));
}
Expand Down Expand Up @@ -368,6 +371,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field("min_feature_size", have_arachne);
toggle_field("min_bead_width", have_arachne);
toggle_field("thin_walls", !have_arachne);

}

void ConfigManipulation::toggle_print_sla_options(DynamicPrintConfig* config)
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/Plater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2134,7 +2134,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
"extruder_colour", "filament_colour", "material_colour", "max_print_height", "printer_model", "printer_notes", "printer_technology",
// These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
"layer_height", "first_layer_height", "min_layer_height", "max_layer_height",
"brim_width", "perimeters", "perimeter_extruder", "fill_density", "infill_extruder", "top_solid_layers",
"brim_width", "perimeters", "only_one_perimeter_first", "perimeter_extruder", "fill_density", "infill_extruder", "top_solid_layers",
"support_material", "support_material_extruder", "support_material_interface_extruder",
"support_material_contact_distance", "support_material_bottom_contact_distance", "raft_layers"
}))
Expand Down
6 changes: 6 additions & 0 deletions src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,12 @@ void TabPrint::build()
optgroup->append_line(line);

optgroup = page->new_optgroup(L("Quality (slower slicing)"));
line = { L("Only one perimeter"), "" };
line.label_path = category_path + "only-one-perimeter-top-bottom";
line.append_option(optgroup->get_option("only_one_perimeter_first"));
line.append_option(optgroup->get_option("only_one_perimeter_top"));
line.append_option(optgroup->get_option("min_width_top_surface"));
optgroup->append_line(line);
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("avoid_crossing_curled_overhangs", category_path + "avoid-crossing-curled-overhangs");
Expand Down
1 change: 1 addition & 0 deletions tests/fff_print/test_perimeters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ SCENARIO("Perimeter nesting", "[Perimeters]")
perimeter_generator_params,
surface,
nullptr,
nullptr,
// cache:
lower_layer_polygons_cache,
// output:
Expand Down

0 comments on commit 6da0abc

Please sign in to comment.