diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index 745bc5289..81658842b 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -244,7 +244,16 @@ jobs: ./BuildLinux.sh -isr mv -n ./build/OrcaSlicer_Linux_V${{ env.ver_pure }}.AppImage ./build/OrcaSlicer_Linux_${{ env.ver }}.AppImage chmod +x ./build/OrcaSlicer_Linux_${{ env.ver }}.AppImage - + + - name: Build orca_custom_preset_tests + if: github.ref == 'refs/heads/main' && inputs.os == 'ubuntu-20.04' + working-directory: ${{ github.workspace }}/build/src + shell: bash + run: | + OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -g 1 + cd ${{ github.workspace }}/resources/profiles + zip -r orca_custom_preset_tests.zip user/ + - name: Upload artifacts Ubuntu if: inputs.os == 'ubuntu-20.04' uses: actions/upload-artifact@v3 @@ -262,3 +271,14 @@ jobs: asset_name: OrcaSlicer_Linux_${{ env.ver }}.AppImage asset_content_type: application/octet-stream max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted + + - name: Deploy orca_custom_preset_tests + if: github.ref == 'refs/heads/main' && inputs.os == 'ubuntu-20.04' + uses: WebFreak001/deploy-nightly@v3.0.0 + with: + upload_url: https://uploads.github.com/repos/SoftFever/OrcaSlicer/releases/137995723/assets{?name,label} + release_id: 137995723 + asset_path: ${{ github.workspace }}/resources/profiles/orca_custom_preset_tests.zip + asset_name: orca_custom_preset_tests + asset_content_type: application/octet-stream + max_releases: 1 diff --git a/.github/workflows/check_profiles.yml b/.github/workflows/check_profiles.yml index e1d18fd54..5878172ad 100644 --- a/.github/workflows/check_profiles.yml +++ b/.github/workflows/check_profiles.yml @@ -1,4 +1,4 @@ -name: Check locale +name: Check profiles on: pull_request: branches: @@ -19,12 +19,21 @@ jobs: - name: Download working-directory: ${{ github.workspace }} run: | - curl -LJO https://github.com/SoftFever/Orca_tools/releases/download/1/OrcaSlicer_profile_validator_ubuntu - chmod +x ./OrcaSlicer_profile_validator_ubuntu + curl -LJO https://github.com/SoftFever/Orca_tools/releases/download/1/OrcaSlicer_profile_validator + chmod +x ./OrcaSlicer_profile_validator # validate profiles - - name: validate profiles + - name: validate system profiles run: | ./OrcaSlicer_profile_validator_ubuntu -p ${{ github.workspace }}/resources/profiles -l 2 + - name: validate custom presets + working-directory: ${{ github.workspace }} + run: | + curl -LJO https://github.com/SoftFever/OrcaSlicer/releases/download/nightly-builds/orca_custom_preset_tests.zip + unzip ./orca_custom_preset_tests.zip -d ${{ github.workspace }}/resources/profiles + ./OrcaSlicer_profile_validator_ubuntu -p ${{ github.workspace }}/resources/profiles -l 2 + + + diff --git a/.gitignore b/.gitignore index 6b560a66c..4ec8a2075 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ src/OrcaSlicer-doc/ **/filament_full/ /deps/DL_CACHE/ /deps/DL_CACHE +resources/profiles/user/default \ No newline at end of file diff --git a/BuildLinux.sh b/BuildLinux.sh index 94b250ba5..772617aaf 100755 --- a/BuildLinux.sh +++ b/BuildLinux.sh @@ -227,13 +227,16 @@ then # cmake pushd build - echo -e "cmake .. -DCMAKE_PREFIX_PATH=\"$PWD/../deps/build/destdir/usr/local\" -DSLIC3R_STATIC=1 ${BUILD_ARGS}" - cmake .. -DCMAKE_PREFIX_PATH="$PWD/../deps/build/destdir/usr/local" -DSLIC3R_STATIC=1 ${BUILD_ARGS} + echo -e "cmake .. -DCMAKE_PREFIX_PATH=\"$PWD/../deps/build/destdir/usr/local\" -DSLIC3R_STATIC=1 -DORCA_TOOLS=ON ${BUILD_ARGS}" + cmake .. -DCMAKE_PREFIX_PATH="$PWD/../deps/build/destdir/usr/local" -DSLIC3R_STATIC=1 ${BUILD_ARGS} -DORCA_TOOLS=ON echo "done" # make Slic3r echo "[8/9] Building Slic3r..." make -j$NCORES OrcaSlicer # Slic3r + + # make OrcaSlicer_profile_validator + make -j$NCORES OrcaSlicer_profile_validator popd ./run_gettext.sh echo "done" diff --git a/resources/profiles/Elegoo/machine/fdm_neptune_4_common.json b/resources/profiles/Elegoo/machine/fdm_neptune_4_common.json index 48e18c656..659cc3c5d 100644 --- a/resources/profiles/Elegoo/machine/fdm_neptune_4_common.json +++ b/resources/profiles/Elegoo/machine/fdm_neptune_4_common.json @@ -116,8 +116,6 @@ "deretraction_speed": [ "40" ], - "bridge_speed": "25", - "internal_bridge_speed" : "70", "silent_mode": "0", "single_extruder_multi_material": "1", "change_filament_gcode": "", diff --git a/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1 0.4 nozzle.json b/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1 0.4 nozzle.json index 7c99007fd..8ac287c83 100644 --- a/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1 0.4 nozzle.json +++ b/resources/profiles/Kingroon/machine/Kingroon KP3S PRO S1 0.4 nozzle.json @@ -1,5 +1,4 @@ { - "bbl_calib_mark_logo": "1", "setting_id": "GM003", "name": "Kingroon KP3S PRO S1 0.4 nozzle", "instantiation": "true", diff --git a/resources/profiles/Kingroon/machine/fdm_machine_common.json b/resources/profiles/Kingroon/machine/fdm_machine_common.json index b29d6a225..a4ea4dd5b 100644 --- a/resources/profiles/Kingroon/machine/fdm_machine_common.json +++ b/resources/profiles/Kingroon/machine/fdm_machine_common.json @@ -1,6 +1,5 @@ { "type": "machine", - "bbl_calib_mark_logo": "1", "name": "fdm_machine_common", "auxiliary_fan": "0", "fan_kickstart": "0", diff --git a/resources/profiles/Snapmaker/machine/fdm_common.json b/resources/profiles/Snapmaker/machine/fdm_common.json index f12ca8f13..6066188b5 100644 --- a/resources/profiles/Snapmaker/machine/fdm_common.json +++ b/resources/profiles/Snapmaker/machine/fdm_common.json @@ -11,7 +11,6 @@ "auxiliary_fan": "0", "remaining_times": "1", "single_extruder_multi_material": "0", - "single_extruder_multi_material_priming": "0", "purge_in_prime_tower": "0", "enable_filament_ramming": "0", "nozzle_volume": "0", diff --git a/src/OrcaSlicer_profile_validator.cpp b/src/OrcaSlicer_profile_validator.cpp index f94b7bec8..374592199 100644 --- a/src/OrcaSlicer_profile_validator.cpp +++ b/src/OrcaSlicer_profile_validator.cpp @@ -1,22 +1,93 @@ +#include "libslic3r/Preset.hpp" +#include "libslic3r/Config.hpp" #include "libslic3r/PresetBundle.hpp" +#include "libslic3r/Print.hpp" #include "libslic3r/Utils.hpp" #include #include #include #include +#include using namespace Slic3r; namespace po = boost::program_options; +void generate_custom_presets(PresetBundle* preset_bundle, AppConfig& app_config) +{ + struct cus_preset + { + std::string name; + std::string parent_name; + }; + // create user presets + auto createCustomPrinters = [&](Preset::Type type) { + std::vector custom_preset; + PresetCollection* collection = nullptr; + if (type == Preset::TYPE_PRINT) + collection = &preset_bundle->prints; + else if (type == Preset::TYPE_FILAMENT) + collection = &preset_bundle->filaments; + else if (type == Preset::TYPE_PRINTER) + collection = &preset_bundle->printers; + else + return; + custom_preset.reserve(collection->size()); + for (auto& parent : collection->get_presets()) { + if (!parent.is_system) + continue; + auto new_name = parent.name + "_orca_test"; + if (parent.vendor) + new_name = parent.vendor->name + "_" + new_name; + custom_preset.push_back({new_name, parent.name}); + } + for (auto p : custom_preset) { + // Creating a new preset. + auto parent = collection->find_preset(p.parent_name); + if (type == Preset::TYPE_FILAMENT) + parent->config.set_key_value("filament_start_gcode", + new ConfigOptionStrings({"this_is_orca_test_filament_start_gcode_mock"})); + else if (type == Preset::TYPE_PRINT) + parent->config.set_key_value("filename_format", new ConfigOptionString("this_is_orca_test_filename_format_mock")); + else if (type == Preset::TYPE_PRINTER) + parent->config.set_key_value("machine_start_gcode", + new ConfigOptionString("this_is_orca_test_machine_start_gcode_mock")); + + collection->save_current_preset(p.name, false, false, parent); + + } + }; + createCustomPrinters(Preset::TYPE_PRINTER); + createCustomPrinters(Preset::TYPE_FILAMENT); + createCustomPrinters(Preset::TYPE_PRINT); + + std::string user_sub_folder = DEFAULT_USER_FOLDER_NAME; + const std::string dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/" + user_sub_folder; + + fs::path user_folder(data_dir() + "/" + PRESET_USER_DIR); + if (!fs::exists(user_folder)) + fs::create_directory(user_folder); + + fs::path folder(dir_user_presets); + if (!fs::exists(folder)) + fs::create_directory(folder); + std::vector need_to_delete_list; // store setting ids of preset + + preset_bundle->prints.save_user_presets(dir_user_presets, PRESET_PRINT_NAME, need_to_delete_list); + preset_bundle->filaments.save_user_presets(dir_user_presets, PRESET_FILAMENT_NAME, need_to_delete_list); + preset_bundle->printers.save_user_presets(dir_user_presets, PRESET_PRINTER_NAME, need_to_delete_list); + + std::cout << "Custom presets generated successfully" << std::endl; +} int main(int argc, char* argv[]) { - po::options_description desc("Allowed options"); + po::options_description desc("Orca Profile Validator\nUsage"); + // clang-format off desc.add_options()("help,h", "help") - ("path,p", po::value()->default_value("../../../resources/profiles"), "profile folder") - ("vendor,v", po::value()->default_value(""), - "Vendor name. Optional, all profiles present in the folder will be validated if not specified") - ("log_level,l", po::value()->default_value(2), - "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs."); + ("path,p", po::value()->default_value("../../../resources/profiles"), "profile folder") + ("vendor,v", po::value()->default_value(""), "Vendor name. Optional, all profiles present in the folder will be validated if not specified") + ("generate_presets,g", po::value()->default_value(false), "Generate user presets for mock test") + ("log_level,l", po::value()->default_value(2), "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs."); + // clang-format on po::variables_map vm; try { @@ -34,9 +105,10 @@ int main(int argc, char* argv[]) return 1; } - std::string path = vm["path"].as(); - std::string vendor = vm["vendor"].as(); - int log_level = vm["log_level"].as(); + std::string path = vm["path"].as(); + std::string vendor = vm["vendor"].as(); + int log_level = vm["log_level"].as(); + bool generate_user_preset = vm["generate_presets"].as(); // check if path is valid, and return error if not if (!fs::exists(path) || !fs::is_directory(path)) { @@ -44,20 +116,29 @@ int main(int argc, char* argv[]) return 1; } - // std::cout<<"path: "<setup_directories(); + // preset_bundle->setup_directories(); preset_bundle->set_is_validation_mode(true); preset_bundle->set_vendor_to_validate(vendor); preset_bundle->set_default_suppressed(true); AppConfig app_config; + app_config.set("preset_folder", "default"); + + if(generate_user_preset) + preset_bundle->remove_user_presets_directory("default"); try { auto preset_substitutions = preset_bundle->load_presets(app_config, ForwardCompatibilitySubstitutionRule::EnableSystemSilent); @@ -66,6 +147,17 @@ int main(int argc, char* argv[]) std::cout << "Validation failed" << std::endl; return 1; } + + if (generate_user_preset) { + generate_custom_presets(preset_bundle, app_config); + return 0; + } + + if (preset_bundle->has_errors()) { + std::cout << "Validation failed" << std::endl; + return 1; + } + std::cout << "Validation completed successfully" << std::endl; return 0; } diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 6bb4e7aff..48c52d968 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1122,6 +1122,7 @@ void PresetCollection::load_presets( if (fs::exists(file_path)) fs::remove(file_path); BOOST_LOG_TRIVIAL(error) << boost::format("parse config %1% failed")%preset.file; + ++m_errors; continue; } @@ -1159,6 +1160,7 @@ void PresetCollection::load_presets( auto inherits_config2 = dynamic_cast(inherits_config); if ((inherits_config2 && !inherits_config2->value.empty()) && !preset.is_custom_defined()) { BOOST_LOG_TRIVIAL(error) << boost::format("can not find parent for config %1%!")%preset.file; + ++m_errors; continue; } // Find a default preset for the config. The PrintPresetCollection provides different default preset based on the "printer_technology" field. @@ -1169,9 +1171,12 @@ void PresetCollection::load_presets( Preset::normalize(preset.config); // Report configuration fields, which are misplaced into a wrong group. std::string incorrect_keys = Preset::remove_invalid_keys(preset.config, default_preset.config); - if (!incorrect_keys.empty()) - BOOST_LOG_TRIVIAL(error) << "Error in a preset file: The preset \"" << - preset.file << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed"; + if (!incorrect_keys.empty()) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) + << "Error in a preset file: The preset \"" << preset.file + << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed"; + } preset.loaded = true; //BBS: add some workaround for previous incorrect settings if ((!preset.setting_id.empty())&&(preset.setting_id == preset.base_id)) @@ -1179,6 +1184,7 @@ void PresetCollection::load_presets( //BBS: add config related logs BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", preset type %1%, name %2%, path %3%, is_system %4%, is_default %5% is_visible %6%")%Preset::get_type_string(m_type) %preset.name %preset.file %preset.is_system %preset.is_default %preset.is_visible; } catch (const std::ifstream::failure &err) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << boost::format("The user-config cannot be loaded: %1%. Reason: %2%")%preset.file %err.what(); fs::path file_path(preset.file); if (fs::exists(file_path)) @@ -1188,6 +1194,7 @@ void PresetCollection::load_presets( fs::remove(file_path); //throw Slic3r::RuntimeError(std::string("The selected preset cannot be loaded: ") + preset.file + "\n\tReason: " + err.what()); } catch (const std::runtime_error &err) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << boost::format("Failed loading the user-config file: %1%. Reason: %2%")%preset.file %err.what(); //throw Slic3r::RuntimeError(std::string("Failed loading the preset file: ") + preset.file + "\n\tReason: " + err.what()); fs::path file_path(preset.file); @@ -1252,6 +1259,7 @@ int PresetCollection::get_differed_values_to_update(Preset& preset, std::map& proje Preset::normalize(preset->config); // Report configuration fields, which are misplaced into a wrong group. std::string incorrect_keys = Preset::remove_invalid_keys(preset->config, default_preset.config); - if (! incorrect_keys.empty()) - BOOST_LOG_TRIVIAL(error) << "Error in a preset file: The preset \"" << - preset->name << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed"; + if (!incorrect_keys.empty()) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << "Error in a preset file: The preset \"" << preset->name + << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed"; + } preset->loaded = true; presets_loaded.emplace_back(*preset); BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", %1% got preset, name %2%, path %3%, is_system %4%, is_default %5% is_visible %6%")%Preset::get_type_string(m_type) %preset->name %preset->file %preset->is_system %preset->is_default %preset->is_visible; @@ -1533,6 +1543,7 @@ void PresetCollection::save_user_presets(const std::string& dir_path, const std: } Preset* parent_preset = this->find_preset(inherits, false, true); if (!parent_preset) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(" can not find parent preset for %1% , inherits %2%")%preset->name %inherits; continue; } @@ -1680,9 +1691,11 @@ bool PresetCollection::load_user_preset(std::string name, std::mapname == m_edited_preset.name && iter->is_dirty) { // Keep modifies when update from remote @@ -2800,9 +2813,13 @@ void PresetCollection::update_map_system_profile_renamed() for (Preset &preset : m_presets) for (const std::string &renamed_from : preset.renamed_from) { const auto [it, success] = m_map_system_profile_renamed.insert(std::pair(renamed_from, preset.name)); - if (! success) - BOOST_LOG_TRIVIAL(error) << boost::format("Preset name \"%1%\" was marked as renamed from \"%2%\", though preset name \"%3%\" was marked as renamed from \"%2%\" as well.") % preset.name % renamed_from % it->second; - } + if (!success) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << boost::format("Preset name \"%1%\" was marked as renamed from \"%2%\", though preset name " + "\"%3%\" was marked as renamed from \"%2%\" as well.") % + preset.name % renamed_from % it->second; + } + } } std::string PresetCollection::name() const diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index ba9af12c3..b03ce605e 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -770,6 +770,9 @@ private: //BBS: mutex std::mutex m_mutex; + + // Orca: used for validation only + int m_errors = 0; }; // Printer supports the FFF and SLA technologies, with different set of configuration values, diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 8e33202ae..f19afe11d 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -831,17 +831,21 @@ bool PresetBundle::import_json_presets(PresetsConfigSubstitutions & s // Report configuration fields, which are misplaced into a wrong group. const Preset &default_preset = collection->default_preset_for(new_config); std::string incorrect_keys = Preset::remove_invalid_keys(preset.config, default_preset.config); - if (!incorrect_keys.empty()) - BOOST_LOG_TRIVIAL(error) << "Error in a preset file: The preset \"" << preset.file << "\" contains the following incorrect keys: " << incorrect_keys - << ", which were removed"; + if (!incorrect_keys.empty()) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << "Error in a preset file: The preset \"" << preset.file + << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed"; + } if (!config_substitutions.empty()) substitutions.push_back({name, collection->type(), PresetConfigSubstitutions::Source::UserFile, file, std::move(config_substitutions)}); preset.save(inherit_preset ? &inherit_preset->config : nullptr); result.push_back(file); } catch (const std::ifstream::failure &err) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << boost::format("The config cannot be loaded: %1%. Reason: %2%") % file % err.what(); } catch (const std::runtime_error &err) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << boost::format("Failed importing config file: %1%. Reason: %2%") % file % err.what(); } return true; @@ -945,6 +949,7 @@ void PresetBundle::update_system_preset_setting_ids(std::mapfind_preset(name, false, true); if (preset) { if (!preset->setting_id.empty() && (preset->setting_id.compare(setting_id) != 0)) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << boost::format("name %1%, local setting_id %2% is different with remote id %3%") %preset->name %preset->setting_id %setting_id; } @@ -3156,7 +3161,7 @@ std::pair PresetBundle::load_vendor_configs_ std::vector> process_subfiles; std::vector> filament_subfiles; std::vector> machine_subfiles; - auto get_name_and_subpath = [](json::iterator& it, std::vector>& subfile_map) { + auto get_name_and_subpath = [this](json::iterator& it, std::vector>& subfile_map) { if (it.value().is_array()) { for (auto iter1 = it.value().begin(); iter1 != it.value().end(); iter1++) { if (iter1.value().is_object()) { @@ -3170,18 +3175,21 @@ std::pair PresetBundle::load_vendor_configs_ } } else { + ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": invalid value type for " << iter2.key(); } } if (!name.empty() && !subpath.empty()) subfile_map.push_back(std::make_pair(name, subpath)); + } else { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": invalid type for " << iter1.key(); } - else - BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": invalid type for " << iter1.key(); } + } else { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": invalid type for " << it.key(); } - else - BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": invalid type for " << it.key(); }; try { boost::nowide::ifstream ifs(root_file); @@ -3279,6 +3287,7 @@ std::pair PresetBundle::load_vendor_configs_ model.variants.emplace_back(VendorProfile::PrinterVariant(variant_name)); } } else { + ++m_errors; BOOST_LOG_TRIVIAL(error)<< __FUNCTION__ << boost::format(": invalid nozzle_diameters %1% for Vendor %1%") % nozzle_diameters % vendor_name; } } @@ -3313,6 +3322,7 @@ std::pair PresetBundle::load_vendor_configs_ // An empty material was inserted into the list of default materials. Remove it. model.default_materials.erase(model.default_materials.begin()); } else { + ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": invalid default_materials %1% for Vendor %1%") % default_materials_field % vendor_name; } } @@ -3340,9 +3350,8 @@ std::pair PresetBundle::load_vendor_configs_ // 3) paste the process/filament/print configs PresetCollection *presets = nullptr; size_t presets_loaded = 0; - bool _validation_mode = validation_mode; - auto parse_subfile = [path, vendor_name, presets_loaded, current_vendor_profile, _validation_mode]( + auto parse_subfile = [this, path, vendor_name, presets_loaded, current_vendor_profile]( ConfigSubstitutionContext& substitution_context, PresetsConfigSubstitutions& substitutions, LoadConfigBundleAttributes& flags, @@ -3368,6 +3377,7 @@ std::pair PresetBundle::load_vendor_configs_ DynamicPrintConfig config_src; config_src.load_from_json(subfile, substitution_context, false, key_values, reason); if (!reason.empty()) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": load config file "< PresetBundle::load_vendor_configs_ } } else { + ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": can not find inherits "< PresetBundle::load_vendor_configs_ Preset::normalize(config); } catch(nlohmann::detail::parse_error &err) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": parse "<< subfile <<" got a nlohmann::detail::parse_error, reason = " << err.what(); reason = std::string("json parse error") + err.what(); return reason; @@ -3430,15 +3442,18 @@ std::pair PresetBundle::load_vendor_configs_ // Report configuration fields, which are misplaced into a wrong group. std::string incorrect_keys = Preset::remove_invalid_keys(config, *default_config); - if (! incorrect_keys.empty()) - BOOST_LOG_TRIVIAL(error)<< __FUNCTION__ << ": The config " << - subfile << " contains incorrect keys: " << incorrect_keys << ", which were removed"; + if (!incorrect_keys.empty()) { + ++m_errors; + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": The config " << subfile << " contains incorrect keys: " << incorrect_keys + << ", which were removed"; + } if (presets_collection->type() == Preset::TYPE_PRINTER) { // Filter out printer presets, which are not mentioned in the vendor profile. // These presets are considered not installed. auto printer_model = config.opt_string("printer_model"); if (printer_model.empty()) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << preset_name << "\" defines no printer model, it will be ignored."; reason = std::string("can not find printer_model"); @@ -3446,6 +3461,7 @@ std::pair PresetBundle::load_vendor_configs_ } auto printer_variant = config.opt_string("printer_variant"); if (printer_variant.empty()) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << preset_name << "\" defines no printer variant, it will be ignored."; reason = std::string("can not find printer_variant"); @@ -3455,6 +3471,7 @@ std::pair PresetBundle::load_vendor_configs_ [&](const VendorProfile::PrinterModel &m) { return m.id == printer_model; } ); if (it_model == current_vendor_profile->models.end()) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << preset_name << "\" defines invalid printer model \"" << printer_model << "\", it will be ignored."; reason = std::string("can not find printer model in vendor profile"); @@ -3462,6 +3479,7 @@ std::pair PresetBundle::load_vendor_configs_ } auto it_variant = it_model->variant(printer_variant); if (it_variant == nullptr) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << preset_name << "\" defines invalid printer variant \"" << printer_variant << "\", it will be ignored."; reason = std::string("can not find printer_variant in vendor profile"); @@ -3470,6 +3488,7 @@ std::pair PresetBundle::load_vendor_configs_ } const Preset *preset_existing = presets_collection->find_preset(preset_name, false); if (preset_existing != nullptr) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" << preset_name << "\" has already been loaded from another Config Bundle."; reason = std::string("duplicated defines"); @@ -3477,7 +3496,7 @@ std::pair PresetBundle::load_vendor_configs_ } auto file_path = (boost::filesystem::path(data_dir()) /PRESET_SYSTEM_DIR/ vendor_name / subfile_iter.second).make_preferred(); - if(_validation_mode) + if(validation_mode) file_path = (boost::filesystem::path(data_dir()) / vendor_name / subfile_iter.second).make_preferred(); // Load the preset into the list of presets, save it to disk. @@ -3491,6 +3510,7 @@ std::pair PresetBundle::load_vendor_configs_ BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << __LINE__ << loaded.name << " load filament_id: " << filament_id; if (presets_collection->type() == Preset::TYPE_FILAMENT) { if (filament_id.empty() && "Template" != vendor_name) { + ++m_errors; BOOST_LOG_TRIVIAL(error) << __FUNCTION__<< ": can not find filament_id for " << preset_name; //throw ConfigurationError(format("can not find inherits %1% for %2%", inherits, preset_name)); reason = "Can not find filament_id for " + preset_name; @@ -3539,6 +3559,7 @@ std::pair PresetBundle::load_vendor_configs_ { std::string reason = parse_subfile(substitution_context, substitutions, flags, subfile, configs, filament_id_maps, presets, presets_loaded); if (!reason.empty()) { + ++m_errors; //parse error std::string subfile_path = path + "/" + vendor_name + "/" + subfile.second; BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", got error when parse process setting from %1%") % subfile_path; @@ -3554,6 +3575,7 @@ std::pair PresetBundle::load_vendor_configs_ { std::string reason = parse_subfile(substitution_context, substitutions, flags, subfile, configs, filament_id_maps, presets, presets_loaded); if (!reason.empty()) { + ++m_errors; //parse error std::string subfile_path = path + "/" + vendor_name + "/" + subfile.second; BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", got error when parse filament setting from %1%") % subfile_path; @@ -3569,6 +3591,7 @@ std::pair PresetBundle::load_vendor_configs_ { std::string reason = parse_subfile(substitution_context, substitutions, flags, subfile, configs, filament_id_maps, presets, presets_loaded); if (!reason.empty()) { + ++m_errors; //parse error std::string subfile_path = path + "/" + vendor_name + "/" + subfile.second; BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", got error when parse printer setting from %1%") % subfile_path; diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 05e386af0..07b49de4e 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -264,6 +264,14 @@ public: return { Preset::TYPE_PRINTER, Preset::TYPE_SLA_PRINT, Preset::TYPE_SLA_MATERIAL }; } + // Orca: for validation only + bool has_errors() const + { + if (m_errors != 0 || printers.m_errors != 0 || filaments.m_errors != 0 || prints.m_errors != 0) + return true; + return false; + } + private: //std::pair load_system_presets(ForwardCompatibilitySubstitutionRule compatibility_rule); //BBS: add json related logic @@ -288,8 +296,11 @@ private: DynamicPrintConfig full_fff_config() const; DynamicPrintConfig full_sla_config() const; + // Orca: used for validation only bool validation_mode = false; std::string vendor_to_validate = ""; + int m_errors = 0; + }; ENABLE_ENUM_BITMASK_OPERATORS(PresetBundle::LoadConfigBundleAttribute)