Comments and dead code cleanup

This commit is contained in:
Lam Wei Lun
2026-09-03 13:40:58 +08:00
parent 8c7160079e
commit bcff39661c
4 changed files with 57 additions and 94 deletions

View File

@@ -5220,29 +5220,18 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
// Material pass: positional per-slot entries. The author published, per slot, either the
// entire filament (full) or specific keys plus optionally a curated type and/or colour.
// - full: the slot always lands on a freshly created standalone detached copy
// ("Detach from parent", project-embedded, universally compatible, within-load
// deduped) - handled up front in the entry loop below; no library preset is ever
// reused or mutated;
// - partial: a type requirement gates the application - on type match (or no
// requirement) the keys are applied onto the slot's effective preset; on mismatch
// the slot is replaced with the best visible candidate, scored by the published
// identity (exact preset name resolved through the collection's name machinery,
// then exact setting_id, exact filament_id, then vendor+type, then type only); a
// preset no other slot references wins on equal scores; with no replacement
// available the receiver's material is kept and the keys are reported as skipped;
// - colour: applied to the slot regardless of the type gate.
// - capacity: on a non-SEMM receiver whose printer has fewer nozzles than the
// authored slot needs, the entry becomes an empty mixed-filament placeholder
// appended at the tail (the GUI flags it; the user assigns components from their
// own filaments); on a single-physical-slot receiver it is dropped and reported
// instead, since an empty mix could never be edited there.
// - full: lands on a freshly created standalone detached copy (no library preset used
// or mutated);
// - partial: a type requirement gates application; on mismatch the slot is replaced
// with the best visible candidate by published identity (exact name, setting_id,
// filament_id, vendor+type, type); with no replacement the receiver's material is
// kept and the keys are reported as skipped;
// - colour: applied regardless of the type gate.
// - capacity: past the printer's physical nozzles the entry becomes an empty
// mixed-filament placeholder; on a single-physical-slot receiver it is dropped.
// Applied partial values land on the collection's edited layer when the slot references
// it and that layer survives the load (visible as a modification, revertible, the user's
// unsaved edits preserved), otherwise on the stored preset in place.
// To keep slot-to-slot aliasing (several slots referencing one preset) from leaking one
// slot's values into another, published slots sharing a preset with another slot are
// re-pointed at distinct presets before the values are applied.
// it and that layer survives the load, otherwise on the stored preset in place. Slots
// aliasing a shared preset are re-pointed at distinct presets before the values apply.
{
// Grow the receiver's slots only as far as the highest published slot (never
// shrink, never pull filler materials for unpublished slots).
@@ -5281,26 +5270,13 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
grow_target = std::max(grow_target, size_t(entry.slot) + 1);
}
// Mixed-filament definitions live in project-level virtual slots, so applying one
// positionally onto a receiver slot that holds a real, physical filament would
// silently convert hardware-backed state into a virtual mix. Compute each mixed
// entry's destination before anything consumes entry.slot (growth, seeding,
// de-aliasing, the overlay below):
// - a definition landing on a receiver slot that already carries a mixed
// definition keeps its place (a like-for-like override of a virtual slot);
// - everything else goes through one monotone append counter preserving author
// order: dest = max(authored, next_free). With a receiver shorter than the
// publish this keeps the authored positions intact; past them (or around a
// collision with a real filament) the mixes pack onto consecutive fresh slots
// AFTER every positional (real-filament) territory. The definition's cells are
// shifted inside the file-side per-slot mixed arrays so they stay readable
// from the new index. No existing slot changes meaning.
// - destinations are also capped: appends past the extruder limit are dropped
// and reported instead of being forced onto a physical filament.
// Physical entries past the printer's capacity join the same append counter
// (dest = next_free, packed consecutively at the tail - never max(authored,
// next_free), which would grow filler physical slots past the capacity) and are
// flagged mixed_placeholder: they become empty mixed-filament placeholders the
// GUI flags for the user to assign components to.
// positionally onto a receiver slot holding a real filament would convert hardware
// state into a virtual mix. Compute each entry's destination before anything
// consumes entry.slot: a definition on a slot that already holds a mixed definition
// keeps its place (like-for-like); everything else follows one monotone append
// counter preserving author order (dest = max(authored, next_free)). Appends past
// the extruder limit are dropped and reported. Physical entries past capacity join
// the same counter as mixed_placeholder empties the GUI flags for assignment.
size_t next_free_slot = this->filament_presets.size();
bool any_mixed_relocated = false;
// All authored-slot -> destination moves decided by this pass, applied to the
@@ -5441,20 +5417,12 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
const auto it = exact_name_by_slot.find(slot);
return it == exact_name_by_slot.end() ? std::string() : it->second;
};
std::set<std::string> used_preset_names(this->filament_presets.begin(), this->filament_presets.end());
// Mirror first_visible_idx()'s start index so suppressed default presets are
// never picked as a slot material.
const size_t first_candidate = this->filaments.is_default_suppressed() ? this->filaments.num_default_presets() : 0;
// Candidate preference for a published entry: exact preset name (the raw author
// name and the collection-resolved name - renames, removed vendor-generic
// library fallback - both identify the exact preset, unambiguous even when ids
// are shared between variants or missing from older files), then the trimmed
// bare form / alias ("Generic PLA" from "Generic PLA @System"): a same-family
// match that must never outrank the exact preset, then exact setting_id
// (variant-level, since "Generic PLA" and "Generic PLA Matte" share
// filament_id), then exact filament_id, then vendor+type, then type only (a
// type-only pick may surface an unrelated preset, e.g. a different vendor's
// PLA).
// Candidate preference for a published entry: exact preset name (raw author and
// collection-resolved), then trimmed bare form / alias, then exact setting_id
// (variant-level), then exact filament_id, then vendor+type, then type only.
auto candidate_score = [](const Preset& candidate, const PublishedMaterialEntry& entry,
const std::string& resolved_name) -> int {
// Exact preset name: raw and collection-resolved forms both outrank the
@@ -5512,7 +5480,6 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
initial_preset = this->filament_presets.empty() ? this->filaments.first_visible().name :
this->filament_presets.back();
this->filament_presets.emplace_back(initial_preset);
used_preset_names.insert(initial_preset);
}
// Published slots that alias another slot (multi-extruder with one filament)
// get re-pointed at distinct presets: the overlay writes onto the slot's

View File

@@ -10,20 +10,16 @@ class PresetBundle;
std::string publish_base_key(const std::string &key);
// Structural keys that are never applied onto the receiver's presets when loading a published
// 3MF (single source of truth for the denylist): applying them would rewrite the user's preset
// inheritance/structure. filament_ids is nevertheless exported via the identity list in
// filter_published_config because 3MF validation needs it - exported, never applied.
// 3MF (single source of truth for the denylist); applying them would rewrite the user's preset
// inheritance/structure. filament_ids is still exported via the identity list (3MF validation
// needs it) - exported, never applied.
const std::set<std::string>& publish_structural_keys();
// The mixed-color filament project keys (parallel per-slot arrays, see PresetBundle's
// s_project_options): a mixed slot's full definition - which slots it blends, the sublayer
// ratios and the optional Z-gradient description. A published mixed slot always serializes
// these keys; on import they are applied into the receiver's project_config (not a filament
// preset), so the mix survives the round-trip.
// s_project_options). Import applies them into project_config, not a filament preset.
const std::set<std::string>& publish_mixed_keys();
// One row of the printer tab's "Retraction" / "Z-Hop" optgroups (key + tab icon id), kept
// together so the tab can later be migrated onto these lists.
// One row of the printer tab's "Retraction" / "Z-Hop" optgroups (config key + tab icon id).
struct PublishablePrinterOption {
const char *key; // config key, e.g. "retraction_length"
const char *icon; // tab icon id, e.g. "printer_extruder_retraction#length"
@@ -33,8 +29,8 @@ struct PublishablePrinterOption {
const std::vector<PublishablePrinterOption>& publishable_printer_retraction_options();
const std::vector<PublishablePrinterOption>& publishable_printer_z_hop_options();
// Union of the two optgroup option lists; the published-3MF overlay applies printer keys only
// when their base key is in this allowlist (anything else is contract-excluded).
// Union of the two optgroup option lists; printer keys apply on import only if their base
// key is in this allowlist.
const std::set<std::string>& publishable_printer_keys();
// Union of setting keys differing from the base/system preset across the current print,
@@ -60,32 +56,25 @@ struct PublishedMaterialEntry {
// 0-based author filament slot; -1 (hand-crafted files) is skipped.
int slot{-1};
std::vector<std::string> keys;
// "Full Publish": the whole filament preset (full_keys) is published. On the receiver
// Full Publish always creates a standalone parentless copy (libslic3r's "Detach from
// parent"): a new project-embedded preset ("Preset Inside Project") with the full
// resolved config, universally compatible (compatible_printers/condition cleared).
// It lives inside the loaded project only - never written to the user's library,
// no existing preset is ever selected-by-reference or mutated. Identical Full
// entries inside one load share one created instance (within-load dedup).
// "Full Publish": the whole filament preset (full_keys) is published. On the receiver Full
// Publish always creates a standalone parentless copy (libslic3r's "Detach from parent"),
// universally compatible and project-embedded only - never written to the user's library.
// Identical Full entries within one load share one created instance (within-load dedup).
bool full{false};
// All non-structural filament keys of the author's slot preset; values travel in the file
// config, masked to the author's slot index.
std::vector<std::string> full_keys;
// Vendor-agnostic (MaterialType) filament type the author requires for this slot; on a
// partial entry's mismatch the slot is replaced with a same-type filament from the
// receiver's library. Full entries consult no gate: they detach unconditionally, and the
// copy carries whatever values the payload bakes.
// partial entry's mismatch the slot is replaced with a same-type filament. Full entries
// consult no gate.
bool publish_type{false};
std::string publish_type_value;
// Required filament colour, applied on load regardless of the type match.
bool publish_color{false};
std::string color;
// Import-side only, never serialized: the entry's authored slot sits past the receiver
// printer's physical filament capacity, so instead of growing a physical slot the entry
// is appended as an empty mixed-filament placeholder (virtual tail slot; the GUI flags
// it and the user assigns components from their own filaments). The flag also keeps the
// entry out of the payload mixed-definition validation and the value-apply passes,
// which only make sense for a slot that carries a real material.
// Import-side only, never serialized: the authored slot sits past the receiver's physical
// capacity, so the entry is appended as an empty mixed-filament placeholder (virtual tail
// slot; the GUI flags it for the user to assign components).
bool mixed_placeholder{false};
};
@@ -93,16 +82,12 @@ struct PublishedMaterialEntry {
std::string normalize_filament_type(const std::string& type);
class DynamicPrintConfig;
// Clear the compatibility lists/conditions on a filament config so it is compatible
// with every printer and every print profile. A detached published material is
// universally compatible by construction: the baseline clone may carry machine-specific
// restrictions. Empty lists + empty conditions => compatible with everything
// (see is_compatible_with_printer, Preset.cpp:840).
// Clear the compatibility lists/conditions on a filament config so it is universally
// compatible once detached (empty lists + empty conditions = compatible with everything).
void make_publish_universal(DynamicPrintConfig &config);
// Naming base for a detached published-material copy: "Generic PLA @System" ->
// "Generic PLA" (truncate at the first '@' variant tail, right-trimmed). Unchanged
// when the name carries no '@'. Empty result means "fall back to identity fields".
// Naming base for a detached published-material copy: "Generic PLA @System" -> "Generic PLA"
// (truncate/right-trim at the first '@' tail). Empty result means "fall back to identity".
std::string publish_material_base_name(const std::string &preset_name);
// Minimal DynamicPrintConfig for a published 3MF export: only the selected published keys,

View File

@@ -174,7 +174,7 @@ void KBShortcutsDialog::fill_shortcuts()
{ ctrl + "O", L("Open Project") },
{ ctrl + "S", L("Save Project") },
{ ctrl + shift + "S", L("Save Project as")},
{ ctrl + shift + "E", L("Publish") },
{ ctrl + shift + "E", L("Publish 3MF") },
// File>Import
{ ctrl + "I", L("Import geometry data from STL/STEP/3MF/OBJ/AMF files") },
// File>Export

View File

@@ -15300,11 +15300,12 @@ void Plater::load_project(wxString const& filename2,
if (using_exported_file()) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " using ecported set project filename: " << filename;
p->set_project_filename(filename);
} else if (loaded_published) {
} else if (loaded_published && !res.empty()) {
// A "published" 3MF loads as a new project: its path must not become the project
// filename (Save/Ctrl-S prompts for a destination instead of overwriting it);
// reset() already cleared the project name, so restore the default title and keep
// the file in recents.
// the file in recents. Only on a successful load (res not empty): a failed or
// cancelled load must not pollute "Recently opened".
p->set_project_name(_L("Untitled"));
if (!filename.IsEmpty())
wxGetApp().mainframe->add_to_recent_projects(filename);
@@ -18316,8 +18317,18 @@ int Plater::export_published_3mf(const std::vector<std::string>& published_keys,
DynamicPrintConfig full_cfg = wxGetApp().preset_bundle->full_config_secure();
DynamicPrintConfig filtered_cfg = filter_published_config(full_cfg, published_keys, material_keys);
std::string payload;
for (const std::string& key : filtered_cfg.keys())
payload += key + " = " + filtered_cfg.opt_serialize(key) + "\n";
for (const std::string& key : filtered_cfg.keys()) {
// A value containing a newline would break the INI written below (read_ini throws),
// so load_from_ini_string discards the whole settings block on import. Skip such
// keys instead of silently dropping every setting.
std::string value = filtered_cfg.opt_serialize(key);
if (value.find('\n') != std::string::npos) {
BOOST_LOG_TRIVIAL(warning) << "publish: dropping key \"" << key
<< "\" from the published payload (value contains a newline)";
continue;
}
payload += key + " = " + value + "\n";
}
model.model_info->metadata_items[ORCA_PUBLISHED_CONFIG_TAG] = std::move(payload);
// Same file layout as save_project(), plus Silence (so export_3mf does not set the project