From c702ddc65dacef54b9ce1f2d444aa73df6aa0844 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 9 Apr 2019 13:42:32 +0200 Subject: [PATCH] Adding absolute correction (XY offset) and gamma correction parameters. --- src/libslic3r/PrintConfig.cpp | 22 +++++++- src/libslic3r/PrintConfig.hpp | 8 ++- src/libslic3r/PrintExport.hpp | 11 ++-- src/libslic3r/Rasterizer/Rasterizer.cpp | 70 +++++++++---------------- src/libslic3r/Rasterizer/Rasterizer.hpp | 9 ++-- src/libslic3r/SLAPrint.cpp | 48 +++++++++++++---- src/slic3r/GUI/Preset.cpp | 4 +- src/slic3r/GUI/Tab.cpp | 6 ++- 8 files changed, 108 insertions(+), 70 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 998906efd4..b236336f00 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2260,11 +2260,31 @@ void PrintConfigDef::init_sla_params() def->mode = comExpert; def->default_value = new ConfigOptionFloat(50.); - def = this->add("printer_correction", coFloats); + def = this->add("relative_correction", coFloats); + def->label = L("Printer scaling correction"); def->full_label = L("Printer scaling correction"); def->tooltip = L("Printer scaling correction"); def->min = 0; + def->mode = comExpert; def->default_value = new ConfigOptionFloats( { 1., 1., 1. } ); + + def = this->add("absolute_correction", coFloat); + def->label = L("Printer absolute correction"); + def->full_label = L("Printer absolute correction"); + def->tooltip = L("Will inflate or deflate the sliced 2D polygons according " + "to the sign of the correction."); + def->mode = comExpert; + def->default_value = new ConfigOptionFloat(0.0); + + def = this->add("gamma_correction", coFloat); + def->label = L("Printer gamma correction"); + def->full_label = L("Printer gamma correction"); + def->tooltip = L("This will apply a gamm correction to the rasterized 2D " + "polygons."); + def->min = 0; + def->mode = comExpert; + def->default_value = new ConfigOptionFloat(1.0); + // SLA Material settings. def = this->add("initial_layer_height", coFloat); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 14b6087dea..db3e63fe7e 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1079,7 +1079,9 @@ public: ConfigOptionInt display_pixels_x; ConfigOptionInt display_pixels_y; ConfigOptionEnum display_orientation; - ConfigOptionFloats printer_correction; + ConfigOptionFloats relative_correction; + ConfigOptionFloat absolute_correction; + ConfigOptionFloat gamma_correction; ConfigOptionFloat fast_tilt_time; ConfigOptionFloat slow_tilt_time; ConfigOptionFloat area_fill; @@ -1094,7 +1096,9 @@ protected: OPT_PTR(display_pixels_x); OPT_PTR(display_pixels_y); OPT_PTR(display_orientation); - OPT_PTR(printer_correction); + OPT_PTR(relative_correction); + OPT_PTR(absolute_correction); + OPT_PTR(gamma_correction); OPT_PTR(fast_tilt_time); OPT_PTR(slow_tilt_time); OPT_PTR(area_fill); diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index ce62f7cb0f..f6537ed324 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -138,6 +138,7 @@ template<> class FilePrinter double m_exp_time_s = .0, m_exp_time_first_s = .0; double m_layer_height = .0; Raster::Origin m_o = Raster::Origin::TOP_LEFT; + double m_gamma; double m_used_material = 0.0; int m_cnt_fade_layers = 0; @@ -194,7 +195,8 @@ public: unsigned width_px, unsigned height_px, double layer_height, double exp_time, double exp_time_first, - RasterOrientation ro = RO_PORTRAIT): + RasterOrientation ro = RO_PORTRAIT, + double gamma = 1.0): m_res(width_px, height_px), m_pxdim(width_mm/width_px, height_mm/height_px), m_exp_time_s(exp_time), @@ -203,7 +205,8 @@ public: // Here is the trick with the orientation. m_o(ro == RO_LANDSCAPE? Raster::Origin::BOTTOM_LEFT : - Raster::Origin::TOP_LEFT ) + Raster::Origin::TOP_LEFT ), + m_gamma(gamma) { } @@ -228,12 +231,12 @@ public: inline void begin_layer(unsigned lyr) { if(m_layers_rst.size() <= lyr) m_layers_rst.resize(lyr+1); - m_layers_rst[lyr].raster.reset(m_res, m_pxdim, m_o); + m_layers_rst[lyr].raster.reset(m_res, m_pxdim, m_o, m_gamma); } inline void begin_layer() { m_layers_rst.emplace_back(); - m_layers_rst.front().raster.reset(m_res, m_pxdim, m_o); + m_layers_rst.front().raster.reset(m_res, m_pxdim, m_o, m_gamma); } inline void finish_layer(unsigned lyr_id) { diff --git a/src/libslic3r/Rasterizer/Rasterizer.cpp b/src/libslic3r/Rasterizer/Rasterizer.cpp index 496a584a24..56227f8d99 100644 --- a/src/libslic3r/Rasterizer/Rasterizer.cpp +++ b/src/libslic3r/Rasterizer/Rasterizer.cpp @@ -19,6 +19,12 @@ namespace Slic3r { +const Polygon& contour(const ExPolygon& p) { return p.contour; } +const ClipperLib::Path& contour(const ClipperLib::Polygon& p) { return p.Contour; } + +const Polygons& holes(const ExPolygon& p) { return p.holes; } +const ClipperLib::Paths& holes(const ClipperLib::Polygon& p) { return p.Holes; } + class Raster::Impl { public: using TPixelRenderer = agg::pixfmt_gray8; // agg::pixfmt_rgb24; @@ -44,6 +50,7 @@ private: TRawRenderer m_raw_renderer; TRendererAA m_renderer; Origin m_o; + double m_gamma; inline void flipy(agg::path_storage& path) const { path.flip_y(0, m_resolution.height_px); @@ -52,7 +59,7 @@ private: public: inline Impl(const Raster::Resolution& res, const Raster::PixelDim &pd, - Origin o): + Origin o, double gamma = 1.0): m_resolution(res), m_pxdim(pd), m_buf(res.pixels()), m_rbuf(reinterpret_cast(m_buf.data()), @@ -61,46 +68,26 @@ public: m_pixfmt(m_rbuf), m_raw_renderer(m_pixfmt), m_renderer(m_raw_renderer), - m_o(o) + m_o(o), + m_gamma(gamma) { m_renderer.color(ColorWhite); - - // If we would like to play around with gamma - // ras.gamma(agg::gamma_power(1.0)); - clear(); } - void draw(const ExPolygon &poly) { + template void draw(const P &poly) { agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 scanlines; + + ras.gamma(agg::gamma_power(m_gamma)); - auto&& path = to_path(poly.contour); + auto&& path = to_path(contour(poly)); if(m_o == Origin::TOP_LEFT) flipy(path); ras.add_path(path); - for(auto h : poly.holes) { - auto&& holepath = to_path(h); - if(m_o == Origin::TOP_LEFT) flipy(holepath); - ras.add_path(holepath); - } - - agg::render_scanlines(ras, scanlines, m_renderer); - } - - void draw(const ClipperLib::Polygon &poly) { - agg::rasterizer_scanline_aa<> ras; - agg::scanline_p8 scanlines; - - auto&& path = to_path(poly.Contour); - - if(m_o == Origin::TOP_LEFT) flipy(path); - - ras.add_path(path); - - for(auto h : poly.Holes) { + for(auto& h : holes(poly)) { auto&& holepath = to_path(h); if(m_o == Origin::TOP_LEFT) flipy(holepath); ras.add_path(holepath); @@ -128,19 +115,11 @@ private: return p(1) * SCALING_FACTOR/m_pxdim.h_mm; } - agg::path_storage to_path(const Polygon& poly) + inline agg::path_storage to_path(const Polygon& poly) { - agg::path_storage path; - - auto it = poly.points.begin(); - path.move_to(getPx(*it), getPy(*it)); - while(++it != poly.points.end()) path.line_to(getPx(*it), getPy(*it)); - path.line_to(getPx(poly.points.front()), getPy(poly.points.front())); - - return path; + return to_path(poly.points); } - double getPx(const ClipperLib::IntPoint& p) { return p.X * SCALING_FACTOR/m_pxdim.w_mm; } @@ -149,7 +128,7 @@ private: return p.Y * SCALING_FACTOR/m_pxdim.h_mm; } - agg::path_storage to_path(const ClipperLib::Path& poly) + template agg::path_storage to_path(const PointVec& poly) { agg::path_storage path; auto it = poly.begin(); @@ -166,8 +145,8 @@ private: const Raster::Impl::TPixel Raster::Impl::ColorWhite = Raster::Impl::TPixel(255); const Raster::Impl::TPixel Raster::Impl::ColorBlack = Raster::Impl::TPixel(0); -Raster::Raster(const Resolution &r, const PixelDim &pd, Origin o): - m_impl(new Impl(r, pd, o)) {} +Raster::Raster(const Resolution &r, const PixelDim &pd, Origin o, double g): + m_impl(new Impl(r, pd, o, g)) {} Raster::Raster() {} @@ -176,19 +155,20 @@ Raster::~Raster() {} Raster::Raster(Raster &&m): m_impl(std::move(m.m_impl)) {} -void Raster::reset(const Raster::Resolution &r, const Raster::PixelDim &pd) +void Raster::reset(const Raster::Resolution &r, const Raster::PixelDim &pd, + double g) { // Free up the unnecessary memory and make sure it stays clear after // an exception auto o = m_impl? m_impl->origin() : Origin::TOP_LEFT; - reset(r, pd, o); + reset(r, pd, o, g); } void Raster::reset(const Raster::Resolution &r, const Raster::PixelDim &pd, - Raster::Origin o) + Raster::Origin o, double gamma) { m_impl.reset(); - m_impl.reset(new Impl(r, pd, o)); + m_impl.reset(new Impl(r, pd, o, gamma)); } void Raster::reset() diff --git a/src/libslic3r/Rasterizer/Rasterizer.hpp b/src/libslic3r/Rasterizer/Rasterizer.hpp index 671dcbb3d9..d4d2277c47 100644 --- a/src/libslic3r/Rasterizer/Rasterizer.hpp +++ b/src/libslic3r/Rasterizer/Rasterizer.hpp @@ -99,8 +99,9 @@ public: }; /// Constructor taking the resolution and the pixel dimension. - explicit Raster(const Resolution& r, const PixelDim& pd, - Origin o = Origin::BOTTOM_LEFT ); + Raster(const Resolution& r, const PixelDim& pd, + Origin o = Origin::BOTTOM_LEFT, double gamma = 1.0); + Raster(); Raster(const Raster& cpy) = delete; Raster& operator=(const Raster& cpy) = delete; @@ -108,8 +109,8 @@ public: ~Raster(); /// Reallocated everything for the given resolution and pixel dimension. - void reset(const Resolution& r, const PixelDim& pd); - void reset(const Resolution& r, const PixelDim& pd, Origin o); + void reset(const Resolution& r, const PixelDim& pd, double gamma = 1.0); + void reset(const Resolution& r, const PixelDim& pd, Origin o, double gamma); /** * Release the allocated resources. Drawing in this state ends in diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 1cbb91fa78..d973ca1561 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -715,10 +715,17 @@ void SLAPrint::process() [this](){ throw_if_canceled(); }); auto mit = slindex_it; + double doffs = m_printer_config.absolute_correction.getFloat(); + coord_t clpr_offs = coord_t(doffs / SCALING_FACTOR); for(size_t id = 0; id < po.m_model_slices.size() && mit != po.m_slice_index.end(); id++) { + // We apply the printer correction offset here. + if(clpr_offs != 0) + po.m_model_slices[id] = + offset_ex(po.m_model_slices[id], clpr_offs); + mit->set_model_slice_idx(po, id); ++mit; } }; @@ -920,10 +927,17 @@ void SLAPrint::process() heights, float(po.config().slice_closing_radius.value)); } + double doffs = m_printer_config.absolute_correction.getFloat(); + coord_t clpr_offs = coord_t(doffs / SCALING_FACTOR); for(size_t i = 0; i < sd->support_slices.size() && i < po.m_slice_index.size(); ++i) { + // We apply the printer correction offset here. + if(clpr_offs != 0) + sd->support_slices[i] = + offset_ex(sd->support_slices[i], clpr_offs); + po.m_slice_index[i].set_support_slice_idx(po, i); } @@ -1031,6 +1045,8 @@ void SLAPrint::process() const double width = m_printer_config.display_width.getFloat() / SCALING_FACTOR; const double height = m_printer_config.display_height.getFloat() / SCALING_FACTOR; const double display_area = width*height; + + const coord_t clpr_back_offs = - coord_t(m_printer_config.absolute_correction.getFloat() / SCALING_FACTOR); // get polygons for all instances in the object auto get_all_polygons = @@ -1114,7 +1130,7 @@ void SLAPrint::process() auto printlayerfn = [this, // functions and read only vars get_all_polygons, polyunion, polydiff, areafn, - area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, delta_fade_time, + area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, delta_fade_time, clpr_back_offs, // write vars &mutex, &models_volume, &supports_volume, &estim_time, &slow_layers, @@ -1150,14 +1166,18 @@ void SLAPrint::process() for(const SliceRecord& record : layer.slices()) { const SLAPrintObject *po = record.print_obj(); - const ExPolygons &modelslices = record.get_slice(soModel); + const ExPolygons &rawmodelslices = record.get_slice(soModel); + const ExPolygons &modelslices = clpr_back_offs != 0 ? offset_ex(rawmodelslices, clpr_back_offs) : rawmodelslices; + bool is_lefth = record.print_obj()->is_left_handed(); if (!modelslices.empty()) { ClipperPolygons v = get_all_polygons(modelslices, po->instances(), is_lefth); for(ClipperPolygon& p_tmp : v) model_polygons.emplace_back(std::move(p_tmp)); } - const ExPolygons &supportslices = record.get_slice(soSupport); + const ExPolygons &rawsupportslices = record.get_slice(soSupport); + const ExPolygons &supportslices = clpr_back_offs != 0 ? offset_ex(rawsupportslices, clpr_back_offs) : rawsupportslices; + if (!supportslices.empty()) { ClipperPolygons v = get_all_polygons(supportslices, po->instances(), is_lefth); for(ClipperPolygon& p_tmp : v) supports_polygons.emplace_back(std::move(p_tmp)); @@ -1266,12 +1286,16 @@ void SLAPrint::process() double lh = ocfg.layer_height.getFloat(); double exp_t = matcfg.exposure_time.getFloat(); double iexp_t = matcfg.initial_exposure_time.getFloat(); + + double gamma = m_printer_config.gamma_correction.getFloat(); if(flpXY) { std::swap(w, h); std::swap(pw, ph); } - m_printer.reset(new SLAPrinter(w, h, pw, ph, lh, exp_t, iexp_t, - flpXY? SLAPrinter::RO_PORTRAIT : - SLAPrinter::RO_LANDSCAPE)); + m_printer.reset( + new SLAPrinter(w, h, pw, ph, lh, exp_t, iexp_t, + flpXY? SLAPrinter::RO_PORTRAIT : + SLAPrinter::RO_LANDSCAPE, + gamma)); } // Allocate space for all the layers @@ -1433,7 +1457,9 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector steps_full = { "initial_layer_height", "material_correction", - "printer_correction" + "relative_correction", + "absolute_correction", + "gamma_correction" }; // Cache the plenty of parameters, which influence the final rasterization only, @@ -1628,10 +1654,10 @@ Vec3d SLAPrint::relative_correction() const { Vec3d corr(1., 1., 1.); - if(printer_config().printer_correction.values.size() == 3) { - corr(X) = printer_config().printer_correction.values[X]; - corr(Y) = printer_config().printer_correction.values[Y]; - corr(Z) = printer_config().printer_correction.values[Z]; + if(printer_config().relative_correction.values.size() == 3) { + corr(X) = printer_config().relative_correction.values[X]; + corr(Y) = printer_config().relative_correction.values[Y]; + corr(Z) = printer_config().relative_correction.values[Z]; } if(material_config().material_correction.values.size() == 3) { diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp index 9faa830da5..e383181f46 100644 --- a/src/slic3r/GUI/Preset.cpp +++ b/src/slic3r/GUI/Preset.cpp @@ -506,7 +506,9 @@ const std::vector& Preset::sla_printer_options() "display_width", "display_height", "display_pixels_x", "display_pixels_y", "display_orientation", "fast_tilt_time", "slow_tilt_time", "area_fill", - "printer_correction", + "relative_correction", + "absolute_correction", + "gamma_correction", "print_host", "printhost_apikey", "printhost_cafile", "printer_notes", "inherits" diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 1c74d4b441..c221611646 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2006,16 +2006,18 @@ void TabPrinter::build_sla() optgroup->append_single_option_line("area_fill"); optgroup = page->new_optgroup(_(L("Corrections"))); - line = Line{ m_config->def()->get("printer_correction")->full_label, "" }; + line = Line{ m_config->def()->get("relative_correction")->full_label, "" }; std::vector axes{ "X", "Y", "Z" }; int id = 0; for (auto& axis : axes) { - auto opt = optgroup->get_option("printer_correction", id); + auto opt = optgroup->get_option("relative_correction", id); opt.opt.label = axis; line.append_option(opt); ++id; } optgroup->append_line(line); + optgroup->append_single_option_line("absolute_correction"); + optgroup->append_single_option_line("gamma_correction"); optgroup = page->new_optgroup(_(L("Print Host upload"))); build_printhost(optgroup.get());