From 7738e2a33cb00e6b009c8a02f2efc98353339b16 Mon Sep 17 00:00:00 2001 From: supermerill Date: Fri, 5 Jun 2020 22:14:10 +0200 Subject: [PATCH] #240 little rework of XY compensation. better import of 'elephant foot' (spelled elefant in prusa) that is now first_layer_size_compensation, using 'legacy to amke the convert. advantage: it reverse the sign now. drawback : no easy export to prusa. --- resources/profiles/BIBO.ini | 2 +- resources/profiles/Basic.ini | 2 +- resources/profiles/Creality.ini | 2 +- resources/profiles/LulzBot.ini | 2 +- resources/profiles/PrusaResearch.ini | 8 +- resources/profiles/Voron.ini | 2 +- resources/ui_layout/print.ui | 3 +- resources/ui_layout/print.ui.legacy | 8 +- resources/ui_layout/printer_sla.ui | 4 +- src/libslic3r/Layer.cpp | 2 +- src/libslic3r/Print.hpp | 3 +- src/libslic3r/PrintConfig.cpp | 49 ++++--- src/libslic3r/PrintConfig.hpp | 18 +-- src/libslic3r/PrintObject.cpp | 206 +++++++++++++++++++-------- src/libslic3r/SLAPrint.cpp | 4 +- src/libslic3r/SLAPrintSteps.cpp | 4 +- src/slic3r/GUI/Preset.cpp | 9 +- 17 files changed, 215 insertions(+), 113 deletions(-) diff --git a/resources/profiles/BIBO.ini b/resources/profiles/BIBO.ini index a6c3aebcb..dca2b49de 100644 --- a/resources/profiles/BIBO.ini +++ b/resources/profiles/BIBO.ini @@ -37,7 +37,7 @@ clip_multipart_objects = 1 compatible_printers = complete_objects = 0 dont_support_bridges = 1 -elefant_foot_compensation = 0 +first_layer_size_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeters_first = 0 diff --git a/resources/profiles/Basic.ini b/resources/profiles/Basic.ini index cbbd5f6f7..d86c76460 100644 --- a/resources/profiles/Basic.ini +++ b/resources/profiles/Basic.ini @@ -247,7 +247,7 @@ external_perimeters_first = 0 extra_perimeters = 0 extra_perimeters_odd_layers = 0 only_one_perimeter_top = 1 -elefant_foot_compensation = -0.05 +first_layer_size_compensation = -0.05 extruder_clearance_height = 20 extruder_clearance_radius = 20 fill_angle = 45 diff --git a/resources/profiles/Creality.ini b/resources/profiles/Creality.ini index d93aeeb68..8c89f34f9 100644 --- a/resources/profiles/Creality.ini +++ b/resources/profiles/Creality.ini @@ -311,7 +311,7 @@ external_perimeters_first = 0 extra_perimeters = 0 extra_perimeters_odd_layers = 0 only_one_perimeter_top = 1 -elefant_foot_compensation = -0.05 +first_layer_size_compensation = -0.05 extruder_clearance_height = 20 extruder_clearance_radius = 25 fill_angle = 45 diff --git a/resources/profiles/LulzBot.ini b/resources/profiles/LulzBot.ini index b936a431e..b8fa117c3 100644 --- a/resources/profiles/LulzBot.ini +++ b/resources/profiles/LulzBot.ini @@ -35,7 +35,7 @@ compatible_printers_condition = complete_objects = 0 default_acceleration = 500 dont_support_bridges = 1 -elefant_foot_compensation = 0 +first_layer_size_compensation = 0 ensure_vertical_shell_thickness = 0 external_perimeter_extrusion_width = 0.56 external_perimeter_speed = 50% diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index caf5f46e1..a6752b312 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -149,7 +149,7 @@ compatible_printers = complete_objects = 0 default_acceleration = 1000 dont_support_bridges = 1 -elefant_foot_compensation = -0.2 +first_layer_size_compensation = -0.2 ensure_vertical_shell_thickness = 1 external_perimeters_first = 0 @@ -275,7 +275,7 @@ extruder_clearance_radius = 35 # Print parameters common to a 0.25mm diameter nozzle. [print:*0.25nozzle*] -elefant_foot_compensation = 0 +first_layer_size_compensation = 0 external_perimeter_extrusion_width = 0.25 extrusion_width = 0.25 first_layer_extrusion_width = 0.3 @@ -291,7 +291,7 @@ support_material_xy_spacing = 150% output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode [print:*0.25nozzleMK3*] -elefant_foot_compensation = 0 +first_layer_size_compensation = 0 external_perimeter_extrusion_width = 0.25 extrusion_width = 0.25 first_layer_extrusion_width = 0.3 @@ -325,7 +325,7 @@ fill_density = 20% output_filename_format = {input_filename_base}_{nozzle_diameter[0]}n_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode [print:*0.25nozzleMINI*] -elefant_foot_compensation = 0 +first_layer_size_compensation = 0 external_perimeter_extrusion_width = 0.25 extrusion_width = 0.25 first_layer_extrusion_width = 0.3 diff --git a/resources/profiles/Voron.ini b/resources/profiles/Voron.ini index 23abf85ee..7ac459476 100644 --- a/resources/profiles/Voron.ini +++ b/resources/profiles/Voron.ini @@ -529,7 +529,7 @@ extra_perimeters_odd_layers = 0 extra_perimeters_overhangs = 0 extruder_clearance_height = 20 extruder_clearance_radius = 20 -elefant_foot_compensation = -0.1 +first_layer_size_compensation = -0.1 fill_angle = 45 fill_density = 13% fill_pattern = gyroid diff --git a/resources/ui_layout/print.ui b/resources/ui_layout/print.ui index df034abec..ab5e3a453 100644 --- a/resources/ui_layout/print.ui +++ b/resources/ui_layout/print.ui @@ -80,7 +80,8 @@ group:label_width$8:Modifying slices setting:hole_to_polyhole line:XY compensation setting:width$6:xy_size_compensation - setting:width$6:elefant_foot_compensation + setting:width$6:xy_inner_size_compensation + setting:width$6:first_layer_size_compensation setting:width$6:hole_size_compensation end_line group:Other diff --git a/resources/ui_layout/print.ui.legacy b/resources/ui_layout/print.ui.legacy index 3a6a0d411..c314efb93 100644 --- a/resources/ui_layout/print.ui.legacy +++ b/resources/ui_layout/print.ui.legacy @@ -204,14 +204,8 @@ group:Filtering setting:model_precision setting:slice_closing_radius group:Modifying slices - line:Curve smoothing - setting:curve_smoothing_precision - setting:curve_smoothing_angle_convex - setting:curve_smoothing_angle_concave - setting:curve_smoothing_cutoff_dist - end_line setting:full_label:xy_size_compensation - setting:full_label:elefant_foot_compensation + setting:full_label:first_layer_size_compensation setting:full_label:hole_size_compensation setting:hole_to_polyhole group:Other diff --git a/resources/ui_layout/printer_sla.ui b/resources/ui_layout/printer_sla.ui index 7e0a4fa10..91b21c49f 100644 --- a/resources/ui_layout/printer_sla.ui +++ b/resources/ui_layout/printer_sla.ui @@ -28,8 +28,8 @@ group:Corrections setting:label$Z:id$1:relative_correction end_line setting:absolute_correction - setting:elefant_foot_compensation - setting:elefant_foot_min_width + setting:first_layer_size_compensation + setting:elephant_foot_min_width setting:gamma_correction group:Exposure setting:min_exposure_time diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index b03357d63..3422d91bf 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -67,7 +67,7 @@ void Layer::make_slices() // Merge typed slices into untyped slices. This method is used to revert the effects of detect_surfaces_type() called for posPrepareInfill. void Layer::merge_slices() { - if (m_regions.size() == 1 && (this->id() > 0 || this->object()->config().elefant_foot_compensation.value == 0)) { + if (m_regions.size() == 1 && (this->id() > 0 || this->object()->config().first_layer_size_compensation.value == 0)) { // Optimization, also more robust. Don't merge classified pieces of layerm->slices, // but use the non-split islands of a layer. For a single region print, these shall be equal. // Don't use this optimization on 1st layer with Elephant foot compensation applied, as this->lslices are uncompensated, diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 47660c402..43b78bdeb 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -227,7 +227,8 @@ private: void generate_support_material(); void _slice(const std::vector &layer_height_profile); - ExPolygons _offset_holes(double hole_delta, const ExPolygons &input) const; + ExPolygons _shrink_contour_holes(double contour_delta, double default_delta, double convex_delta, const ExPolygons& input) const; + ExPolygons _grow_contour_holes(double contour_delta, double default_delta, double convex_delta, const ExPolygons& input) const; void _transform_hole_to_polyholes(); ExPolygons _smooth_curves(const ExPolygons &input, const PrintRegionConfig &conf) const; std::string _fix_slicing_errors(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index cd058d198..0318b03d3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -127,16 +127,6 @@ void PrintConfigDef::init_common_params() "If left blank, the default OS CA certificate repository is used."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); - - def = this->add("elefant_foot_compensation", coFloat); - def->label = L("First layer"); - def->full_label = L("XY First layer compensation"); - def->category = OptionCategory::slicing; - def->tooltip = L("The first layer will be grown / shrunk in the XY plane by the configured value " - "to compensate for the 1st layer squish aka an Elephant Foot effect. (should be negative = inwards)"); - def->sidetext = L("mm"); - def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloat(0)); } @@ -1399,6 +1389,16 @@ void PrintConfigDef::init_fff_params() def->mode = comExpert; def->set_default_value(new ConfigOptionPercent(100)); + def = this->add("first_layer_size_compensation", coFloat); + def->label = L("First layer"); + def->full_label = L("XY First layer compensation"); + def->category = OptionCategory::slicing; + def->tooltip = L("The first layer will be grown / shrunk in the XY plane by the configured value " + "to compensate for the 1st layer squish aka an Elephant Foot effect. (should be negative = inwards)"); + def->sidetext = L("mm"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0)); + def = this->add("fill_smooth_width", coFloatOrPercent); def->label = L("width"); def->full_label = L("Ironing width"); @@ -3414,12 +3414,23 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionFloat(10.)); def = this->add("xy_size_compensation", coFloat); - def->label = L("All layers"); - def->full_label = L("XY size compensation"); + def->label = L("Outter"); + def->full_label = L("Outter XY size compensation"); def->category = OptionCategory::slicing; def->tooltip = L("The object will be grown/shrunk in the XY plane by the configured value " - "(negative = inwards, positive = outwards). This might be useful " - "for fine-tuning sizes."); + "(negative = inwards, positive = outwards). This might be useful for fine-tuning sizes." + "\nThis one only applies to the 'exterior' shell of the object"); + def->sidetext = L("mm"); + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(0)); + + def = this->add("xy_inner_size_compensation", coFloat); + def->label = L("Inner"); + def->full_label = L("Inner XY size compensation"); + def->category = OptionCategory::slicing; + def->tooltip = L("The object will be grown/shrunk in the XY plane by the configured value " + "(negative = inwards, positive = outwards). This might be useful for fine-tuning sizes." + "\nThis one only applies to the 'inner' shell of the object"); def->sidetext = L("mm"); def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0)); @@ -3430,7 +3441,8 @@ void PrintConfigDef::init_fff_params() def->category = OptionCategory::slicing; def->tooltip = L("The convex holes will be grown / shrunk in the XY plane by the configured value" " (negative = inwards, positive = outwards, should be negative as the holes are always a bit smaller irl)." - " This might be useful for fine-tuning hole sizes."); + " This might be useful for fine-tuning hole sizes." + "\nThis setting behave the same as 'Inner XY size compensation' but only for convex shapes. It's added to 'Inner XY size compensation', it does not replace it. "); def->sidetext = L("mm"); def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0)); @@ -3752,7 +3764,7 @@ void PrintConfigDef::init_sla_params() def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(0.0)); - def = this->add("elefant_foot_min_width", coFloat); + def = this->add("elephant_foot_min_width", coFloat); def->label = L("Elephant foot minimum width"); def->category = OptionCategory::slicing; def->tooltip = L("Minimum width of features to maintain when doing elephant foot compensation."); @@ -4320,6 +4332,11 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va opt_key = "printhost_cafile"; } else if (opt_key == "octoprint_apikey") { opt_key = "printhost_apikey"; + } else if (opt_key == "elefant_foot_compensation") { + opt_key = "first_layer_size_compensation"; + float v = boost::lexical_cast(value); + if (v != 0) + value = boost::lexical_cast(-v); } // Ignore the following obsolete configuration keys: diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 2f8be6793..324ef3b97 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -492,11 +492,12 @@ public: ConfigOptionFloat brim_offset; ConfigOptionBool clip_multipart_objects; ConfigOptionBool dont_support_bridges; - ConfigOptionFloat elefant_foot_compensation; ConfigOptionPercent external_perimeter_cut_corners; ConfigOptionBool exact_last_layer_height; ConfigOptionFloatOrPercent extrusion_width; ConfigOptionFloatOrPercent first_layer_height; + ConfigOptionFloat first_layer_size_compensation; + ConfigOptionFloat hole_size_compensation; ConfigOptionBool infill_only_where_needed; // Force the generation of solid shells between adjacent materials/volumes. ConfigOptionBool interface_shells; @@ -538,7 +539,7 @@ public: ConfigOptionBool support_material_with_sheath; ConfigOptionFloatOrPercent support_material_xy_spacing; ConfigOptionFloat xy_size_compensation; - ConfigOptionFloat hole_size_compensation; + ConfigOptionFloat xy_inner_size_compensation; ConfigOptionBool wipe_into_objects; protected: @@ -552,11 +553,12 @@ protected: OPT_PTR(brim_offset); OPT_PTR(clip_multipart_objects); OPT_PTR(dont_support_bridges); - OPT_PTR(elefant_foot_compensation); OPT_PTR(external_perimeter_cut_corners); OPT_PTR(exact_last_layer_height); OPT_PTR(extrusion_width); + OPT_PTR(hole_size_compensation); OPT_PTR(first_layer_height); + OPT_PTR(first_layer_size_compensation); OPT_PTR(infill_only_where_needed); OPT_PTR(interface_shells); OPT_PTR(layer_height); @@ -592,7 +594,7 @@ protected: OPT_PTR(support_material_threshold); OPT_PTR(support_material_with_sheath); OPT_PTR(xy_size_compensation); - OPT_PTR(hole_size_compensation); + OPT_PTR(xy_inner_size_compensation); OPT_PTR(wipe_into_objects); } }; @@ -1477,8 +1479,8 @@ public: ConfigOptionBool display_mirror_y; ConfigOptionFloats relative_correction; ConfigOptionFloat absolute_correction; - ConfigOptionFloat elefant_foot_compensation; - ConfigOptionFloat elefant_foot_min_width; + ConfigOptionFloat first_layer_size_compensation; + ConfigOptionFloat elephant_foot_min_width; ConfigOptionFloat gamma_correction; ConfigOptionFloat fast_tilt_time; ConfigOptionFloat slow_tilt_time; @@ -1502,8 +1504,8 @@ protected: OPT_PTR(display_orientation); OPT_PTR(relative_correction); OPT_PTR(absolute_correction); - OPT_PTR(elefant_foot_compensation); - OPT_PTR(elefant_foot_min_width); + OPT_PTR(first_layer_size_compensation); + OPT_PTR(elephant_foot_min_width); OPT_PTR(gamma_correction); OPT_PTR(fast_tilt_time); OPT_PTR(slow_tilt_time); diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index e5b417715..5e0ed31ff 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -642,7 +642,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vectorthrow_if_canceled(); Layer *layer = m_layers[layer_id]; // Apply size compensation and perform clipping of multi-part objects. - float delta = float(scale_(m_config.xy_size_compensation.value)); - float hole_delta = float(scale_(this->config().hole_size_compensation.value)); + float outter_delta = float(scale_(m_config.xy_size_compensation.value)); + float inner_delta = float(scale_(m_config.xy_inner_size_compensation.value)); + float hole_delta = inner_delta + float(scale_(m_config.hole_size_compensation.value)); //FIXME only apply the compensation if no raft is enabled. float first_layer_compensation = 0.f; - if (layer_id == 0 && m_config.raft_layers == 0 && m_config.elefant_foot_compensation.value != 0) { + if (layer_id == 0 && m_config.raft_layers == 0 && m_config.first_layer_size_compensation.value != 0) { // Only enable Elephant foot compensation if printing directly on the print bed. - first_layer_compensation = float(scale_(m_config.elefant_foot_compensation.value)); + first_layer_compensation = float(scale_(m_config.first_layer_size_compensation.value)); if (first_layer_compensation > 0) { - delta += first_layer_compensation; + outter_delta += first_layer_compensation; + inner_delta += first_layer_compensation; + hole_delta += first_layer_compensation; first_layer_compensation = 0; } - else if (delta > 0) { - if (-first_layer_compensation < delta) { - delta += first_layer_compensation; - first_layer_compensation = 0; - } - else { - first_layer_compensation += delta; - delta = 0; + else { + float min_delta = std::min(outter_delta, std::min(inner_delta, hole_delta)); + if (min_delta > 0) { + if (-first_layer_compensation < min_delta) { + outter_delta += first_layer_compensation; + inner_delta += first_layer_compensation; + hole_delta += first_layer_compensation; + first_layer_compensation = 0; + } else { + first_layer_compensation += min_delta; + outter_delta -= min_delta; + inner_delta -= min_delta; + hole_delta -= min_delta; + } } } } @@ -2340,35 +2350,23 @@ end: if (layer->regions().size() == 1) { // Single region, growing or shrinking. LayerRegion *layerm = layer->regions().front(); - ExPolygons expolygons = to_expolygons(std::move(layerm->slices().surfaces)); - // Apply the XY hole compensation. - if (hole_delta > 0) { - expolygons = _offset_holes(-hole_delta, expolygons); + ExPolygons expolygons = to_expolygons(std::move(layerm->m_slices.surfaces)); + // Apply all three main XY compensation. + if (hole_delta > 0 || inner_delta > 0 || outter_delta > 0) { + expolygons = _grow_contour_holes(std::max(0.f, outter_delta), std::max(0.f, inner_delta), std::max(0.f, hole_delta), expolygons); if (layer_id == 0 && first_layer_compensation != 0) expolygons_first_layer = expolygons; } - // Apply the XY compensation. - if (delta > 0.f) { - expolygons = offset_ex(expolygons, delta); - if (layer_id == 0 && first_layer_compensation != 0) - expolygons_first_layer = offset_ex(expolygons_first_layer, float(scale_(m_config.xy_size_compensation.value))); - } - // Apply the elephant foot compensation. + // Apply the elephant foot compensation. if (layer_id == 0 && first_layer_compensation != 0.f) { expolygons = union_ex(Slic3r::elephant_foot_compensation(expolygons, layerm->flow(frExternalPerimeter), unscale(-first_layer_compensation))); } - // Apply the negative XY compensation. - if (delta < 0.f) { - expolygons = offset_ex(expolygons, delta); + // Apply all three main negative XY compensation. + if (hole_delta < 0 || inner_delta < 0 || outter_delta < 0) { + expolygons = _shrink_contour_holes(std::min(0.f, outter_delta), std::min(0.f, inner_delta), std::min(0.f, hole_delta), expolygons); if (layer_id == 0 && first_layer_compensation != 0) - expolygons_first_layer = offset_ex(expolygons_first_layer, float(scale_(m_config.xy_size_compensation.value))); - } - // Apply the negative XY hole compensation. - if (hole_delta < 0) { - expolygons = _offset_holes(-hole_delta, expolygons); - if (layer_id == 0 && first_layer_compensation != 0) - expolygons_first_layer = _offset_holes(-hole_delta, expolygons_first_layer); + expolygons_first_layer = _shrink_contour_holes(std::min(0.f, outter_delta), std::min(0.f, inner_delta), std::min(0.f, hole_delta), expolygons_first_layer); } if (layer->regions().front()->region()->config().curve_smoothing_precision > 0.f) { @@ -2379,16 +2377,17 @@ end: } layerm->m_slices.set(std::move(expolygons), stPosInternal | stDensSparse); } else { - bool upscale = ! upscaled && delta > 0.f; - bool clip = ! clipped && m_config.clip_multipart_objects.value; + float max_growth = std::max(hole_delta, std::max(inner_delta, outter_delta)); + float min_growth = std::min(hole_delta, std::min(inner_delta, outter_delta)); + bool clip = /*! clipped && ??? */ m_config.clip_multipart_objects.value; ExPolygons merged_poly_for_holes_growing; - if (hole_delta > 0.f) { + if (max_growth > 0) { //merge polygons because region can cut "holes". //then, cut them to give them again later to their region merged_poly_for_holes_growing = layer->merged(float(SCALED_EPSILON)); - merged_poly_for_holes_growing = _offset_holes(-hole_delta, union_ex(merged_poly_for_holes_growing)); + merged_poly_for_holes_growing = _grow_contour_holes(std::max(0.f, outter_delta), std::max(0.f, inner_delta), std::max(0.f, hole_delta), union_ex(merged_poly_for_holes_growing)); } - if (upscale || clip || hole_delta > 0.f) { + if (clip || max_growth > 0) { // Multiple regions, growing or just clipping one region by the other. // When clipping the regions, priority is given to the first regions. Polygons processed; @@ -2396,16 +2395,16 @@ end: LayerRegion *layerm = layer->regions()[region_id]; ExPolygons slices = to_expolygons(std::move(layerm->slices().surfaces)); if (hole_delta > 0.f) { - slices = intersection_ex(offset_ex(slices, hole_delta), merged_poly_for_holes_growing); + slices = intersection_ex(offset_ex(slices, max_growth), merged_poly_for_holes_growing); } - // Apply the XY compensation if >0. - if (upscale || (layer_id == 0 && first_layer_compensation > 0)) - slices = offset_ex(std::move(slices), std::max(delta, 0.f) + std::max(first_layer_compensation, 0.f)); + // Apply the first_layer_compensation if >0. + if (layer_id == 0 && first_layer_compensation > 0) + slices = offset_ex(std::move(slices), std::max(first_layer_compensation, 0.f)); //smoothing if (layerm->region()->config().curve_smoothing_precision > 0.f) slices = _smooth_curves(slices, layerm->region()->config()); + // Trim by the slices of already processed regions. if (region_id > 0 && clip) - // Trim by the slices of already processed regions. slices = diff_ex(to_polygons(std::move(slices)), processed); if (clip && (region_id + 1 < layer->regions().size())) // Collect the already processed regions to trim the to be processed regions. @@ -2413,23 +2412,20 @@ end: layerm->m_slices.set(std::move(slices), stPosInternal | stDensSparse); } } - if (delta < 0.f || first_layer_compensation != 0.f || hole_delta < 0.f) { + if (min_growth < 0.f || first_layer_compensation != 0.f) { // Apply the negative XY compensation. (the ones that is <0) ExPolygons trimming; static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5); if (layer_id == 0 && first_layer_compensation < 0.f) { - expolygons_first_layer = offset_ex(layer->merged(eps), std::min(delta, 0.f) - eps); + expolygons_first_layer = offset_ex(layer->merged(eps), - eps); trimming = Slic3r::elephant_foot_compensation(expolygons_first_layer, layer->regions().front()->flow(frExternalPerimeter), unscale(-first_layer_compensation)); } - else if (delta != 0.f) { - trimming = offset_ex(layer->merged(float(SCALED_EPSILON)), delta - float(SCALED_EPSILON)); - } else { trimming = layer->merged(float(SCALED_EPSILON)); } - if (hole_delta < 0) - trimming = _offset_holes(-hole_delta, trimming); + if (min_growth < 0) + trimming = _shrink_contour_holes(std::min(0.f, outter_delta), std::min(0.f, inner_delta), std::min(0.f, hole_delta), trimming); //trim surfaces for (size_t region_id = 0; region_id < layer->regions().size(); ++region_id) { layer->regions()[region_id]->trim_surfaces(to_polygons(trimming)); @@ -2453,7 +2449,68 @@ end: BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - end"; } -ExPolygons PrintObject::_offset_holes(double hole_delta, const ExPolygons &polys) const{ +ExPolygons PrintObject::_shrink_contour_holes(double contour_delta, double default_delta, double convex_delta, const ExPolygons& polys) const { + Polygons contours; + Polygons holes; + for (const ExPolygon& ex_poly : polys) { + for (const Polygon& hole : ex_poly.holes) { + //check if convex to reduce it + // check whether first point forms a convex angle + //note: we allow a deviation of 5.7° (0.01rad = 0.57°) + bool ok = true; + ok = (hole.points.front().ccw_angle(hole.points.back(), *(hole.points.begin() + 1)) <= PI + 0.1); + // check whether points 1..(n-1) form convex angles + if (ok) + for (Points::const_iterator p = hole.points.begin() + 1; p != hole.points.end() - 1; ++p) { + ok = (p->ccw_angle(*(p - 1), *(p + 1)) <= PI + 0.1); + if (!ok) break; + } + + // check whether last point forms a convex angle + ok &= (hole.points.back().ccw_angle(*(hole.points.end() - 2), hole.points.front()) <= PI + 0.1); + + if (ok) { + if (convex_delta != 0) { + for (Polygon &newHole : offset(hole, -convex_delta)) { + newHole.make_counter_clockwise(); + holes.emplace_back(std::move(newHole)); + } + } else { + holes.push_back(hole); + holes.back().make_counter_clockwise(); + } + } else { + if (default_delta != 0) { + for (Polygon &newHole : offset(hole, -default_delta)) { + newHole.make_counter_clockwise(); + holes.push_back(std::move(newHole)); + } + } else { + holes.push_back(hole); + holes.back().make_counter_clockwise(); + } + } + } + //modify contour + if (contour_delta != 0) { + Polygons new_contours = offset(ex_poly.contour, contour_delta); + if (new_contours.size() == 1) + contours = new_contours[0]; + else if (new_contours.size() == 0) + continue; + else { + //create a new expolygon for each contour + for (Polygon& contour : new_contours) { + contours.emplace_back(std::move(contour)); + } + continue; + } + } + } + return diff_ex(union_(contours), union_(holes)); +} + +ExPolygons PrintObject::_grow_contour_holes(double contour_delta, double default_delta, double convex_delta, const ExPolygons &polys) const{ ExPolygons new_polys; for (const ExPolygon &ex_poly : polys) { ExPolygon new_ex_poly(ex_poly); @@ -2472,21 +2529,48 @@ ExPolygons PrintObject::_offset_holes(double hole_delta, const ExPolygons &polys } // check whether last point forms a convex angle - ok &= (hole.points.back().ccw_angle(*(hole.points.end() - 2), hole.points.front()) <= PI + 0.1); + ok = ok && (hole.points.back().ccw_angle(*(hole.points.end() - 2), hole.points.front()) <= PI + 0.1); if (ok) { - for (Polygon newHole : offset(hole, hole_delta)) { - //reverse because it's a hole, not an object - newHole.make_clockwise(); - new_ex_poly.holes.push_back(newHole); - } + if (convex_delta != 0) { + for (Polygon &newHole : offset(hole, -convex_delta)) { + //reverse because it's a hole, not an object + newHole.make_clockwise(); + new_ex_poly.holes.emplace_back(std::move(newHole)); + } + } else + new_ex_poly.holes.push_back(hole); } else { - new_ex_poly.holes.push_back(hole); + if (default_delta != 0) { + for (Polygon &newHole : offset(hole, -default_delta)) { + //reverse because it's a hole, not an object + newHole.make_clockwise(); + new_ex_poly.holes.emplace_back(std::move(newHole)); + } + } else + new_ex_poly.holes.push_back(hole); + } + } + //modify contour + if (contour_delta != 0) { + Polygons new_contours = offset(ex_poly.contour, contour_delta); + if (new_contours.size() == 1) + new_ex_poly.contour = new_contours[0]; + else if (new_contours.size() == 0) + continue; + else { + //create a new expolygon for each contour (unlikely to happen) + for (Polygon& contour : new_contours) { + ExPolygon new_ex_poly_w_contour(new_ex_poly); + new_ex_poly_w_contour.contour = std::move(contour); + new_polys.emplace_back(std::move(new_ex_poly_w_contour)); + } + continue; } } new_polys.push_back(new_ex_poly); } - return new_polys; + return union_ex(new_polys); } /// max angle: you ahve to be lwer than that to divide it. PI => all accepted diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 565718c84..b08a0c9da 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -787,8 +787,8 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vectorm_printer_config.elefant_foot_min_width.getFloat() / 2.; - double start_efc = m_print->m_printer_config.elefant_foot_compensation.getFloat(); + double min_w = m_print->m_printer_config.elephant_foot_min_width.getFloat() / 2.; + double start_efc = m_print->m_printer_config.first_layer_size_compensation.getFloat(); double doffs = m_print->m_printer_config.absolute_correction.getFloat(); coord_t clpr_offs = scaled(doffs); diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 77bb72d5a..ae85ca581 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -503,7 +503,10 @@ const std::vector& Preset::print_options() "bridge_overlap", "first_layer_flow_ratio", "clip_multipart_objects", "enforce_full_fill_volume", "external_infill_margin", "bridged_infill_margin", - "elefant_foot_compensation", "xy_size_compensation", "hole_size_compensation", + "first_layer_size_compensation", + "xy_size_compensation", + "xy_inner_size_compensation", + "hole_size_compensation", "hole_to_polyhole", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", @@ -712,8 +715,8 @@ const std::vector& Preset::sla_printer_options() "fast_tilt_time", "slow_tilt_time", "area_fill", "relative_correction", "absolute_correction", - "elefant_foot_compensation", - "elefant_foot_min_width", + "first_layer_size_compensation", + "elephant_foot_min_width", "gamma_correction", "min_exposure_time", "max_exposure_time", "min_initial_exposure_time", "max_initial_exposure_time",