OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
OrcaSlicer_profile_validator.cpp File Reference
#include "nanosvg/nanosvg.h"
#include "nanosvg/nanosvgrast.h"
#include <vector>
#include <boost/filesystem/path.hpp>
#include <map>
#include "libslic3r/Point.hpp"
#include "libslic3r/libslic3r.h"
#include "libslic3r/Polygon.hpp"
#include "libslic3r/PrintConfig.hpp"
#include <utility>
#include "libslic3r/CustomGCode.hpp"
#include <iterator>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/log/core/record_view.hpp>
#include <boost/log/expressions/message.hpp>
#include <cstddef>
#include <exception>
#include "libslic3r/PlaceholderParser.hpp"
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/value_semantic.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/errors.hpp>
#include "libslic3r/BoundingBox.hpp"
#include "libslic3r/GCode.hpp"
#include "libslic3r/GCode/WipeTower.hpp"
#include "libslic3r/GCode/WipeTowerEstimate.hpp"
#include "libslic3r/Geometry.hpp"
#include "libslic3r/Preset.hpp"
#include "libslic3r/Config.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Utils.hpp"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/make_shared.hpp>
#include <boost/program_options.hpp>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <set>
#include <string>
#include "libslic3r/AppConfig.hpp"
#include "libslic3r/Format/STEP.hpp"

Go to the source code of this file.

Namespaces

namespace  anonymous_namespace{OrcaSlicer_profile_validator.cpp}

Macros

#define NANOSVG_IMPLEMENTATION
#define NANOSVGRAST_IMPLEMENTATION

Typedefs

using anonymous_namespace{OrcaSlicer_profile_validator.cpp}::Templates = std::set<std::pair<std::string, std::string>>

Functions

void generate_custom_presets (PresetBundle *preset_bundle, AppConfig &app_config)
Vec2d anonymous_namespace{OrcaSlicer_profile_validator.cpp}::printable_area_center (const DynamicPrintConfig &cfg)
Vec2d anonymous_namespace{OrcaSlicer_profile_validator.cpp}::place_wipe_tower (DynamicPrintConfig &cfg, const Vec2d &center)
std::string anonymous_namespace{OrcaSlicer_profile_validator.cpp}::slice_two_color_cube_and_export (DynamicPrintConfig cfg, bool is_bbl, bool by_object)
void anonymous_namespace{OrcaSlicer_profile_validator.cpp}::select_printer_default_presets (PresetBundle &bundle)
void anonymous_namespace{OrcaSlicer_profile_validator.cpp}::install_slice_context_log_sink ()
DynamicPrintConfig anonymous_namespace{OrcaSlicer_profile_validator.cpp}::slice_config (PresetBundle &bundle)
std::string anonymous_namespace{OrcaSlicer_profile_validator.cpp}::slice_selection (PresetBundle &bundle, const std::string &what, bool by_object, const std::string &outdir, const std::string &file_base)
Templates anonymous_namespace{OrcaSlicer_profile_validator.cpp}::preset_templates (const DynamicPrintConfig &cfg)
int anonymous_namespace{OrcaSlicer_profile_validator.cpp}::slice_all_printers (const std::string &vendor, const std::string &outdir)
int main (int argc, char *argv[])

Variables

static std::string anonymous_namespace{OrcaSlicer_profile_validator.cpp}::g_slice_context

Macro Definition Documentation

◆ NANOSVG_IMPLEMENTATION

#define NANOSVG_IMPLEMENTATION

◆ NANOSVGRAST_IMPLEMENTATION

#define NANOSVGRAST_IMPLEMENTATION

Function Documentation

◆ generate_custom_presets()

void generate_custom_presets ( PresetBundle * preset_bundle,
AppConfig & app_config )
69{
70 struct cus_preset
71 {
72 std::string name;
73 std::string parent_name;
74 };
75 // create user presets
76 auto createCustomPrinters = [&](Preset::Type type) {
77 std::vector<cus_preset> custom_preset;
78 PresetCollection* collection = nullptr;
79 if (type == Preset::TYPE_PRINT)
80 collection = &preset_bundle->prints;
81 else if (type == Preset::TYPE_FILAMENT)
82 collection = &preset_bundle->filaments;
83 else if (type == Preset::TYPE_PRINTER)
84 collection = &preset_bundle->printers;
85 else
86 return;
87 custom_preset.reserve(collection->size());
88 for (auto& parent : collection->get_presets()) {
89 if (!parent.is_system)
90 continue;
91 auto new_name = parent.name + "_orca_test";
92 if (parent.vendor)
93 new_name = parent.vendor->name + "_" + new_name;
94 custom_preset.push_back({new_name, parent.name});
95 }
96 for (auto p : custom_preset) {
97 // Creating a new preset.
98 auto parent = collection->find_preset(p.parent_name);
99 auto vendor = collection->get_preset_with_vendor_profile(*parent);
100 if (type == Preset::TYPE_FILAMENT) {
101 parent->config.set_key_value("filament_start_gcode",
102 new ConfigOptionStrings({"this_is_orca_test_filament_start_gcode_mock"}));
103 parent->config.set_key_value("filament_notes", new ConfigOptionString(vendor.vendor->name));
104 } else if (type == Preset::TYPE_PRINT) {
105 parent->config.set_key_value("filename_format", new ConfigOptionString("this_is_orca_test_filename_format_mock"));
106 parent->config.set_key_value("notes", new ConfigOptionString(vendor.vendor->name));
107 } else if (type == Preset::TYPE_PRINTER) {
108 parent->config.set_key_value("machine_start_gcode", new ConfigOptionString("this_is_orca_test_machine_start_gcode_mock"));
109 parent->config.set_key_value("printer_notes", new ConfigOptionString(vendor.vendor->name));
110 }
111
112 collection->save_current_preset(p.name, false, false, parent);
113
114 }
115 };
116 createCustomPrinters(Preset::TYPE_PRINTER);
117 createCustomPrinters(Preset::TYPE_FILAMENT);
118 createCustomPrinters(Preset::TYPE_PRINT);
119
120 std::string user_sub_folder = DEFAULT_USER_FOLDER_NAME;
121 const std::string dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/" + user_sub_folder;
122
123 fs::path user_folder(data_dir() + "/" + PRESET_USER_DIR);
124 if (!fs::exists(user_folder))
125 fs::create_directory(user_folder);
126
127 fs::path folder(dir_user_presets);
128 if (!fs::exists(folder))
129 fs::create_directory(folder);
130 std::map<std::string, std::string> need_to_delete_list; // store setting ids of preset
131
132 preset_bundle->prints.save_user_presets(dir_user_presets, PRESET_PRINT_NAME, need_to_delete_list);
133 preset_bundle->filaments.save_user_presets(dir_user_presets, PRESET_FILAMENT_NAME, need_to_delete_list);
134 preset_bundle->printers.save_user_presets(dir_user_presets, PRESET_PRINTER_NAME, need_to_delete_list);
135
136 std::cout << "Custom presets generated successfully" << std::endl;
137}
#define DEFAULT_USER_FOLDER_NAME
Definition PresetBundle.hpp:31
#define PRESET_USER_DIR
Definition Preset.hpp:32
#define PRESET_PRINTER_NAME
Definition Preset.hpp:35
#define PRESET_PRINT_NAME
Definition Preset.hpp:34
#define PRESET_FILAMENT_NAME
Definition Preset.hpp:33
Definition Config.hpp:1190
PrinterPresetCollection printers
Definition PresetBundle.hpp:503
PresetCollection prints
Definition PresetBundle.hpp:497
PresetCollection filaments
Definition PresetBundle.hpp:499
Definition Preset.hpp:570
size_t size() const
Definition Preset.hpp:865
const std::deque< Preset > & get_presets() const
Definition Preset.hpp:781
PresetWithVendorProfile get_preset_with_vendor_profile(const Preset &preset) const
Definition Preset.cpp:3705
void save_user_presets(const std::string &dir_path, const std::string &type, std::map< std::string, std::string > &need_to_delete_list)
Definition Preset.cpp:2465
void save_current_preset(const std::string &new_name, bool detach=false, bool save_to_project=false, Preset *_curr_preset=nullptr)
Definition Preset.cpp:3348
Preset * find_preset(const std::string &name, bool first_visible_if_not_found=false, bool real=false, bool only_from_library=false)
Definition Preset.cpp:3772
Type
Definition Preset.hpp:244
@ TYPE_PRINTER
Definition Preset.hpp:250
@ TYPE_PRINT
Definition Preset.hpp:246
@ TYPE_FILAMENT
Definition Preset.hpp:248
const std::string & data_dir()
Definition utils.cpp:365
zaa_minimize_perimeter_height ConfigOptionString
Definition PrintConfig.hpp:1702

References Slic3r::ConfigOptionString, Slic3r::data_dir(), DEFAULT_USER_FOLDER_NAME, Slic3r::PresetBundle::filaments, Slic3r::PresetCollection::find_preset(), Slic3r::PresetCollection::get_preset_with_vendor_profile(), Slic3r::PresetCollection::get_presets(), PRESET_FILAMENT_NAME, PRESET_PRINT_NAME, PRESET_PRINTER_NAME, PRESET_USER_DIR, Slic3r::PresetBundle::printers, Slic3r::PresetBundle::prints, Slic3r::PresetCollection::save_current_preset(), Slic3r::PresetCollection::save_user_presets(), Slic3r::PresetCollection::size(), Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, and Slic3r::Preset::TYPE_PRINTER.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int argc,
char * argv[] )
654{
655 po::options_description desc("Orca Profile Validator\nUsage");
656 // clang-format off
657 desc.add_options()("help,h", "help")
658#ifdef __APPLE__
659 ("path,p", po::value<std::string>()->default_value("../../../../../../../resources/profiles"), "profile folder")
660#else
661 ("path,p", po::value<std::string>()->default_value("../../../resources/profiles"), "profile folder")
662#endif
663 ("vendor,v", po::value<std::string>()->default_value(""), "Vendor name. Optional, all profiles present in the folder will be validated if not specified")
664 ("generate_presets,g", po::value<bool>()->default_value(false), "Generate user presets for mock test")
665 ("slice,s", po::bool_switch()->default_value(false), "Slice a two-colour cube through every printer, and through every other system process and filament preset whose templates no printer's own slice expands, so every custom g-code and filename_format shipped is expanded, names in {if} branches not taken included (catches placeholder/flow errors that static checks miss). Off unless this flag is present.")
666 ("outdir,o", po::value<std::string>()->default_value(""), "With -s, also save each slice's g-code to this folder (as <vendor>__<printer>[__<preset>].gcode) for manual inspection. Optional.")
667 ("check_filament_subtypes,f", po::bool_switch()->default_value(true), "Also flag printers with duplicate (ambiguous) filament subtypes. Off unless this flag is present.")
668 ("log_level,l", po::value<int>()->default_value(2), "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs.");
669 // clang-format on
670
671 po::variables_map vm;
672 try {
673 po::store(po::parse_command_line(argc, argv, desc), vm);
674
675 if (vm.count("help")) {
676 std::cout << desc << "\n";
677 return 1;
678 }
679
680 po::notify(vm);
681 } catch (const po::error& e) {
682 std::cerr << "Error: " << e.what() << "\n";
683 std::cerr << desc << "\n";
684 return 1;
685 }
686
687 std::string path = vm["path"].as<std::string>();
688 std::string vendor = vm["vendor"].as<std::string>();
689 int log_level = vm["log_level"].as<int>();
690 bool generate_user_preset = vm["generate_presets"].as<bool>();
691 bool slice_mode = vm["slice"].as<bool>();
692 std::string slice_outdir = vm["outdir"].as<std::string>();
693 bool check_filament_subtypes = vm["check_filament_subtypes"].as<bool>();
694
695 // check if path is valid, and return error if not
696 if (!fs::exists(path) || !fs::is_directory(path)) {
697 std::cerr << "Error: " << path << " is not a valid directory\n";
698 return 1;
699 }
700
701 // std::cout<<"path: "<<path<<std::endl;
702 // std::cout<<"vendor: "<<vendor<<std::endl;
703 // std::cout<<"log_level: "<<log_level<<std::endl;
704
705 set_data_dir(path);
706 // Orca: the profiles folder lives at <resources>/profiles, so point resources_dir() at that
707 // <resources> parent. Without this, resources_dir() is empty and slice mode's HRC lookup
708 // (info/nozzle_info.json) resolves to a non-existent relative path and falls back to a
709 // built-in table (logging a spurious parse error and dropping the E3D entry).
710 if (fs::exists(fs::path(path).parent_path() / "info"))
711 set_resources_dir(fs::path(path).parent_path().string());
712
713 auto user_dir = fs::path(Slic3r::data_dir()) / PRESET_USER_DIR;
714 user_dir.make_preferred();
715 if (!fs::exists(user_dir))
716 fs::create_directory(user_dir);
717
718 set_logging_level(log_level);
719
720 // Slice mode expands every printer's custom g-code by actually slicing (see slice_all_printers).
721 // A distinct opt-in mode so the default static checks stay fast for every profile PR.
722 if (slice_mode)
723 return slice_all_printers(vendor, slice_outdir);
724
725 auto preset_bundle = new PresetBundle();
726 // preset_bundle->setup_directories();
727 preset_bundle->set_is_validation_mode(true);
728 preset_bundle->set_vendor_to_validate(vendor);
729
730 preset_bundle->set_default_suppressed(true);
731 AppConfig app_config;
732 app_config.set("preset_folder", "default");
733
734 if(generate_user_preset)
735 preset_bundle->remove_user_presets_directory("default");
736
737 try {
738 auto preset_substitutions = preset_bundle->load_presets(app_config, ForwardCompatibilitySubstitutionRule::Disable);
739 } catch (const std::exception& ex) {
740 BOOST_LOG_TRIVIAL(error) << ex.what();
741 std::cout << "Validation failed" << std::endl;
742 return 1;
743 }
744 // Report loaded presets
745 std::cout << "Total loaded vendors: " << preset_bundle->vendors.size() << std::endl;
746
747 if (generate_user_preset) {
748 generate_custom_presets(preset_bundle, app_config);
749 return 0;
750 }
751
752 if (preset_bundle->has_errors(check_filament_subtypes)) {
753 std::cout << "Validation failed" << std::endl;
754 return 1;
755 }
756
757 std::cout << "Validation completed successfully" << std::endl;
758 return 0;
759}
void generate_custom_presets(PresetBundle *preset_bundle, AppConfig &app_config)
Definition OrcaSlicer_profile_validator.cpp:68
Definition AppConfig.hpp:100
void set(const std::string &section, const std::string &key, const std::string &value)
Definition AppConfig.hpp:167
Definition PresetBundle.hpp:210
void set_data_dir(const std::string &dir)
Definition utils.cpp:353
void set_logging_level(unsigned int level)
Definition utils.cpp:171
void set_resources_dir(const std::string &dir)
Definition utils.cpp:291
int slice_all_printers(const std::string &vendor, const std::string &outdir)
Definition OrcaSlicer_profile_validator.cpp:449

References Slic3r::data_dir(), Slic3r::Disable, generate_custom_presets(), PRESET_USER_DIR, Slic3r::AppConfig::set(), Slic3r::set_data_dir(), Slic3r::set_logging_level(), Slic3r::set_resources_dir(), and anonymous_namespace{OrcaSlicer_profile_validator.cpp}::slice_all_printers().

Here is the call graph for this function: