mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Adding absolute correction (XY offset) and gamma correction parameters.
This commit is contained in:
		
							parent
							
								
									d8cb1b0792
								
							
						
					
					
						commit
						c702ddc65d
					
				
					 8 changed files with 108 additions and 70 deletions
				
			
		|  | @ -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); | ||||
|  |  | |||
|  | @ -1079,7 +1079,9 @@ public: | |||
|     ConfigOptionInt                         display_pixels_x; | ||||
|     ConfigOptionInt                         display_pixels_y; | ||||
|     ConfigOptionEnum<SLADisplayOrientation> 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); | ||||
|  |  | |||
|  | @ -138,6 +138,7 @@ template<> class FilePrinter<FilePrinterFormat::SLA_PNGZIP> | |||
|     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) { | ||||
|  |  | |||
|  | @ -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<TPixelRenderer::value_type*>(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<class P> 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<class PointVec> 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() | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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<t_config_opt | |||
|     static std::unordered_set<std::string> 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) { | ||||
|  |  | |||
|  | @ -506,7 +506,9 @@ const std::vector<std::string>& 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" | ||||
|  |  | |||
|  | @ -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<std::string> 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()); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros