diff --git a/src/libslic3r/Format/SL1_SVG.cpp b/src/libslic3r/Format/SL1_SVG.cpp index 8788577d3..52fad1473 100644 --- a/src/libslic3r/Format/SL1_SVG.cpp +++ b/src/libslic3r/Format/SL1_SVG.cpp @@ -3,10 +3,50 @@ #include "libslic3r/LocalesUtils.hpp" #include "libslic3r/ClipperUtils.hpp" +#include +#include +#include + namespace Slic3r { namespace { +size_t constexpr coord_t_bufsize = 40; + +inline char const* decimal_from(coord_t snumber, char* buffer) +{ + std::make_unsigned_t number = 0; + + char* ret = buffer; + + if( snumber < 0 ) { + *buffer++ = '-'; + number = -snumber; + } else + number = snumber; + + if( number == 0 ) { + *buffer++ = '0'; + } else { + char* p_first = buffer; + while( number != 0 ) { + *buffer++ = '0' + number % 10; + number /= 10; + } + std::reverse( p_first, buffer ); + } + + *buffer = '\0'; + + return ret; +} + +inline std::string coord2str(coord_t crd) +{ + char buf[coord_t_bufsize]; + return decimal_from(crd, buf); +} + void transform(ExPolygon &ep, const sla::RasterBase::Trafo &tr, const BoundingBox &bb) { if (tr.flipXY) { @@ -35,46 +75,23 @@ void append_svg(std::string &buf, const Polygon &poly) auto c = poly.points.front(); - buf += "(c.x()), precision) + -// " " + float_to_string_decimal_point(unscaled(c.y()), precision) + " m"; - -// for (auto &p : poly) { -// auto d = p - c; -// if (d.squaredNorm() == 0) continue; -// buf += " "; -// buf += float_to_string_decimal_point(unscaled(p.x() - c.x()), precision); -// buf += " "; -// buf += float_to_string_decimal_point(unscaled(p.y() - c.y()), precision); -// c = p; -// } -// buf += " z\""; // mark path as closed -// buf += " />\n"; -//} - } // namespace // A fake raster from SVG @@ -101,8 +118,8 @@ public: // in mm due to the header's definition. std::string wf = float_to_string_decimal_point(unscaled(m_bb.size().x())); std::string hf = float_to_string_decimal_point(unscaled(m_bb.size().y())); - std::string w = std::to_string(coord_t(m_res.width_px)); - std::string h = std::to_string(coord_t(m_res.height_px)); + std::string w = coord2str(coord_t(m_res.width_px)); + std::string h = coord2str(coord_t(m_res.height_px)); // Notice the header also defines the fill-rule as nonzero which should // generate correct results for our ExPolygons. @@ -126,7 +143,7 @@ public: double tol = std::min(m_bb.size().x() / double(m_res.width_px), m_bb.size().y() / double(m_res.height_px)); - ExPolygons cpolys = poly.simplify(tol / 4.); + ExPolygons cpolys = poly.simplify(tol); for (auto &cpoly : cpolys) { transform(cpoly, m_trafo, m_bb); @@ -165,8 +182,10 @@ std::unique_ptr SL1_SVGArchive::create_raster() const auto w = cfg().display_width.getFloat(); auto h = cfg().display_height.getFloat(); - auto res_x = size_t(cfg().display_pixels_x.getInt()); - auto res_y = size_t(cfg().display_pixels_y.getInt()); +// auto res_x = size_t(cfg().display_pixels_x.getInt()); +// auto res_y = size_t(cfg().display_pixels_y.getInt()); + size_t res_x = std::round(scaled(w) / cfg().sla_output_precision.getFloat()); + size_t res_y = std::round(scaled(h) / cfg().sla_output_precision.getFloat()); std::array mirror; @@ -188,8 +207,7 @@ std::unique_ptr SL1_SVGArchive::create_raster() const // Gamma does not really make sense in an svg, right? // double gamma = cfg().gamma_correction.getFloat(); - - return std::make_unique(svgarea, sla::Resolution{res_x * 4, res_y * 4}, tr); + return std::make_unique(svgarea, sla::Resolution{res_x, res_y}, tr); } sla::RasterEncoder SL1_SVGArchive::get_encoder() const diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 44995cce3..ca1363da2 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -573,7 +573,7 @@ static std::vector s_Preset_sla_printer_options { "elefant_foot_min_width", "gamma_correction", "min_exposure_time", "max_exposure_time", - "min_initial_exposure_time", "max_initial_exposure_time", "sla_archive_format", + "min_initial_exposure_time", "max_initial_exposure_time", "sla_archive_format", "sla_output_precision", //FIXME the print host keys are left here just for conversion from the Printer preset to Physical Printer preset. "print_host", "printhost_apikey", "printhost_cafile", "printer_notes", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index f0926b0a4..3070f865b 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3805,6 +3805,14 @@ void PrintConfigDef::init_sla_params() def->label = L("Format of the output SLA archive"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("SL1")); + + def = this->add("sla_output_precision", coFloat); + def->label = L("SLA output precision"); + def->tooltip = L("Minimum resolution in nanometers"); + def->sidetext = L("nm"); + def->min = 1; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(1000)); } void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 07b024536..75079ee71 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -981,6 +981,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, min_initial_exposure_time)) ((ConfigOptionFloat, max_initial_exposure_time)) ((ConfigOptionString, sla_archive_format)) + ((ConfigOptionFloat, sla_output_precision)) ) PRINT_CONFIG_CLASS_DERIVED_DEFINE0( diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 746def7c4..7b78dfea2 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -838,7 +838,8 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector steps_ignore = { diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index b4354c30e..a20bdb831 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2521,6 +2521,7 @@ void TabPrinter::build_sla() optgroup = page->new_optgroup(L("Output")); optgroup->append_single_option_line("sla_archive_format"); + optgroup->append_single_option_line("sla_output_precision"); build_print_host_upload_group(page.get());