Implemented volumetric flow rate hints,

removed some C++11 conditioned compilation. Slic3r now requires C++11.
This commit is contained in:
bubnikv 2017-11-09 15:10:20 +01:00
parent 9a0100d6de
commit b23b9ea1d2
10 changed files with 151 additions and 236 deletions

View File

@ -1010,7 +1010,7 @@ public:
{ {
ConfigOption *opt = this->optptr(opt_key, create); ConfigOption *opt = this->optptr(opt_key, create);
assert(opt == nullptr || opt->type() == typename TYPE::static_type()); assert(opt == nullptr || opt->type() == typename TYPE::static_type());
return (opt == nullptr || opt->type() == typename TYPE::static_type()) ? nullptr : static_cast<TYPE*>(opt); return (opt == nullptr || opt->type() != typename TYPE::static_type()) ? nullptr : static_cast<TYPE*>(opt);
} }
template<typename TYPE> template<typename TYPE>
const TYPE* option(const t_config_option_key &opt_key) const const TYPE* option(const t_config_option_key &opt_key) const
@ -1101,23 +1101,23 @@ public:
// Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. // Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store.
t_config_option_keys keys() const override; t_config_option_keys keys() const override;
std::string& opt_string(const t_config_option_key &opt_key, bool create = false) { return dynamic_cast<ConfigOptionString*>(this->option(opt_key, create))->value; } std::string& opt_string(const t_config_option_key &opt_key, bool create = false) { return this->option<ConfigOptionString>(opt_key, create)->value; }
const std::string& opt_string(const t_config_option_key &opt_key) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key); } const std::string& opt_string(const t_config_option_key &opt_key) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key); }
std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) { return dynamic_cast<ConfigOptionStrings*>(this->option(opt_key))->get_at(idx); } std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionStrings>(opt_key)->get_at(idx); }
const std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key, idx); } const std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key, idx); }
double& opt_float(const t_config_option_key &opt_key) { return dynamic_cast<ConfigOptionFloat*>(this->option(opt_key))->value; } double& opt_float(const t_config_option_key &opt_key) { return this->option<ConfigOptionFloat>(opt_key)->value; }
const double opt_float(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionFloat*>(this->option(opt_key))->value; } const double opt_float(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionFloat*>(this->option(opt_key))->value; }
double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return dynamic_cast<ConfigOptionFloats*>(this->option(opt_key))->get_at(idx); } double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloats>(opt_key)->get_at(idx); }
const double opt_float(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloats*>(this->option(opt_key))->get_at(idx); } const double opt_float(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloats*>(this->option(opt_key))->get_at(idx); }
int& opt_int(const t_config_option_key &opt_key) { return dynamic_cast<ConfigOptionInt*>(this->option(opt_key))->value; } int& opt_int(const t_config_option_key &opt_key) { return this->option<ConfigOptionInt>(opt_key)->value; }
const int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionInt*>(this->option(opt_key))->value; } const int opt_int(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionInt*>(this->option(opt_key))->value; }
int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return dynamic_cast<ConfigOptionInts*>(this->option(opt_key))->get_at(idx); } int& opt_int(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionInts>(opt_key)->get_at(idx); }
const int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); } const int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
bool opt_bool(const t_config_option_key &opt_key) const { return dynamic_cast<const ConfigOptionBool*>(this->option(opt_key))->value != 0; } bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionBools*>(this->option(opt_key))->get_at(idx) != 0; } bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
protected: protected:
DynamicConfig() {} DynamicConfig() {}

View File

@ -149,7 +149,6 @@ inline Polylines to_polylines(const ExPolygons &src)
return polylines; return polylines;
} }
#if SLIC3R_CPPVER >= 11
inline Polylines to_polylines(ExPolygon &&src) inline Polylines to_polylines(ExPolygon &&src)
{ {
Polylines polylines; Polylines polylines;
@ -166,6 +165,7 @@ inline Polylines to_polylines(ExPolygon &&src)
assert(idx == polylines.size()); assert(idx == polylines.size());
return polylines; return polylines;
} }
inline Polylines to_polylines(ExPolygons &&src) inline Polylines to_polylines(ExPolygons &&src)
{ {
Polylines polylines; Polylines polylines;
@ -184,7 +184,6 @@ inline Polylines to_polylines(ExPolygons &&src)
assert(idx == polylines.size()); assert(idx == polylines.size());
return polylines; return polylines;
} }
#endif
inline Polygons to_polygons(const ExPolygon &src) inline Polygons to_polygons(const ExPolygon &src)
{ {

View File

@ -176,11 +176,7 @@ void Fill3DHoneycomb::_fill_surface_single(
} }
} }
Polylines chained = PolylineCollection::chained_path_from( Polylines chained = PolylineCollection::chained_path_from(
#if SLIC3R_CPPVER >= 11
std::move(polylines), std::move(polylines),
#else
polylines,
#endif
PolylineCollection::leftmost_point(polylines), false); // reverse allowed PolylineCollection::leftmost_point(polylines), false); // reverse allowed
bool first = true; bool first = true;
for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) { for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) {
@ -199,12 +195,7 @@ void Fill3DHoneycomb::_fill_surface_single(
} }
} }
// The lines cannot be connected. // The lines cannot be connected.
#if SLIC3R_CPPVER >= 11 polylines_out.emplace_back(std::move(*it_polyline));
polylines_out.push_back(std::move(*it_polyline));
#else
polylines_out.push_back(Polyline());
std::swap(polylines_out.back(), *it_polyline);
#endif
first = false; first = false;
} }
} }

View File

@ -17,12 +17,7 @@ void FillHoneycomb::_fill_surface_single(
CacheID cache_id(params.density, this->spacing); CacheID cache_id(params.density, this->spacing);
Cache::iterator it_m = this->cache.find(cache_id); Cache::iterator it_m = this->cache.find(cache_id);
if (it_m == this->cache.end()) { if (it_m == this->cache.end()) {
#if 0
// #if SLIC3R_CPPVER > 11
it_m = this->cache.emplace_hint(it_m);
#else
it_m = this->cache.insert(it_m, std::pair<CacheID, CacheData>(cache_id, CacheData())); it_m = this->cache.insert(it_m, std::pair<CacheID, CacheData>(cache_id, CacheData()));
#endif
CacheData &m = it_m->second; CacheData &m = it_m->second;
coord_t min_spacing = scale_(this->spacing); coord_t min_spacing = scale_(this->spacing);
m.distance = min_spacing / params.density; m.distance = min_spacing / params.density;
@ -99,11 +94,7 @@ void FillHoneycomb::_fill_surface_single(
// connect paths // connect paths
if (! paths.empty()) { // prevent calling leftmost_point() on empty collections if (! paths.empty()) { // prevent calling leftmost_point() on empty collections
Polylines chained = PolylineCollection::chained_path_from( Polylines chained = PolylineCollection::chained_path_from(
#if SLIC3R_CPPVER >= 11
std::move(paths), std::move(paths),
#else
paths,
#endif
PolylineCollection::leftmost_point(paths), false); PolylineCollection::leftmost_point(paths), false);
assert(paths.empty()); assert(paths.empty());
paths.clear(); paths.clear();

View File

@ -93,11 +93,7 @@ void FillRectilinear::_fill_surface_single(
} }
} }
Polylines chained = PolylineCollection::chained_path_from( Polylines chained = PolylineCollection::chained_path_from(
#if SLIC3R_CPPVER >= 11
std::move(polylines), std::move(polylines),
#else
polylines,
#endif
PolylineCollection::leftmost_point(polylines), false); // reverse allowed PolylineCollection::leftmost_point(polylines), false); // reverse allowed
bool first = true; bool first = true;
for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) { for (Polylines::iterator it_polyline = chained.begin(); it_polyline != chained.end(); ++ it_polyline) {
@ -118,12 +114,7 @@ void FillRectilinear::_fill_surface_single(
} }
} }
// The lines cannot be connected. // The lines cannot be connected.
#if SLIC3R_CPPVER >= 11 polylines_out.emplace_back(std::move(*it_polyline));
polylines_out.push_back(std::move(*it_polyline));
#else
polylines_out.push_back(Polyline());
std::swap(polylines_out.back(), *it_polyline);
#endif
first = false; first = false;
} }
} }

View File

@ -8,39 +8,6 @@ namespace Slic3r {
// This static method returns a sane extrusion width default. // This static method returns a sane extrusion width default.
static inline float auto_extrusion_width(FlowRole role, float nozzle_diameter, float height) static inline float auto_extrusion_width(FlowRole role, float nozzle_diameter, float height)
{ {
#if 0
// Here we calculate a sane default by matching the flow speed (at the nozzle) and the feed rate.
// shape: rectangle with semicircles at the ends
// This "sane" extrusion width gives the following results for a 0.4mm dmr nozzle:
// Layer Calculated Calculated width
// heigh extrusion over nozzle
// width diameter
// 0.40 0.40 1.00
// 0.35 0.43 1.09
// 0.30 0.48 1.21
// 0.25 0.56 1.39
// 0.20 0.67 1.68
// 0.15 0.87 2.17
// 0.10 1.28 3.20
// 0.05 2.52 6.31
//
float width = float(0.25 * (nozzle_diameter * nozzle_diameter) * PI / height + height * (1.0 - 0.25 * PI));
switch (role) {
case frExternalPerimeter:
case frSupportMaterial:
case frSupportMaterialInterface:
return nozzle_diameter;
case frPerimeter:
case frSolidInfill:
case frTopSolidInfill:
// do not limit width for sparse infill so that we use full native flow for it
return std::min(std::max(width, nozzle_diameter * 1.05f), nozzle_diameter * 1.7f);
case frInfill:
default:
return std::max(width, nozzle_diameter * 1.05f);
}
#else
switch (role) { switch (role) {
case frSupportMaterial: case frSupportMaterial:
case frSupportMaterialInterface: case frSupportMaterialInterface:
@ -53,7 +20,6 @@ static inline float auto_extrusion_width(FlowRole role, float nozzle_diameter, f
case frInfill: case frInfill:
return 1.125f * nozzle_diameter; return 1.125f * nozzle_diameter;
} }
#endif
} }
// This constructor builds a Flow object from an extrusion width config setting // This constructor builds a Flow object from an extrusion width config setting

View File

@ -154,7 +154,6 @@ inline Polylines to_polylines(const Polygons &polys)
return polylines; return polylines;
} }
#if SLIC3R_CPPVER >= 11
inline Polylines to_polylines(Polygons &&polys) inline Polylines to_polylines(Polygons &&polys)
{ {
Polylines polylines; Polylines polylines;
@ -168,7 +167,6 @@ inline Polylines to_polylines(Polygons &&polys)
assert(idx == polylines.size()); assert(idx == polylines.size());
return polylines; return polylines;
} }
#endif
} // Slic3r } // Slic3r

View File

@ -1,4 +1,4 @@
//#undef NDEBUGc //#undef NDEBUG
#include <cassert> #include <cassert>
#include "PresetBundle.hpp" #include "PresetBundle.hpp"
@ -36,7 +36,7 @@ std::string PresetHints::cooling_description(const Preset &preset)
if (preset.config.opt_bool("fan_always_on", 0)) { if (preset.config.opt_bool("fan_always_on", 0)) {
int disable_fan_first_layers = preset.config.opt_int("disable_fan_first_layers", 0); int disable_fan_first_layers = preset.config.opt_int("disable_fan_first_layers", 0);
int min_fan_speed = preset.config.opt_int("min_fan_speed", 0); int min_fan_speed = preset.config.opt_int("min_fan_speed", 0);
sprintf(buf, "will always run at %d% ", min_fan_speed); sprintf(buf, "will always run at %d%% ", min_fan_speed);
out += buf; out += buf;
if (disable_fan_first_layers > 1) { if (disable_fan_first_layers > 1) {
sprintf(buf, "except for the first %d layers", disable_fan_first_layers); sprintf(buf, "except for the first %d layers", disable_fan_first_layers);
@ -50,26 +50,37 @@ std::string PresetHints::cooling_description(const Preset &preset)
return out; return out;
} }
static const ConfigOptionFloatOrPercent& first_positive(const ConfigOptionFloatOrPercent *v1, const ConfigOptionFloatOrPercent &v2, const ConfigOptionFloatOrPercent &v3)
{
return (v1 != nullptr && v1->value > 0) ? *v1 : ((v2.value > 0) ? v2 : v3);
}
static double first_positive(double v1, double v2)
{
return (v1 > 0.) ? v1 : v2;
}
std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle &preset_bundle) std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle &preset_bundle)
{ {
// Find out, to which nozzle index is the current filament profile assigned. // Find out, to which nozzle index is the current filament profile assigned.
unsigned int idx_nozzle = 0; int idx_extruder = 0;
for (; idx_nozzle < (unsigned int)preset_bundle.filaments.size(); ++ idx_nozzle) int num_extruders = (int)preset_bundle.filament_presets.size();
if (preset_bundle.filament_presets[idx_nozzle] == preset_bundle.filaments.get_selected_preset().name) for (; idx_extruder < num_extruders; ++ idx_extruder)
if (preset_bundle.filament_presets[idx_extruder] == preset_bundle.filaments.get_selected_preset().name)
break; break;
if (idx_nozzle == (unsigned int)preset_bundle.filaments.size()) if (idx_extruder == num_extruders)
// The current filament preset is not active for any extruder. // The current filament preset is not active for any extruder.
idx_nozzle = (unsigned int)-1; idx_extruder = -1;
const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config; const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config;
const DynamicPrintConfig &filament_config = preset_bundle.filaments.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 &printer_config = preset_bundle.printers .get_edited_preset().config;
// Current printer values. // Current printer values.
double nozzle_diameter = printer_config.opt_float("nozzle_diameter", idx_nozzle); float nozzle_diameter = (float)printer_config.opt_float("nozzle_diameter", idx_extruder);
// Print config values // Print config values
double layer_height = print_config.get_abs_value("layer_height", nozzle_diameter); double layer_height = print_config.opt_float("layer_height");
double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height); double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height);
double support_material_speed = print_config.opt_float("support_material_speed"); double support_material_speed = print_config.opt_float("support_material_speed");
double support_material_interface_speed = print_config.get_abs_value("support_material_interface_speed", support_material_speed); double support_material_interface_speed = print_config.get_abs_value("support_material_interface_speed", support_material_speed);
@ -87,168 +98,132 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
// Maximum volumetric speed allowed for the print profile. // Maximum volumetric speed allowed for the print profile.
double max_volumetric_speed = print_config.opt_float("max_volumetric_speed"); double max_volumetric_speed = print_config.opt_float("max_volumetric_speed");
const auto &extrusion_width = print_config.get_abs_value("extrusion_width"); const auto &extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("extrusion_width");
const auto &support_material_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("support_material_extrusion_width");
const auto &external_perimeter_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width"); const auto &external_perimeter_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width");
const auto &infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("infill_extrusion_width");
const auto &solid_infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("solid_infill_extrusion_width");
const auto &perimeter_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("perimeter_extrusion_width");
const auto &top_infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("top_infill_extrusion_width");
const auto &first_layer_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("first_layer_extrusion_width"); const auto &first_layer_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("first_layer_extrusion_width");
const auto &infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("infill_extrusion_width");
const auto &perimeter_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("perimeter_extrusion_width");
const auto &solid_infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("solid_infill_extrusion_width");
const auto &support_material_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("support_material_extrusion_width");
const auto &top_infill_extrusion_width = *print_config.option<ConfigOptionFloatOrPercent>("top_infill_extrusion_width");
int perimeter_extruder = print_config.opt_int("perimeter_extruder"); // Index of an extruder assigned to a feature. If set to 0, an active extruder will be used for a multi-material print.
int infill_extruder = print_config.opt_int("infill_extruder"); // If different from idx_extruder, it will not be taken into account for this hint.
int solid_infill_extruder = print_config.opt_int("solid_infill_extruder"); auto feature_extruder_active = [idx_extruder, num_extruders](int i) {
int support_material_extruder = print_config.opt_int("support_material_extruder"); return i <= 0 || i > num_extruders || idx_extruder == -1 || idx_extruder == i - 1;
int support_material_interface_extruder = print_config.opt_int("support_material_interface_extruder"); };
bool perimeter_extruder_active = feature_extruder_active(print_config.opt_int("perimeter_extruder"));
bool infill_extruder_active = feature_extruder_active(print_config.opt_int("infill_extruder"));
bool solid_infill_extruder_active = feature_extruder_active(print_config.opt_int("solid_infill_extruder"));
bool support_material_extruder_active = feature_extruder_active(print_config.opt_int("support_material_extruder"));
bool support_material_interface_extruder_active = feature_extruder_active(print_config.opt_int("support_material_interface_extruder"));
// Current filament values // Current filament values
double filament_diameter = filament_config.opt_float("filament_diameter", 0); double filament_diameter = filament_config.opt_float("filament_diameter", 0);
double filament_crossection = M_PI * 0.25 * filament_diameter * filament_diameter;
double extrusion_multiplier = filament_config.opt_float("extrusion_multiplier", 0); double extrusion_multiplier = filament_config.opt_float("extrusion_multiplier", 0);
double filament_max_volumetric_speed = filament_config.opt_float("filament_max_volumetric_speed", 0); // The following value will be annotated by this hint, so it does not take part in the calculation.
// double filament_max_volumetric_speed = filament_config.opt_float("filament_max_volumetric_speed", 0);
auto external_perimeter_flow = Flow::new_from_config_width(frExternalPerimeter, external_perimeter_extrusion_width, (float)nozzle_diameter, (float)layer_height, 0);
auto perimeter_flow = Flow::new_from_config_width(frPerimeter, perimeter_extrusion_width, (float)nozzle_diameter, (float)layer_height, 0);
auto infill_flow = Flow::new_from_config_width(frInfill, infill_extrusion_width, (float)nozzle_diameter, (float)layer_height, 0);
auto solid_infill_flow = Flow::new_from_config_width(frInfill, solid_infill_extrusion_width, (float)nozzle_diameter, (float)layer_height, 0);
auto top_solid_infill_flow = Flow::new_from_config_width(frInfill, top_infill_extrusion_width, (float)nozzle_diameter, (float)layer_height, 0);
// auto support_material_flow = Flow::new_from_config_width(frSupportMaterial, ,
// (float)nozzle_diameter, (float)layer_height, 0);
auto support_material_interface_flow = Flow::new_from_config_width(frSupportMaterialInterface, *print_config.option<ConfigOptionFloatOrPercent>("support_material_extrusion_width"),
(float)nozzle_diameter, (float)layer_height, 0);
std::string out; std::string out;
out="Hu"; for (size_t idx_type = (first_layer_extrusion_width.value == 0) ? 1 : 0; idx_type < 3; ++ idx_type) {
return out; // First test the maximum volumetric extrusion speed for non-bridging extrusions.
} bool first_layer = idx_type == 0;
bool bridging = idx_type == 2;
#if 0 const ConfigOptionFloatOrPercent *first_layer_extrusion_width_ptr = (first_layer && first_layer_extrusion_width.value > 0) ?
static create_flow(FlowRole role, ConfigOptionFloatOrPercent &width, double layer_height, bool bridge, bool first_layer, double width) const &first_layer_extrusion_width : nullptr;
{ const float lh = float(first_layer ? first_layer_height : layer_height);
ConfigOptionFloatOrPercent config_width; const float bfr = bridging ? bridge_flow_ratio : 0.f;
if (width != -1) { double max_flow = 0.;
// use the supplied custom width, if any std::string max_flow_extrusion_type;
config_width.value = width; if (perimeter_extruder_active) {
config_width.percent = false; double external_perimeter_rate = Flow::new_from_config_width(frExternalPerimeter,
} else { first_positive(first_layer_extrusion_width_ptr, external_perimeter_extrusion_width, extrusion_width),
// otherwise, get extrusion width from configuration nozzle_diameter, lh, bfr).mm3_per_mm() *
// (might be an absolute value, or a percent value, or zero for auto) (bridging ? bridge_speed :
if (first_layer && this->_print->config.first_layer_extrusion_width.value > 0) { first_positive(std::max(external_perimeter_speed, small_perimeter_speed), max_print_speed));
config_width = this->_print->config.first_layer_extrusion_width; if (max_flow < external_perimeter_rate) {
} else if (role == frExternalPerimeter) { max_flow = external_perimeter_rate;
config_width = this->config.external_perimeter_extrusion_width; max_flow_extrusion_type = "external perimeters";
} else if (role == frPerimeter) { }
config_width = this->config.perimeter_extrusion_width; double perimeter_rate = Flow::new_from_config_width(frPerimeter,
} else if (role == frInfill) { first_positive(first_layer_extrusion_width_ptr, perimeter_extrusion_width, extrusion_width),
config_width = this->config.infill_extrusion_width; nozzle_diameter, lh, bfr).mm3_per_mm() *
} else if (role == frSolidInfill) { (bridging ? bridge_speed :
config_width = this->config.solid_infill_extrusion_width; first_positive(std::max(perimeter_speed, small_perimeter_speed), max_print_speed));
} else if (role == frTopSolidInfill) { if (max_flow < perimeter_rate) {
config_width = this->config.top_infill_extrusion_width; max_flow = perimeter_rate;
} else { max_flow_extrusion_type = "perimeters";
CONFESS("Unknown role"); }
} }
} if (! bridging && infill_extruder_active) {
if (config_width.value == 0) { double infill_rate = Flow::new_from_config_width(frInfill,
config_width = object.config.extrusion_width; first_positive(first_layer_extrusion_width_ptr, infill_extrusion_width, extrusion_width),
nozzle_diameter, lh, bfr).mm3_per_mm() * first_positive(infill_speed, max_print_speed);
if (max_flow < infill_rate) {
max_flow = infill_rate;
max_flow_extrusion_type = "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() *
(bridging ? bridge_speed : first_positive(solid_infill_speed, max_print_speed));
if (max_flow < solid_infill_rate) {
max_flow = solid_infill_rate;
max_flow_extrusion_type = "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() * first_positive(top_solid_infill_speed, max_print_speed);
if (max_flow < top_solid_infill_rate) {
max_flow = top_solid_infill_rate;
max_flow_extrusion_type = "top solid infill";
}
}
}
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() *
(bridging ? bridge_speed : first_positive(support_material_speed, max_print_speed));
if (max_flow < support_material_rate) {
max_flow = support_material_rate;
max_flow_extrusion_type = "support";
}
}
if (support_material_interface_extruder_active) {
double support_material_interface_rate = 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() *
(bridging ? bridge_speed : first_positive(support_material_interface_speed, max_print_speed));
if (max_flow < support_material_interface_rate) {
max_flow = support_material_interface_rate;
max_flow_extrusion_type = "support interface";
}
}
//FIXME handle gap_fill_speed
if (! out.empty())
out += "\n";
out += (first_layer ? "First layer volumetric" : (bridging ? "Bridging volumetric" : "Volumetric"));
out += " flow rate is maximized ";
out += ((max_volumetric_speed > 0 && max_volumetric_speed < max_flow) ?
"by the print profile maximum" :
("when printing " + max_flow_extrusion_type))
+ " with a volumetric rate ";
if (max_volumetric_speed > 0 && max_volumetric_speed < max_flow)
max_flow = max_volumetric_speed;
char buf[2048];
sprintf(buf, "%3.2f mm³/s", max_flow);
out += buf;
sprintf(buf, " at filament speed %3.2f mm/s.", max_flow / filament_crossection);
out += buf;
} }
// get the configured nozzle_diameter for the extruder associated return out;
// to the flow role requested
size_t extruder = 0; // 1-based
if (role == frPerimeter || role == frExternalPerimeter) {
extruder = this->config.perimeter_extruder;
} else if (role == frInfill) {
extruder = this->config.infill_extruder;
} else if (role == frSolidInfill || role == frTopSolidInfill) {
extruder = this->config.solid_infill_extruder;
} else {
CONFESS("Unknown role $role");
}
double nozzle_diameter = this->_print->config.nozzle_diameter.get_at(extruder-1);
return Flow::new_from_config_width(role, config_width, nozzle_diameter, layer_height, bridge ? (float)this->config.bridge_flow_ratio : 0.0);
} }
if (first_layer && this->_print->config.first_layer_extrusion_width.value > 0) {
config_width = this->_print->config.first_layer_extrusion_width;
auto flow = Flow::new_from_config_width(frExternalPerimeter, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio);
Flow Print::skirt_flow() const
{
ConfigOptionFloatOrPercent width = this->config.first_layer_extrusion_width;
if (width.value == 0) width = this->regions.front()->config.perimeter_extrusion_width;
/* We currently use a random object's support material extruder.
While this works for most cases, we should probably consider all of the support material
extruders and take the one with, say, the smallest index;
The same logic should be applied to the code that selects the extruder during G-code
generation as well. */
return Flow::new_from_config_width(
frPerimeter,
width,
this->config.nozzle_diameter.get_at(this->objects.front()->config.support_material_extruder-1),
this->skirt_first_layer_height(),
0
);
}
Flow Print::brim_flow() const
{
ConfigOptionFloatOrPercent width = this->config.first_layer_extrusion_width;
if (width.value == 0) width = this->regions.front()->config.perimeter_extrusion_width;
/* We currently use a random region's perimeter extruder.
While this works for most cases, we should probably consider all of the perimeter
extruders and take the one with, say, the smallest index.
The same logic should be applied to the code that selects the extruder during G-code
generation as well. */
return Flow::new_from_config_width(
frPerimeter,
width,
this->config.nozzle_diameter.get_at(this->regions.front()->config.perimeter_extruder-1),
this->skirt_first_layer_height(),
0
);
}
Flow support_material_flow(const PrintObject *object, float layer_height)
{
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.
(support_material_extrusion_width.value > 0) ? support_material_extrusion_width : 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(nozzle_diameter.get_at(support_material_extruder-1)),
(layer_height > 0.f) ? layer_height : float(layer_height.value),
false);
}
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
{
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.
(first_layer_extrusion_width.value > 0) ? first_layer_extrusion_width : support_material_extrusion_width,
float(nozzle_diameter.get_at(object->config.support_material_extruder-1)),
(layer_height > 0.f) ? layer_height : float(first_layer_height)),
false);
}
Flow support_material_interface_flow(const PrintObject *object, float layer_height)
{
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.
(support_material_extrusion_width > 0) ? support_material_extrusion_width : 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(nozzle_diameter.get_at(object->config.support_material_interface_extruder-1)),
layer_height,
false);
}
#endif
}; // namespace Slic3r }; // namespace Slic3r

View File

@ -226,6 +226,8 @@ PresetCollection* O_OBJECT_SLIC3R
Ref<PresetCollection> O_OBJECT_SLIC3R_T Ref<PresetCollection> O_OBJECT_SLIC3R_T
PresetBundle* O_OBJECT_SLIC3R PresetBundle* O_OBJECT_SLIC3R
Ref<PresetBundle> O_OBJECT_SLIC3R_T Ref<PresetBundle> O_OBJECT_SLIC3R_T
PresetHints* O_OBJECT_SLIC3R
Ref<PresetHints> O_OBJECT_SLIC3R_T
Axis T_UV Axis T_UV
ExtrusionLoopRole T_UV ExtrusionLoopRole T_UV

View File

@ -205,6 +205,8 @@
%typemap{Ref<PresetCollection>}{simple}; %typemap{Ref<PresetCollection>}{simple};
%typemap{PresetBundle*}; %typemap{PresetBundle*};
%typemap{Ref<PresetBundle>}{simple}; %typemap{Ref<PresetBundle>}{simple};
%typemap{PresetHints*};
%typemap{Ref<PresetHints>}{simple};
%typemap{PrintRegionPtrs*}; %typemap{PrintRegionPtrs*};
%typemap{PrintObjectPtrs*}; %typemap{PrintObjectPtrs*};