From 221a4836fd53baffd55636548223a88e7a62a31f Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 26 Mar 2019 14:06:40 +0100 Subject: [PATCH] Manual unification of print polygons. With clipper not with the agg rasterizer, because they can be reused for the statistics. --- src/libslic3r/SLAPrint.cpp | 128 ++++++++++++++++++++++++++++--------- src/libslic3r/SLAPrint.hpp | 23 +++++-- 2 files changed, 115 insertions(+), 36 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 2553fae85..0a2681866 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -934,11 +934,11 @@ void SLAPrint::process() m_printer_input.end(), PrintLayer(lvlid)); - if(it == m_printer_input.end() || it->level != lvlid) + if(it == m_printer_input.end() || it->level() != lvlid) it = m_printer_input.insert(it, PrintLayer(lvlid)); - it->slices.emplace_back(std::cref(slicerecord)); + it->add(slicerecord); } } @@ -990,43 +990,53 @@ void SLAPrint::process() { if(canceled()) return; - PrintLayer& lrange = m_printer_input[level_id]; + PrintLayer& printlayer = m_printer_input[level_id]; // Switch to the appropriate layer in the printer printer.begin_layer(level_id); - for(const SliceRecord& slrecord : lrange.slices) - { // for all layers in the current level + auto orientation = flpXY? SLADisplayOrientation::sladoPortrait : + SLADisplayOrientation::sladoLandscape; - if(canceled()) break; + // Get the transformed and properly oriented slice + const ExPolygons& slice = printlayer.transformed_slice(orientation); - // get the layer reference - const ExPolygons& objslice = slrecord.get_slice(soModel); - const ExPolygons& supslice = slrecord.get_slice(soSupport); - const SLAPrintObject *po = slrecord.print_obj(); - assert(po != nullptr); + // Now draw all the polygons with the printer... + for(const ExPolygon& p : slice) printer.draw_polygon(p, level_id); - // Draw all the polygons in the slice to the actual layer. - for(const SLAPrintObject::Instance& tr : po->instances()) { - for(ExPolygon poly : objslice) { - // The order is important here: - // apply rotation before translation... - poly.rotate(double(tr.rotation)); - poly.translate(tr.shift(X), tr.shift(Y)); - if(flpXY) swapXY(poly); - printer.draw_polygon(poly, level_id); - } - for(ExPolygon poly : supslice) { - // The order is important here: - // apply rotation before translation... - poly.rotate(double(tr.rotation)); - poly.translate(tr.shift(X), tr.shift(Y)); - if(flpXY) swapXY(poly); - printer.draw_polygon(poly, level_id); - } - } - } +// for(const SliceRecord& slrecord : printlayer.m_slices) +// { // for all layers in the current level + +// if(canceled()) break; + +// // get the layer reference +// const ExPolygons& objslice = slrecord.get_slice(soModel); +// const ExPolygons& supslice = slrecord.get_slice(soSupport); +// const SLAPrintObject *po = slrecord.print_obj(); +// assert(po != nullptr); + +// // Draw all the polygons in the slice to the actual layer. +// for(const SLAPrintObject::Instance& tr : po->instances()) { +// for(ExPolygon poly : objslice) { +// // The order is important here: +// // apply rotation before translation... +// poly.rotate(double(tr.rotation)); +// poly.translate(tr.shift(X), tr.shift(Y)); +// if(flpXY) swapXY(poly); +// printer.draw_polygon(poly, level_id); +// } + +// for(ExPolygon poly : supslice) { +// // The order is important here: +// // apply rotation before translation... +// poly.rotate(double(tr.rotation)); +// poly.translate(tr.shift(X), tr.shift(Y)); +// if(flpXY) swapXY(poly); +// printer.draw_polygon(poly, level_id); +// } +// } +// } // Finish the layer for later saving it. printer.finish_layer(level_id); @@ -1662,4 +1672,60 @@ std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in) return final_path; } +const ExPolygons &SLAPrint::PrintLayer::transformed_slice(SLADisplayOrientation o) const +{ + if (! m_trcache.empty()) return m_trcache; + + size_t cap = 0; + for (const SliceRecord& sr : m_slices) { + if(sr.print_obj()) { + size_t insts = sr.print_obj()->instances().size(); + cap += insts * (sr.get_slice(soModel).size() + + sr.get_slice(soSupport).size()); + } + } + + Polygons allpolys; + allpolys.reserve(cap); + + for (const SliceRecord& sr : m_slices) { + const ExPolygons& objsl = sr.get_slice(soModel); + const ExPolygons& supsl = sr.get_slice(soSupport); + + if (! sr.print_obj()) continue; + + for(const SLAPrintObject::Instance& tr : sr.print_obj()->instances()) + { + Polygons polys; + size_t polyscap = 0; + for(const ExPolygon &p : objsl) polyscap += p.holes.size() + 1; + for(const ExPolygon &p : supsl) polyscap += p.holes.size() + 1; + polys.reserve(polyscap); + + for(const ExPolygon &p : objsl) { + polys.emplace_back(p.contour); + for(auto& h : p.holes) polys.emplace_back(h); + } + + for(const ExPolygon &p : supsl) { + polys.emplace_back(p.contour); + for(auto& h : p.holes) polys.emplace_back(h); + } + + for(Polygon& poly : polys) { + poly.rotate(double(tr.rotation)); + poly.translate(tr.shift(X), tr.shift(Y)); + if(o == SLADisplayOrientation::sladoPortrait) + for(auto& p : poly.points) std::swap(p(X), p(Y)); + + allpolys.emplace_back(std::move(poly)); + } + } + } + + m_trcache = union_ex(allpolys); + + return m_trcache; +} + } // namespace Slic3r diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index d52aa0e8a..9fe6d4cc4 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -329,18 +329,31 @@ public: // An aggregation of SliceRecord-s from all the print objects for each // occupied layer. Slice record levels dont have to match exactly. // They are unified if the level difference is within +/- SCALED_EPSILON - struct PrintLayer { - coord_t level; + class PrintLayer { + coord_t m_level; // The collection of slice records for the current level. - std::vector> slices; + std::vector> m_slices; - explicit PrintLayer(coord_t lvl) : level(lvl) {} + // No need for concurrency handling with CachedObject (hopefully) + mutable ExPolygons m_trcache; + + public: + + explicit PrintLayer(coord_t lvl) : m_level(lvl) {} // for being sorted in their container (see m_printer_input) bool operator<(const PrintLayer& other) const { - return level < other.level; + return m_level < other.m_level; } + + void add(const SliceRecord& sr) { + m_trcache.clear(); m_slices.emplace_back(sr); + } + + coord_t level() const { return m_level; } + + const ExPolygons& transformed_slice(SLADisplayOrientation o) const; }; SLAPrint(): m_stepmask(slapsCount, true) {}