mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-06 09:37:55 +00:00
feat(libslic3r): multi-nozzle slicing engine for H2C/A2L
Port BambuStudio's dual-nozzle slicing core: H2C-era config keys, filament-to-nozzle grouping with per-layer dynamic regrouping, filament/nozzle/hotend gcode placeholder vocabulary, multi-nozzle wipe tower pre-heat/pre-cool, the two-pass pre-cooling injector, and corexy farthest-point timelapse.
This commit is contained in:
@@ -83,6 +83,15 @@ const std::vector<std::string> filament_extruder_override_keys = {
|
||||
"filament_retraction_distances_when_cut"
|
||||
};
|
||||
|
||||
// Some filament override parameters are generated from filament_extruder_override_keys,
|
||||
// while filament_retract_length_nc is defined separately. Keep the generator list
|
||||
// unchanged and use this helper for behavior checks that need the full override set.
|
||||
bool is_filament_extruder_override_key(const std::string &opt_key)
|
||||
{
|
||||
return std::find(filament_extruder_override_keys.begin(), filament_extruder_override_keys.end(), opt_key) != filament_extruder_override_keys.end() ||
|
||||
opt_key == "filament_retract_length_nc";
|
||||
}
|
||||
|
||||
size_t get_extruder_index(const GCodeConfig& config, unsigned int filament_id)
|
||||
{
|
||||
if (filament_id < config.filament_map.size()) {
|
||||
@@ -569,17 +578,28 @@ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ExtruderType)
|
||||
|
||||
static const t_config_enum_values s_keys_map_NozzleVolumeType = {
|
||||
{ "Standard", nvtStandard },
|
||||
{ "High Flow", nvtHighFlow }
|
||||
{ "High Flow", nvtHighFlow },
|
||||
{ "TPU High Flow", nvtTPUHighFlow },
|
||||
{ "Hybrid", nvtHybrid }
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NozzleVolumeType)
|
||||
|
||||
static const t_config_enum_values s_keys_map_FilamentMapMode = {
|
||||
{ "Auto For Flush", fmmAutoForFlush },
|
||||
{ "Auto For Match", fmmAutoForMatch },
|
||||
{ "Manual", fmmManual }
|
||||
{ "Manual", fmmManual },
|
||||
{ "Nozzle Manual", fmmNozzleManual }
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FilamentMapMode)
|
||||
|
||||
// PrimeVolumeMode. Serialized string keys must stay stable; they round-trip through .3mf.
|
||||
static const t_config_enum_values s_keys_map_PrimeVolumeMode = {
|
||||
{ "Default", pvmDefault },
|
||||
{ "Saving", pvmSaving },
|
||||
{ "Fast", pvmFast }
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrimeVolumeMode)
|
||||
|
||||
|
||||
//BBS
|
||||
std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type)
|
||||
@@ -650,6 +670,60 @@ std::vector<std::string> save_extruder_ams_count_to_string(const std::vector<std
|
||||
return extruder_ams_count_str;
|
||||
}
|
||||
|
||||
// Parses the extruder_nozzle_stats option: one "|"-separated token list per
|
||||
// extruder, each token
|
||||
// "<volume_type_name>#<count>". Empty string => no per-type stats for that extruder.
|
||||
std::vector<std::map<NozzleVolumeType, int>> get_extruder_nozzle_stats(const std::vector<std::string> &strs)
|
||||
{
|
||||
std::vector<std::map<NozzleVolumeType, int>> extruder_nozzle_counts;
|
||||
for (const std::string &str : strs) {
|
||||
std::map<NozzleVolumeType, int> nozzle_count_map;
|
||||
if (str.empty()) {
|
||||
extruder_nozzle_counts.emplace_back(nozzle_count_map);
|
||||
continue;
|
||||
}
|
||||
std::vector<std::string> nozzle_infos;
|
||||
boost::algorithm::split(nozzle_infos, str, boost::algorithm::is_any_of("|"));
|
||||
for (auto &nozzle_info : nozzle_infos) {
|
||||
std::vector<std::string> attr;
|
||||
boost::algorithm::split(attr, nozzle_info, boost::algorithm::is_any_of("#"));
|
||||
// Guard against malformed device/project data: skip tokens without a "<type>#<count>"
|
||||
// shape or with an unknown volume-type key instead of throwing (.at) or reading attr[1]
|
||||
// out of bounds. Corrupt tokens are dropped and logged; the rest still parse.
|
||||
if (attr.size() < 2) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "get_extruder_nozzle_stats: skipping malformed token '" << nozzle_info << "'";
|
||||
continue;
|
||||
}
|
||||
auto it = s_keys_map_NozzleVolumeType.find(attr[0]);
|
||||
if (it == s_keys_map_NozzleVolumeType.end()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "get_extruder_nozzle_stats: skipping unknown nozzle volume type '" << attr[0] << "'";
|
||||
continue;
|
||||
}
|
||||
NozzleVolumeType volume_type = NozzleVolumeType(it->second);
|
||||
int nozzle_count = std::atoi(attr[1].c_str());
|
||||
nozzle_count_map[volume_type] = nozzle_count;
|
||||
}
|
||||
extruder_nozzle_counts.emplace_back(nozzle_count_map);
|
||||
}
|
||||
return extruder_nozzle_counts;
|
||||
}
|
||||
|
||||
std::vector<std::string> save_extruder_nozzle_stats_to_string(const std::vector<std::map<NozzleVolumeType, int>> &extruder_nozzle_stats)
|
||||
{
|
||||
std::vector<std::string> extruder_nozzle_count_str;
|
||||
for (size_t idx = 0; idx < extruder_nozzle_stats.size(); ++idx) {
|
||||
std::ostringstream oss;
|
||||
const auto &item = extruder_nozzle_stats[idx];
|
||||
for (auto it = item.begin(); it != item.end(); ++it) {
|
||||
oss << get_nozzle_volume_type_string(it->first) << "#" << it->second;
|
||||
if (std::next(it) != item.end())
|
||||
oss << "|";
|
||||
}
|
||||
extruder_nozzle_count_str.emplace_back(oss.str());
|
||||
}
|
||||
return extruder_nozzle_count_str;
|
||||
}
|
||||
|
||||
static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology)
|
||||
{
|
||||
for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options)
|
||||
@@ -2548,6 +2622,25 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionInts{1});
|
||||
|
||||
// Multi-nozzle: per-filament map to the config slot identified by (extruder, nozzle_volume_type).
|
||||
// Forward-compat-only registration with no consumer yet.
|
||||
// Orca: resolves per-variant slots via get_index_for_extruder at PrintApply time rather than a
|
||||
// read-time filament-config-index lookup, so nothing in src/ reads this key. Kept registered so an
|
||||
// H2C project/config that carries it loads without an unknown-option substitution warning.
|
||||
// Internal use only, no translation.
|
||||
def = this->add("filament_map_2", coInts);
|
||||
def->label = "Filament map plus for multi nozzle";
|
||||
def->tooltip = "Filament map to the index identified by extruder and nozzle_volume_type";
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionInts{1});
|
||||
|
||||
// Per-filament nozzle-volume-type override (multi-volume/Hybrid). Registered so the value
|
||||
// round-trips through .3mf plate metadata (filament_volume_maps); load/save-only for now and
|
||||
// inert for existing printers (unread by slicing until the multi-volume pipeline lands).
|
||||
def = this->add("filament_volume_map", coInts);
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionInts{(int)(NozzleVolumeType::nvtStandard)});
|
||||
|
||||
def = this->add("physical_extruder_map",coInts);
|
||||
// internal use only, don't need translation
|
||||
def->label = "Map the logical extruder to physical extruder";
|
||||
@@ -2563,14 +2656,22 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_values.push_back("Auto For Flush");
|
||||
def->enum_values.push_back("Auto For Match");
|
||||
def->enum_values.push_back("Manual");
|
||||
def->enum_values.push_back("Nozzle Manual");
|
||||
def->enum_values.push_back("Default");
|
||||
def->enum_labels.push_back(L("Auto For Flush"));
|
||||
def->enum_labels.push_back(L("Auto For Match"));
|
||||
def->enum_labels.push_back(L("Manual"));
|
||||
def->enum_labels.push_back(L("Nozzle Manual"));
|
||||
def->enum_labels.push_back(L("Default"));
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionEnum<FilamentMapMode>(fmmAutoForFlush));
|
||||
|
||||
// Fully-manual mode (fmmNozzleManual): per-filament -> physical-nozzle assignment.
|
||||
// Inert until the nozzle-assignment engine consumes it. Internal use only, no translation.
|
||||
def = this->add("filament_nozzle_map", coInts);
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionInts{1});
|
||||
|
||||
def = this->add("filament_flush_temp", coInts);
|
||||
def->label = L("Flush temperature");
|
||||
def->tooltip = L("Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range.");
|
||||
@@ -2581,6 +2682,19 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L(u8"\u2103" /* °C */); // degrees Celsius, CIS languages need translation
|
||||
def->set_default_value(new ConfigOptionIntsNullable{0});
|
||||
|
||||
// Fast-purge flush temperature: used only when prime_volume_mode==Fast.
|
||||
// Default 0 (fall back to the recommended-range upper bound, identical to filament_flush_temp),
|
||||
// so the key is inert for the shipping fleet. Kept out of the g-code config block (banned_keys).
|
||||
def = this->add("filament_flush_temp_fast", coInts);
|
||||
def->label = L("Flush temperature");
|
||||
def->tooltip = L("Flush temperature used in fast purge mode.");
|
||||
def->mode = comAdvanced;
|
||||
def->nullable = true;
|
||||
def->min = 0;
|
||||
def->max = max_temp;
|
||||
def->sidetext = L(u8"℃" /* °C */); // degrees Celsius, CIS languages need translation
|
||||
def->set_default_value(new ConfigOptionIntsNullable{0});
|
||||
|
||||
def = this->add("filament_flush_volumetric_speed", coFloats);
|
||||
def->label = L("Flush volumetric speed");
|
||||
def->tooltip = L("Volumetric speed when flushing filament. 0 indicates the max volumetric speed.");
|
||||
@@ -2954,6 +3068,18 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionInts{3});
|
||||
|
||||
// A single 32-bit int encodes the compatibility level of a filament across all extruders (up to 10).
|
||||
// Every 3 bits represent one extruder: bits [3*i, 3*i+2] -> extruder i.
|
||||
// Compatibility levels: 0 = printable, 1 = error, 2 = critical warning, 3 = warning (4-7 reserved).
|
||||
// Default 0 (printable) keeps the key inert for filaments/printers that do not declare it.
|
||||
def = this->add("filament_extruder_compatibility", coInts);
|
||||
def->label = L("Filament-extruder compatibility");
|
||||
def->tooltip = L("A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). "
|
||||
"Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). "
|
||||
"0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved.");
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionInts{0});
|
||||
|
||||
// BBS
|
||||
def = this->add("temperature_vitrification", coInts);
|
||||
def->label = L("Softening temperature");
|
||||
@@ -3857,6 +3983,12 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode=comDevelop;
|
||||
def->set_default_value(new ConfigOptionBool(true));
|
||||
|
||||
def = this->add("cooling_filter_enabled", coBool);
|
||||
def->label = L("Use cooling filter");
|
||||
def->tooltip = L("Enable this if printer support cooling filter");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("gcode_flavor", coEnum);
|
||||
def->label = L("G-code flavor");
|
||||
def->tooltip = L("What kind of G-code the printer is compatible with.");
|
||||
@@ -4659,6 +4791,39 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionFloats{ 0., 0. });
|
||||
|
||||
// Bedslinger mass/force limits.
|
||||
// Consumed by GCode::mass_load_limited_machine_acceleration (curr_y_acceleration_limit)
|
||||
// and the printed-mass check. Default 0 keeps them inactive for existing printers.
|
||||
def = this->add("machine_max_force_Y", coFloat);
|
||||
def->full_label = L("Maximum force of the Y axis");
|
||||
def->category = L("Machine limits");
|
||||
def->readonly = false;
|
||||
def->tooltip = L("The allowed maximum output force of Y axis");
|
||||
def->sidetext = L("N");
|
||||
def->min = 0;
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("machine_bed_mass_Y", coFloat);
|
||||
def->full_label = L("Bed mass of the Y axis");
|
||||
def->category = L("Machine limits");
|
||||
def->readonly = false;
|
||||
def->tooltip = L("The machine bed mass load of Y axis");
|
||||
def->sidetext = L("g");
|
||||
def->min = 0;
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("machine_max_printed_mass", coFloat);
|
||||
def->full_label = L("The allowed max printed mass");
|
||||
def->category = L("Machine limits");
|
||||
def->readonly = false;
|
||||
def->tooltip = L("The allowed max printed mass on a plate");
|
||||
def->sidetext = L("g");
|
||||
def->min = 0;
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
// M204 P... [mm/sec^2]
|
||||
def = this->add("machine_max_acceleration_extruding", coFloats);
|
||||
def->full_label = L("Maximum acceleration for extruding");
|
||||
@@ -5404,10 +5569,15 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = "Nozzle Volume Type";
|
||||
def->tooltip = "Nozzle volume type for extruders.";
|
||||
def->enum_keys_map = &ConfigOptionEnum<NozzleVolumeType>::get_enum_values();
|
||||
// Order must match the NozzleVolumeType enum values (Standard=0, High Flow=1, Hybrid=2, TPU High Flow=3).
|
||||
def->enum_values.push_back(L("Standard"));
|
||||
def->enum_values.push_back(L("High Flow"));
|
||||
def->enum_values.push_back(L("Hybrid"));
|
||||
def->enum_values.push_back(L("TPU High Flow"));
|
||||
def->enum_labels.push_back(L("Standard"));
|
||||
def->enum_labels.push_back(L("High Flow"));
|
||||
def->enum_labels.push_back(L("Hybrid"));
|
||||
def->enum_labels.push_back(L("TPU High Flow"));
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard });
|
||||
|
||||
@@ -5418,8 +5588,12 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_keys_map = &ConfigOptionEnum<NozzleVolumeType>::get_enum_values();
|
||||
def->enum_values.push_back(L("Standard"));
|
||||
def->enum_values.push_back(L("High Flow"));
|
||||
def->enum_values.push_back(L("Hybrid"));
|
||||
def->enum_values.push_back(L("TPU High Flow"));
|
||||
def->enum_labels.push_back(L("Standard"));
|
||||
def->enum_labels.push_back(L("High Flow"));
|
||||
def->enum_labels.push_back(L("Hybrid"));
|
||||
def->enum_labels.push_back(L("TPU High Flow"));
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard });
|
||||
|
||||
@@ -5436,6 +5610,43 @@ void PrintConfigDef::init_fff_params()
|
||||
def->tooltip = "AMS counts per extruder.";
|
||||
def->set_default_value(new ConfigOptionStrings { });
|
||||
|
||||
// Multi-nozzle: per-extruder physical nozzle inventory by volume type,
|
||||
// "<volume_type>#<count>" tokens joined by "|". Internal use only, no translation.
|
||||
def = this->add("extruder_nozzle_stats", coStrings);
|
||||
def->label = "Extruder nozzle stats";
|
||||
def->tooltip = "Physical nozzle counts per extruder, keyed by nozzle volume type.";
|
||||
def->set_default_value(new ConfigOptionStrings { });
|
||||
|
||||
// Multi-nozzle: number of physical nozzles per extruder. Forward-compat-only registration
|
||||
// with no slicing consumer: the nozzle-assignment engine derives its per-extruder physical nozzle
|
||||
// inventory from the richer `extruder_nozzle_stats` key, not from this scalar count, so nothing in
|
||||
// src/ reads it. Kept registered so an H2C project/config that carries the key loads without an
|
||||
// unknown-option substitution warning. Default {1} == today's single-nozzle-per-extruder assumption,
|
||||
// so absent/default is a no-op for every shipping printer. Internal use only, no translation.
|
||||
def = this->add("extruder_nozzle_count", coInts);
|
||||
def->label = "extruder nozzle count";
|
||||
def->tooltip = "extruder nozzle count";
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionInts{1});
|
||||
|
||||
// Per-nozzle volume type. Forward-compat-only registration with no slicing consumer — nothing in
|
||||
// src/ reads it; the engine resolves per-nozzle volume types from `extruder_nozzle_stats` tokens
|
||||
// instead. Kept registered so a project/config carrying it loads without an unknown-option
|
||||
// substitution warning. Registers Standard/High Flow/TPU High Flow only (no Hybrid).
|
||||
// Internal use only, no translation.
|
||||
def = this->add("extruder_nozzle_volume_type", coEnums);
|
||||
def->label = "Extruder nozzle volume type";
|
||||
def->tooltip = "Nozzle volume type per physical nozzle of an extruder.";
|
||||
def->enum_keys_map = &ConfigOptionEnum<NozzleVolumeType>::get_enum_values();
|
||||
def->enum_values.push_back("Standard");
|
||||
def->enum_values.push_back("High Flow");
|
||||
def->enum_values.push_back("TPU High Flow");
|
||||
def->enum_labels.push_back("Standard");
|
||||
def->enum_labels.push_back("High Flow");
|
||||
def->enum_labels.push_back("TPU High Flow");
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard });
|
||||
|
||||
def = this->add("enable_filament_dynamic_map", coBool);
|
||||
def->label = L("Enable filament dynamic map");
|
||||
def->tooltip = L("Enable dynamic filament mapping during print.");
|
||||
@@ -5534,6 +5745,19 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||
|
||||
// Per-(extruder,variant) deretraction speed at an extruder change. This value
|
||||
// ships in multi-extruder machine profiles but has no slicer consumer — it is a device/firmware-facing
|
||||
// profile key. Registered here (ConfigDef-only, no FullPrintConfig static member) so X2D/P2S profiles
|
||||
// that already carry it — and the H2D/A2L leaves — validate as a known key; unread by the slicer.
|
||||
// nullable so absent leaves stay nil (excluded from the g-code config block).
|
||||
def = this->add("deretract_speed_extruder_change", coFloats);
|
||||
def->label = L("Deretraction speed (extruder change)");
|
||||
def->tooltip = L("Speed for reloading filament into the nozzle when switching extruder.");
|
||||
def->sidetext = L("mm/s"); // millimeters per second, CIS languages need translation
|
||||
def->mode = comDevelop;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable { 0. });
|
||||
|
||||
def = this->add("use_firmware_retraction", coBool);
|
||||
def->label = L("Use firmware retraction");
|
||||
def->tooltip = L("This experimental setting uses G10 and G11 commands to have the firmware "
|
||||
@@ -5952,6 +6176,20 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnum<TimelapseType>(tlTraditional));
|
||||
|
||||
// Farthest-point timelapse. Corexy-only refinement layered on top of the existing
|
||||
// timelapse_type: when enabled the traditional-mode snapshot is
|
||||
// taken at the extrusion point farthest from the camera (0,0) instead of traveling to a safe/chute
|
||||
// position. Gated in GCode::process_layer by timelapse_type==tlTraditional && printer_structure!=psI3,
|
||||
// so it is inert for i3 (A1/A2L) printers and whenever the toggle is off (default false → every
|
||||
// existing printer's g-code is byte-identical). Only H2C/H2D machine profiles set it =1.
|
||||
def = this->add("farthest_point_timelapse", coBool);
|
||||
def->label = L("Farthest point timelapse");
|
||||
def->tooltip = L("When enabled, the timelapse snapshot is taken at the farthest point from camera "
|
||||
"instead of traveling to the wipe tower or excess chute. "
|
||||
"Only effective in traditional timelapse mode on non-I3 printers.");
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("standby_temperature_delta", coInt);
|
||||
def->label = L("Temperature variation");
|
||||
// TRN PrintSettings : "Ooze prevention" > "Temperature variation"
|
||||
@@ -6875,6 +7113,14 @@ void PrintConfigDef::init_fff_params()
|
||||
//def->sidetext = "";
|
||||
def->set_default_value(new ConfigOptionFloats{0.3});
|
||||
|
||||
// Fast-purge mode: the flush multiplier used when prime_volume_mode==Fast.
|
||||
// Only consumed on the pvmFast branch (default prime_volume_mode==Default reads flush_multiplier),
|
||||
// so this key is inert for the shipping fleet. Kept out of the g-code config block (banned_keys).
|
||||
def = this->add("flush_multiplier_fast", coFloats);
|
||||
def->label = L("Flush multiplier (Fast mode)");
|
||||
def->tooltip = L("The flush multiplier used in fast purge mode.");
|
||||
def->set_default_value(new ConfigOptionFloats{1.2});
|
||||
|
||||
// BBS
|
||||
def = this->add("prime_volume", coFloat);
|
||||
def->label = L("Prime volume");
|
||||
@@ -6884,6 +7130,22 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionFloat(45.));
|
||||
|
||||
// Dual-extruder purge control: Default reproduces current behaviour
|
||||
// (per-extruder flush_multiplier + filament_prime_volume); Saving reduces the prime volume,
|
||||
// Fast selects flush_multiplier_fast + filament_flush_temp_fast. Default pvmDefault = inert.
|
||||
def = this->add("prime_volume_mode", coEnum);
|
||||
def->label = L("Prime volume mode");
|
||||
def->tooltip = L("Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<PrimeVolumeMode>::get_enum_values();
|
||||
def->enum_values.push_back("Default");
|
||||
def->enum_values.push_back("Saving");
|
||||
def->enum_values.push_back("Fast");
|
||||
def->enum_labels.push_back(L("Default"));
|
||||
def->enum_labels.push_back(L("Saving"));
|
||||
def->enum_labels.push_back(L("Fast"));
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionEnum<PrimeVolumeMode>(pvmDefault));
|
||||
|
||||
def = this->add("wipe_tower_x", coFloats);
|
||||
//def->label = L("Position X");
|
||||
//def->tooltip = L("X coordinate of the left front corner of a wipe tower.");
|
||||
@@ -7340,6 +7602,162 @@ void PrintConfigDef::init_fff_params()
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Multi-nozzle + pre-heat + nozzle-change (nc) config keys ----
|
||||
// These back 6-nozzle cluster grouping, the pre-heat/pre-cool time model and wipe-tower
|
||||
// nozzle-change handling. Defaults are no-ops for existing single-nozzle printers (all new
|
||||
// readers gate on extruder_max_nozzle_count > 1).
|
||||
def = this->add("machine_hotend_change_time", coFloat);
|
||||
def->label = L("Hotend change time");
|
||||
def->tooltip = L("Time to change hotend.");
|
||||
def->sidetext = L("s");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(0.0));
|
||||
|
||||
// Printer-owned toggle selecting the time-aware grouping objective (flush + change/print
|
||||
// time) over the flush-only objective. Default false == today's flush-only grouping, so
|
||||
// absent/default is inert. Consumed by the grouping solver (SpeedInfo).
|
||||
// Orca: pinned to comDevelop (rather than the default comSimple) to match the sibling multi-nozzle
|
||||
// dev keys and keep it out of user selectors.
|
||||
def = this->add("group_algo_with_time", coBool);
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("machine_prepare_compensation_time", coFloat);
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionFloat(260));
|
||||
|
||||
def = this->add("enable_pre_heating", coBool);
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
// Pre-heat injector context key. handle_hotend_as_extruder is read defensively by the injector;
|
||||
// registered here (comDevelop, default off) as a known inert key.
|
||||
def = this->add("handle_hotend_as_extruder", coBool);
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
// filament_max_temperature_drop_when_ec: inert (default {0}, passed into the injector context but
|
||||
// never consumed). Registered inert-only (comDevelop); not wired into any estimator read, and not
|
||||
// added to any per-variant expansion list.
|
||||
def = this->add("filament_max_temperature_drop_when_ec", coFloats);
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionFloats{0});
|
||||
|
||||
def = this->add("hotend_cooling_rate", coFloats);
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{2});
|
||||
|
||||
def = this->add("hotend_heating_rate", coFloats);
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{2});
|
||||
|
||||
def = this->add("filament_change_length_nc", coFloats);
|
||||
def->label = L("Hotend change");
|
||||
def->tooltip = L("When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloats{10});
|
||||
|
||||
def = this->add("filament_ramming_travel_time", coFloats);
|
||||
def->label = L("Extruder change");
|
||||
def->tooltip = L("To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after "
|
||||
"the ramming is complete. The setting define the travel time.");
|
||||
def->mode = comAdvanced;
|
||||
def->sidetext = "s";
|
||||
def->min = 0;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{0});
|
||||
|
||||
def = this->add("filament_pre_cooling_temperature", coInts);
|
||||
def->label = L("Extruder change");
|
||||
def->tooltip = L("To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled.");
|
||||
def->mode = comAdvanced;
|
||||
def->sidetext = "°C";
|
||||
def->min = 0;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionIntsNullable{0});
|
||||
|
||||
def = this->add("filament_ramming_volumetric_speed", coFloats);
|
||||
def->label = L("Extruder change");
|
||||
def->tooltip = L("The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed.");
|
||||
def->sidetext = L("mm³/s");
|
||||
def->min = -1;
|
||||
def->max = 200;
|
||||
def->mode = comAdvanced;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{-1});
|
||||
|
||||
def = this->add("filament_ramming_travel_time_nc", coFloats);
|
||||
def->label = L("Hotend change");
|
||||
def->tooltip = L("To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after "
|
||||
"the ramming is complete. The setting define the travel time.");
|
||||
def->mode = comAdvanced;
|
||||
def->sidetext = "s";
|
||||
def->min = 0;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{0});
|
||||
|
||||
def = this->add("filament_pre_cooling_temperature_nc", coInts);
|
||||
def->label = L("Hotend change");
|
||||
def->tooltip = L(
|
||||
"To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled.");
|
||||
def->mode = comAdvanced;
|
||||
def->sidetext = "°C";
|
||||
def->min = 0;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionIntsNullable{0});
|
||||
|
||||
def = this->add("filament_ramming_volumetric_speed_nc", coFloats);
|
||||
def->label = L("Hotend change");
|
||||
def->tooltip = L("The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed.");
|
||||
def->sidetext = L("mm³/s");
|
||||
def->min = -1;
|
||||
def->max = 200;
|
||||
def->mode = comAdvanced;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{-1});
|
||||
|
||||
def = this->add("filament_retract_length_nc", coFloats);
|
||||
def->label = L("length when change hotend");
|
||||
def->tooltip = L("When this retraction value is modified, it will be used as the amount of filament retracted "
|
||||
"inside the hotend before changing hotends.");
|
||||
def->sidetext = L("mm");
|
||||
def->mode = comDevelop;
|
||||
def->nullable = true;
|
||||
def->min = 0;
|
||||
def->max = 18;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable { 10. });
|
||||
|
||||
def = this->add("extruder_max_nozzle_count", coInts);
|
||||
def->mode = comDevelop;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionIntsNullable{ 1 });
|
||||
|
||||
// Printer flag gating the fast-purge mode selector in the Multi-Filament
|
||||
// UI. comDevelop, default false; no shipping profile sets it, so the UI stays hidden.
|
||||
def = this->add("support_fast_purge_mode", coBool);
|
||||
def->label = L("Support fast purge mode");
|
||||
def->tooltip = L("Whether this printer supports fast purge mode with optimized temperature and multiplier.");
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("filament_prime_volume_nc", coFloats);
|
||||
def->label = L("Hotend change");
|
||||
def->tooltip = L("The volume of material required to prime the extruder for a hotend change on the tower.");
|
||||
def->sidetext = L("mm³");
|
||||
def->min = 1.0;
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionFloats{60.});
|
||||
|
||||
def = this->add("filament_preheat_temperature_delta", coFloats);
|
||||
def->label = L("Preheat temperature delta");
|
||||
def->tooltip = L("Temperature delta applied during pre-heating before tool change.");
|
||||
def->sidetext = "°C";
|
||||
def->mode = comDevelop;
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{0});
|
||||
|
||||
def = this->add("detect_narrow_internal_solid_infill", coBool);
|
||||
def->label = L("Detect narrow internal solid infills");
|
||||
def->category = L("Strength");
|
||||
@@ -7389,13 +7807,14 @@ void PrintConfigDef::init_filament_option_keys()
|
||||
m_filament_option_keys = {
|
||||
"filament_diameter", "min_layer_height", "max_layer_height","volumetric_speed_coefficients",
|
||||
"retraction_length", "z_hop", "z_hop_types", "retract_lift_above", "retract_lift_below", "retract_lift_enforce", "retraction_speed", "deretraction_speed",
|
||||
"retract_before_wipe", "retract_restart_extra", "retraction_minimum_travel", "wipe", "wipe_distance",
|
||||
"retract_before_wipe", "filament_retract_length_nc", "retract_restart_extra", "retraction_minimum_travel", "wipe", "wipe_distance",
|
||||
"retract_when_changing_layer", "retract_length_toolchange", "retract_restart_extra_toolchange", "filament_colour",
|
||||
"default_filament_profile","retraction_distances_when_cut","long_retractions_when_cut"/*,"filament_seam_gap"*/
|
||||
};
|
||||
|
||||
m_filament_retract_keys = {
|
||||
"deretraction_speed",
|
||||
"filament_retract_length_nc",
|
||||
"long_retractions_when_cut",
|
||||
"retract_before_wipe",
|
||||
"retract_lift_above",
|
||||
@@ -8414,6 +8833,15 @@ std::set<std::string> print_options_with_variant = {
|
||||
std::set<std::string> filament_options_with_variant = {
|
||||
"filament_flow_ratio",
|
||||
"filament_max_volumetric_speed",
|
||||
// Per-variant ramming / pre-cooling / nozzle-change filament overrides
|
||||
"filament_ramming_volumetric_speed",
|
||||
"filament_pre_cooling_temperature",
|
||||
"filament_ramming_travel_time",
|
||||
"filament_ramming_volumetric_speed_nc",
|
||||
"filament_pre_cooling_temperature_nc",
|
||||
"filament_ramming_travel_time_nc",
|
||||
"filament_retract_length_nc",
|
||||
"filament_preheat_temperature_delta",
|
||||
//"filament_extruder_id",
|
||||
"filament_extruder_variant",
|
||||
"filament_retraction_length",
|
||||
@@ -8461,7 +8889,8 @@ std::set<std::string> printer_extruder_options = {
|
||||
"extruder_printable_area",
|
||||
"extruder_printable_height",
|
||||
"min_layer_height",
|
||||
"max_layer_height"
|
||||
"max_layer_height",
|
||||
"extruder_max_nozzle_count" // Per-extruder max (sub-)nozzle count
|
||||
};
|
||||
|
||||
std::set<std::string> printer_options_with_variant_1 = {
|
||||
@@ -8489,6 +8918,9 @@ std::set<std::string> printer_options_with_variant_1 = {
|
||||
"nozzle_type",
|
||||
"printer_extruder_id",
|
||||
"printer_extruder_variant",
|
||||
// Per-variant hotend heat-up / cool-down rates (pre-heat time model)
|
||||
"hotend_cooling_rate",
|
||||
"hotend_heating_rate",
|
||||
"nozzle_flush_dataset"
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user