Add filament_max_overlap, to control the line spacing via filament setting

It allows to control the spacing vs width (10%% fill vs a bit less)
The 'enforce 100% fill volume' is also adjusted to take that into account
Note that if you're using multiple extruders/filament everywhere (and spacing setting for width setting),
  the result may be a bit unexpected, as the gui can't display all the interactions,
  also some features (like support) may revert to default overlap value, if printed with multiple filaments.
supermerill/SuperSlicer#1590
This commit is contained in:
supermerill 2021-09-26 13:50:49 +02:00
parent b45963727f
commit 088b92917c
37 changed files with 380 additions and 227 deletions

View File

@ -21,6 +21,7 @@ group:Filament properties
setting:width$7:filament_type
setting:filament_soluble
setting:filament_shrink
setting:filament_max_overlap
group:Print speed override
setting:filament_max_speed
setting:filament_max_volumetric_speed

View File

@ -742,7 +742,9 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex
if (def == nullptr)
throw NoDefinitionException(opt_key);
const ConfigOptionDef* opt_def = def->get(opt_key);
if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
if (opt_def->ratio_over.empty())
return opt_fl_per->get_abs_value(extruder_id, 1);
if (opt_def->ratio_over != "depends")
return opt_fl_per->get_abs_value(extruder_id, this->get_computed_value(opt_def->ratio_over, extruder_id));
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
throw ConfigurationError(ss.str());
@ -753,7 +755,9 @@ double ConfigBase::get_computed_value(const t_config_option_key &opt_key, int ex
if (def == nullptr)
throw NoDefinitionException(opt_key);
const ConfigOptionDef* opt_def = def->get(opt_key);
if (!opt_def->ratio_over.empty() && opt_def->ratio_over != "depends")
if (opt_def->ratio_over.empty())
return opt_per->get_abs_value(extruder_id, 1);
if (opt_def->ratio_over != "depends")
return opt_per->get_abs_value(extruder_id, this->get_computed_value(opt_def->ratio_over, extruder_id));
std::stringstream ss; ss << "ConfigBase::get_abs_value(): " << opt_key << " has no valid ratio_over to compute of";
throw ConfigurationError(ss.str());

View File

@ -64,12 +64,12 @@ void ExtrusionPath::polygons_covered_by_width(Polygons &out, const float scaled_
polygons_append(out, offset(this->polyline, double(scale_(this->width/2)) + scaled_epsilon));
}
void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const
void ExtrusionPath::polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const
{
// Instantiating the Flow class to get the line spacing.
// Don't know the nozzle diameter, setting to zero. It shall not matter it shall be optimized out by the compiler.
// if the spacing is negative, use the width instead. can happen on ironing second pass.
Flow flow(this->width, this->height, 0.f, (this->width*4 < this->height)?true:is_bridge(this->role()));
Flow flow(this->width, this->height, 0.f, spacing_ratio, (this->width*4 < this->height)?true:is_bridge(this->role()));
polygons_append(out, offset(this->polyline, 0.5f * double(flow.scaled_spacing()) + scaled_epsilon));
}
@ -249,10 +249,10 @@ void ExtrusionLoop::polygons_covered_by_width(Polygons &out, const float scaled_
path.polygons_covered_by_width(out, scaled_epsilon);
}
void ExtrusionLoop::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const
void ExtrusionLoop::polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const
{
for (const ExtrusionPath &path : this->paths)
path.polygons_covered_by_spacing(out, scaled_epsilon);
path.polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon);
}
std::string ExtrusionEntity::role_to_string(ExtrusionRole role)

View File

@ -196,11 +196,11 @@ public:
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
virtual void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const = 0;
virtual void polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const = 0;
virtual Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
virtual Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
virtual Polygons polygons_covered_by_spacing(const float spacing_ratio, const float scaled_epsilon) const
{ Polygons out; this->polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon); return out; }
virtual Polyline as_polyline() const = 0;
virtual void collect_polylines(Polylines &dst) const = 0;
virtual Polylines as_polylines() const { Polylines dst; this->collect_polylines(dst); return dst; }
@ -262,11 +262,11 @@ public:
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override;
void polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const override;
virtual Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
virtual Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
virtual Polygons polygons_covered_by_spacing(const float spacing_ratio, const float scaled_epsilon) const
{ Polygons out; this->polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon); return out; }
Polyline as_polyline() const override { return this->polyline; }
void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); }
double total_volume() const override { return mm3_per_mm * unscale<double>(length()); }
@ -353,9 +353,9 @@ public:
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override {
void polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const override {
for (const THING &entity : this->paths)
entity.polygons_covered_by_spacing(out, scaled_epsilon);
entity.polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon);
}
Polyline as_polyline() const override {
@ -381,7 +381,7 @@ public:
return out;
}
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const override{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const override { Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
Polygons polygons_covered_by_spacing(const float spacing_ratio, const float scaled_epsilon) const override { Polygons out; this->polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon); return out; }
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (!pl.empty()) dst.emplace_back(std::move(pl)); }
double total_volume() const override { double volume = 0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
};
@ -463,11 +463,11 @@ public:
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override;
void polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const override;
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
Polygons polygons_covered_by_spacing(const float spacing_ratio, const float scaled_epsilon) const
{ Polygons out; this->polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon); return out; }
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)); }
double total_volume() const override { double volume = 0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }

View File

@ -121,10 +121,10 @@ void ExtrusionEntityCollection::polygons_covered_by_width(Polygons &out, const f
entity->polygons_covered_by_width(out, scaled_epsilon);
}
void ExtrusionEntityCollection::polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const
void ExtrusionEntityCollection::polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const
{
for (const ExtrusionEntity *entity : this->entities)
entity->polygons_covered_by_spacing(out, scaled_epsilon);
entity->polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon);
}
// Recursively count paths and loops contained in this collection.

View File

@ -103,11 +103,11 @@ public:
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion spacing.
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
// Useful to calculate area of an infill, which has been really filled in by a 100% rectilinear infill.
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override;
void polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const override;
Polygons polygons_covered_by_width(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
Polygons polygons_covered_by_spacing(const float spacing_ratio, const float scaled_epsilon) const
{ Polygons out; this->polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon); return out; }
/// Recursively count paths and loops contained in this collection
size_t items_count() const;

View File

@ -149,7 +149,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
}
//adjust spacing/density (to over-extrude when needed)
if (surface.has_mod_overBridge()) {
params.density = float(layerm.region()->config().over_bridge_flow_ratio.get_abs_value(1));
params.density = float(region_config.over_bridge_flow_ratio.get_abs_value(1));
}
//note: same as getRoleFromSurfaceType()
@ -442,7 +442,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
// so we can safely ignore the slight variation that might have
// been applied to $f->flow_spacing
} else {
surface_fill.params.flow = Flow::new_from_spacing((float)f->get_spacing(), surface_fill.params.flow.nozzle_diameter, (float)surface_fill.params.flow.height, surface_fill.params.flow.bridge);
float overlap = surface_fill.params.config->get_computed_value("filament_max_overlap", surface_fill.params.extruder - 1);
surface_fill.params.flow = Flow::new_from_spacing((float)f->get_spacing(), surface_fill.params.flow.nozzle_diameter, (float)surface_fill.params.flow.height, overlap, surface_fill.params.flow.bridge);
}
//apply bridge_overlap if needed
@ -452,8 +453,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
for (ExPolygon &expoly : surface_fill.expolygons) {
//set overlap polygons
if (layerm->region()->config().perimeters > 0) {
f->overlap = layerm->region()->config().get_abs_value("infill_overlap", (perimeter_spacing + (f->get_spacing())) / 2);
if (surface_fill.params.config->perimeters > 0) {
f->overlap = surface_fill.params.config->infill_overlap.get_abs_value((perimeter_spacing + (f->get_spacing())) / 2);
if (f->overlap != 0) {
f->no_overlap_expolygons = intersection_ex(layerm->fill_no_overlap_expolygons, ExPolygons() = { expoly });
} else {
@ -646,7 +647,7 @@ void Layer::make_ironing()
fill.angle = float(ironing_params.angle + 0.25 * M_PI);
fill.link_max_length = (coord_t)scale_(3. * fill.get_spacing());
double height = ironing_params.height * fill.get_spacing() / nozzle_dmr;
Flow flow = Flow::new_from_spacing(float(nozzle_dmr), 0., float(height), false);
Flow flow = Flow::new_from_spacing(float(nozzle_dmr), 0., float(height), 1.f, false);
double flow_mm3_per_mm = flow.mm3_per_mm();
Surface surface_fill((stPosTop | stDensSolid), ExPolygon());
for (ExPolygon &expoly : ironing_areas) {

View File

@ -189,18 +189,21 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
length_tot += unscaled(line->length());
}
}
double extruded_volume = params.flow.mm3_per_mm() * length_tot;
//compute flow to remove spacing_ratio from the equation
double extruded_volume = 0;
if (params.flow.spacing_ratio < 1.f && !params.flow.bridge) {
// the spacing is larger than usual. get the flow from the current spacing
Flow test_flow = Flow::new_from_spacing(params.flow.spacing(), params.flow.nozzle_diameter, params.flow.height, 1, params.flow.bridge);
extruded_volume = test_flow.mm3_per_mm() * length_tot;
}else
extruded_volume = params.flow.mm3_per_mm() * length_tot;
// compute real volume
double polyline_volume = compute_unscaled_volume_to_fill(surface, params);
//printf("process want %f mm3 extruded for a volume of %f space : we mult by %f %i\n",
// extrudedVolume,
// (poylineVolume),
// (poylineVolume) / extrudedVolume,
// this->no_overlap_expolygons.size());
if (extruded_volume != 0 && polyline_volume != 0) mult_flow = polyline_volume / extruded_volume;
if (extruded_volume != 0 && polyline_volume != 0) mult_flow *= polyline_volume / extruded_volume;
//failsafe, it can happen
if (mult_flow > 1.3) mult_flow = 1.3;
if (mult_flow < 0.8) mult_flow = 0.8;
BOOST_LOG_TRIVIAL(info) << "Infill process extrude " << extruded_volume << " mm3 for a volume of " << polyline_volume << " mm3 : we mult the flow by " << mult_flow;
}
// Save into layer.
@ -237,7 +240,7 @@ Fill::do_gap_fill(const ExPolygons& gapfill_areas, const FillParams& params, Ext
double max = 2. * params.flow.scaled_width();
// collapse
//be sure we don't gapfill where the perimeters are already touching each other (negative spacing).
min = std::max(min, double(Flow::new_from_spacing((float)EPSILON, (float)params.flow.nozzle_diameter, (float)params.flow.height, false).scaled_width()));
min = std::max(min, double(Flow::new_from_spacing((float)EPSILON, (float)params.flow.nozzle_diameter, (float)params.flow.height, 1, false).scaled_width()));
//ExPolygons gapfill_areas_collapsed = diff_ex(
// offset2_ex(gapfill_areas, double(-min / 2), double(+min / 2)),
// offset2_ex(gapfill_areas, double(-max / 2), double(+max / 2)),

View File

@ -72,7 +72,7 @@ struct FillParams
ExtrusionRole role { erNone };
//flow to use
Flow flow = Flow(0.f, 0.f, 0.f, false);
Flow flow = Flow(0.f, 0.f, 0.f, 1.f, false);
//full configuration for the region, to avoid copying every bit that is needed. Use this for process-specific parameters.
PrintRegionConfig const *config{ nullptr };

View File

@ -3402,27 +3402,30 @@ FillRectilinearWGapFill::fill_surface_extrusion(const Surface *surface, const Fi
//check if not over-extruding
if (!params.dont_adjust && params.full_infill() && !params.flow.bridge && params.fill_exactly) {
// compute the path of the nozzle -> extruded volume
double lengthTot = 0;
int nbLines = 0;
double length_tot = 0;
int nb_lines = 0;
for (const Polyline &pline : polylines_rectilinear) {
Lines lines = pline.lines();
for (auto line = lines.begin(); line != lines.end(); ++line) {
lengthTot += unscaled(line->length());
nbLines++;
length_tot += unscaled(line->length());
nb_lines++;
}
}
double extrudedVolume = params.flow.mm3_per_mm() * lengthTot;
//compute flow to remove spacing_ratio from the equation
double extruded_volume = 0;
if (params.flow.spacing_ratio < 1.f && !params.flow.bridge) {
// the spacing is larger than usual. get the flow from the current spacing
Flow test_flow = Flow::new_from_spacing(params.flow.spacing(), params.flow.nozzle_diameter, params.flow.height, 1, params.flow.bridge);
extruded_volume = test_flow.mm3_per_mm() * length_tot;
} else
extruded_volume = params.flow.mm3_per_mm() * length_tot;
// compute real volume
double poylineVolume = compute_unscaled_volume_to_fill(surface, params);
//printf("process want %f mm3 extruded for a volume of %f space : we mult by %f %i\n",
// extrudedVolume,
// (poylineVolume),
// (poylineVolume) / extrudedVolume,
// this->no_overlap_expolygons.size());
if (extrudedVolume != 0 && poylineVolume != 0) flow_mult_exact_volume = poylineVolume / extrudedVolume;
double polyline_volume = compute_unscaled_volume_to_fill(surface, params);
if (extruded_volume != 0 && polyline_volume != 0) flow_mult_exact_volume = polyline_volume / extruded_volume;
//failsafe, it can happen
if (flow_mult_exact_volume > 1.3) flow_mult_exact_volume = 1.3;
if (flow_mult_exact_volume < 0.8) flow_mult_exact_volume = 0.8;
BOOST_LOG_TRIVIAL(info) << "Infill (without gapfil) process extrude " << extruded_volume << " mm3 for a volume of " << polyline_volume << " mm3 : we mult the flow by " << flow_mult_exact_volume;
}
//Create extrusions
@ -3443,7 +3446,7 @@ FillRectilinearWGapFill::fill_surface_extrusion(const Surface *surface, const Fi
coll_nosort->entities.push_back(eec);
unextruded_areas = diff_ex(rectilinear_areas, union_ex(eec->polygons_covered_by_spacing(10), true));
unextruded_areas = diff_ex(rectilinear_areas, union_ex(eec->polygons_covered_by_spacing(params.flow.spacing_ratio , 10), true));
}
else
unextruded_areas = rectilinear_areas;

View File

@ -73,27 +73,38 @@ namespace Slic3r {
Polylines polylines_layer = f2->fill_surface(&srf_to_fill, params);
if (!polylines_layer.empty()) {
//compute the path of the nozzle
double lengthTot = 0;
int nbLines = 0;
for (Polyline &pline : polylines_layer) {
Lines lines = pline.lines();
for (Line &line : lines) {
lengthTot += unscaled(line.length());
nbLines++;
}
}
double extrudedVolume = params.flow.mm3_per_mm() * lengthTot / params.density;
if (extrudedVolume == 0) extrudedVolume = volume;
//get the role
ExtrusionRole good_role = params.role;
if (good_role == erNone || good_role == erCustom) {
good_role = params.flow.bridge && idx == 0 ? erBridgeInfill : rolePass[idx];
}
// print
float mult_flow = float(params.fill_exactly /*&& idx == 0*/ ? std::min(2., volume / extrudedVolume) : 1);
//get the flow
float mult_flow = 1;
if (params.fill_exactly) {
//compute the path of the nozzle
double length_tot = 0;
int nb_lines = 0;
for (Polyline& pline : polylines_layer) {
Lines lines = pline.lines();
for (Line& line : lines) {
length_tot += unscaled(line.length());
nb_lines++;
}
}
//compute flow to remove spacing_ratio from the equation
double extruded_volume = 0;
if (params.flow.spacing_ratio < 1.f && !params.flow.bridge) {
// the spacing is larger than usual. get the flow from the current spacing
Flow test_flow = Flow::new_from_spacing(params.flow.spacing(), params.flow.nozzle_diameter, params.flow.height, 1, params.flow.bridge);
extruded_volume = test_flow.mm3_per_mm() * length_tot / params.density;
} else
extruded_volume = params.flow.mm3_per_mm() * length_tot / params.density;
if (extruded_volume == 0) extruded_volume = volume;
// print
mult_flow = (float)std::min(2., volume / extruded_volume);
BOOST_LOG_TRIVIAL(info) << "Ironing process extrude " << extruded_volume << " mm3 for a volume of " << volume << " mm3 : we mult the flow by " << mult_flow;
}
extrusion_entities_append_paths(
eec.entities, std::move(polylines_layer),
good_role,

View File

@ -1,6 +1,7 @@
#include "Flow.hpp"
#include "I18N.hpp"
#include "Print.hpp"
#include "Layer.hpp"
#include <cmath>
#include <assert.h>
@ -180,7 +181,7 @@ double Flow::extrusion_width(const std::string& opt_key, const ConfigOptionResol
// This constructor builds a Flow object from an extrusion width config setting
// and other context properties.
Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio)
Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float spacing_ratio, float bridge_flow_ratio)
{
// we need layer height unless it's a bridge
if (height <= 0 && bridge_flow_ratio == 0)
@ -201,11 +202,11 @@ Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent
w = float(width.get_abs_value(nozzle_diameter));
}
return Flow(w, height, nozzle_diameter, bridge_flow_ratio > 0);
return Flow(w, height, nozzle_diameter, spacing_ratio, bridge_flow_ratio > 0);
}
// This constructor builds a Flow object from a given centerline spacing.
Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge)
Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height, float spacing_ratio, bool bridge)
{
// we need layer height unless it's a bridge
if (height <= 0 && !bridge)
@ -216,11 +217,11 @@ Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height,
float width = float(bridge ?
(spacing - BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter) :
#ifdef HAS_PERIMETER_LINE_OVERLAP
(spacing + PERIMETER_LINE_OVERLAP_FACTOR * height * (1. - 0.25 * PI));
(spacing + PERIMETER_LINE_OVERLAP_FACTOR * height * (1. - 0.25 * PI) * spacing_ratio);
#else
(spacing + height * (1. - 0.25 * PI)));
(spacing + height * (1. - 0.25 * PI) * spacing_ratio));
#endif
return Flow(width, bridge ? width : height, nozzle_diameter, bridge);
return Flow(width, bridge ? width : height, nozzle_diameter, spacing_ratio, bridge);
}
// This method returns the centerline spacing between two adjacent extrusions
@ -231,7 +232,7 @@ float Flow::spacing() const
if (this->bridge)
return this->width + BRIDGE_EXTRA_SPACING;
// rectangle with semicircles at the ends
float min_flow_spacing = this->width - this->height * (1. - 0.25 * PI);
float min_flow_spacing = this->width - this->height * (1. - 0.25 * PI) * spacing_ratio;
float res = this->width - PERIMETER_LINE_OVERLAP_FACTOR * (this->width - min_flow_spacing);
#else
float res = float(this->bridge ? (this->width + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter) : (this->width - this->height * (1. - 0.25 * PI) * spacing_ratio));
@ -274,13 +275,18 @@ double Flow::mm3_per_mm() const
Flow support_material_flow(const PrintObject *object, float layer_height)
{
int extruder_id = object->config().support_material_extruder.value - 1;
if (extruder_id < 0) {
extruder_id = object->layers().front()->get_region(0)->region()->config().perimeter_extruder - 1;
}
return Flow::new_from_config_width(
frSupportMaterial,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
(object->config().support_material_extrusion_width.value > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
// if object->config().support_material_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
float(object->print()->config().nozzle_diameter.get_at(extruder_id)),
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value),
extruder_id < 0 ? 1 : object->config().get_computed_value("filament_max_overlap", extruder_id), //if can get an extruder, then use its param, or use full overlap if we don't know the extruder id.
// bridge_flow_ratio
0.f);
}
@ -292,25 +298,35 @@ Flow support_material_1st_layer_flow(const PrintObject *object, float layer_heig
if (layer_height <= 0.f && !object->print()->config().nozzle_diameter.empty()){
slice_height = (float)object->get_first_layer_height();
}
int extruder_id = object->config().support_material_extruder.value -1;
if (extruder_id < 0) {
extruder_id = object->layers().front()->get_region(0)->region()->config().infill_extruder - 1;
}
return Flow::new_from_config_width(
frSupportMaterial,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
(width.value > 0) ? width : object->config().extrusion_width,
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder - 1)),
float(object->print()->config().nozzle_diameter.get_at(extruder_id)),
slice_height,
extruder_id < 0 ? 1 : object->config().get_computed_value("filament_max_overlap", extruder_id), //if can get an extruder, then use its param, or use full overlap if we don't know the extruder id.
// bridge_flow_ratio
0.f);
}
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
{
int extruder_id = object->config().support_material_interface_extruder.value - 1;
if (extruder_id < 0) {
extruder_id = object->layers().front()->get_region(0)->region()->config().infill_extruder - 1;
}
return Flow::new_from_config_width(
frSupportMaterialInterface,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
(object->config().support_material_extrusion_width > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
// if object->config().support_material_interface_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_interface_extruder-1)),
float(object->print()->config().nozzle_diameter.get_at(extruder_id)),
(layer_height > 0.f) ? layer_height : float(object->config().layer_height.value),
extruder_id < 0 ? 1 : object->config().get_computed_value("filament_max_overlap", extruder_id), //if can get an extruder, then use its param, or use full overlap if we don't know the extruder id.
// bridge_flow_ratio
0.f);
}

View File

@ -67,10 +67,10 @@ public:
// Is it a bridge?
bool bridge;
// % of spacing taken into account 1=>all/default, 0=> width=spacing
float spacing_ratio = 1;
float spacing_ratio;
Flow(float _w, float _h, float _nd, bool _bridge = false) :
width(_w), height(_h), nozzle_diameter(_nd), bridge(_bridge) {}
Flow(float _w, float _h, float _nd, float spacing_ratio, bool _bridge) :
width(_w), height(_h), nozzle_diameter(_nd), spacing_ratio(spacing_ratio), bridge(_bridge) {}
float spacing() const;
float spacing(const Flow &other) const;
@ -87,14 +87,14 @@ public:
bool operator==(const Flow &rhs) const { return this->width == rhs.width && this->height == rhs.height && this->nozzle_diameter == rhs.nozzle_diameter && this->bridge == rhs.bridge; }
static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio = 0);
static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float spacing_ratio, float bridge_flow_ratio);
// Create a flow from the spacing of extrusion lines.
// This method is used exclusively to calculate new flow of 100% infill, where the extrusion width was allowed to scale
// to fit a region with integer number of lines.
static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge);
static Flow new_from_spacing(float spacing, float nozzle_diameter, float height, float spacing_ratio, bool bridge);
static float overlap(float height) {
return (float)(height * (1. - 0.25 * PI));
float overlap(float height) {
return (float)(height * (1. - 0.25 * PI)) * spacing_ratio;
}
// Sane extrusion width defautl based on nozzle diameter.

View File

@ -933,7 +933,8 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of
m_wipe_tower_width,
m_wipe_tower_depth);
double unscaled_brim_width = m_config->wipe_tower_brim.get_abs_value(m_nozzle_diameter);
Slic3r::Flow brim_flow = Flow::new_from_config_width(FlowRole::frPerimeter, m_object_config->first_layer_extrusion_width, m_nozzle_diameter, m_layer_height);
Slic3r::Flow brim_flow = Flow::new_from_config_width(FlowRole::frPerimeter, m_object_config->first_layer_extrusion_width, m_nozzle_diameter, m_layer_height,
1,0); //don't care of spacing and bridge
WipeTowerWriter writer(m_layer_height, brim_flow.width, m_gcode_flavor, m_filpar);
writer.set_extrusion_flow(brim_flow.mm3_per_mm())

View File

@ -1518,7 +1518,7 @@ MedialAxis::grow_to_nozzle_diameter(ThickPolylines& pp, const ExPolygons& anchor
float(unscaled(this->nozzle_diameter)),
float(unscaled(this->nozzle_diameter)),
float(unscaled(this->height)),
false).scaled_width();
1, false).scaled_width();
//ensure the width is not lower than min_width.
for (ThickPolyline& polyline : pp) {
for (int i = 0; i < polyline.points.size(); ++i) {

View File

@ -38,8 +38,8 @@ namespace Slic3r {
void PerimeterGenerator::process()
{
//set spacing
this->perimeter_flow.spacing_ratio = this->config->perimeter_overlap.get_abs_value(1);
this->ext_perimeter_flow.spacing_ratio = this->config->external_perimeter_overlap.get_abs_value(1);
this->perimeter_flow.spacing_ratio = std::min(this->perimeter_flow.spacing_ratio, (float)this->config->perimeter_overlap.get_abs_value(1));
this->ext_perimeter_flow.spacing_ratio = std::min(this->ext_perimeter_flow.spacing_ratio, (float)this->config->external_perimeter_overlap.get_abs_value(1));
// other perimeters
this->_mm3_per_mm = this->perimeter_flow.mm3_per_mm();
@ -991,7 +991,7 @@ void PerimeterGenerator::process()
// collapse
double min = 0.2 * perimeter_width * (1 - INSET_OVERLAP_TOLERANCE);
//be sure we don't gapfill where the perimeters are already touching each other (negative spacing).
min = std::max(min, double(Flow::new_from_spacing(EPSILON, (float)nozzle_diameter, (float)this->layer->height, false).scaled_width()));
min = std::max(min, double(Flow::new_from_spacing(EPSILON, (float)nozzle_diameter, (float)this->layer->height, this->perimeter_flow.spacing_ratio, false).scaled_width()));
double max = 2.2 * perimeter_spacing;
//remove areas that are too big (shouldn't occur...)
ExPolygons too_big = offset2_ex(gaps, double(-max / 2), double(+max / 2));

View File

@ -656,6 +656,7 @@ const std::vector<std::string>& Preset::filament_options()
"extrusion_multiplier", "filament_density", "filament_cost", "filament_spool_weight", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time",
"filament_unloading_speed", "filament_toolchange_delay", "filament_unloading_speed_start", "filament_unload_time", "filament_cooling_moves",
"filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
"filament_max_overlap",
"filament_shrink",
"filament_use_skinnydip", // skinnydip params start
"filament_use_fast_skinnydip",

View File

@ -38,7 +38,7 @@ static std::vector<std::string> s_project_options {
const char *PresetBundle::PRUSA_BUNDLE = "PrusaResearch";
PresetBundle::PresetBundle() :
prints(Preset::TYPE_FFF_PRINT, Preset::print_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
fff_prints(Preset::TYPE_FFF_PRINT, Preset::print_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
filaments(Preset::TYPE_FFF_FILAMENT, Preset::filament_options(), static_cast<const PrintRegionConfig&>(FullPrintConfig::defaults())),
sla_materials(Preset::TYPE_SLA_MATERIAL, Preset::sla_material_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults())),
sla_prints(Preset::TYPE_SLA_PRINT, Preset::sla_print_options(), static_cast<const SLAPrintObjectConfig&>(SLAFullPrintConfig::defaults())),
@ -54,9 +54,9 @@ PresetBundle::PresetBundle() :
// "printer_vendor", "printer_model", "printer_variant", "default_print_profile", "default_filament_profile"
// Create the ID config keys, as they are not part of the Static print config classes.
this->prints.default_preset().config.optptr("print_settings_id", true);
this->prints.default_preset().compatible_printers_condition();
this->prints.default_preset().inherits();
this->fff_prints.default_preset().config.optptr("print_settings_id", true);
this->fff_prints.default_preset().compatible_printers_condition();
this->fff_prints.default_preset().inherits();
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values = { "" };
this->filaments.default_preset().compatible_printers_condition();
@ -96,7 +96,7 @@ PresetBundle::PresetBundle() :
}
// Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above.
this->prints .select_preset(0);
this->fff_prints .select_preset(0);
this->sla_prints .select_preset(0);
this->filaments .select_preset(0);
this->sla_materials.select_preset(0);
@ -113,14 +113,14 @@ void PresetBundle::reset(bool delete_files)
{
// Clear the existing presets, delete their respective files.
this->vendors.clear();
this->prints .reset(delete_files);
this->fff_prints .reset(delete_files);
this->sla_prints .reset(delete_files);
this->filaments .reset(delete_files);
this->sla_materials.reset(delete_files);
this->printers .reset(delete_files);
this->filament_presets.clear();
this->filament_presets.emplace_back(this->filaments.get_selected_preset_name());
this->obsolete_presets.prints.clear();
this->obsolete_presets.fff_prints.clear();
this->obsolete_presets.sla_prints.clear();
this->obsolete_presets.filaments.clear();
this->obsolete_presets.sla_materials.clear();
@ -179,7 +179,7 @@ PresetsConfigSubstitutions PresetBundle::load_presets(AppConfig &config, Forward
;
try {
this->prints.load_presets(dir_user_presets, "print", substitutions, substitution_rule);
this->fff_prints.load_presets(dir_user_presets, "print", substitutions, substitution_rule);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
@ -278,32 +278,32 @@ std::pair<PresetsConfigSubstitutions, std::string> PresetBundle::load_system_pre
std::vector<std::string> PresetBundle::merge_presets(PresetBundle &&other)
{
this->vendors.insert(other.vendors.begin(), other.vendors.end());
std::vector<std::string> duplicate_prints = this->prints .merge_presets(std::move(other.prints), this->vendors);
std::vector<std::string> duplicate_fff_prints = this->fff_prints .merge_presets(std::move(other.fff_prints), this->vendors);
std::vector<std::string> duplicate_sla_prints = this->sla_prints .merge_presets(std::move(other.sla_prints), this->vendors);
std::vector<std::string> duplicate_filaments = this->filaments .merge_presets(std::move(other.filaments), this->vendors);
std::vector<std::string> duplicate_sla_materials = this->sla_materials.merge_presets(std::move(other.sla_materials), this->vendors);
std::vector<std::string> duplicate_printers = this->printers .merge_presets(std::move(other.printers), this->vendors);
append(this->obsolete_presets.prints, std::move(other.obsolete_presets.prints));
append(this->obsolete_presets.fff_prints, std::move(other.obsolete_presets.fff_prints));
append(this->obsolete_presets.sla_prints, std::move(other.obsolete_presets.sla_prints));
append(this->obsolete_presets.filaments, std::move(other.obsolete_presets.filaments));
append(this->obsolete_presets.sla_materials, std::move(other.obsolete_presets.sla_materials));
append(this->obsolete_presets.printers, std::move(other.obsolete_presets.printers));
append(duplicate_prints, std::move(duplicate_sla_prints));
append(duplicate_prints, std::move(duplicate_filaments));
append(duplicate_prints, std::move(duplicate_sla_materials));
append(duplicate_prints, std::move(duplicate_printers));
return duplicate_prints;
append(duplicate_fff_prints, std::move(duplicate_sla_prints));
append(duplicate_fff_prints, std::move(duplicate_filaments));
append(duplicate_fff_prints, std::move(duplicate_sla_materials));
append(duplicate_fff_prints, std::move(duplicate_printers));
return duplicate_fff_prints;
}
void PresetBundle::update_system_maps()
{
this->prints .update_map_system_profile_renamed();
this->fff_prints .update_map_system_profile_renamed();
this->sla_prints .update_map_system_profile_renamed();
this->filaments .update_map_system_profile_renamed();
this->sla_materials.update_map_system_profile_renamed();
this->printers .update_map_system_profile_renamed();
this->prints .update_map_alias_to_profile_name();
this->fff_prints .update_map_alias_to_profile_name();
this->sla_prints .update_map_alias_to_profile_name();
this->filaments .update_map_alias_to_profile_name();
this->sla_materials.update_map_alias_to_profile_name();
@ -333,8 +333,8 @@ const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& p
if (preset_type == Preset::TYPE_PRINTER || preset_type == Preset::TYPE_INVALID)
return alias;
const PresetCollection& presets = preset_type == Preset::TYPE_FFF_PRINT ? prints :
preset_type == Preset::TYPE_SLA_PRINT ? sla_prints :
const PresetCollection& presets = preset_type == Preset::TYPE_FFF_PRINT ? fff_prints :
preset_type == Preset::TYPE_SLA_PRINT ? sla_prints :
preset_type == Preset::TYPE_FFF_FILAMENT ? filaments :
sla_materials;
@ -344,8 +344,8 @@ const std::string& PresetBundle::get_preset_name_by_alias( const Preset::Type& p
void PresetBundle::save_changes_for_preset(const std::string& new_name, Preset::Type type,
const std::vector<std::string>& unselected_options)
{
PresetCollection& presets = type == Preset::TYPE_FFF_PRINT ? prints :
type == Preset::TYPE_SLA_PRINT ? sla_prints :
PresetCollection& presets = type == Preset::TYPE_FFF_PRINT ? fff_prints :
type == Preset::TYPE_SLA_PRINT ? sla_prints :
type == Preset::TYPE_FFF_FILAMENT ? filaments :
type == Preset::TYPE_SLA_MATERIAL ? sla_materials : printers;
@ -446,7 +446,7 @@ void PresetBundle::load_selections(AppConfig &config, const std::string &preferr
true);
// Selects the profile, leaves it to -1 if the initial profile name is empty or if it was not found.
prints.select_preset_by_name_strict(initial_print_profile_name);
fff_prints.select_preset_by_name_strict(initial_print_profile_name);
filaments.select_preset_by_name_strict(initial_filament_profile_name);
sla_prints.select_preset_by_name_strict(initial_sla_print_profile_name);
sla_materials.select_preset_by_name_strict(initial_sla_material_profile_name);
@ -485,7 +485,7 @@ void PresetBundle::export_selections(AppConfig &config)
assert(this->printers.get_edited_preset().printer_technology() != ptFFF || filament_presets.size() >= 1);
//assert(this->printers.get_edited_preset().printer_technology() != ptFFF || filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front());
config.clear_section("presets");
config.set("presets", "print", prints.get_selected_preset_name());
config.set("presets", "print", fff_prints.get_selected_preset_name());
config.set("presets", "filament", filament_presets.front());
for (unsigned i = 1; i < filament_presets.size(); ++i) {
char name[64];
@ -521,7 +521,7 @@ DynamicPrintConfig PresetBundle::full_fff_config() const
{
DynamicPrintConfig out;
out.apply(FullPrintConfig::defaults());
out.apply(this->prints.get_edited_preset().config);
out.apply(this->fff_prints.get_edited_preset().config);
// Add the default filament preset to have the "filament_preset_id" defined.
out.apply(this->filaments.default_preset().config);
out.apply(this->printers.get_edited_preset().config);
@ -533,8 +533,8 @@ DynamicPrintConfig PresetBundle::full_fff_config() const
std::vector<std::string> compatible_printers_condition;
std::vector<std::string> compatible_prints_condition;
std::vector<std::string> inherits;
compatible_printers_condition.emplace_back(this->prints.get_edited_preset().compatible_printers_condition());
inherits .emplace_back(this->prints.get_edited_preset().inherits());
compatible_printers_condition.emplace_back(this->fff_prints.get_edited_preset().compatible_printers_condition());
inherits .emplace_back(this->fff_prints.get_edited_preset().inherits());
if (num_extruders <= 1) {
out.apply(this->filaments.get_edited_preset().config);
@ -597,7 +597,7 @@ DynamicPrintConfig PresetBundle::full_fff_config() const
opt->value = boost::algorithm::clamp<int>(opt->value, 0, int(num_extruders));
}
out.option<ConfigOptionString >("print_settings_id", true)->value = this->prints.get_selected_preset_name();
out.option<ConfigOptionString >("print_settings_id", true)->value = this->fff_prints.get_selected_preset_name();
out.option<ConfigOptionStrings>("filament_settings_id", true)->values = this->filament_presets;
out.option<ConfigOptionString >("printer_settings_id", true)->value = this->printers.get_selected_preset_name();
out.option<ConfigOptionString >("physical_printer_settings_id", true)->value = this->physical_printers.get_selected_printer_name();
@ -809,7 +809,7 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
switch (Preset::printer_technology(config)) {
case ptFFF:
{
load_preset(this->prints, 0, "print_settings_id");
load_preset(this->fff_prints, 0, "print_settings_id");
load_preset(this->printers, num_extruders + 1, "printer_settings_id");
// 3) Now load the filaments. If there are multiple filament presets, split them and load them.
@ -1052,7 +1052,7 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree, co
// preset_bundle is set when loading user config bundles, which must not overwrite the system profiles.
static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree, const PresetBundle *preset_bundle)
{
flatten_configbundle_hierarchy(tree, "print", preset_bundle ? preset_bundle->prints.system_preset_names() : std::vector<std::string>());
flatten_configbundle_hierarchy(tree, "print", preset_bundle ? preset_bundle->fff_prints.system_preset_names() : std::vector<std::string>());
flatten_configbundle_hierarchy(tree, "filament", preset_bundle ? preset_bundle->filaments.system_preset_names() : std::vector<std::string>());
flatten_configbundle_hierarchy(tree, "sla_print", preset_bundle ? preset_bundle->sla_prints.system_preset_names() : std::vector<std::string>());
flatten_configbundle_hierarchy(tree, "sla_material", preset_bundle ? preset_bundle->sla_materials.system_preset_names() : std::vector<std::string>());
@ -1104,7 +1104,7 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_configbundle(
// 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
// Parse the obsolete preset names, to be deleted when upgrading from the old configuration structure.
std::vector<std::string> loaded_prints;
std::vector<std::string> loaded_fff_prints;
std::vector<std::string> loaded_filaments;
std::vector<std::string> loaded_sla_prints;
std::vector<std::string> loaded_sla_materials;
@ -1126,8 +1126,8 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_configbundle(
PhysicalPrinterCollection *ph_printers = nullptr;
std::string ph_printer_name;
if (boost::starts_with(section.first, "print:")) {
presets = &this->prints;
loaded = &loaded_prints;
presets = &this->fff_prints;
loaded = &loaded_fff_prints;
preset_name = section.first.substr(6);
} else if (boost::starts_with(section.first, "filament:")) {
presets = &this->filaments;
@ -1177,7 +1177,7 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_configbundle(
for (auto &kvp : section.second) {
std::vector<std::string> *dst = nullptr;
if (kvp.first == "print")
dst = &this->obsolete_presets.prints;
dst = &this->obsolete_presets.fff_prints;
else if (kvp.first == "filament")
dst = &this->obsolete_presets.filaments;
else if (kvp.first == "sla_print")
@ -1384,7 +1384,7 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_configbundle(
// 3) Activate the presets and physical printer if any exists.
if (! flags.has(LoadConfigBundleAttribute::LoadSystem)) {
if (! active_print.empty())
prints.select_preset_by_name(active_print, true);
fff_prints.select_preset_by_name(active_print, true);
if (! active_sla_print.empty())
sla_prints.select_preset_by_name(active_sla_print, true);
if (! active_sla_material.empty())
@ -1554,9 +1554,9 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri
assert(printer_preset.config.has("default_print_profile"));
assert(printer_preset.config.has("default_filament_profile"));
const std::vector<std::string> &prefered_filament_profiles = printer_preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
this->prints.update_compatible(printer_preset_with_vendor_profile, nullptr, select_other_print_if_incompatible,
PreferedPrintProfileMatch(this->prints.get_edited_preset(), printer_preset.config.opt_string("default_print_profile")));
const PresetWithVendorProfile print_preset_with_vendor_profile = this->prints.get_edited_preset_with_vendor_profile();
this->fff_prints.update_compatible(printer_preset_with_vendor_profile, nullptr, select_other_print_if_incompatible,
PreferedPrintProfileMatch(this->fff_prints.get_edited_preset(), printer_preset.config.opt_string("default_print_profile")));
const PresetWithVendorProfile print_preset_with_vendor_profile = this->fff_prints.get_edited_preset_with_vendor_profile();
// Remember whether the filament profiles were compatible before updating the filament compatibility.
std::vector<char> filament_preset_was_compatible(this->filament_presets.size(), false);
for (size_t idx = 0; idx < this->filament_presets.size(); ++ idx) {
@ -1613,7 +1613,7 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst
// Export the print, filament and printer profiles.
for (const PresetCollection *presets : {
(const PresetCollection*)&this->prints, (const PresetCollection*)&this->filaments,
(const PresetCollection*)&this->fff_prints, (const PresetCollection*)&this->filaments,
(const PresetCollection*)&this->sla_prints, (const PresetCollection*)&this->sla_materials,
(const PresetCollection*)&this->printers }) {
for (const Preset &preset : (*presets)()) {
@ -1636,7 +1636,7 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst
// Export the names of the active presets.
c << std::endl << "[presets]" << std::endl;
c << "print = " << this->prints.get_selected_preset_name() << std::endl;
c << "print = " << this->fff_prints.get_selected_preset_name() << std::endl;
c << "sla_print = " << this->sla_prints.get_selected_preset_name() << std::endl;
c << "sla_material = " << this->sla_materials.get_selected_preset_name() << std::endl;
c << "printer = " << this->printers.get_selected_preset_name() << std::endl;
@ -1673,7 +1673,7 @@ void PresetBundle::set_filament_preset(size_t idx, const std::string &name)
void PresetBundle::set_default_suppressed(bool default_suppressed)
{
prints.set_default_suppressed(default_suppressed);
fff_prints.set_default_suppressed(default_suppressed);
filaments.set_default_suppressed(default_suppressed);
sla_prints.set_default_suppressed(default_suppressed);
sla_materials.set_default_suppressed(default_suppressed);

View File

@ -32,10 +32,12 @@ public:
// Export selections (current print, current filaments, current printer) into config.ini
void export_selections(AppConfig &config);
PresetCollection prints;
PresetCollection fff_prints;
PresetCollection sla_prints;
PresetCollection filaments;
PresetCollection sla_materials;
PresetCollection& prints(PrinterTechnology pt) { return pt == ptFFF ? this->fff_prints : this->sla_prints; }
const PresetCollection& prints(PrinterTechnology pt) const { return pt == ptFFF ? this->fff_prints : this->sla_prints; }
PresetCollection& materials(PrinterTechnology pt) { return pt == ptFFF ? this->filaments : this->sla_materials; }
const PresetCollection& materials(PrinterTechnology pt) const { return pt == ptFFF ? this->filaments : this->sla_materials; }
PrinterPresetCollection printers;
@ -54,7 +56,7 @@ public:
VendorMap vendors;
struct ObsoletePresets {
std::vector<std::string> prints;
std::vector<std::string> fff_prints;
std::vector<std::string> sla_prints;
std::vector<std::string> filaments;
std::vector<std::string> sla_materials;
@ -63,7 +65,7 @@ public:
ObsoletePresets obsolete_presets;
bool has_defauls_only() const
{ return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); }
{ return fff_prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); }
DynamicPrintConfig full_config() const;
// full_config() with the "printhost_apikey" and "printhost_cafile" removed.

View File

@ -291,7 +291,8 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
else if (
opt_key == "first_layer_extrusion_width"
|| opt_key == "min_layer_height"
|| opt_key == "max_layer_height") {
|| opt_key == "max_layer_height"
|| opt_key == "filament_max_overlap") {
osteps.emplace_back(posPerimeters);
osteps.emplace_back(posInfill);
osteps.emplace_back(posSupportMaterial);
@ -1598,7 +1599,12 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
double max_layer_height = config().max_layer_height.values[extruder_id];
double nozzle_diameter = config().nozzle_diameter.values[extruder_id];
if (max_layer_height < EPSILON) max_layer_height = nozzle_diameter * 0.75;
double skirt_width = Flow::new_from_config_width(frPerimeter, *Flow::extrusion_option("skirt_extrusion_width", m_default_region_config), (float)m_config.nozzle_diameter.get_at(extruder_id), print_first_layer_height).width;
double skirt_width = Flow::new_from_config_width(frPerimeter,
*Flow::extrusion_option("skirt_extrusion_width", m_default_region_config),
(float)m_config.nozzle_diameter.get_at(extruder_id),
print_first_layer_height,
1,0 //don't care, all i want if width from width
).width;
//check first layer
if (object->region_volumes[region_id].front().first.first < object_first_layer_height) {
if (object_first_layer_height + EPSILON < min_layer_height)
@ -1717,7 +1723,9 @@ Flow Print::brim_flow(size_t extruder_id, const PrintObjectConfig& brim_config)
frPerimeter,
*Flow::extrusion_option("brim_extrusion_width", tempConf),
(float)m_config.nozzle_diameter.get_at(extruder_id),
(float)get_first_layer_height()
(float)get_first_layer_height(),
(extruder_id < m_config.nozzle_diameter.values.size()) ? brim_config.get_computed_value("filament_max_overlap", extruder_id) : 1,
0
);
}
@ -1750,7 +1758,9 @@ Flow Print::skirt_flow(size_t extruder_id, bool first_layer/*=false*/) const
frPerimeter,
*Flow::extrusion_option("skirt_extrusion_width", m_default_region_config),
(float)max_nozzle_diam,
(float)get_first_layer_height()
(float)get_first_layer_height(),
1, // hard to say what extruder we have here(many) m_default_region_config.get_computed_value("filament_max_overlap", extruder -1),
0
);
}
@ -2290,7 +2300,7 @@ void Print::_make_brim(const Flow &flow, const PrintObjectPtrs &objects, ExPolyg
else
object_islands.emplace_back(brim_offset == 0 ? to_expolygon(expoly.contour) : offset_ex(to_expolygon(expoly.contour), brim_offset)[0]);
if (!object->support_layers().empty()) {
Polygons polys = object->support_layers().front()->support_fills.polygons_covered_by_spacing(float(SCALED_EPSILON));
Polygons polys = object->support_layers().front()->support_fills.polygons_covered_by_spacing(flow.spacing_ratio, float(SCALED_EPSILON));
for (Polygon poly : polys) {
object_islands.emplace_back(brim_offset == 0 ? ExPolygon{ poly } : offset_ex(poly, brim_offset)[0]);
}
@ -2405,7 +2415,7 @@ void Print::_make_brim_ears(const Flow &flow, const PrintObjectPtrs &objects, Ex
object_islands.emplace_back(brim_offset == 0 ? to_expolygon(expoly.contour) : offset_ex(to_expolygon(expoly.contour), brim_offset)[0]);
if (!object->support_layers().empty()) {
Polygons polys = object->support_layers().front()->support_fills.polygons_covered_by_spacing(float(SCALED_EPSILON));
Polygons polys = object->support_layers().front()->support_fills.polygons_covered_by_spacing(flow.spacing_ratio, float(SCALED_EPSILON));
for (Polygon poly : polys) {
//don't put ears over supports unless it's 100% fill
if (object->config().support_material_solid_first_layer) {
@ -2566,7 +2576,7 @@ void Print::_make_brim_interior(const Flow &flow, const PrintObjectPtrs &objects
object_islands.push_back(brim_offset == 0 ? expoly : offset_ex(expoly, brim_offset)[0]);
if (!object->support_layers().empty()) {
spacing = scaled(object->config().support_material_interface_spacing.value) + support_material_flow(object, float(get_first_layer_height())).scaled_width() * 1.5;
Polygons polys = offset2(object->support_layers().front()->support_fills.polygons_covered_by_spacing(float(SCALED_EPSILON)), spacing, -spacing);
Polygons polys = offset2(object->support_layers().front()->support_fills.polygons_covered_by_spacing(flow.spacing_ratio, float(SCALED_EPSILON)), spacing, -spacing);
for (Polygon poly : polys) {
object_islands.push_back(brim_offset == 0 ? ExPolygon{ poly } : offset_ex(poly, brim_offset)[0]);
}
@ -2718,7 +2728,8 @@ Polygons Print::first_layer_islands() const
for (ExPolygon &expoly : object->m_layers.front()->lslices)
object_islands.push_back(expoly.contour);
if (! object->support_layers().empty())
object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
//was polygons_covered_by_spacing, but is it really important?
object->support_layers().front()->support_fills.polygons_covered_by_width(object_islands, float(SCALED_EPSILON));
islands.reserve(islands.size() + object_islands.size() * object->instances().size());
for (const PrintInstance &instance : object->instances())
for (Polygon &poly : object_islands) {

View File

@ -1558,15 +1558,28 @@ void PrintConfigDef::init_fff_params()
def = this->add("filament_shrink", coPercents);
def->label = L("Shrinkage");
def->tooltip = L("Enter the shrinkage percentage that the filament will get after cooling (94% if you measure 94mm instead of 100mm)."
" The part will be scaled in xy to compensate."
" Only the filament used for the perimeter is taken into account."
"\nBe sure to allow enough space between objects, as this compensation is done after the checks.");
" The part will be scaled in xy to compensate."
" Only the filament used for the perimeter is taken into account."
"\nBe sure to allow enough space between objects, as this compensation is done after the checks.");
def->sidetext = L("%");
def->ratio_over = "";
def->min = 10;
def->mode = comExpert;
def->is_vector_extruder = true;
def->set_default_value(new ConfigOptionPercents{ 100 });
def = this->add("filament_max_overlap", coPercents);
def->label = L("Max line overlap");
def->tooltip = L("This settign will ensure that all overlap are no hgher than this value."
" This is useful for filament that are too viscous, as the line can't flow under the previous one.");
def->sidetext = L("%");
def->ratio_over = "";
def->min = 0;
def->max = 100;
def->mode = comExpert;
def->is_vector_extruder = true;
def->set_default_value(new ConfigOptionPercents{ 100 });
def = this->add("filament_density", coFloats);
def->label = L("Density");
def->category = OptionCategory::filament;
@ -5678,6 +5691,7 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = {
"filament_max_speed",
"filament_max_wipe_tower_speed",
"filament_melt_zone_pause",
"filament_max_overlap",
"filament_shrink",
"filament_skinnydip_distance",
"filament_toolchange_part_fan_speed",
@ -5962,13 +5976,17 @@ double PrintConfig::min_object_distance(const ConfigBase *config, double ref_hei
if (skirts > 0 && ref_height == 0)
skirts += config->option("skirt_brim")->getInt();
if (skirts > 0 && config->option("skirt_height")->getInt() >= 1 && !config->option("complete_objects_one_skirt")->getBool()) {
float overlap_ratio = 1;
if (config->option<ConfigOptionPercents>("filament_max_overlap")) overlap_ratio = config->get_computed_value("filament_max_overlap");
if (ref_height == 0) {
skirt_dist = config->option("skirt_distance")->getFloat();
Flow skirt_flow = Flow::new_from_config_width(
frPerimeter,
*Flow::extrusion_option("skirt_extrusion_width", *config),
(float)max_nozzle_diam,
(float)first_layer_height
(float)first_layer_height,
overlap_ratio,
0
);
skirt_dist += skirt_flow.width + (skirt_flow.spacing() * ((double)skirts - 1));
base_dist = std::max(base_dist, skirt_dist + 1);
@ -5982,7 +6000,9 @@ double PrintConfig::min_object_distance(const ConfigBase *config, double ref_hei
frPerimeter,
*Flow::extrusion_option("skirt_extrusion_width", *config),
(float)max_nozzle_diam,
(float)first_layer_height
(float)first_layer_height,
overlap_ratio,
0
);
skirt_dist += skirt_flow.width + (skirt_flow.spacing() * ((double)skirts - 1));
}
@ -6112,7 +6132,7 @@ std::string DynamicPrintConfig::validate()
}
template<typename TYPE>
const TYPE* find_option(const t_config_option_key &opt_key, DynamicPrintConfig* default_config, const std::vector<const DynamicPrintConfig*> &other_config) {
const TYPE* find_option(const t_config_option_key &opt_key, DynamicPrintConfig* default_config, const std::vector<DynamicPrintConfig*> &other_config) {
const TYPE* option = default_config->option<TYPE>(opt_key);
if (option)
return option;
@ -6124,8 +6144,8 @@ const TYPE* find_option(const t_config_option_key &opt_key, DynamicPrintConfig*
return nullptr;
}
bool DynamicPrintConfig::update_phony(const std::vector<const DynamicPrintConfig*> config_collection) {
bool something_changed = false;
std::set<const DynamicPrintConfig*> DynamicPrintConfig::update_phony(const std::vector<DynamicPrintConfig*> config_collection) {
std::set<const DynamicPrintConfig*> something_changed;
//update width/spacing links
const char* widths[] = { "", "external_perimeter_", "perimeter_", "infill_", "solid_infill_", "top_infill_", "support_material_", "first_layer_", "skirt_" };
for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++i) {
@ -6135,21 +6155,34 @@ bool DynamicPrintConfig::update_phony(const std::vector<const DynamicPrintConfig
key_spacing += "extrusion_spacing";
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>(key_width);
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>(key_spacing);
if (width_option && spacing_option)
if (width_option && spacing_option){
std::set<const DynamicPrintConfig*> returned_values;
if (!spacing_option->is_phony() && width_option->is_phony())
something_changed |= value_changed(key_spacing, config_collection);
else
something_changed |= value_changed(key_width, config_collection);
returned_values = value_changed(key_spacing, config_collection);
else
returned_values = value_changed(key_width, config_collection);
something_changed.insert(returned_values.begin(), returned_values.end());
}
}
return something_changed;
}
//note: width<-> spacing conversion is done via float, so max 6-7 digit of precision.
bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const std::vector<const DynamicPrintConfig*> config_collection) {
std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const std::vector<DynamicPrintConfig*> config_collection) {
if (opt_key == "layer_height") {
update_phony(config_collection);
if (!update_phony(config_collection).empty())
return { this };
return {};
}
if (opt_key == "filament_max_overlap") {
for (auto conf : config_collection) {
if (conf->option("extrusion_width"))
if (!conf->update_phony(config_collection).empty())
return { conf };
}
return {};
}
bool something_changed = false;
@ -6164,7 +6197,10 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
for (double dmr : nozzle_diameter_option->values)
max_nozzle_diameter = std::max(max_nozzle_diameter, dmr);
double spacing_value = spacing_option->get_abs_value(max_nozzle_diameter);
Flow flow = Flow::new_from_spacing(spacing_value, max_nozzle_diameter,layer_height_option->value, false);
float overlap_ratio = 1;
const ConfigOptionPercents* filament_max_overlap_option = find_option<ConfigOptionPercents>("filament_max_overlap", this, config_collection);
if (filament_max_overlap_option) overlap_ratio = filament_max_overlap_option->get_abs_value(0, 1.);
Flow flow = Flow::new_from_spacing(spacing_value, max_nozzle_diameter,layer_height_option->value, overlap_ratio, false);
//test for valid height. If too high, revert to round shape
if (flow.height > spacing_value / (1 - (1. - 0.25 * PI) * flow.spacing_ratio)) {
flow.width = spacing_value / (1 - (1. - 0.25 * PI) * flow.spacing_ratio);
@ -6196,7 +6232,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
if (width_option && perimeter_overlap_option) {
width_option->set_phony(true);
spacing_option->set_phony(false);
flow.spacing_ratio = perimeter_overlap_option->get_abs_value(1);
flow.spacing_ratio = std::min(flow.spacing_ratio, float(perimeter_overlap_option->get_abs_value(1)));
flow.width = spacing_option->get_abs_value(max_nozzle_diameter) + layer_height_option->value * (1. - 0.25 * PI) * flow.spacing_ratio;
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
width_option->percent = spacing_option->percent;
@ -6204,12 +6240,13 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
}
}
if (opt_key == "external_perimeter_extrusion_spacing") {
const ConfigOptionPercent* perimeter_overlap_option = find_option<ConfigOptionPercent>("perimeter_overlap", this, config_collection);
const ConfigOptionPercent* external_perimeter_overlap_option = find_option<ConfigOptionPercent>("external_perimeter_overlap", this, config_collection);
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width");
if (width_option && external_perimeter_overlap_option) {
width_option->set_phony(true);
spacing_option->set_phony(false);
flow.spacing_ratio = external_perimeter_overlap_option->get_abs_value(0.5);
flow.spacing_ratio = std::min(flow.spacing_ratio * 0.5f, float(external_perimeter_overlap_option->get_abs_value(0.25) + perimeter_overlap_option->get_abs_value(0.25)));
flow.width = spacing_option->get_abs_value(max_nozzle_diameter) + layer_height_option->value * (1. - 0.25 * PI) * flow.spacing_ratio;
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
width_option->percent = spacing_option->percent;
@ -6266,6 +6303,9 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
const ConfigOptionFloats* nozzle_diameter_option = find_option<ConfigOptionFloats>("nozzle_diameter", this, config_collection);
const ConfigOptionFloat* layer_height_option = find_option<ConfigOptionFloat>("layer_height", this, config_collection);
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>(opt_key);
float overlap_ratio = 1;
const ConfigOptionPercents* filament_max_overlap_option = find_option<ConfigOptionPercents>("filament_max_overlap", this, config_collection);
if (filament_max_overlap_option) overlap_ratio = filament_max_overlap_option->get_abs_value(0, 1.);
if (layer_height_option && width_option && nozzle_diameter_option) {
//compute spacing with current height and change the width
float max_nozzle_diameter = 0;
@ -6278,7 +6318,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
if (width_option) {
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
if (flow.width < flow.height) flow.height = flow.width;
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
@ -6290,7 +6330,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
if (width_option) {
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
if (flow.width < flow.height) flow.height = flow.width;
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
@ -6303,23 +6343,24 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
if (width_option && perimeter_overlap_option) {
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow flow = Flow::new_from_config_width(FlowRole::frExternalPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow flow = Flow::new_from_config_width(FlowRole::frExternalPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
if (flow.width < flow.height) flow.height = flow.width;
flow.spacing_ratio = perimeter_overlap_option->get_abs_value(1);
flow.spacing_ratio = std::min(flow.spacing_ratio, (float)perimeter_overlap_option->get_abs_value(1));
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
something_changed = true;
}
}
if (opt_key == "external_perimeter_extrusion_width") {
const ConfigOptionPercent* perimeter_overlap_option = find_option<ConfigOptionPercent>("perimeter_overlap", this, config_collection);
const ConfigOptionPercent* external_perimeter_overlap_option = find_option<ConfigOptionPercent>("external_perimeter_overlap", this, config_collection);
spacing_option = this->option<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_spacing");
if (width_option && external_perimeter_overlap_option) {
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow ext_perimeter_flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow ext_perimeter_flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
if (ext_perimeter_flow.width < ext_perimeter_flow.height) ext_perimeter_flow.height = ext_perimeter_flow.width;
ext_perimeter_flow.spacing_ratio = external_perimeter_overlap_option->get_abs_value(0.5);
ext_perimeter_flow.spacing_ratio = std::min(ext_perimeter_flow.spacing_ratio * 0.5f, float(external_perimeter_overlap_option->get_abs_value(0.25) + perimeter_overlap_option->get_abs_value(0.25)));
spacing_option->value = (width_option->percent) ? std::round(100 * ext_perimeter_flow.spacing() / max_nozzle_diameter) : (std::round(ext_perimeter_flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
something_changed = true;
@ -6330,7 +6371,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
if (width_option) {
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow flow = Flow::new_from_config_width(FlowRole::frInfill, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow flow = Flow::new_from_config_width(FlowRole::frInfill, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
if (flow.width < flow.height) flow.height = flow.width;
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
@ -6342,7 +6383,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
if (width_option) {
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow flow = Flow::new_from_config_width(FlowRole::frSolidInfill, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow flow = Flow::new_from_config_width(FlowRole::frSolidInfill, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
if (flow.width < flow.height) flow.height = flow.width;
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
@ -6354,7 +6395,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
if (width_option) {
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow flow = Flow::new_from_config_width(FlowRole::frTopSolidInfill, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow flow = Flow::new_from_config_width(FlowRole::frTopSolidInfill, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
if (flow.width < flow.height) flow.height = flow.width;
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
@ -6383,7 +6424,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
spacing_option->set_phony(false);
spacing_option->value = 100;
spacing_option->percent = true;
Flow flow = Flow::new_from_spacing(spacing_option->get_abs_value(max_nozzle_diameter), max_nozzle_diameter, layer_height_option->value, false);
Flow flow = Flow::new_from_spacing(spacing_option->get_abs_value(max_nozzle_diameter), max_nozzle_diameter, layer_height_option->value, overlap_ratio, false);
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
width_option->percent = spacing_option->percent;
something_changed = true;
@ -6392,7 +6433,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
width_option->percent = true;
width_option->set_phony(false);
spacing_option->set_phony(true);
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0);
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
spacing_option->percent = width_option->percent;
something_changed = true;
@ -6400,7 +6441,9 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
}
}
}
return something_changed;
if(something_changed)
return { this };
return {};
}
//FIXME localize this function.

View File

@ -468,8 +468,9 @@ public:
/// callback to changed other settings that are linked (like width & spacing)
/// </summary>
/// <param name="opt_key">name of the changed option</param>
bool value_changed(const t_config_option_key& opt_key, const std::vector<const DynamicPrintConfig*> config_collection);
bool update_phony(const std::vector<const DynamicPrintConfig*> config_collection);
/// <return> configs that have at least a change</param>
std::set<const DynamicPrintConfig*> value_changed(const t_config_option_key& opt_key, const std::vector<DynamicPrintConfig*> config_collection);
std::set<const DynamicPrintConfig*> update_phony(const std::vector<DynamicPrintConfig*> config_collection);
};
class StaticPrintConfig : public StaticConfig
@ -1304,6 +1305,7 @@ public:
ConfigOptionInts fan_below_layer_time;
ConfigOptionStrings filament_colour;
ConfigOptionStrings filament_notes;
ConfigOptionPercents filament_max_overlap;
ConfigOptionPercents filament_shrink;
ConfigOptionFloatOrPercent first_layer_acceleration;
ConfigOptionInts first_layer_bed_temperature;
@ -1405,6 +1407,7 @@ protected:
OPT_PTR(fan_below_layer_time);
OPT_PTR(filament_colour);
OPT_PTR(filament_notes);
OPT_PTR(filament_max_overlap);
OPT_PTR(filament_shrink);
OPT_PTR(first_layer_acceleration);
OPT_PTR(first_layer_bed_temperature);

View File

@ -861,6 +861,7 @@ namespace Slic3r {
|| opt_key == "external_perimeter_overlap"
|| opt_key == "gap_fill_overlap"
|| opt_key == "no_perimeter_unsupported_algo"
|| opt_key == "filament_max_overlap"
|| opt_key == "perimeters"
|| opt_key == "perimeter_overlap"
|| opt_key == "solid_infill_extrusion_spacing"

View File

@ -55,7 +55,9 @@ Flow PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool fir
// Get the configured nozzle_diameter for the extruder associated to the flow role requested.
// Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right.
double nozzle_diameter = m_print->config().nozzle_diameter.get_at(this->extruder(role, object) - 1);
return Flow::new_from_config_width(role, config_width, (float)nozzle_diameter, (float)layer_height, bridge ? (float)m_config.bridge_flow_ratio.get_abs_value(1) : 0.0f);
return Flow::new_from_config_width(role, config_width, (float)nozzle_diameter, (float)layer_height,
this->config().get_computed_value("filament_max_overlap", this->extruder(role, object) - 1),
bridge ? (float)m_config.bridge_flow_ratio.get_abs_value(1) : 0.0f);
}
float PrintRegion::width(FlowRole role, bool first_layer, const PrintObject& object) const

View File

@ -3051,7 +3051,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
//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);
Flow flow(float(m_support_material_flow.width), float(raft_layer.height), m_support_material_flow.nozzle_diameter, m_support_material_flow.spacing_ratio, raft_layer.bridging);
// find centerline of the external loop/extrusions
ExPolygons to_infill = (support_layer_id == 0 || ! with_sheath) ?
// union_ex(base_polygons, true) :
@ -3108,7 +3108,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// We don't use $base_flow->spacing because we need a constant spacing
// value that guarantees that all layers are correctly aligned.
spacing = m_support_material_flow.spacing();
flow = Flow(float(m_support_material_interface_flow.width), float(raft_layer.height), m_support_material_flow.nozzle_diameter, raft_layer.bridging);
flow = Flow(float(m_support_material_interface_flow.width), float(raft_layer.height), m_support_material_flow.nozzle_diameter, m_support_material_flow.spacing_ratio, raft_layer.bridging);
density = float(interface_density);
} else
continue;
@ -3225,6 +3225,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
float(layer_ex.layer->bridging ? layer_ex.layer->height : (interface_as_base ? m_support_material_flow.width : m_support_material_interface_flow.width)),
float(layer_ex.layer->height),
m_support_material_interface_flow.nozzle_diameter,
m_support_material_interface_flow.spacing_ratio,
layer_ex.layer->bridging);
Fill *filler = i == 2 ? filler_intermediate_interface.get() : filler_interface.get();
float density = interface_density;
@ -3267,6 +3268,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
float(base_layer.layer->bridging ? base_layer.layer->height : m_support_material_flow.width),
float(base_layer.layer->height),
m_support_material_flow.nozzle_diameter,
m_support_material_flow.spacing_ratio,
base_layer.layer->bridging);
coordf_t spacing = m_support_material_flow.spacing();
filler->link_max_length = coord_t(scale_(spacing * link_max_length_factor / support_density));

View File

@ -339,7 +339,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
fill_density = 100;
} else
fill_density = wxGetApp().preset_bundle->prints.get_selected_preset().config.option<ConfigOptionPercent>("fill_density")->value;
fill_density = wxGetApp().preset_bundle->fff_prints.get_selected_preset().config.option<ConfigOptionPercent>("fill_density")->value;
new_conf.set_key_value("fill_density", new ConfigOptionPercent(fill_density));
apply(config, &new_conf);
if (cb_value_change)

View File

@ -2778,7 +2778,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized)
const PrintConfig& config = print.config();
size_t extruders_count = config.nozzle_diameter.size();
if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) {
const DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
const DynamicPrintConfig& print_config = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config;
double layer_height = print_config.opt_float("layer_height");
double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height);
double nozzle_diameter = print.config().nozzle_diameter.values[0];

View File

@ -2245,7 +2245,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
const Print *print = m_process->fff_print();
const DynamicPrintConfig &print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
const DynamicPrintConfig &print_config = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config;
double layer_height = print_config.opt_float("layer_height");
double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height);
double nozzle_diameter = print->config().nozzle_diameter.values[0];

View File

@ -1495,9 +1495,7 @@ void ObjectList::get_settings_choice(const wxString& category_name)
for (auto sel : selections)
selected_options.push_back((*settings_list)[sel].first);
const DynamicPrintConfig& from_config = printer_technology() == ptFFF ?
wxGetApp().preset_bundle->prints.get_edited_preset().config :
wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
const DynamicPrintConfig& from_config = wxGetApp().preset_bundle->prints(printer_technology()).get_edited_preset().config;
for (auto& setting : (*settings_list))
{
@ -1562,7 +1560,7 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name)
_(L("Add Settings Bundle for Object"));
take_snapshot(snapshot_text);
const DynamicPrintConfig& from_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
const DynamicPrintConfig& from_config = wxGetApp().preset_bundle->prints(printer_technology()).get_edited_preset().config;
for (auto& opt_key : options)
{
if (find(opt_keys.begin(), opt_keys.end(), opt_key) == opt_keys.end()) {
@ -2830,7 +2828,7 @@ DynamicPrintConfig ObjectList::get_default_layer_config(const int obj_idx)
DynamicPrintConfig config;
coordf_t layer_height = object(obj_idx)->config.has("layer_height") ?
object(obj_idx)->config.opt_float("layer_height") :
wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_float("layer_height");
wxGetApp().preset_bundle->prints(printer_technology()).get_edited_preset().config.opt_float("layer_height");
config.set_key_value("layer_height",new ConfigOptionFloat(layer_height));
config.set_key_value("extruder", new ConfigOptionInt(0));

View File

@ -212,9 +212,7 @@ void ObjectSettings::update_config_values(ModelConfig* config)
return;
// update config values according to configuration hierarchy
DynamicPrintConfig main_config = printer_technology == ptFFF ?
wxGetApp().preset_bundle->prints.get_edited_preset().config :
wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
DynamicPrintConfig main_config = wxGetApp().preset_bundle->prints(printer_technology).get_edited_preset().config;
auto load_config = [this, config, &main_config]()
{

View File

@ -644,7 +644,7 @@ wxBoxSizer* Preview::create_layers_slider_sizer()
m_layers_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100);
m_layers_slider->SetDrawMode(wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA,
wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects"));
wxGetApp().preset_bundle->fff_prints.get_edited_preset().config.opt_bool("complete_objects"));
m_layers_slider->enable_action_icon(wxGetApp().is_editor());
sizer->Add(m_layers_slider, 0, wxEXPAND, 0);
@ -783,7 +783,7 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
m_layers_slider->SetTicksValues(ticks_info_from_model);
bool sla_print_technology = plater->printer_technology() == ptSLA;
bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects");
bool sequential_print = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config.opt_bool("complete_objects");
m_layers_slider->SetDrawMode(sla_print_technology, sequential_print);
m_layers_slider->SetExtruderColors(plater->get_extruder_colors_from_plater_config());
if (sla_print_technology)

View File

@ -236,7 +236,7 @@ void GLGizmosManager::update_data()
}
else if (is_wipe_tower)
{
DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
DynamicPrintConfig& config = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config;
set_scale(Vec3d::Ones());
set_rotation(Vec3d(0., 0., (M_PI/180.) * dynamic_cast<const ConfigOptionFloat*>(config.option("wipe_tower_rotation_angle"))->value));
set_flattening_data(nullptr);

View File

@ -292,7 +292,7 @@ void FreqChangedParams::msw_rescale()
FreqChangedParams::FreqChangedParams(wxWindow* parent) :
OG_Settings(parent, false)
{
DynamicPrintConfig* config = &wxGetApp().preset_bundle->prints.get_edited_preset().config;
DynamicPrintConfig* config = &wxGetApp().preset_bundle->fff_prints.get_edited_preset().config;
// Frequently changed parameters for FFF_technology
m_og->set_config(config);
@ -4660,7 +4660,7 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name)
//FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config.
// This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config.
if (this->printer_technology == ptFFF) {
const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
const DynamicPrintConfig &config = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config;
model.wipe_tower.position = Vec2d(config.opt_float("wipe_tower_x"), config.opt_float("wipe_tower_y"));
model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle");
}
@ -4716,7 +4716,7 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
//FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config.
// This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config.
if (this->printer_technology == ptFFF) {
const DynamicPrintConfig &config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
const DynamicPrintConfig &config = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config;
model.wipe_tower.position = Vec2d(config.opt_float("wipe_tower_x"), config.opt_float("wipe_tower_y"));
model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle");
}
@ -4772,7 +4772,7 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
//FIXME updating the Print config from the Wipe tower config values at the ModelWipeTower.
// This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config.
if (this->printer_technology == ptFFF) {
const DynamicPrintConfig &current_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
const DynamicPrintConfig &current_config = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config;
Vec2d current_position(current_config.opt_float("wipe_tower_x"), current_config.opt_float("wipe_tower_y"));
double current_rotation = current_config.opt_float("wipe_tower_rotation_angle");
if (current_position != model.wipe_tower.position || current_rotation != model.wipe_tower.rotation) {

View File

@ -79,7 +79,7 @@ PresetComboBox::PresetComboBox(wxWindow* parent, Preset::Type preset_type, const
switch (m_type)
{
case Preset::TYPE_FFF_PRINT: {
m_collection = &m_preset_bundle->prints;
m_collection = &m_preset_bundle->fff_prints;
m_main_bitmap_name = "cog";
break;
}

View File

@ -161,9 +161,9 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
// The current filament preset is not active for any extruder.
idx_extruder = -1;
const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config;
const DynamicPrintConfig &filament_config = preset_bundle.filaments.get_edited_preset().config;
const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
const DynamicPrintConfig &print_config = preset_bundle.fff_prints.get_edited_preset().config;
const DynamicPrintConfig &filament_config = preset_bundle.filaments .get_edited_preset().config;
const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
// Current printer values.
float nozzle_diameter = (float)printer_config.opt_float("nozzle_diameter", idx_extruder);
@ -249,13 +249,15 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
}
return (speed_normal > 0.) ? speed_normal : speed_max;
};
float filament_max_overlap = filament_config.get_computed_value("filament_max_overlap", std::max(0, idx_extruder));
if (perimeter_extruder_active) {
Flow external_flow = Flow::new_from_config_width(frExternalPerimeter,
first_positive(first_layer_extrusion_width_ptr, external_perimeter_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr);
nozzle_diameter, lh,
std::min(filament_max_overlap, (float)print_config.opt<ConfigOptionPercent>("external_perimeter_overlap")->get_abs_value(1)),
bfr);
if (external_flow.height > external_flow.width)
external_flow.height = external_flow.width;
external_flow.spacing_ratio = print_config.opt<ConfigOptionPercent>("external_perimeter_overlap")->get_abs_value(1);
double external_perimeter_rate = external_flow.mm3_per_mm() *
(bridging ? bridge_speed :
limit_by_first_layer_speed(std::max(external_perimeter_speed, small_perimeter_speed), max_print_speed));
@ -265,10 +267,11 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
}
Flow perimeter_flow = Flow::new_from_config_width(frPerimeter,
first_positive(first_layer_extrusion_width_ptr, perimeter_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr);
nozzle_diameter, lh,
std::min(filament_max_overlap, (float)print_config.opt<ConfigOptionPercent>("perimeter_overlap")->get_abs_value(1)),
bfr);
if (perimeter_flow.height > perimeter_flow.width)
perimeter_flow.height = perimeter_flow.width;
perimeter_flow.spacing_ratio = print_config.opt<ConfigOptionPercent>("perimeter_overlap")->get_abs_value(1);
double perimeter_rate = perimeter_flow.mm3_per_mm() *
(bridging ? bridge_speed :
limit_by_first_layer_speed(std::max(perimeter_speed, small_perimeter_speed), max_print_speed));
@ -280,7 +283,9 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
if (! bridging && infill_extruder_active) {
Flow infill_flow = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr);
nozzle_diameter, lh,
filament_max_overlap,
bfr);
if (infill_flow.height > infill_flow.width)
infill_flow.height = infill_flow.width;
double infill_rate = infill_flow.mm3_per_mm() * limit_infill_by_first_layer_speed(infill_speed, max_print_speed);
@ -292,7 +297,9 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
if (solid_infill_extruder_active) {
Flow solid_infill_flow = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, solid_infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, 0);
nozzle_diameter, lh,
filament_max_overlap,
0);
if (solid_infill_flow.height > solid_infill_flow.width)
solid_infill_flow.height = solid_infill_flow.width;
double solid_infill_rate = solid_infill_flow.mm3_per_mm() *
@ -304,7 +311,9 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
if (! bridging) {
Flow top_solid_infill_flow = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, top_infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr);
nozzle_diameter, lh,
filament_max_overlap,
bfr);
if (top_solid_infill_flow.height > top_solid_infill_flow.width)
top_solid_infill_flow.height = top_solid_infill_flow.width;
double top_solid_infill_rate = top_solid_infill_flow.mm3_per_mm() * limit_infill_by_first_layer_speed(top_solid_infill_speed, max_print_speed);
@ -317,7 +326,9 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
if (support_material_extruder_active) {
Flow support_material_flow = Flow::new_from_config_width(frSupportMaterial,
first_positive(first_layer_extrusion_width_ptr, support_material_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr);
nozzle_diameter, lh,
filament_max_overlap,
bfr);
if (support_material_flow.height > support_material_flow.width)
support_material_flow.height = support_material_flow.width;
double support_material_rate = support_material_flow.mm3_per_mm() *
@ -330,7 +341,9 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
if (support_material_interface_extruder_active) {
Flow support_material_interface_flow = Flow::new_from_config_width(frSupportMaterialInterface,
first_positive(first_layer_extrusion_width_ptr, support_material_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr);
nozzle_diameter, lh,
filament_max_overlap,
bfr);
if (support_material_interface_flow.height > support_material_interface_flow.width)
support_material_interface_flow.height = support_material_interface_flow.width;
double support_material_interface_rate = support_material_interface_flow.mm3_per_mm() *
@ -363,7 +376,7 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle& preset_bundle)
{
const DynamicPrintConfig& print_config = preset_bundle.prints.get_edited_preset().config;
const DynamicPrintConfig& print_config = preset_bundle.fff_prints.get_edited_preset().config;
const DynamicPrintConfig& printer_config = preset_bundle.printers.get_edited_preset().config;
float layer_height = float(print_config.opt_float("layer_height"));
@ -377,14 +390,22 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle& pre
return out;
}
const DynamicPrintConfig& filament_config = preset_bundle.filaments.get_edited_preset().config;
float filament_max_overlap = filament_config.get_computed_value("filament_max_overlap", 0);
Flow external_perimeter_flow = Flow::new_from_config_width(
frExternalPerimeter,
*print_config.opt<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width"),
nozzle_diameter, layer_height, false);
nozzle_diameter,
layer_height,
filament_max_overlap,
false);
Flow perimeter_flow = Flow::new_from_config_width(
frPerimeter,
*print_config.opt<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"),
nozzle_diameter, layer_height, false);
nozzle_diameter,
layer_height,
filament_max_overlap,
false);
// failsafe for too big height
if (external_perimeter_flow.height > external_perimeter_flow.width)
@ -421,7 +442,7 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle& pre
std::string PresetHints::recommended_extrusion_width(const PresetBundle& preset_bundle)
{
const DynamicPrintConfig& print_config = preset_bundle.prints.get_edited_preset().config;
const DynamicPrintConfig& print_config = preset_bundle.fff_prints.get_edited_preset().config;
const DynamicPrintConfig& printer_config = preset_bundle.printers.get_edited_preset().config;
int nb_nozzles = printer_config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
@ -434,8 +455,10 @@ std::string PresetHints::recommended_extrusion_width(const PresetBundle& preset_
std::string out;
Flow first_layer_flow = Flow::new_from_spacing(nozzle_diameter, nozzle_diameter, first_layer_height, false);
Flow layer_flow = Flow::new_from_spacing(nozzle_diameter, nozzle_diameter, layer_height, false);
const DynamicPrintConfig& filament_config = preset_bundle.filaments.get_edited_preset().config;
float filament_max_overlap = filament_config.get_computed_value("filament_max_overlap", 0);
Flow first_layer_flow = Flow::new_from_spacing(nozzle_diameter, nozzle_diameter, first_layer_height, filament_max_overlap, false);
Flow layer_flow = Flow::new_from_spacing(nozzle_diameter, nozzle_diameter, layer_height, filament_max_overlap, false);
out += _utf8(L("Ideally, the spacing between two extrusions shouldn't be lower than the nozzle diameter. Below are the extrusion widths for a spacing equal to the nozzle diameter.\n"));
out += (boost::format(_utf8(L("Recommended min extrusion width for the first layer (with a first layer height of %1%) is %2$.3f mm (or %3%%%)\n")))
@ -452,8 +475,8 @@ std::string PresetHints::recommended_extrusion_width(const PresetBundle& preset_
// on the active layer height.
std::string PresetHints::top_bottom_shell_thickness_explanation(const PresetBundle &preset_bundle)
{
const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config;
const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
const DynamicPrintConfig &print_config = preset_bundle.fff_prints.get_edited_preset().config;
const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config;
std::string out;

View File

@ -1187,20 +1187,47 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
//wxGetApp().preset_bundle->value_changed(opt_key);
// update phony fields
if (m_config->value_changed(opt_key, { wxGetApp().plater()->config() })) {
//auto thing = wxGetApp().plater()->
std::set<const DynamicPrintConfig*> changed = m_config->value_changed(opt_key, {
&wxGetApp().preset_bundle->prints(wxGetApp().plater()->printer_technology()).get_edited_preset().config,
&wxGetApp().preset_bundle->materials(wxGetApp().plater()->printer_technology()).get_edited_preset().config,
&wxGetApp().preset_bundle->printers.get_edited_preset().config,
/*&wxGetApp().preset_bundle->full_config()*/ });
if (changed.find(m_config) != changed.end()) {
update_dirty();
//# Initialize UI components with the config values.
reload_config();
}
if (changed.find(&wxGetApp().preset_bundle->fff_prints.get_edited_preset().config) != changed.end()) {
wxGetApp().get_tab(Preset::Type::TYPE_FFF_PRINT)->update_dirty();
wxGetApp().get_tab(Preset::Type::TYPE_FFF_PRINT)->reload_config();
}
if (changed.find(&wxGetApp().preset_bundle->sla_prints.get_edited_preset().config) != changed.end()) {
wxGetApp().get_tab(Preset::Type::TYPE_SLA_PRINT)->update_dirty();
wxGetApp().get_tab(Preset::Type::TYPE_SLA_PRINT)->reload_config();
}
if (changed.find(&wxGetApp().preset_bundle->filaments.get_edited_preset().config) != changed.end()) {
wxGetApp().get_tab(Preset::Type::TYPE_FFF_FILAMENT)->update_dirty();
wxGetApp().get_tab(Preset::Type::TYPE_FFF_FILAMENT)->reload_config();
}
if (changed.find(&wxGetApp().preset_bundle->sla_materials.get_edited_preset().config) != changed.end()) {
wxGetApp().get_tab(Preset::Type::TYPE_SLA_MATERIAL)->update_dirty();
wxGetApp().get_tab(Preset::Type::TYPE_SLA_MATERIAL)->reload_config();
}
if (changed.find(&wxGetApp().preset_bundle->printers.get_edited_preset().config) != changed.end()) {
wxGetApp().get_tab(Preset::Type::TYPE_PRINTER)->update_dirty();
wxGetApp().get_tab(Preset::Type::TYPE_PRINTER)->reload_config();
}
update();
}
// Show/hide the 'purging volumes' button
void Tab::update_wiping_button_visibility() {
if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA)
if (m_preset_bundle->printers.get_selected_preset().printer_technology() != ptFFF)
return; // ys_FIXME
bool wipe_tower_enabled = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value;
bool wipe_tower_enabled = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->fff_prints.get_edited_preset().config ).option("wipe_tower"))->value;
bool multiple_extruders = dynamic_cast<ConfigOptionFloats*>((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1;
auto wiping_dialog_button = wxGetApp().sidebar().get_wiping_dialog_button();
@ -2129,7 +2156,7 @@ bool Tab::create_pages(std::string setting_type_name, int idx_page)
void TabPrint::build()
{
m_presets = &m_preset_bundle->prints;
m_presets = &m_preset_bundle->fff_prints;
load_initial_data();
if (create_pages("print.ui")) return;
@ -3128,7 +3155,11 @@ void Tab::load_current_preset()
//update width/spacing links
if (m_type == Preset::TYPE_FFF_PRINT) {
//verify that spacings are set
if (m_config && m_config->update_phony({ wxGetApp().plater()->config() })) {
if (m_config && !m_config->update_phony({
&wxGetApp().preset_bundle->prints(wxGetApp().plater()->printer_technology()).get_edited_preset().config,
&wxGetApp().preset_bundle->materials(wxGetApp().plater()->printer_technology()).get_edited_preset().config,
&wxGetApp().preset_bundle->printers.get_edited_preset().config
}).empty()) {
update_dirty();
reload_config();
}
@ -3273,9 +3304,9 @@ void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/,
bool new_preset_compatible;
};
std::vector<PresetUpdate> updates = {
{ Preset::Type::TYPE_FFF_PRINT, &m_preset_bundle->prints, ptFFF },
{ Preset::Type::TYPE_FFF_PRINT, &m_preset_bundle->fff_prints, ptFFF },
{ Preset::Type::TYPE_SLA_PRINT, &m_preset_bundle->sla_prints, ptSLA },
{ Preset::Type::TYPE_FFF_FILAMENT, &m_preset_bundle->filaments, ptFFF },
{ Preset::Type::TYPE_FFF_FILAMENT, &m_preset_bundle->filaments, ptFFF },
{ Preset::Type::TYPE_SLA_MATERIAL, &m_preset_bundle->sla_materials,ptSLA }
};
for (PresetUpdate &pu : updates) {
@ -3382,8 +3413,7 @@ void Tab::select_preset(std::string preset_name, bool delete_current /*=false*/,
wxGetApp().mainframe->plater()->canvas3D()->set_arrange_settings(m_presets->get_edited_preset().config, m_presets->get_edited_preset().printer_technology());
}
if (m_type == Preset::TYPE_PRINTER) {
wxGetApp().mainframe->plater()->canvas3D()->set_arrange_settings(m_preset_bundle->prints.get_edited_preset().config, m_presets->get_edited_preset().printer_technology());
wxGetApp().mainframe->plater()->canvas3D()->set_arrange_settings(m_preset_bundle->prints(m_presets->get_edited_preset().printer_technology()).get_edited_preset().config, m_presets->get_edited_preset().printer_technology());
}
}
@ -3805,8 +3835,7 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep
{
// Collect names of non-default non-external profiles.
PrinterTechnology printer_technology = m_preset_bundle->printers.get_edited_preset().printer_technology();
PresetCollection &depending_presets = (deps.type == Preset::TYPE_PRINTER) ? m_preset_bundle->printers :
(printer_technology == ptFFF) ? m_preset_bundle->prints : m_preset_bundle->sla_prints;
PresetCollection &depending_presets = (deps.type == Preset::TYPE_PRINTER) ? m_preset_bundle->printers : m_preset_bundle->prints(printer_technology);
wxArrayString presets;
for (size_t idx = 0; idx < depending_presets.size(); ++ idx)
{

View File

@ -677,21 +677,21 @@ bool PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons
// Throw when parsing invalid configuration. Only valid configuration is supposed to be provided over the air.
bundle.load_configbundle(update.source.string(), PresetBundle::LoadConfigBundleAttribute::LoadSystem, ForwardCompatibilitySubstitutionRule::Disable);
BOOST_LOG_TRIVIAL(info) << format("Deleting %1% conflicting presets", bundle.prints.size() + bundle.filaments.size() + bundle.printers.size());
BOOST_LOG_TRIVIAL(info) << format("Deleting %1% conflicting presets", bundle.fff_prints.size() + bundle.filaments.size() + bundle.printers.size());
auto preset_remover = [](const Preset &preset) {
BOOST_LOG_TRIVIAL(info) << '\t' << preset.file;
fs::remove(preset.file);
};
for (const auto &preset : bundle.prints) { preset_remover(preset); }
for (const auto &preset : bundle.fff_prints){ preset_remover(preset); }
for (const auto &preset : bundle.filaments) { preset_remover(preset); }
for (const auto &preset : bundle.printers) { preset_remover(preset); }
// Also apply the `obsolete_presets` property, removing obsolete ini files
BOOST_LOG_TRIVIAL(info) << format("Deleting %1% obsolete presets",
bundle.obsolete_presets.prints.size() + bundle.obsolete_presets.filaments.size() + bundle.obsolete_presets.printers.size());
bundle.obsolete_presets.fff_prints.size() + bundle.obsolete_presets.filaments.size() + bundle.obsolete_presets.printers.size());
auto obsolete_remover = [](const char *subdir, const std::string &preset) {
auto path = fs::path(Slic3r::data_dir()) / subdir / preset;
@ -700,7 +700,7 @@ bool PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) cons
fs::remove(path);
};
for (const auto &name : bundle.obsolete_presets.prints) { obsolete_remover("print", name); }
for (const auto &name : bundle.obsolete_presets.fff_prints) { obsolete_remover("print", name); }
for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("filament", name); }
for (const auto &name : bundle.obsolete_presets.sla_prints) { obsolete_remover("sla_print", name); }
for (const auto &name : bundle.obsolete_presets.sla_materials/*filaments*/) { obsolete_remover("sla_material", name); }