Implemented volumetric flow rate hints,
removed some C++11 conditioned compilation. Slic3r now requires C++11.
This commit is contained in:
parent
9a0100d6de
commit
b23b9ea1d2
@ -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() {}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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*};
|
||||||
|
Loading…
Reference in New Issue
Block a user