diff --git a/CMakeLists.txt b/CMakeLists.txt index 190e9e0bd..4f75c16f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ endif () # Proposal for C++ unit tests and sandboxes option(SLIC3R_BUILD_SANDBOXES "Build development sandboxes" OFF) option(SLIC3R_BUILD_TESTS "Build unit tests" OFF) +option(ORCA_TOOLS "Build Orca tools" OFF) if (IS_CROSS_COMPILE) message("Detected cross compilation setup. Tests and encoding checks will be forcedly disabled!") @@ -378,7 +379,7 @@ endif() # boost::process was introduced first in version 1.64.0, # boost::beast::detail::base64 was introduced first in version 1.66.0 set(MINIMUM_BOOST_VERSION "1.66.0") -set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time;iostreams") +set(_boost_components "system;filesystem;thread;log;locale;regex;chrono;atomic;date_time;iostreams;program_options") find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components}) add_library(boost_libs INTERFACE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c8e63107a..cc7f331fa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -102,6 +102,15 @@ if (SLIC3R_GUI) add_subdirectory(slic3r) endif() +if(ORCA_TOOLS) + # OrcaSlicer_profile_validator + add_executable(OrcaSlicer_profile_validator OrcaSlicer_profile_validator.cpp) + target_link_libraries(OrcaSlicer_profile_validator libslic3r boost_headeronly libcurl OpenSSL::SSL OpenSSL::Crypto) + target_compile_definitions(OrcaSlicer_profile_validator PRIVATE -DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x602 -DBOOST_SYSTEM_USE_UTF8) + if(WIN32) + target_link_libraries(OrcaSlicer_profile_validator bcrypt.lib) + endif() +endif() # Create a slic3r executable # Process mainfests for various platforms. diff --git a/src/OrcaSlicer_profile_validator.cpp b/src/OrcaSlicer_profile_validator.cpp new file mode 100644 index 000000000..f94b7bec8 --- /dev/null +++ b/src/OrcaSlicer_profile_validator.cpp @@ -0,0 +1,71 @@ +#include "libslic3r/PresetBundle.hpp" +#include "libslic3r/Utils.hpp" +#include +#include +#include +#include + +using namespace Slic3r; +namespace po = boost::program_options; + +int main(int argc, char* argv[]) +{ + po::options_description desc("Allowed options"); + 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."); + + po::variables_map vm; + try { + po::store(po::parse_command_line(argc, argv, desc), vm); + + if (vm.count("help")) { + std::cout << desc << "\n"; + return 1; + } + + po::notify(vm); + } catch (const po::error& e) { + std::cerr << "Error: " << e.what() << "\n"; + std::cerr << desc << "\n"; + return 1; + } + + std::string path = vm["path"].as(); + std::string vendor = vm["vendor"].as(); + int log_level = vm["log_level"].as(); + + // check if path is valid, and return error if not + if (!fs::exists(path) || !fs::is_directory(path)) { + std::cerr << "Error: " << path << " is not a valid directory\n"; + return 1; + } + + + // std::cout<<"path: "<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; + + try { + auto preset_substitutions = preset_bundle->load_presets(app_config, ForwardCompatibilitySubstitutionRule::EnableSystemSilent); + } catch (const std::exception& ex) { + BOOST_LOG_TRIVIAL(error) << ex.what(); + std::cout << "Validation failed" << std::endl; + return 1; + } + std::cout << "Validation completed successfully" << std::endl; + return 0; +} diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 464fd2b91..8e33202ae 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -1211,6 +1211,9 @@ std::pair PresetBundle::load_system_pre // Here the vendor specific read only Config Bundles are stored. //BBS: change directory by design boost::filesystem::path dir = (boost::filesystem::path(data_dir()) / PRESET_SYSTEM_DIR).make_preferred(); + if (validation_mode) + dir = (boost::filesystem::path(data_dir())).make_preferred(); + PresetsConfigSubstitutions substitutions; std::string errors_cummulative; bool first = true; @@ -1221,6 +1224,10 @@ std::pair PresetBundle::load_system_pre std::string vendor_name = dir_entry.path().filename().string(); // Remove the .json suffix. vendor_name.erase(vendor_name.size() - 5); + + if (validation_mode && !vendor_to_validate.empty() && vendor_name != vendor_to_validate) + continue; + try { // Load the config bundle, flatten it. if (first) { @@ -1243,8 +1250,12 @@ std::pair PresetBundle::load_system_pre } } } catch (const std::runtime_error &err) { - errors_cummulative += err.what(); - errors_cummulative += "\n"; + if (validation_mode) + throw err; + else { + errors_cummulative += err.what(); + errors_cummulative += "\n"; + } } } } @@ -3329,8 +3340,9 @@ 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](\ + auto parse_subfile = [path, vendor_name, presets_loaded, current_vendor_profile, _validation_mode]( ConfigSubstitutionContext& substitution_context, PresetsConfigSubstitutions& substitutions, LoadConfigBundleAttributes& flags, @@ -3465,6 +3477,9 @@ 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) + 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. Preset &loaded = presets_collection->load_preset(file_path.string(), preset_name, std::move(config), false); if (flags.has(LoadConfigBundleAttribute::LoadSystem)) { diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index f9167cb4c..05e386af0 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -121,6 +121,9 @@ public: void update_selections(AppConfig &config); void set_calibrate_printer(std::string name); + void set_is_validation_mode(bool mode) { validation_mode = mode; } + void set_vendor_to_validate(std::string vendor) { vendor_to_validate = vendor; } + PresetCollection prints; PresetCollection sla_prints; PresetCollection filaments; @@ -284,6 +287,9 @@ private: DynamicPrintConfig full_fff_config() const; DynamicPrintConfig full_sla_config() const; + + bool validation_mode = false; + std::string vendor_to_validate = ""; }; ENABLE_ENUM_BITMASK_OPERATORS(PresetBundle::LoadConfigBundleAttribute)