wip
This commit is contained in:
tamasmeszaros 2022-01-12 13:54:18 +01:00
parent b45c6ef173
commit 72da90d28f
10 changed files with 147 additions and 93 deletions

View file

@ -446,8 +446,8 @@ void fill_slicerconf(ConfMap &m, const SLAPrint &print)
std::unique_ptr<sla::RasterBase> SL1Archive::create_raster() const
{
sla::RasterBase::Resolution res;
sla::RasterBase::PixelDim pxdim;
sla::Resolution res;
sla::PixelDim pxdim;
std::array<bool, 2> mirror;
double w = m_cfg.display_width.getFloat();
@ -468,8 +468,8 @@ std::unique_ptr<sla::RasterBase> SL1Archive::create_raster() const
std::swap(pw, ph);
}
res = sla::RasterBase::Resolution{pw, ph};
pxdim = sla::RasterBase::PixelDim{w / pw, h / ph};
res = sla::Resolution{pw, ph};
pxdim = sla::PixelDim{w / pw, h / ph};
sla::RasterBase::Trafo tr{orientation, mirror};
double gamma = m_cfg.gamma_correction.getFloat();

View file

@ -1,6 +1,7 @@
#include "SL1_SVG.hpp"
#include "SLA/RasterBase.hpp"
#include "libslic3r/LocalesUtils.hpp"
#include "libslic3r/ClipperUtils.hpp"
namespace Slic3r {
@ -29,41 +30,79 @@ void transform(ExPolygon &ep, const sla::RasterBase::Trafo &tr, const BoundingBo
void append_svg(std::string &buf, const Polygon &poly)
{
buf += "<path d=\"M";
if (poly.points.empty())
return;
auto c = poly.points.front();
buf += "<path d=\"M " + std::to_string(c.x()) + " " + std::to_string(c.y()) + " m";
for (auto &p : poly) {
auto d = p - c;
if (d.squaredNorm() == 0) continue;
buf += " ";
buf += std::to_string(p.x());
buf += std::to_string(p.x() - c.x());
buf += " ";
buf += std::to_string(p.y());
buf += std::to_string(p.y() - c.y());
c = p;
}
buf += " z\""; // mark path as closed
buf += " />\n";
}
//static constexpr int precision = -1;
//void append_svg_fp(std::string &buf, const Polygon &poly)
//{
// if (poly.points.empty())
// return;
// auto c = poly.points.front();
// buf += "<path d=\"M " + float_to_string_decimal_point(unscaled<float>(c.x()), precision) +
// " " + float_to_string_decimal_point(unscaled<float>(c.y()), precision) + " m";
// for (auto &p : poly) {
// auto d = p - c;
// if (d.squaredNorm() == 0) continue;
// buf += " ";
// buf += float_to_string_decimal_point(unscaled<float>(p.x() - c.x()), precision);
// buf += " ";
// buf += float_to_string_decimal_point(unscaled<float>(p.y() - c.y()), precision);
// c = p;
// }
// buf += " z\""; // mark path as closed
// buf += " />\n";
//}
} // namespace
// A fake raster from SVG
class SVGRaster : public sla::RasterBase {
// Resolution here will be used for svg boundaries
BoundingBox m_bb;
Trafo m_trafo;
BoundingBox m_bb;
sla::Resolution m_res;
Trafo m_trafo;
Vec2d m_sc;
std::string m_svg;
public:
SVGRaster(Resolution res = {}, Trafo tr = {})
: m_bb{BoundingBox{{0, 0}, Vec2crd{res.width_px, res.height_px}}}
SVGRaster(const BoundingBox &svgarea, sla::Resolution res, Trafo tr = {})
: m_bb{svgarea}
, m_res{res}
, m_trafo{tr}
, m_sc{double(m_res.width_px) / m_bb.size().x(), double(m_res.height_px) / m_bb.size().y()}
{
// Inside the svg header, the boundaries will be defined in mm to
// the actual bed size. The viewport is then defined to work with our
// scaled coordinates. All the exported polygons will be in these scaled
// coordinates but svg rendering software will interpret them correctly
// in mm due to the header's definition.
std::string wf = float_to_string_decimal_point(unscaled<float>(res.width_px));
std::string hf = float_to_string_decimal_point(unscaled<float>(res.height_px));
std::string w = std::to_string(res.width_px);
std::string h = std::to_string(res.height_px);
std::string wf = float_to_string_decimal_point(unscaled<float>(m_bb.size().x()));
std::string hf = float_to_string_decimal_point(unscaled<float>(m_bb.size().y()));
std::string w = std::to_string(coord_t(m_res.width_px));
std::string h = std::to_string(coord_t(m_res.height_px));
// Notice the header also defines the fill-rule as nonzero which should
// generate correct results for our ExPolygons.
@ -84,21 +123,28 @@ public:
{
auto cpoly = poly;
transform(cpoly, m_trafo, m_bb);
append_svg(m_svg, cpoly.contour);
for (auto &h : cpoly.holes)
append_svg(m_svg, h);
double tol = std::min(m_bb.size().x() / double(m_res.width_px),
m_bb.size().y() / double(m_res.height_px));
ExPolygons cpolys = poly.simplify(tol / 4.);
for (auto &cpoly : cpolys) {
transform(cpoly, m_trafo, m_bb);
for (auto &p : cpoly.contour.points)
p = {std::round(p.x() * m_sc.x()), std::round(p.y() * m_sc.y())};
for (auto &h : cpoly.holes)
for (auto &p : h)
p = {std::round(p.x() * m_sc.x()), std::round(p.y() * m_sc.y())};
append_svg(m_svg, cpoly.contour);
for (auto &h : cpoly.holes)
append_svg(m_svg, h);
}
}
Resolution resolution() const override
{
return {size_t(m_bb.size().x()), size_t(m_bb.size().y())};
}
// Pixel dimension is undefined in this case.
PixelDim pixel_dimensions() const override { return {0, 0}; }
Trafo trafo() const override { return m_trafo; }
Trafo trafo() const override { return m_trafo; }
sla::EncodedRaster encode(sla::RasterEncoder /*encoder*/) const override
{
@ -116,8 +162,11 @@ public:
std::unique_ptr<sla::RasterBase> SL1_SVGArchive::create_raster() const
{
auto w = scaled<size_t>(cfg().display_width.getFloat());
auto h = scaled<size_t>(cfg().display_height.getFloat());
auto w = cfg().display_width.getFloat();
auto h = cfg().display_height.getFloat();
auto res_x = size_t(cfg().display_pixels_x.getInt());
auto res_y = size_t(cfg().display_pixels_y.getInt());
std::array<bool, 2> mirror;
@ -133,13 +182,14 @@ std::unique_ptr<sla::RasterBase> SL1_SVGArchive::create_raster() const
std::swap(w, h);
}
sla::RasterBase::Resolution res{w, h};
BoundingBox svgarea{{0, 0}, {scaled(w), scaled(h)}};
sla::RasterBase::Trafo tr{orientation, mirror};
// Gamma does not really make sense in an svg, right?
// double gamma = cfg().gamma_correction.getFloat();
return std::make_unique<SVGRaster>(res, tr);
return std::make_unique<SVGRaster>(svgarea, sla::Resolution{res_x * 4, res_y * 4}, tr);
}
sla::RasterEncoder SL1_SVGArchive::get_encoder() const

View file

@ -41,7 +41,7 @@ public:
using TValue = typename TColor::value_type;
using TPixel = typename PixelRenderer::pixel_type;
using TRawBuffer = agg::rendering_buffer;
protected:
Resolution m_resolution;
@ -153,8 +153,8 @@ public:
}
Trafo trafo() const override { return m_trafo; }
Resolution resolution() const override { return m_resolution; }
PixelDim pixel_dimensions() const override
Resolution resolution() const { return m_resolution; }
PixelDim pixel_dimensions() const
{
return {SCALING_FACTOR / m_pxdim_scaled.w_mm,
SCALING_FACTOR / m_pxdim_scaled.h_mm};
@ -186,11 +186,15 @@ class RasterGrayscaleAA : public _RasterGrayscaleAA {
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,
RasterGrayscaleAA(const Resolution &res,
const PixelDim &pd,
const RasterBase::Trafo &trafo,
GammaFn &&fn)
: Base(res,
pd,
trafo,
Colors<TColor>::White,
Colors<TColor>::Black,
std::forward<GammaFn>(fn))
{}
@ -208,10 +212,10 @@ public:
class RasterGrayscaleAAGammaPower: public RasterGrayscaleAA {
public:
RasterGrayscaleAAGammaPower(const RasterBase::Resolution &res,
const RasterBase::PixelDim & pd,
const RasterBase::Trafo & trafo,
double gamma = 1.)
RasterGrayscaleAAGammaPower(const Resolution &res,
const PixelDim &pd,
const RasterBase::Trafo &trafo,
double gamma = 1.)
: RasterGrayscaleAA(res, pd, trafo, agg::gamma_power(gamma))
{}
};

View file

@ -68,10 +68,10 @@ EncodedRaster PPMRasterEncoder::operator()(const void *ptr, size_t w, size_t h,
}
std::unique_ptr<RasterBase> create_raster_grayscale_aa(
const RasterBase::Resolution &res,
const RasterBase::PixelDim & pxdim,
double gamma,
const RasterBase::Trafo & tr)
const Resolution &res,
const PixelDim &pxdim,
double gamma,
const RasterBase::Trafo &tr)
{
std::unique_ptr<RasterBase> rst;

View file

@ -31,6 +31,27 @@ public:
const char * extension() const { return m_ext.c_str(); }
};
/// Type that represents a resolution in pixels.
struct Resolution {
size_t width_px = 0;
size_t height_px = 0;
Resolution() = default;
Resolution(size_t w, size_t h) : width_px(w), height_px(h) {}
size_t pixels() const { return width_px * height_px; }
};
/// Types that represents the dimension of a pixel in millimeters.
struct PixelDim {
double w_mm = 1.;
double h_mm = 1.;
PixelDim() = default;
PixelDim(double px_width_mm, double px_height_mm)
: w_mm(px_width_mm), h_mm(px_height_mm)
{}
};
using RasterEncoder =
std::function<EncodedRaster(const void *ptr, size_t w, size_t h, size_t num_components)>;
@ -63,35 +84,14 @@ public:
Point get_center() const { return {center_x, center_y}; }
};
/// Type that represents a resolution in pixels.
struct Resolution {
size_t width_px = 0;
size_t height_px = 0;
Resolution() = default;
Resolution(size_t w, size_t h) : width_px(w), height_px(h) {}
size_t pixels() const { return width_px * height_px; }
};
/// Types that represents the dimension of a pixel in millimeters.
struct PixelDim {
double w_mm = 1.;
double h_mm = 1.;
PixelDim() = default;
PixelDim(double px_width_mm, double px_height_mm)
: w_mm(px_width_mm), h_mm(px_height_mm)
{}
};
virtual ~RasterBase() = default;
/// Draw a polygon with holes.
virtual void draw(const ExPolygon& poly) = 0;
/// Get the resolution of the raster.
virtual Resolution resolution() const = 0;
virtual PixelDim pixel_dimensions() const = 0;
// virtual Resolution resolution() const = 0;
// virtual PixelDim pixel_dimensions() const = 0;
virtual Trafo trafo() const = 0;
virtual EncodedRaster encode(RasterEncoder encoder) const = 0;
@ -109,10 +109,10 @@ std::ostream& operator<<(std::ostream &stream, const EncodedRaster &bytes);
// If gamma is zero, thresholding will be performed which disables AA.
std::unique_ptr<RasterBase> create_raster_grayscale_aa(
const RasterBase::Resolution &res,
const RasterBase::PixelDim & pxdim,
double gamma = 1.0,
const RasterBase::Trafo & tr = {});
const Resolution &res,
const PixelDim &pxdim,
double gamma = 1.0,
const RasterBase::Trafo &tr = {});
}} // namespace Slic3r::sla