From 2749c63b10054077f5282cd2c1033ae8bf4cf5a5 Mon Sep 17 00:00:00 2001 From: Merill Date: Wed, 21 Mar 2018 22:19:42 +0100 Subject: [PATCH] overextruding a bit on top of bridge to come back to a correct height --- resources/profiles/PrusaResearch.ini | 1 + slic3r.pl | 1 + t/flow.t | 1 + t/perimeters.t | 1 + xs/src/libslic3r/Fill/Fill.cpp | 21 ++- xs/src/libslic3r/LayerRegion.cpp | 13 +- xs/src/libslic3r/Print.hpp | 1 + xs/src/libslic3r/PrintConfig.cpp | 15 ++ xs/src/libslic3r/PrintConfig.hpp | 2 + xs/src/libslic3r/PrintObject.cpp | 210 ++++++++++++++++++++++++++- xs/src/libslic3r/Surface.cpp | 26 +++- xs/src/libslic3r/Surface.hpp | 5 + xs/src/slic3r/GUI/Preset.cpp | 3 +- xs/src/slic3r/GUI/PresetHints.cpp | 1 + xs/src/slic3r/GUI/Tab.cpp | 1 + 15 files changed, 281 insertions(+), 21 deletions(-) diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini index 2e8c65fb0..f7c21bab8 100644 --- a/resources/profiles/PrusaResearch.ini +++ b/resources/profiles/PrusaResearch.ini @@ -34,6 +34,7 @@ avoid_crossing_perimeters = 0 bridge_acceleration = 1000 bridge_angle = 0 bridge_flow_ratio = 0.8 +over_bridge_flow_ratio = 1.2 bridge_speed = 20 brim_width = 0 clip_multipart_objects = 1 diff --git a/slic3r.pl b/slic3r.pl index d96359491..9cc05e6ef 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -531,6 +531,7 @@ Usage: slic3r.pl [ OPTIONS ] [ file.stl ] [ file2.stl ] ... Set a different extrusion width for support material --infill-overlap Overlap between infill and perimeters (default: $config->{infill_overlap}) --bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: $config->{bridge_flow_ratio}) + --over-bridge-flow-ratio Multiplier for extrusion when solid-filling over a bridge (> 0, default: $config->{over_bridge_flow_ratio}) Multiple extruder options: --extruder-offset Offset of each extruder, if firmware doesn't handle the displacement diff --git a/t/flow.t b/t/flow.t index 2fa0d8f10..e2de6542a 100644 --- a/t/flow.t +++ b/t/flow.t @@ -44,6 +44,7 @@ use Slic3r::Test; my $config = Slic3r::Config::new_from_defaults; $config->set('bridge_speed', 99); $config->set('bridge_flow_ratio', 1); + $config->set('over_bridge_flow_ratio', 1); $config->set('cooling', [ 0 ]); # to prevent speeds from being altered $config->set('first_layer_speed', '100%'); # to prevent speeds from being altered diff --git a/t/perimeters.t b/t/perimeters.t index 74bfb045d..0f8b89578 100644 --- a/t/perimeters.t +++ b/t/perimeters.t @@ -248,6 +248,7 @@ use Slic3r::Test; $config->set('slowdown_below_layer_time', [ 0 ]); $config->set('bridge_fan_speed', [ 100 ]); $config->set('bridge_flow_ratio', 33); # arbitrary value + $config->set('over_bridge_flow_ratio', 110); # arbitrary value $config->set('overhangs', 1); my $print = Slic3r::Test::init_print('overhang', config => $config); my %layer_speeds = (); # print Z => [ speeds ] diff --git a/xs/src/libslic3r/Fill/Fill.cpp b/xs/src/libslic3r/Fill/Fill.cpp index 4461f0588..fcb12c47e 100644 --- a/xs/src/libslic3r/Fill/Fill.cpp +++ b/xs/src/libslic3r/Fill/Fill.cpp @@ -63,14 +63,14 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out) // (we'll use them for comparing compatible groups) std::vector group_attrib(groups.size()); for (size_t i = 0; i < groups.size(); ++ i) { - // we can only merge solid non-bridge surfaces, so discard + // we can only merge solid non-bridge non-overextruded surfaces, so discard // non-solid surfaces const Surface &surface = *groups[i].front(); - if (surface.is_solid() && (!surface.is_bridge() || layerm.layer()->id() == 0)) { + if (surface.is_solid() && (!surface.is_bridge() || layerm.layer()->id() == 0) && !surface.is_overBridge()) { group_attrib[i].is_solid = true; - group_attrib[i].flow_width = (surface.surface_type == stTop) ? top_solid_infill_flow.width : solid_infill_flow.width; - group_attrib[i].pattern = (surface.surface_type == stTop && surface.is_external()) ? layerm.region()->config.top_fill_pattern.value : ipRectilinear; - group_attrib[i].pattern = (surface.surface_type == stBottom && surface.is_external()) ? layerm.region()->config.bottom_fill_pattern.value : ipRectilinear; + group_attrib[i].flow_width = (surface.is_top()) ? top_solid_infill_flow.width : solid_infill_flow.width; + group_attrib[i].pattern = (surface.is_top() && surface.is_external()) ? layerm.region()->config.top_fill_pattern.value : ipRectilinear; + group_attrib[i].pattern = (surface.is_bottom() && surface.is_external()) ? layerm.region()->config.bottom_fill_pattern.value : ipRectilinear; } } // Loop through solid groups, find compatible groups and append them to this one. @@ -155,14 +155,14 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out) continue; InfillPattern fill_pattern = layerm.region()->config.fill_pattern.value; double density = fill_density; - FlowRole role = (surface.surface_type == stTop) ? frTopSolidInfill : + FlowRole role = (surface.is_top()) ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill); bool is_bridge = layerm.layer()->id() > 0 && surface.is_bridge(); if (surface.is_solid()) { density = 100.; fill_pattern = (surface.is_external() && ! is_bridge) ? - (surface.surface_type == stTop ? layerm.region()->config.top_fill_pattern.value : layerm.region()->config.bottom_fill_pattern.value) : + (surface.is_top() ? layerm.region()->config.top_fill_pattern.value : layerm.region()->config.bottom_fill_pattern.value) : ipRectilinear; } else if (density <= 0) continue; @@ -241,6 +241,11 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out) } else { flow = Flow::new_from_spacing(f->spacing, flow.nozzle_diameter, h, is_bridge || f->use_bridge_flow()); } + + float flow_percent = 1; + if(surface.is_overBridge()){ + flow_percent = layerm.region()->config.over_bridge_flow_ratio; + } // Save into layer. auto *eec = new ExtrusionEntityCollection(); @@ -254,7 +259,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out) (surface.is_solid() ? ((surface.surface_type == stTop) ? erTopSolidInfill : erSolidInfill) : erInternalInfill), - flow.mm3_per_mm(), flow.width, flow.height); + flow.mm3_per_mm()*flow_percent, flow.width*flow_percent, flow.height); } // add thin fill regions diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp index 66f9bc582..27ed4ee2d 100644 --- a/xs/src/libslic3r/LayerRegion.cpp +++ b/xs/src/libslic3r/LayerRegion.cpp @@ -121,7 +121,7 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer) fill_boundaries.reserve(number_polygons(surfaces)); bool has_infill = this->region()->config.fill_density.value > 0.; for (const Surface &surface : this->fill_surfaces.surfaces) { - if (surface.surface_type == stTop) { + if (surface.is_top()) { // Collect the top surfaces, inflate them and trim them by the bottom surfaces. // This gives the priority to bottom surfaces. surfaces_append(top, offset_ex(surface.expolygon, float(margin), EXTERNAL_SURFACES_OFFSET_PARAMETERS), surface); @@ -132,13 +132,12 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer) if (! surface.empty()) bridges.push_back(surface); } - bool internal_surface = surface.surface_type != stTop && ! surface.is_bottom(); if (has_infill || surface.surface_type != stInternal) { - if (internal_surface) + if (!surface.is_external()) // Make a copy as the following line uses the move semantics. internal.push_back(surface); polygons_append(fill_boundaries, STDMOVE(surface.expolygon)); - } else if (internal_surface) + } else if (!surface.is_external()) internal.push_back(STDMOVE(surface)); } } @@ -304,7 +303,7 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer) s2.clear(); } } - if (s1.surface_type == stTop) + if (s1.is_top()) // Trim the top surfaces by the bottom surfaces. This gives the priority to the bottom surfaces. polys = diff(polys, bottom_polygons); surfaces_append( @@ -357,13 +356,13 @@ LayerRegion::prepare_fill_surfaces() // if no solid layers are requested, turn top/bottom surfaces to internal if (this->region()->config.top_solid_layers == 0) { for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) - if (surface->surface_type == stTop) + if (surface->is_top()) surface->surface_type = (this->layer()->object()->config.infill_only_where_needed) ? stInternalVoid : stInternal; } if (this->region()->config.bottom_solid_layers == 0) { for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) { - if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge) + if (surface->is_bottom()) surface->surface_type = stInternal; } } diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index c56e64c6c..802ba5981 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -199,6 +199,7 @@ public: void process_external_surfaces(); void discover_vertical_shells(); void bridge_over_infill(); + void replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_replacement, SurfaceType st_under_it); void _make_perimeters(); void _infill(); void clip_fill_surfaces(); diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 3a2010793..b93eafd9a 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -113,6 +113,17 @@ PrintConfigDef::PrintConfigDef() def->min = 0; def->default_value = new ConfigOptionFloat(1); + def = this->add("over_bridge_flow_ratio", coFloat); + def->label = L("Over-bridge flow ratio"); + def->category = L("Advanced"); + def->tooltip = L("This factor affects the amount of plastic to overextrude " + "when we are filling on top of a bridge surface." + "With a number >1, we can retreive the correct z-height " + "even if the bridged layer has fallen a bit."); + def->cli = "over-bridge-flow-ratio=f"; + def->min = 0; + def->default_value = new ConfigOptionFloat(1); + def = this->add("bridge_speed", coFloat); def->label = L("Bridges"); def->category = L("Speed"); @@ -2013,6 +2024,10 @@ std::string FullPrintConfig::validate() if (this->bridge_flow_ratio <= 0) return "Invalid value for --bridge-flow-ratio"; + // --over-bridge-flow-ratio + if (this->over_bridge_flow_ratio <= 0) + return "Invalid value for --over-bridge-flow-ratio"; + // extruder clearance if (this->extruder_clearance_radius <= 0) return "Invalid value for --extruder-clearance-radius"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 0378c80ed..e9164aba1 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -376,6 +376,7 @@ public: ConfigOptionFloat bridge_angle; ConfigOptionInt bottom_solid_layers; ConfigOptionFloat bridge_flow_ratio; + ConfigOptionFloat over_bridge_flow_ratio; ConfigOptionFloat bridge_speed; ConfigOptionBool ensure_vertical_shell_thickness; ConfigOptionEnum top_fill_pattern; @@ -416,6 +417,7 @@ protected: OPT_PTR(bridge_angle); OPT_PTR(bottom_solid_layers); OPT_PTR(bridge_flow_ratio); + OPT_PTR(over_bridge_flow_ratio); OPT_PTR(bridge_speed); OPT_PTR(ensure_vertical_shell_thickness); OPT_PTR(top_fill_pattern); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index 6cbb776b4..64facb6d9 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -363,10 +363,18 @@ void PrintObject::_prepare_infill() // the following step needs to be done before combination because it may need // to remove only half of the combined infill this->bridge_over_infill(); + std::cout<<"INTERNAL BRIDGE ===========================================\n"; + this->replaceSurfaceType( stInternalSolid, stInternalOverBridge, stInternalBridge); + std::cout<<"BOTTOM BRIDGE ===========================================\n"; + this->replaceSurfaceType( stInternalSolid, stInternalOverBridge, stBottomBridge); + std::cout<<"TOP BRIDGE ===========================================\n"; + this->replaceSurfaceType( stTop, stTopOverBridge, stInternalBridge); + this->replaceSurfaceType( stTop, stTopOverBridge, stBottomBridge); // combine fill surfaces to honor the "infill every N layers" option this->combine_infill(); + #ifdef SLIC3R_DEBUG_SLICE_PROCESSING for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) { for (const Layer *layer : this->layers) { @@ -435,6 +443,7 @@ void PrintObject::detect_surfaces_type() // unless internal shells are requested Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? this->layers[idx_layer + 1] : nullptr; Layer *lower_layer = (idx_layer > 0) ? this->layers[idx_layer - 1] : nullptr; + Layer *under_lower_layer = (idx_layer > 1) ? this->layers[idx_layer - 2] : nullptr; // collapse very narrow parts (using the safety offset in the diff is not enough) float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f; @@ -478,6 +487,7 @@ void PrintObject::detect_surfaces_type() diff(layerm_slices_surfaces, to_polygons(lower_layer->slices), true), -offset, offset), surface_type_bottom_other); + // if user requested internal shells, we need to identify surfaces // lying on other slices not belonging to this region if (interface_shells) { @@ -494,6 +504,7 @@ void PrintObject::detect_surfaces_type() stBottom); } #endif + } else { // if no lower layer, all surfaces of this one are solid // we clone surfaces because we're going to clear the slices collection @@ -501,6 +512,22 @@ void PrintObject::detect_surfaces_type() for (Surface &surface : bottom) surface.surface_type = surface_type_bottom_1st; } + + // Any surface lying on the void is a true bottom bridge (an overhang) + // and we have to conpensate if we are over that + // Surfaces bottomOverBridge; + // if(under_lower_layer){ + // surfaces_append( + // bottomOverBridge, + // offset2_ex( + // diff(layerm_slices_surfaces, to_polygons(under_lower_layer->slices), true), + // -offset, offset), + // stInternalOverBridge); + // std::cout<slices.expolygons.size()<<" > "<slices.expolygons.size();i++) std::cout<<" area of under_lower_layer "<slices.expolygons[i].area()<<"\n"; + // for(int i=0;i> expolygons_with_attributes; expolygons_with_attributes.emplace_back(std::make_pair(union_ex(top), SVG::ExPolygonAttributes("green"))); expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottom), SVG::ExPolygonAttributes("brown"))); + expolygons_with_attributes.emplace_back(std::make_pair(union_ex(bottomOverBridge), SVG::ExPolygonAttributes("grey"))); expolygons_with_attributes.emplace_back(std::make_pair(to_expolygons(layerm->slices.surfaces), SVG::ExPolygonAttributes("black"))); SVG::export_expolygons(debug_out_path("1_detect_surfaces_type_%d_region%d-layer_%f.svg", iRun ++, idx_region, layer->print_z).c_str(), expolygons_with_attributes); } @@ -535,6 +563,12 @@ void PrintObject::detect_surfaces_type() { Polygons topbottom = to_polygons(top); polygons_append(topbottom, to_polygons(bottom)); + // ExPolygons overExPolygons = diff_ex(to_polygons(bottomOverBridge), topbottom, false); + // surfaces_append(surfaces_out, + // overExPolygons, + // stInternalOverBridge); + // for(int i=0;i_print, region) { + size_t region_id = region - this->_print->regions.begin(); + + FOREACH_LAYER(this, layer_it) { + // skip first layer + if (layer_it == this->layers.begin()) continue; + + Layer* layer = *layer_it; + LayerRegion* layerm = layer->regions[region_id]; + + // extract the stInternalSolid surfaces that might be transformed into bridges + Polygons internal_solid; + layerm->fill_surfaces.filter_by_type(st_to_replace, &internal_solid); + + double internsolidareainit=0; + for (ExPolygon &ex : union_ex(internal_solid)) internsolidareainit+=ex.area(); + + Polygons internal_over_tot_init; + layerm->fill_surfaces.filter_by_type(st_replacement, &internal_over_tot_init); + double totoverareaInit=0; + for (ExPolygon &ex : union_ex(internal_over_tot_init)) totoverareaInit+=ex.area(); + + Polygons stBottom_init; + layerm->fill_surfaces.filter_by_type(stBottom, &stBottom_init); + double bottomeareainit=0; + for (ExPolygon &ex : union_ex(stBottom_init)) bottomeareainit+=ex.area(); + + Polygons stBottomBridge_init; + layerm->fill_surfaces.filter_by_type(stBottomBridge, &stBottomBridge_init); + double bottombridgearea=0; + for (ExPolygon &ex : union_ex(stBottomBridge_init)) bottombridgearea+=ex.area(); + + Polygons stIntBridge_init; + layerm->fill_surfaces.filter_by_type(st_under_it, &stIntBridge_init); + double intbridgeareainit=0; + for (ExPolygon &ex : union_ex(stIntBridge_init)) intbridgeareainit+=ex.area(); + + std::cout<<"init st_replacement="<layers.begin()) - 1 >= 0) { + const Layer* lower_layer = this->layers[int(layer_it - this->layers.begin()) - 1]; + + // iterate through regions and collect internal surfaces + Polygons lower_internal; + FOREACH_LAYERREGION(lower_layer, lower_layerm_it){ + Polygons lower_internal_OK; + Polygons lower_internal_Bridge; + Polygons lower_internal_Over; + (*lower_layerm_it)->fill_surfaces.filter_by_type(st_replacement, &lower_internal_OK); + (*lower_layerm_it)->fill_surfaces.filter_by_type(st_under_it, &lower_internal_Bridge); + (*lower_layerm_it)->fill_surfaces.filter_by_type(st_to_replace, &lower_internal_Over); + double okarea =0, bridgearea=0, overarea=0; + for (ExPolygon &ex : union_ex(lower_internal_OK)) okarea+=ex.area(); + for (ExPolygon &ex : union_ex(lower_internal_Bridge)) bridgearea+=ex.area(); + for (ExPolygon &ex : union_ex(lower_internal_Over)) overarea+=ex.area(); + std::cout<<"@layer "<layers.begin()) + <<" region under has "<fill_surfaces.filter_by_type(st_under_it, &lower_internal); + } + double sumarea=0; + for (ExPolygon &ex : union_ex(lower_internal)) sumarea+=ex.area(); + std::cout<<"@layer "<layers.begin())<<" region under has "<layers.begin())<<"\n"; + } + + #ifdef SLIC3R_DEBUG + printf("Bridging " PRINTF_ZU " internal areas at layer " PRINTF_ZU "\n", to_overextrude.size(), layer->id()); + #endif + + // compute the remaning internal solid surfaces as difference + ExPolygons not_to_overextrude = diff_ex(internal_solid, to_polygons(to_overextrude), true); + to_overextrude = intersection_ex(to_polygons(to_overextrude), internal_solid, true); + // build the new collection of fill_surfaces + layerm->fill_surfaces.remove_type(st_to_replace); + double overareafinal = 0, solidareafinal=0; + for (ExPolygon &ex : to_overextrude){ + overareafinal += ex.area(); + layerm->fill_surfaces.surfaces.push_back(Surface(st_replacement, ex)); + } + for (ExPolygon &ex : not_to_overextrude){ + solidareafinal += ex.area(); + layerm->fill_surfaces.surfaces.push_back(Surface(st_to_replace, ex)); + } + Polygons internal_over_tot; + layerm->fill_surfaces.filter_by_type(stInternalOverBridge, &internal_over_tot); + double totoverarea=0; + for (ExPolygon &ex : union_ex(internal_over_tot)) totoverarea+=ex.area(); + std::cout<<"final: st_to_replace="<extruders->{infill}->bridge_flow->width - $layerm->height; + for (my $i = $layer_id-1; $excess >= $self->get_layer($i)->height; $i--) { + Slic3r::debugf " skipping infill below those areas at layer %d\n", $i; + foreach my $lower_layerm (@{$self->get_layer($i)->regions}) { + my @new_surfaces = (); + # subtract the area from all types of surfaces + foreach my $group (@{$lower_layerm->fill_surfaces->group}) { + push @new_surfaces, map $group->[0]->clone(expolygon => $_), + @{diff_ex( + [ map $_->p, @$group ], + [ map @$_, @$to_overextrude ], + )}; + push @new_surfaces, map Slic3r::Surface->new( + expolygon => $_, + surface_type => S_TYPE_INTERNALVOID, + ), @{intersection_ex( + [ map $_->p, @$group ], + [ map @$_, @$to_overextrude ], + )}; + } + $lower_layerm->fill_surfaces->clear; + $lower_layerm->fill_surfaces->append($_) for @new_surfaces; + } + + $excess -= $self->get_layer($i)->height; + } + } + */ + +#ifdef SLIC3R_DEBUG_SLICE_PROCESSING + layerm->export_region_slices_to_svg_debug("7_overextrude_over_bridge"); + layerm->export_region_fill_surfaces_to_svg_debug("7_overextrude_over_bridge"); +#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ + } + } +} + + SlicingParameters PrintObject::slicing_parameters() const { return SlicingParameters::create_from_config( @@ -1699,8 +1905,8 @@ void PrintObject::discover_horizontal_shells() continue; // Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == S_TYPE_TOP) ? 'top' : 'bottom'; - size_t solid_layers = (type == stTop) ? region_config.top_solid_layers.value : region_config.bottom_solid_layers.value; - for (int n = (type == stTop) ? i-1 : i+1; std::abs(n - i) < solid_layers; (type == stTop) ? -- n : ++ n) { + size_t solid_layers = (type == stTop || type == stTopOverBridge) ? region_config.top_solid_layers.value : region_config.bottom_solid_layers.value; + for (int n = (type == stTop || type == stTopOverBridge) ? i-1 : i+1; std::abs(n - i) < solid_layers; (type == stTop || type == stTopOverBridge) ? -- n : ++ n) { if (n < 0 || n >= int(this->layers.size())) continue; // Slic3r::debugf " looking for neighbors on layer %d...\n", $n; diff --git a/xs/src/libslic3r/Surface.cpp b/xs/src/libslic3r/Surface.cpp index 384540d87..bdc0b7e9a 100644 --- a/xs/src/libslic3r/Surface.cpp +++ b/xs/src/libslic3r/Surface.cpp @@ -22,7 +22,9 @@ Surface::is_solid() const || this->surface_type == stBottom || this->surface_type == stBottomBridge || this->surface_type == stInternalSolid - || this->surface_type == stInternalBridge; + || this->surface_type == stInternalBridge + || this->surface_type == stInternalOverBridge + || this->surface_type == stTopOverBridge; } bool @@ -30,7 +32,15 @@ Surface::is_external() const { return this->surface_type == stTop || this->surface_type == stBottom - || this->surface_type == stBottomBridge; + || this->surface_type == stBottomBridge + || this->surface_type == stTopOverBridge; +} + +bool +Surface::is_top() const +{ + return this->surface_type == stTop + || this->surface_type == stTopOverBridge; } bool @@ -38,6 +48,7 @@ Surface::is_internal() const { return this->surface_type == stInternal || this->surface_type == stInternalBridge + || this->surface_type == stInternalOverBridge || this->surface_type == stInternalSolid || this->surface_type == stInternalVoid; } @@ -55,6 +66,12 @@ Surface::is_bridge() const return this->surface_type == stBottomBridge || this->surface_type == stInternalBridge; } +bool +Surface::is_overBridge() const +{ + return this->surface_type == stInternalOverBridge + || this->surface_type == stTopOverBridge; +} BoundingBox get_extents(const Surface &surface) { @@ -91,7 +108,8 @@ const char* surface_type_to_color_name(const SurfaceType surface_type) case stBottomBridge: return "rgb(0,0,255)"; // "blue"; case stInternal: return "rgb(255,255,128)"; // yellow case stInternalSolid: return "rgb(255,0,255)"; // magenta - case stInternalBridge: return "rgb(0,255,255)"; + case stInternalBridge: return "rgb(0,255,255)"; // cyan + case stInternalOverBridge: return "rgb(0,255,128)"; // green-cyan case stInternalVoid: return "rgb(128,128,128)"; case stPerimeter: return "rgb(128,0,0)"; // maroon default: return "rgb(64,64,64)"; @@ -128,6 +146,8 @@ void export_surface_type_legend_to_svg(SVG &svg, const Point &pos) pos_x += step_x; svg.draw_legend(Point(pos_x, pos_y), "internal bridge", surface_type_to_color_name(stInternalBridge)); pos_x += step_x; + svg.draw_legend(Point(pos_x, pos_y), "internal over bridge", surface_type_to_color_name(stInternalOverBridge)); + pos_x += step_x; svg.draw_legend(Point(pos_x, pos_y), "internal void" , surface_type_to_color_name(stInternalVoid)); } diff --git a/xs/src/libslic3r/Surface.hpp b/xs/src/libslic3r/Surface.hpp index c2cec3793..3ad7380cd 100644 --- a/xs/src/libslic3r/Surface.hpp +++ b/xs/src/libslic3r/Surface.hpp @@ -19,6 +19,9 @@ enum SurfaceType { stInternalSolid, // 1st layer of dense infill over sparse infill, printed with a bridging extrusion flow. stInternalBridge, + // 2nd layer of dense infill over sparse infill/nothing, printed with an over-extruding flow. + stInternalOverBridge, + stTopOverBridge, // stInternal turns into void surfaces if the sparse infill is used for supports only, // or if sparse infill layers get combined into a single layer. stInternalVoid, @@ -97,9 +100,11 @@ public: void clear() { expolygon.clear(); } bool is_solid() const; bool is_external() const; + bool is_top() const; bool is_internal() const; bool is_bottom() const; bool is_bridge() const; + bool is_overBridge() const; }; typedef std::vector Surfaces; diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 0c8df208c..78a115aa8 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -197,7 +197,8 @@ const std::vector& Preset::print_options() "infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder", "ooze_prevention", "standby_temperature_delta", "interface_shells", "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", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects", + "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", + "over_bridge_flow_ratio", "clip_multipart_objects", "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_per_color_wipe", "only_one_perimeter_top", "compatible_printers", "compatible_printers_condition" diff --git a/xs/src/slic3r/GUI/PresetHints.cpp b/xs/src/slic3r/GUI/PresetHints.cpp index d4c929c1c..aad28766a 100644 --- a/xs/src/slic3r/GUI/PresetHints.cpp +++ b/xs/src/slic3r/GUI/PresetHints.cpp @@ -84,6 +84,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle double support_material_interface_speed = print_config.get_abs_value("support_material_interface_speed", support_material_speed); double bridge_speed = print_config.opt_float("bridge_speed"); double bridge_flow_ratio = print_config.opt_float("bridge_flow_ratio"); + double over_bridge_flow_ratio = print_config.opt_float("over_bridge_flow_ratio"); double perimeter_speed = print_config.opt_float("perimeter_speed"); double external_perimeter_speed = print_config.get_abs_value("external_perimeter_speed", perimeter_speed); double gap_fill_speed = print_config.opt_float("gap_fill_speed"); diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index cd95666a6..ad5d0629c 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -538,6 +538,7 @@ void TabPrint::build() optgroup = page->new_optgroup(_(L("Flow"))); optgroup->append_single_option_line("bridge_flow_ratio"); + optgroup->append_single_option_line("over_bridge_flow_ratio"); optgroup = page->new_optgroup(_(L("Other"))); optgroup->append_single_option_line("clip_multipart_objects");