mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-10 17:21:10 +00:00
refactor(imex): replace "primary" magic string with kImexPrimaryMode constant
Across 6 files the literal "primary" string was the sentinel for "no IMEX parallel mode active" — used for short-circuiting in serialization, ghost visualization, zone calc, popup-menu list construction, the IMEXModesCtrl non-deletable first row, and several layer-of-export checks. A typo in any one would silently bypass the guard. Define kImexPrimaryMode in IMEXHelpers.hpp with a docstring describing what equality with it means semantically, and route every call site through it. No behavior change. Touched: bbs_3mf.cpp, GCode.cpp, PartPlate.cpp, Plater.cpp, Tab.cpp. The bbs_3mf and Tab files now include IMEXHelpers.hpp; the other three already did. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
efa9d65cb4
commit
085f5ccec8
@@ -1,5 +1,6 @@
|
||||
#include "../libslic3r.h"
|
||||
#include "../Exception.hpp"
|
||||
#include "../IMEXHelpers.hpp"
|
||||
#include "../Model.hpp"
|
||||
#include "../Preset.hpp"
|
||||
#include "../Utils.hpp"
|
||||
@@ -7791,7 +7792,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
|
||||
|
||||
{
|
||||
auto* imex_mode_opt = plate_data->config.option<ConfigOptionString>("imex_parallel_mode");
|
||||
if (imex_mode_opt && !imex_mode_opt->value.empty() && imex_mode_opt->value != "primary")
|
||||
if (imex_mode_opt && !imex_mode_opt->value.empty() && imex_mode_opt->value != kImexPrimaryMode)
|
||||
stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << IMEX_PARALLEL_MODE_ATTR << "\" " << VALUE_ATTR << "=\"" << imex_mode_opt->value << "\"/>\n";
|
||||
}
|
||||
{
|
||||
|
||||
@@ -2407,7 +2407,7 @@ static std::vector<int> get_imex_active_tools(const Print& print)
|
||||
return active_tools;
|
||||
|
||||
const std::string& raw_mode = print.objects().front()->config().imex_parallel_mode.value;
|
||||
const std::string active_mode = raw_mode.empty() ? "primary" : raw_mode;
|
||||
const std::string active_mode = raw_mode.empty() ? kImexPrimaryMode : raw_mode;
|
||||
|
||||
const auto* mode_names_opt = print.config().option<ConfigOptionStrings>("imex_mode_names");
|
||||
const auto* tools_opt = print.config().option<ConfigOptionStrings>("imex_mode_active_tools");
|
||||
@@ -3101,7 +3101,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
m_imex_head_filament_map.clear();
|
||||
if (print.config().is_imex.value && !print.objects().empty()) {
|
||||
const std::string& raw = print.objects().front()->config().imex_parallel_mode.value;
|
||||
imex_active_mode = raw.empty() ? "primary" : raw;
|
||||
imex_active_mode = raw.empty() ? kImexPrimaryMode : raw;
|
||||
m_imex_parallel_mode = imex_active_mode;
|
||||
m_imex_head_filament_map = parse_imex_head_filament_map(
|
||||
print.objects().front()->config().imex_head_filament_map.value);
|
||||
@@ -3240,7 +3240,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
|
||||
// In primary mode, regular tool-change PA handles each tool as it becomes active.
|
||||
// In parallel modes no tool changes occur, so every carriage must be addressed
|
||||
// explicitly here before printing starts.
|
||||
if (!m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary"
|
||||
if (!m_imex_parallel_mode.empty() && m_imex_parallel_mode != kImexPrimaryMode
|
||||
&& !m_config.physical_extruder_map.values.empty()) {
|
||||
// initial_physical: pem-translate the print's initial logical extruder so the
|
||||
// loop can skip the primary head (which emitted PA via the normal path).
|
||||
@@ -4710,7 +4710,7 @@ LayerResult GCode::process_layer(
|
||||
// so they're not in m_writer.extruders() and multiple_extruders==false (max id==0).
|
||||
// Use the static set_temperature path for IMEX so the T index is always emitted.
|
||||
// In primary mode, fall through to the standard path — tool changes handle temps normally.
|
||||
if (!m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary") {
|
||||
if (!m_imex_parallel_mode.empty() && m_imex_parallel_mode != kImexPrimaryMode) {
|
||||
// All active tools need explicit temps — none receive tool-change commands,
|
||||
// so we can't rely on the condition used for non-IMEX (temp != initial_layer_temp).
|
||||
// A tool whose initial and regular temps are the same still needs to be set here.
|
||||
@@ -7599,7 +7599,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
|
||||
// Guard the pem lookup: PrintApply populates pem when printer_extruder_id
|
||||
// is set, but defense-in-depth prevents a throw from get_at on any
|
||||
// empty-pem path that might slip through in exotic profiles.
|
||||
const bool imex_parallel = !m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary";
|
||||
const bool imex_parallel = !m_imex_parallel_mode.empty() && m_imex_parallel_mode != kImexPrimaryMode;
|
||||
const int pa_tool = (imex_parallel && !m_config.physical_extruder_map.values.empty())
|
||||
? m_config.physical_extruder_map.get_at((int)new_filament_id)
|
||||
: -1;
|
||||
@@ -7903,7 +7903,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo
|
||||
|
||||
if (m_config.enable_pressure_advance.get_at(new_filament_id)) {
|
||||
// Empty-pem guard mirrors the earlier PA site; get_at throws on empty values.
|
||||
const bool imex_parallel = !m_imex_parallel_mode.empty() && m_imex_parallel_mode != "primary";
|
||||
const bool imex_parallel = !m_imex_parallel_mode.empty() && m_imex_parallel_mode != kImexPrimaryMode;
|
||||
const int pa_tool = (imex_parallel && !m_config.physical_extruder_map.values.empty())
|
||||
? m_config.physical_extruder_map.get_at((int)new_filament_id)
|
||||
: -1;
|
||||
|
||||
@@ -13,6 +13,13 @@ namespace Slic3r {
|
||||
|
||||
class PresetBundle;
|
||||
|
||||
// Reserved sentinel name for the always-present, non-deletable Primary mode in
|
||||
// `imex_mode_names`. Comparison with this constant indicates "no parallel printing
|
||||
// in effect" — IMEX zone visualization, ghost rendering, secondary-tool PA / temp
|
||||
// emission, and the 3MF metadata serialization all short-circuit when the active
|
||||
// plate mode equals this. Treat any value NOT equal to this as a parallel mode.
|
||||
inline constexpr const char* kImexPrimaryMode = "primary";
|
||||
|
||||
// Returns the effective physical_extruder_map given an optionally-explicit map and
|
||||
// the printer's `printer_extruder_id`. If `explicit_pem` has size >= 2 the caller
|
||||
// authored one, and it is returned verbatim. Otherwise the map is auto-derived
|
||||
|
||||
@@ -375,12 +375,12 @@ std::string PartPlate::get_imex_mode() const
|
||||
if (opt && !opt->value.empty())
|
||||
return opt->value;
|
||||
}
|
||||
return "primary";
|
||||
return kImexPrimaryMode;
|
||||
}
|
||||
|
||||
void PartPlate::set_imex_mode(const std::string& mode)
|
||||
{
|
||||
if (mode.empty() || mode == "primary") {
|
||||
if (mode.empty() || mode == kImexPrimaryMode) {
|
||||
m_config.erase("imex_parallel_mode");
|
||||
} else {
|
||||
m_config.set_key_value("imex_parallel_mode", new ConfigOptionString(mode));
|
||||
@@ -568,13 +568,13 @@ void PartPlate::calc_imex_zones()
|
||||
|
||||
// Per-plate mode takes priority over the process preset.
|
||||
std::string active_mode = get_imex_mode();
|
||||
if (active_mode == "primary") {
|
||||
if (active_mode == kImexPrimaryMode) {
|
||||
const DynamicPrintConfig& process_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
auto* mode_opt = process_cfg.option<ConfigOptionString>("imex_parallel_mode");
|
||||
if (mode_opt && !mode_opt->value.empty())
|
||||
active_mode = mode_opt->value;
|
||||
}
|
||||
if (active_mode == "primary" || active_mode.empty())
|
||||
if (active_mode == kImexPrimaryMode || active_mode.empty())
|
||||
return;
|
||||
|
||||
// Grid dimensions and tool layout from printer config
|
||||
@@ -919,7 +919,7 @@ std::string PartPlate::build_imex_cache_key() const
|
||||
return "";
|
||||
// Per-plate mode takes priority over process preset.
|
||||
std::string active_mode = get_imex_mode();
|
||||
if (active_mode == "primary") {
|
||||
if (active_mode == kImexPrimaryMode) {
|
||||
const DynamicPrintConfig& process_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
auto* mode_opt = process_cfg.option<ConfigOptionString>("imex_parallel_mode");
|
||||
if (mode_opt && !mode_opt->value.empty())
|
||||
@@ -1005,12 +1005,12 @@ bool PartPlate::resolve_active_mode_tools(std::string& out_tools_str, int& out_p
|
||||
if (!is_imex_opt || !is_imex_opt->value) return false;
|
||||
|
||||
std::string active_mode = get_imex_mode();
|
||||
if (active_mode == "primary" || active_mode.empty()) {
|
||||
if (active_mode == kImexPrimaryMode || active_mode.empty()) {
|
||||
const DynamicPrintConfig& proc_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
if (auto* mo = proc_cfg.option<ConfigOptionString>("imex_parallel_mode"))
|
||||
active_mode = mo->value;
|
||||
}
|
||||
if (active_mode.empty() || active_mode == "primary") return false;
|
||||
if (active_mode.empty() || active_mode == kImexPrimaryMode) return false;
|
||||
|
||||
auto* names = printer_cfg.option<ConfigOptionStrings>("imex_mode_names");
|
||||
auto* tools = printer_cfg.option<ConfigOptionStrings>("imex_mode_active_tools");
|
||||
@@ -1214,7 +1214,7 @@ bool PartPlate::has_imex_multimaterial_conflict() const
|
||||
if (!pb) return false;
|
||||
auto* is_imex_opt = pb->printers.get_edited_preset().config.option<ConfigOptionBool>("is_imex");
|
||||
if (!is_imex_opt || !is_imex_opt->value) return false;
|
||||
if (get_imex_mode() == "primary") return false;
|
||||
if (get_imex_mode() == kImexPrimaryMode) return false;
|
||||
|
||||
// Condition 2: objects on this plate actually use more than one unique filament/extruder
|
||||
std::vector<int> used = get_extruders(true);
|
||||
|
||||
@@ -9944,7 +9944,7 @@ static std::vector<wxString> collect_imex_warnings(PartPlate* plate)
|
||||
|
||||
// Checks 2 & 3 only apply when a non-primary parallel mode is active
|
||||
const std::string mode = plate->get_imex_mode();
|
||||
if (mode == "primary") return warnings;
|
||||
if (mode == kImexPrimaryMode) return warnings;
|
||||
|
||||
PresetBundle* bundle = wxGetApp().preset_bundle;
|
||||
if (!bundle) return warnings;
|
||||
@@ -17970,14 +17970,14 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi
|
||||
ret = select_plate(plate_index);
|
||||
if (!ret) {
|
||||
PartPlate* curr_plate = p->partplate_list.get_curr_plate();
|
||||
// Build ordered mode list: "primary" first, then all named modes.
|
||||
// Build ordered mode list: kImexPrimaryMode first, then all named modes.
|
||||
std::vector<std::string> modes;
|
||||
modes.push_back("primary");
|
||||
modes.push_back(kImexPrimaryMode);
|
||||
const DynamicPrintConfig& printer_cfg = wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
auto* names_opt = printer_cfg.option<ConfigOptionStrings>("imex_mode_names");
|
||||
if (names_opt) {
|
||||
for (const auto& n : names_opt->values)
|
||||
if (!n.empty() && n != "primary") modes.push_back(n);
|
||||
if (!n.empty() && n != kImexPrimaryMode) modes.push_back(n);
|
||||
}
|
||||
|
||||
if (right_click) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//#include "slic3r/Utils/Serial.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "PresetHints.hpp"
|
||||
#include "libslic3r/IMEXHelpers.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
@@ -4431,7 +4432,7 @@ public:
|
||||
m_n_rows = n_rows;
|
||||
m_layout = layout;
|
||||
for (size_t i = 0; i < names.size(); ++i)
|
||||
add_row(names[i], tools[i], gcodes[i], /*is_primary=*/(names[i] == "primary"));
|
||||
add_row(names[i], tools[i], gcodes[i], /*is_primary=*/(names[i] == kImexPrimaryMode));
|
||||
Layout();
|
||||
}
|
||||
|
||||
@@ -4448,7 +4449,7 @@ public:
|
||||
size_t primary_cfg_idx = std::string::npos;
|
||||
if (names) {
|
||||
for (size_t i = 0; i < names->values.size(); ++i) {
|
||||
if (names->values[i] == "primary") {
|
||||
if (names->values[i] == kImexPrimaryMode) {
|
||||
primary_cfg_idx = i;
|
||||
if (tools && i < tools->values.size()) primary_tools = tools->values[i];
|
||||
if (gcodes && i < gcodes->values.size()) primary_gcode = gcodes->values[i];
|
||||
@@ -4456,7 +4457,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
add_row("primary", primary_tools, primary_gcode, /*is_primary=*/true);
|
||||
add_row(kImexPrimaryMode, primary_tools, primary_gcode, /*is_primary=*/true);
|
||||
|
||||
size_t n = names ? names->values.size() : 0;
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
@@ -4472,7 +4473,7 @@ public:
|
||||
get_mode_data() const {
|
||||
std::vector<std::string> names, tools, gcodes;
|
||||
for (auto& r : m_rows) {
|
||||
std::string nm = r.is_primary ? "primary" : r.name->GetValue().ToStdString();
|
||||
std::string nm = r.is_primary ? std::string(kImexPrimaryMode) : r.name->GetValue().ToStdString();
|
||||
if (nm.empty()) continue;
|
||||
names.push_back(nm);
|
||||
tools.push_back(active_tools_string(r));
|
||||
|
||||
Reference in New Issue
Block a user