Added a single perimeter to the first layer of support or raft.
Fixes [Request] Add optional perimeter to raft #756 Fixes First support layer does not stick to bed #2101 New parameters raft_first_layer_density and raft_first_layer_expansion to influence the 1st layer of raft or support. Fixes Allow to disable raft under support structures. #3772 Fixes raft is larger than necessary #2568 Fixes Supports on the build plate should have a solid bottom interface for better adhesion #1165 Changed the 1st layer infill to rectilinear even for soluble materials. Fixes first layer of support for multi filament support oddly spaced #1445 Fixes Full Soluble Materials interfacing into Models + Soluble material noise on Bed #684
This commit is contained in:
parent
77d007c484
commit
fcb714cd24
@ -102,6 +102,7 @@ public:
|
||||
virtual double min_mm3_per_mm() const = 0;
|
||||
virtual Polyline as_polyline() const = 0;
|
||||
virtual void collect_polylines(Polylines &dst) const = 0;
|
||||
virtual void collect_points(Points &dst) const = 0;
|
||||
virtual Polylines as_polylines() const { Polylines dst; this->collect_polylines(dst); return dst; }
|
||||
virtual double length() const = 0;
|
||||
virtual double total_volume() const = 0;
|
||||
@ -167,6 +168,7 @@ public:
|
||||
double min_mm3_per_mm() const override { return this->mm3_per_mm; }
|
||||
Polyline as_polyline() const override { return this->polyline; }
|
||||
void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); }
|
||||
void collect_points(Points &dst) const override { append(dst, this->polyline.points); }
|
||||
double total_volume() const override { return mm3_per_mm * unscale<double>(length()); }
|
||||
|
||||
private:
|
||||
@ -217,6 +219,12 @@ public:
|
||||
double min_mm3_per_mm() const override;
|
||||
Polyline as_polyline() const override;
|
||||
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
|
||||
void collect_points(Points &dst) const override {
|
||||
size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); });
|
||||
dst.reserve(dst.size() + n);
|
||||
for (const ExtrusionPath &p : this->paths)
|
||||
append(dst, p.polyline.points);
|
||||
}
|
||||
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
||||
};
|
||||
|
||||
@ -268,6 +276,12 @@ public:
|
||||
double min_mm3_per_mm() const override;
|
||||
Polyline as_polyline() const override { return this->polygon().split_at_first_point(); }
|
||||
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
|
||||
void collect_points(Points &dst) const override {
|
||||
size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); });
|
||||
dst.reserve(dst.size() + n);
|
||||
for (const ExtrusionPath &p : this->paths)
|
||||
append(dst, p.polyline.points);
|
||||
}
|
||||
double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
||||
|
||||
//static inline std::string role_to_string(ExtrusionLoopRole role);
|
||||
|
@ -117,6 +117,11 @@ public:
|
||||
extrusion_entity->collect_polylines(dst);
|
||||
}
|
||||
|
||||
void collect_points(Points &dst) const override {
|
||||
for (ExtrusionEntity* extrusion_entity : this->entities)
|
||||
extrusion_entity->collect_points(dst);
|
||||
}
|
||||
|
||||
double length() const override {
|
||||
throw Slic3r::RuntimeError("Calling length() on a ExtrusionEntityCollection");
|
||||
return 0.;
|
||||
|
@ -2573,10 +2573,11 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy
|
||||
|
||||
std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fills)
|
||||
{
|
||||
static constexpr const char *support_label = "support material";
|
||||
static constexpr const char *support_interface_label = "support material interface";
|
||||
|
||||
std::string gcode;
|
||||
if (! support_fills.entities.empty()) {
|
||||
const char *support_label = "support material";
|
||||
const char *support_interface_label = "support material interface";
|
||||
const double support_speed = m_config.support_material_speed.value;
|
||||
const double support_interface_speed = m_config.support_material_interface_speed.get_abs_value(support_speed);
|
||||
for (const ExtrusionEntity *ee : support_fills.entities) {
|
||||
@ -2589,9 +2590,14 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
|
||||
gcode += this->extrude_path(*path, label, speed);
|
||||
else {
|
||||
const ExtrusionMultiPath *multipath = dynamic_cast<const ExtrusionMultiPath*>(ee);
|
||||
assert(multipath != nullptr);
|
||||
if (multipath)
|
||||
gcode += this->extrude_multi_path(*multipath, label, speed);
|
||||
else {
|
||||
const ExtrusionEntityCollection *eec = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
||||
assert(eec);
|
||||
if (eec)
|
||||
gcode += this->extrude_support(*eec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -426,7 +426,8 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"bridge_speed", "gap_fill_speed", "gap_fill_enabled", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
|
||||
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height", "draft_shield",
|
||||
"min_skirt_length", "brim_width", "brim_offset", "brim_type", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion",
|
||||
"support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
|
||||
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
|
||||
"support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||
|
@ -1731,8 +1731,7 @@ void Print::_make_skirt()
|
||||
for (const SupportLayer *layer : object->support_layers()) {
|
||||
if (layer->print_z > skirt_height_z)
|
||||
break;
|
||||
for (const ExtrusionEntity *extrusion_entity : layer->support_fills.entities)
|
||||
append(object_points, extrusion_entity->as_polyline().points);
|
||||
layer->support_fills.collect_points(object_points);
|
||||
}
|
||||
// Repeat points for each object copy.
|
||||
for (const PrintInstance &instance : object->instances()) {
|
||||
|
@ -1775,6 +1775,25 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionString(""));
|
||||
def->cli = ConfigOptionDef::nocli;
|
||||
|
||||
def = this->add("raft_first_layer_density", coPercent);
|
||||
def->label = L("First layer density");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("Density of the first raft or support layer.");
|
||||
def->sidetext = L("%");
|
||||
def->min = 0;
|
||||
def->max = 150;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionPercent(90));
|
||||
|
||||
def = this->add("raft_first_layer_expansion", coFloat);
|
||||
def->label = L("First layer expansion");
|
||||
def->category = L("Support material");
|
||||
def->tooltip = L("Expansion of the first raft or support layer to improve adhesion to print bed.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(3.));
|
||||
|
||||
def = this->add("raft_layers", coInt);
|
||||
def->label = L("Raft layers");
|
||||
def->category = L("Support material");
|
||||
|
@ -473,6 +473,8 @@ public:
|
||||
// Force the generation of solid shells between adjacent materials/volumes.
|
||||
ConfigOptionBool interface_shells;
|
||||
ConfigOptionFloat layer_height;
|
||||
ConfigOptionPercent raft_first_layer_density;
|
||||
ConfigOptionFloat raft_first_layer_expansion;
|
||||
ConfigOptionInt raft_layers;
|
||||
ConfigOptionEnum<SeamPosition> seam_position;
|
||||
// ConfigOptionFloat seam_preferred_direction;
|
||||
@ -520,6 +522,8 @@ protected:
|
||||
OPT_PTR(infill_only_where_needed);
|
||||
OPT_PTR(interface_shells);
|
||||
OPT_PTR(layer_height);
|
||||
OPT_PTR(raft_first_layer_density);
|
||||
OPT_PTR(raft_first_layer_expansion);
|
||||
OPT_PTR(raft_layers);
|
||||
OPT_PTR(seam_position);
|
||||
OPT_PTR(slice_closing_radius);
|
||||
|
@ -576,6 +576,8 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
|| opt_key == "support_material_synchronize_layers"
|
||||
|| opt_key == "support_material_threshold"
|
||||
|| opt_key == "support_material_with_sheath"
|
||||
|| opt_key == "raft_first_layer_density"
|
||||
|| opt_key == "raft_first_layer_expansion"
|
||||
|| opt_key == "dont_support_bridges"
|
||||
|| opt_key == "first_layer_extrusion_width") {
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
|
@ -2536,7 +2536,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
|
||||
|
||||
// How much to inflate the support columns to be stable. This also applies to the 1st layer, if no raft layers are to be printed.
|
||||
const float inflate_factor_fine = float(scale_((m_slicing_params.raft_layers() > 1) ? 0.5 : EPSILON));
|
||||
const float inflate_factor_1st_layer = float(scale_(3.)) - inflate_factor_fine;
|
||||
const float inflate_factor_1st_layer = std::max(0.f, float(scale_(object.config().raft_first_layer_expansion)) - inflate_factor_fine);
|
||||
MyLayer *contacts = top_contacts .empty() ? nullptr : top_contacts .front();
|
||||
MyLayer *interfaces = interface_layers.empty() ? nullptr : interface_layers.front();
|
||||
MyLayer *columns_base = base_layers .empty() ? nullptr : base_layers .front();
|
||||
@ -2581,7 +2581,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
|
||||
new_layer.print_z = m_slicing_params.first_print_layer_height;
|
||||
new_layer.height = m_slicing_params.first_print_layer_height;
|
||||
new_layer.bottom_z = 0.;
|
||||
new_layer.polygons = offset(base, inflate_factor_1st_layer);
|
||||
new_layer.polygons = inflate_factor_1st_layer > 0 ? offset(base, inflate_factor_1st_layer) : base;
|
||||
}
|
||||
// Insert the base layers.
|
||||
for (size_t i = 1; i < m_slicing_params.base_raft_layers; ++ i) {
|
||||
@ -2608,7 +2608,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
|
||||
} else if (columns_base != nullptr) {
|
||||
// Expand the bases of the support columns in the 1st layer.
|
||||
columns_base->polygons = diff(
|
||||
offset(columns_base->polygons, inflate_factor_1st_layer),
|
||||
inflate_factor_1st_layer > 0 ? offset(columns_base->polygons, inflate_factor_1st_layer) : columns_base->polygons,
|
||||
offset(m_object->layers().front()->lslices, (float)scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS));
|
||||
if (contacts != nullptr)
|
||||
columns_base->polygons = diff(columns_base->polygons, interface_polygons);
|
||||
@ -2754,6 +2754,41 @@ std::pair<PrintObjectSupportMaterial::MyLayersPtr, PrintObjectSupportMaterial::M
|
||||
return base_and_interface_layers;
|
||||
}
|
||||
|
||||
static inline void fill_expolygon_generate_paths(
|
||||
ExtrusionEntitiesPtr &dst,
|
||||
ExPolygon &&expolygon,
|
||||
Fill *filler,
|
||||
const FillParams &fill_params,
|
||||
float density,
|
||||
ExtrusionRole role,
|
||||
const Flow &flow)
|
||||
{
|
||||
Surface surface(stInternal, std::move(expolygon));
|
||||
Polylines polylines;
|
||||
try {
|
||||
polylines = filler->fill_surface(&surface, fill_params);
|
||||
} catch (InfillFailedException &) {
|
||||
}
|
||||
extrusion_entities_append_paths(
|
||||
dst,
|
||||
std::move(polylines),
|
||||
role,
|
||||
flow.mm3_per_mm(), flow.width, flow.height);
|
||||
}
|
||||
|
||||
static inline void fill_expolygons_generate_paths(
|
||||
ExtrusionEntitiesPtr &dst,
|
||||
ExPolygons &&expolygons,
|
||||
Fill *filler,
|
||||
const FillParams &fill_params,
|
||||
float density,
|
||||
ExtrusionRole role,
|
||||
const Flow &flow)
|
||||
{
|
||||
for (ExPolygon &expoly : expolygons)
|
||||
fill_expolygon_generate_paths(dst, std::move(expoly), filler, fill_params, density, role, flow);
|
||||
}
|
||||
|
||||
static inline void fill_expolygons_generate_paths(
|
||||
ExtrusionEntitiesPtr &dst,
|
||||
ExPolygons &&expolygons,
|
||||
@ -2763,20 +2798,53 @@ static inline void fill_expolygons_generate_paths(
|
||||
const Flow &flow)
|
||||
{
|
||||
FillParams fill_params;
|
||||
fill_params.density = density;
|
||||
fill_params.density = density;
|
||||
fill_params.dont_adjust = true;
|
||||
for (ExPolygon &expoly : expolygons) {
|
||||
Surface surface(stInternal, std::move(expoly));
|
||||
fill_expolygons_generate_paths(dst, std::move(expolygons), filler, fill_params, density, role, flow);
|
||||
}
|
||||
|
||||
static inline void fill_expolygons_with_sheath_generate_paths(
|
||||
ExtrusionEntitiesPtr &dst,
|
||||
const Polygons &polygons,
|
||||
Fill *filler,
|
||||
float density,
|
||||
ExtrusionRole role,
|
||||
const Flow &flow,
|
||||
bool with_sheath)
|
||||
{
|
||||
if (polygons.empty())
|
||||
return;
|
||||
|
||||
if (! with_sheath) {
|
||||
fill_expolygons_generate_paths(dst, offset2_ex(polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON)), filler, density, role, flow);
|
||||
return;
|
||||
}
|
||||
|
||||
FillParams fill_params;
|
||||
fill_params.density = density;
|
||||
fill_params.dont_adjust = true;
|
||||
|
||||
double spacing = flow.scaled_spacing();
|
||||
// Clip the sheath path to avoid the extruder to get exactly on the first point of the loop.
|
||||
double clip_length = spacing * 0.15;
|
||||
|
||||
for (ExPolygon &expoly : offset2_ex(polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width()))) {
|
||||
// Don't reorder the skirt and its infills.
|
||||
auto eec = std::make_unique<ExtrusionEntityCollection>();
|
||||
eec->no_sort = true;
|
||||
// Draw the perimeters.
|
||||
Polylines polylines;
|
||||
try {
|
||||
polylines = filler->fill_surface(&surface, fill_params);
|
||||
} catch (InfillFailedException &) {
|
||||
}
|
||||
extrusion_entities_append_paths(
|
||||
dst,
|
||||
std::move(polylines),
|
||||
role,
|
||||
flow.mm3_per_mm(), flow.width, flow.height);
|
||||
polylines.reserve(expoly.holes.size() + 1);
|
||||
for (size_t i = 0; i <= expoly.holes.size(); ++ i) {
|
||||
Polyline pl(i == 0 ? expoly.contour.points : expoly.holes[i - 1].points);
|
||||
pl.points.emplace_back(pl.points.front());
|
||||
pl.clip_end(clip_length);
|
||||
polylines.emplace_back(std::move(pl));
|
||||
}
|
||||
extrusion_entities_append_paths(eec->entities, polylines, erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height);
|
||||
// Fill in the rest.
|
||||
fill_expolygons_generate_paths(eec->entities, offset_ex(expoly, float(-0.4 * spacing)), filler, fill_params, density, role, flow);
|
||||
dst.emplace_back(eec.release());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3430,45 +3498,26 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||
|
||||
// Print the support base below the support columns, or the support base for the support columns plus the contacts.
|
||||
if (support_layer_id > 0) {
|
||||
Polygons to_infill_polygons = (support_layer_id < m_slicing_params.base_raft_layers) ?
|
||||
const Polygons &to_infill_polygons = (support_layer_id < m_slicing_params.base_raft_layers) ?
|
||||
raft_layer.polygons :
|
||||
//FIXME misusing contact_polygons for support columns.
|
||||
((raft_layer.contact_polygons == nullptr) ? Polygons() : *raft_layer.contact_polygons);
|
||||
if (! to_infill_polygons.empty()) {
|
||||
Flow flow(float(m_support_material_flow.width), float(raft_layer.height), m_support_material_flow.nozzle_diameter, raft_layer.bridging);
|
||||
// find centerline of the external loop/extrusions
|
||||
ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ?
|
||||
// union_ex(base_polygons, true) :
|
||||
offset2_ex(to_infill_polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON)) :
|
||||
offset2_ex(to_infill_polygons, float(SCALED_EPSILON), float(- SCALED_EPSILON - 0.5*flow.scaled_width()));
|
||||
if (! to_infill.empty() && with_sheath) {
|
||||
// Draw a perimeter all around the support infill. This makes the support stable, but difficult to remove.
|
||||
// TODO: use brim ordering algorithm
|
||||
to_infill_polygons = to_polygons(to_infill);
|
||||
// TODO: use offset2_ex()
|
||||
to_infill = offset_ex(to_infill, float(- 0.4 * flow.scaled_spacing()));
|
||||
extrusion_entities_append_paths(
|
||||
support_layer.support_fills.entities,
|
||||
to_polylines(std::move(to_infill_polygons)),
|
||||
erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height);
|
||||
}
|
||||
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();
|
||||
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));
|
||||
fill_expolygons_generate_paths(
|
||||
// Destination
|
||||
support_layer.support_fills.entities,
|
||||
// Regions to fill
|
||||
std::move(to_infill),
|
||||
// Filler and its parameters
|
||||
filler, float(support_density),
|
||||
// Extrusion parameters
|
||||
erSupportMaterial, flow);
|
||||
}
|
||||
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));
|
||||
fill_expolygons_with_sheath_generate_paths(
|
||||
// Destination
|
||||
support_layer.support_fills.entities,
|
||||
// Regions to fill
|
||||
to_infill_polygons,
|
||||
// Filler and its parameters
|
||||
filler, float(support_density),
|
||||
// Extrusion parameters
|
||||
erSupportMaterial, flow,
|
||||
with_sheath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3526,12 +3575,21 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||
size_t idx_layer_bottom_contact = size_t(-1);
|
||||
size_t idx_layer_top_contact = size_t(-1);
|
||||
size_t idx_layer_intermediate = size_t(-1);
|
||||
size_t idx_layer_interface = size_t(-1);
|
||||
size_t idx_layer_base_interface = size_t(-1);
|
||||
auto filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear));
|
||||
size_t idx_layer_interface = size_t(-1);
|
||||
size_t idx_layer_base_interface = size_t(-1);
|
||||
const auto fill_type_interface = m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear;
|
||||
const auto fill_type_first_layer = ipRectilinear;
|
||||
auto filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(fill_type_interface));
|
||||
// Filler for the 1st layer interface, if different from filler_interface.
|
||||
auto filler_first_layer_ptr = std::unique_ptr<Fill>(range.begin() == 0 && fill_type_interface != fill_type_first_layer ? Fill::new_from_type(fill_type_first_layer) : nullptr);
|
||||
// Pointer to the 1st layer interface filler.
|
||||
auto filler_first_layer = filler_first_layer_ptr ? filler_first_layer_ptr.get() : filler_interface.get();
|
||||
// Filler for the base interface (to be used for soluble interface / non soluble base, to produce non soluble interface layer below soluble interface layer).
|
||||
auto filler_base_interface = std::unique_ptr<Fill>(base_interface_layers.empty() ? nullptr : Fill::new_from_type(ipRectilinear));
|
||||
auto filler_support = std::unique_ptr<Fill>(Fill::new_from_type(infill_pattern));
|
||||
filler_interface->set_bounding_box(bbox_object);
|
||||
if (filler_first_layer_ptr)
|
||||
filler_first_layer_ptr->set_bounding_box(bbox_object);
|
||||
if (filler_base_interface)
|
||||
filler_base_interface->set_bounding_box(bbox_object);
|
||||
filler_support->set_bounding_box(bbox_object);
|
||||
@ -3656,7 +3714,6 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||
|
||||
// Base support or flange.
|
||||
if (! base_layer.empty() && ! base_layer.polygons_to_extrude().empty()) {
|
||||
//FIXME When paralellizing, each thread shall have its own copy of the fillers.
|
||||
Fill *filler = filler_support.get();
|
||||
filler->angle = angles[support_layer_id % angles.size()];
|
||||
// We don't use $base_flow->spacing because we need a constant spacing
|
||||
@ -3669,42 +3726,31 @@ void PrintObjectSupportMaterial::generate_toolpaths(
|
||||
filler->spacing = m_support_material_flow.spacing();
|
||||
filler->link_max_length = coord_t(scale_(filler->spacing * link_max_length_factor / support_density));
|
||||
float density = float(support_density);
|
||||
// find centerline of the external loop/extrusions
|
||||
ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ?
|
||||
// union_ex(base_polygons, true) :
|
||||
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()));
|
||||
bool sheath = with_sheath;
|
||||
if (base_layer.layer->bottom_z < EPSILON) {
|
||||
// Base flange (the 1st layer).
|
||||
filler = filler_interface.get();
|
||||
filler = filler_first_layer;
|
||||
filler->angle = Geometry::deg2rad(float(m_object_config->support_material_angle.value + 90.));
|
||||
density = 0.5f;
|
||||
density = float(m_object_config->raft_first_layer_density.value * 0.01);
|
||||
flow = m_first_layer_flow;
|
||||
// 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.
|
||||
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
|
||||
Polygons to_infill_polygons = to_polygons(to_infill);
|
||||
// TODO: use offset2_ex()
|
||||
to_infill = offset_ex(to_infill, - 0.4f * float(flow.scaled_spacing()));
|
||||
extrusion_entities_append_paths(
|
||||
base_layer.extrusions,
|
||||
to_polylines(std::move(to_infill_polygons)),
|
||||
erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height);
|
||||
sheath = true;
|
||||
}
|
||||
fill_expolygons_generate_paths(
|
||||
fill_expolygons_with_sheath_generate_paths(
|
||||
// Destination
|
||||
base_layer.extrusions,
|
||||
base_layer.extrusions,
|
||||
// Regions to fill
|
||||
std::move(to_infill),
|
||||
base_layer.polygons_to_extrude(),
|
||||
// Filler and its parameters
|
||||
filler, density,
|
||||
// Extrusion parameters
|
||||
erSupportMaterial, flow);
|
||||
erSupportMaterial, flow,
|
||||
sheath);
|
||||
|
||||
}
|
||||
|
||||
// Merge base_interface_layers to base_layers to avoid unneccessary retractions
|
||||
|
@ -1499,6 +1499,8 @@ void TabPrint::build()
|
||||
|
||||
optgroup = page->new_optgroup(L("Raft"));
|
||||
optgroup->append_single_option_line("raft_layers", category_path + "raft-layers");
|
||||
optgroup->append_single_option_line("raft_first_layer_density", category_path + "raft-first-layer-density");
|
||||
optgroup->append_single_option_line("raft_first_layer_expansion", category_path + "raft-first-layer-expansion");
|
||||
// # optgroup->append_single_option_line(get_option_("raft_contact_distance");
|
||||
|
||||
optgroup = page->new_optgroup(L("Options for support material and raft"));
|
||||
|
Loading…
Reference in New Issue
Block a user