From fe7105ff3264be48d380a255081e6819bae6e6c2 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Mon, 5 Apr 2021 00:03:59 -0500 Subject: Initial cut to add an OutputFormat enumeration for SLA printing. --- resources/ui_layout/printer_sla.ui | 2 + src/PrusaSlicer.cpp | 9 ++- src/libslic3r/CMakeLists.txt | 4 + src/libslic3r/Config.hpp | 25 ++++++ src/libslic3r/Format/CWS.cpp | 135 ++++++++++++++++++++++++++++++++ src/libslic3r/Format/CWS.hpp | 19 +++++ src/libslic3r/Preset.cpp | 1 + src/libslic3r/PrintConfig.cpp | 22 ++++++ src/libslic3r/PrintConfig.hpp | 14 ++++ src/libslic3r/SLAPrint.cpp | 7 ++ src/libslic3r/SLAPrint.hpp | 2 + src/slic3r/GUI/Field.cpp | 4 + src/slic3r/GUI/OptionsGroup.cpp | 2 + src/slic3r/GUI/UnsavedChangesDialog.cpp | 2 + 14 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 src/libslic3r/Format/CWS.cpp create mode 100644 src/libslic3r/Format/CWS.hpp diff --git a/resources/ui_layout/printer_sla.ui b/resources/ui_layout/printer_sla.ui index efb9799f7..26337655c 100644 --- a/resources/ui_layout/printer_sla.ui +++ b/resources/ui_layout/printer_sla.ui @@ -1,5 +1,7 @@ page:General:printer +group:Output Method + setting:output_format group:Size and coordinates bed_shape setting:max_print_height diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 19f2b5592..9f0cda32b 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -37,9 +37,11 @@ #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Format/AMF.hpp" #include "libslic3r/Format/3mf.hpp" +#include "libslic3r/Format/Format.hpp" #include "libslic3r/Format/STL.hpp" #include "libslic3r/Format/OBJ.hpp" #include "libslic3r/Format/SL1.hpp" +#include "libslic3r/Format/CWS.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/Thread.hpp" @@ -445,8 +447,9 @@ int CLI::run(int argc, char **argv) std::string outfile = m_config.opt_string("output"); Print fff_print; SLAPrint sla_print; - SL1Archive sla_archive(sla_print.printer_config()); - sla_print.set_printer(&sla_archive); + std::shared_ptr sla_archive = Slic3r::get_output_format(m_print_config); + + sla_print.set_printer(sla_archive); sla_print.set_status_callback( [](const PrintBase::SlicingStatus& s) { @@ -504,7 +507,7 @@ int CLI::run(int argc, char **argv) outfile = sla_print.output_filepath(outfile); // We need to finalize the filename beforehand because the export function sets the filename inside the zip metadata outfile_final = sla_print.print_statistics().finalize_output_path(outfile); - sla_archive.export_print(outfile_final, sla_print); + sla_archive->export_print(outfile_final, sla_print); } if (outfile != outfile_final) { if (Slic3r::rename_file(outfile, outfile_final)) { diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 4c5f67b3c..45d9cfa8a 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -67,6 +67,8 @@ add_library(libslic3r STATIC Flow.cpp Flow.hpp format.hpp + Format/Format.hpp + Format/Format.cpp Format/3mf.cpp Format/3mf.hpp Format/AMF.cpp @@ -81,6 +83,8 @@ add_library(libslic3r STATIC Format/STL.hpp Format/SL1.hpp Format/SL1.cpp + Format/CWS.hpp + Format/CWS.cpp GCode/ThumbnailData.cpp GCode/ThumbnailData.hpp GCode/CoolingBuffer.cpp diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index e9735fd19..52c057c76 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -186,6 +186,31 @@ inline PrinterTechnology operator&=(PrinterTechnology& a, PrinterTechnology b) { a = a & b; return a; } +/// +enum OutputFormat : uint16_t +{ + ofMaskedCWS = 1 << 0, + ofSL1 = 1 << 1, + ofGCode = 1 << 2, + ofUnknown = 1 << 15 +}; + +inline OutputFormat operator|(OutputFormat a, OutputFormat b) { + return static_cast(static_cast(a) | static_cast(b)); +} +inline OutputFormat operator&(OutputFormat a, OutputFormat b) { + return static_cast(static_cast(a)& static_cast(b)); +} +inline OutputFormat operator|=(OutputFormat& a, OutputFormat b) { + a = a | b; return a; +} +inline OutputFormat operator&=(OutputFormat& a, OutputFormat b) { + a = a & b; return a; +} + + + + // A generic value of a configuration option. class ConfigOption { public: diff --git a/src/libslic3r/Format/CWS.cpp b/src/libslic3r/Format/CWS.cpp new file mode 100644 index 000000000..c04581d79 --- /dev/null +++ b/src/libslic3r/Format/CWS.cpp @@ -0,0 +1,135 @@ +#include "libslic3r/Format/CWS.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/Time.hpp" + +namespace Slic3r { + +using ConfMap = std::map; +using namespace std::string_literals; + +namespace { + +std::string to_ini(const ConfMap &m) +{ + std::string ret; + for (auto ¶m : m) ret += param.first + " = " + param.second + "\n"; + // this format, at least for the Malyan M100, seems to want this in the config. + auto _t = m.find("layerHeight"s); + if (_t != m.cend()) + ret += "" + _t->second + "< / SliceHeight>"; + + return ret; +} + +std::string get_cfg_value(const DynamicPrintConfig &cfg, const std::string &key) +{ + std::string ret; + + if (cfg.has(key)) { + auto opt = cfg.option(key); + if (opt) ret = opt->serialize(); + } + + return ret; +} + +void fill_iniconf(ConfMap &m, const SLAPrint &print) +{ + auto &cfg = print.full_print_config(); + m["layerHeight"] = get_cfg_value(cfg, "layer_height"); + m["expTime"] = get_cfg_value(cfg, "exposure_time"); + m["expTimeFirst"] = get_cfg_value(cfg, "initial_exposure_time"); + m["materialName"] = get_cfg_value(cfg, "sla_material_settings_id"); + m["printerModel"] = get_cfg_value(cfg, "printer_model"); + m["printerVariant"] = get_cfg_value(cfg, "printer_variant"); + m["printerProfile"] = get_cfg_value(cfg, "printer_settings_id"); + m["printProfile"] = get_cfg_value(cfg, "sla_print_settings_id"); + m["fileCreationTimestamp"] = Utils::utc_timestamp(); + m["prusaSlicerVersion"] = SLIC3R_BUILD_ID; + + SLAPrintStatistics stats = print.print_statistics(); + // Set statistics values to the printer + + double used_material = (stats.objects_used_material + + stats.support_used_material) / 1000; + + int num_fade = print.default_object_config().faded_layers.getInt(); + num_fade = num_fade >= 0 ? num_fade : 0; + + m["usedMaterial"] = std::to_string(used_material); + m["numFade"] = std::to_string(num_fade); + m["numSlow"] = std::to_string(stats.slow_layers_count); + m["numFast"] = std::to_string(stats.fast_layers_count); + m["printTime"] = std::to_string(stats.estimated_print_time); + + m["action"] = "print"; +} + +void fill_slicerconf(ConfMap &m, const SLAPrint &print) +{ + using namespace std::literals::string_view_literals; + + // Sorted list of config keys, which shall not be stored into the ini. + static constexpr auto banned_keys = { + "compatible_printers"sv, + "compatible_prints"sv, + //FIXME The print host keys should not be exported to full_print_config anymore. The following keys may likely be removed. + "print_host"sv, + "printhost_apikey"sv, + "printhost_cafile"sv + }; + + assert(std::is_sorted(banned_keys.begin(), banned_keys.end())); + auto is_banned = [](const std::string &key) { + return std::binary_search(banned_keys.begin(), banned_keys.end(), key); + }; + + auto &cfg = print.full_print_config(); + for (const std::string &key : cfg.keys()) + if (! is_banned(key) && ! cfg.option(key)->is_nil()) + m[key] = cfg.opt_serialize(key); + +} + +} // namespace + + +void MaskedCWSArchive::export_print(Zipper& zipper, + const SLAPrint &print, + const std::string &prjname) +{ + std::string project = + prjname.empty() ? + boost::filesystem::path(zipper.get_filename()).stem().string() : + prjname; + std::cerr << "Calling from MaskedCWSArchive\n" ; + + ConfMap iniconf, slicerconf; + fill_iniconf(iniconf, print); + + iniconf["jobDir"] = project; + + fill_slicerconf(slicerconf, print); + + try { + zipper.add_entry("default.slicing"); + zipper << to_ini(iniconf); + + zipper.add_entry("prusaslicer.ini"); + zipper << to_ini(slicerconf); + + size_t i = 0; + for (const sla::EncodedRaster &rst : m_layers) { + + std::string imgname = project + string_printf("%.5d", i++) + "." + + rst.extension(); + + zipper.add_entry(imgname.c_str(), rst.data(), rst.size()); + } + } catch(std::exception& e) { + BOOST_LOG_TRIVIAL(error) << e.what(); + // Rethrow the exception + throw; + } +} +} // namespace Slic3r diff --git a/src/libslic3r/Format/CWS.hpp b/src/libslic3r/Format/CWS.hpp new file mode 100644 index 000000000..e4d92882e --- /dev/null +++ b/src/libslic3r/Format/CWS.hpp @@ -0,0 +1,19 @@ +#ifndef slic3r_format_CWS_HPP +#define slic3r_format_CWS_HPP + +#include "libslic3r/Zipper.hpp" +#include "libslic3r/Format/SL1.hpp" + +namespace Slic3r { +// "Masked" CWS as used by Malyan S100 +class MaskedCWSArchive : public SL1Archive { + SLAPrinterConfig m_cfg; +public: + MaskedCWSArchive() = default; + explicit MaskedCWSArchive(const SLAPrinterConfig &cfg): m_cfg(cfg) {} + explicit MaskedCWSArchive(SLAPrinterConfig &&cfg): m_cfg(std::move(cfg)) {} + void export_print(Zipper &zipper, const SLAPrint &print, const std::string &projectname = "") override; +}; +} // namespace Slic3r + +#endif // slic3r_format_CWS_HPP diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 6c5a8c6f6..bf1aa5f6b 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -798,6 +798,7 @@ const std::vector& Preset::sla_printer_options() if (s_opts.empty()) { s_opts = { "printer_technology", + "output_format", "bed_shape", "bed_custom_texture", "bed_custom_model", "max_print_height", "display_width", "display_height", "display_pixels_x", "display_pixels_y", "display_mirror_x", "display_mirror_y", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 1c442d4ce..781b8c880 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -5007,6 +5007,18 @@ void PrintConfigDef::init_sla_params() def->max = 10; def->mode = comExpert; def->set_default_value(new ConfigOptionFloat(2.0)); + + + def = this->add("output_format", coEnum); + def->label = L("Output Format"); + def->tooltip = L("Select the output format for this printer."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("mCWS"); + def->enum_values.push_back("SL1"); + def->enum_labels.push_back(L("Masked CWS")); + def->enum_labels.push_back(L("Prusa SL1")); + def->mode = comAdvanced; // output_format should be preconfigured in profiles; + def->set_default_value(new ConfigOptionEnum(ofMaskedCWS)); } void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value) @@ -5369,6 +5381,16 @@ DynamicPrintConfig* DynamicPrintConfig::new_from_defaults_keys(const std::vector return out; } +OutputFormat output_format(const ConfigBase &cfg) +{ + std::cerr << "Detected technology " << printer_technology(cfg) << "\n"; + if (printer_technology(cfg) == ptFFF) return ofGCode; + const ConfigOptionEnum *opt = cfg.option>("output_format"); + if (opt) return opt->value; + + return ofUnknown; +} + /* double min_object_distance(const ConfigBase &cfg) { diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 31330a942..4a6f6fe01 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -166,6 +166,17 @@ template<> inline const t_config_enum_values& ConfigOptionEnum inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { + static t_config_enum_values keys_map; + if (keys_map.empty()) { + keys_map["mCWS"] = ofMaskedCWS; + keys_map["SL1"] = ofSL1; + } + return keys_map; +} + + + template<> inline const t_config_enum_values& ConfigOptionEnum::get_enum_values() { static t_config_enum_values keys_map; if (keys_map.empty()) { @@ -400,6 +411,7 @@ extern const PrintConfigDef print_config_def; class StaticPrintConfig; PrinterTechnology printer_technology(const ConfigBase &cfg); +OutputFormat output_format(const ConfigBase &cfg); // double min_object_distance(const ConfigBase &cfg); // Slic3r dynamic configuration, used to override the configuration @@ -1668,6 +1680,7 @@ class SLAPrinterConfig : public StaticPrintConfig STATIC_PRINT_CONFIG_CACHE(SLAPrinterConfig) public: ConfigOptionEnum printer_technology; + ConfigOptionEnum output_format; ConfigOptionPoints bed_shape; ConfigOptionFloat max_print_height; ConfigOptionFloat display_width; @@ -1698,6 +1711,7 @@ protected: void initialize(StaticCacheBase &cache, const char *base_ptr) { OPT_PTR(printer_technology); + OPT_PTR(output_format); OPT_PTR(bed_shape); OPT_PTR(max_print_height); OPT_PTR(display_width); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 11900f309..66c7b2e7f 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -678,6 +678,12 @@ void SLAPrint::set_printer(SLAPrinter *arch) m_printer = arch; } +void SLAPrint::set_printer(std::shared_ptr arch) +{ + this->set_printer(arch.get()); + m_printer_ref = arch; // add this so that the reference count is increased. +} + bool SLAPrint::invalidate_step(SLAPrintStep step) { bool invalidated = Inherited::invalidate_step(step); @@ -839,6 +845,7 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector& print_layers() const { return m_printer_input; } void set_printer(SLAPrinter *archiver); + void set_printer(std::shared_ptr archiver); private: @@ -525,6 +526,7 @@ private: // The archive object which collects the raster images after slicing SLAPrinter *m_printer = nullptr; + std::shared_ptr m_printer_ref; // Estimated print time, material consumed. SLAPrintStatistics m_print_statistics; diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 86c7e4a5d..8a4e3ac3e 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -1192,6 +1192,8 @@ void Choice::set_value(const boost::any& value, bool change_event) val = idx_from_enum_value(val); else if (m_opt_id.compare("wipe_advanced_algo") == 0) val = idx_from_enum_value(val); + else if (m_opt_id.compare("output_format") == 0) + val = idx_from_enum_value(val); field->SetSelection(val); break; } @@ -1307,6 +1309,8 @@ boost::any& Choice::get_value() convert_to_enum_value(ret_enum); else if (m_opt_id.compare("wipe_advanced_algo") == 0) convert_to_enum_value(ret_enum); + else if (m_opt_id.compare("output_format") == 0) + convert_to_enum_value(ret_enum); } else if (m_opt.gui_type == "f_enum_open") { const int ret_enum = field->GetSelection(); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 403508917..e5ac7a7bf 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -975,6 +975,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config ret = static_cast(config.option>(opt_key)->value); } else if (opt_key == "wipe_advanced_algo") { ret = static_cast(config.option>(opt_key)->value); + } else if (opt_key == "output_format") { + ret = static_cast(config.option>(opt_key)->value); } } break; diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 110f4c637..007c25e72 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -959,6 +959,8 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig& return get_string_from_enum(opt_key, config); if (opt_key == "display_orientation") return get_string_from_enum(opt_key, config); + if (opt_key == "output_format") + return get_string_from_enum(opt_key, config); if (opt_key == "gcode_flavor") return get_string_from_enum(opt_key, config); if (opt_key == "host_type") -- cgit v1.2.3