diff --git a/src/libslic3r/PrintExport.hpp b/src/libslic3r/PrintExport.hpp index 60bc7dbe6..0a9a54187 100644 --- a/src/libslic3r/PrintExport.hpp +++ b/src/libslic3r/PrintExport.hpp @@ -218,8 +218,10 @@ public: std::sprintf(lyrnum, "%.5d", i); auto zfilename = project + lyrnum + ".png"; writer.next_entry(zfilename); - writer << m_layers_rst[i].second.rdbuf(); - m_layers_rst[i].second.str(""); + writer << m_layers_rst[i].second.str(); + // writer << m_layers_rst[i].second.rdbuf(); + // we can keep the date for later calls of this method + //m_layers_rst[i].second.str(""); } } @@ -250,146 +252,6 @@ public: } }; -//// Let's shadow this eigen interface -//inline coord_t px(const Point& p) { return p(0); } -//inline coord_t py(const Point& p) { return p(1); } -//inline coordf_t px(const Vec2d& p) { return p(0); } -//inline coordf_t py(const Vec2d& p) { return p(1); } - -//template -//void print_to(Print& print, -// std::string dirpath, -// double width_mm, -// double height_mm, -// Args&&...args) -//{ - -// std::string& dir = dirpath; - -// // This map will hold the layers sorted by z coordinate. Layers on the -// // same height (from different objects) will be mapped to the same key and -// // rasterized to the same image. -// std::map layers; - -// auto& objects = print.objects(); - -// // Merge the sliced layers with the support layers -// std::for_each(objects.cbegin(), objects.cend(), -// [&layers](const PrintObject *o) -// { -// for(const auto l : o->layers()) { -// auto& lyrs = layers[static_cast(scale_(l->print_z))]; -// lyrs.push_back(l); -// } - -// for(const auto l : o->support_layers()) { -// auto& lyrs = layers[static_cast(scale_(l->print_z))]; -// lyrs.push_back(l); -// } -// }); - -// auto print_bb = print.bounding_box(); -// Vec2d punsc = unscale(print_bb.size()); - -// // If the print does not fit into the print area we should cry about it. -// if(px(punsc) > width_mm || py(punsc) > height_mm) { -// BOOST_LOG_TRIVIAL(warning) << "Warning: Print will not fit!" << "\n" -// << "Width needed: " << px(punsc) << "\n" -// << "Height needed: " << py(punsc) << "\n"; -// } - -// // Offset for centering the print onto the print area -// auto cx = scale_(width_mm)/2 - (px(print_bb.center()) - px(print_bb.min)); -// auto cy = scale_(height_mm)/2 - (py(print_bb.center()) - py(print_bb.min)); - -// // Create the actual printer, forward any additional arguments to it. -// FilePrinter printer(width_mm, height_mm, -// std::forward(args)...); - -// printer.print_config(print); - -// printer.layers(layers.size()); // Allocate space for all the layers - -// int st_prev = 0; -// const std::string jobdesc = "Rasterizing and compressing sliced layers"; -// tbb::spin_mutex m; - -// std::vector keys; -// keys.reserve(layers.size()); -// for(auto& e : layers) keys.push_back(e.first); - -// print.set_status(0, jobdesc); - -// // Method that prints one layer -// auto process_layer = [&layers, &keys, &printer, &st_prev, &m, -// &jobdesc, print_bb, dir, cx, cy, &print] -// (unsigned layer_id) -// { -// LayerPtrs lrange = layers[keys[layer_id]]; - -// printer.begin_layer(layer_id); // Switch to the appropriate layer - -// for(Layer *lp : lrange) { -// Layer& l = *lp; - -// ExPolygonCollection slices = l.slices; // Copy the layer slices - -// // Sort the polygons in the layer -// std::stable_sort(slices.expolygons.begin(), slices.expolygons.end(), -// [](const ExPolygon& a, const ExPolygon& b) { -// return a.contour.contains(b.contour.first_point()) ? false : -// true; -// }); - -// // Draw all the polygons in the slice to the actual layer. -// for (const Point &d : l.object()->copies()) -// for (ExPolygon slice : slices.expolygons) { -// slice.translate(px(d), py(d)); -// slice.translate(-px(print_bb.min) + cx, -// -py(print_bb.min) + cy); - -// printer.draw_polygon(slice, layer_id); -// } - -// /*if(print.has_support_material() && layer_id > 0) { -// BOOST_LOG_TRIVIAL(warning) << "support material for layer " -// << layer_id -// << " defined but export is " -// "not yet implemented."; - -// }*/ - -// } - -// printer.finish_layer(layer_id); // Finish the layer for later saving it. - -// auto st = static_cast(layer_id*80.0/layers.size()); -// m.lock(); -// if( st - st_prev > 10) { -// print.set_status(st, jobdesc); -// st_prev = st; -// } -// m.unlock(); - -// // printer.saveLayer(layer_id, dir); We could save the layer immediately -// }; - -// // Print all the layers in parallel -// tbb::parallel_for(0, -// layers.size(), -// process_layer); - -// // Sequential version (for testing) -// // for(unsigned l = 0; l < layers.size(); ++l) process_layer(l); - -//// print.set_status(100, jobdesc); - -// // Save the print into the file system. -// print.set_status(90, "Writing layers to disk"); -// printer.save(dir); -// print.set_status(100, "Writing layers completed"); -//} - } #endif // PRINTEXPORT_HPP diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index c4abc583e..6721decf9 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -28,6 +28,7 @@ public: sla::PointSet support_points; // all the support points (manual/auto) SupportTreePtr support_tree_ptr; // the supports SlicedSupports support_slices; // sliced supports + std::vector level_ids; }; namespace { @@ -567,11 +568,10 @@ void SLAPrint::process() } }; - auto& levels = m_printer_input; - // We have the layer polygon collection but we need to unite them into // an index where the key is the height level in discrete levels (clipper) - auto index_slices = [this, ilh, ilhd, &levels](SLAPrintObject& po) { + auto index_slices = [this, ilh, ilhd](SLAPrintObject& po) { + po.m_slice_index.clear(); auto sih = LevelID(scale_(ilh)); // For all print objects, go through its initial layers and place them @@ -591,7 +591,7 @@ void SLAPrint::process() // It is important that the next levels match the levels in // model_slice method. Only difference is that here it works with // scaled coordinates - std::vector levelids; + auto& levelids = po.m_level_ids; levelids.clear(); if(sminZ >= smodelgnd) levelids.emplace_back(sminZ); for(LevelID h = sminZ + sih; h < smaxZ; h += slh) if(h >= smodelgnd) levelids.emplace_back(h); @@ -615,11 +615,9 @@ void SLAPrint::process() // shortcut for empty index into the slice vectors static const auto EMPTY_SLICE = SLAPrintObject::SliceRecord::NONE; - + for(int i = 0; i < oslices.size(); ++i) { LevelID h = levelids[i]; - auto& lyrs = levels[h]; // this initializes a new record - lyrs.emplace_back(oslices[i], po.m_instances); float fh = float(double(h) * SCALING_FACTOR); @@ -632,13 +630,14 @@ void SLAPrint::process() if(po.m_supportdata) { // deal with the support slices if present auto& sslices = po.m_supportdata->support_slices; + po.m_supportdata->level_ids.clear(); + po.m_supportdata->level_ids.reserve(sslices.size()); + for(int i = 0; i < sslices.size(); ++i) { int a = i == 0 ? 0 : 1; int b = i == 0 ? 0 : i - 1; LevelID h = sminZ + a * sih + b * slh; - - auto& lyrs = levels[h]; - lyrs.emplace_back(sslices[i], po.m_instances); + po.m_supportdata->level_ids.emplace_back(h); float fh = float(double(h) * SCALING_FACTOR); @@ -649,10 +648,40 @@ void SLAPrint::process() } }; + auto& levels = m_printer_input; + // Rasterizing the model objects, and their supports auto rasterize = [this, ilh, ilhd, max_objstatus, &levels]() { if(canceled()) return; + // clear the rasterizer input + m_printer_input.clear(); + + for(SLAPrintObject * o : m_objects) { + auto& po = *o; + SlicedModel & oslices = po.m_model_slices; + + // We need to adjust the min Z level of the slices to be zero + LevelID smfirst = po.m_supportdata? po.m_supportdata->level_ids.front() : 0; + LevelID mfirst = po.m_level_ids.front(); + LevelID gndlvl = -(std::min(smfirst, mfirst)); + + // now merge this object's support and object slices with the rest + // of the print object slices + + for(int i = 0; i < oslices.size(); ++i) { + auto& lyrs = levels[gndlvl + po.m_level_ids[i]]; + lyrs.emplace_back(oslices[i], po.m_instances); + } + + if(!po.m_supportdata) continue; + auto& sslices = po.m_supportdata->support_slices; + for(int i = 0; i < sslices.size(); ++i) { + auto& lyrs = levels[gndlvl + po.m_supportdata->level_ids[i]]; + lyrs.emplace_back(sslices[i], po.m_instances); + } + } + // collect all the keys std::vector keys; keys.reserve(levels.size()); for(auto& e : levels) keys.emplace_back(e.first); @@ -704,8 +733,10 @@ void SLAPrint::process() // Draw all the polygons in the slice to the actual layer. for(auto& cp : copies) { for(ExPolygon slice : sl) { - slice.translate(cp.shift(X), cp.shift(Y)); + // The order is important here: + // apply rotation before translation... slice.rotate(cp.rotation); + slice.translate(cp.shift(X), cp.shift(Y)); printer.draw_polygon(slice, level_id); } } diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 2d6eb49c2..dbf3a49c7 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -33,6 +33,10 @@ class GLCanvas; using _SLAPrintObjectBase = PrintObjectBaseWithState; +// Layers according to quantized height levels. This will be consumed by +// the printer (rasterizer) in the SLAPrint class. +using LevelID = long long; + class SLAPrintObject : public _SLAPrintObjectBase { private: // Prevents erroneous use by other classes. @@ -93,7 +97,6 @@ public: // to the z coordinate of the object coordinate system. struct SliceRecord { using Key = float; -// inline static float scale_back(Key h) { return float(h * SCALING_FACTOR); } using Idx = size_t; static const Idx NONE = Idx(-1); // this will be the max limit of size_t @@ -145,6 +148,7 @@ private: std::vector m_stepmask; std::vector m_model_slices; SliceIndex m_slice_index; + std::vector m_level_ids; // Caching the transformed (m_trafo) raw mesh of the object mutable CachedObject m_transformed_rmesh; @@ -214,10 +218,6 @@ private: lref(std::cref(lyr)), copies(std::cref(cp)) {} }; - // Layers according to quantized height levels. This will be consumed by - // the printer (rasterizer) in the SLAPrint class. - using LevelID = long long; - // One level may contain multiple slices from multiple objects and their // supports using LayerRefs = std::vector; diff --git a/src/slic3r/GUI/ProgressStatusBar.cpp b/src/slic3r/GUI/ProgressStatusBar.cpp index 93ab3feb9..8cdb53c9d 100644 --- a/src/slic3r/GUI/ProgressStatusBar.cpp +++ b/src/slic3r/GUI/ProgressStatusBar.cpp @@ -71,14 +71,12 @@ int ProgressStatusBar::get_progress() const void ProgressStatusBar::set_progress(int val) { if(!m_prog->IsShown()) show_progress(true); + if(val < 0) return; if(val == m_prog->GetRange()) { m_prog->SetValue(0); show_progress(false); } - else if(val < 0) { - m_prog->Pulse(); - } else { m_prog->SetValue(val); } diff --git a/src/slic3r/GUI/ProgressStatusBar.hpp b/src/slic3r/GUI/ProgressStatusBar.hpp index f33a70ed3..225b0331e 100644 --- a/src/slic3r/GUI/ProgressStatusBar.hpp +++ b/src/slic3r/GUI/ProgressStatusBar.hpp @@ -35,6 +35,8 @@ public: ~ProgressStatusBar(); int get_progress() const; + // if the argument is less than 0 it shows the last state or + // pulses if no state was set before. void set_progress(int); int get_range() const; void set_range(int = 100);