Welcome to mirror list, hosted at ThFree Co, Russian Federation.

AGGRaster.hpp « SLA « libslic3r « src - github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 917f718e981754986ec57dcbd030ab224091302d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#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