ensure the layer height & first layer height are low enough.

TODO: same for actual real layer height (from variable layer heights)
This commit is contained in:
supermerill 2021-08-09 19:46:09 +02:00 committed by supermerill
parent a510c3039c
commit 26500cd9a0
8 changed files with 188 additions and 84 deletions

View File

@ -112,7 +112,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
FlowRole extrusion_role = surface.has_pos_top() ? frTopSolidInfill : (surface.has_fill_solid() ? frSolidInfill : frInfill);
bool is_bridge = layer.id() > 0 && surface.has_mod_bridge();
bool is_denser = false;
params.extruder = layerm.region()->extruder(extrusion_role);
params.extruder = layerm.region()->extruder(extrusion_role, *layer.object());
params.pattern = region_config.fill_pattern.value;
params.density = float(region_config.fill_density) / 100.f;
params.dont_adjust = false;
@ -324,7 +324,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
}
if (internal_solid_fill == nullptr) {
// Produce another solid fill.
params.extruder = layerm.region()->extruder(frSolidInfill);
params.extruder = layerm.region()->extruder(frSolidInfill, *layer.object());
params.pattern = layerm.region()->config().solid_fill_pattern.value;
params.density = 100.f;
params.role = erInternalInfill;

View File

@ -1518,20 +1518,6 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
return L("One or more object were assigned an extruder that the printer does not have.");
#endif
auto validate_extrusion_width = [min_nozzle_diameter, max_nozzle_diameter](const ConfigBase &config, const char *opt_key, double layer_height, std::string &err_msg) -> bool {
double extrusion_width_min = config.get_abs_value(opt_key, min_nozzle_diameter);
double extrusion_width_max = config.get_abs_value(opt_key, max_nozzle_diameter);
if (extrusion_width_min == 0) {
// Default "auto-generated" extrusion width is always valid.
} else if (extrusion_width_min <= layer_height) {
err_msg = (boost::format(L("%1%=%2% mm is too low to be printable at a layer height %3% mm")) % opt_key % extrusion_width_min % layer_height).str();
return false;
} else if (extrusion_width_max >= max_nozzle_diameter * 4.) {
err_msg = (boost::format(L("Excessive %1%=%2% mm to be printable with a nozzle diameter %3% mm")) % opt_key % extrusion_width_max % max_nozzle_diameter).str();
return false;
}
return true;
};
for (PrintObject *object : m_objects) {
if (object->config().raft_layers > 0 || object->config().support_material.value) {
if ((object->config().support_material_extruder == 0 || object->config().support_material_interface_extruder == 0) && max_nozzle_diameter - min_nozzle_diameter > EPSILON) {
@ -1555,40 +1541,62 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
}
}
}
// validate first_layer_height
double first_layer_height = object->config().get_abs_value("first_layer_height", this->m_config.nozzle_diameter.get_at(0));
double first_layer_min_nozzle_diameter;
if (object->config().raft_layers > 0) {
// if we have raft layers, only support material extruder is used on first layer
size_t first_layer_extruder = object->config().raft_layers == 1
? object->config().support_material_interface_extruder-1
: object->config().support_material_extruder-1;
first_layer_min_nozzle_diameter = (first_layer_extruder == size_t(-1)) ?
min_nozzle_diameter :
m_config.nozzle_diameter.get_at(first_layer_extruder);
} else {
// if we don't have raft layers, any nozzle diameter is potentially used in first layer
first_layer_min_nozzle_diameter = min_nozzle_diameter;
}
if (first_layer_height > first_layer_min_nozzle_diameter)
return { PrintBase::PrintValidationError::pveWrongSettings,L("First layer height can't be greater than nozzle diameter") };
// validate layer_height
double layer_height = object->config().layer_height.value;
if (layer_height > min_nozzle_diameter)
return { PrintBase::PrintValidationError::pveWrongSettings,L("Layer height can't be greater than nozzle diameter") };
// Validate extrusion widths.
std::string err_msg;
if (! validate_extrusion_width(object->config(), "extrusion_width", layer_height, err_msg))
return { PrintBase::PrintValidationError::pveWrongSettings,err_msg };
if ((object->config().support_material || object->config().raft_layers > 0) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg))
return { PrintBase::PrintValidationError::pveWrongSettings,err_msg };
for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" })
for (size_t i = 0; i < object->region_volumes.size(); ++ i)
if (! object->region_volumes[i].empty() && ! validate_extrusion_width(this->get_region(i)->config(), opt_key, layer_height, err_msg))
return { PrintBase::PrintValidationError::pveWrongSettings, err_msg };
// validate layer_height for each region
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++region_id) {
if (object->region_volumes[region_id].empty()) continue;
const PrintRegion* region = this->regions()[region_id];
std::vector<uint16_t> object_extruders;
PrintRegion::collect_object_printing_extruders(config(), object->config(), region->config(), object_extruders);
//object->region_volumes[region_id].front().first.second < object->layers()
double layer_height = object->config().layer_height.value;
for (uint16_t extruder_id : object_extruders) {
double min_layer_height = config().min_layer_height.values[extruder_id];
double max_layer_height = config().max_layer_height.values[extruder_id];
double nozzle_diameter = config().nozzle_diameter.values[extruder_id];
double first_layer_height = object->config().first_layer_height.get_abs_value(nozzle_diameter);
if (max_layer_height < EPSILON) max_layer_height = nozzle_diameter * 0.75;
//check first layer
if (object->region_volumes[region_id].front().first.first < first_layer_height) {
if (first_layer_height + EPSILON < min_layer_height)
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be greater than %s")) % "min layer height").str() };
for (auto tuple : std::vector<std::pair<double, const char*>>{
{nozzle_diameter, "nozzle diameter"},
{max_layer_height, "max layer height"},
{skirt_flow(extruder_id).width, "skirt extrusion width"},
{region->width(FlowRole::frSupportMaterial, true, *object), "support material extrusion width"},
{region->width(FlowRole::frPerimeter, true, *object), "perimeter extrusion width"},
{region->width(FlowRole::frExternalPerimeter, true, *object), "perimeter extrusion width"},
{region->width(FlowRole::frInfill, true, *object), "infill extrusion width"},
{region->width(FlowRole::frSolidInfill, true, *object), "solid infill extrusion width"},
{region->width(FlowRole::frTopSolidInfill, true, *object), "top solid infill extrusion width"},
})
if (first_layer_height > tuple.first + EPSILON)
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be greater than %s")) % tuple.second).str() };
}
//check not-first layer
if (object->region_volumes[region_id].front().first.second > layer_height) {
if (layer_height + EPSILON < min_layer_height)
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("First layer height can't be greater than %s")) % "min layer height").str() };
for (auto tuple : std::vector<std::pair<double, const char*>>{
{nozzle_diameter, "nozzle diameter"},
{max_layer_height, "max layer height"},
{skirt_flow(extruder_id).width, "skirt extrusion width"},
{region->width(FlowRole::frSupportMaterial, false, *object), "support material extrusion width"},
{region->width(FlowRole::frPerimeter, false, *object), "perimeter extrusion width"},
{region->width(FlowRole::frExternalPerimeter, false, *object), "perimeter extrusion width"},
{region->width(FlowRole::frInfill, false, *object), "infill extrusion width"},
{region->width(FlowRole::frSolidInfill, false, *object), "solid infill extrusion width"},
{region->width(FlowRole::frTopSolidInfill, false, *object), "top solid infill extrusion width"},
})
if (layer_height > tuple.first + EPSILON)
return { PrintBase::PrintValidationError::pveWrongSettings, (boost::format(L("Layer height can't be greater than %s")) % tuple.second).str() };
}
}
}
}
}

View File

@ -65,8 +65,9 @@ public:
const Print* print() const { return m_print; }
const PrintRegionConfig& config() const { return m_config; }
// 1-based extruder identifier for this region and role.
uint16_t extruder(FlowRole role) const;
Flow flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const;
uint16_t extruder(FlowRole role, const PrintObject& object) const;
Flow flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject& object) const;
float width(FlowRole role, bool first_layer, const PrintObject& object) const;
// Average diameter of nozzles participating on extruding this region.
coordf_t nozzle_dmr_avg(const PrintConfig &print_config) const;
// Average diameter of nozzles participating on extruding this region.

View File

@ -5945,7 +5945,13 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
double max_nozzle_diameter = 0;
for (double dmr : nozzle_diameter_option->values)
max_nozzle_diameter = std::max(max_nozzle_diameter, dmr);
Flow flow = Flow::new_from_spacing(spacing_option->get_abs_value(max_nozzle_diameter), max_nozzle_diameter, layer_height_option->value, false);
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);
//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);
flow.height = flow.width;
}
if (opt_key == "extrusion_spacing") {
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("extrusion_width");
if (width_option) {
@ -6055,6 +6061,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
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);
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;
something_changed = true;
@ -6066,6 +6073,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
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);
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;
something_changed = true;
@ -6078,6 +6086,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
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);
if (flow.width < flow.height) flow.height = flow.width;
flow.spacing_ratio = 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;
@ -6091,6 +6100,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
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);
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);
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;
@ -6103,6 +6113,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
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);
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;
something_changed = true;
@ -6114,6 +6125,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
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);
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;
something_changed = true;
@ -6125,6 +6137,7 @@ bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const
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);
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;
something_changed = true;

View File

@ -2171,7 +2171,7 @@ namespace Slic3r {
static void apply_to_print_region_config(PrintRegionConfig& out, const DynamicPrintConfig& in)
{
// 1) Copy the "extruder key to infill_extruder and perimeter_extruder.
// 1) Copy the "extruder" key to infill_extruder and perimeter_extruder.
std::string sextruder = "extruder";
auto* opt_extruder = in.opt<ConfigOptionInt>(sextruder);
if (opt_extruder) {
@ -2381,7 +2381,7 @@ namespace Slic3r {
}
std::vector<ExPolygons> expolygons_by_layer = this->slice_region(region_id, slice_zs, slicing_mode, slicing_mode_normal_below_layer, SlicingMode::Regular);
//scale for shrinkage
const size_t extruder_id = this->print()->regions()[region_id]->extruder(FlowRole::frPerimeter) - 1;
const size_t extruder_id = this->print()->regions()[region_id]->extruder(FlowRole::frPerimeter, *this) - 1;
double scale = print()->config().filament_shrink.get_abs_value(extruder_id, 1);
if (scale != 1) {
scale = 1 / scale;
@ -2434,7 +2434,7 @@ namespace Slic3r {
}
//scale for shrinkage
for (SlicedVolume& sv : sliced_volumes) {
double scale = print()->config().filament_shrink.get_abs_value(this->print()->regions()[sv.region_id]->extruder(FlowRole::frPerimeter) - 1, 1);
double scale = print()->config().filament_shrink.get_abs_value(this->print()->regions()[sv.region_id]->extruder(FlowRole::frPerimeter, *this) - 1, 1);
if (scale != 1) {
scale = 1 / scale;
for (ExPolygons& polys : sv.expolygons_by_layer)

View File

@ -4,7 +4,7 @@
namespace Slic3r {
// 1-based extruder identifier for this region and role.
uint16_t PrintRegion::extruder(FlowRole role) const
uint16_t PrintRegion::extruder(FlowRole role, const PrintObject& object) const
{
size_t extruder = 0;
if (role == frPerimeter || role == frExternalPerimeter)
@ -13,6 +13,10 @@ uint16_t PrintRegion::extruder(FlowRole role) const
extruder = m_config.infill_extruder;
else if (role == frSolidInfill || role == frTopSolidInfill)
extruder = m_config.solid_infill_extruder;
else if (role == frSupportMaterial)
extruder = object.config().support_material_extruder;
else if (role == frSupportMaterialInterface)
extruder = object.config().support_material_interface_extruder;
else
throw Slic3r::InvalidArgument("Unknown role");
return extruder;
@ -50,10 +54,48 @@ 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) - 1);
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);
}
float PrintRegion::width(FlowRole role, bool first_layer, const PrintObject& object) const
{
const ConfigOptionFloatOrPercent* config_width = nullptr;
// otherwise, get extrusion width from configuration
// (might be an absolute value, or a percent value, or zero for auto)
if (first_layer && object.config().first_layer_extrusion_width.value > 0) {
config_width = &object.config().first_layer_extrusion_width;
} else if (role == frExternalPerimeter) {
config_width = &m_config.external_perimeter_extrusion_width;
} else if (role == frPerimeter) {
config_width = &m_config.perimeter_extrusion_width;
} else if (role == frInfill) {
config_width = &m_config.infill_extrusion_width;
} else if (role == frSolidInfill) {
config_width = &m_config.solid_infill_extrusion_width;
} else if (role == frTopSolidInfill) {
config_width = &m_config.top_infill_extrusion_width;
} else if (role == frSupportMaterial || role == frSupportMaterialInterface) {
config_width = &object.config().support_material_extrusion_width;
} else {
throw Slic3r::InvalidArgument("Unknown role");
}
if (!config_width || config_width->value == 0)
config_width = &object.config().extrusion_width;
// 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);
if (config_width->value <= 0.) {
// If user left option to 0, calculate a sane default width.
return Flow::auto_extrusion_width(role, nozzle_diameter);
} else {
// If user set a manual value, use it.
return float(config_width->get_abs_value(nozzle_diameter));
}
}
coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
{
return (print_config.nozzle_diameter.get_at(m_config.perimeter_extruder.value - 1) +

View File

@ -227,18 +227,26 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
return (speed_normal > 0.) ? speed_normal : speed_max;
};
if (perimeter_extruder_active) {
double external_perimeter_rate = Flow::new_from_config_width(frExternalPerimeter,
first_positive(first_layer_extrusion_width_ptr, external_perimeter_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr).mm3_per_mm() *
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);
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));
if (max_flow < external_perimeter_rate) {
max_flow = external_perimeter_rate;
max_flow_extrusion_type = _utf8(L("external perimeters"));
}
double perimeter_rate = Flow::new_from_config_width(frPerimeter,
first_positive(first_layer_extrusion_width_ptr, perimeter_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr).mm3_per_mm() *
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);
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));
if (max_flow < perimeter_rate) {
@ -247,27 +255,36 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
}
}
if (! bridging && infill_extruder_active) {
double infill_rate = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr).mm3_per_mm() * limit_infill_by_first_layer_speed(infill_speed, max_print_speed);
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);
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);
if (max_flow < infill_rate) {
max_flow = infill_rate;
max_flow_extrusion_type = _utf8(L("infill"));
}
}
if (solid_infill_extruder_active) {
double solid_infill_rate = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, solid_infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, 0).mm3_per_mm() *
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);
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() *
(bridging ? bridge_speed : limit_infill_by_first_layer_speed(solid_infill_speed, max_print_speed));
if (max_flow < solid_infill_rate) {
max_flow = solid_infill_rate;
max_flow_extrusion_type = _utf8(L("solid infill"));
}
if (! bridging) {
double top_solid_infill_rate = Flow::new_from_config_width(frInfill,
first_positive(first_layer_extrusion_width_ptr, top_infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr).mm3_per_mm() * limit_infill_by_first_layer_speed(top_solid_infill_speed, max_print_speed);
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);
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);
if (max_flow < top_solid_infill_rate) {
max_flow = top_solid_infill_rate;
max_flow_extrusion_type = _utf8(L("top solid infill"));
@ -275,9 +292,12 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
}
}
if (support_material_extruder_active) {
double support_material_rate = Flow::new_from_config_width(frSupportMaterial,
first_positive(first_layer_extrusion_width_ptr, support_material_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr).mm3_per_mm() *
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);
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() *
(bridging ? bridge_speed : limit_by_first_layer_speed(support_material_speed, max_print_speed));
if (max_flow < support_material_rate) {
max_flow = support_material_rate;
@ -285,9 +305,12 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
}
}
if (support_material_interface_extruder_active) {
double support_material_interface_rate = Flow::new_from_config_width(frSupportMaterialInterface,
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).mm3_per_mm() *
nozzle_diameter, lh, 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() *
(bridging ? bridge_speed : limit_by_first_layer_speed(support_material_interface_speed, max_print_speed));
if (max_flow < support_material_interface_rate) {
max_flow = support_material_interface_rate;
@ -340,7 +363,17 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle& pre
*print_config.opt<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"),
nozzle_diameter, layer_height, false);
//set spacing
// failsafe for too big height
if (external_perimeter_flow.height > external_perimeter_flow.width)
external_perimeter_flow.height = external_perimeter_flow.width;
if (perimeter_flow.height > perimeter_flow.width)
perimeter_flow.height = perimeter_flow.width;
if (external_perimeter_flow.height != perimeter_flow.height) {
perimeter_flow.height = std::min(perimeter_flow.height, external_perimeter_flow.height);
external_perimeter_flow.height = perimeter_flow.height;
}
// set spacing
external_perimeter_flow.spacing_ratio = print_config.opt<ConfigOptionPercent>("external_perimeter_overlap")->get_abs_value(1);
perimeter_flow.spacing_ratio = print_config.opt<ConfigOptionPercent>("perimeter_overlap")->get_abs_value(1);

View File

@ -1186,6 +1186,7 @@ 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() })) {
update_dirty();
//# Initialize UI components with the config values.
@ -2979,24 +2980,30 @@ void TabPrinter::toggle_options()
//z step checks
{
double z_step = m_config->opt_float("z_step");
int64_t z_step_Mlong = (int64_t)(z_step * 1000000.);
DynamicPrintConfig new_conf;
bool has_changed = false;
const std::vector<double>& min_layer_height = m_config->option<ConfigOptionFloats>("min_layer_height")->values;
for (int i = 0; i < min_layer_height.size(); i++)
if (min_layer_height[i] / z_step != 0) {
if(!has_changed )
for (int i = 0; i < min_layer_height.size(); i++) {
if (min_layer_height[i] != 0 && (int64_t)(min_layer_height[i] * 1000000.) % z_step_Mlong != 0) {
if (!has_changed)
new_conf = *m_config;
new_conf.option<ConfigOptionFloats>("min_layer_height")->values[i] = std::max(z_step, Slic3r::check_z_step(new_conf.option<ConfigOptionFloats>("min_layer_height")->values[i], z_step));
has_changed = true;
}
const std::vector<double>& max_layer_height = m_config->option<ConfigOptionFloats>("max_layer_height")->values;
for (int i = 0; i < max_layer_height.size(); i++)
if (max_layer_height[i] / z_step != 0) {
}
const std::vector<double>& nozzle_diameters = m_config->option<ConfigOptionFloats>("nozzle_diameter")->values;
std::vector<double> max_layer_height = m_config->option<ConfigOptionFloats>("max_layer_height")->values;
for (int i = 0; i < max_layer_height.size(); i++) {
if (max_layer_height[i] == 0)
max_layer_height[i] = nozzle_diameters[i] * 0.75;
if ((int64_t)(max_layer_height[i] * 1000000.) % z_step_Mlong != 0) {
if (!has_changed)
new_conf = *m_config;
new_conf.option<ConfigOptionFloats>("max_layer_height")->values[i] = std::max(z_step, Slic3r::check_z_step(new_conf.option<ConfigOptionFloats>("max_layer_height")->values[i], z_step));
has_changed = true;
}
}
if (has_changed) {
load_config(new_conf);
}