diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 49909ec270..e4f421414a 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1205,6 +1205,13 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ DynamicPrintConfig filament_overrides; //BBS: add plate index t_config_option_keys print_diff = print_config_diffs(m_config, new_full_config, filament_overrides, this->m_plate_index, filament_maps); + // Orca: filament_map_2 is engine-derived state, never a user input: the rebuild below + // recomputes it from filament_map/filament_volume_map/the variant slots on every apply + // (all of which are diffed and invalidation-listed on their own), and the grouping + // write-back overwrites it during process(). The incoming full config only ever carries + // the ConfigDef default, so diffing it would invalidate every print step on each apply + // for any multi-extruder printer and permanently invalidate fresh slice results. + print_diff.erase(std::remove(print_diff.begin(), print_diff.end(), "filament_map_2"), print_diff.end()); t_config_option_keys full_config_diff = full_print_config_diffs(m_full_print_config, new_full_config, this->m_plate_index); // Collect changes to object and region configs. t_config_option_keys object_diff = m_default_object_config.diff(new_full_config); diff --git a/tests/libslic3r/test_toolordering_nozzle_group.cpp b/tests/libslic3r/test_toolordering_nozzle_group.cpp index fbc05d811f..dcc2ae9521 100644 --- a/tests/libslic3r/test_toolordering_nozzle_group.cpp +++ b/tests/libslic3r/test_toolordering_nozzle_group.cpp @@ -460,3 +460,39 @@ TEST_CASE("Print config-index resolvers pick per-filament Hybrid slots", "[Print REQUIRE(print.get_nozzle_config_index(2, 0) == 1); // extruder slot, not the High Flow slot } } + +TEST_CASE("Re-applying an unchanged config after slicing keeps the result valid", "[Print][H2C]") +{ + // apply() rebuilds m_config.filament_map_2 to the real per-filament slot map, while the + // incoming full config only ever carries the ConfigDef default for it. The engine-derived + // key must therefore be kept out of the apply diff: the GUI re-applies right after slicing + // completes, and a phantom filament_map_2 diff would invalidate every freshly sliced result + // on any multi-extruder printer. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.option("nozzle_diameter", true)->values = {0.4, 0.4}; + config.option("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#1|High Flow#2"}; + config.option("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option("filament_diameter", true)->values = {1.75, 1.75, 1.75}; + config.option("filament_colour", true)->values = {"#FF0000", "#00FF00", "#0000FF"}; + config.option("filament_map", true)->values = {1, 2, 2}; + config.option("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtStandard, (int) nvtHighFlow}; + + Model model; + ModelObject *object = model.add_object("cube", "", make_cube(20, 20, 20)); + object->add_instance()->set_offset(Vec3d(100., 100., 0.)); + + Print print; + print.apply(model, config); + print.process(); + REQUIRE(print.is_step_done(psSlicingFinished)); + + auto status = print.apply(model, config); + REQUIRE(status != PrintBase::APPLY_STATUS_INVALIDATED); + REQUIRE(print.is_step_done(psSlicingFinished)); +}