Initial version of sl1 import with sla::Raster refactor.
This commit is contained in:
parent
6eb51a1cca
commit
247fca6d55
39 changed files with 2136 additions and 1094 deletions
222
src/libslic3r/SLA/AGGRaster.hpp
Normal file
222
src/libslic3r/SLA/AGGRaster.hpp
Normal file
|
@ -0,0 +1,222 @@
|
|||
#ifndef AGGRASTER_HPP
|
||||
#define AGGRASTER_HPP
|
||||
|
||||
#include <libslic3r/SLA/RasterBase.hpp>
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/MTUtils.hpp"
|
||||
#include <libnest2d/backends/clipper/clipper_polygon.hpp>
|
||||
|
||||
// For rasterizing
|
||||
#include <agg/agg_basics.h>
|
||||
#include <agg/agg_rendering_buffer.h>
|
||||
#include <agg/agg_pixfmt_gray.h>
|
||||
#include <agg/agg_pixfmt_rgb.h>
|
||||
#include <agg/agg_renderer_base.h>
|
||||
#include <agg/agg_renderer_scanline.h>
|
||||
|
||||
#include <agg/agg_scanline_p.h>
|
||||
#include <agg/agg_rasterizer_scanline_aa.h>
|
||||
#include <agg/agg_path_storage.h>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
inline const Polygon& contour(const ExPolygon& p) { return p.contour; }
|
||||
inline const ClipperLib::Path& contour(const ClipperLib::Polygon& p) { return p.Contour; }
|
||||
|
||||
inline const Polygons& holes(const ExPolygon& p) { return p.holes; }
|
||||
inline const ClipperLib::Paths& holes(const ClipperLib::Polygon& p) { return p.Holes; }
|
||||
|
||||
namespace sla {
|
||||
|
||||
template<class Color> struct Colors {
|
||||
static const Color White;
|
||||
static const Color Black;
|
||||
};
|
||||
|
||||
template<class Color> const Color Colors<Color>::White = Color{255};
|
||||
template<class Color> const Color Colors<Color>::Black = Color{0};
|
||||
|
||||
template<class PixelRenderer,
|
||||
template<class /*agg::renderer_base<PixelRenderer>*/> class Renderer,
|
||||
class Rasterizer = agg::rasterizer_scanline_aa<>,
|
||||
class Scanline = agg::scanline_p8>
|
||||
class AGGRaster: public RasterBase {
|
||||
public:
|
||||
using TColor = typename PixelRenderer::color_type;
|
||||
using TValue = typename TColor::value_type;
|
||||
using TPixel = typename PixelRenderer::pixel_type;
|
||||
using TRawBuffer = agg::rendering_buffer;
|
||||
|
||||
protected:
|
||||
|
||||
Resolution m_resolution;
|
||||
PixelDim m_pxdim_scaled; // used for scaled coordinate polygons
|
||||
|
||||
std::vector<TPixel> m_buf;
|
||||
agg::rendering_buffer m_rbuf;
|
||||
|
||||
PixelRenderer m_pixrenderer;
|
||||
|
||||
agg::renderer_base<PixelRenderer> m_raw_renderer;
|
||||
Renderer<agg::renderer_base<PixelRenderer>> m_renderer;
|
||||
|
||||
Trafo m_trafo;
|
||||
Scanline m_scanlines;
|
||||
Rasterizer m_rasterizer;
|
||||
|
||||
void flipy(agg::path_storage &path) const
|
||||
{
|
||||
path.flip_y(0, double(m_resolution.height_px));
|
||||
}
|
||||
|
||||
void flipx(agg::path_storage &path) const
|
||||
{
|
||||
path.flip_x(0, double(m_resolution.width_px));
|
||||
}
|
||||
|
||||
double getPx(const Point &p) { return p(0) * m_pxdim_scaled.w_mm; }
|
||||
double getPy(const Point &p) { return p(1) * m_pxdim_scaled.h_mm; }
|
||||
agg::path_storage to_path(const Polygon &poly) { return to_path(poly.points); }
|
||||
double getPx(const ClipperLib::IntPoint &p) { return p.X * m_pxdim_scaled.w_mm; }
|
||||
double getPy(const ClipperLib::IntPoint& p) { return p.Y * m_pxdim_scaled.h_mm; }
|
||||
|
||||
template<class PointVec> agg::path_storage _to_path(const PointVec& v)
|
||||
{
|
||||
agg::path_storage path;
|
||||
|
||||
auto it = v.begin();
|
||||
path.move_to(getPx(*it), getPy(*it));
|
||||
while(++it != v.end()) path.line_to(getPx(*it), getPy(*it));
|
||||
path.line_to(getPx(v.front()), getPy(v.front()));
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
template<class PointVec> agg::path_storage _to_path_flpxy(const PointVec& v)
|
||||
{
|
||||
agg::path_storage path;
|
||||
|
||||
auto it = v.begin();
|
||||
path.move_to(getPy(*it), getPx(*it));
|
||||
while(++it != v.end()) path.line_to(getPy(*it), getPx(*it));
|
||||
path.line_to(getPy(v.front()), getPx(v.front()));
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
template<class PointVec> agg::path_storage to_path(const PointVec &v)
|
||||
{
|
||||
auto path = m_trafo.flipXY ? _to_path_flpxy(v) : _to_path(v);
|
||||
|
||||
path.translate_all_paths(m_trafo.center_x * m_pxdim_scaled.w_mm,
|
||||
m_trafo.center_y * m_pxdim_scaled.h_mm);
|
||||
|
||||
if(m_trafo.mirror_x) flipx(path);
|
||||
if(m_trafo.mirror_y) flipy(path);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
template<class P> void _draw(const P &poly)
|
||||
{
|
||||
m_rasterizer.reset();
|
||||
|
||||
m_rasterizer.add_path(to_path(contour(poly)));
|
||||
for(auto& h : holes(poly)) m_rasterizer.add_path(to_path(h));
|
||||
|
||||
agg::render_scanlines(m_rasterizer, m_scanlines, m_renderer);
|
||||
}
|
||||
|
||||
public:
|
||||
template<class GammaFn> AGGRaster(const Resolution &res,
|
||||
const PixelDim & pd,
|
||||
const Trafo & trafo,
|
||||
const TColor & foreground,
|
||||
const TColor & background,
|
||||
GammaFn && gammafn)
|
||||
: m_resolution(res)
|
||||
, m_pxdim_scaled(SCALING_FACTOR / pd.w_mm, SCALING_FACTOR / pd.h_mm)
|
||||
, m_buf(res.pixels())
|
||||
, m_rbuf(reinterpret_cast<TValue *>(m_buf.data()),
|
||||
unsigned(res.width_px),
|
||||
unsigned(res.height_px),
|
||||
int(res.width_px *PixelRenderer::num_components))
|
||||
, m_pixrenderer(m_rbuf)
|
||||
, m_raw_renderer(m_pixrenderer)
|
||||
, m_renderer(m_raw_renderer)
|
||||
, m_trafo(trafo)
|
||||
{
|
||||
m_renderer.color(foreground);
|
||||
clear(background);
|
||||
|
||||
m_rasterizer.gamma(gammafn);
|
||||
}
|
||||
|
||||
Trafo trafo() const override { return m_trafo; }
|
||||
Resolution resolution() const override { return m_resolution; }
|
||||
PixelDim pixel_dimensions() const override
|
||||
{
|
||||
return {SCALING_FACTOR / m_pxdim_scaled.w_mm,
|
||||
SCALING_FACTOR / m_pxdim_scaled.h_mm};
|
||||
}
|
||||
|
||||
void draw(const ExPolygon &poly) override { _draw(poly); }
|
||||
void draw(const ClipperLib::Polygon &poly) override { _draw(poly); }
|
||||
|
||||
EncodedRaster encode(RasterEncoder encoder) const override
|
||||
{
|
||||
return encoder(m_buf.data(), m_resolution.width_px, m_resolution.height_px, 1);
|
||||
}
|
||||
|
||||
void clear(const TColor color) { m_raw_renderer.clear(color); }
|
||||
};
|
||||
|
||||
/*
|
||||
* Captures an anti-aliased monochrome canvas where vectorial
|
||||
* polygons can be rasterized. Fill color is always white and the background is
|
||||
* black. Contours are anti-aliased.
|
||||
*
|
||||
* A gamma function can be specified at compile time to make it more flexible.
|
||||
*/
|
||||
using _RasterGrayscaleAA =
|
||||
AGGRaster<agg::pixfmt_gray8, agg::renderer_scanline_aa_solid>;
|
||||
|
||||
class RasterGrayscaleAA : public _RasterGrayscaleAA {
|
||||
using Base = _RasterGrayscaleAA;
|
||||
using typename Base::TColor;
|
||||
using typename Base::TValue;
|
||||
public:
|
||||
template<class GammaFn>
|
||||
RasterGrayscaleAA(const RasterBase::Resolution &res,
|
||||
const RasterBase::PixelDim & pd,
|
||||
const RasterBase::Trafo & trafo,
|
||||
GammaFn && fn)
|
||||
: Base(res, pd, trafo, Colors<TColor>::White, Colors<TColor>::Black,
|
||||
std::forward<GammaFn>(fn))
|
||||
{}
|
||||
|
||||
uint8_t read_pixel(size_t col, size_t row) const
|
||||
{
|
||||
static_assert(std::is_same<TValue, uint8_t>::value, "Not grayscale pix");
|
||||
|
||||
uint8_t px;
|
||||
Base::m_buf[row * Base::resolution().width_px + col].get(px);
|
||||
return px;
|
||||
}
|
||||
|
||||
void clear() { Base::clear(Colors<TColor>::Black); }
|
||||
};
|
||||
|
||||
class RasterGrayscaleAAGammaPower: public RasterGrayscaleAA {
|
||||
public:
|
||||
RasterGrayscaleAAGammaPower(const RasterBase::Resolution &res,
|
||||
const RasterBase::PixelDim & pd,
|
||||
const RasterBase::Trafo & trafo,
|
||||
double gamma = 1.)
|
||||
: RasterGrayscaleAA(res, pd, trafo, agg::gamma_power(gamma))
|
||||
{}
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::sla
|
||||
|
||||
#endif // AGGRASTER_HPP
|
Loading…
Add table
Add a link
Reference in a new issue