Initial cut to add an OutputFormat enumeration for SLA printing.

This commit is contained in:
Joseph Lenox 2021-04-05 00:03:59 -05:00
parent 5b6f71dfef
commit fe7105ff32
14 changed files with 245 additions and 3 deletions

View File

@ -1,5 +1,7 @@
page:General:printer
group:Output Method
setting:output_format
group:Size and coordinates
bed_shape
setting:max_print_height

View File

@ -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<SL1Archive> 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)) {

View File

@ -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

View File

@ -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<OutputFormat>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
}
inline OutputFormat operator&(OutputFormat a, OutputFormat b) {
return static_cast<OutputFormat>(static_cast<uint8_t>(a)& static_cast<uint8_t>(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:

View File

@ -0,0 +1,135 @@
#include "libslic3r/Format/CWS.hpp"
#include "libslic3r/PrintConfig.hpp"
#include "libslic3r/Time.hpp"
namespace Slic3r {
using ConfMap = std::map<std::string, std::string>;
using namespace std::string_literals;
namespace {
std::string to_ini(const ConfMap &m)
{
std::string ret;
for (auto &param : 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 += "<SliceHeight>" + _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

View File

@ -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

View File

@ -798,6 +798,7 @@ const std::vector<std::string>& 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",

View File

@ -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<OutputFormat>::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<OutputFormat>(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<OutputFormat> *opt = cfg.option<ConfigOptionEnum<OutputFormat>>("output_format");
if (opt) return opt->value;
return ofUnknown;
}
/*
double min_object_distance(const ConfigBase &cfg)
{

View File

@ -166,6 +166,17 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology
return keys_map;
}
template<> inline const t_config_enum_values& ConfigOptionEnum<OutputFormat>::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<WipeAlgo>::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<PrinterTechnology> printer_technology;
ConfigOptionEnum<OutputFormat> 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);

View File

@ -678,6 +678,12 @@ void SLAPrint::set_printer(SLAPrinter *arch)
m_printer = arch;
}
void SLAPrint::set_printer(std::shared_ptr<SLAPrinter> 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<t_config_opt
"max_print_height",
"printer_technology",
"output_filename_format",
"output_format",
"fast_tilt_time",
"slow_tilt_time",
"area_fill",

View File

@ -503,6 +503,7 @@ public:
const std::vector<PrintLayer>& print_layers() const { return m_printer_input; }
void set_printer(SLAPrinter *archiver);
void set_printer(std::shared_ptr<SLAPrinter> archiver);
private:
@ -525,6 +526,7 @@ private:
// The archive object which collects the raster images after slicing
SLAPrinter *m_printer = nullptr;
std::shared_ptr<SLAPrinter> m_printer_ref;
// Estimated print time, material consumed.
SLAPrintStatistics m_print_statistics;

View File

@ -1192,6 +1192,8 @@ void Choice::set_value(const boost::any& value, bool change_event)
val = idx_from_enum_value<SLAPillarConnectionMode>(val);
else if (m_opt_id.compare("wipe_advanced_algo") == 0)
val = idx_from_enum_value<WipeAlgo>(val);
else if (m_opt_id.compare("output_format") == 0)
val = idx_from_enum_value<OutputFormat>(val);
field->SetSelection(val);
break;
}
@ -1307,6 +1309,8 @@ boost::any& Choice::get_value()
convert_to_enum_value<SLAPillarConnectionMode>(ret_enum);
else if (m_opt_id.compare("wipe_advanced_algo") == 0)
convert_to_enum_value<WipeAlgo>(ret_enum);
else if (m_opt_id.compare("output_format") == 0)
convert_to_enum_value<OutputFormat>(ret_enum);
}
else if (m_opt.gui_type == "f_enum_open") {
const int ret_enum = field->GetSelection();

View File

@ -975,6 +975,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
ret = static_cast<int>(config.option<ConfigOptionEnum<SLAPillarConnectionMode>>(opt_key)->value);
} else if (opt_key == "wipe_advanced_algo") {
ret = static_cast<int>(config.option<ConfigOptionEnum<WipeAlgo>>(opt_key)->value);
} else if (opt_key == "output_format") {
ret = static_cast<int>(config.option<ConfigOptionEnum<OutputFormat>>(opt_key)->value);
}
}
break;

View File

@ -959,6 +959,8 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
return get_string_from_enum<CompleteObjectSort>(opt_key, config);
if (opt_key == "display_orientation")
return get_string_from_enum<SLADisplayOrientation>(opt_key, config);
if (opt_key == "output_format")
return get_string_from_enum<OutputFormat>(opt_key, config);
if (opt_key == "gcode_flavor")
return get_string_from_enum<GCodeFlavor>(opt_key, config);
if (opt_key == "host_type")