reworked autospeed & ironing role:

- now only extrusions with a "0" are taken into account for autospeed computation
 - removed min_mm3_per_mm from extrusionentity as it's now computed by a visitor.
 - ironing pattern now use ironing role like ironing PP
 - ironing_speed is now a float or percent, over top_solid_infill_speed
 - added some missing ratio_over
 - updated to_prusa to convert %  accel & speed to flat value from config, instead of 0.
This commit is contained in:
supermerill 2021-06-18 19:29:27 +02:00 committed by remi durand
parent 4028cd2a1b
commit 8e4e8023c0
11 changed files with 167 additions and 112 deletions

View File

@ -17,7 +17,7 @@ import subprocess
repo = "slic3r/slic3r"
program_name = "Slic3r"
path_7zip = r"C:\Program Files\7-Zip\7z.exe"
github_auth_token = "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"
github_auth_token = "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"
def get_version():
settings_stream = open("./version.inc", mode="r", encoding="utf-8");

View File

@ -228,6 +228,9 @@ group:label_width$8:sidetext_width$7:Speed for print moves
setting:width$4:solid_infill_speed
setting:width$4:top_solid_infill_speed
end_line
line:Ironing speed
setting:label$_:width$4:ironing_speed
end_line
line:Support speed
setting:width$4:support_material_speed
setting:width$4:support_material_interface_speed
@ -241,7 +244,6 @@ group:label_width$8:sidetext_width$7:Speed for print moves
setting:width$4:gap_fill_speed
setting:width$4:thin_walls_speed
end_line
setting:label$Ironing post-process speed:label_width$30:width$4:ironing_speed
group:Speed for non-print moves
line:Travel speed
setting:label$xy:travel_speed

View File

@ -255,15 +255,6 @@ void ExtrusionLoop::polygons_covered_by_spacing(Polygons &out, const float scale
path.polygons_covered_by_spacing(out, scaled_epsilon);
}
double ExtrusionLoop::min_mm3_per_mm() const
{
double min_mm3_per_mm = std::numeric_limits<double>::max();
for (const ExtrusionPath &path : this->paths)
if (path.role() != erGapFill && path.role() != erThinWall && path.role() != erMilling)
min_mm3_per_mm = std::min(min_mm3_per_mm, path.mm3_per_mm);
return min_mm3_per_mm;
}
std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
{
switch (role) {

View File

@ -201,8 +201,6 @@ public:
{ 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; }
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
virtual double min_mm3_per_mm() const = 0;
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; }
@ -269,8 +267,6 @@ public:
{ 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; }
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const override { return this->mm3_per_mm; }
Polyline as_polyline() const override { return this->polyline; }
void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); }
double total_volume() const override { return mm3_per_mm * unscale<double>(length()); }
@ -362,15 +358,6 @@ public:
entity.polygons_covered_by_spacing(out, scaled_epsilon);
}
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const override {
double min_mm3_per_mm = std::numeric_limits<double>::max();
for (const THING &entity : this->paths)
if (entity.role() != erGapFill && entity.role() != erThinWall && entity.role() != erMilling)
min_mm3_per_mm = std::min(min_mm3_per_mm, entity.min_mm3_per_mm());
return min_mm3_per_mm;
}
Polyline as_polyline() const override {
Polyline out;
if (!paths.empty()) {
@ -481,8 +468,6 @@ public:
{ 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; }
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const override;
Polyline as_polyline() const override { return this->polygon().split_at_first_point(); }
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
double total_volume() const override { double volume = 0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }

View File

@ -170,15 +170,4 @@ FlatenEntities::flatten(const ExtrusionEntityCollection &to_flatten) && {
return std::move(to_fill);
}
double
ExtrusionEntityCollection::min_mm3_per_mm() const
{
double min_mm3_per_mm = std::numeric_limits<double>::max();
for (const ExtrusionEntity *entity : this->entities)
if(entity->role() != erGapFill && entity->role() != erThinWall && entity->role() != erMilling)
min_mm3_per_mm = std::min(min_mm3_per_mm, entity->min_mm3_per_mm());
return min_mm3_per_mm;
}
}

View File

@ -115,7 +115,6 @@ public:
/// You should be iterating over flatten().entities if you are interested in the underlying ExtrusionEntities (and don't care about hierarchy).
/// \param preserve_ordering Flag to method that will flatten if and only if the underlying collection is sortable when True (default: False).
ExtrusionEntityCollection flatten(bool preserve_ordering = false) const;
double min_mm3_per_mm() const override;
double total_volume() const override { double volume=0.; for (const auto& ent : entities) volume+=ent->total_volume(); return volume; }
// Following methods shall never be called on an ExtrusionEntityCollection.

View File

@ -36,6 +36,9 @@ namespace Slic3r {
if (params.config != NULL && idx > 0) params_modifided.flow_mult *= (float)params.config->fill_smooth_distribution.get_abs_value(1);
else if (params.config != NULL && idx == 0) params_modifided.flow_mult *= (1.f - (float)params.config->fill_smooth_distribution.get_abs_value(1));
else params_modifided.flow_mult *= (float)percentFlow[idx];
//set role
if (rolePass[idx] != erNone)
params_modifided.role = rolePass[idx];
//choose if we are going to extrude with or without overlap
if ((params.flow.bridge && idx == 0) || has_overlap[idx] || this->no_overlap_expolygons.empty()){
@ -115,8 +118,8 @@ namespace Slic3r {
// first infill
FillParams first_pass_params = params;
if(first_pass_params.role != ExtrusionRole::erSupportMaterial && first_pass_params.role != ExtrusionRole::erSupportMaterialInterface)
first_pass_params.role = ExtrusionRole::erSolidInfill;
//if(first_pass_params.role != ExtrusionRole::erSupportMaterial && first_pass_params.role != ExtrusionRole::erSupportMaterialInterface)
//s first_pass_params.role = ExtrusionRole::erSolidInfill;
perform_single_fill(0, *eecroot, *surface, first_pass_params, volume_to_occupy);
//use monotonic for ironing pass

View File

@ -18,9 +18,9 @@ public:
fillPattern[0] = InfillPattern::ipRectilinearWGapFill;
fillPattern[1] = InfillPattern::ipRectilinear;
fillPattern[2] = InfillPattern::ipRectilinear;
rolePass[0] = erSolidInfill;
rolePass[1] = erTopSolidInfill;
rolePass[2] = erTopSolidInfill;
rolePass[0] = erNone;// erTopSolidInfill;
rolePass[1] = erIroning;
rolePass[2] = erIroning;
percentWidth[0] = 1;
percentWidth[1] = 2;
percentWidth[2] = 1.0;
@ -73,9 +73,9 @@ public:
fillPattern[0] = InfillPattern::ipHilbertCurve; //ipRectilinear
fillPattern[1] = InfillPattern::ipConcentric;
fillPattern[2] = InfillPattern::ipRectilinear;
rolePass[0] = erTopSolidInfill;//erSolidInfill
rolePass[1] = erSolidInfill;
rolePass[2] = erTopSolidInfill;
rolePass[0] = erSolidInfill;//erSolidInfill
rolePass[1] = erTopSolidInfill;
rolePass[2] = erIroning;
percentWidth[0] = 1; //0.8
percentWidth[1] = 1.5;
percentWidth[2] = 2.8;
@ -106,9 +106,9 @@ public:
fillPattern[0] = InfillPattern::ipHilbertCurve; //ipHilbertCurve
fillPattern[1] = InfillPattern::ipHilbertCurve;
fillPattern[2] = InfillPattern::ipRectilinear;
rolePass[0] = erSolidInfill;
rolePass[1] = erTopSolidInfill;
rolePass[2] = erTopSolidInfill;
rolePass[0] = erTopSolidInfill;
rolePass[1] = erIroning;
rolePass[2] = erIroning;
percentWidth[0] = 1;
percentWidth[1] = 1.5;
percentWidth[2] = 1.0;

View File

@ -746,6 +746,81 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re
// free functions called by GCode::_do_export()
namespace DoExport {
class ExtrusionMinMM : public ExtrusionVisitorConst {
double min = std::numeric_limits<double>::max();
std::unordered_set<ExtrusionRole> excluded;
public:
ExtrusionMinMM(const ConfigBase* config) {
excluded.insert(erIroning);
excluded.insert(erMilling);
excluded.insert(erCustom);
excluded.insert(erMixed);
excluded.insert(erNone);
excluded.insert(erWipeTower);
if (config->get_abs_value("perimeter_speed") != 0 && config->get_abs_value("small_perimeter_speed") != 0) {
excluded.insert(erPerimeter);
excluded.insert(erSkirt);
}
if (config->get_abs_value("external_perimeter_speed") != 0 && config->get_abs_value("small_perimeter_speed") != 0)
excluded.insert(erExternalPerimeter);
if (config->get_abs_value("overhangs_speed") != 0 && config->get_abs_value("small_perimeter_speed") != 0)
excluded.insert(erOverhangPerimeter);
if (config->get_abs_value("gap_fill_speed") != 0)
excluded.insert(erGapFill);
if (config->get_abs_value("thin_walls_speed") != 0)
excluded.insert(erThinWall);
if (config->get_abs_value("infill_speed") != 0)
excluded.insert(erInternalInfill);
if (config->get_abs_value("solid_infill_speed") != 0)
excluded.insert(erSolidInfill);
if (config->get_abs_value("top_solid_infill_speed") != 0)
excluded.insert(erTopSolidInfill);
if (config->get_abs_value("bridge_speed") != 0)
excluded.insert(erBridgeInfill);
if (config->get_abs_value("bridge_speed_internal") != 0)
excluded.insert(erInternalBridgeInfill);
if (config->get_abs_value("support_material_speed") != 0)
excluded.insert(erSupportMaterial);
if (config->get_abs_value("support_material_interface_speed") != 0)
excluded.insert(erSupportMaterialInterface);
}
virtual void use(const ExtrusionPath& path) override {
if (excluded.find(path.role()) == excluded.end())
min = std::min(min, path.mm3_per_mm);
}
virtual void use(const ExtrusionPath3D& path3D) override {
if (excluded.find(path3D.role()) == excluded.end())
min = std::min(min, path3D.mm3_per_mm);
}
virtual void use(const ExtrusionMultiPath& multipath) override {
for (const ExtrusionPath& path : multipath.paths)
use(path);
}
virtual void use(const ExtrusionMultiPath3D& multipath) override {
for (const ExtrusionPath& path : multipath.paths)
use(path);
}
virtual void use(const ExtrusionLoop& loop) override {
for (const ExtrusionPath& path : loop.paths)
use(path);
}
virtual void use(const ExtrusionEntityCollection& collection) override {
for (const ExtrusionEntity* entity : collection.entities)
entity->visit(*this);
}
double reset_use_get(const ExtrusionEntityCollection entity) { reset(); use(entity); return get(); }
double get() { return min; }
void reset() { min = std::numeric_limits<double>::max(); }
//test if at least a ExtrusionRole from tests is used for min computation
bool is_compatible(std::initializer_list<ExtrusionRole> tests) {
for (ExtrusionRole test : tests)
if (excluded.find(test) == excluded.end())
return true;
return false;
}
};
static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool& silent_time_estimator_enabled)
{
silent_time_estimator_enabled = (config.gcode_flavor.value == gcfMarlin) && config.silent_mode;
@ -756,6 +831,7 @@ namespace DoExport {
static double autospeed_volumetric_limit(const Print &print)
{
ExtrusionMinMM compute_min_mm3_per_mm{ &print.full_print_config() };
// get the minimum cross-section used in the print
std::vector<double> mm3_per_mm;
for (auto object : print.objects()) {
@ -763,37 +839,20 @@ namespace DoExport {
const PrintRegion* region = print.regions()[region_id];
for (auto layer : object->layers()) {
const LayerRegion* layerm = layer->regions()[region_id];
if (region->config().get_abs_value("perimeter_speed") == 0 ||
region->config().get_abs_value("small_perimeter_speed") == 0 ||
region->config().get_abs_value("external_perimeter_speed") == 0 ||
region->config().get_abs_value("overhangs_speed") == 0)
mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm());
if (region->config().get_abs_value("infill_speed") == 0 ||
region->config().get_abs_value("solid_infill_speed") == 0 ||
region->config().get_abs_value("top_solid_infill_speed") == 0 ||
region->config().get_abs_value("bridge_speed") == 0 ||
region->config().get_abs_value("bridge_speed_internal") == 0)
{
// Minimal volumetric flow should not be calculated over ironing extrusions.
// Use following lambda instead of the built-it method.
// https://github.com/prusa3d/PrusaSlicer/issues/5082
auto min_mm3_per_mm_no_ironing = [](const ExtrusionEntityCollection& eec) -> double {
double min = std::numeric_limits<double>::max();
for (const ExtrusionEntity* ee : eec.entities)
if (ee->role() != erIroning)
min = std::min(min, ee->min_mm3_per_mm());
return min;
};
mm3_per_mm.push_back(min_mm3_per_mm_no_ironing(layerm->fills));
}
if (compute_min_mm3_per_mm.is_compatible({ erPerimeter, erExternalPerimeter, erOverhangPerimeter }))
mm3_per_mm.push_back(compute_min_mm3_per_mm.reset_use_get(layerm->perimeters));
if (compute_min_mm3_per_mm.is_compatible({ erInternalInfill, erSolidInfill, erTopSolidInfill,erBridgeInfill,erInternalBridgeInfill }))
mm3_per_mm.push_back(compute_min_mm3_per_mm.reset_use_get(layerm->fills));
}
}
if (object->config().get_abs_value("support_material_speed") == 0 ||
object->config().get_abs_value("support_material_interface_speed") == 0)
if (compute_min_mm3_per_mm.is_compatible({ erSupportMaterial, erSupportMaterialInterface }))
for (auto layer : object->support_layers())
mm3_per_mm.push_back(layer->support_fills.min_mm3_per_mm());
mm3_per_mm.push_back(compute_min_mm3_per_mm.reset_use_get(layer->support_fills));
}
if (compute_min_mm3_per_mm.is_compatible({ erSkirt })) {
mm3_per_mm.push_back(compute_min_mm3_per_mm.reset_use_get(print.skirt()));
mm3_per_mm.push_back(compute_min_mm3_per_mm.reset_use_get(print.brim()));
}
// filter out 0-width segments
mm3_per_mm.erase(std::remove_if(mm3_per_mm.begin(), mm3_per_mm.end(), [](double v) { return v < 0.000001; }), mm3_per_mm.end());
double volumetric_speed = 0.;
@ -3122,9 +3181,10 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s
double min_length = scale_(this->m_config.small_perimeter_min_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
double max_length = scale_(this->m_config.small_perimeter_max_length.get_abs_value(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0)));
if (loop.length() <= min_length) {
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
} else {
speed = -(loop.length() - min_length) / (max_length - min_length);
//set speed between -1 and 0 you have to multiply the real peed by the opposite of that, and add the other part as small_perimeter_speed
speed = (min_length - loop.length()) / (max_length - min_length);
}
}
@ -3749,40 +3809,53 @@ std::string GCode::_before_extrude(const ExtrusionPath &path, const std::string
if (factor < 1 && !(is_bridge(path.role()))) {
float small_speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed);
//apply factor between feature speed and small speed
speed = speed * factor + (1.f - factor) * small_speed;
}
speed = (speed * factor) + double((1.f - factor) * small_speed);
}
}
if (m_volumetric_speed != 0. && speed == 0) {
//if m_volumetric_speed, use the max size for thinwall & gapfill, to avoid variations
speed = m_volumetric_speed / path.mm3_per_mm;
if (speed > m_config.max_print_speed.value)
speed = m_config.max_print_speed.value;
double vol_speed = m_volumetric_speed / path.mm3_per_mm;
if (vol_speed > m_config.max_print_speed.value)
vol_speed = m_config.max_print_speed.value;
// if using a % of an auto speed, use the % over the volumetric speed.
if (path.role() == erExternalPerimeter) {
speed = m_config.get_abs_value("external_perimeter_speed", vol_speed);
} else if (path.role() == erInternalBridgeInfill) {
speed = m_config.get_abs_value("bridge_speed_internal", vol_speed);
} else if (path.role() == erOverhangPerimeter) {
speed = m_config.get_abs_value("overhangs_speed", vol_speed);
} else if (path.role() == erSolidInfill) {
speed = m_config.get_abs_value("solid_infill_speed", vol_speed);
} else if (path.role() == erTopSolidInfill) {
speed = m_config.get_abs_value("top_solid_infill_speed", vol_speed);
}
if(speed == 0){
speed = vol_speed;
}
}
if (speed == 0) // this code shouldn't trigger as if it's 0, you have to get a m_volumetric_speed
speed = m_config.max_print_speed.value;
if (this->on_first_layer())
if (path.role() == erInternalInfill || path.role() == erSolidInfill)
speed = std::min(m_config.get_abs_value("first_layer_infill_speed", speed), speed);
else
speed = std::min(m_config.get_abs_value("first_layer_speed", speed), speed);
if (m_config.max_volumetric_speed.value > 0) {
// cap speed with max_volumetric_speed anyway (even if user is not using autospeed)
speed = std::min(
speed,
m_config.max_volumetric_speed.value / path.mm3_per_mm
);
if (path.role() == erInternalInfill || path.role() == erSolidInfill) {
double first_layer_infill_speed = m_config.get_abs_value("first_layer_infill_speed", speed);
if(first_layer_infill_speed > 0)
speed = std::min(first_layer_infill_speed, speed);
} else {
double first_layer_speed = m_config.get_abs_value("first_layer_speed", speed);
if (first_layer_speed > 0)
speed = std::min(first_layer_speed, speed);
}
// cap speed with max_volumetric_speed anyway (even if user is not using autospeed)
if (m_config.max_volumetric_speed.value > 0 && path.mm3_per_mm > 0) {
speed = std::min(m_config.max_volumetric_speed.value / path.mm3_per_mm, speed);
}
if (EXTRUDER_CONFIG_WITH_DEFAULT(filament_max_volumetric_speed, 0) > 0) {
// cap speed with max_volumetric_speed anyway (even if user is not using autospeed)
speed = std::min(
speed,
EXTRUDER_CONFIG_WITH_DEFAULT(filament_max_volumetric_speed, speed) / path.mm3_per_mm
);
double filament_max_volumetric_speed = EXTRUDER_CONFIG_WITH_DEFAULT(filament_max_volumetric_speed, 0);
if (filament_max_volumetric_speed > 0) {
speed = std::min(filament_max_volumetric_speed, speed);
}
if (EXTRUDER_CONFIG_WITH_DEFAULT(filament_max_speed, 0) > 0) {
speed = std::min(
speed,
EXTRUDER_CONFIG_WITH_DEFAULT(filament_max_speed, speed));
double filament_max_speed = EXTRUDER_CONFIG_WITH_DEFAULT(filament_max_speed, 0);
if (filament_max_speed > 0) {
speed = std::min(filament_max_speed, speed);
}
double F = speed * 60; // convert mm/sec to mm/min

View File

@ -311,6 +311,7 @@ void PrintConfigDef::init_fff_params()
"\nSet zero to disable acceleration control for bridges."
"\nNote that it won't be applied to overhangs, they still use the perimeter acceleration.");
def->sidetext = L("mm/s² or %");
def->ratio_over = "default_acceleration";
def->min = 0;
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
@ -636,6 +637,7 @@ void PrintConfigDef::init_fff_params()
"\nYou can set it as a % of the max of the X/Y machine acceleration limit."
"\nSet zero to prevent resetting acceleration at all.");
def->sidetext = L("mm/s² or %");
def->ratio_over = "machine_max_acceleration_X";
def->min = 0;
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
@ -1752,6 +1754,7 @@ void PrintConfigDef::init_fff_params()
"\nCan be a % of the default acceleration"
"\nSet zero to disable acceleration control for first layer.");
def->sidetext = L("mm/s² or %");
def->ratio_over = "default_acceleration";
def->min = 0;
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
@ -1902,7 +1905,8 @@ void PrintConfigDef::init_fff_params()
def->full_label = L("Gap fill speed");
def->category = OptionCategory::speed;
def->tooltip = L("Speed for filling small gaps using short zigzag moves. Keep this reasonably low "
"to avoid too much shaking and resonance issues.");
"to avoid too much shaking and resonance issues."
"\nGap fill extrusions are ignored from the automatic volumetric speed computation, unless you set it to 0.");
def->sidetext = L("mm/s");
def->min = 0;
def->mode = comAdvanced;
@ -1994,6 +1998,7 @@ void PrintConfigDef::init_fff_params()
"\nCan be a % of the default acceleration"
"\nSet zero to disable acceleration control for infill.");
def->sidetext = L("mm/s² or %");
def->ratio_over = "default_acceleration";
def->min = 0;
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
@ -2308,14 +2313,17 @@ void PrintConfigDef::init_fff_params()
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloat(0.1));
def = this->add("ironing_speed", coFloat);
def = this->add("ironing_speed", coFloatOrPercent);
def->label = L("Ironing");
def->category = OptionCategory::ironing;
def->tooltip = L("Ironing");
def->tooltip = L("Ironing speed. Used for the ironing pass of the ironing infill pattern, and the post-process infill."
" Can be defined as mm.s, or a % of the top solid infill speed."
"\nIroning extrusions are ignored from the automatic volumetric speed computation.");
def->sidetext = L("mm/s");
def->min = 0;
def->ratio_over = "top_solid_infill_speed";
def->min = 0.1;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(15));
def->set_default_value(new ConfigOptionFloatOrPercent(15, false));
def = this->add("layer_gcode", coString);
def->label = L("After layer change G-code");
@ -2885,6 +2893,8 @@ void PrintConfigDef::init_fff_params()
"\nCan be a % of the default acceleration"
"\nSet zero to disable acceleration control for perimeters.");
def->sidetext = L("mm/s² or %");
def->ratio_over = "default_acceleration";
def->min = 0;
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloatOrPercent(0,false));
@ -5557,9 +5567,12 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
}
} else if ("elefant_foot_min_width" == opt_key) {
opt_key = "elephant_foot_min_width";
} else if("first_layer_acceleration" == opt_key || "infill_acceleration" == opt_key || "bridge_acceleration" == opt_key || "default_acceleration" == opt_key || "overhangs_speed" == opt_key || "perimeter_acceleration" == opt_key){
if (value.find("%") != std::string::npos)
value = "0";
} else if("first_layer_acceleration" == opt_key || "infill_acceleration" == opt_key || "bridge_acceleration" == opt_key || "default_acceleration" == opt_key || "perimeter_acceleration" == opt_key
|| "overhangs_speed" == opt_key || "ironing_speed" == opt_key){
// remove '%'
if (value.find("%") != std::string::npos) {
value = std::to_string(all_conf.get_abs_value(opt_key));
}
} else if ("gap_fill_speed" == opt_key && all_conf.has("gap_fill") && !all_conf.option<ConfigOptionBool>("gap_fill")->value) {
value = "0";
} else if ("bridge_flow_ratio" == opt_key && all_conf.has("bridge_flow_ratio")) {

View File

@ -805,7 +805,7 @@ public:
ConfigOptionEnum<IroningType> ironing_type;
ConfigOptionPercent ironing_flowrate;
ConfigOptionFloat ironing_spacing;
ConfigOptionFloat ironing_speed;
ConfigOptionFloatOrPercent ironing_speed;
// milling options
ConfigOptionFloatOrPercent milling_after_z;
ConfigOptionFloatOrPercent milling_extra_size;