Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@fr.fr>2018-09-26 17:57:30 +0300
committersupermerill <merill@fr.fr>2018-09-26 17:57:30 +0300
commit8e5cc9c906c3e9033656d53d6ec2f8c8914ff40f (patch)
tree13a6e4712e3919a21d2488a9071d337b7e6e6e94
parent8b9fb5b654646c6fad20f4617a81d0ffbf0dc4b7 (diff)
parenta383f89a7d7121073690beab9bab36f0ac578d29 (diff)
Merge branch 'master_slic3rPE_PR'
-rw-r--r--xs/src/libslic3r/Fill/Fill.cpp2
-rw-r--r--xs/src/libslic3r/Fill/FillBase.cpp22
-rw-r--r--xs/src/libslic3r/Fill/FillBase.hpp4
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear2.cpp54
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear2.hpp3
-rw-r--r--xs/src/libslic3r/Fill/FillSmooth.cpp27
-rw-r--r--xs/src/libslic3r/Fill/FillSmooth.hpp3
-rw-r--r--xs/src/libslic3r/GCode.cpp4
-rw-r--r--xs/src/libslic3r/LayerRegion.cpp27
-rw-r--r--xs/src/libslic3r/PrintConfig.cpp9
-rw-r--r--xs/src/libslic3r/PrintConfig.hpp2
-rw-r--r--xs/src/libslic3r/PrintObject.cpp3
-rw-r--r--xs/src/libslic3r/SupportMaterial.cpp72
-rw-r--r--xs/src/slic3r/GUI/Preset.cpp3
-rw-r--r--xs/src/slic3r/GUI/Tab.cpp5
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 &params, const Flow &flow, ExtrusionEntityCollection &out) {
+void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &params, 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 &para
/// 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 &params, 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 &params,
+ const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out);
// Perform the fill.
virtual Polylines fill_surface(const Surface *surface, const FillParams &params);
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 &para
}
-//Polylines FillRectilinear2Peri::fill_surface(const Surface *surface, const FillParams &params) {
-
-void FillRectilinear2Peri::fill_surface_extrusion(const Surface *surface, const FillParams &params, const Flow &flow, ExtrusionEntityCollection &out) {
+void
+FillRectilinear2Peri::fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ 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 &params);
- virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params, const Flow &flow, ExtrusionEntityCollection &out);
+ virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ 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 &params, const Flow &flow, ExtrusionEntityCollection &out)
+ void FillSmooth::fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ 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 &params);
- virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params, const Flow &flow, ExtrusionEntityCollection &out );
+ virtual void fill_surface_extrusion(const Surface *surface, const FillParams &params,
+ 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")));