diff options
author | supermerill <merill@fr.fr> | 2018-09-26 17:57:30 +0300 |
---|---|---|
committer | supermerill <merill@fr.fr> | 2018-09-26 17:57:30 +0300 |
commit | 8e5cc9c906c3e9033656d53d6ec2f8c8914ff40f (patch) | |
tree | 13a6e4712e3919a21d2488a9071d337b7e6e6e94 | |
parent | 8b9fb5b654646c6fad20f4617a81d0ffbf0dc4b7 (diff) | |
parent | a383f89a7d7121073690beab9bab36f0ac578d29 (diff) |
Merge branch 'master_slic3rPE_PR'
-rw-r--r-- | xs/src/libslic3r/Fill/Fill.cpp | 2 | ||||
-rw-r--r-- | xs/src/libslic3r/Fill/FillBase.cpp | 22 | ||||
-rw-r--r-- | xs/src/libslic3r/Fill/FillBase.hpp | 4 | ||||
-rw-r--r-- | xs/src/libslic3r/Fill/FillRectilinear2.cpp | 54 | ||||
-rw-r--r-- | xs/src/libslic3r/Fill/FillRectilinear2.hpp | 3 | ||||
-rw-r--r-- | xs/src/libslic3r/Fill/FillSmooth.cpp | 27 | ||||
-rw-r--r-- | xs/src/libslic3r/Fill/FillSmooth.hpp | 3 | ||||
-rw-r--r-- | xs/src/libslic3r/GCode.cpp | 4 | ||||
-rw-r--r-- | xs/src/libslic3r/LayerRegion.cpp | 27 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintConfig.cpp | 9 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintConfig.hpp | 2 | ||||
-rw-r--r-- | xs/src/libslic3r/PrintObject.cpp | 3 | ||||
-rw-r--r-- | xs/src/libslic3r/SupportMaterial.cpp | 72 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/Preset.cpp | 3 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/Tab.cpp | 5 |
15 files changed, 165 insertions, 75 deletions
diff --git a/xs/src/libslic3r/Fill/Fill.cpp b/xs/src/libslic3r/Fill/Fill.cpp index 40e87cbe4..0158221af 100644 --- a/xs/src/libslic3r/Fill/Fill.cpp +++ b/xs/src/libslic3r/Fill/Fill.cpp @@ -296,7 +296,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out) //params.flow_mult = layerm.region()->config.over_bridge_flow_ratio; } - f->fill_surface_extrusion(&surface, params, flow, out); + f->fill_surface_extrusion(&surface, params, flow, erNone, out.entities); } // add thin fill regions diff --git a/xs/src/libslic3r/Fill/FillBase.cpp b/xs/src/libslic3r/Fill/FillBase.cpp index f8647a0b0..e1eae0244 100644 --- a/xs/src/libslic3r/Fill/FillBase.cpp +++ b/xs/src/libslic3r/Fill/FillBase.cpp @@ -136,7 +136,7 @@ std::pair<float, Point> Fill::_infill_direction(const Surface *surface) const return std::pair<float, Point>(out_angle, out_shift); } -void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out) { +void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out) { //add overlap & call fill_surface Polylines polylines = this->fill_surface(surface, params); if (polylines.empty()) @@ -184,16 +184,22 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ /// pass the no_sort attribute to the extrusion path eec->no_sort = this->no_sort(); /// add it into the collection - out.entities.push_back(eec); + out.push_back(eec); + //get the role + ExtrusionRole good_role = role; + if (good_role == erNone || good_role == erCustom) { + good_role = (flow.bridge ? erBridgeInfill : + (surface->is_solid() ? + ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) : + erInternalInfill)); + } /// push the path extrusion_entities_append_paths( eec->entities, STDMOVE(polylines), - flow.bridge ? - erBridgeInfill : - (surface->is_solid() ? - ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) : - erInternalInfill), - flow.mm3_per_mm() * params.flow_mult * multFlow, flow.width * params.flow_mult * multFlow, flow.height); + good_role, + flow.mm3_per_mm() * params.flow_mult * multFlow, + flow.width * params.flow_mult * multFlow, + flow.height); } diff --git a/xs/src/libslic3r/Fill/FillBase.hpp b/xs/src/libslic3r/Fill/FillBase.hpp index e569a4773..79a43a821 100644 --- a/xs/src/libslic3r/Fill/FillBase.hpp +++ b/xs/src/libslic3r/Fill/FillBase.hpp @@ -86,7 +86,9 @@ public: virtual bool no_sort() const { return false; } // This method have to fill the ExtrusionEntityCollection. It call fill_surface by default - virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out ); + // if role == erNone or ERCustom, this method have to choose the best role itself, else it must use the argument's role. + virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, + const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out); // Perform the fill. virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms); diff --git a/xs/src/libslic3r/Fill/FillRectilinear2.cpp b/xs/src/libslic3r/Fill/FillRectilinear2.cpp index 3c0f0a7cc..be1c218ee 100644 --- a/xs/src/libslic3r/Fill/FillRectilinear2.cpp +++ b/xs/src/libslic3r/Fill/FillRectilinear2.cpp @@ -1474,9 +1474,10 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams ¶ } -//Polylines FillRectilinear2Peri::fill_surface(const Surface *surface, const FillParams ¶ms) { - -void FillRectilinear2Peri::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out) { +void +FillRectilinear2Peri::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, + const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out) +{ ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection(); //you don't want to sort the extrusions: big infill first, small second eecroot->no_sort = true; @@ -1501,17 +1502,26 @@ void FillRectilinear2Peri::fill_surface_extrusion(const Surface *surface, const eec->no_sort = this->no_sort(); /// add it into the collection eecroot->entities.push_back(eec); + //get the role + ExtrusionRole good_role = role; + if (good_role == erNone || good_role == erCustom) { + good_role = flow.bridge ? + erBridgeInfill : + (surface->is_solid() ? + ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) : + erInternalInfill); + } /// push the path extrusion_entities_append_paths( - eec->entities, (polylines_1), - flow.bridge ? - erBridgeInfill : - (surface->is_solid() ? - ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) : - erInternalInfill), - flow.mm3_per_mm() * params.flow_mult, flow.width * params.flow_mult, flow.height); + eec->entities, + polylines_1, + good_role, + flow.mm3_per_mm() * params.flow_mult, + flow.width * params.flow_mult, + flow.height); } + // === extrude dense infill === Polylines polylines_2; bool canFill = true; @@ -1531,20 +1541,28 @@ void FillRectilinear2Peri::fill_surface_extrusion(const Surface *surface, const eec->no_sort = this->no_sort(); /// add it into the collection eecroot->entities.push_back(eec); + //get the role + ExtrusionRole good_role = role; + if (good_role == erNone || good_role == erCustom) { + good_role = flow.bridge ? + erBridgeInfill : + (surface->is_solid() ? + ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) : + erInternalInfill); + } /// push the path extrusion_entities_append_paths( - eec->entities, (polylines_2), - flow.bridge ? - erBridgeInfill : - (surface->is_solid() ? - ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) : - erInternalInfill), - flow.mm3_per_mm() * params.flow_mult, flow.width * params.flow_mult, flow.height); + eec->entities, + polylines_2, + good_role, + flow.mm3_per_mm() * params.flow_mult, + flow.width * params.flow_mult, + flow.height); } // === end === if (!eecroot->empty()) { - out.entities.push_back(eecroot); + out.push_back(eecroot); } else { delete eecroot; } diff --git a/xs/src/libslic3r/Fill/FillRectilinear2.hpp b/xs/src/libslic3r/Fill/FillRectilinear2.hpp index 53621d139..3457fad95 100644 --- a/xs/src/libslic3r/Fill/FillRectilinear2.hpp +++ b/xs/src/libslic3r/Fill/FillRectilinear2.hpp @@ -76,7 +76,8 @@ public: virtual Fill* clone() const { return new FillRectilinear2Peri(*this); }; virtual ~FillRectilinear2Peri() {} //virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms); - virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out); + virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, + const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out); }; diff --git a/xs/src/libslic3r/Fill/FillSmooth.cpp b/xs/src/libslic3r/Fill/FillSmooth.cpp index 59e63c792..7168c5882 100644 --- a/xs/src/libslic3r/Fill/FillSmooth.cpp +++ b/xs/src/libslic3r/Fill/FillSmooth.cpp @@ -19,7 +19,8 @@ namespace Slic3r { } - void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out) + void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, + const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out) { coordf_t init_spacing = this->spacing; @@ -142,9 +143,14 @@ namespace Slic3r { eec = new ExtrusionEntityCollection(); eecroot->entities.push_back(eec); eec->no_sort = false; //can be sorted inside the pass + //get the role + ExtrusionRole good_role = role; + if (good_role == erNone || good_role == erCustom) { + good_role = flow.bridge ? erBridgeInfill : rolePass[0]; + } extrusion_entities_append_paths( eec->entities, STDMOVE(polylines_layer1), - flow.bridge ? erBridgeInfill : rolePass[0], + good_role, //reduced flow height for a better view (it's only a gui thing) params.flow_mult * flow.mm3_per_mm() * percentFlow[0] * (params.fill_exactly ? poylineVolume / extrudedVolume : 1), (float)(flow.width*percentFlow[0] * (params.fill_exactly ? poylineVolume / extrudedVolume : 1)), (float)flow.height*0.8); @@ -192,11 +198,15 @@ namespace Slic3r { eec = new ExtrusionEntityCollection(); eecroot->entities.push_back(eec); eec->no_sort = false; + //get the role + ExtrusionRole good_role = role; + if (good_role == erNone || good_role == erCustom) { + good_role = rolePass[1]; + } // print thin - extrusion_entities_append_paths( eec->entities, STDMOVE(polylines_layer2), - rolePass[1], + good_role, params.flow_mult * flow.mm3_per_mm() * percentFlow[1] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1), //min-reduced flow width for a better view (it's only a gui thing) (float)(flow.width*(percentFlow[1] < 0.1 ? 0.1 : percentFlow[1])), (float)flow.height); @@ -244,10 +254,15 @@ namespace Slic3r { eec = new ExtrusionEntityCollection(); eecroot->entities.push_back(eec); eec->no_sort = false; + //get the role + ExtrusionRole good_role = role; + if (good_role == erNone || good_role == erCustom) { + good_role = rolePass[2]; + } // print thin extrusion_entities_append_paths( eec->entities, STDMOVE(polylines_layer3), - rolePass[2], //slow (if last) + good_role, //slow (if last) //reduced flow width for a better view (it's only a gui thing) params.flow_mult * flow.mm3_per_mm() * percentFlow[2] * (params.fill_exactly ? volumeToOccupy / extrudedVolume : 1), (float)(flow.width*(percentFlow[2] < 0.1 ? 0.1 : percentFlow[2])), (float)flow.height); @@ -255,7 +270,7 @@ namespace Slic3r { } if (!eecroot->entities.empty()) - out.entities.push_back(eecroot); + out.push_back(eecroot); } diff --git a/xs/src/libslic3r/Fill/FillSmooth.hpp b/xs/src/libslic3r/Fill/FillSmooth.hpp index 3e9300a8f..eb558f088 100644 --- a/xs/src/libslic3r/Fill/FillSmooth.hpp +++ b/xs/src/libslic3r/Fill/FillSmooth.hpp @@ -35,7 +35,8 @@ public: virtual Fill* clone() const { return new FillSmooth(*this); } virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms); - virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, const Flow &flow, ExtrusionEntityCollection &out ); + virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, + const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out); protected: int nbPass=2; diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 62563ef25..27c838037 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -2241,6 +2241,10 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill for (const ExtrusionEntity *ee : support_fills.entities) { ExtrusionRole role = ee->role(); assert(role == erSupportMaterial || role == erSupportMaterialInterface); + if (const ExtrusionEntityCollection* coll = dynamic_cast<const ExtrusionEntityCollection*>(ee)) { + gcode += extrude_support(*coll); + continue; + } const char *label = (role == erSupportMaterial) ? support_label : support_interface_label; const double speed = (role == erSupportMaterial) ? support_speed : support_interface_speed; const ExtrusionPath *path = dynamic_cast<const ExtrusionPath*>(ee); diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp index a409f3885..aee94ab17 100644 --- a/xs/src/libslic3r/LayerRegion.cpp +++ b/xs/src/libslic3r/LayerRegion.cpp @@ -95,9 +95,18 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* void LayerRegion::process_external_surfaces(const Layer* lower_layer) { const Surfaces &surfaces = this->fill_surfaces.surfaces; - const double margin = scale_(this->region()->config.external_infill_margin.getFloat()); - const double margin_bridged = scale_(this->region()->config.bridged_infill_margin.getFloat()); - + const bool has_infill = this->region()->config.fill_density.value > 0.; + coord_t margin = scale_(this->region()->config.external_infill_margin.getFloat()); + coord_t margin_bridged = scale_(this->region()->config.bridged_infill_margin.getFloat()); + //if no infill, reduce the margin for averythign to only the perimeter + if (!has_infill) { + if ((this->region()->config.perimeters.value > 0)) { + const coord_t perimeter_width = scale_(this->region()->config.perimeter_extrusion_width.get_abs_value(this->layer()->object()->config.layer_height.value)); + const coord_t first_perimeter_width = scale_(this->region()->config.external_perimeter_extrusion_width.get_abs_value(this->layer()->object()->config.layer_height.value)); + margin = first_perimeter_width + perimeter_width * (this->region()->config.perimeters.value - 1); + } else margin = 0; + margin_bridged = margin; + } #ifdef SLIC3R_DEBUG_SLICE_PROCESSING export_region_fill_surfaces_to_svg_debug("3_process_external_surfaces-initial"); #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ @@ -122,7 +131,6 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer) { // bottom_polygons are used to trim inflated top surfaces. 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.is_top()) { // Collect the top surfaces, inflate them and trim them by the bottom surfaces. @@ -140,8 +148,15 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer) // Make a copy as the following line uses the move semantics. internal.push_back(surface); polygons_append(fill_boundaries, STDMOVE(surface.expolygon)); - } else if (!surface.is_external()) - internal.push_back(STDMOVE(surface)); + } else{ + if (!surface.is_external()) + internal.push_back(STDMOVE(surface)); + //push surface as perimeter-only inside the fill_boundaries + if (margin_bridged > 0) { + ExPolygons peri_poly = diff_ex(ExPolygons() = { surface.expolygon }, offset_ex(surface.expolygon, -margin_bridged)); + polygons_append(fill_boundaries, peri_poly); + } + } } } diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index ca516a4a4..bd6dda0c7 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1484,11 +1484,18 @@ PrintConfigDef::PrintConfigDef() def = this->add("printer_settings_id", coString); def->default_value = new ConfigOptionString(""); + def = this->add("support_material_solid_first_layer", coBool); + def->label = L("Solid first layer"); + def->category = L("Support material"); + def->tooltip = L("Use a solid layer instead of a raft for the layer that touch the build plate."); + def->cli = "support-material-solid-first-layer!"; + def->default_value = new ConfigOptionBool(false); + def = this->add("raft_layers", coInt); def->label = L("Raft layers"); def->category = L("Support material"); def->tooltip = L("The object will be raised by this number of layers, and support material " - "will be generated under it."); + "will be generated under it."); def->sidetext = L("layers"); def->cli = "raft-layers=i"; def->min = 0; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 007528077..c8697c3a0 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -350,6 +350,7 @@ public: ConfigOptionEnum<SupportMaterialPattern> support_material_pattern; ConfigOptionFloat support_material_spacing; ConfigOptionFloat support_material_speed; + ConfigOptionBool support_material_solid_first_layer; ConfigOptionBool support_material_synchronize_layers; ConfigOptionInt support_material_threshold; ConfigOptionBool support_material_with_sheath; @@ -389,6 +390,7 @@ protected: OPT_PTR(support_material_pattern); OPT_PTR(support_material_spacing); OPT_PTR(support_material_speed); + OPT_PTR(support_material_solid_first_layer); OPT_PTR(support_material_synchronize_layers); OPT_PTR(support_material_xy_spacing); OPT_PTR(support_material_threshold); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index c6bf07c40..f49339477 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -196,7 +196,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_ || opt_key == "support_material_threshold" || opt_key == "support_material_with_sheath" || opt_key == "dont_support_bridges" - || opt_key == "first_layer_extrusion_width") { + || opt_key == "first_layer_extrusion_width" + || opt_key == "support_material_solid_first_layer") { steps.emplace_back(posSupportMaterial); } else if ( opt_key == "interface_shells" diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp index 6c12c86ff..2dcf30481 100644 --- a/xs/src/libslic3r/SupportMaterial.cpp +++ b/xs/src/libslic3r/SupportMaterial.cpp @@ -1869,11 +1869,7 @@ static inline void fill_expolygons_generate_paths( fill_params.dont_adjust = true; for (ExPolygons::const_iterator it_expolygon = expolygons.begin(); it_expolygon != expolygons.end(); ++ it_expolygon) { Surface surface(stInternal, *it_expolygon); - extrusion_entities_append_paths( - dst, - filler->fill_surface(&surface, fill_params), - role, - flow.mm3_per_mm(), flow.width, flow.height); + filler->fill_surface_extrusion(&surface, fill_params, flow, role, dst); } } @@ -1889,13 +1885,9 @@ static inline void fill_expolygons_generate_paths( fill_params.density = density; fill_params.complete = true; fill_params.dont_adjust = true; - for (ExPolygons::iterator it_expolygon = expolygons.begin(); it_expolygon != expolygons.end(); ++ it_expolygon) { + for (ExPolygons::iterator it_expolygon = expolygons.begin(); it_expolygon != expolygons.end(); ++it_expolygon) { Surface surface(stInternal, std::move(*it_expolygon)); - extrusion_entities_append_paths( - dst, - filler->fill_surface(&surface, fill_params), - role, - flow.mm3_per_mm(), flow.width, flow.height); + filler->fill_surface_extrusion(&surface, fill_params, flow, role, dst); } } @@ -2546,7 +2538,8 @@ void PrintObjectSupportMaterial::generate_toolpaths( MyLayer &raft_layer = *raft_layers[support_layer_id]; std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(ipRectilinear)); - std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern)); + std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern)); + std::unique_ptr<Fill> filler_dense = std::unique_ptr<Fill>(Fill::new_from_type(ipRectiWithPerimeter)); filler_interface->set_bounding_box(bbox_object); filler_support->set_bounding_box(bbox_object); @@ -2577,7 +2570,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( if (! to_infill.empty()) { // We don't use $base_flow->spacing because we need a constant spacing // value that guarantees that all layers are correctly aligned. - Fill *filler = filler_support.get(); + Fill *filler = filler_support.get(); filler->angle = raft_angle_base; filler->spacing = m_support_material_flow.spacing(); filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_density)); @@ -2599,10 +2592,16 @@ void PrintObjectSupportMaterial::generate_toolpaths( float density = 0.f; if (support_layer_id == 0) { // Base flange. - filler->angle = raft_angle_1st_layer; + if (this->m_object_config->support_material_solid_first_layer.value) { + filler = filler_dense.get(); + density = 1.f; + filler->angle = 0; + } else { + filler->angle = raft_angle_1st_layer; + // 70% of density on the 1st layer. + density = 0.7f; + } filler->spacing = m_first_layer_flow.spacing(); - // 70% of density on the 1st layer. - density = 0.7f; } else if (support_layer_id >= m_slicing_params.base_raft_layers) { filler->angle = raft_angle_interface; // We don't use $base_flow->spacing because we need a constant spacing @@ -2649,7 +2648,8 @@ void PrintObjectSupportMaterial::generate_toolpaths( size_t idx_layer_intermediate = size_t(-1); size_t idx_layer_inteface = size_t(-1); std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear)); - std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern)); + std::unique_ptr<Fill> filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern)); + std::unique_ptr<Fill> filler_solid = std::unique_ptr<Fill>(Fill::new_from_type(ipRectiWithPerimeter)); filler_interface->set_bounding_box(bbox_object); filler_support->set_bounding_box(bbox_object); for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id) @@ -2722,20 +2722,31 @@ void PrintObjectSupportMaterial::generate_toolpaths( float(layer_ex.layer->height), m_support_material_interface_flow.nozzle_diameter, layer_ex.layer->bridging); - filler_interface->angle = interface_as_base ? + Fill *filler = filler_interface.get(); + float density = interface_density; + //if first alyer and solid first layer : draw concentric with 100% density + if (support_layer.id() == 0 && this->m_object_config->support_material_solid_first_layer.value) { + filler = filler_solid.get(); + density = 1.f; + interface_flow = m_first_layer_flow; + filler->angle = 0; + filler->spacing = interface_flow.spacing(); + } else { + filler->angle = interface_as_base ? // If zero interface layers are configured, use the same angle as for the base layers. angles[support_layer_id % angles.size()] : // Use interface angle for the interface layers. interface_angle; - filler_interface->spacing = m_support_material_interface_flow.spacing(); - filler_interface->link_max_length = coord_t(scale_(filler_interface->spacing * link_max_length_factor / interface_density)); + filler->spacing = m_support_material_interface_flow.spacing(); + filler->link_max_length = coord_t(scale_(filler_interface->spacing * link_max_length_factor / density)); + } fill_expolygons_generate_paths( // Destination layer_ex.extrusions, // Regions to fill union_ex(layer_ex.polygons_to_extrude(), true), // Filler and its parameters - filler_interface.get(), float(interface_density), + filler, float(density), // Extrusion parameters erSupportMaterialInterface, interface_flow); } @@ -2761,16 +2772,21 @@ void PrintObjectSupportMaterial::generate_toolpaths( offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON)) : offset2_ex(base_layer.polygons_to_extrude(), float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width())); if (base_layer.layer->bottom_z < EPSILON) { - // Base flange (the 1st layer). - filler = filler_interface.get(); - filler->angle = Geometry::deg2rad(float(m_object_config->support_material_angle.value + 90.)); - density = 0.5f; - flow = m_first_layer_flow; + if (this->m_object_config->support_material_solid_first_layer.value) { + // Base flange (the 1st layer). + filler = filler_solid.get(); + filler->angle = 0; + density = 1.f; + } else { + filler = filler_interface.get(); + filler->angle = Geometry::deg2rad(float(m_object_config->support_material_angle.value + 90.)); + density = 0.5f; + filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density)); + } // use the proper spacing for first layer as we don't need to align // its pattern to the other layers - //FIXME When paralellizing, each thread shall have its own copy of the fillers. + flow = m_first_layer_flow; filler->spacing = flow.spacing(); - filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / density)); } else if (with_sheath) { // Draw a perimeter all around the support infill. This makes the support stable, but difficult to remove. // TODO: use brim ordering algorithm diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 8b5cf3cda..62006982e 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -306,7 +306,8 @@ const std::vector<std::string>& Preset::print_options() "elefant_foot_compensation", "xy_size_compensation", "hole_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "only_one_perimeter_top", "single_extruder_multi_material_priming", "compatible_printers", "compatible_printers_condition", "inherits", - "infill_dense", "no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only", "exact_last_layer_height" + "infill_dense", "no_perimeter_unsupported", "min_perimeter_unsupported", "noperi_bridge_only", "support_material_solid_first_layer", + "exact_last_layer_height" }; return s_opts; } diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index fa28ff680..b0afd4351 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -869,8 +869,9 @@ void TabPrint::build() optgroup->append_single_option_line("support_material_threshold"); optgroup->append_single_option_line("support_material_enforce_layers"); - optgroup = page->new_optgroup(_(L("Raft"))); - optgroup->append_single_option_line("raft_layers"); + optgroup = page->new_optgroup(_(L("Raft"))); + optgroup->append_single_option_line("support_material_solid_first_layer"); + optgroup->append_single_option_line("raft_layers"); // # optgroup->append_single_option_line(get_option_("raft_contact_distance"); optgroup = page->new_optgroup(_(L("Options for support material and raft"))); |