Fix per-obj multi-variant options handling (#14700)

* ENH: config: add logic to apply params to object/region config with multi-extruder

JIRA: no-jira
Change-Id: Ieab98cd8d031e5ca82a3aad2d0b89d8ae4a794f1
(cherry picked from commit 3179fd416e68ca8bc2d746f859508d07db18fe5b)

* FIX: X1C switch to H2D lose Highflow parameter

Jira: STUDIO-15272
Change-Id: Id8cf5d93a49d5542ac82f9554974b458e15c1193
(cherry picked from commit 15d9f072ff658a3beb4f916d978dfea12c2d9f16)

* Fix mishandling of `stride` param and add unit test for it

* Fix modified multi-variant per-obj option highlight

* Fix issue that per-obj FloatsOrPercents options are marked as dirty incorrectly when lost focus

---------

Co-authored-by: lane.wei <lane.wei@bambulab.com>
Co-authored-by: weiting.ji <weiting.ji@bambulab.com>
This commit is contained in:
Noisyfox
2026-07-11 22:21:22 +08:00
committed by GitHub
parent 22e121f4e4
commit 93d5b65852
9 changed files with 320 additions and 41 deletions

View File

@@ -724,7 +724,7 @@ PrintObjectRegions::BoundingBox find_modifier_volume_extents(const PrintObjectRe
return out;
}
PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_or_parent_region_config, const DynamicPrintConfig *layer_range_config, const ModelVolume &volume, size_t num_extruders);
PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_or_parent_region_config, const DynamicPrintConfig *layer_range_config, const ModelVolume &volume, size_t num_extruders, std::vector<int>& variant_index);
void print_region_ref_inc(PrintRegion &r) { ++ r.m_ref_cnt; }
void print_region_ref_reset(PrintRegion &r) { r.m_ref_cnt = 0; }
@@ -738,7 +738,8 @@ bool verify_update_print_object_regions(
const PrintRegionConfig &default_region_config,
size_t num_extruders,
PrintObjectRegions &print_object_regions,
const std::function<void(const PrintRegionConfig&, const PrintRegionConfig&, const t_config_option_keys&)> &callback_invalidate)
const std::function<void(const PrintRegionConfig&, const PrintRegionConfig&, const t_config_option_keys&)> &callback_invalidate,
std::vector<int>& variant_index)
{
// Sort by ModelVolume ID.
model_volumes_sort_by_id(model_volumes);
@@ -783,7 +784,7 @@ bool verify_update_print_object_regions(
} else if (PrintObjectRegions::BoundingBox parent_bbox = find_modifier_volume_extents(layer_range, parent_region_id); parent_bbox.intersects(*bbox))
// Such parent region does not exist. If it is needed, then we need to reslice.
// Only create new region for a modifier, which actually modifies config of it's parent.
if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, **it_model_volume, num_extruders);
if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, **it_model_volume, num_extruders, variant_index);
config != parent_region.region->config())
// This modifier newly overrides a region, which it did not before. We need to reslice.
return false;
@@ -791,8 +792,8 @@ bool verify_update_print_object_regions(
}
}
PrintRegionConfig cfg = region.parent == -1 ?
region_config_from_model_volume(default_region_config, layer_range.config, **it_model_volume, num_extruders) :
region_config_from_model_volume(layer_range.volume_regions[region.parent].region->config(), nullptr, **it_model_volume, num_extruders);
region_config_from_model_volume(default_region_config, layer_range.config, **it_model_volume, num_extruders, variant_index) :
region_config_from_model_volume(layer_range.volume_regions[region.parent].region->config(), nullptr, **it_model_volume, num_extruders, variant_index);
if (cfg != region.region->config()) {
// Region configuration changed.
if (print_region_ref_cnt(*region.region) == 0) {
@@ -964,6 +965,7 @@ static PrintObjectRegions* generate_print_object_regions(
size_t num_extruders,
const float xy_contour_compensation,
const std::vector<unsigned int> &painting_extruders,
std::vector<int> &variant_index,
const bool has_painted_fuzzy_skin)
{
// Reuse the old object or generate a new one.
@@ -1022,7 +1024,7 @@ static PrintObjectRegions* generate_print_object_regions(
// Add a model volume, assign an existing region or generate a new one.
layer_range.volume_regions.push_back({
&volume, -1,
get_create_region(region_config_from_model_volume(default_region_config, layer_range.config, volume, num_extruders)),
get_create_region(region_config_from_model_volume(default_region_config, layer_range.config, volume, num_extruders, variant_index)),
bbox
});
} else if (volume.is_negative_volume()) {
@@ -1039,7 +1041,7 @@ static PrintObjectRegions* generate_print_object_regions(
if (parent_volume.is_model_part() || parent_volume.is_modifier())
if (PrintObjectRegions::BoundingBox parent_bbox = find_modifier_volume_extents(layer_range, parent_region_id); parent_bbox.intersects(*bbox)) {
// Only create new region for a modifier, which actually modifies config of it's parent.
if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, volume, num_extruders);
if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, volume, num_extruders, variant_index);
config != parent_region.region->config()) {
added = true;
layer_range.volume_regions.push_back({ &volume, parent_region_id, get_create_region(std::move(config)), bbox });
@@ -1162,12 +1164,13 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
}
//apply extruder related values
std::vector<int> print_variant_index;
if (!extruder_applied) {
// 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");
print_variant_index = new_full_config.update_values_to_printer_extruders(new_full_config, print_options_with_variant, "print_extruder_id", "print_extruder_variant");
m_ori_full_print_config = new_full_config;
new_full_config.update_values_to_printer_extruders_for_multiple_filaments(new_full_config, filament_options_with_variant, "filament_self_index", "filament_extruder_variant");
@@ -1475,7 +1478,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
if (object_config_changed)
model_object.config.assign_config(model_object_new.config);
if (! object_diff.empty() || object_config_changed || num_extruders_changed ) {
PrintObjectConfig new_config = PrintObject::object_config_from_model_object(m_default_object_config, model_object, num_extruders );
PrintObjectConfig new_config = PrintObject::object_config_from_model_object(m_default_object_config, model_object, num_extruders, print_variant_index);
for (const PrintObjectStatus &print_object_status : print_object_status_db.get_range(model_object)) {
t_config_option_keys diff = print_object_status.print_object->config().diff(new_config);
if (! diff.empty()) {
@@ -1541,10 +1544,10 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
// Generate a list of trafos and XY offsets for instances of a ModelObject
// Producing the config for PrintObject on demand, caching it at print_object_last.
const PrintObject *print_object_last = nullptr;
auto print_object_apply_config = [this, &print_object_last, model_object, num_extruders ](PrintObject *print_object) {
auto print_object_apply_config = [this, &print_object_last, model_object, num_extruders, &print_variant_index](PrintObject *print_object) {
print_object->config_apply(print_object_last ?
print_object_last->config() :
PrintObject::object_config_from_model_object(m_default_object_config, *model_object, num_extruders ));
PrintObject::object_config_from_model_object(m_default_object_config, *model_object, num_extruders, print_variant_index));
print_object_last = print_object;
};
if (old.empty()) {
@@ -1715,7 +1718,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
for (auto it = it_print_object; it != it_print_object_end; ++it)
if ((*it)->m_shared_regions != nullptr)
update_apply_status((*it)->invalidate_state_by_config_options(old_config, new_config, diff_keys));
})) {
},
print_variant_index)) {
// Regions are valid, just keep them.
} else {
// Regions were reshuffled.
@@ -1737,6 +1741,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
num_extruders ,
print_object.is_mm_painted() ? 0.f : float(print_object.config().xy_contour_compensation.value),
painting_extruders,
print_variant_index,
print_object.is_fuzzy_skin_painted());
}
for (auto it = it_print_object; it != it_print_object_end; ++it)