Rasterizer skeleton
This commit is contained in:
parent
d9ff63c022
commit
e1b9c13024
5 changed files with 184 additions and 49 deletions
|
@ -167,6 +167,7 @@ add_library(libslic3r STATIC
|
||||||
${LIBDIR}/libslic3r/TriangleMesh.hpp
|
${LIBDIR}/libslic3r/TriangleMesh.hpp
|
||||||
# ${LIBDIR}/libslic3r/utils.cpp
|
# ${LIBDIR}/libslic3r/utils.cpp
|
||||||
${LIBDIR}/libslic3r/Utils.hpp
|
${LIBDIR}/libslic3r/Utils.hpp
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(libslic3r_gui STATIC
|
add_library(libslic3r_gui STATIC
|
||||||
|
@ -331,6 +332,19 @@ add_library(semver STATIC
|
||||||
${LIBDIR}/semver/semver.c
|
${LIBDIR}/semver/semver.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
find_package(PNG REQUIRED)
|
||||||
|
|
||||||
|
add_library(rasterizer STATIC
|
||||||
|
${LIBDIR}/libslic3r/Rasterizer/Rasterizer.hpp
|
||||||
|
${LIBDIR}/libslic3r/Rasterizer/Rasterizer.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(rasterizer ${PNG_LIBRARIES})
|
||||||
|
target_include_directories(rasterizer PRIVATE ${PNG_INCLUDE_DIRS})
|
||||||
|
target_compile_definitions(rasterizer PRIVATE ${PNG_DEFINITIONS})
|
||||||
|
target_link_libraries(libslic3r rasterizer)
|
||||||
|
|
||||||
# Generate the Slic3r Perl module (XS) typemap file.
|
# Generate the Slic3r Perl module (XS) typemap file.
|
||||||
set(MyTypemap ${CMAKE_CURRENT_BINARY_DIR}/typemap)
|
set(MyTypemap ${CMAKE_CURRENT_BINARY_DIR}/typemap)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
// For png export of the sliced model
|
// For png export of the sliced model
|
||||||
#include <wx/dcmemory.h>
|
#include <wx/dcmemory.h>
|
||||||
#include <wx/bitmap.h>
|
#include <wx/bitmap.h>
|
||||||
|
#include <wx/image.h>
|
||||||
#include <wx/graphics.h>
|
#include <wx/graphics.h>
|
||||||
|
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
template class PrintState<PrintStep, psCount>;
|
template class PrintState<PrintStep, psCount>;
|
||||||
|
@ -1251,30 +1254,54 @@ template<Print::FilePrinterFormat format>
|
||||||
class FilePrinter {
|
class FilePrinter {
|
||||||
public:
|
public:
|
||||||
void drawPolygon(const ExPolygon& p);
|
void drawPolygon(const ExPolygon& p);
|
||||||
|
void finish();
|
||||||
void save(const std::string& path);
|
void save(const std::string& path);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
class FilePrinter<Print::FilePrinterFormat::PNG> {
|
class FilePrinter<Print::FilePrinterFormat::PNG> {
|
||||||
wxBitmap bitmap_;
|
wxBitmap bitmap_;
|
||||||
wxMemoryDC dc_;
|
std::unique_ptr<wxMemoryDC> dc_;
|
||||||
std::unique_ptr<wxGraphicsContext> gc_;
|
std::unique_ptr<wxGraphicsContext> gc_;
|
||||||
|
double pxw_;
|
||||||
|
double pxh_;
|
||||||
public:
|
public:
|
||||||
inline FilePrinter(unsigned width, unsigned height):
|
inline FilePrinter(unsigned width_px, unsigned height_px,
|
||||||
bitmap_(width, height),
|
double width_mm, double height_mm):
|
||||||
dc_(bitmap_),
|
bitmap_(width_px, height_px),
|
||||||
gc_(wxGraphicsContext::Create(dc_)) {
|
dc_(new wxMemoryDC(bitmap_)),
|
||||||
|
gc_(wxGraphicsContext::Create(*dc_)),
|
||||||
|
pxw_(width_mm/width_px),
|
||||||
|
pxh_(height_mm/width_px)
|
||||||
|
{
|
||||||
gc_->SetAntialiasMode(wxANTIALIAS_DEFAULT);
|
gc_->SetAntialiasMode(wxANTIALIAS_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawPolygon(const ExPolygon& p) {
|
FilePrinter(const FilePrinter& ) = delete;
|
||||||
gc_->SetPen( *wxRED_PEN );
|
FilePrinter(FilePrinter&& m):
|
||||||
|
bitmap_(std::move(m.bitmap_)), dc_(std::move(m.dc_)),
|
||||||
|
gc_(std::move(m.gc_)), pxw_(m.pxw_), pxh_(m.pxh_) {}
|
||||||
|
|
||||||
|
void drawPolygon(const Polygon& p) {
|
||||||
|
|
||||||
|
gc_->SetPen(*wxWHITE_PEN);
|
||||||
std::vector<wxPoint2DDouble> points;
|
std::vector<wxPoint2DDouble> points;
|
||||||
points.reserve(p.contour.points.size());
|
points.reserve(p.points.size());
|
||||||
for(auto pp : p.contour.points) points.emplace_back(pp.x, pp.y);
|
|
||||||
|
for(auto pp : p.points) {
|
||||||
|
points.emplace_back(
|
||||||
|
std::round(pp.x * SCALING_FACTOR/pxw_),
|
||||||
|
std::round(pp.y * SCALING_FACTOR/pxh_)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
gc_->DrawLines(points.size(), points.data());
|
gc_->DrawLines(points.size(), points.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void finish() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void save(const std::string& path) {
|
void save(const std::string& path) {
|
||||||
if(!bitmap_.SaveFile(path, wxBITMAP_TYPE_PNG)) {
|
if(!bitmap_.SaveFile(path, wxBITMAP_TYPE_PNG)) {
|
||||||
std::cout << "fail for " << path << std::endl;
|
std::cout << "fail for " << path << std::endl;
|
||||||
|
@ -1294,8 +1321,6 @@ void Print::print_to(std::string dirpath, Args...args)
|
||||||
if(dir.back() != '/') dir.push_back('/');
|
if(dir.back() != '/') dir.push_back('/');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FilePrinter<format> printer(std::forward<Args>(args)...);
|
|
||||||
|
|
||||||
LayerPtrs layers;
|
LayerPtrs layers;
|
||||||
|
|
||||||
std::for_each(objects.begin(), objects.end(), [&layers](PrintObject *o){
|
std::for_each(objects.begin(), objects.end(), [&layers](PrintObject *o){
|
||||||
|
@ -1308,17 +1333,17 @@ void Print::print_to(std::string dirpath, Args...args)
|
||||||
return l1->print_z < l2->print_z;
|
return l1->print_z < l2->print_z;
|
||||||
});
|
});
|
||||||
|
|
||||||
// auto printSlice = [&printer](ExPolygon path) {
|
|
||||||
|
|
||||||
// };
|
|
||||||
|
|
||||||
int layer_id = -1;
|
|
||||||
ExPolygons previous_layer_slices;
|
ExPolygons previous_layer_slices;
|
||||||
auto print_bb = bounding_box();
|
auto print_bb = bounding_box();
|
||||||
|
|
||||||
for(auto lp : layers) {
|
std::vector<FilePrinter<format>> printers;
|
||||||
Layer& l = *lp;
|
printers.reserve(layers.size());
|
||||||
++layer_id;
|
for(unsigned i = 0; i < layers.size(); i++)
|
||||||
|
printers.emplace_back(std::forward<Args>(args)...);
|
||||||
|
|
||||||
|
#pragma omp parallel for
|
||||||
|
for(int layer_id = 0; layer_id < layers.size(); layer_id++) {
|
||||||
|
Layer& l = *(layers[layer_id]);
|
||||||
|
|
||||||
auto slices = l.slices;
|
auto slices = l.slices;
|
||||||
using Sl = ExPolygons::value_type;
|
using Sl = ExPolygons::value_type;
|
||||||
|
@ -1330,7 +1355,8 @@ void Print::print_to(std::string dirpath, Args...args)
|
||||||
|
|
||||||
ExPolygons current_layer_slices;
|
ExPolygons current_layer_slices;
|
||||||
|
|
||||||
// please enable C++14 ...
|
auto& printer = printers[layer_id];
|
||||||
|
|
||||||
std::for_each(l.object()->_shifted_copies.begin(),
|
std::for_each(l.object()->_shifted_copies.begin(),
|
||||||
l.object()->_shifted_copies.end(),
|
l.object()->_shifted_copies.end(),
|
||||||
[&] (Point d)
|
[&] (Point d)
|
||||||
|
@ -1341,35 +1367,39 @@ void Print::print_to(std::string dirpath, Args...args)
|
||||||
{
|
{
|
||||||
slice.translate(d.x, d.y);
|
slice.translate(d.x, d.y);
|
||||||
slice.translate(-print_bb.min.x, -print_bb.min.y);
|
slice.translate(-print_bb.min.x, -print_bb.min.y);
|
||||||
printer.drawPolygon(slice);
|
|
||||||
// $print_polygon->($expolygon->contour, 'contour');
|
printer.drawPolygon(slice.contour);
|
||||||
// $print_polygon->($_, 'hole') for @{$expolygon->holes};
|
std::for_each(slice.holes.begin(), slice.holes.end(),
|
||||||
|
[&printer](const Polygon& hole){
|
||||||
|
printer.drawPolygon(hole);
|
||||||
|
});
|
||||||
|
|
||||||
current_layer_slices.push_back(slice);
|
current_layer_slices.push_back(slice);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
printer.save(dir + "layer" + std::to_string(layer_id) + ".png");
|
printer.finish();
|
||||||
|
|
||||||
// layer_id++;
|
// layer_id++;
|
||||||
// if ($layer->slice_z == -1) {
|
// if ($layer->slice_z == -1) {
|
||||||
// printf $fh qq{ <g id="layer%d">\n}, $layer_id;
|
// printf $fh qq{ <g id="layer%d">\n}, $layer_id;
|
||||||
// } else {
|
// } else {
|
||||||
// printf $fh qq{ <g id="layer%d" slic3r:z="%s">\n}, $layer_id, unscale($layer->slice_z);
|
// printf $fh qq{ <g id="layer%d" slic3r:z="%s">\n}, $layer_id, unscale($layer->slice_z);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// my @current_layer_slices = ();
|
// my @current_layer_slices = ();
|
||||||
// # sort slices so that the outermost ones come first
|
// # sort slices so that the outermost ones come first
|
||||||
// my @slices = sort { $a->contour->contains_point($b->contour->first_point) ? 0 : 1 } @{$layer->slices};
|
// my @slices = sort { $a->contour->contains_point($b->contour->first_point) ? 0 : 1 } @{$layer->slices};
|
||||||
// foreach my $copy (@{$layer->object->_shifted_copies}) {
|
// foreach my $copy (@{$layer->object->_shifted_copies}) {
|
||||||
// foreach my $slice (@slices) {
|
// foreach my $slice (@slices) {
|
||||||
// my $expolygon = $slice->clone;
|
// my $expolygon = $slice->clone;
|
||||||
// $expolygon->translate(@$copy);
|
// $expolygon->translate(@$copy);
|
||||||
// $expolygon->translate(-$print_bb->x_min, -$print_bb->y_min);
|
// $expolygon->translate(-$print_bb->x_min, -$print_bb->y_min);
|
||||||
// $print_polygon->($expolygon->contour, 'contour');
|
// $print_polygon->($expolygon->contour, 'contour');
|
||||||
// $print_polygon->($_, 'hole') for @{$expolygon->holes};
|
// $print_polygon->($_, 'hole') for @{$expolygon->holes};
|
||||||
// push @current_layer_slices, $expolygon;
|
// push @current_layer_slices, $expolygon;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// # generate support material
|
// # generate support material
|
||||||
// if ($self->has_support_material && $layer->id > 0) {
|
// if ($self->has_support_material && $layer->id > 0) {
|
||||||
// my (@supported_slices, @unsupported_slices) = ();
|
// my (@supported_slices, @unsupported_slices) = ();
|
||||||
|
@ -1398,10 +1428,14 @@ void Print::print_to(std::string dirpath, Args...args)
|
||||||
// @previous_layer_slices = @current_layer_slices;
|
// @previous_layer_slices = @current_layer_slices;
|
||||||
previous_layer_slices = current_layer_slices;
|
previous_layer_slices = current_layer_slices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for(unsigned i = 0; i < printers.size(); i++)
|
||||||
|
// printers[i].save(dir + "layer" + std::to_string(i) + ".png");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Print::print_to_png(std::string dirpath) {
|
void Print::print_to_png(std::string dirpath, long width_px, long height_px,
|
||||||
print_to<FilePrinterFormat::PNG>(dirpath, 800, 600);
|
Pointf pixel_size_mm) {
|
||||||
|
print_to<FilePrinterFormat::PNG>(dirpath, 2560, 1440, 700, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,13 +315,17 @@ public:
|
||||||
SVG
|
SVG
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_to_png(std::string dirpath);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
template<FilePrinterFormat format, class...Args>
|
template<FilePrinterFormat format, class...Args>
|
||||||
void print_to(std::string dirpath, Args...args);
|
void print_to(std::string dirpath, Args...args);
|
||||||
|
|
||||||
|
void print_to_png(std::string dirpath, long width_px, long height_px,
|
||||||
|
Pointf pixel_size_mm);
|
||||||
|
|
||||||
|
void print_to_png(std::string dirpath) {
|
||||||
|
// Where should this be specified?
|
||||||
|
print_to_png(dirpath, 2560, 1440, Pointf{2560/700.0, 2560/400.0});
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
|
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
|
||||||
PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
|
PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
|
||||||
|
|
40
xs/src/libslic3r/Rasterizer/Rasterizer.cpp
Normal file
40
xs/src/libslic3r/Rasterizer/Rasterizer.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "Rasterizer.hpp"
|
||||||
|
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Raster::Impl {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Raster::Raster(const Raster::Resolution &r, const Raster::PixelDim &pd):
|
||||||
|
impl_(new Impl), resolution_(r), pxdim_(pd) {}
|
||||||
|
|
||||||
|
Raster::~Raster() {}
|
||||||
|
|
||||||
|
Raster::Raster(const Raster &cpy): resolution_(cpy.resolution_),
|
||||||
|
pxdim_(cpy.pxdim_) {
|
||||||
|
*impl_ = *(cpy.impl_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Raster::Raster(Raster &&m):
|
||||||
|
impl_(std::move(m.impl_)), resolution_(m.resolution_), pxdim_(m.pxdim_) {}
|
||||||
|
|
||||||
|
void Raster::clear()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Raster::draw(const Polygon &poly)
|
||||||
|
{
|
||||||
|
png_image ifo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Raster::finish()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
xs/src/libslic3r/Rasterizer/Rasterizer.hpp
Normal file
43
xs/src/libslic3r/Rasterizer/Rasterizer.hpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef RASTERIZER_HPP
|
||||||
|
#define RASTERIZER_HPP
|
||||||
|
|
||||||
|
#include <Polygon.hpp>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Raster {
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> impl_;
|
||||||
|
public:
|
||||||
|
|
||||||
|
struct Resolution {
|
||||||
|
unsigned width_px;
|
||||||
|
unsigned height_px;
|
||||||
|
inline Resolution(unsigned w, unsigned h): width_px(w), height_px(h) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PixelDim {
|
||||||
|
double w_mm;
|
||||||
|
double h_mm;
|
||||||
|
inline PixelDim(double px_width_mm, double px_height_mm ):
|
||||||
|
w_mm(px_width_mm), h_mm(px_height_mm) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline explicit Raster(const Resolution& r, const PixelDim& pd );
|
||||||
|
~Raster();
|
||||||
|
Raster(const Raster& cpy);
|
||||||
|
Raster(Raster&& m);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
void draw(const Polygon& poly);
|
||||||
|
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Resolution resolution_;
|
||||||
|
PixelDim pxdim_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // RASTERIZER_HPP
|
Loading…
Reference in a new issue