mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 10:51:22 +00:00
Add nozzle flow variant & make some options multi-variant (#13712)
# Description Port BBS per-extruder config variants toggle, thanks Bambu! Also fix invalid num error when resetting multi-variant filament overrides. TODOs: - [x] Make more configs multi-variant (such as speeds) - [x] Add flow variant (normal/high flow) combo box - [x] Add botton to sync config to other variant # Screenshots/Recordings/Graphs <img width="846" height="1494" alt="image" src="https://github.com/user-attachments/assets/47abf053-f5b8-4c86-ac0b-c0323ed8b242" /> <img width="1478" height="1189" alt="707420e5be01c30af3e6ede1f3dc9b67" src="https://github.com/user-attachments/assets/11268712-da65-42ab-9cb8-3cede7790a5c" /> <img width="1478" height="1189" alt="81d5d3877f4d5bf9dccd44d7f0b30aa7" src="https://github.com/user-attachments/assets/cda5ea51-07c3-48fc-bfbb-1428dca14e26" /> ## Tests <!-- > Please describe the tests that you have conducted to verify the changes made in this PR. --> <!-- > A guide for users on how to download the artifacts from this PR. --> [How to Download Pull Requests Artifacts for Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts) Fix #10336
This commit is contained in:
@@ -685,6 +685,32 @@ bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, con
|
||||
return success;
|
||||
}
|
||||
|
||||
double ConfigBase::get_abs_value_at(const t_config_option_key &opt_key, size_t index) const
|
||||
{
|
||||
const ConfigOption *raw_opt = this->option(opt_key);
|
||||
assert(raw_opt != nullptr);
|
||||
if (raw_opt->type() == coFloats) {
|
||||
return static_cast<const ConfigOptionFloats*>(raw_opt)->get_at(index);
|
||||
}
|
||||
if (raw_opt->type() == coFloatsOrPercents) {
|
||||
const ConfigDef *def = this->def();
|
||||
if (def == nullptr) throw NoDefinitionException(opt_key);
|
||||
const ConfigOptionDef *opt_def = def->get(opt_key);
|
||||
assert(opt_def != nullptr);
|
||||
|
||||
if (opt_def->ratio_over.empty()) {
|
||||
return 0;
|
||||
} else {
|
||||
const ConfigOption *ratio_opt = this->option(opt_def->ratio_over);
|
||||
assert(ratio_opt->type() == coFloats);
|
||||
const ConfigOptionFloats *ratio_values = static_cast<const ConfigOptionFloats *>(ratio_opt);
|
||||
return static_cast<const ConfigOptionFloatsOrPercents *>(raw_opt)->get_at(index).get_abs_value(ratio_values->get_at(index));
|
||||
}
|
||||
}
|
||||
|
||||
throw ConfigurationError("ConfigBase::get_abs_value_at(): Not a valid option type for get_abs_value_at()");
|
||||
}
|
||||
|
||||
// Return an absolute value of a possibly relative config variable.
|
||||
// For example, return absolute infill extrusion width, either from an absolute value, or relative to the layer height.
|
||||
double ConfigBase::get_abs_value(const t_config_option_key &opt_key) const
|
||||
@@ -1886,6 +1912,39 @@ t_config_option_keys DynamicConfig::equal(const DynamicConfig &other) const
|
||||
return equal;
|
||||
}
|
||||
|
||||
double& DynamicConfig::opt_float(const t_config_option_key &opt_key, unsigned int idx)
|
||||
{
|
||||
if (ConfigOptionFloats *opt_floats = dynamic_cast<ConfigOptionFloats *>(this->option(opt_key))) {
|
||||
return opt_floats->get_at(idx);
|
||||
} else {
|
||||
ConfigOptionFloatsNullable *opt_floats_nullable = dynamic_cast<ConfigOptionFloatsNullable *>(this->option(opt_key));
|
||||
assert(opt_floats_nullable != nullptr);
|
||||
return opt_floats_nullable->get_at(idx);
|
||||
}
|
||||
}
|
||||
const double& DynamicConfig::opt_float(const t_config_option_key &opt_key, unsigned int idx) const
|
||||
{
|
||||
if (const ConfigOptionFloats *opt_floats = dynamic_cast<const ConfigOptionFloats *>(this->option(opt_key))) {
|
||||
return opt_floats->get_at(idx);
|
||||
} else if (const ConfigOptionFloatsNullable *opt_floats_nullable = dynamic_cast<const ConfigOptionFloatsNullable *>(this->option(opt_key))) {
|
||||
return opt_floats_nullable->get_at(idx);
|
||||
} else {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicConfig::opt_bool(const t_config_option_key &opt_key, unsigned int idx) const {
|
||||
if (const ConfigOptionBools *opts = dynamic_cast<const ConfigOptionBools *>(this->option(opt_key))) {
|
||||
return opts->get_at(idx) != 0;
|
||||
}
|
||||
else {
|
||||
const ConfigOptionBoolsNullable *opt_s = dynamic_cast<const ConfigOptionBoolsNullable *>(this->option(opt_key));
|
||||
assert(opt_s != nullptr);
|
||||
return opt_s->get_at(idx) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <cereal/types/polymorphic.hpp>
|
||||
|
||||
@@ -30,8 +30,14 @@
|
||||
namespace Slic3r {
|
||||
struct FloatOrPercent
|
||||
{
|
||||
double value;
|
||||
bool percent;
|
||||
double value = 0;
|
||||
bool percent = false;
|
||||
|
||||
FloatOrPercent() {}
|
||||
FloatOrPercent(double value_, bool percent_) : value(value_), percent(percent_) { }
|
||||
|
||||
double get_abs_value(double ratio_over) const { return this->percent ? (ratio_over * this->value / 100) : this->value; }
|
||||
|
||||
private:
|
||||
friend class cereal::access;
|
||||
template<class Archive> void serialize(Archive& ar) { ar(this->value); ar(this->percent); }
|
||||
@@ -2726,6 +2732,7 @@ public:
|
||||
void set_deserialize_strict(std::initializer_list<SetDeserializeItem> items)
|
||||
{ ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Disable }; this->set_deserialize(items, ctxt); }
|
||||
|
||||
double get_abs_value_at(const t_config_option_key &opt_key, size_t index) const;
|
||||
double get_abs_value(const t_config_option_key &opt_key) const;
|
||||
double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const;
|
||||
void setenv_() const;
|
||||
@@ -2900,13 +2907,17 @@ public:
|
||||
|
||||
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; }
|
||||
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); }
|
||||
double & opt_float(const t_config_option_key &opt_key, unsigned int idx);
|
||||
const double & opt_float(const t_config_option_key &opt_key, unsigned int idx) const;
|
||||
double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionFloatsNullable>(opt_key)->get_at(idx); }
|
||||
const double & opt_float_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionFloatsNullable *>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
int& opt_int(const t_config_option_key &opt_key) { return this->option<ConfigOptionInt>(opt_key)->value; }
|
||||
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 this->option<ConfigOptionInts>(opt_key)->get_at(idx); }
|
||||
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); }
|
||||
int& opt_int_nullable(const t_config_option_key &opt_key, unsigned int idx) { return this->option<ConfigOptionIntsNullable>(opt_key)->get_at(idx);}
|
||||
const int & opt_int_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionIntsNullable*>(this->option(opt_key))->get_at(idx);}
|
||||
|
||||
// In ConfigManipulation::toggle_print_fff_options, it is called on option with type ConfigOptionEnumGeneric* and also ConfigOptionEnum*.
|
||||
// Thus the virtual method getInt() is used to retrieve the enum value.
|
||||
@@ -2914,9 +2925,13 @@ public:
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return static_cast<ENUM>(this->option(opt_key)->getInt()); }
|
||||
// BBS
|
||||
int opt_enum(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionEnumsGeneric*>(this->option(opt_key))->get_at(idx); }
|
||||
int opt_enum_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionEnumsGenericNullable*>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
|
||||
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 this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const;
|
||||
bool opt_bool_nullable(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionBoolsNullable*>(this->option(opt_key))->get_at(idx);}
|
||||
|
||||
|
||||
// Command line processing
|
||||
bool read_cli(int argc, const char* const argv[], t_config_option_keys* extra, t_config_option_keys* keys = nullptr);
|
||||
|
||||
@@ -960,15 +960,15 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
|
||||
|
||||
params.role_speed = 0;
|
||||
if (params.extrusion_role == erBridgeInfill)
|
||||
params.role_speed = region_config.bridge_speed;
|
||||
params.role_speed = region_config.bridge_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erInternalBridgeInfill)
|
||||
params.role_speed = region_config.get_abs_value("internal_bridge_speed");
|
||||
params.role_speed = region_config.get_abs_value_at("internal_bridge_speed", layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erInternalInfill)
|
||||
params.role_speed = region_config.sparse_infill_speed;
|
||||
params.role_speed = region_config.sparse_infill_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erTopSolidInfill)
|
||||
params.role_speed = region_config.top_surface_speed;
|
||||
params.role_speed = region_config.top_surface_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
else if (params.extrusion_role == erSolidInfill)
|
||||
params.role_speed = region_config.internal_solid_infill_speed;
|
||||
params.role_speed = region_config.internal_solid_infill_speed.get_at(layer.get_extruder_id(params.extruder));
|
||||
// Calculate flow spacing for infill pattern generation.
|
||||
if (surface.is_solid() || is_bridge) {
|
||||
params.spacing = params.flow.spacing();
|
||||
|
||||
+175
-142
@@ -337,7 +337,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
if(retraction_length_remaining <=EPSILON) return {retractionBeforeWipe,0.f};
|
||||
|
||||
// Calculate wipe speed
|
||||
double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed");
|
||||
double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.cur_extruder_index()));
|
||||
wipe_speed = std::max(wipe_speed, 10.0);
|
||||
|
||||
// Process wipe path & calculate wipe path length
|
||||
@@ -429,7 +429,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
|
||||
/* Reduce feedrate a bit; travel speed is often too high to move on existing material.
|
||||
Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */
|
||||
double _wipe_speed = gcodegen.config().get_abs_value("wipe_speed");// gcodegen.writer().config.travel_speed.value * 0.8;
|
||||
double _wipe_speed = gcodegen.config().get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.cur_extruder_index()));// gcodegen.writer().config.travel_speed.value * 0.8;
|
||||
if(gcodegen.config().role_based_wipe_speed)
|
||||
_wipe_speed = gcodegen.writer().get_current_speed() / 60.0;
|
||||
if(_wipe_speed < 10)
|
||||
@@ -515,7 +515,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
outer_wall_line_width = default_line_width == 0.0 ? filament_diameter : default_line_width;
|
||||
}
|
||||
Flow outer_wall_flow = Flow(outer_wall_line_width, config.layer_height, config.nozzle_diameter.get_at(extruder_id));
|
||||
float outer_wall_speed = print.default_region_config().outer_wall_speed.value;
|
||||
float outer_wall_speed = print.default_region_config().outer_wall_speed.get_at(extruder_id);
|
||||
outer_wall_volumetric_speed = outer_wall_speed * outer_wall_flow.mm3_per_mm();
|
||||
if (outer_wall_volumetric_speed > filament_max_volumetric_speed)
|
||||
outer_wall_volumetric_speed = filament_max_volumetric_speed;
|
||||
@@ -1602,6 +1602,7 @@ static std::vector<Vec2d> get_path_of_change_filament(const Print& print)
|
||||
|
||||
#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.filament()->extruder_id())
|
||||
#define FILAMENT_CONFIG(OPT) m_config.OPT.get_at(m_writer.filament()->id())
|
||||
#define NOZZLE_CONFIG(OPT) m_config.OPT.get_at(cur_extruder_index())
|
||||
|
||||
void GCode::PlaceholderParserIntegration::reset()
|
||||
{
|
||||
@@ -2806,11 +2807,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
|
||||
print.throw_if_canceled();
|
||||
|
||||
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id);
|
||||
|
||||
int extruder_id = get_extruder_id(initial_extruder_id);
|
||||
|
||||
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id, extruder_id);
|
||||
|
||||
// Orca: Initialise AdaptivePA processor filter
|
||||
m_pa_processor = std::make_unique<AdaptivePAProcessor>(*this, tool_ordering.all_extruders());
|
||||
|
||||
@@ -3245,12 +3246,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
if (print.calib_params().mode == CalibMode::Calib_PA_Line) {
|
||||
std::string gcode;
|
||||
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Layer_Change) + "\n";
|
||||
if ((print.default_object_config().outer_wall_acceleration.value > 0 && print.default_object_config().outer_wall_acceleration.value > 0)) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(print.default_object_config().outer_wall_acceleration.value + 0.5));
|
||||
if ((NOZZLE_CONFIG(outer_wall_acceleration) > 0 && NOZZLE_CONFIG(outer_wall_acceleration) > 0)) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(outer_wall_acceleration) + 0.5));
|
||||
}
|
||||
|
||||
if (print.default_object_config().outer_wall_jerk.value > 0) {
|
||||
double jerk = print.default_object_config().outer_wall_jerk.value;
|
||||
if (NOZZLE_CONFIG(outer_wall_jerk) > 0) {
|
||||
double jerk = NOZZLE_CONFIG(outer_wall_jerk);
|
||||
gcode += m_writer.set_jerk_xy(jerk);
|
||||
}
|
||||
|
||||
@@ -3333,8 +3334,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
file.writeln(printing_by_object_gcode);
|
||||
}
|
||||
// Reset the cooling buffer internal state (the current position, feed rate, accelerations).
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id, get_extruder_id(initial_extruder_id));
|
||||
m_cooling_buffer->reset(this->writer().get_position());
|
||||
m_cooling_buffer->set_current_extruder(initial_extruder_id);
|
||||
// Process all layers of a single object instance (sequential mode) with a parallel pipeline:
|
||||
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
|
||||
// and export G-code into file.
|
||||
@@ -3645,6 +3646,13 @@ void GCode::check_placeholder_parser_failed()
|
||||
}
|
||||
}
|
||||
|
||||
size_t GCode::cur_extruder_index() const
|
||||
{
|
||||
//TODO: check if the function is duplicated
|
||||
//just return m_writer.filament()->extruder_id()
|
||||
return get_extruder_id(m_writer.filament()->id());
|
||||
}
|
||||
|
||||
size_t GCode::get_extruder_id(unsigned int filament_id) const
|
||||
{
|
||||
if (m_print) {
|
||||
@@ -3940,51 +3948,75 @@ void GCode::print_machine_envelope(GCodeOutputStream &file, Print &print)
|
||||
const auto flavor = print.config().gcode_flavor.value;
|
||||
if ((flavor == gcfMarlinLegacy || flavor == gcfMarlinFirmware || flavor == gcfRepRapFirmware) &&
|
||||
print.config().emit_machine_limits_to_gcode.value == true) {
|
||||
|
||||
// Get all physical tool ids current print will use
|
||||
std::unordered_set<unsigned int> used_extruders;
|
||||
for (const auto& extruder : m_writer.extruders()) {
|
||||
used_extruders.insert(extruder.extruder_id());
|
||||
}
|
||||
|
||||
// Get the max limit value among used extruders
|
||||
auto get_max_value = [&used_extruders](const std::string key, const ConfigOptionFloats& v) {
|
||||
unsigned int stride = 1;
|
||||
if (printer_options_with_variant_2.count(key) > 0) {
|
||||
stride = 2;
|
||||
}
|
||||
|
||||
double value = std::numeric_limits<double>::lowest();
|
||||
for (unsigned int extruder : used_extruders) {
|
||||
value = std::max(value, v.values[extruder * stride]);
|
||||
}
|
||||
|
||||
assert(value > std::numeric_limits<double>::lowest());
|
||||
return value;
|
||||
};
|
||||
#define MAX_LIMIT(OPT) get_max_value(#OPT, print.config().OPT)
|
||||
|
||||
int factor = flavor == gcfRepRapFirmware ? 60 : 1; // RRF M203 and M566 are in mm/min
|
||||
file.write_format("M201 X%d Y%d Z%d E%d\n",
|
||||
int(print.config().machine_max_acceleration_x.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_y.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_z.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_e.values.front() + 0.5));
|
||||
int(MAX_LIMIT(machine_max_acceleration_x) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_y) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_z) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_e) + 0.5));
|
||||
file.write_format("M203 X%d Y%d Z%d E%d\n",
|
||||
int(print.config().machine_max_speed_x.values.front() * factor + 0.5),
|
||||
int(print.config().machine_max_speed_y.values.front() * factor + 0.5),
|
||||
int(print.config().machine_max_speed_z.values.front() * factor + 0.5),
|
||||
int(print.config().machine_max_speed_e.values.front() * factor + 0.5));
|
||||
int(MAX_LIMIT(machine_max_speed_x) * factor + 0.5),
|
||||
int(MAX_LIMIT(machine_max_speed_y) * factor + 0.5),
|
||||
int(MAX_LIMIT(machine_max_speed_z) * factor + 0.5),
|
||||
int(MAX_LIMIT(machine_max_speed_e) * factor + 0.5));
|
||||
|
||||
// Now M204 - acceleration. This one is quite hairy thanks to how Marlin guys care about
|
||||
// Legacy Marlin should export travel acceleration the same as printing acceleration.
|
||||
// MarlinFirmware has the two separated.
|
||||
int travel_acc = flavor == gcfMarlinLegacy
|
||||
? int(print.config().machine_max_acceleration_extruding.values.front() + 0.5)
|
||||
: int(print.config().machine_max_acceleration_travel.values.front() + 0.5);
|
||||
? int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5)
|
||||
: int(MAX_LIMIT(machine_max_acceleration_travel) + 0.5);
|
||||
if (flavor == gcfRepRapFirmware)
|
||||
file.write_format("M204 P%d T%d ; sets acceleration (P, T), mm/sec^2\n",
|
||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5),
|
||||
travel_acc);
|
||||
else if (flavor == gcfMarlinFirmware)
|
||||
// New Marlin uses M204 P[print] R[retract] T[travel]
|
||||
file.write_format("M204 P%d R%d T%d ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2\n",
|
||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_retracting.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_travel.values.front() + 0.5));
|
||||
int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_retracting) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_travel) + 0.5));
|
||||
else
|
||||
file.write_format("M204 P%d R%d T%d\n",
|
||||
int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_retracting.values.front() + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_extruding) + 0.5),
|
||||
int(MAX_LIMIT(machine_max_acceleration_retracting) + 0.5),
|
||||
travel_acc);
|
||||
|
||||
assert(is_decimal_separator_point());
|
||||
file.write_format(flavor == gcfRepRapFirmware
|
||||
? "M566 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/min\n"
|
||||
: "M205 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/sec\n",
|
||||
print.config().machine_max_jerk_x.values.front() * factor,
|
||||
print.config().machine_max_jerk_y.values.front() * factor,
|
||||
print.config().machine_max_jerk_z.values.front() * factor,
|
||||
print.config().machine_max_jerk_e.values.front() * factor);
|
||||
MAX_LIMIT(machine_max_jerk_x) * factor,
|
||||
MAX_LIMIT(machine_max_jerk_y) * factor,
|
||||
MAX_LIMIT(machine_max_jerk_z) * factor,
|
||||
MAX_LIMIT(machine_max_jerk_e) * factor);
|
||||
|
||||
// New Marlin uses M205 J[mm] for junction deviation (only apply if it is > 0)
|
||||
file.write_format(writer().set_junction_deviation(config().machine_max_junction_deviation.values.front()).c_str());
|
||||
file.write_format(writer().set_junction_deviation(MAX_LIMIT(machine_max_junction_deviation)).c_str());
|
||||
|
||||
// Orca: Override input shaping values
|
||||
if (print.config().input_shaping_emit.value && flavor != gcfMarlinLegacy) {
|
||||
@@ -3997,6 +4029,7 @@ void GCode::print_machine_envelope(GCodeOutputStream &file, Print &print)
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef MAX_LIMIT
|
||||
}
|
||||
|
||||
// BBS
|
||||
@@ -4434,10 +4467,10 @@ std::string GCode::generate_skirt(const Print &print,
|
||||
if (first_layer && i==loops.first) {
|
||||
//set skirt start point location
|
||||
const Point desired_start_point = Skirt::find_start_point(loop, skirt_start_angle);
|
||||
gcode += this->extrude_loop(loop, "skirt", m_config.support_speed.value, {}, &desired_start_point);
|
||||
gcode += this->extrude_loop(loop, "skirt", NOZZLE_CONFIG(support_speed), {}, &desired_start_point);
|
||||
}
|
||||
else
|
||||
gcode += this->extrude_loop(loop, "skirt", m_config.support_speed.value);
|
||||
gcode += this->extrude_loop(loop, "skirt", NOZZLE_CONFIG(support_speed));
|
||||
|
||||
// If we only want a single wall on non-first layers, break now
|
||||
if (!first_layer && print.m_config.single_loop_draft_shield) {
|
||||
@@ -4499,7 +4532,7 @@ std::string GCode::generate_object_brim(const Print &print, const PrintObject &o
|
||||
m_avoid_crossing_perimeters.use_external_mp();
|
||||
for (const ExtrusionEntity* ee : brim.entities)
|
||||
if (ee != nullptr)
|
||||
gcode += this->extrude_entity(*ee, "brim", m_config.support_speed.value);
|
||||
gcode += this->extrude_entity(*ee, "brim", NOZZLE_CONFIG(support_speed));
|
||||
m_avoid_crossing_perimeters.use_external_mp(false);
|
||||
m_avoid_crossing_perimeters.disable_once();
|
||||
for (ObjectID object_id : object_ids)
|
||||
@@ -4698,12 +4731,12 @@ LayerResult GCode::process_layer(
|
||||
}
|
||||
case CalibMode::Calib_VFA_Tower: {
|
||||
auto _speed = print.calib_params().start + std::floor(print_z / 5.0) * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({std::round(_speed)}));
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_Vol_speed_Tower: {
|
||||
auto _speed = print.calib_params().start + print_z * print.calib_params().step;
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloat(std::round(_speed)));
|
||||
m_calib_config.set_key_value("outer_wall_speed", new ConfigOptionFloatsNullable({std::round(_speed)}));
|
||||
break;
|
||||
}
|
||||
case CalibMode::Calib_Retraction_tower: {
|
||||
@@ -4760,16 +4793,16 @@ LayerResult GCode::process_layer(
|
||||
//BBS
|
||||
if (first_layer) {
|
||||
// Orca: we don't need to optimize the Klipper as only set once
|
||||
if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.initial_layer_acceleration.value + 0.5));
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0 && NOZZLE_CONFIG(initial_layer_acceleration) > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int)floor(NOZZLE_CONFIG(initial_layer_acceleration) + 0.5));
|
||||
}
|
||||
|
||||
if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) {
|
||||
gcode += m_writer.set_jerk_xy(m_config.initial_layer_jerk.value);
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0 && NOZZLE_CONFIG(initial_layer_jerk) > 0) {
|
||||
gcode += m_writer.set_jerk_xy(NOZZLE_CONFIG(initial_layer_jerk));
|
||||
}
|
||||
|
||||
if (m_writer.get_gcode_flavor() == gcfMarlinFirmware && m_config.default_junction_deviation.value > 0) {
|
||||
gcode += m_writer.set_junction_deviation(m_config.default_junction_deviation.value);
|
||||
if (m_writer.get_gcode_flavor() == gcfMarlinFirmware && NOZZLE_CONFIG(default_junction_deviation) > 0) {
|
||||
gcode += m_writer.set_junction_deviation(NOZZLE_CONFIG(default_junction_deviation));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4790,12 +4823,12 @@ LayerResult GCode::process_layer(
|
||||
}
|
||||
// Reset acceleration at sencond layer
|
||||
// Orca: only set once, don't need to call set_accel_and_jerk
|
||||
if (m_config.default_acceleration.value > 0 && m_config.initial_layer_acceleration.value > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int) floor(m_config.default_acceleration.value + 0.5));
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0 && NOZZLE_CONFIG(initial_layer_acceleration) > 0) {
|
||||
gcode += m_writer.set_print_acceleration((unsigned int) floor(NOZZLE_CONFIG(default_acceleration) + 0.5));
|
||||
}
|
||||
|
||||
if (m_config.default_jerk.value > 0 && m_config.initial_layer_jerk.value > 0) {
|
||||
gcode += m_writer.set_jerk_xy(m_config.default_jerk.value);
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0 && NOZZLE_CONFIG(initial_layer_jerk) > 0) {
|
||||
gcode += m_writer.set_jerk_xy(NOZZLE_CONFIG(default_jerk));
|
||||
}
|
||||
|
||||
// Transition from 1st to 2nd layer. Adjust nozzle temperatures as prescribed by the nozzle dependent
|
||||
@@ -4850,8 +4883,8 @@ LayerResult GCode::process_layer(
|
||||
for (const auto &layer_to_print : layers) {
|
||||
if (layer_to_print.object_layer) {
|
||||
const auto& regions = layer_to_print.object_layer->regions();
|
||||
const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [](const LayerRegion* r) {
|
||||
return r->has_extrusions() && r->region().config().enable_overhang_speed;
|
||||
const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [this](const LayerRegion* r) {
|
||||
return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(cur_extruder_index());
|
||||
});
|
||||
if (enable_overhang_speed) {
|
||||
m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.original_object,
|
||||
@@ -5391,7 +5424,7 @@ LayerResult GCode::process_layer(
|
||||
this->set_origin(0., 0.);
|
||||
m_avoid_crossing_perimeters.use_external_mp();
|
||||
for (const ExtrusionEntity* ee : print.m_supportBrimMap.at(instance_to_print.print_object.id()).entities) {
|
||||
gcode += this->extrude_entity(*ee, "brim", m_config.support_speed.value);
|
||||
gcode += this->extrude_entity(*ee, "brim", NOZZLE_CONFIG(support_speed));
|
||||
}
|
||||
m_avoid_crossing_perimeters.use_external_mp(false);
|
||||
// Allow a straight travel move to the first object point.
|
||||
@@ -5805,11 +5838,11 @@ std::string GCode::extrude_loop(const ExtrusionLoop& loop_ref,
|
||||
|
||||
// SoftFever: check loop lenght for small perimeter.
|
||||
double small_peri_speed = -1;
|
||||
if (speed == -1 && loop.length() <= SMALL_PERIMETER_LENGTH(m_config.small_perimeter_threshold.value)) {
|
||||
if(m_config.small_perimeter_speed == 0)
|
||||
small_peri_speed = m_config.outer_wall_speed * 0.5;
|
||||
if (speed == -1 && loop.length() <= SMALL_PERIMETER_LENGTH(NOZZLE_CONFIG(small_perimeter_threshold))) {
|
||||
if(NOZZLE_CONFIG(small_perimeter_speed).value == 0)
|
||||
small_peri_speed = NOZZLE_CONFIG(outer_wall_speed) * 0.5;
|
||||
else
|
||||
small_peri_speed = m_config.small_perimeter_speed.get_abs_value(m_config.outer_wall_speed);
|
||||
small_peri_speed = NOZZLE_CONFIG(small_perimeter_speed).get_abs_value(NOZZLE_CONFIG(outer_wall_speed));
|
||||
}
|
||||
|
||||
// extrude along the path
|
||||
@@ -6199,8 +6232,8 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
|
||||
if (!support_fills.no_sort)
|
||||
chain_and_reorder_extrusion_entities(extrusions, m_last_pos.to_point());
|
||||
|
||||
const double support_speed = m_config.support_speed.value;
|
||||
const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
//const double support_speed = m_config.support_speed.value;
|
||||
//const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
for (const ExtrusionEntity *ee : extrusions) {
|
||||
ExtrusionRole role = ee->role();
|
||||
assert(role == erSupportMaterial || role == erSupportMaterialInterface || role == erSupportTransition || role == erIroning);
|
||||
@@ -6411,47 +6444,47 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
unsigned int acceleration_i = 0;
|
||||
double jerk = 0;
|
||||
// adjust acceleration
|
||||
if (m_config.default_acceleration.value > 0) {
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0) {
|
||||
double acceleration;
|
||||
if (this->on_first_layer() && m_config.initial_layer_acceleration.value > 0) {
|
||||
acceleration = m_config.initial_layer_acceleration.value;
|
||||
if (this->on_first_layer() && NOZZLE_CONFIG(initial_layer_acceleration) > 0) {
|
||||
acceleration = NOZZLE_CONFIG(initial_layer_acceleration);
|
||||
#if 0
|
||||
} else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) {
|
||||
acceleration = m_config.first_layer_acceleration_over_raft.value;
|
||||
#endif
|
||||
} else if (m_config.get_abs_value("bridge_acceleration") > 0 && is_bridge(path.role())) {
|
||||
acceleration = m_config.get_abs_value("bridge_acceleration");
|
||||
} else if (m_config.get_abs_value("sparse_infill_acceleration") > 0 && (path.role() == erInternalInfill)) {
|
||||
acceleration = m_config.get_abs_value("sparse_infill_acceleration");
|
||||
} else if (m_config.get_abs_value("internal_solid_infill_acceleration") > 0 && (path.role() == erSolidInfill)) {
|
||||
acceleration = m_config.get_abs_value("internal_solid_infill_acceleration");
|
||||
} else if (m_config.outer_wall_acceleration.value > 0 && is_external_perimeter(path.role())) {
|
||||
acceleration = m_config.outer_wall_acceleration.value;
|
||||
} else if (m_config.inner_wall_acceleration.value > 0 && is_internal_perimeter(path.role())) {
|
||||
acceleration = m_config.inner_wall_acceleration.value;
|
||||
} else if (m_config.top_surface_acceleration.value > 0 && is_top_surface(path.role())) {
|
||||
acceleration = m_config.top_surface_acceleration.value;
|
||||
} else if (m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index()) > 0 && is_bridge(path.role())) {
|
||||
acceleration = m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index());
|
||||
} else if (m_config.get_abs_value_at("sparse_infill_acceleration", cur_extruder_index()) > 0 && (path.role() == erInternalInfill)) {
|
||||
acceleration = m_config.get_abs_value_at("sparse_infill_acceleration", cur_extruder_index());
|
||||
} else if (m_config.get_abs_value_at("internal_solid_infill_acceleration", cur_extruder_index()) > 0 && (path.role() == erSolidInfill)) {
|
||||
acceleration = m_config.get_abs_value_at("internal_solid_infill_acceleration", cur_extruder_index());
|
||||
} else if (NOZZLE_CONFIG(outer_wall_acceleration) > 0 && is_external_perimeter(path.role())) {
|
||||
acceleration = NOZZLE_CONFIG(outer_wall_acceleration);
|
||||
} else if (NOZZLE_CONFIG(inner_wall_acceleration) > 0 && is_internal_perimeter(path.role())) {
|
||||
acceleration = NOZZLE_CONFIG(inner_wall_acceleration);
|
||||
} else if (NOZZLE_CONFIG(top_surface_acceleration) > 0 && is_top_surface(path.role())) {
|
||||
acceleration = NOZZLE_CONFIG(top_surface_acceleration);
|
||||
} else {
|
||||
acceleration = m_config.default_acceleration.value;
|
||||
acceleration = NOZZLE_CONFIG(default_acceleration);
|
||||
}
|
||||
acceleration_i = (unsigned int)floor(acceleration + 0.5);
|
||||
}
|
||||
|
||||
// adjust X Y jerk
|
||||
if (m_config.default_jerk.value > 0) {
|
||||
if (this->on_first_layer() && m_config.initial_layer_jerk.value > 0) {
|
||||
jerk = m_config.initial_layer_jerk.value;
|
||||
} else if (m_config.outer_wall_jerk.value > 0 && is_external_perimeter(path.role())) {
|
||||
jerk = m_config.outer_wall_jerk.value;
|
||||
} else if (m_config.inner_wall_jerk.value > 0 && is_internal_perimeter(path.role())) {
|
||||
jerk = m_config.inner_wall_jerk.value;
|
||||
} else if (m_config.top_surface_jerk.value > 0 && is_top_surface(path.role())) {
|
||||
jerk = m_config.top_surface_jerk.value;
|
||||
} else if (m_config.infill_jerk.value > 0 && is_infill(path.role())) {
|
||||
jerk = m_config.infill_jerk.value;
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0) {
|
||||
if (this->on_first_layer() && NOZZLE_CONFIG(initial_layer_jerk) > 0) {
|
||||
jerk = NOZZLE_CONFIG(initial_layer_jerk);
|
||||
} else if (NOZZLE_CONFIG(outer_wall_jerk) > 0 && is_external_perimeter(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(outer_wall_jerk);
|
||||
} else if (NOZZLE_CONFIG(inner_wall_jerk) > 0 && is_internal_perimeter(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(inner_wall_jerk);
|
||||
} else if (NOZZLE_CONFIG(top_surface_jerk) > 0 && is_top_surface(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(top_surface_jerk);
|
||||
} else if (NOZZLE_CONFIG(infill_jerk) > 0 && is_infill(path.role())) {
|
||||
jerk = NOZZLE_CONFIG(infill_jerk);
|
||||
}
|
||||
else {
|
||||
jerk = m_config.default_jerk.value;
|
||||
jerk = NOZZLE_CONFIG(default_jerk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6514,37 +6547,37 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
// set speed
|
||||
if (speed == -1) {
|
||||
if (path.role() == erPerimeter) {
|
||||
speed = m_config.get_abs_value("inner_wall_speed");
|
||||
speed = NOZZLE_CONFIG(inner_wall_speed);
|
||||
if (sloped) {
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("inner_wall_speed")));
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(speed));
|
||||
}
|
||||
} else if (path.role() == erExternalPerimeter) {
|
||||
speed = m_config.get_abs_value("outer_wall_speed");
|
||||
speed = NOZZLE_CONFIG(outer_wall_speed);
|
||||
if (sloped) {
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("outer_wall_speed")));
|
||||
speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(speed));
|
||||
}
|
||||
}
|
||||
else if(path.role() == erInternalBridgeInfill) {
|
||||
speed = m_config.get_abs_value("internal_bridge_speed");
|
||||
speed = m_config.get_abs_value_at("internal_bridge_speed", cur_extruder_index());
|
||||
} else if (path.role() == erOverhangPerimeter || path.role() == erSupportTransition || path.role() == erBridgeInfill) {
|
||||
speed = m_config.get_abs_value("bridge_speed");
|
||||
speed = NOZZLE_CONFIG(bridge_speed);
|
||||
} else if (path.role() == erInternalInfill) {
|
||||
speed = m_config.get_abs_value("sparse_infill_speed");
|
||||
speed = NOZZLE_CONFIG(sparse_infill_speed);
|
||||
} else if (path.role() == erSolidInfill) {
|
||||
speed = m_config.get_abs_value("internal_solid_infill_speed");
|
||||
speed = NOZZLE_CONFIG(internal_solid_infill_speed);
|
||||
} else if (path.role() == erTopSolidInfill) {
|
||||
speed = m_config.get_abs_value("top_surface_speed");
|
||||
speed = NOZZLE_CONFIG(top_surface_speed);
|
||||
} else if (path.role() == erIroning) {
|
||||
speed = m_config.get_abs_value("ironing_speed");
|
||||
} else if (path.role() == erBottomSurface) {
|
||||
speed = m_config.get_abs_value("initial_layer_infill_speed");
|
||||
speed = NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
} else if (path.role() == erGapFill) {
|
||||
speed = m_config.get_abs_value("gap_infill_speed");
|
||||
speed = NOZZLE_CONFIG(gap_infill_speed);
|
||||
}
|
||||
else if (path.role() == erSupportMaterial ||
|
||||
path.role() == erSupportMaterialInterface) {
|
||||
const double support_speed = m_config.support_speed.value;
|
||||
const double support_interface_speed = m_config.get_abs_value("support_interface_speed");
|
||||
const double support_speed = NOZZLE_CONFIG(support_speed);
|
||||
const double support_interface_speed = NOZZLE_CONFIG(support_interface_speed);
|
||||
speed = (path.role() == erSupportMaterial) ? support_speed : support_interface_speed;
|
||||
} else {
|
||||
throw Slic3r::InvalidArgument("Invalid speed");
|
||||
@@ -6565,16 +6598,16 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
//BBS: for solid infill of first layer, speed can be higher as long as
|
||||
//wall lines have be attached
|
||||
if (path.role() != erBottomSurface) {
|
||||
speed = is_perimeter(path.role()) ? m_config.get_abs_value("initial_layer_speed") :
|
||||
m_config.get_abs_value("initial_layer_infill_speed");
|
||||
speed = is_perimeter(path.role()) ? NOZZLE_CONFIG(initial_layer_speed) :
|
||||
NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
}
|
||||
} else if (m_config.slow_down_layers > 1 && m_config.raft_layers == 0) {
|
||||
|
||||
if (_layer > 0 && _layer < m_config.slow_down_layers) {
|
||||
const auto first_layer_speed =
|
||||
is_perimeter(path.role())
|
||||
? m_config.get_abs_value("initial_layer_speed")
|
||||
: m_config.get_abs_value("initial_layer_infill_speed");
|
||||
? NOZZLE_CONFIG(initial_layer_speed)
|
||||
: NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
if (first_layer_speed < speed) {
|
||||
speed = std::min(
|
||||
speed,
|
||||
@@ -6586,8 +6619,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
|
||||
if (_layer > m_config.raft_layers && (_layer - m_config.raft_layers) < m_config.slow_down_layers) {
|
||||
const auto first_layer_speed
|
||||
= is_perimeter(path.role()) ? m_config.get_abs_value("initial_layer_speed") :
|
||||
m_config.get_abs_value("initial_layer_infill_speed");
|
||||
= is_perimeter(path.role()) ? NOZZLE_CONFIG(initial_layer_speed) :
|
||||
NOZZLE_CONFIG(initial_layer_infill_speed);
|
||||
if (first_layer_speed < speed) {
|
||||
speed = std::min(speed, Slic3r::lerp(first_layer_speed, speed,
|
||||
(double) (_layer - m_config.raft_layers) / m_config.slow_down_layers));
|
||||
@@ -6653,10 +6686,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
bool variable_speed = false;
|
||||
std::vector<ProcessedPoint> new_points {};
|
||||
|
||||
if (m_config.enable_overhang_speed && !this->on_first_layer() && !object_layer_over_raft() &&
|
||||
if (NOZZLE_CONFIG(enable_overhang_speed) && !this->on_first_layer() && !object_layer_over_raft() &&
|
||||
(is_bridge(path.role()) || is_perimeter(path.role()))) {
|
||||
bool is_external = is_external_perimeter(path.role());
|
||||
double ref_speed = is_external ? m_config.get_abs_value("outer_wall_speed") : m_config.get_abs_value("inner_wall_speed");
|
||||
double ref_speed = is_external ? NOZZLE_CONFIG(outer_wall_speed) : NOZZLE_CONFIG(inner_wall_speed);
|
||||
if (ref_speed == 0)
|
||||
ref_speed = FILAMENT_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm;
|
||||
|
||||
@@ -6669,46 +6702,46 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||
|
||||
ConfigOptionPercents overhang_overlap_levels({90, 75, 50, 25, 13, 0});
|
||||
|
||||
if (m_config.slowdown_for_curled_perimeters){
|
||||
if (NOZZLE_CONFIG(slowdown_for_curled_perimeters)){
|
||||
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
||||
{FloatOrPercent{100, true},
|
||||
(m_config.get_abs_value("overhang_1_4_speed", ref_speed) < 0.5) ?
|
||||
(NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_1_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_2_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_2_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_3_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_3_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_4_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_4_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_4_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_4_4_speed", ref_speed) * 100 / ref_speed, true}});
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true}});
|
||||
|
||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
||||
ref_speed, speed, m_config.slowdown_for_curled_perimeters);
|
||||
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters));
|
||||
}else{
|
||||
ConfigOptionFloatsOrPercents dynamic_overhang_speeds(
|
||||
{FloatOrPercent{100, true},
|
||||
(m_config.get_abs_value("overhang_1_4_speed", ref_speed) < 0.5) ?
|
||||
(NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_1_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_2_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_1_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_2_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_3_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_2_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_3_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
(m_config.get_abs_value("overhang_4_4_speed", ref_speed) < 0.5) ?
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_3_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
(NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) < 0.5) ?
|
||||
FloatOrPercent{100, true} :
|
||||
FloatOrPercent{m_config.get_abs_value("overhang_4_4_speed", ref_speed) * 100 / ref_speed, true},
|
||||
FloatOrPercent{m_config.get_abs_value("bridge_speed") * 100 / ref_speed, true}});
|
||||
FloatOrPercent{NOZZLE_CONFIG(overhang_4_4_speed).get_abs_value(ref_speed) * 100 / ref_speed, true},
|
||||
FloatOrPercent{NOZZLE_CONFIG(bridge_speed) * 100 / ref_speed, true}});
|
||||
|
||||
new_points = m_extrusion_quality_estimator.estimate_extrusion_quality(path, overhang_overlap_levels, dynamic_overhang_speeds,
|
||||
ref_speed, speed, m_config.slowdown_for_curled_perimeters);
|
||||
ref_speed, speed, NOZZLE_CONFIG(slowdown_for_curled_perimeters));
|
||||
}
|
||||
variable_speed = std::any_of(new_points.begin(), new_points.end(),
|
||||
[speed](const ProcessedPoint &p) { return fabs(double(p.speed) - speed) > 1; }); // Ignore small speed variations (under 1mm/sec)
|
||||
@@ -7367,40 +7400,40 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string
|
||||
unsigned int acceleration_to_set = 0;
|
||||
|
||||
if (this->on_first_layer()) {
|
||||
unsigned int initial_layer_travel_acceleration = m_config.get_abs_value("initial_layer_travel_acceleration");
|
||||
double initial_layer_travel_jerk = m_config.get_abs_value("initial_layer_travel_jerk");
|
||||
unsigned int initial_layer_travel_acceleration = m_config.get_abs_value_at("initial_layer_travel_acceleration", cur_extruder_index());
|
||||
double initial_layer_travel_jerk = m_config.get_abs_value_at("initial_layer_travel_jerk", cur_extruder_index());
|
||||
|
||||
if (m_config.default_acceleration.value > 0 && initial_layer_travel_acceleration > 0) {
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0 && initial_layer_travel_acceleration > 0) {
|
||||
acceleration_to_set = (unsigned int) floor(initial_layer_travel_acceleration + 0.5);
|
||||
}
|
||||
if (m_config.default_jerk.value > 0 && initial_layer_travel_jerk > 0) {
|
||||
if (NOZZLE_CONFIG(default_jerk)> 0 && initial_layer_travel_jerk > 0) {
|
||||
jerk_to_set = initial_layer_travel_jerk;
|
||||
}
|
||||
} else { // ORCA: Handle short-travel acceleration and jerk for outer perimeters (if applicable)
|
||||
const bool is_short_travel = travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel));
|
||||
|
||||
if (m_config.default_acceleration.value > 0) {
|
||||
if (NOZZLE_CONFIG(default_acceleration) > 0) {
|
||||
if (role == erOverhangPerimeter && is_short_travel) {
|
||||
const double bridge_acceleration = m_config.get_abs_value("bridge_acceleration");
|
||||
const double bridge_acceleration = m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index());
|
||||
|
||||
if (bridge_acceleration > 0)
|
||||
acceleration_to_set = (unsigned int) floor(bridge_acceleration + 0.5);
|
||||
} else if (role == erExternalPerimeter && is_short_travel) {
|
||||
if (m_config.outer_wall_acceleration.value > 0)
|
||||
acceleration_to_set = (unsigned int) floor(m_config.outer_wall_acceleration.value + 0.5);
|
||||
if (NOZZLE_CONFIG(outer_wall_acceleration) > 0)
|
||||
acceleration_to_set = (unsigned int) floor(NOZZLE_CONFIG(outer_wall_acceleration) + 0.5);
|
||||
} else {
|
||||
if (m_config.travel_acceleration.value > 0)
|
||||
acceleration_to_set = (unsigned int) floor(m_config.travel_acceleration.value + 0.5);
|
||||
if (NOZZLE_CONFIG(travel_acceleration) > 0)
|
||||
acceleration_to_set = (unsigned int) floor(NOZZLE_CONFIG(travel_acceleration) + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_config.default_jerk.value > 0) {
|
||||
if (NOZZLE_CONFIG(default_jerk) > 0) {
|
||||
if ((role == erExternalPerimeter || role == erOverhangPerimeter) && is_short_travel) {
|
||||
if (m_config.outer_wall_jerk.value > 0)
|
||||
jerk_to_set = m_config.outer_wall_jerk.value;
|
||||
if (NOZZLE_CONFIG(outer_wall_jerk) > 0)
|
||||
jerk_to_set = NOZZLE_CONFIG(outer_wall_jerk);
|
||||
} else {
|
||||
if (m_config.travel_jerk.value > 0)
|
||||
jerk_to_set = m_config.travel_jerk.value;
|
||||
if (NOZZLE_CONFIG(travel_jerk) > 0)
|
||||
jerk_to_set = NOZZLE_CONFIG(travel_jerk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,6 +392,7 @@ private:
|
||||
|
||||
//BBS
|
||||
void check_placeholder_parser_failed();
|
||||
size_t cur_extruder_index() const;
|
||||
size_t get_extruder_id(unsigned int filament_id) const;
|
||||
|
||||
void set_last_pos(const Point &pos) { m_last_pos = Point3(pos, 0); m_last_pos_defined = true; }
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0)
|
||||
CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_config(gcodegen.config()), m_toolchange_prefix(gcodegen.writer().toolchange_prefix()), m_current_extruder(0), m_current_nozzle(0)
|
||||
{
|
||||
this->reset(gcodegen.writer().get_position());
|
||||
|
||||
@@ -37,7 +37,7 @@ void CoolingBuffer::reset(const Vec3d &position)
|
||||
m_current_pos[0] = float(position.x());
|
||||
m_current_pos[1] = float(position.y());
|
||||
m_current_pos[2] = float(position.z());
|
||||
m_current_pos[4] = float(m_config.travel_speed.value);
|
||||
m_current_pos[4] = float(m_config.travel_speed.get_at(m_current_nozzle));
|
||||
m_fan_speed = -1;
|
||||
m_additional_fan_speed = -1;
|
||||
m_current_fan_speed = -1;
|
||||
|
||||
@@ -25,7 +25,7 @@ class CoolingBuffer {
|
||||
public:
|
||||
CoolingBuffer(GCode &gcodegen);
|
||||
void reset(const Vec3d &position);
|
||||
void set_current_extruder(unsigned int extruder_id) { m_current_extruder = extruder_id; }
|
||||
void set_current_extruder(unsigned int extruder_id, unsigned int nozzle_id) { m_current_extruder = extruder_id; m_current_nozzle = nozzle_id; }
|
||||
std::string process_layer(std::string &&gcode, size_t layer_id, bool flush);
|
||||
|
||||
private:
|
||||
@@ -55,6 +55,7 @@ private:
|
||||
// the PrintConfig slice of FullPrintConfig is constant, thus no thread synchronization is required.
|
||||
const PrintConfig &m_config;
|
||||
unsigned int m_current_extruder;
|
||||
unsigned int m_current_nozzle;
|
||||
//BBS: current fan speed
|
||||
int m_current_fan_speed;
|
||||
};
|
||||
|
||||
@@ -1472,7 +1472,7 @@ WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origi
|
||||
m_bridging(10.f),
|
||||
m_no_sparse_layers(config.wipe_tower_no_sparse_layers),
|
||||
m_gcode_flavor(config.gcode_flavor),
|
||||
m_travel_speed(config.travel_speed),
|
||||
m_travel_speed(config.travel_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_current_tool(initial_tool),
|
||||
//wipe_volumes(flush_matrix)
|
||||
m_enable_timelapse_print(config.timelapse_type.value == TimelapseType::tlSmooth),
|
||||
@@ -1497,7 +1497,7 @@ WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origi
|
||||
// it is taken over following default. Speeds from config are not
|
||||
// easily accessible here.
|
||||
const float default_speed = 60.f;
|
||||
m_first_layer_speed = config.get_abs_value("initial_layer_speed");
|
||||
m_first_layer_speed = config.initial_layer_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool));
|
||||
if (m_first_layer_speed == 0.f) // just to make sure autospeed doesn't break it.
|
||||
m_first_layer_speed = default_speed / 2.f;
|
||||
|
||||
|
||||
@@ -1262,9 +1262,9 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
|
||||
m_bridging(float(config.wipe_tower_bridging)),
|
||||
m_no_sparse_layers(config.wipe_tower_no_sparse_layers),
|
||||
m_gcode_flavor(config.gcode_flavor),
|
||||
m_travel_speed(config.travel_speed),
|
||||
m_infill_speed(default_region_config.sparse_infill_speed),
|
||||
m_perimeter_speed(default_region_config.inner_wall_speed),
|
||||
m_travel_speed(config.travel_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_infill_speed(default_region_config.sparse_infill_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_perimeter_speed(default_region_config.inner_wall_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool))),
|
||||
m_current_tool(initial_tool),
|
||||
wipe_volumes(wiping_matrix), m_wipe_tower_max_purge_speed(float(config.wipe_tower_max_purge_speed)),
|
||||
m_enable_arc_fitting(config.enable_arc_fitting),
|
||||
@@ -1280,7 +1280,7 @@ WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& defau
|
||||
// it is taken over following default. Speeds from config are not
|
||||
// easily accessible here.
|
||||
const float default_speed = 60.f;
|
||||
m_first_layer_speed = config.initial_layer_speed;
|
||||
m_first_layer_speed = config.initial_layer_speed.get_at(get_extruder_index(config, (unsigned int)initial_tool));
|
||||
if (m_first_layer_speed == 0.f) // just to make sure autospeed doesn't break it.
|
||||
m_first_layer_speed = default_speed / 2.f;
|
||||
|
||||
|
||||
+101
-53
@@ -28,6 +28,39 @@ bool GCodeWriter::supports_separate_travel_acceleration(GCodeFlavor flavor)
|
||||
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
||||
{
|
||||
this->config.apply(print_config, true);
|
||||
|
||||
// Some machine limits are stride-2 (normal, silent) pairs, here we extract the value that will be used,
|
||||
// which is always normal mode at the moment
|
||||
// TODO: support silent? Any printer actually have that?
|
||||
auto get_machine_limits = [](const std::string key, const ConfigOptionFloats& opt) -> std::vector<double> {
|
||||
unsigned int stride = 1;
|
||||
unsigned int offset = 0;
|
||||
if (printer_options_with_variant_2.count(key) > 0) {
|
||||
stride = 2;
|
||||
// offset = <TODO: current print mode>;
|
||||
}
|
||||
|
||||
std::vector<double> results;
|
||||
results.reserve(opt.values.size() / stride);
|
||||
|
||||
for (unsigned int i = offset; i < opt.values.size(); i += stride) {
|
||||
results.emplace_back(opt.values[i]);
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
auto rounded = [](std::vector<double>&& vec) -> std::vector<double>&&{
|
||||
std::transform(vec.cbegin(), vec.cend(), vec.begin(), [](const double v) { return std::round(v); });
|
||||
return std::move(vec);
|
||||
};
|
||||
auto to_uint = [](const std::vector<double>& vec) {
|
||||
std::vector<unsigned int> r;
|
||||
std::transform(vec.begin(), vec.end(), std::back_inserter(r), [](const double v) { return static_cast<unsigned int>(v); });
|
||||
return r;
|
||||
};
|
||||
#define LIMITS(OPT) get_machine_limits(#OPT, print_config.OPT)
|
||||
#define LIMITS_UINT(OPT) to_uint(rounded(LIMITS(OPT)))
|
||||
|
||||
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
|
||||
bool use_mach_limits = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware ||
|
||||
print_config.gcode_flavor.value == gcfKlipper || print_config.gcode_flavor.value == gcfRepRapFirmware;
|
||||
@@ -35,29 +68,40 @@ void GCodeWriter::apply_print_config(const PrintConfig &print_config)
|
||||
// For Klipper, SET_VELOCITY_LIMIT ACCEL= applies to all moves, so the effective cap
|
||||
// is the minimum of the extruding limit and the per-axis X/Y limits.
|
||||
// This ensures user-configured Motion Ability limits are honoured (#12244).
|
||||
unsigned int extruding_limit = std::lrint(print_config.machine_max_acceleration_extruding.values.front());
|
||||
auto extruding_limit = LIMITS_UINT(machine_max_acceleration_extruding);
|
||||
if (print_config.gcode_flavor.value == gcfKlipper) {
|
||||
unsigned int x_limit = std::lrint(print_config.machine_max_acceleration_x.values.front());
|
||||
unsigned int y_limit = std::lrint(print_config.machine_max_acceleration_y.values.front());
|
||||
if (x_limit > 0) extruding_limit = std::min(extruding_limit, x_limit);
|
||||
if (y_limit > 0) extruding_limit = std::min(extruding_limit, y_limit);
|
||||
auto x_limit = LIMITS_UINT(machine_max_acceleration_x);
|
||||
auto y_limit = LIMITS_UINT(machine_max_acceleration_y);
|
||||
|
||||
for (size_t i = 0; i < extruding_limit.size(); i++) {
|
||||
if (x_limit[i] > 0) extruding_limit[i] = std::min(extruding_limit[i], x_limit[i]);
|
||||
if (y_limit[i] > 0) extruding_limit[i] = std::min(extruding_limit[i], y_limit[i]);
|
||||
}
|
||||
}
|
||||
m_max_acceleration = extruding_limit;
|
||||
m_max_acceleration = std::move(extruding_limit);
|
||||
} else {
|
||||
m_max_acceleration = 0;
|
||||
m_max_acceleration.clear();
|
||||
}
|
||||
if (use_mach_limits && supports_separate_travel_acceleration(print_config.gcode_flavor.value)) {
|
||||
m_max_travel_acceleration = LIMITS_UINT(machine_max_acceleration_travel);
|
||||
} else {
|
||||
m_max_travel_acceleration.clear();
|
||||
}
|
||||
m_max_travel_acceleration = static_cast<unsigned int>(
|
||||
std::round((use_mach_limits && supports_separate_travel_acceleration(print_config.gcode_flavor.value)) ?
|
||||
print_config.machine_max_acceleration_travel.values.front() :
|
||||
0));
|
||||
if (use_mach_limits) {
|
||||
m_max_jerk_x = std::lrint(print_config.machine_max_jerk_x.values.front());
|
||||
m_max_jerk_y = std::lrint(print_config.machine_max_jerk_y.values.front());
|
||||
m_max_junction_deviation = (print_config.machine_max_junction_deviation.values.front());
|
||||
};
|
||||
m_max_jerk_z = print_config.machine_max_jerk_z.values.front();
|
||||
m_max_jerk_e = print_config.machine_max_jerk_e.values.front();
|
||||
m_max_jerk_x = rounded(LIMITS(machine_max_jerk_x));
|
||||
m_max_jerk_y = rounded(LIMITS(machine_max_jerk_y));
|
||||
m_max_junction_deviation = LIMITS(machine_max_junction_deviation);
|
||||
} else {
|
||||
m_max_jerk_x.clear();
|
||||
m_max_jerk_y.clear();
|
||||
m_max_junction_deviation.clear();
|
||||
}
|
||||
m_max_jerk_z = LIMITS(machine_max_jerk_z);
|
||||
m_max_jerk_e = LIMITS(machine_max_jerk_e);
|
||||
m_resolution = print_config.resolution.value;
|
||||
|
||||
#undef LIMITS
|
||||
#undef LIMITS_UINT
|
||||
}
|
||||
|
||||
void GCodeWriter::set_extruders(std::vector<unsigned int> extruder_ids)
|
||||
@@ -212,14 +256,18 @@ std::string GCodeWriter::set_chamber_temperature(int temperature, bool wait)
|
||||
return gcode.str();
|
||||
}
|
||||
|
||||
#define EXTRUDER_LIMIT(OPT) \
|
||||
(filament() ? ((OPT).size() <= filament()->extruder_id() ? 0 : (OPT)[filament()->extruder_id()]) : \
|
||||
((OPT).empty() ? 0 : *std::max_element((OPT).cbegin(), (OPT).cend())))
|
||||
|
||||
// copied from PrusaSlicer
|
||||
std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned int acceleration)
|
||||
{
|
||||
// Clamp the acceleration to the allowed maximum.
|
||||
if (type == Acceleration::Print && m_max_acceleration > 0 && acceleration > m_max_acceleration)
|
||||
acceleration = m_max_acceleration;
|
||||
if (type == Acceleration::Travel && m_max_travel_acceleration > 0 && acceleration > m_max_travel_acceleration)
|
||||
acceleration = m_max_travel_acceleration;
|
||||
if (type == Acceleration::Print && EXTRUDER_LIMIT(m_max_acceleration) > 0 && acceleration > EXTRUDER_LIMIT(m_max_acceleration))
|
||||
acceleration = EXTRUDER_LIMIT(m_max_acceleration);
|
||||
if (type == Acceleration::Travel && EXTRUDER_LIMIT(m_max_travel_acceleration) > 0 && acceleration > EXTRUDER_LIMIT(m_max_travel_acceleration))
|
||||
acceleration = EXTRUDER_LIMIT(m_max_travel_acceleration);
|
||||
|
||||
// Are we setting travel acceleration for a flavour that supports separate travel and print acc?
|
||||
bool separate_travel = (type == Acceleration::Travel && supports_separate_travel_acceleration(this->config.gcode_flavor));
|
||||
@@ -262,10 +310,10 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
std::ostringstream gcode;
|
||||
if (FLAVOR_IS(gcfKlipper)) {
|
||||
// Clamp the jerk to the allowed maximum.
|
||||
if (m_max_jerk_x > 0 && jerk > m_max_jerk_x)
|
||||
jerk = m_max_jerk_x;
|
||||
if (m_max_jerk_y > 0 && jerk > m_max_jerk_y)
|
||||
jerk = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
gcode << "SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=" << jerk;
|
||||
|
||||
@@ -274,12 +322,12 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
double jerk_xy = jerk;
|
||||
|
||||
// Clamp against the X machine limit
|
||||
if (m_max_jerk_x > 0 && jerk_xy > m_max_jerk_x)
|
||||
jerk_xy = m_max_jerk_x;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk_xy > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk_xy = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
|
||||
// Clamp against the Y machine limit as well to be safe
|
||||
if (m_max_jerk_y > 0 && jerk_xy > m_max_jerk_y)
|
||||
jerk_xy = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk_xy > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk_xy = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
// Output the lowest safe limit using ONLY the X parameter
|
||||
gcode << "M207 X" << jerk_xy;
|
||||
@@ -287,16 +335,16 @@ std::string GCodeWriter::set_jerk_xy(double jerk)
|
||||
double jerk_x = jerk;
|
||||
double jerk_y = jerk;
|
||||
// Clamp the axis jerk to the allowed maximum.
|
||||
if (m_max_jerk_x > 0 && jerk > m_max_jerk_x)
|
||||
jerk_x = m_max_jerk_x;
|
||||
if (m_max_jerk_y > 0 && jerk > m_max_jerk_y)
|
||||
jerk_y = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk_x = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk_y = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
gcode << "M205 X" << jerk_x << " Y" << jerk_y;
|
||||
}
|
||||
//the is_bbl check should be in the else statement above so that it doesn't inadverently added Z & E to klipper
|
||||
if (m_is_bbl_printers)
|
||||
gcode << std::setprecision(2) << " Z" << m_max_jerk_z << " E" << m_max_jerk_e;
|
||||
gcode << std::setprecision(2) << " Z" << EXTRUDER_LIMIT(m_max_jerk_z) << " E" << EXTRUDER_LIMIT(m_max_jerk_e);
|
||||
|
||||
if (GCodeWriter::full_gcode_comment) gcode << " ; adjust jerk";
|
||||
gcode << "\n";
|
||||
@@ -312,8 +360,8 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je
|
||||
throw std::runtime_error(_u8L("set_accel_and_jerk() is only supported by Klipper"));
|
||||
|
||||
// Clamp the acceleration to the allowed maximum.
|
||||
if (m_max_acceleration > 0 && acceleration > m_max_acceleration)
|
||||
acceleration = m_max_acceleration;
|
||||
if (EXTRUDER_LIMIT(m_max_acceleration) > 0 && acceleration > EXTRUDER_LIMIT(m_max_acceleration))
|
||||
acceleration = EXTRUDER_LIMIT(m_max_acceleration);
|
||||
|
||||
bool is_empty = true;
|
||||
std::ostringstream gcode;
|
||||
@@ -327,10 +375,10 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je
|
||||
is_empty = false;
|
||||
}
|
||||
// Clamp the jerk to the allowed maximum.
|
||||
if (m_max_jerk_x > 0 && jerk > m_max_jerk_x)
|
||||
jerk = m_max_jerk_x;
|
||||
if (m_max_jerk_y > 0 && jerk > m_max_jerk_y)
|
||||
jerk = m_max_jerk_y;
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_x) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_x))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_x);
|
||||
if (EXTRUDER_LIMIT(m_max_jerk_y) > 0 && jerk > EXTRUDER_LIMIT(m_max_jerk_y))
|
||||
jerk = EXTRUDER_LIMIT(m_max_jerk_y);
|
||||
|
||||
if (jerk > 0.01 && !is_approx(jerk, m_last_jerk)) {
|
||||
gcode << " SQUARE_CORNER_VELOCITY=" << jerk;
|
||||
@@ -351,13 +399,13 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je
|
||||
|
||||
std::string GCodeWriter::set_junction_deviation(double junction_deviation){
|
||||
std::ostringstream gcode;
|
||||
if (FLAVOR_IS(gcfMarlinFirmware) && m_max_junction_deviation > 0 && junction_deviation > 0) {
|
||||
if (FLAVOR_IS(gcfMarlinFirmware) && EXTRUDER_LIMIT(m_max_junction_deviation) > 0 && junction_deviation > 0) {
|
||||
// Clamp the junction deviation to the allowed maximum.
|
||||
gcode << "M205 J";
|
||||
if (junction_deviation <= m_max_junction_deviation) {
|
||||
if (junction_deviation <= EXTRUDER_LIMIT(m_max_junction_deviation)) {
|
||||
gcode << std::fixed << std::setprecision(3) << junction_deviation;
|
||||
} else {
|
||||
gcode << std::fixed << std::setprecision(3) << m_max_junction_deviation;
|
||||
gcode << std::fixed << std::setprecision(3) << EXTRUDER_LIMIT(m_max_junction_deviation);
|
||||
}
|
||||
if (GCodeWriter::full_gcode_comment) {
|
||||
gcode << " ; Junction Deviation";
|
||||
@@ -610,7 +658,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com
|
||||
GCodeG1Formatter w;
|
||||
w.emit_xy(point_on_plate);
|
||||
auto speed = m_is_first_layer
|
||||
? this->config.get_abs_value("initial_layer_travel_speed") : this->config.travel_speed.value;
|
||||
? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
w.emit_f(speed * 60.0);
|
||||
//BBS
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
@@ -696,7 +744,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
// BBS
|
||||
Vec3d dest_point = point;
|
||||
auto travel_speed =
|
||||
m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed") : this->config.travel_speed.value;
|
||||
m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
//BBS: a z_hop need to be handle when travel
|
||||
if (std::abs(m_to_lift) > EPSILON) {
|
||||
assert(std::abs(m_lifted) < EPSILON);
|
||||
@@ -793,13 +841,13 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co
|
||||
{
|
||||
//force to move xy first then z after filament change
|
||||
w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y()));
|
||||
w.emit_f(this->config.travel_speed.value * 60.0);
|
||||
w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0);
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
out_string = w.string() + _travel_to_z(point_on_plate.z(), comment);
|
||||
} else {
|
||||
GCodeG1Formatter w;
|
||||
w.emit_xyz(point_on_plate);
|
||||
w.emit_f(this->config.travel_speed.value * 60.0);
|
||||
w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0);
|
||||
w.emit_comment(GCodeWriter::full_gcode_comment, comment);
|
||||
out_string = w.string();
|
||||
}
|
||||
@@ -832,10 +880,10 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
|
||||
{
|
||||
m_pos(2) = z;
|
||||
|
||||
double speed = this->config.travel_speed_z.value;
|
||||
double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
if (speed == 0.) {
|
||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||
: this->config.travel_speed.value;
|
||||
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id()))
|
||||
: this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
}
|
||||
|
||||
GCodeG1Formatter w;
|
||||
@@ -849,11 +897,11 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
|
||||
std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment)
|
||||
{
|
||||
std::string output;
|
||||
double speed = this->config.travel_speed_z.value;
|
||||
double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
|
||||
if (speed == 0.) {
|
||||
speed = m_is_first_layer ? this->config.get_abs_value("initial_layer_travel_speed")
|
||||
: this->config.travel_speed.value;
|
||||
speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id()))
|
||||
: this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id()));
|
||||
}
|
||||
|
||||
if (!this->config.enable_arc_fitting) { // Orca: if arc fitting is disabled, approximate the arc with small linear segments
|
||||
|
||||
@@ -135,22 +135,22 @@ public:
|
||||
bool m_single_extruder_multi_material;
|
||||
std::vector<Extruder*> m_curr_filament_extruder;
|
||||
int m_curr_extruder_id;
|
||||
unsigned int m_last_acceleration;
|
||||
unsigned int m_last_travel_acceleration;
|
||||
unsigned int m_max_travel_acceleration;
|
||||
unsigned int m_last_acceleration;
|
||||
unsigned int m_last_travel_acceleration;
|
||||
std::vector<unsigned int> m_max_travel_acceleration;
|
||||
|
||||
// Limit for setting the acceleration, to respect the machine limits set for the Marlin firmware.
|
||||
// If set to zero, the limit is not in action.
|
||||
unsigned int m_max_acceleration;
|
||||
double m_max_jerk_x;
|
||||
double m_max_jerk_y;
|
||||
double m_last_jerk;
|
||||
double m_max_jerk_z;
|
||||
double m_max_jerk_e;
|
||||
double m_max_junction_deviation;
|
||||
// If set to zero, the limit is not in action. Indexed by 0-based physical nozzle id.
|
||||
std::vector<unsigned int> m_max_acceleration;
|
||||
std::vector<double> m_max_jerk_x;
|
||||
std::vector<double> m_max_jerk_y;
|
||||
double m_last_jerk;
|
||||
std::vector<double> m_max_jerk_z;
|
||||
std::vector<double> m_max_jerk_e;
|
||||
std::vector<double> m_max_junction_deviation;
|
||||
|
||||
unsigned int m_travel_acceleration;
|
||||
unsigned int m_travel_jerk;
|
||||
// unsigned int m_travel_acceleration;
|
||||
// unsigned int m_travel_jerk;
|
||||
|
||||
|
||||
//BBS
|
||||
|
||||
@@ -136,7 +136,7 @@ ExPolygons Layer::merged(float offset_scaled) const
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
bool Layer::is_perimeter_compatible(const Print& print, const PrintRegion& a, const PrintRegion& b)
|
||||
{
|
||||
const PrintRegionConfig& config = a.config();
|
||||
const PrintRegionConfig& other_config = b.config();
|
||||
@@ -146,10 +146,10 @@ bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b)
|
||||
&& config.wall_loops == other_config.wall_loops
|
||||
&& config.wall_sequence == other_config.wall_sequence
|
||||
&& config.is_infill_first == other_config.is_infill_first
|
||||
&& config.inner_wall_speed == other_config.inner_wall_speed
|
||||
&& config.outer_wall_speed == other_config.outer_wall_speed
|
||||
&& config.small_perimeter_speed == other_config.small_perimeter_speed
|
||||
&& config.gap_infill_speed.value == other_config.gap_infill_speed.value
|
||||
&& config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
|
||||
&& config.filter_out_gap_fill.value == other_config.filter_out_gap_fill.value
|
||||
&& config.detect_overhang_wall == other_config.detect_overhang_wall
|
||||
&& config.overhang_reverse == other_config.overhang_reverse
|
||||
@@ -209,7 +209,7 @@ void Layer::make_perimeters()
|
||||
if (! (*it)->slices.empty()) {
|
||||
LayerRegion* other_layerm = *it;
|
||||
const PrintRegion &other_region = other_layerm->region();
|
||||
if (is_perimeter_compatible(this_region, other_region))
|
||||
if (is_perimeter_compatible(*m_object->print(), this_region, other_region))
|
||||
{
|
||||
other_layerm->perimeters.clear();
|
||||
other_layerm->fills.clear();
|
||||
|
||||
@@ -17,6 +17,7 @@ class LayerRegion;
|
||||
using LayerRegionPtrs = std::vector<LayerRegion*>;
|
||||
class PrintRegion;
|
||||
class PrintObject;
|
||||
class Print;
|
||||
|
||||
namespace FillAdaptive {
|
||||
struct Octree;
|
||||
@@ -186,7 +187,7 @@ public:
|
||||
}
|
||||
|
||||
// Whether two regions can be printed in a continues perimeter
|
||||
static bool is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b);
|
||||
static bool is_perimeter_compatible(const Print& print, const PrintRegion& a, const PrintRegion& b);
|
||||
void make_perimeters();
|
||||
// Phony version of make_fills() without parameters for Perl integration only.
|
||||
void make_fills() { this->make_fills(nullptr, nullptr); }
|
||||
|
||||
+13
-13
@@ -2972,31 +2972,31 @@ void Model::setPrintSpeedTable(const DynamicPrintConfig& config, const PrintConf
|
||||
//Slic3r::DynamicPrintConfig config = wxGetApp().preset_bundle->full_config();
|
||||
printSpeedMap.maxSpeed = 0;
|
||||
if (config.has("inner_wall_speed")) {
|
||||
printSpeedMap.perimeterSpeed = config.opt_float("inner_wall_speed");
|
||||
printSpeedMap.perimeterSpeed = config.opt_float_nullable("inner_wall_speed", 0);
|
||||
if (printSpeedMap.perimeterSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.perimeterSpeed;
|
||||
}
|
||||
if (config.has("outer_wall_speed")) {
|
||||
printSpeedMap.externalPerimeterSpeed = config.opt_float("outer_wall_speed");
|
||||
printSpeedMap.externalPerimeterSpeed = config.opt_float_nullable("outer_wall_speed", 0);
|
||||
printSpeedMap.maxSpeed = std::max(printSpeedMap.maxSpeed, printSpeedMap.externalPerimeterSpeed);
|
||||
}
|
||||
if (config.has("sparse_infill_speed")) {
|
||||
printSpeedMap.infillSpeed = config.opt_float("sparse_infill_speed");
|
||||
printSpeedMap.infillSpeed = config.opt_float_nullable("sparse_infill_speed", 0);
|
||||
if (printSpeedMap.infillSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.infillSpeed;
|
||||
}
|
||||
if (config.has("internal_solid_infill_speed")) {
|
||||
printSpeedMap.solidInfillSpeed = config.opt_float("internal_solid_infill_speed");
|
||||
printSpeedMap.solidInfillSpeed = config.opt_float_nullable("internal_solid_infill_speed", 0);
|
||||
if (printSpeedMap.solidInfillSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.solidInfillSpeed;
|
||||
}
|
||||
if (config.has("top_surface_speed")) {
|
||||
printSpeedMap.topSolidInfillSpeed = config.opt_float("top_surface_speed");
|
||||
printSpeedMap.topSolidInfillSpeed = config.opt_float_nullable("top_surface_speed", 0);
|
||||
if (printSpeedMap.topSolidInfillSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.topSolidInfillSpeed;
|
||||
}
|
||||
if (config.has("support_speed")) {
|
||||
printSpeedMap.supportSpeed = config.opt_float("support_speed");
|
||||
printSpeedMap.supportSpeed = config.opt_float_nullable("support_speed", 0);
|
||||
|
||||
if (printSpeedMap.supportSpeed > printSpeedMap.maxSpeed)
|
||||
printSpeedMap.maxSpeed = printSpeedMap.supportSpeed;
|
||||
@@ -3228,21 +3228,21 @@ double Model::findMaxSpeed(const ModelObject* object) {
|
||||
double smallPerimeterSpeedObj = Model::printSpeedMap.smallPerimeterSpeed;
|
||||
for (std::string objectKey : objectKeys) {
|
||||
if (objectKey == "inner_wall_speed"){
|
||||
perimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
perimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
externalPerimeterSpeedObj = Model::printSpeedMap.externalPerimeterSpeed / Model::printSpeedMap.perimeterSpeed * perimeterSpeedObj;
|
||||
}
|
||||
if (objectKey == "sparse_infill_speed")
|
||||
infillSpeedObj = object->config.opt_float(objectKey);
|
||||
infillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "internal_solid_infill_speed")
|
||||
solidInfillSpeedObj = object->config.opt_float(objectKey);
|
||||
solidInfillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "top_surface_speed")
|
||||
topSolidInfillSpeedObj = object->config.opt_float(objectKey);
|
||||
topSolidInfillSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "support_speed")
|
||||
supportSpeedObj = object->config.opt_float(objectKey);
|
||||
supportSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "outer_wall_speed")
|
||||
externalPerimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
externalPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
if (objectKey == "small_perimeter_speed")
|
||||
smallPerimeterSpeedObj = object->config.opt_float(objectKey);
|
||||
smallPerimeterSpeedObj = object->config.get().opt_float_nullable(objectKey, 0);
|
||||
}
|
||||
objMaxSpeed = std::max(perimeterSpeedObj, std::max(externalPerimeterSpeedObj, std::max(infillSpeedObj, std::max(solidInfillSpeedObj, std::max(topSolidInfillSpeedObj, std::max(supportSpeedObj, std::max(smallPerimeterSpeedObj, objMaxSpeed)))))));
|
||||
if (objMaxSpeed <= 0) objMaxSpeed = 250.;
|
||||
|
||||
@@ -1352,7 +1352,7 @@ static inline std::vector<std::vector<ExPolygons>> segmentation_top_and_bottom_l
|
||||
out.extrusion_width = std::max<float>(out.extrusion_width, outer_wall_line_width);
|
||||
out.top_shell_layers = std::max<int>(out.top_shell_layers, config.top_shell_layers);
|
||||
out.bottom_shell_layers = std::max<int>(out.bottom_shell_layers, config.bottom_shell_layers);
|
||||
out.small_region_threshold = config.gap_infill_speed.value > 0 ?
|
||||
out.small_region_threshold = config.gap_infill_speed.get_at(print_object.print()->get_extruder_id(config.outer_wall_filament_id - 1)) > 0 ?
|
||||
// Gap fill enabled. Enable a single line of 1/2 extrusion width.
|
||||
0.5f * outer_wall_line_width :
|
||||
// Gap fill disabled. Enable two lines slightly overlapping.
|
||||
|
||||
@@ -581,7 +581,7 @@ void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExP
|
||||
coord_t ext_perimeter_width = this->ext_perimeter_flow.scaled_width();
|
||||
coord_t ext_perimeter_spacing = this->ext_perimeter_flow.scaled_spacing();
|
||||
|
||||
bool has_gap_fill = this->config->gap_infill_speed.value > 0;
|
||||
bool has_gap_fill = this->config->gap_infill_speed.get_at(get_extruder_index(*print_config, this->config->outer_wall_filament_id - 1)) > 0;
|
||||
|
||||
// split the polygons with top/not_top
|
||||
// get the offset from solid surface anchor
|
||||
@@ -1189,7 +1189,7 @@ void PerimeterGenerator::process_classic()
|
||||
// internal flow which is unrelated.
|
||||
coord_t min_spacing = coord_t(perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||
coord_t ext_min_spacing = coord_t(ext_perimeter_spacing * (1 - INSET_OVERLAP_TOLERANCE));
|
||||
bool has_gap_fill = this->config->gap_infill_speed.value > 0;
|
||||
bool has_gap_fill = this->config->gap_infill_speed.get_at(get_extruder_index(*print_config, this->config->outer_wall_filament_id - 1)) > 0;
|
||||
|
||||
// BBS: this flow is for smaller external perimeter for small area
|
||||
coord_t ext_min_spacing_smaller = coord_t(ext_perimeter_spacing * (1 - SMALLER_EXT_INSET_OVERLAP_TOLERANCE));
|
||||
|
||||
@@ -3832,9 +3832,9 @@ void PresetBundle::update_filament_count()
|
||||
: filament_presets.back());
|
||||
}
|
||||
|
||||
bool PresetBundle::support_different_extruders()
|
||||
bool PresetBundle::support_different_extruders() const
|
||||
{
|
||||
Preset& printer_preset = this->printers.get_edited_preset();
|
||||
const Preset& printer_preset = this->printers.get_edited_preset();
|
||||
int extruder_count;
|
||||
bool supported = printer_preset.config.support_different_extruders(extruder_count);
|
||||
|
||||
|
||||
@@ -370,7 +370,7 @@ public:
|
||||
|
||||
//BBS: add some functions for multiple extruders
|
||||
int get_printer_extruder_count() const;
|
||||
bool support_different_extruders();
|
||||
bool support_different_extruders() const;
|
||||
|
||||
// Orca: Ensure filament_presets has at least one slot per nozzle on FFF printers.
|
||||
// Called from (load|update)_selections before the parallel project_config arrays
|
||||
|
||||
+145
-139
@@ -1349,8 +1349,8 @@ StringObjectException Print::validate(std::vector<StringObjectException> *warnin
|
||||
const auto all_regions = m_objects.front()->all_regions();
|
||||
if (all_regions.size() > 1) {
|
||||
// Orca: make sure regions are not compatible
|
||||
if (std::any_of(all_regions.begin() + 1, all_regions.end(), [ra = all_regions.front()](const auto rb) {
|
||||
return !Layer::is_perimeter_compatible(ra, rb);
|
||||
if (std::any_of(all_regions.begin() + 1, all_regions.end(), [this, ra = all_regions.front()](const auto rb) {
|
||||
return !Layer::is_perimeter_compatible(*this, ra, rb);
|
||||
})) {
|
||||
return {L("Spiral (vase) mode does not work when an object contains more than one material."), nullptr, "spiral_mode"};
|
||||
}
|
||||
@@ -1782,146 +1782,152 @@ StringObjectException Print::validate(std::vector<StringObjectException> *warnin
|
||||
// shrinkage warnings below.
|
||||
StringObjectException motion_warning;
|
||||
try {
|
||||
auto check_motion_ability_object_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_object_config.get_abs_value(key) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
auto check_motion_ability_region_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_region_config.get_abs_value(key) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
std::string warning_key;
|
||||
|
||||
const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0];
|
||||
const bool ignore_jerk_validation = m_config.gcode_flavor == gcfMarlinFirmware && max_junction_deviation > 0;
|
||||
|
||||
// check jerk
|
||||
if (!ignore_jerk_validation) {
|
||||
if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 ||
|
||||
m_default_object_config.inner_wall_jerk == 1) {
|
||||
motion_warning.string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces");
|
||||
if (m_default_object_config.outer_wall_jerk == 1)
|
||||
warning_key = "outer_wall_jerk";
|
||||
else if (m_default_object_config.inner_wall_jerk == 1)
|
||||
warning_key = "inner_wall_jerk";
|
||||
else
|
||||
warning_key = "default_jerk";
|
||||
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
|
||||
if (warning_key.empty() && m_default_object_config.default_jerk > 0) {
|
||||
std::vector<std::string> jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk",
|
||||
"top_surface_jerk", "initial_layer_jerk", "travel_jerk"};
|
||||
const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]);
|
||||
warning_key.clear();
|
||||
warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L(
|
||||
"The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\n"
|
||||
"Orca will automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the maximum jerk setting in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check junction deviation
|
||||
else if (m_default_object_config.default_junction_deviation.value > max_junction_deviation) {
|
||||
motion_warning.string = L( "Junction deviation setting exceeds the printer's maximum value (machine_max_junction_deviation).\n"
|
||||
"Orca will automatically cap the junction deviation to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the machine_max_junction_deviation value in your printer's configuration to get higher limits.");
|
||||
motion_warning.opt_key = "default_junction_deviation";
|
||||
}
|
||||
|
||||
// check acceleration
|
||||
const auto max_accel = m_config.machine_max_acceleration_extruding.values[0];
|
||||
if (warning_key.empty() && m_default_object_config.default_acceleration > 0 && max_accel > 0) {
|
||||
const bool support_travel_acc = (m_config.gcode_flavor == gcfRepetier || m_config.gcode_flavor == gcfMarlinFirmware ||
|
||||
m_config.gcode_flavor == gcfRepRapFirmware);
|
||||
|
||||
std::vector<std::string> accel_to_check;
|
||||
if (!support_travel_acc)
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
"travel_acceleration",
|
||||
};
|
||||
else
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_accel);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L("The acceleration setting exceeds the printer's maximum acceleration "
|
||||
"(machine_max_acceleration_extruding).\nOrca will "
|
||||
"automatically cap the acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_extruding value in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
if (support_travel_acc) {
|
||||
const auto max_travel = m_config.machine_max_acceleration_travel.values[0];
|
||||
if (max_travel > 0) {
|
||||
accel_to_check = {
|
||||
"travel_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_travel);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L(
|
||||
"The travel acceleration setting exceeds the printer's maximum travel acceleration "
|
||||
"(machine_max_acceleration_travel).\nOrca will "
|
||||
"automatically cap the travel acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_travel value in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
auto check_extruder = [&](const int extruder_id) {
|
||||
auto check_motion_ability_object_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_object_config.get_abs_value_at(key, extruder_id) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
auto check_motion_ability_region_setting = [&](const std::vector<std::string>& keys_to_check, double limit) -> std::string {
|
||||
std::string warning_key;
|
||||
for (const auto& key : keys_to_check) {
|
||||
if (m_default_region_config.get_abs_value_at(key, extruder_id) > limit) {
|
||||
warning_key = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return warning_key;
|
||||
};
|
||||
std::string warning_key;
|
||||
|
||||
// check speed
|
||||
// Orca: disable the speed check for now as we don't cap the speed
|
||||
// if (warning_key.empty()) {
|
||||
// auto speed_to_check = {"inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed",
|
||||
// "top_surface_speed", "bridge_speed", "internal_bridge_speed", "gap_infill_speed"};
|
||||
// const auto max_speed = std::min(m_config.machine_max_speed_x.values[0], m_config.machine_max_speed_y.values[0]);
|
||||
// warning_key.clear();
|
||||
// warning_key = check_motion_ability_region_setting(speed_to_check, max_speed);
|
||||
// if (warning_key.empty() && m_config.travel_speed > max_speed)
|
||||
// warning_key = "travel_speed";
|
||||
// if (!warning_key.empty()) {
|
||||
// warning->string = L(
|
||||
// "The speed setting exceeds the printer's maximum speed (machine_max_speed_x/machine_max_speed_y).\nOrca will "
|
||||
// "automatically cap the print speed to ensure it doesn't surpass the printer's capabilities.\nYou can adjust the "
|
||||
// "maximum speed setting in your printer's configuration to get higher speeds.");
|
||||
// warning->opt_key = warning_key;
|
||||
// }
|
||||
// }
|
||||
const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0]; // TODO: fix this
|
||||
const bool ignore_jerk_validation = m_config.gcode_flavor == gcfMarlinFirmware && max_junction_deviation > 0;
|
||||
|
||||
// check jerk
|
||||
if (!ignore_jerk_validation) {
|
||||
if (m_default_object_config.default_jerk.get_at(extruder_id) == 1 || m_default_object_config.outer_wall_jerk.get_at(extruder_id) == 1 ||
|
||||
m_default_object_config.inner_wall_jerk.get_at(extruder_id) == 1) {
|
||||
motion_warning.string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces");
|
||||
if (m_default_object_config.outer_wall_jerk.get_at(extruder_id) == 1)
|
||||
warning_key = "outer_wall_jerk";
|
||||
else if (m_default_object_config.inner_wall_jerk.get_at(extruder_id) == 1)
|
||||
warning_key = "inner_wall_jerk";
|
||||
else
|
||||
warning_key = "default_jerk";
|
||||
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
|
||||
if (warning_key.empty() && m_default_object_config.default_jerk.get_at(extruder_id) > 0) {
|
||||
std::vector<std::string> jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk",
|
||||
"top_surface_jerk", "initial_layer_jerk", "travel_jerk"};
|
||||
const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]);
|
||||
warning_key.clear();
|
||||
warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L(
|
||||
"The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\n"
|
||||
"Orca will automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the maximum jerk setting in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check junction deviation
|
||||
// Orca: Only marlin FW supports max junction deviation. Dont display warning if firmware is not supporting it.
|
||||
const bool support_max_junction_deviation = ( m_config.gcode_flavor == gcfMarlinFirmware);
|
||||
if (warning_key.empty() && m_default_object_config.default_junction_deviation.get_at(extruder_id) > max_junction_deviation && support_max_junction_deviation) {
|
||||
motion_warning.string = L( "Junction deviation setting exceeds the printer's maximum value (machine_max_junction_deviation).\n"
|
||||
"Orca will automatically cap the junction deviation to ensure it doesn't surpass the printer's capabilities.\n"
|
||||
"You can adjust the machine_max_junction_deviation value in your printer's configuration to get higher limits.");
|
||||
motion_warning.opt_key = "default_junction_deviation";
|
||||
}
|
||||
|
||||
// check acceleration
|
||||
const auto max_accel = m_config.machine_max_acceleration_extruding.values[0];
|
||||
if (warning_key.empty() && m_default_object_config.default_acceleration.get_at(extruder_id) > 0 && max_accel > 0) {
|
||||
const bool support_travel_acc = (m_config.gcode_flavor == gcfRepetier || m_config.gcode_flavor == gcfMarlinFirmware ||
|
||||
m_config.gcode_flavor == gcfRepRapFirmware);
|
||||
|
||||
std::vector<std::string> accel_to_check;
|
||||
if (!support_travel_acc)
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
"travel_acceleration",
|
||||
};
|
||||
else
|
||||
accel_to_check = {
|
||||
"default_acceleration",
|
||||
"inner_wall_acceleration",
|
||||
"outer_wall_acceleration",
|
||||
"bridge_acceleration",
|
||||
"initial_layer_acceleration",
|
||||
"sparse_infill_acceleration",
|
||||
"internal_solid_infill_acceleration",
|
||||
"top_surface_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_accel);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L("The acceleration setting exceeds the printer's maximum acceleration "
|
||||
"(machine_max_acceleration_extruding).\nOrca will "
|
||||
"automatically cap the acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_extruding value in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
if (support_travel_acc) {
|
||||
const auto max_travel = m_config.machine_max_acceleration_travel.values[0];
|
||||
if (max_travel > 0) {
|
||||
accel_to_check = {
|
||||
"travel_acceleration",
|
||||
};
|
||||
warning_key = check_motion_ability_object_setting(accel_to_check, max_travel);
|
||||
if (!warning_key.empty()) {
|
||||
motion_warning.string = L(
|
||||
"The travel acceleration setting exceeds the printer's maximum travel acceleration "
|
||||
"(machine_max_acceleration_travel).\nOrca will "
|
||||
"automatically cap the travel acceleration speed to ensure it doesn't surpass the printer's "
|
||||
"capabilities.\nYou can adjust the "
|
||||
"machine_max_acceleration_travel value in your printer's configuration to get higher speeds.");
|
||||
motion_warning.opt_key = warning_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check speed
|
||||
// Orca: disable the speed check for now as we don't cap the speed
|
||||
// if (warning_key.empty()) {
|
||||
// auto speed_to_check = {"inner_wall_speed", "outer_wall_speed", "sparse_infill_speed", "internal_solid_infill_speed",
|
||||
// "top_surface_speed", "bridge_speed", "internal_bridge_speed", "gap_infill_speed"};
|
||||
// const auto max_speed = std::min(m_config.machine_max_speed_x.values[0], m_config.machine_max_speed_y.values[0]);
|
||||
// warning_key.clear();
|
||||
// warning_key = check_motion_ability_region_setting(speed_to_check, max_speed);
|
||||
// if (warning_key.empty() && m_config.travel_speed > max_speed)
|
||||
// warning_key = "travel_speed";
|
||||
// if (!warning_key.empty()) {
|
||||
// motion_warning.string = L(
|
||||
// "The speed setting exceeds the printer's maximum speed (machine_max_speed_x/machine_max_speed_y).\nOrca will "
|
||||
// "automatically cap the print speed to ensure it doesn't surpass the printer's capabilities.\nYou can adjust the "
|
||||
// "maximum speed setting in your printer's configuration to get higher speeds.");
|
||||
// motion_warning.opt_key = warning_key;
|
||||
// }
|
||||
// }
|
||||
};
|
||||
check_extruder(0); // TODO: check used extruder variants
|
||||
|
||||
// check wall sequence and precise outer wall
|
||||
if (m_default_region_config.precise_outer_wall && m_default_region_config.wall_sequence != WallSequence::InnerOuter)
|
||||
|
||||
@@ -1189,7 +1189,7 @@ private:
|
||||
std::vector<unsigned int> m_slice_used_filaments_first_layer;
|
||||
|
||||
//BBS: plate's origin
|
||||
Vec3d m_origin;
|
||||
Vec3d m_origin {0, 0, 0};
|
||||
//BBS: modified_count
|
||||
int m_modified_count {0};
|
||||
//BBS
|
||||
|
||||
@@ -1163,8 +1163,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
|
||||
//apply extruder related values
|
||||
if (!extruder_applied) {
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant");
|
||||
// variant_2 must be processed first, because variant_1 will make `printer_extruder_id` and `printer_extruder_variant` half of the size that makes `get_index_for_extruder` no longer work properly
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2);
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant");
|
||||
//update print config related with variants
|
||||
new_full_config.update_values_to_printer_extruders(new_full_config, print_options_with_variant, "print_extruder_id", "print_extruder_variant");
|
||||
|
||||
|
||||
+344
-286
File diff suppressed because it is too large
Load Diff
@@ -430,6 +430,17 @@ enum FilamentMapMode {
|
||||
|
||||
extern std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type);
|
||||
|
||||
static std::set<NozzleVolumeType> get_valid_nozzle_volume_type() {
|
||||
std::set<NozzleVolumeType> type;
|
||||
for (int i = 0; i <= nvtMaxNozzleVolumeType; ++i) {
|
||||
auto t = static_cast<NozzleVolumeType>(i);
|
||||
// TODO: Orca: Support hybrid
|
||||
//if (t == nvtHybrid) continue;
|
||||
type.insert(t);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string get_nozzle_volume_type_string(NozzleVolumeType nozzle_volume_type);
|
||||
|
||||
static std::string bed_type_to_gcode_string(const BedType type)
|
||||
@@ -658,7 +669,7 @@ public:
|
||||
|
||||
//BBS
|
||||
bool is_using_different_extruders();
|
||||
bool support_different_extruders(int& extruder_count);
|
||||
bool support_different_extruders(int& extruder_count) const;
|
||||
int get_index_for_extruder(int extruder_or_filament_id, std::string id_name, ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type, std::string variant_name, unsigned int stride = 1) const;
|
||||
void update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name, unsigned int stride = 1, unsigned int extruder_id = 0);
|
||||
void update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, std::set<std::string>& key_set, std::string id_name, std::string variant_name);
|
||||
@@ -965,13 +976,13 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, support_interface_bottom_layers))
|
||||
// Spacing between interface lines (the hatching distance). Set zero to get a solid interface.
|
||||
((ConfigOptionFloat, support_interface_spacing))
|
||||
((ConfigOptionFloat, support_interface_speed))
|
||||
((ConfigOptionFloatsNullable, support_interface_speed))
|
||||
((ConfigOptionEnum<SupportMaterialPattern>, support_base_pattern))
|
||||
((ConfigOptionEnum<SupportMaterialInterfacePattern>, support_interface_pattern))
|
||||
// Spacing between support material lines (the hatching distance).
|
||||
((ConfigOptionFloat, support_base_pattern_spacing))
|
||||
((ConfigOptionFloat, support_expansion))
|
||||
((ConfigOptionFloat, support_speed))
|
||||
((ConfigOptionFloatsNullable, support_speed))
|
||||
((ConfigOptionEnum<SupportMaterialStyle>, support_style))
|
||||
|
||||
// Orca: a flag enabling the ability to override flow ratios
|
||||
@@ -1039,25 +1050,25 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, min_length_factor))
|
||||
|
||||
// Move all acceleration and jerk settings to object
|
||||
((ConfigOptionFloat, default_acceleration))
|
||||
((ConfigOptionFloat, outer_wall_acceleration))
|
||||
((ConfigOptionFloat, inner_wall_acceleration))
|
||||
((ConfigOptionFloat, top_surface_acceleration))
|
||||
((ConfigOptionFloat, initial_layer_acceleration))
|
||||
((ConfigOptionFloatOrPercent, bridge_acceleration))
|
||||
((ConfigOptionFloat, travel_acceleration))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_acceleration))
|
||||
((ConfigOptionFloatOrPercent, internal_solid_infill_acceleration))
|
||||
((ConfigOptionFloatsNullable, default_acceleration))
|
||||
((ConfigOptionFloatsNullable, outer_wall_acceleration))
|
||||
((ConfigOptionFloatsNullable, inner_wall_acceleration))
|
||||
((ConfigOptionFloatsNullable, top_surface_acceleration))
|
||||
((ConfigOptionFloatsNullable, initial_layer_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, bridge_acceleration))
|
||||
((ConfigOptionFloatsNullable, travel_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, sparse_infill_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, internal_solid_infill_acceleration))
|
||||
|
||||
((ConfigOptionFloat, default_jerk))
|
||||
((ConfigOptionFloat, outer_wall_jerk))
|
||||
((ConfigOptionFloat, inner_wall_jerk))
|
||||
((ConfigOptionFloat, infill_jerk))
|
||||
((ConfigOptionFloat, top_surface_jerk))
|
||||
((ConfigOptionFloat, initial_layer_jerk))
|
||||
((ConfigOptionFloat, travel_jerk))
|
||||
((ConfigOptionFloatsNullable, default_jerk))
|
||||
((ConfigOptionFloatsNullable, outer_wall_jerk))
|
||||
((ConfigOptionFloatsNullable, inner_wall_jerk))
|
||||
((ConfigOptionFloatsNullable, infill_jerk))
|
||||
((ConfigOptionFloatsNullable, top_surface_jerk))
|
||||
((ConfigOptionFloatsNullable, initial_layer_jerk))
|
||||
((ConfigOptionFloatsNullable, travel_jerk))
|
||||
((ConfigOptionBool, precise_z_height))
|
||||
((ConfigOptionFloat, default_junction_deviation))
|
||||
((ConfigOptionFloatsNullable, default_junction_deviation))
|
||||
|
||||
((ConfigOptionBool, interlocking_beam))
|
||||
((ConfigOptionFloat,interlocking_beam_width))
|
||||
@@ -1084,8 +1095,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloat, bridge_flow))
|
||||
((ConfigOptionFloatOrPercent, bridge_line_width))
|
||||
((ConfigOptionFloat, internal_bridge_flow))
|
||||
((ConfigOptionFloat, bridge_speed))
|
||||
((ConfigOptionFloatOrPercent, internal_bridge_speed))
|
||||
((ConfigOptionFloatsNullable, bridge_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, internal_bridge_speed))
|
||||
((ConfigOptionEnum<EnsureVerticalShellThickness>, ensure_vertical_shell_thickness))
|
||||
((ConfigOptionPercent, top_surface_density))
|
||||
((ConfigOptionPercent, bottom_surface_density))
|
||||
@@ -1093,7 +1104,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionEnum<InfillPattern>, bottom_surface_pattern))
|
||||
((ConfigOptionEnum<InfillPattern>, internal_solid_infill_pattern))
|
||||
((ConfigOptionFloatOrPercent, outer_wall_line_width))
|
||||
((ConfigOptionFloat, outer_wall_speed))
|
||||
((ConfigOptionFloatsNullable, outer_wall_speed))
|
||||
((ConfigOptionFloat, infill_direction))
|
||||
((ConfigOptionFloat, solid_infill_direction))
|
||||
((ConfigOptionString, solid_infill_rotate_template))
|
||||
@@ -1122,12 +1133,12 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, fuzzy_skin_ripples_per_layer))
|
||||
((ConfigOptionPercent, fuzzy_skin_ripple_offset))
|
||||
((ConfigOptionInt, fuzzy_skin_layers_between_ripple_offset))
|
||||
((ConfigOptionFloat, gap_infill_speed))
|
||||
((ConfigOptionFloatsNullable, gap_infill_speed))
|
||||
((ConfigOptionInt, sparse_infill_filament_id))
|
||||
((ConfigOptionFloatOrPercent, sparse_infill_line_width))
|
||||
((ConfigOptionPercent, infill_wall_overlap))
|
||||
((ConfigOptionPercent, top_bottom_infill_wall_overlap))
|
||||
((ConfigOptionFloat, sparse_infill_speed))
|
||||
((ConfigOptionFloatsNullable, sparse_infill_speed))
|
||||
((ConfigOptionPercent, skeleton_infill_density))
|
||||
((ConfigOptionPercent, skin_infill_density))
|
||||
((ConfigOptionFloat, infill_lock_depth))
|
||||
@@ -1159,7 +1170,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, outer_wall_filament_id))
|
||||
((ConfigOptionInt, inner_wall_filament_id))
|
||||
((ConfigOptionFloatOrPercent, inner_wall_line_width))
|
||||
((ConfigOptionFloat, inner_wall_speed))
|
||||
((ConfigOptionFloatsNullable, inner_wall_speed))
|
||||
// Total number of perimeters.
|
||||
((ConfigOptionInt, wall_loops))
|
||||
((ConfigOptionBool, alternate_extra_wall))
|
||||
@@ -1168,19 +1179,19 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionInt, top_surface_filament_id))
|
||||
((ConfigOptionInt, bottom_surface_filament_id))
|
||||
((ConfigOptionFloatOrPercent, internal_solid_infill_line_width))
|
||||
((ConfigOptionFloat, internal_solid_infill_speed))
|
||||
((ConfigOptionFloatsNullable, internal_solid_infill_speed))
|
||||
// Detect thin walls.
|
||||
((ConfigOptionBool, detect_thin_wall))
|
||||
((ConfigOptionFloatOrPercent, top_surface_line_width))
|
||||
((ConfigOptionInt, top_shell_layers))
|
||||
((ConfigOptionFloat, top_shell_thickness))
|
||||
((ConfigOptionFloat, top_surface_speed))
|
||||
((ConfigOptionFloatsNullable, top_surface_speed))
|
||||
//BBS
|
||||
((ConfigOptionBool, enable_overhang_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_1_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_2_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_3_4_speed))
|
||||
((ConfigOptionFloatOrPercent, overhang_4_4_speed))
|
||||
((ConfigOptionBoolsNullable, enable_overhang_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_1_4_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_2_4_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_3_4_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, overhang_4_4_speed))
|
||||
((ConfigOptionBool, only_one_wall_top))
|
||||
|
||||
//SoftFever
|
||||
@@ -1196,8 +1207,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, precise_outer_wall))
|
||||
((ConfigOptionPercent, bridge_density))
|
||||
((ConfigOptionFloat, filter_out_gap_fill))
|
||||
((ConfigOptionFloatOrPercent, small_perimeter_speed))
|
||||
((ConfigOptionFloat, small_perimeter_threshold))
|
||||
((ConfigOptionFloatsOrPercentsNullable, small_perimeter_speed))
|
||||
((ConfigOptionFloatsNullable, small_perimeter_threshold))
|
||||
((ConfigOptionFloat, top_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloat, bottom_solid_infill_flow_ratio))
|
||||
((ConfigOptionFloatOrPercent, infill_anchor))
|
||||
@@ -1206,7 +1217,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
// Orca
|
||||
((ConfigOptionBool, make_overhang_printable))
|
||||
((ConfigOptionBool, extra_perimeters_on_overhangs))
|
||||
((ConfigOptionBool, slowdown_for_curled_perimeters))
|
||||
((ConfigOptionBoolsNullable, slowdown_for_curled_perimeters))
|
||||
((ConfigOptionBool, hole_to_polyhole))
|
||||
((ConfigOptionFloatOrPercent, hole_to_polyhole_threshold))
|
||||
((ConfigOptionBool, hole_to_polyhole_twisted))
|
||||
@@ -1369,7 +1380,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
|
||||
((ConfigOptionFloat, max_volumetric_extrusion_rate_slope))
|
||||
((ConfigOptionFloat, max_volumetric_extrusion_rate_slope_segment_length))
|
||||
((ConfigOptionBool, extrusion_rate_smoothing_external_perimeter_only))
|
||||
((ConfigOptionBool, extrusion_rate_smoothing_external_perimeter_only))
|
||||
|
||||
|
||||
((ConfigOptionPercents, retract_before_wipe))
|
||||
@@ -1401,8 +1412,8 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionString, change_extrusion_role_gcode))
|
||||
((ConfigOptionString, process_change_extrusion_role_gcode))
|
||||
((ConfigOptionStrings, filament_change_extrusion_role_gcode))
|
||||
((ConfigOptionFloat, travel_speed))
|
||||
((ConfigOptionFloat, travel_speed_z))
|
||||
((ConfigOptionFloatsNullable, travel_speed))
|
||||
((ConfigOptionFloatsNullable, travel_speed_z))
|
||||
((ConfigOptionBool, silent_mode))
|
||||
((ConfigOptionString, machine_pause_gcode))
|
||||
((ConfigOptionString, template_custom_gcode))
|
||||
@@ -1426,9 +1437,9 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, use_relative_e_distances))
|
||||
((ConfigOptionBool, accel_to_decel_enable))
|
||||
((ConfigOptionPercent, accel_to_decel_factor))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_travel_speed))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_travel_acceleration))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_travel_jerk))
|
||||
((ConfigOptionFloatsOrPercentsNullable, initial_layer_travel_speed))
|
||||
((ConfigOptionFloatsOrPercentsNullable, initial_layer_travel_acceleration))
|
||||
((ConfigOptionFloatsOrPercentsNullable, initial_layer_travel_jerk))
|
||||
((ConfigOptionBool, bbl_calib_mark_logo))
|
||||
((ConfigOptionBool, disable_m73))
|
||||
|
||||
@@ -1538,10 +1549,10 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionInts, complete_print_exhaust_fan_speed))
|
||||
((ConfigOptionFloatOrPercent, initial_layer_line_width))
|
||||
((ConfigOptionFloat, initial_layer_print_height))
|
||||
((ConfigOptionFloat, initial_layer_speed))
|
||||
((ConfigOptionFloatsNullable, initial_layer_speed))
|
||||
|
||||
//BBS
|
||||
((ConfigOptionFloat, initial_layer_infill_speed))
|
||||
((ConfigOptionFloatsNullable, initial_layer_infill_speed))
|
||||
((ConfigOptionInts, nozzle_temperature_initial_layer))
|
||||
((ConfigOptionInts, full_fan_speed_layer))
|
||||
((ConfigOptionFloats, fan_max_speed))
|
||||
|
||||
@@ -897,13 +897,15 @@ void PrintObject::generate_support_material()
|
||||
void PrintObject::estimate_curled_extrusions()
|
||||
{
|
||||
if (this->set_started(posEstimateCurledExtrusions)) {
|
||||
if ( std::any_of(this->print()->m_print_regions.begin(), this->print()->m_print_regions.end(),
|
||||
[](const PrintRegion *region) { return region->config().enable_overhang_speed.getBool(); })) {
|
||||
if ( std::any_of(this->print()->m_print_regions.begin(), this->print()->m_print_regions.end(), [](const PrintRegion* region) {
|
||||
const auto& cfg = region->config().enable_overhang_speed.values;
|
||||
return std::any_of(cfg.begin(), cfg.end(), [](const unsigned char v) { return (bool) v; });
|
||||
})) {
|
||||
|
||||
// Estimate curling of support material and add it to the malformaition lines of each layer
|
||||
float support_flow_width = support_material_flow(this, this->config().layer_height).width();
|
||||
SupportSpotsGenerator::Params params{this->print()->m_config.filament_type.values,
|
||||
float(this->print()->default_object_config().inner_wall_acceleration.getFloat()),
|
||||
/*float(this->print()->default_object_config().inner_wall_acceleration.getFloat()),*/
|
||||
this->config().raft_layers.getInt(), this->config().brim_type.value,
|
||||
float(this->config().brim_width.getFloat())};
|
||||
SupportSpotsGenerator::estimate_malformations(this->layers(), params);
|
||||
@@ -1150,11 +1152,11 @@ bool PrintObject::invalidate_state_by_config_options(
|
||||
// todo multi_extruders: Parameter migration between single and double extruder printers
|
||||
auto is_gap_fill_changed_state_due_to_speed = [&opt_key, &old_config, &new_config]() -> bool {
|
||||
if (opt_key == "gap_infill_speed") {
|
||||
const auto *old_gap_fill_speed = old_config.option<ConfigOptionFloat>(opt_key);
|
||||
const auto *new_gap_fill_speed = new_config.option<ConfigOptionFloat>(opt_key);
|
||||
const auto *old_gap_fill_speed = old_config.option<ConfigOptionFloatsNullable>(opt_key);
|
||||
const auto *new_gap_fill_speed = new_config.option<ConfigOptionFloatsNullable>(opt_key);
|
||||
assert(old_gap_fill_speed && new_gap_fill_speed);
|
||||
return (old_gap_fill_speed->value > 0.f && new_gap_fill_speed->value == 0.f) ||
|
||||
(old_gap_fill_speed->value == 0.f && new_gap_fill_speed->value > 0.f);
|
||||
return (old_gap_fill_speed->values.size() != new_gap_fill_speed->values.size())
|
||||
|| (old_gap_fill_speed->values != new_gap_fill_speed->values);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace SupportSpotsGenerator {
|
||||
struct Params
|
||||
{
|
||||
Params(
|
||||
const std::vector<std::string> &filament_types, float max_acceleration, int raft_layers_count, BrimType brim_type, float brim_width)
|
||||
: max_acceleration(max_acceleration), raft_layers_count(raft_layers_count), brim_type(brim_type), brim_width(brim_width)
|
||||
const std::vector<std::string> &filament_types/*, float max_acceleration*/, int raft_layers_count, BrimType brim_type, float brim_width)
|
||||
: /*max_acceleration(max_acceleration), */raft_layers_count(raft_layers_count), brim_type(brim_type), brim_width(brim_width)
|
||||
{
|
||||
if (filament_types.size() > 1) {
|
||||
BOOST_LOG_TRIVIAL(warning)
|
||||
@@ -36,8 +36,8 @@ struct Params
|
||||
|
||||
// the algorithm should use the following units for all computations: distance [mm], mass [g], time [s], force [g*mm/s^2]
|
||||
const float bridge_distance = 16.0f; // mm
|
||||
const float max_acceleration; // mm/s^2 ; max acceleration of object in XY -- should be applicable only to printers with bed slinger,
|
||||
// however we do not have such info yet. The force is usually small anyway, so not such a big deal to include it everytime
|
||||
// const float max_acceleration; // mm/s^2 ; max acceleration of object in XY -- should be applicable only to printers with bed slinger,
|
||||
// // however we do not have such info yet. The force is usually small anyway, so not such a big deal to include it everytime
|
||||
const int raft_layers_count;
|
||||
std::string filament_type;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &conf
|
||||
const float nozzle_diameter = config.option<ConfigOptionFloats>("nozzle_diameter")->get_at(extruder_id);
|
||||
if (line_width <= 0.) line_width = Flow::auto_extrusion_width(frPerimeter, nozzle_diameter);
|
||||
Flow pattern_line = Flow(line_width, layer_height, nozzle_diameter);
|
||||
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloat>("outer_wall_speed")->value),
|
||||
auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option<ConfigOptionFloatsNullable>("outer_wall_speed")->get_at(extruder_id)),
|
||||
filament_max_volumetric_speed / pattern_line.mm3_per_mm());
|
||||
|
||||
return std::floor(pa_speed);
|
||||
|
||||
@@ -280,7 +280,7 @@ private:
|
||||
|
||||
struct SuggestedConfigCalibPAPattern
|
||||
{
|
||||
const std::vector<std::pair<std::string, double>> float_pairs{{"initial_layer_speed", 30}};
|
||||
const std::vector<std::pair<std::string, std::vector<double>>> floats_pairs{{"initial_layer_speed", {30}}};
|
||||
|
||||
const std::vector<std::pair<std::string, double>> nozzle_ratio_pairs{{"line_width", 112.5}, {"initial_layer_line_width", 140}};
|
||||
|
||||
@@ -312,13 +312,13 @@ public:
|
||||
|
||||
protected:
|
||||
// todo multi_extruders:
|
||||
double speed_first_layer() const { return m_config.option<ConfigOptionFloat>("initial_layer_speed")->value; };
|
||||
double speed_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_speed")->value; };
|
||||
double accel_perimeter() const { return m_config.option<ConfigOptionFloat>("outer_wall_acceleration")->value; }
|
||||
double speed_first_layer() const { return m_config.get_abs_value_at("initial_layer_speed", m_params.extruder_id); };
|
||||
double speed_perimeter() const { return m_config.get_abs_value_at("outer_wall_speed", m_params.extruder_id); };
|
||||
double accel_perimeter() const { return m_config.get_abs_value_at("outer_wall_acceleration", m_params.extruder_id); }
|
||||
double line_width_first_layer() const
|
||||
{
|
||||
// TODO: FIXME: find out current filament/extruder?
|
||||
const double nozzle_diameter = m_config.opt_float("nozzle_diameter", 0);
|
||||
const double nozzle_diameter = m_config.opt_float("nozzle_diameter", m_params.extruder_id);
|
||||
return m_config.get_abs_value("initial_layer_line_width", nozzle_diameter);
|
||||
};
|
||||
double line_width() const;
|
||||
|
||||
Reference in New Issue
Block a user