mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-08 09:46:55 +00:00
fix more issues
This commit is contained in:
@@ -9,5 +9,5 @@
|
||||
"bed_texture": "creality_k1se_buildplate_texture.svg",
|
||||
"hotend_model": "",
|
||||
"default_bed_type": "Textured PEI Plate",
|
||||
"default_materials": "Generic ABS @Creality K1-all;Generic ASA @Creality K1-all;Generic PA-CF @Creality K1-all;Generic PC @Creality K1-all;Generic PETG @Creality K1-all;Generic PLA @Creality K1-all;Generic PLA High Speed @Creality K1-all;Generic PLA Matte @Creality K1-all;Generic PLA Silk @Creality K1-all;Generic PLA-CF @Creality K1-all;Generic TPU @Creality K1-all"
|
||||
"default_materials": "Generic ABS @Creality K1-all;Generic ABS @K1 SE-all;Generic ASA @Creality K1-all;Generic ASA @K1 SE-all;Generic PA-CF @Creality K1-all;Generic PC @Creality K1-all;Generic PETG @Creality K1-all;Generic PETG @K1 SE-all;Generic PLA @Creality K1-all;Generic PLA @K1 SE-all;Generic PLA High Speed @Creality K1-all;Generic PLA Matte @Creality K1-all;Generic PLA Silk @Creality K1-all;Generic PLA-CF @Creality K1-all;Generic PLA-CF @K1 SE-all;Generic TPU @Creality K1-all;Generic TPU @K1 SE-all"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"bed_texture": "creality_k1c_buildplate_texture.svg",
|
||||
"hotend_model": "",
|
||||
"default_bed_type": "Textured PEI Plate",
|
||||
"default_materials": "Generic ABS @Creality K1-all;Generic ASA @Creality K1-all;Generic PA-CF @Creality K1-all;Generic PC @Creality K1-all;Generic PETG @Creality K1-all;Generic PLA @Creality K1-all;Generic PLA High Speed @Creality K1-all;Generic PLA Matte @Creality K1-all;Generic PLA Silk @Creality K1-all;Generic PLA-CF @Creality K1-all;Generic TPU @Creality K1-all"
|
||||
"default_materials": "Generic ABS @Creality K1-all;Generic ABS @K1C-all;Generic ASA @Creality K1-all;Generic ASA @K1C-all;Generic PA-CF @Creality K1-all;Generic PA-CF @K1C-all;Generic PC @Creality K1-all;Generic PC @K1C-all;Generic PETG @Creality K1-all;Generic PETG @K1C-all;Generic PLA @Creality K1-all;Generic PLA @K1C-all;Generic PLA High Speed @Creality K1-all;Generic PLA Matte @Creality K1-all;Generic PLA Silk @Creality K1-all;Generic PLA-CF @Creality K1-all;Generic PLA-CF @K1C-all;Generic TPU @Creality K1-all;Generic TPU @K1C-all"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"bed_texture": "creality_k2plus_buildplate_texture.svg",
|
||||
"hotend_model": "",
|
||||
"default_bed_type": "Textured PEI Plate",
|
||||
"default_materials": "Generic ABS @Creality K2-all;Generic ASA @Creality K2-all;Generic PETG @Creality K2-all;Generic PLA @Creality K2-all;Generic PLA High Speed @Creality K2-all;Generic PLA Matte @Creality K2-all;Generic PLA Silk @Creality K2-all"
|
||||
"default_materials": "Generic ABS @Creality K2-all;Generic ABS @K2 Plus-all;Generic ASA @Creality K2-all;Generic ASA @K2 Plus-all;Generic PETG @Creality K2-all;Generic PETG @K2 Plus-all;Generic PLA @Creality K2-all;Generic PLA @K2 Plus-all;Generic PLA High Speed @Creality K2-all;Generic PLA Matte @Creality K2-all;Generic PLA Silk @Creality K2-all"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"bed_texture": "creality_k2pro_buildplate_texture.svg",
|
||||
"default_bed_type": "Textured PEI Plate",
|
||||
"hotend_model": "",
|
||||
"default_materials": "Generic ABS @Creality K2-all;Generic ASA @Creality K2-all;Generic PETG @Creality K2-all;Generic PLA @Creality K2-all;Generic PLA High Speed @Creality K2-all;Generic PLA Matte @Creality K2-all;Generic PLA Silk @Creality K2-all"
|
||||
"default_materials": "Generic ABS @Creality K2-all;Generic ABS @K2 Pro-all;Generic ASA @Creality K2-all;Generic ASA @K2 Pro-all;Generic PETG @Creality K2-all;Generic PETG @K2 Pro-all;Generic PLA @Creality K2-all;Generic PLA @K2 Pro-all;Generic PLA High Speed @Creality K2-all;Generic PLA Matte @Creality K2-all;Generic PLA Silk @Creality K2-all"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"default_bed_type": "Textured PEI Plate",
|
||||
"bed_texture": "creality_k2_buildplate_texture.svg",
|
||||
"hotend_model": "",
|
||||
"default_materials": "Generic ABS @Creality K2-all;Generic ASA @Creality K2-all;Generic PETG @Creality K2-all;Generic PLA @Creality K2-all;Generic PLA High Speed @Creality K2-all;Generic PLA Matte @Creality K2-all;Generic PLA Silk @Creality K2-all"
|
||||
"default_materials": "Generic ABS @Creality K2-all;Generic ABS @K2-all;Generic ASA @Creality K2-all;Generic ASA @K2-all;Generic PETG @Creality K2-all;Generic PETG @K2-all;Generic PLA @Creality K2-all;Generic PLA @K2-all;Generic PLA High Speed @Creality K2-all;Generic PLA Matte @Creality K2-all;Generic PLA Silk @Creality K2-all"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "flashforge_g3u_buildplate_model.stl",
|
||||
"bed_texture": "flashforge_g3u_buildplate_texture.svg",
|
||||
"hotend_model": "",
|
||||
"default_materials": "Generic PVA @Flashforge;Generic HIPS @Flashforge;Generic PETG-CF @Flashforge G3U;Generic PETG @Flashforge G3U;Generic PLA-CF @Flashforge G3U;Generic PLA @Flashforge G3U;Generic ASA @Flashforge G3U;Generic ABS @Flashforge G3U;FusRock PET-CF;FusRock PAHT-CF;FusRock NexPA-CF25;FusRock S-Multi;FusRock S-PAHT;Polymaker CoPA;Polymaker S1"
|
||||
"default_materials": "FusRock NexPA-CF25;FusRock PAHT-CF;FusRock PAHT-CF @G3U 0.6 Nozzle;FusRock PET-CF;FusRock PET-CF @G3U 0.6 Nozzle;FusRock S-Multi;FusRock S-PAHT;Generic ABS @Flashforge G3U;Generic ABS @Flashforge G3U 0.6 Nozzle;Generic ASA @Flashforge G3U;Generic ASA @Flashforge G3U 0.6 Nozzle;Generic HIPS @Flashforge;Generic HIPS @Flashforge G3U 0.6 Nozzle;Generic PETG @Flashforge G3U;Generic PETG @Flashforge G3U 0.6 Nozzle;Generic PETG @Flashforge G3U 0.8 Nozzle;Generic PETG-CF @Flashforge G3U;Generic PETG-CF @Flashforge G3U 0.6 Nozzle;Generic PETG-CF @Flashforge G3U 0.8 Nozzle;Generic PLA @Flashforge G3U;Generic PLA-CF @Flashforge G3U;Generic PLA-CF @Flashforge G3U 0.6 Nozzle;Generic PLA-CF @Flashforge G3U 0.8 Nozzle;Generic PVA @Flashforge;Polymaker CoPA;Polymaker S1"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "Wanhao_D12-230_buildplate_model.stl",
|
||||
"bed_texture": "D12_texture.png",
|
||||
"hotend_model": "Wanhao D12-300_hotend.stl",
|
||||
"default_materials": "YUMI PLA Bowden;YUMI PETG;"
|
||||
"default_materials": "YUMI PLA Direct Drive;YUMI PETG;"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "Wanhao_D12-230_buildplate_model.stl",
|
||||
"bed_texture": "D12_texture.png",
|
||||
"hotend_model": "Wanhao D12-300_hotend.stl",
|
||||
"default_materials": "YUMI PLA Bowden;YUMI PETG;"
|
||||
"default_materials": "YUMI PLA Direct Drive;YUMI PETG;"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "Wanhao_D12-300_buildplate_model.stl",
|
||||
"bed_texture": "D12_texture.png",
|
||||
"hotend_model": "Wanhao D12-300_hotend.stl",
|
||||
"default_materials": "YUMI PLA Bowden;YUMI PETG;"
|
||||
"default_materials": "YUMI PLA Direct Drive;YUMI PETG;"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "Wanhao_D12-300_buildplate_model.stl",
|
||||
"bed_texture": "D12_texture.png",
|
||||
"hotend_model": "Wanhao D12-300_hotend.stl",
|
||||
"default_materials": "YUMI PLA Bowden;YUMI PETG;"
|
||||
"default_materials": "YUMI PLA Direct Drive;YUMI PETG;"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "Wanhao_D12-500_buildplate_model.stl",
|
||||
"bed_texture": "D12_texture.png",
|
||||
"hotend_model": "Wanhao D12-300_hotend.stl",
|
||||
"default_materials": "YUMI PLA Bowden;YUMI PETG;"
|
||||
"default_materials": "YUMI PLA Direct Drive;YUMI PETG;"
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"bed_model": "Wanhao_D12-500_buildplate_model.stl",
|
||||
"bed_texture": "D12_texture.png",
|
||||
"hotend_model": "Wanhao D12-300_hotend.stl",
|
||||
"default_materials": "YUMI PLA Bowden;YUMI PETG;"
|
||||
"default_materials": "YUMI PLA Direct Drive;YUMI PETG;"
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ int main(int argc, char* argv[])
|
||||
("generate_presets,g", po::value<bool>()->default_value(false), "Generate user presets for mock test")
|
||||
("slice,s", po::bool_switch()->default_value(false), "Slice a two-colour cube through every printer to expand all custom g-code (catches placeholder/flow errors that static checks miss). Off unless this flag is present.")
|
||||
("outdir,o", po::value<std::string>()->default_value(""), "With -s, also save each printer's g-code to this folder (as <vendor>__<printer>.gcode) for manual inspection. Optional.")
|
||||
("check_filament_subtypes,f", po::bool_switch()->default_value(false), "Also flag printers with duplicate (ambiguous) filament subtypes. Off unless this flag is present.")
|
||||
("check_filament_subtypes,f", po::bool_switch()->default_value(true), "Also flag printers with duplicate (ambiguous) filament subtypes. Off unless this flag is present.")
|
||||
("log_level,l", po::value<int>()->default_value(2), "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs.");
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -16,6 +18,12 @@ namespace {
|
||||
|
||||
constexpr const char* CrealityPrintAgent_VERSION = "0.1.0";
|
||||
|
||||
std::string to_lower(std::string s)
|
||||
{
|
||||
for (auto& c : s) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
return s;
|
||||
}
|
||||
|
||||
bool has_visible_base_preset(const PresetCollection& filaments, const std::string& filament_id)
|
||||
{
|
||||
for (const auto& p : filaments.get_presets()) {
|
||||
@@ -27,19 +35,47 @@ bool has_visible_base_preset(const PresetCollection& filaments, const std::strin
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lower-case words of a preset name with the "@scope" suffix dropped:
|
||||
// "Generic PLA Matte @Creality K2-all" -> {"generic", "pla", "matte"}.
|
||||
std::vector<std::string> name_words(const std::string& name)
|
||||
{
|
||||
std::vector<std::string> words;
|
||||
std::string word;
|
||||
for (char c : name.substr(0, name.find('@'))) {
|
||||
if (std::isalnum(static_cast<unsigned char>(c))) {
|
||||
word += static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
} else if (!word.empty()) {
|
||||
words.push_back(word);
|
||||
word.clear();
|
||||
}
|
||||
}
|
||||
if (!word.empty())
|
||||
words.push_back(word);
|
||||
return words;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Score visible compatible filament presets against the CFS spool metadata and
|
||||
// return the best-matching filament_id. Scoring:
|
||||
// +20 preset name contains brand_name as a substring
|
||||
// (e.g. "Hyper PLA" in "Hyper PLA @Creality K2 0.4 nozzle")
|
||||
// +10 preset name contains the vendor substring (e.g. "Creality")
|
||||
// Tiebreak: prefer the SYSTEM (shipped) preset over user copies. Brand-
|
||||
// specific system presets carry their own filament_id; user copies of
|
||||
// generic presets inherit a generic filament_id from their parent, so
|
||||
// preferring the user copy can collapse a brand-specific match back to
|
||||
// "Generic PLA" via the inherited id. Plus: this code targets upstream
|
||||
// OrcaSlicer where shipping the user's local tuning would be wrong.
|
||||
// +10 the preset belongs to the spool's vendor - by its owning VendorProfile OR by
|
||||
// its name. The profile test is what finds the vendor's own generics, which are
|
||||
// named "Generic <material> @<scope>" and do not repeat the vendor; the name test
|
||||
// still finds a third party filament shipped inside that vendor's bundle, which
|
||||
// carries the bundle owner's profile but names its real brand.
|
||||
// -5 per word of the preset name the spool never mentioned ("generic" excepted -
|
||||
// it marks the unbranded base product rather than a qualifier), so the least
|
||||
// specific preset that still explains the spool wins. Without it a spool
|
||||
// reporting only "PLA" scores "Generic PLA High Speed" and "Generic PLA Matte"
|
||||
// exactly as high as "Generic PLA"; those are three products with three
|
||||
// filament_ids, so whichever sorted first won and the printer got the wrong
|
||||
// one. Applied after the score gate, so it only reorders genuine matches.
|
||||
// Tiebreak: prefer the SYSTEM (shipped) preset over user copies, then by name so the
|
||||
// winner never depends on how std::sort leaves equal elements. User copies of generic
|
||||
// presets inherit a generic filament_id from their parent, so preferring the user copy
|
||||
// can collapse a brand-specific match back to "Generic PLA" via the inherited id.
|
||||
// Requires the preset's declared filament_type to equal the spool's base type
|
||||
// (PLA/PETG/ABS/...) so we never auto-pick a PETG preset for a PLA spool.
|
||||
// Falls back to filaments.filament_id_by_type(base_type) when nothing scores.
|
||||
@@ -48,15 +84,17 @@ std::string CrealityPrintAgent::match_filament_preset(const PresetCollection& fi
|
||||
const std::string& brand_name,
|
||||
const std::string& base_type)
|
||||
{
|
||||
auto to_lower = [](std::string s) {
|
||||
for (auto& c : s) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
return s;
|
||||
};
|
||||
|
||||
const std::string vendor_lower = to_lower(vendor);
|
||||
const std::string brand_lower = to_lower(brand_name);
|
||||
const std::string type_lower = to_lower(base_type);
|
||||
|
||||
// Everything the spool told us about itself, as words. A word in a preset's name
|
||||
// that is not in here is a qualifier the spool never claimed.
|
||||
std::set<std::string> spool_words{"generic"};
|
||||
for (const std::string& src : {brand_lower, vendor_lower, type_lower})
|
||||
for (auto& w : name_words(src))
|
||||
spool_words.insert(std::move(w));
|
||||
|
||||
struct Match {
|
||||
const Preset* preset;
|
||||
int score;
|
||||
@@ -83,11 +121,20 @@ std::string CrealityPrintAgent::match_filament_preset(const PresetCollection& fi
|
||||
int score = 0;
|
||||
if (!brand_lower.empty() && name_lower.find(brand_lower) != std::string::npos)
|
||||
score += 20;
|
||||
if (!vendor_lower.empty() && name_lower.find(vendor_lower) != std::string::npos)
|
||||
// Profile OR name - neither alone covers both the vendor's own generics and the
|
||||
// third party filaments shipped inside its bundle. See the header comment.
|
||||
if (!vendor_lower.empty()
|
||||
&& ((p.vendor != nullptr && to_lower(p.vendor->name) == vendor_lower)
|
||||
|| name_lower.find(vendor_lower) != std::string::npos))
|
||||
score += 10;
|
||||
|
||||
if (score > 0)
|
||||
matches.push_back({&p, score, !p.is_system && !p.is_default});
|
||||
if (score == 0) continue;
|
||||
|
||||
for (const auto& w : name_words(p.name))
|
||||
if (spool_words.count(w) == 0)
|
||||
score -= 5;
|
||||
|
||||
matches.push_back({&p, score, !p.is_system && !p.is_default});
|
||||
}
|
||||
|
||||
if (matches.empty()) {
|
||||
@@ -105,7 +152,7 @@ std::string CrealityPrintAgent::match_filament_preset(const PresetCollection& fi
|
||||
[](const Match& a, const Match& b) {
|
||||
if (a.score != b.score) return a.score > b.score;
|
||||
if (a.is_user != b.is_user) return !a.is_user; // prefer system over user
|
||||
return false;
|
||||
return a.preset->name < b.preset->name; // keep the winner deterministic
|
||||
});
|
||||
|
||||
BOOST_LOG_TRIVIAL(info)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
|
||||
add_executable(${_TEST_NAME}_tests
|
||||
${_TEST_NAME}_tests_main.cpp
|
||||
test_creality_cfs_match.cpp
|
||||
test_dev_mapping.cpp
|
||||
test_filament_bitmap_utils.cpp
|
||||
test_network_versions.cpp
|
||||
|
||||
141
tests/slic3rutils/test_creality_cfs_match.cpp
Normal file
141
tests/slic3rutils/test_creality_cfs_match.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "libslic3r/Preset.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "slic3r/Utils/CrealityPrintAgent.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
namespace {
|
||||
|
||||
// A standalone filament collection, built the same way PresetBundle builds its own, so the
|
||||
// CFS matcher can be exercised without loading the shipped profiles or touching a printer.
|
||||
struct FilamentTestCollection : public PresetCollection
|
||||
{
|
||||
FilamentTestCollection()
|
||||
: PresetCollection(Preset::TYPE_FILAMENT, Preset::filament_options(),
|
||||
static_cast<const PrintRegionConfig &>(FullPrintConfig::defaults()))
|
||||
{}
|
||||
};
|
||||
|
||||
struct FilamentSpec
|
||||
{
|
||||
const char *name;
|
||||
const char *filament_id;
|
||||
const char *filament_type;
|
||||
bool is_library = false; // belongs to the Orca Filament Library, not the printer vendor
|
||||
bool is_system = true;
|
||||
};
|
||||
|
||||
// Load the specs into the collection, then stamp the fields the matcher reads. Done in a second
|
||||
// pass because load_preset() keeps m_presets sorted, so a reference taken during the first pass
|
||||
// can be left dangling by a later load.
|
||||
void populate(PresetCollection &filaments, const std::vector<FilamentSpec> &specs,
|
||||
const VendorProfile &vendor, const VendorProfile &library)
|
||||
{
|
||||
for (const FilamentSpec &spec : specs) {
|
||||
DynamicPrintConfig config(filaments.default_preset().config);
|
||||
config.option<ConfigOptionStrings>("filament_type", true)->values = {spec.filament_type};
|
||||
filaments.load_preset(std::string(), spec.name, config, /*select=*/false);
|
||||
}
|
||||
for (auto it = filaments.begin(); it != filaments.end(); ++it) {
|
||||
const auto spec = std::find_if(specs.begin(), specs.end(),
|
||||
[&](const FilamentSpec &s) { return it->name == s.name; });
|
||||
if (spec == specs.end())
|
||||
continue;
|
||||
it->filament_id = spec->filament_id;
|
||||
it->vendor = spec->is_library ? &library : &vendor;
|
||||
it->is_system = spec->is_system;
|
||||
it->is_default = false;
|
||||
it->is_visible = true;
|
||||
it->is_compatible = true;
|
||||
}
|
||||
}
|
||||
|
||||
// What a stock K2 with a 0.4 nozzle sees after the filament_id rework: the vendor's plain generics
|
||||
// carry no "Creality" in their name (they are "Generic <material> @<scope>"), while the subtype
|
||||
// variants that do keep a vendor scope are separate products with their own filament_ids.
|
||||
const std::vector<FilamentSpec> k2_stock_nozzle{
|
||||
{"AliZ PLA @System", "ALIZ-PLA", "PLA", /*is_library=*/true},
|
||||
{"Generic PETG @K2-all", "PETG-GENERIC", "PETG"},
|
||||
{"Generic PLA @K2-all", "PLA-GENERIC", "PLA"},
|
||||
{"Generic PLA High Speed @Creality K2-all","PLA-HS", "PLA"},
|
||||
{"Generic PLA Matte @Creality K2-all", "PLA-MATTE", "PLA"},
|
||||
{"Generic PLA Silk @Creality K2-all", "PLA-SILK", "PLA"},
|
||||
{"Hyper PLA @K2-all", "PLA-HYPER", "PLA"},
|
||||
};
|
||||
|
||||
std::string match(const std::vector<FilamentSpec> &specs, const std::string &spool_vendor,
|
||||
const std::string &spool_name, const std::string &base_type)
|
||||
{
|
||||
FilamentTestCollection filaments;
|
||||
VendorProfile vendor("Creality");
|
||||
VendorProfile library(PresetBundle::ORCA_FILAMENT_LIBRARY);
|
||||
vendor.name = "Creality";
|
||||
library.name = PresetBundle::ORCA_FILAMENT_LIBRARY;
|
||||
populate(filaments, specs, vendor, library);
|
||||
return CrealityPrintAgent::match_filament_preset(filaments, spool_vendor, spool_name, base_type);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Orca: a CFS spool that names no recognised product must map to the vendor's plain generic. The
|
||||
// subtype variants ("High Speed", "Matte", "Silk") score just as well on vendor alone, and since
|
||||
// each is its own product with its own filament_id, letting one of them win sends the printer the
|
||||
// id of a filament the user does not have loaded.
|
||||
TEST_CASE("An unbranded CFS spool maps to the vendor's plain generic, not a subtype", "[CFS][Creality]")
|
||||
{
|
||||
CHECK(match(k2_stock_nozzle, "Creality", "", "PLA") == "PLA-GENERIC");
|
||||
}
|
||||
|
||||
// Orca: the vendor bonus reads the preset's owning VendorProfile. "Generic PETG @K2-all" does not
|
||||
// repeat "Creality" anywhere in its name, so a name based vendor test scored nothing for it and the
|
||||
// spool fell through to the collection wide first-of-type - an unrelated third party PETG.
|
||||
TEST_CASE("A CFS spool matches its vendor's presets even when the name omits the vendor", "[CFS][Creality]")
|
||||
{
|
||||
CHECK(match(k2_stock_nozzle, "Creality", "", "PETG") == "PETG-GENERIC");
|
||||
}
|
||||
|
||||
TEST_CASE("A branded CFS spool still beats the generic", "[CFS][Creality]")
|
||||
{
|
||||
CHECK(match(k2_stock_nozzle, "Creality", "Hyper PLA", "PLA") == "PLA-HYPER");
|
||||
}
|
||||
|
||||
// Orca: the specificity penalty must not stop a spool that genuinely asks for a subtype from
|
||||
// getting it - only unclaimed qualifiers are penalised.
|
||||
TEST_CASE("A CFS spool that names a subtype gets that subtype", "[CFS][Creality]")
|
||||
{
|
||||
CHECK(match(k2_stock_nozzle, "Creality", "Generic PLA Silk", "PLA") == "PLA-SILK");
|
||||
CHECK(match(k2_stock_nozzle, "Creality", "Generic PLA Matte", "PLA") == "PLA-MATTE");
|
||||
}
|
||||
|
||||
// Orca: a third party spool matches no preset by brand or vendor, so it falls back to the first
|
||||
// visible preset of the same type rather than returning nothing. Which one that is depends on the
|
||||
// collection's ordering, so only the type is pinned here - what matters is that a PLA spool never
|
||||
// comes back empty and never comes back as another material.
|
||||
TEST_CASE("A CFS spool from an unknown vendor falls back to a preset of the same type", "[CFS][Creality]")
|
||||
{
|
||||
const std::string matched = match(k2_stock_nozzle, "SomeOtherBrand", "", "PLA");
|
||||
REQUIRE_FALSE(matched.empty());
|
||||
const auto spec = std::find_if(k2_stock_nozzle.begin(), k2_stock_nozzle.end(),
|
||||
[&](const FilamentSpec &s) { return matched == s.filament_id; });
|
||||
REQUIRE(spec != k2_stock_nozzle.end());
|
||||
CHECK(std::string(spec->filament_type) == "PLA");
|
||||
}
|
||||
|
||||
|
||||
// Orca: Creality's bundle also ships third party filaments ("eSUN PLA+ @K2 Plus-all"). Those carry
|
||||
// Creality's VendorProfile but name their real brand, so the vendor bonus has to accept a name
|
||||
// match as well as a profile match - otherwise an eSUN spool stops matching its own preset.
|
||||
TEST_CASE("A third party spool matches its preset inside the printer vendor's bundle", "[CFS][Creality]")
|
||||
{
|
||||
const std::vector<FilamentSpec> with_third_party{
|
||||
{"Generic PLA @K2-all", "PLA-GENERIC", "PLA"},
|
||||
{"eSUN PLA+ @K2 Plus-all", "ESUN-PLA", "PLA"}, // shipped by Creality, branded eSUN
|
||||
};
|
||||
CHECK(match(with_third_party, "eSUN", "", "PLA") == "ESUN-PLA");
|
||||
// ... and a Creality spool still prefers Creality's own generic over the eSUN preset, which
|
||||
// carries Creality's profile too but adds a brand word the spool never claimed.
|
||||
CHECK(match(with_third_party, "Creality", "", "PLA") == "PLA-GENERIC");
|
||||
}
|
||||
Reference in New Issue
Block a user