From 2ee32bb244d2945cf0d1f574d8525f78ae30b05b Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Mon, 19 Jun 2017 11:25:11 +0200 Subject: [PATCH] Added new option for additional overlap between regions printed with distinct extruders or settings --- lib/Slic3r/GUI/PresetEditor.pm | 3 +- xs/src/libslic3r/PrintConfig.cpp | 8 ++++ xs/src/libslic3r/PrintConfig.hpp | 2 + xs/src/libslic3r/PrintObject.cpp | 76 ++++++++++++++++++++------------ 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/lib/Slic3r/GUI/PresetEditor.pm b/lib/Slic3r/GUI/PresetEditor.pm index d00deb4bd..1eeb3c031 100644 --- a/lib/Slic3r/GUI/PresetEditor.pm +++ b/lib/Slic3r/GUI/PresetEditor.pm @@ -467,7 +467,7 @@ sub options { perimeter_extruder infill_extruder solid_infill_extruder support_material_extruder support_material_interface_extruder ooze_prevention standby_temperature_delta - interface_shells + interface_shells regions_overlap extrusion_width first_layer_extrusion_width perimeter_extrusion_width external_perimeter_extrusion_width infill_extrusion_width solid_infill_extrusion_width top_infill_extrusion_width support_material_extrusion_width @@ -665,6 +665,7 @@ sub build { } { my $optgroup = $page->new_optgroup('Advanced'); + $optgroup->append_single_option_line('regions_overlap'); $optgroup->append_single_option_line('interface_shells'); } } diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index cc95d38b6..3a5ca6866 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -967,6 +967,14 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->default_value = new ConfigOptionInt(0); + def = this->add("regions_overlap", coFloat); + def->label = "Regions/extruders overlap"; + def->category = "Extruders"; + def->tooltip = "This setting applies an additional overlap between regions printed with distinct extruders or distinct settings. This shouldn't be needed under normal circumstances."; + def->sidetext = "mm"; + def->cli = "regions-overlap=s"; + def->default_value = new ConfigOptionFloat(0); + def = this->add("raft_offset", coFloat); def->label = "Raft offset"; def->category = "Support material"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 91e463f3a..4f91ef806 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -161,6 +161,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig ConfigOptionBool interface_shells; ConfigOptionFloat layer_height; ConfigOptionInt raft_layers; + ConfigOptionFloat regions_overlap; ConfigOptionEnum seam_position; ConfigOptionBool support_material; ConfigOptionInt support_material_angle; @@ -192,6 +193,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig OPT_PTR(interface_shells); OPT_PTR(layer_height); OPT_PTR(raft_layers); + OPT_PTR(regions_overlap); OPT_PTR(seam_position); OPT_PTR(support_material); OPT_PTR(support_material_angle); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index ff87345eb..ed434d48c 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -224,7 +224,8 @@ PrintObject::invalidate_state_by_config(const PrintConfigBase &config) if (opt_key == "layer_height" || opt_key == "first_layer_height" || opt_key == "xy_size_compensation" - || opt_key == "raft_layers") { + || opt_key == "raft_layers" + || opt_key == "regions_overlap") { steps.insert(posSlice); } else if (opt_key == "support_material_contact_distance") { steps.insert(posSlice); @@ -737,38 +738,57 @@ void PrintObject::_slice() } this->delete_layer(int(this->layers.size()) - 1); } - - for (size_t layer_id = 0; layer_id < layers.size(); ++ layer_id) { - Layer *layer = this->layers[layer_id]; - // Apply size compensation and perform clipping of multi-part objects. - float delta = float(scale_(this->config.xy_size_compensation.value)); - bool scale = delta != 0.f; - if (layer->regions.size() == 1) { - if (scale) { + + // Apply size compensation and perform clipping of multi-part objects. + const coord_t xy_size_compensation = scale_(this->config.xy_size_compensation.value); + for (Layer* layer : this->layers) { + if (xy_size_compensation > 0) { + if (layer->regions.size() == 1) { // Single region, growing or shrinking. - LayerRegion *layerm = layer->regions.front(); - layerm->slices.set(offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta), stInternal); - } - } else if (scale) { - // Multiple regions, growing, shrinking or just clipping one region by the other. - // When clipping the regions, priority is given to the first regions. - Polygons processed; - for (size_t region_id = 0; region_id < layer->regions.size(); ++ region_id) { - LayerRegion *layerm = layer->regions[region_id]; - ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces)); - if (scale) - slices = offset_ex(slices, delta); - if (region_id > 0) - // Trim by the slices of already processed regions. - slices = diff_ex(to_polygons(std::move(slices)), processed); - if (region_id + 1 < layer->regions.size()) - // Collect the already processed regions to trim the to be processed regions. - processed += to_polygons(slices); - layerm->slices.set(std::move(slices), stInternal); + LayerRegion* layerm = layer->regions.front(); + layerm->slices.set( + offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), xy_size_compensation), + stInternal + ); + } else { + // Multiple regions, growing, shrinking or just clipping one region by the other. + // When clipping the regions, priority is given to the first regions. + Polygons processed; + for (size_t region_id = 0; region_id < layer->regions.size(); ++region_id) { + LayerRegion* layerm = layer->regions[region_id]; + Polygons slices = layerm->slices; + + if (xy_size_compensation > 0) + slices = offset(slices, xy_size_compensation); + + if (region_id > 0) + // Trim by the slices of already processed regions. + slices = diff(std::move(slices), processed); + + if (region_id + 1 < layer->regions.size()) + // Collect the already processed regions to trim the to be processed regions. + append_to(processed, slices); + + layerm->slices.set(union_ex(slices), stInternal); + } } } + // Merge all regions' slices to get islands, chain them by a shortest path. layer->make_slices(); + + // Apply regions overlap + if (this->config.regions_overlap.value > 0) { + const coord_t delta = scale_(this->config.regions_overlap.value)/2; + for (LayerRegion* layerm : layer->regions) + layerm->slices.set( + intersection_ex( + offset(layerm->slices, +delta), + layer->slices + ), + stInternal + ); + } } }