Added CLI options to slice using the installed profiles

SPE-2164
This commit is contained in:
YuSanka 2024-02-20 13:13:17 +01:00 committed by Lukas Matena
parent f4f1eb5f9b
commit a46980ca47
5 changed files with 194 additions and 5 deletions

View File

@ -173,6 +173,13 @@ int CLI::run(int argc, char **argv)
m_print_config.apply(config);
}
bool has_config_from_profiles = m_profiles_sharing.empty() &&
(!m_config.opt_string("print-profile").empty() ||
!m_config.option<ConfigOptionStrings>("material-profile")->values.empty() ||
!m_config.opt_string("printer-profile").empty() );
if (has_config_from_profiles && !check_and_load_input_profiles(printer_technology))
return 1;
#ifdef SLIC3R_GUI
#if ENABLE_GL_CORE_PROFILE
std::pair<int, int> opengl_version = { 0, 0 };
@ -264,6 +271,9 @@ int CLI::run(int argc, char **argv)
}
Model model;
try {
if (has_config_from_profiles)
model = Model::read_from_file(file, nullptr, nullptr, Model::LoadAttribute::AddDefaultInstances);
else {
// When loading an AMF or 3MF, config is imported as well, including the printer technology.
DynamicPrintConfig config;
ConfigSubstitutionContext config_substitutions(config_substitution_rule);
@ -285,6 +295,7 @@ int CLI::run(int argc, char **argv)
// config is applied to m_print_config before the current m_config values.
config += std::move(m_print_config);
m_print_config = std::move(config);
}
}
catch (std::exception& e) {
boost::nowide::cerr << file << ": " << e.what() << std::endl;
@ -1048,6 +1059,33 @@ bool CLI::processed_profiles_sharing()
return true;
}
bool CLI::check_and_load_input_profiles(PrinterTechnology& printer_technology)
{
Slic3r::DynamicPrintConfig config = {};
std::string ret = Slic3r::load_full_print_config(m_config.opt_string("print-profile"),
m_config.option<ConfigOptionStrings>("material-profile")->values,
m_config.opt_string("printer-profile"),
config, printer_technology);
if (!ret.empty()) {
boost::nowide::cerr << ret << std::endl;
return false;
}
config.normalize_fdm();
PrinterTechnology other_printer_technology = get_printer_technology(config);
if (printer_technology == ptUnknown)
printer_technology = other_printer_technology;
else if (printer_technology != other_printer_technology && other_printer_technology != ptUnknown) {
boost::nowide::cerr << "Mixing configurations for FFF and SLA technologies" << std::endl;
return false;
}
m_print_config.apply(config);
return true;
}
// __has_feature() is used later for Clang, this is for compatibility with other compilers (such as GCC and MSVC)
#ifndef __has_feature
# define __has_feature(x) 0

View File

@ -42,6 +42,8 @@ private:
bool has_print_action() const { return m_config.opt_bool("export_gcode") || m_config.opt_bool("export_sla"); }
bool processed_profiles_sharing();
bool check_and_load_input_profiles(PrinterTechnology& printer_technology);
std::string output_filepath(const Model &model, IO::ExportFormat format) const;
};

View File

@ -5119,6 +5119,22 @@ CLIMiscConfigDef::CLIMiscConfigDef()
def->tooltip = L("Render with a software renderer. The bundled MESA software renderer is loaded instead of the default OpenGL driver.");
def->min = 0;
#endif /* _MSC_VER */
def = this->add("printer-profile", coString);
def->label = ("Printer preset name");
def->tooltip = ("Name of the printer preset used for slicing.");
def->set_default_value(new ConfigOptionString());
def = this->add("print-profile", coString);
def->label = ("Print preset name");
def->tooltip = ("Name of the print preset used for slicing.");
def->set_default_value(new ConfigOptionString());
def = this->add("material-profile", coStrings);
def->label = ("Material preset name(s)");
def->tooltip = ("Name(s) of the material preset(s) used for slicing.\n"
"Could be filaments or sla_material preset name(s) depending on printer tochnology");
def->set_default_value(new ConfigOptionStrings());
}
CLIProfilesSharingConfigDef::CLIProfilesSharingConfigDef()
@ -5151,11 +5167,6 @@ CLIProfilesSharingConfigDef::CLIProfilesSharingConfigDef()
"Note:\n"
"To print out JSON into file use 'output' option.\n"
"To specify configuration folder use 'datadir' option.");
def = this->add("printer-profile", coString);
def->label = ("Printer preset name");
def->tooltip = ("Name of the printer preset used for slicing.");
def->set_default_value(new ConfigOptionString());
}
const CLIActionsConfigDef cli_actions_config_def;

View File

@ -391,4 +391,133 @@ bool load_full_print_config(const std::string& print_preset_name, const std::str
return !is_failed;
}
// Helper function for load full config from installed presets by profile names
std::string load_full_print_config(const std::string& print_preset_name,
const std::vector<std::string>& material_preset_names_in,
const std::string& printer_preset_name,
DynamicPrintConfig& config,
PrinterTechnology printer_technology)
{
// check entered profile names
if (print_preset_name.empty() ||
material_preset_names_in.empty() ||
printer_preset_name.empty())
return "Request is not completed. All of Print/Material/Printer profiles have to be entered";
// check preset bundle
PresetBundle preset_bundle;
if (!load_preset_bundle_from_datadir(preset_bundle))
return Slic3r::format("Failed to load data from the datadir '%1%'.", data_dir());
// check existance of required profiles
std::string errors;
const Preset* printer_preset = preset_bundle.printers.find_preset(printer_preset_name);
if (!printer_preset)
errors += "\n" + Slic3r::format("Printer profile '%1%' wasn't found.", printer_preset_name);
else if (printer_technology == ptUnknown)
printer_technology = printer_preset->printer_technology();
else if (printer_technology != printer_preset->printer_technology())
errors += "\n" + std::string("Printer technology of the selected printer preset is differs with required printer technology");
PresetCollection& print_presets = printer_technology == ptFFF ? preset_bundle.prints : preset_bundle.sla_prints;
const Preset* print_preset = print_presets.find_preset(print_preset_name);
if (!print_preset)
errors += "\n" + Slic3r::format("Print profile '%1%' wasn't found.", print_preset_name);
PresetCollection& material_presets = printer_technology == ptFFF ? preset_bundle.filaments : preset_bundle.sla_materials;
auto check_material = [&material_presets] (const std::string& name, std::string& errors) -> void {
const Preset* material_preset = material_presets.find_preset(name);
if (!material_preset)
errors += "\n" + Slic3r::format("Material profile '%1%' wasn't found.", name);
};
check_material(material_preset_names_in.front(), errors);
if (material_preset_names_in.size() > 1) {
for (int idx = 1; idx < material_preset_names_in.size(); idx++) {
if (material_preset_names_in[idx] != material_preset_names_in.front())
check_material(material_preset_names_in[idx], errors);
}
}
if (!errors.empty())
return errors;
// check and update list of material presets
std::vector<std::string> material_preset_names = material_preset_names_in;
if (printer_technology == ptSLA && material_preset_names.size() > 1) {
BOOST_LOG_TRIVIAL(warning) << "Note: More than one sla material profiles were entered. Extras material profiles will be ignored.";
material_preset_names.resize(1);
}
if (printer_technology == ptFFF) {
const int extruders_count = static_cast<const ConfigOptionFloats*>(printer_preset->config.option("nozzle_diameter"))->values.size();
if (extruders_count > material_preset_names.size()) {
BOOST_LOG_TRIVIAL(warning) << "Note: Less than needed filament profiles were entered. Missed filament profiles will be filled with first material.";
material_preset_names.reserve(extruders_count);
for (int i = extruders_count - material_preset_names.size(); i > 0; i--)
material_preset_names.push_back(material_preset_names.front());
}
else if (extruders_count < material_preset_names.size()) {
BOOST_LOG_TRIVIAL(warning) << "Note: More than needed filament profiles were entered. Extras filament profiles will be ignored.";
material_preset_names.resize(extruders_count);
}
}
// check profiles compatibility
const PresetWithVendorProfile printer_preset_with_vendor_profile = preset_bundle.printers.get_preset_with_vendor_profile(*printer_preset);
const PresetWithVendorProfile print_preset_with_vendor_profile = print_presets.get_preset_with_vendor_profile(*print_preset);
if (!is_compatible_with_printer(print_preset_with_vendor_profile, printer_preset_with_vendor_profile))
errors += "\n" + Slic3r::format("Print profile '%1%' is not compatible with printer profile %2%.", print_preset_name, printer_preset_name);
auto check_material_preset_compatibility = [&material_presets, printer_preset_name, print_preset_name, printer_preset_with_vendor_profile, print_preset_with_vendor_profile]
(const std::string& name, std::string& errors) -> void {
const Preset* material_preset = material_presets.find_preset(name);
const PresetWithVendorProfile material_preset_with_vendor_profile = material_presets.get_preset_with_vendor_profile(*material_preset);
if (!is_compatible_with_printer(material_preset_with_vendor_profile, printer_preset_with_vendor_profile))
errors += "\n" + Slic3r::format("Material profile '%1%' is not compatible with printer profile %2%.", name, printer_preset_name);
if (!is_compatible_with_print(material_preset_with_vendor_profile, print_preset_with_vendor_profile, printer_preset_with_vendor_profile))
errors += "\n" + Slic3r::format("Material profile '%1%' is not compatible with print profile %2%.", name, print_preset_name);
};
check_material_preset_compatibility(material_preset_names.front(), errors);
if (material_preset_names.size() > 1) {
for (int idx = 1; idx < material_preset_names.size(); idx++) {
if (material_preset_names[idx] != material_preset_names.front())
check_material_preset_compatibility(material_preset_names[idx], errors);
}
}
if (!errors.empty())
return errors;
// get full print configuration
preset_bundle.printers.select_preset_by_name(printer_preset_name, true);
print_presets.select_preset_by_name(print_preset_name, true);
if (printer_technology == ptSLA)
material_presets.select_preset_by_name(material_preset_names.front(), true);
else if (printer_technology == ptFFF) {
auto& extruders_filaments = preset_bundle.extruders_filaments;
extruders_filaments.clear();
for (size_t i = 0; i < material_preset_names.size(); ++i)
extruders_filaments.emplace_back(ExtruderFilaments(&preset_bundle.filaments, i, material_preset_names[i]));
}
config = preset_bundle.full_config();
return "";
}
} // namespace Slic3r

View File

@ -19,6 +19,15 @@ std::string GetDataDir();
class DynamicPrintConfig;
bool load_full_print_config(const std::string& print_preset, const std::string& filament_preset, const std::string& printer_preset, DynamicPrintConfig& out_config);
// Load full print config into config
// Return error/warning string if any exists
std::string load_full_print_config( const std::string& print_preset_name,
const std::vector<std::string>& material_preset_names,
const std::string& printer_preset_name,
DynamicPrintConfig& config,
PrinterTechnology printer_technology);
} // namespace Slic3r
#endif // slic3r_ProfilesSharingUtils_hpp_