XY flip is implemented, works only for portrait LCD.
This commit is contained in:
parent
35a8a5374c
commit
9917edcdcc
@ -31,8 +31,6 @@ template<FilePrinterFormat format>
|
|||||||
class FilePrinter {
|
class FilePrinter {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void print_config(const Print&);
|
|
||||||
|
|
||||||
// Draw an ExPolygon which is a polygon inside a slice on the specified layer.
|
// Draw an ExPolygon which is a polygon inside a slice on the specified layer.
|
||||||
void draw_polygon(const ExPolygon& p, unsigned lyr);
|
void draw_polygon(const ExPolygon& p, unsigned lyr);
|
||||||
|
|
||||||
@ -147,8 +145,8 @@ template<> class FilePrinter<FilePrinterFormat::SLA_PNGZIP>
|
|||||||
+layerh_str+"+printer=DWARF3\n";
|
+layerh_str+"+printer=DWARF3\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change this to TOP_LEFT if you want correct PNG orientation
|
// The PNG format has its origin in the top left corner.
|
||||||
static const Raster::Origin ORIGIN = Raster::Origin::BOTTOM_LEFT;
|
static const Raster::Origin ORIGIN = Raster::Origin::TOP_LEFT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline FilePrinter(double width_mm, double height_mm,
|
inline FilePrinter(double width_mm, double height_mm,
|
||||||
|
@ -45,15 +45,20 @@ private:
|
|||||||
TRawRenderer m_raw_renderer;
|
TRawRenderer m_raw_renderer;
|
||||||
TRendererAA m_renderer;
|
TRendererAA m_renderer;
|
||||||
Origin m_o;
|
Origin m_o;
|
||||||
std::function<void(agg::path_storage&)> m_flipy = [](agg::path_storage&) {};
|
|
||||||
|
inline void flipy(agg::path_storage& path) const {
|
||||||
|
path.flip_y(0, m_resolution.height_px);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline Impl(const Raster::Resolution& res, const Raster::PixelDim &pd,
|
inline Impl(const Raster::Resolution& res, const Raster::PixelDim &pd,
|
||||||
Origin o):
|
Origin o):
|
||||||
m_resolution(res), m_pxdim(pd),
|
m_resolution(res), m_pxdim(pd),
|
||||||
m_buf(res.pixels()),
|
m_buf(res.pixels()),
|
||||||
m_rbuf(reinterpret_cast<TPixelRenderer::value_type*>(m_buf.data()),
|
m_rbuf(reinterpret_cast<TPixelRenderer::value_type*>(m_buf.data()),
|
||||||
res.width_px, res.height_px,
|
res.width_px, res.height_px,
|
||||||
res.width_px*TPixelRenderer::num_components),
|
int(res.width_px*TPixelRenderer::num_components)),
|
||||||
m_pixfmt(m_rbuf),
|
m_pixfmt(m_rbuf),
|
||||||
m_raw_renderer(m_pixfmt),
|
m_raw_renderer(m_pixfmt),
|
||||||
m_renderer(m_raw_renderer),
|
m_renderer(m_raw_renderer),
|
||||||
@ -65,10 +70,6 @@ public:
|
|||||||
// ras.gamma(agg::gamma_power(1.0));
|
// ras.gamma(agg::gamma_power(1.0));
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if(m_o == Origin::TOP_LEFT) m_flipy = [this](agg::path_storage& path) {
|
|
||||||
path.flip_y(0, m_resolution.height_px);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(const ExPolygon &poly) {
|
void draw(const ExPolygon &poly) {
|
||||||
@ -76,12 +77,14 @@ public:
|
|||||||
agg::scanline_p8 scanlines;
|
agg::scanline_p8 scanlines;
|
||||||
|
|
||||||
auto&& path = to_path(poly.contour);
|
auto&& path = to_path(poly.contour);
|
||||||
m_flipy(path);
|
|
||||||
|
if(m_o == Origin::TOP_LEFT) flipy(path);
|
||||||
|
|
||||||
ras.add_path(path);
|
ras.add_path(path);
|
||||||
|
|
||||||
for(auto h : poly.holes) {
|
for(auto h : poly.holes) {
|
||||||
auto&& holepath = to_path(h);
|
auto&& holepath = to_path(h);
|
||||||
m_flipy(holepath);
|
if(m_o == Origin::TOP_LEFT) flipy(holepath);
|
||||||
ras.add_path(holepath);
|
ras.add_path(holepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,8 +208,9 @@ void Raster::save(std::ostream& stream, Compression comp)
|
|||||||
<< m_impl->resolution().height_px << " "
|
<< m_impl->resolution().height_px << " "
|
||||||
<< "255 ";
|
<< "255 ";
|
||||||
|
|
||||||
|
auto sz = m_impl->buffer().size()*sizeof(Impl::TBuffer::value_type);
|
||||||
stream.write(reinterpret_cast<const char*>(m_impl->buffer().data()),
|
stream.write(reinterpret_cast<const char*>(m_impl->buffer().data()),
|
||||||
m_impl->buffer().size()*sizeof(Impl::TBuffer::value_type));
|
std::streamsize(sz));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,13 @@ public:
|
|||||||
PNG //!> PNG compression
|
PNG //!> PNG compression
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The Rasterizer expects the input polygons to have their coordinate
|
||||||
|
/// system origin in the bottom left corner. If the raster is then
|
||||||
|
/// configured with the TOP_LEFT origin parameter (in the constructor) than
|
||||||
|
/// it will flip the Y axis in output to maintain the correct orientation.
|
||||||
|
/// This is the default case with PNG images. They have the origin in the
|
||||||
|
/// top left corner. Without the flipping, the image would be upside down
|
||||||
|
/// with the scaled (clipper) coordinate system of the input polygons.
|
||||||
enum class Origin {
|
enum class Origin {
|
||||||
TOP_LEFT,
|
TOP_LEFT,
|
||||||
BOTTOM_LEFT
|
BOTTOM_LEFT
|
||||||
|
@ -715,6 +715,8 @@ void SLAPrint::process()
|
|||||||
std::vector<long long> keys; keys.reserve(levels.size());
|
std::vector<long long> keys; keys.reserve(levels.size());
|
||||||
for(auto& e : levels) keys.emplace_back(e.first);
|
for(auto& e : levels) keys.emplace_back(e.first);
|
||||||
|
|
||||||
|
bool flpXY = m_printer_config.display_flip_xy.getBool();
|
||||||
|
|
||||||
{ // create a raster printer for the current print parameters
|
{ // create a raster printer for the current print parameters
|
||||||
// I don't know any better
|
// I don't know any better
|
||||||
auto& ocfg = m_objects.front()->m_config;
|
auto& ocfg = m_objects.front()->m_config;
|
||||||
@ -729,6 +731,8 @@ void SLAPrint::process()
|
|||||||
double exp_t = matcfg.exposure_time.getFloat();
|
double exp_t = matcfg.exposure_time.getFloat();
|
||||||
double iexp_t = matcfg.initial_exposure_time.getFloat();
|
double iexp_t = matcfg.initial_exposure_time.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));
|
m_printer.reset(new SLAPrinter(w, h, pw, ph, lh, exp_t, iexp_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,7 +748,7 @@ void SLAPrint::process()
|
|||||||
|
|
||||||
// procedure to process one height level. This will run in parallel
|
// procedure to process one height level. This will run in parallel
|
||||||
auto lvlfn =
|
auto lvlfn =
|
||||||
[this, &slck, &keys, &levels, &printer, slot, sd, ist, &pst]
|
[this, &slck, &keys, &levels, &printer, slot, sd, ist, &pst, flpXY]
|
||||||
(unsigned level_id)
|
(unsigned level_id)
|
||||||
{
|
{
|
||||||
if(canceled()) return;
|
if(canceled()) return;
|
||||||
@ -764,8 +768,12 @@ void SLAPrint::process()
|
|||||||
for(ExPolygon slice : sl) {
|
for(ExPolygon slice : sl) {
|
||||||
// The order is important here:
|
// The order is important here:
|
||||||
// apply rotation before translation...
|
// apply rotation before translation...
|
||||||
slice.rotate(cp.rotation);
|
slice.rotate(double(cp.rotation));
|
||||||
slice.translate(cp.shift(X), cp.shift(Y));
|
slice.translate(cp.shift(X), cp.shift(Y));
|
||||||
|
if(flpXY) {
|
||||||
|
for(auto& p : slice.contour.points) std::swap(p(X), p(Y));
|
||||||
|
for(auto& h : slice.holes) for(auto& p : h.points) std::swap(p(X), p(Y));
|
||||||
|
}
|
||||||
printer.draw_polygon(slice, level_id);
|
printer.draw_polygon(slice, level_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user