From e1b9c13024f82ebcb047b2e181f279f052059de3 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 16 May 2018 18:51:28 +0200 Subject: [PATCH] Rasterizer skeleton --- xs/CMakeLists.txt | 14 +++ xs/src/libslic3r/Print.cpp | 124 +++++++++++++-------- xs/src/libslic3r/Print.hpp | 12 +- xs/src/libslic3r/Rasterizer/Rasterizer.cpp | 40 +++++++ xs/src/libslic3r/Rasterizer/Rasterizer.hpp | 43 +++++++ 5 files changed, 184 insertions(+), 49 deletions(-) create mode 100644 xs/src/libslic3r/Rasterizer/Rasterizer.cpp create mode 100644 xs/src/libslic3r/Rasterizer/Rasterizer.hpp diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 4f44fc7bf..f2c44dde8 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -167,6 +167,7 @@ add_library(libslic3r STATIC ${LIBDIR}/libslic3r/TriangleMesh.hpp # ${LIBDIR}/libslic3r/utils.cpp ${LIBDIR}/libslic3r/Utils.hpp + ) add_library(libslic3r_gui STATIC @@ -331,6 +332,19 @@ add_library(semver STATIC ${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. set(MyTypemap ${CMAKE_CURRENT_BINARY_DIR}/typemap) add_custom_command( diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 8a9665448..05d635afe 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -14,8 +14,11 @@ // For png export of the sliced model #include #include +#include #include +#include + namespace Slic3r { template class PrintState; @@ -1251,30 +1254,54 @@ template class FilePrinter { public: void drawPolygon(const ExPolygon& p); + void finish(); void save(const std::string& path); }; template<> class FilePrinter { wxBitmap bitmap_; - wxMemoryDC dc_; + std::unique_ptr dc_; std::unique_ptr gc_; + double pxw_; + double pxh_; public: - inline FilePrinter(unsigned width, unsigned height): - bitmap_(width, height), - dc_(bitmap_), - gc_(wxGraphicsContext::Create(dc_)) { + inline FilePrinter(unsigned width_px, unsigned height_px, + double width_mm, double height_mm): + bitmap_(width_px, height_px), + dc_(new wxMemoryDC(bitmap_)), + gc_(wxGraphicsContext::Create(*dc_)), + pxw_(width_mm/width_px), + pxh_(height_mm/width_px) + { gc_->SetAntialiasMode(wxANTIALIAS_DEFAULT); } - void drawPolygon(const ExPolygon& p) { - gc_->SetPen( *wxRED_PEN ); + FilePrinter(const FilePrinter& ) = delete; + 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 points; - points.reserve(p.contour.points.size()); - for(auto pp : p.contour.points) points.emplace_back(pp.x, pp.y); + points.reserve(p.points.size()); + + 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()); } + void finish() { + + } + void save(const std::string& path) { if(!bitmap_.SaveFile(path, wxBITMAP_TYPE_PNG)) { 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('/'); #endif - FilePrinter printer(std::forward(args)...); - LayerPtrs layers; 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; }); -// auto printSlice = [&printer](ExPolygon path) { - -// }; - - int layer_id = -1; ExPolygons previous_layer_slices; auto print_bb = bounding_box(); - for(auto lp : layers) { - Layer& l = *lp; - ++layer_id; + std::vector> printers; + printers.reserve(layers.size()); + for(unsigned i = 0; i < layers.size(); i++) + printers.emplace_back(std::forward(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; using Sl = ExPolygons::value_type; @@ -1330,7 +1355,8 @@ void Print::print_to(std::string dirpath, Args...args) ExPolygons current_layer_slices; - // please enable C++14 ... + auto& printer = printers[layer_id]; + std::for_each(l.object()->_shifted_copies.begin(), l.object()->_shifted_copies.end(), [&] (Point d) @@ -1341,35 +1367,39 @@ void Print::print_to(std::string dirpath, Args...args) { slice.translate(d.x, d.y); slice.translate(-print_bb.min.x, -print_bb.min.y); - printer.drawPolygon(slice); - // $print_polygon->($expolygon->contour, 'contour'); - // $print_polygon->($_, 'hole') for @{$expolygon->holes}; + + printer.drawPolygon(slice.contour); + std::for_each(slice.holes.begin(), slice.holes.end(), + [&printer](const Polygon& hole){ + printer.drawPolygon(hole); + }); + current_layer_slices.push_back(slice); }); }); - printer.save(dir + "layer" + std::to_string(layer_id) + ".png"); + printer.finish(); -// layer_id++; -// if ($layer->slice_z == -1) { -// printf $fh qq{ \n}, $layer_id; -// } else { -// printf $fh qq{ \n}, $layer_id, unscale($layer->slice_z); -// } + // layer_id++; + // if ($layer->slice_z == -1) { + // printf $fh qq{ \n}, $layer_id; + // } else { + // printf $fh qq{ \n}, $layer_id, unscale($layer->slice_z); + // } -// my @current_layer_slices = (); -// # sort slices so that the outermost ones come first -// my @slices = sort { $a->contour->contains_point($b->contour->first_point) ? 0 : 1 } @{$layer->slices}; -// foreach my $copy (@{$layer->object->_shifted_copies}) { -// foreach my $slice (@slices) { -// my $expolygon = $slice->clone; -// $expolygon->translate(@$copy); -// $expolygon->translate(-$print_bb->x_min, -$print_bb->y_min); -// $print_polygon->($expolygon->contour, 'contour'); -// $print_polygon->($_, 'hole') for @{$expolygon->holes}; -// push @current_layer_slices, $expolygon; -// } -// } + // my @current_layer_slices = (); + // # sort slices so that the outermost ones come first + // my @slices = sort { $a->contour->contains_point($b->contour->first_point) ? 0 : 1 } @{$layer->slices}; + // foreach my $copy (@{$layer->object->_shifted_copies}) { + // foreach my $slice (@slices) { + // my $expolygon = $slice->clone; + // $expolygon->translate(@$copy); + // $expolygon->translate(-$print_bb->x_min, -$print_bb->y_min); + // $print_polygon->($expolygon->contour, 'contour'); + // $print_polygon->($_, 'hole') for @{$expolygon->holes}; + // push @current_layer_slices, $expolygon; + // } + // } // # generate support material // if ($self->has_support_material && $layer->id > 0) { // 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; } + +// 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) { - print_to(dirpath, 800, 600); +void Print::print_to_png(std::string dirpath, long width_px, long height_px, + Pointf pixel_size_mm) { + print_to(dirpath, 2560, 1440, 700, 400); } } diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index 01561dad3..48cb0898a 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -315,13 +315,17 @@ public: SVG }; - void print_to_png(std::string dirpath); - -private: - template 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: bool invalidate_state_by_config_options(const std::vector &opt_keys); PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume); diff --git a/xs/src/libslic3r/Rasterizer/Rasterizer.cpp b/xs/src/libslic3r/Rasterizer/Rasterizer.cpp new file mode 100644 index 000000000..99d3968b2 --- /dev/null +++ b/xs/src/libslic3r/Rasterizer/Rasterizer.cpp @@ -0,0 +1,40 @@ +#include "Rasterizer.hpp" + +#include + + +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() +{ + +} + +} diff --git a/xs/src/libslic3r/Rasterizer/Rasterizer.hpp b/xs/src/libslic3r/Rasterizer/Rasterizer.hpp new file mode 100644 index 000000000..db4ee02f3 --- /dev/null +++ b/xs/src/libslic3r/Rasterizer/Rasterizer.hpp @@ -0,0 +1,43 @@ +#ifndef RASTERIZER_HPP +#define RASTERIZER_HPP + +#include + +namespace Slic3r { + +class Raster { + class Impl; + std::unique_ptr 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