Fix command-line slicing when a filament leaves out a per-variant setting

This commit is contained in:
SoftFever
2026-09-29 21:09:20 +08:00
parent d87fe1b290
commit 1504bd7153
4 changed files with 68 additions and 14 deletions
+30
View File
@@ -3476,6 +3476,14 @@ int CLI::run(int argc, char **argv)
} }
new_variant_counts = old_variant_counts; new_variant_counts = old_variant_counts;
//filament_variant_count = old_variant_counts; //filament_variant_count = old_variant_counts;
//ORCA: lay the per-variant options out one value per variant of the current filaments before each
// loaded filament replaces its own variants, including an option only a loaded filament
// defines, which otherwise starts as a single default value and never reaches the others.
for (const DynamicPrintConfig &config : load_filaments_config)
for (const std::string &opt_key : filament_options_with_variant)
if (opt_key != "filament_extruder_variant" && config.has(opt_key))
m_print_config.option(opt_key, true);
normalize_filament_values_to_variants(m_print_config);
for (int index = 0; index < load_filaments_config.size(); index++) { for (int index = 0; index < load_filaments_config.size(); index++) {
DynamicPrintConfig& config = load_filaments_config[index]; DynamicPrintConfig& config = load_filaments_config[index];
int filament_index = load_filaments_index[index]; int filament_index = load_filaments_index[index];
@@ -3647,6 +3655,25 @@ int CLI::run(int argc, char **argv)
} }
} }
//ORCA: a per-variant option the loaded filament does not define keeps the values of the
// variants the filament already had, and a variant new to it takes its first one's.
const int old_start = old_start_indice[filament_index - 1];
std::vector<int> kept_variant_indice = new_variant_indice;
for (int &i : kept_variant_indice)
if (i < 0)
i = old_start;
for (const std::string &opt_key : filament_options_with_variant) {
if (config.has(opt_key))
continue;
auto *opt_vec_dst = dynamic_cast<ConfigOptionVectorBase *>(m_print_config.option(opt_key));
if (opt_vec_dst == nullptr || opt_vec_dst->size() < size_t(old_start + old_variant_count))
continue;
// set_with_restore_2() pads its source in place
std::unique_ptr<ConfigOption> old_values(opt_vec_dst->clone());
opt_vec_dst->set_with_restore_2(static_cast<ConfigOptionVectorBase *>(old_values.get()), kept_variant_indice, old_start,
old_variant_count, true);
}
//update the old index //update the old index
if (old_variant_count != new_variant_count) if (old_variant_count != new_variant_count)
{ {
@@ -4081,6 +4108,9 @@ int CLI::run(int argc, char **argv)
if (printer_technology == ptFFF) { if (printer_technology == ptFFF) {
fff_print_config.apply(m_print_config, true); fff_print_config.apply(m_print_config, true);
m_print_config.apply(fff_print_config, true); m_print_config.apply(fff_print_config, true);
//ORCA: an option no preset or project defines has just come in as its single default value, and a
// command line override may hold one value per filament.
normalize_filament_values_to_variants(m_print_config);
} else { } else {
boost::nowide::cerr << "invalid printer_technology " << std::endl; boost::nowide::cerr << "invalid printer_technology " << std::endl;
record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH], sliced_info); record_exit_reson(outfile_dir, CLI_INVALID_PRINTER_TECH, 0, cli_errors[CLI_INVALID_PRINTER_TECH], sliced_info);
+21 -14
View File
@@ -9405,20 +9405,8 @@ void PrintConfigDef::handle_legacy_composite(DynamicPrintConfig &config)
} }
// Orca: a config saved before a key joined filament_options_with_variant stores it once per filament // Orca: a config saved before a key joined filament_options_with_variant stores it once per filament
// rather than once per filament variant. Give every variant of a filament that filament's value. // rather than once per filament variant, and one exported by an older CLI may store a single value.
if (auto *self_index = config.option<ConfigOptionInts>("filament_self_index"); self_index && !self_index->empty()) { normalize_filament_values_to_variants(config);
const int filament_count = *std::max_element(self_index->values.begin(), self_index->values.end());
if (filament_count > 0 && size_t(filament_count) < self_index->size()) {
for (const std::string &key : filament_options_with_variant) {
auto *opt = dynamic_cast<ConfigOptionVectorBase *>(config.option(key));
if (!opt || opt->size() != size_t(filament_count))
continue;
std::unique_ptr<ConfigOption> per_filament(opt->clone());
for (size_t variant = 0; variant < self_index->size(); ++variant)
opt->set_at(per_filament.get(), variant, self_index->values[variant] - 1);
}
}
}
} }
const PrintConfigDef print_config_def; const PrintConfigDef print_config_def;
@@ -10735,6 +10723,25 @@ void set_variant_override(ConfigOptionVectorBase &target, const ConfigOptionVect
target.set_to_index(&source, indices, stride); target.set_to_index(&source, indices, stride);
} }
void normalize_filament_values_to_variants(DynamicPrintConfig &config)
{
const auto *self_index = config.option<ConfigOptionInts>("filament_self_index");
if (self_index == nullptr || self_index->empty())
return;
const int filament_count = *std::max_element(self_index->values.begin(), self_index->values.end());
if (filament_count <= 0 || size_t(filament_count) >= self_index->size())
return;
for (const std::string &key : filament_options_with_variant) {
auto *opt = dynamic_cast<ConfigOptionVectorBase *>(config.option(key));
if (opt == nullptr || (opt->size() != size_t(filament_count) && opt->size() != 1))
continue;
std::unique_ptr<ConfigOption> per_filament(opt->clone());
// set_at() takes the first value for a filament past the end of a single-value vector
for (size_t variant = 0; variant < self_index->size(); ++variant)
opt->set_at(per_filament.get(), variant, self_index->values[variant] - 1);
}
}
//used for object/region config //used for object/region config
//use the smallest of multiple to single //use the smallest of multiple to single
+5
View File
@@ -884,6 +884,11 @@ extern std::set<std::string> empty_options;
void set_variant_override(ConfigOptionVectorBase &target, const ConfigOptionVectorBase &source, void set_variant_override(ConfigOptionVectorBase &target, const ConfigOptionVectorBase &source,
const std::vector<int> &variant_index, int stride = 1); const std::vector<int> &variant_index, int stride = 1);
// Orca: lays every filament_options_with_variant option out one value per filament variant, as
// filament_self_index maps the variants to filaments. An option holding one value per filament, or a
// single value, gives every variant of a filament that filament's value; other lengths are left alone.
void normalize_filament_values_to_variants(DynamicPrintConfig &config);
extern std::set<std::string> filament_dev_options; extern std::set<std::string> filament_dev_options;
extern void update_static_print_config_from_dynamic(ConfigBase& config, const DynamicPrintConfig& dest_config, std::vector<int> variant_index, std::set<std::string>& key_set1, int stride = 1); extern void update_static_print_config_from_dynamic(ConfigBase& config, const DynamicPrintConfig& dest_config, std::vector<int> variant_index, std::set<std::string>& key_set1, int stride = 1);
@@ -717,3 +717,15 @@ TEST_CASE("get_index_for_extruder scales the variant column by the requested str
REQUIRE(col0_stride2 == 0); REQUIRE(col0_stride2 == 0);
REQUIRE(col1_stride2 == 2); REQUIRE(col1_stride2 == 2);
} }
// A per-variant filament option read with a single value gives it to every filament variant. A project
// exported by an older CLI holds a single value for an option no loaded preset defined, such as
// filament_ironing_flow.
TEST_CASE("A per-variant filament option read with a single value gives it to every filament variant", "[Config]")
{
// filament 1 defines Standard and High Flow, filament 2 Standard
DynamicPrintConfig config;
config.option<ConfigOptionInts>("filament_self_index", true)->values = {1, 1, 2};
config.load_from_ini_string("pressure_advance = 0.021", ForwardCompatibilitySubstitutionRule::Disable);
REQUIRE(config.option<ConfigOptionFloats>("pressure_advance")->values == std::vector<double>({0.021, 0.021, 0.021}));
}