diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index df9446cf5..003ed5af4 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -43,7 +43,7 @@ class FilePrinter { public: // 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 Polygon& p, unsigned lyr); // Tell the printer how many layers should it consider. void layers(unsigned layernum); @@ -209,7 +209,7 @@ public: inline void layers(unsigned cnt) { if(cnt > 0) m_layers_rst.resize(cnt); } inline unsigned layers() const { return unsigned(m_layers_rst.size()); } - inline void draw_polygon(const ExPolygon& p, unsigned lyr) { + inline void draw_polygon(const Polygon& p, unsigned lyr) { assert(lyr < m_layers_rst.size()); m_layers_rst[lyr].first.draw(p); } diff --git a/src/libslic3r/Rasterizer/Rasterizer.cpp b/src/libslic3r/Rasterizer/Rasterizer.cpp index 5961d9b78..3e42e37d8 100644 --- a/src/libslic3r/Rasterizer/Rasterizer.cpp +++ b/src/libslic3r/Rasterizer/Rasterizer.cpp @@ -1,5 +1,5 @@ #include "Rasterizer.hpp" -#include +#include #include @@ -72,22 +72,16 @@ public: clear(); } - void draw(const ExPolygon &poly) { + void draw(const Polygon &poly) { agg::rasterizer_scanline_aa<> ras; agg::scanline_p8 scanlines; - auto&& path = to_path(poly.contour); + auto&& path = to_path(poly); if(m_o == Origin::TOP_LEFT) flipy(path); ras.add_path(path); - for(auto h : poly.holes) { - auto&& holepath = to_path(h); - if(m_o == Origin::TOP_LEFT) flipy(holepath); - ras.add_path(holepath); - } - agg::render_scanlines(ras, scanlines, m_renderer); } @@ -169,7 +163,7 @@ void Raster::clear() m_impl->clear(); } -void Raster::draw(const ExPolygon &poly) +void Raster::draw(const Polygon &poly) { assert(m_impl); m_impl->draw(poly); diff --git a/src/libslic3r/Rasterizer/Rasterizer.hpp b/src/libslic3r/Rasterizer/Rasterizer.hpp index 06d5b88c6..05ffd99b3 100644 --- a/src/libslic3r/Rasterizer/Rasterizer.hpp +++ b/src/libslic3r/Rasterizer/Rasterizer.hpp @@ -6,7 +6,7 @@ namespace Slic3r { -class ExPolygon; +class Polygon; /** * @brief Raster captures an anti-aliased monochrome canvas where vectorial @@ -83,7 +83,7 @@ public: void clear(); /// Draw a polygon with holes. - void draw(const ExPolygon& poly); + void draw(const Polygon& poly); /// Save the raster on the specified stream. void save(std::ostream& stream, Compression comp = Compression::RAW); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index ee24cf3ec..af3f20a59 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -915,19 +915,7 @@ void SLAPrint::process() report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); }; - auto fillstats = [this]() { - - m_print_statistics.clear(); - - // Fill statistics - fill_statistics(); - - report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); - }; - - // Rasterizing the model objects, and their supports - auto rasterize = [this, max_objstatus, ilhs]() { - if(canceled()) return; + auto fillstats = [this, ilhs]() { // clear the rasterizer input m_printer_input.clear(); @@ -962,6 +950,18 @@ void SLAPrint::process() } } + m_print_statistics.clear(); + + // Fill statistics + fill_statistics(); + + report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); + }; + + // Rasterizing the model objects, and their supports + auto rasterize = [this, max_objstatus]() { + if(canceled()) return; + // collect all the keys // If the raster has vertical orientation, we will flip the coordinates @@ -1015,28 +1015,30 @@ void SLAPrint::process() // Switch to the appropriate layer in the printer printer.begin_layer(level_id); - using Instance = SLAPrintObject::Instance; - - auto draw = - [&printer, flpXY, level_id](ExPolygon& poly, const Instance& tr) - { - poly.rotate(double(tr.rotation)); - poly.translate(tr.shift(X), tr.shift(Y)); - if(flpXY) swapXY(poly); + for(const Polygon& poly : printlayer.transformed_slices()) printer.draw_polygon(poly, level_id); - }; - for(const SliceRecord& sr : printlayer.slices()) { - if(! sr.print_obj()) continue; - for(const Instance& inst : sr.print_obj()->instances()) { - ExPolygons objsl = sr.get_slice(soModel); - for(ExPolygon& poly : objsl) draw(poly, inst); +// auto draw = +// [&printer, flpXY, level_id](Polygon& poly, const Instance& tr) +// { +// poly.rotate(double(tr.rotation)); +// poly.translate(tr.shift(X), tr.shift(Y)); +// if(flpXY) for(auto& p : poly.points) std::swap(p(X), p(Y)); +// printer.draw_polygon(poly, level_id); +// }; - ExPolygons supsl = sr.get_slice(soSupport); - for(ExPolygon& poly : supsl) draw(poly, inst); - } - } +// for(const SliceRecord& sr : printlayer.slices()) { +// if(! sr.print_obj()) continue; + +// for(const Instance& inst : sr.print_obj()->instances()) { +// ExPolygons objsl = sr.get_slice(soModel); +// for(ExPolygon& poly : objsl) draw(poly, inst); + +// ExPolygons supsl = sr.get_slice(soSupport); +// for(ExPolygon& poly : supsl) draw(poly, inst); +// } +// } // Finish the layer for later saving it. printer.finish_layer(level_id); @@ -1217,9 +1219,6 @@ bool SLAPrint::invalidate_state_by_config_options(const std::vector& instances) { + auto get_all_polygons = + [flpXY](const ExPolygons& input_polygons, + const std::vector& instances) + { const size_t inst_cnt = instances.size(); size_t polygon_cnt = 0; @@ -1249,6 +1255,7 @@ void SLAPrint::fill_statistics() ExPolygon tmp = polygon; tmp.rotate(double(instances[i].rotation)); tmp.translate(instances[i].shift.x(), instances[i].shift.y()); + if(flpXY) swapXY(tmp); polygons_append(polygons, to_polygons(std::move(tmp))); } } @@ -1263,55 +1270,30 @@ void SLAPrint::fill_statistics() size_t slow_layers = 0; size_t fast_layers = 0; - // find highest object - // Which is a better bet? To compare by max_z or by number of layers in the index? - // float max_z = 0.; - size_t max_layers_cnt = 0; - size_t highest_obj_idx = 0; - for (SLAPrintObject *&po : m_objects) { - auto& slice_index = po->get_slice_index(); - if (! slice_index.empty()) { - // float z = (-- slice_index.end())->slice_level(); - size_t cnt = slice_index.size(); - //if (z > max_z) { - if (cnt > max_layers_cnt) { - max_layers_cnt = cnt; - // max_z = z; - highest_obj_idx = &po - &m_objects.front(); - } - } - } - - const SLAPrintObject * highest_obj = m_objects[highest_obj_idx]; - auto& highest_obj_slice_index = highest_obj->get_slice_index(); - const double delta_fade_time = (init_exp_time - exp_time) / (fade_layers_cnt + 1); double fade_layer_time = init_exp_time; int sliced_layer_cnt = 0; - for (const SliceRecord& layer : highest_obj_slice_index) + for (PrintLayer& layer : m_printer_input) { - const auto l_height = double(layer.layer_height()); + if(layer.slices().empty()) continue; + + // Layer height should match for all object slices for a given level. + const auto l_height = double(layer.slices().front().get().layer_height()); // Calculation of the consumed material Polygons model_polygons; Polygons supports_polygons; - for (SLAPrintObject * po : m_objects) - { - const SliceRecord *record = nullptr; - { - const SliceRecord& slr = po->closest_slice_to_slice_level(layer.slice_level(), float(EPSILON)); - if (!slr.is_valid()) continue; - record = &slr; - } + for(const SliceRecord& record : layer.slices()) { + const SLAPrintObject *po = record.print_obj(); - const ExPolygons &modelslices = record->get_slice(soModel); + const ExPolygons &modelslices = record.get_slice(soModel); if (!modelslices.empty()) append(model_polygons, get_all_polygons(modelslices, po->instances())); - const ExPolygons &supportslices = record->get_slice(soSupport); + const ExPolygons &supportslices = record.get_slice(soSupport); if (!supportslices.empty()) append(supports_polygons, get_all_polygons(supportslices, po->instances())); } @@ -1321,7 +1303,7 @@ void SLAPrint::fill_statistics() for (const Polygon& polygon : model_polygons) layer_model_area += polygon.area(); - if (layer_model_area != 0) + if (layer_model_area < 0 || layer_model_area > 0) models_volume += layer_model_area * l_height; if (!supports_polygons.empty() && !model_polygons.empty()) @@ -1330,9 +1312,13 @@ void SLAPrint::fill_statistics() for (const Polygon& polygon : supports_polygons) layer_support_area += polygon.area(); - if (layer_support_area != 0) + if (layer_support_area < 0 || layer_model_area > 0) supports_volume += layer_support_area * l_height; + // Here we can save the expensively calculated polygons for printing + append(model_polygons, supports_polygons); + layer.transformed_slices(union_(model_polygons)); + // Calculation of the slow and fast layers to the future controlling those values on FW const bool is_fast_layer = (layer_model_area + layer_support_area) <= display_area*area_fill; @@ -1365,7 +1351,7 @@ void SLAPrint::fill_statistics() // Estimated printing time // A layers count o the highest object - if (max_layers_cnt == 0) + if (m_printer_input.size() == 0) m_print_statistics.estimated_print_time = "N/A"; else m_print_statistics.estimated_print_time = get_time_dhms(float(estim_time)); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index afdfab415..9b6c89687 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -127,7 +127,7 @@ public: bool is_valid() const { return ! std::isnan(m_slice_z); } - const SLAPrintObject* print_obj() const { return m_po; } + const SLAPrintObject* print_obj() const { assert(m_po); return m_po; } // Methods for setting the indices into the slice vectors. void set_model_slice_idx(const SLAPrintObject &po, size_t id) { @@ -328,6 +328,7 @@ class SLAPrint : public PrintBaseWithState private: // Prevents erroneous use by other classes. typedef PrintBaseWithState Inherited; + void fill_statistics(); public: // An aggregation of SliceRecord-s from all the print objects for each @@ -339,6 +340,14 @@ public: // The collection of slice records for the current level. std::vector> m_slices; + Polygons m_transformed_slices; + + template void transformed_slices(Container&& c) { + m_transformed_slices = std::forward(c); + } + + friend void SLAPrint::fill_statistics(); + public: explicit PrintLayer(coord_t lvl) : m_level(lvl) {} @@ -353,6 +362,10 @@ public: coord_t level() const { return m_level; } auto slices() const -> const decltype (m_slices)& { return m_slices; } + + const Polygons& transformed_slices() const { + return m_transformed_slices; + } }; SLAPrint(): m_stepmask(slapsCount, true) {} @@ -399,8 +412,6 @@ private: // Invalidate steps based on a set of parameters changed. bool invalidate_state_by_config_options(const std::vector &opt_keys); - void fill_statistics(); - SLAPrintConfig m_print_config; SLAPrinterConfig m_printer_config; SLAMaterialConfig m_material_config;