mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-11 01:41:03 +00:00
Merge upstream main: multi-variant printers, X-Ray view, preview and startup work
The two conflicts are both places where upstream landed on top of IDEX/IQEX
code. In GCode.cpp the relocated file header block meets the IMEX placeholder
block, and the placeholders are set first: file_start_gcode is processed through
the placeholder parser now, which throws on a name it does not know, so a script
naming {imex_mode} would abort the export if the header ran first. In
test_multifilament.cpp both sides appended a case at the end of the file.
This commit is contained in:
@@ -627,7 +627,9 @@ static const t_config_enum_values s_keys_map_NozzleVolumeType = {
|
||||
{ "Standard", nvtStandard },
|
||||
{ "High Flow", nvtHighFlow },
|
||||
{ "TPU High Flow", nvtTPUHighFlow },
|
||||
{ "Hybrid", nvtHybrid }
|
||||
{ "Hybrid", nvtHybrid },
|
||||
{ "E3D High Flow", nvtE3DHighFlow },
|
||||
{ "Extra High Flow", nvtExtraHighFlow }
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NozzleVolumeType)
|
||||
|
||||
@@ -695,9 +697,34 @@ int get_config_index_base(NozzleVolumeType volume_type, ExtruderType extruder_ty
|
||||
for (int index = 0; index < int(variant_list.size()); ++index) {
|
||||
if (extruder_variant == variant_list[index] && variant_ids_1based[index] == variant_id_1based) { return index; }
|
||||
}
|
||||
// Without this variant, use the id's own first variant (usually Standard), not variant index 0,
|
||||
// which belongs to the first filament or extruder.
|
||||
for (int index = 0; index < int(variant_list.size()); ++index) {
|
||||
if (variant_ids_1based[index] == variant_id_1based) { return index; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::set<NozzleVolumeType> get_extruder_supported_nozzle_volume_types(const DynamicPrintConfig &printer_config, int extruder_id)
|
||||
{
|
||||
std::set<NozzleVolumeType> supported_types;
|
||||
|
||||
auto *variant_list = printer_config.option<ConfigOptionStrings>("extruder_variant_list");
|
||||
auto *extruder_types = printer_config.option<ConfigOptionEnumsGeneric>("extruder_type");
|
||||
if (!variant_list || !extruder_types || extruder_id < 0 ||
|
||||
extruder_id >= (int) variant_list->values.size() || extruder_id >= (int) extruder_types->values.size())
|
||||
return supported_types;
|
||||
|
||||
const ExtruderType extruder_type = ExtruderType(extruder_types->values[extruder_id]);
|
||||
for (NozzleVolumeType volume_type : get_valid_nozzle_volume_type()) {
|
||||
// An unsupported extruder type yields an empty name, which would match any list.
|
||||
const std::string variant = get_extruder_variant_string(extruder_type, volume_type);
|
||||
if (!variant.empty() && variant_list->values[extruder_id].find(variant) != std::string::npos)
|
||||
supported_types.insert(volume_type);
|
||||
}
|
||||
return supported_types;
|
||||
}
|
||||
|
||||
std::string get_nozzle_volume_type_string(NozzleVolumeType nozzle_volume_type)
|
||||
{
|
||||
if (nozzle_volume_type > nvtMaxNozzleVolumeType) {
|
||||
@@ -1541,7 +1568,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(1));
|
||||
|
||||
def = this->add("top_solid_infill_flow_ratio", coFloat);
|
||||
def = this->add("top_solid_infill_flow_ratio", coFloats);
|
||||
def->label = L("Top surface flow ratio");
|
||||
def->category = L("Advanced");
|
||||
def->tooltip = L("This factor affects the amount of material for top solid infill. "
|
||||
@@ -1550,7 +1577,8 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 2;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(1));
|
||||
def->nullable = true;
|
||||
def->set_default_value(new ConfigOptionFloatsNullable{1});
|
||||
|
||||
def = this->add("bottom_solid_infill_flow_ratio", coFloat);
|
||||
def->label = L("Bottom surface flow ratio");
|
||||
@@ -5941,15 +5969,20 @@ 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).
|
||||
// Listed in display order. A position is not the enum value (E3D High Flow is 5, after the reserved 4),
|
||||
// so map a position to its NozzleVolumeType through enum_keys_map.
|
||||
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_values.push_back(L("E3D High Flow"));
|
||||
def->enum_values.push_back(L("Extra 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->enum_labels.push_back(L("E3D High Flow"));
|
||||
def->enum_labels.push_back(L("Extra High Flow"));
|
||||
def->mode = comSimple;
|
||||
def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard });
|
||||
|
||||
@@ -5962,10 +5995,14 @@ void PrintConfigDef::init_fff_params()
|
||||
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_values.push_back(L("E3D High Flow"));
|
||||
def->enum_values.push_back(L("Extra 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->enum_labels.push_back(L("E3D High Flow"));
|
||||
def->enum_labels.push_back(L("Extra High Flow"));
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard });
|
||||
|
||||
@@ -6004,7 +6041,7 @@ void PrintConfigDef::init_fff_params()
|
||||
// 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).
|
||||
// substitution warning. Registers the physical types only (no Hybrid).
|
||||
// Internal use only, no translation.
|
||||
def = this->add("extruder_nozzle_volume_type", coEnums);
|
||||
def->label = "Extruder nozzle volume type";
|
||||
@@ -6013,9 +6050,13 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_values.push_back("Standard");
|
||||
def->enum_values.push_back("High Flow");
|
||||
def->enum_values.push_back("TPU High Flow");
|
||||
def->enum_values.push_back("E3D High Flow");
|
||||
def->enum_values.push_back("Extra High Flow");
|
||||
def->enum_labels.push_back("Standard");
|
||||
def->enum_labels.push_back("High Flow");
|
||||
def->enum_labels.push_back("TPU High Flow");
|
||||
def->enum_labels.push_back("E3D High Flow");
|
||||
def->enum_labels.push_back("Extra High Flow");
|
||||
def->mode = comDevelop;
|
||||
def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard });
|
||||
|
||||
@@ -6856,6 +6897,20 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("wipe_tower_sparse_layers_combination", coBool);
|
||||
def->label = L("Combine sparse layers");
|
||||
def->tooltip = L("If enabled, consecutive layers on which the prime tower has no filament change are printed as a single "
|
||||
"thicker tower layer instead of one thin layer each, the same way infill combination merges sparse infill. "
|
||||
"The merged layer is printed at the top of the run, at the height of everything it covers.\n\n"
|
||||
"Only whole layers are merged, and never past the maximum layer height of the nozzle printing the tower "
|
||||
"(three quarters of the nozzle diameter when that is left at 0). Two or more layers therefore have to fit "
|
||||
"under that limit before anything changes at all: at a 0.2 mm layer height under a 0.3 mm maximum nothing "
|
||||
"is merged, while at 0.1 mm three layers become one.\n\n"
|
||||
"Unlike \"No sparse layers\" the tower keeps following the model, so the toolhead never has to reach down to it. "
|
||||
"Has no effect with \"No sparse layers\", smooth timelapse or clumping detection, which need a tower on every layer.");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("single_extruder_multi_material_priming", coBool);
|
||||
def->label = L("Prime all printing extruders");
|
||||
def->tooltip = L("If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print.");
|
||||
@@ -9279,6 +9334,8 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
||||
value = "tree(auto)";
|
||||
} else if (opt_key == "support_base_pattern" && value == "none") {
|
||||
value = "hollow";
|
||||
} else if (opt_key == "tree_support_wall_count" && value == "-1") {
|
||||
value = "0";
|
||||
} else if (opt_key == "different_settings_to_system") {
|
||||
std::string copy_value = value;
|
||||
copy_value.erase(std::remove(copy_value.begin(), copy_value.end(), '\"'), copy_value.end()); // remove '"' in string
|
||||
@@ -9565,7 +9622,8 @@ std::set<std::string> print_options_with_variant = {
|
||||
"initial_layer_travel_jerk",
|
||||
"default_junction_deviation",
|
||||
"print_extruder_id", //coInts
|
||||
"print_extruder_variant" //coStrings
|
||||
"print_extruder_variant", //coStrings
|
||||
"top_solid_infill_flow_ratio"
|
||||
};
|
||||
|
||||
std::set<std::string> filament_options_with_variant = {
|
||||
@@ -10222,6 +10280,13 @@ bool DynamicPrintConfig::is_using_different_extruders()
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DynamicPrintConfig::has_multi_variant_filament() const
|
||||
{
|
||||
auto variants = dynamic_cast<const ConfigOptionStrings*>(this->option("filament_extruder_variant"));
|
||||
auto diameters = dynamic_cast<const ConfigOptionFloats*>(this->option("filament_diameter"));
|
||||
return variants && diameters && variants->size() > diameters->size();
|
||||
}
|
||||
|
||||
bool DynamicPrintConfig::support_different_extruders(int& extruder_count) const
|
||||
{
|
||||
std::set<std::string> variant_set;
|
||||
@@ -11222,6 +11287,11 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen
|
||||
return;
|
||||
}
|
||||
std::vector<int> filament_maps = opt_filament_map->values;
|
||||
auto opt_ids = id_name.empty()? nullptr: dynamic_cast<const ConfigOptionInts*>(this->option(id_name));
|
||||
// Orca: a map shorter than the filament count must not drop the filaments past its end;
|
||||
// they take the first extruder.
|
||||
if (opt_ids && !opt_ids->values.empty())
|
||||
filament_maps.resize(std::max<size_t>(filament_maps.size(), *std::max_element(opt_ids->values.begin(), opt_ids->values.end())), 1);
|
||||
size_t filament_count = filament_maps.size();
|
||||
//apply process settings
|
||||
auto opt_extruder_type = dynamic_cast<const ConfigOptionEnumsGeneric*>(printer_config.option("extruder_type"));
|
||||
@@ -11240,7 +11310,6 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen
|
||||
// indexed out of bounds.
|
||||
if (opt_filament_volume_maps && opt_filament_volume_maps->values.size() == filament_count)
|
||||
filament_volume_maps = opt_filament_volume_maps->values;
|
||||
auto opt_ids = id_name.empty()? nullptr: dynamic_cast<const ConfigOptionInts*>(this->option(id_name));
|
||||
std::vector<int> variant_index;
|
||||
|
||||
variant_index.resize(filament_count, -1);
|
||||
@@ -11257,9 +11326,10 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen
|
||||
//variant index
|
||||
variant_index[f_index] = get_index_for_extruder(f_index+1, id_name, extruder_type, nozzle_volume_type, variant_name);
|
||||
if (variant_index[f_index] < 0) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, filament_index %4%, extruder index %5%")
|
||||
// Orca: a filament need not define every extruder variant (a Direct Drive filament on a
|
||||
// Bowden printer), so this is not an invalid state: the filament's first variant is used.
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, filament_index %4%, extruder index %5%")
|
||||
%__LINE__ %s_keys_names_ExtruderType[extruder_type] % s_keys_names_NozzleVolumeType[nozzle_volume_type] % (f_index+1) %filament_maps[f_index];
|
||||
assert(false);
|
||||
//for some updates happens in a invalid state(caused by popup window)
|
||||
//we need to avoid crash
|
||||
variant_index[f_index] = 0;
|
||||
|
||||
Reference in New Issue
Block a user