Fix for empty or broken png output.
Fix for instance transformation order error and state invalidation issues with rasterization.
This commit is contained in:
parent
bf94751a94
commit
55d62b8295
@ -218,8 +218,10 @@ public:
|
|||||||
std::sprintf(lyrnum, "%.5d", i);
|
std::sprintf(lyrnum, "%.5d", i);
|
||||||
auto zfilename = project + lyrnum + ".png";
|
auto zfilename = project + lyrnum + ".png";
|
||||||
writer.next_entry(zfilename);
|
writer.next_entry(zfilename);
|
||||||
writer << m_layers_rst[i].second.rdbuf();
|
writer << m_layers_rst[i].second.str();
|
||||||
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<FilePrinterFormat format, class LayerFormat, class...Args>
|
|
||||||
//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<long long, LayerPtrs> 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<long long>(scale_(l->print_z))];
|
|
||||||
// lyrs.push_back(l);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for(const auto l : o->support_layers()) {
|
|
||||||
// auto& lyrs = layers[static_cast<long long>(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<format, LayerFormat> printer(width_mm, height_mm,
|
|
||||||
// std::forward<Args>(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<long long> 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<int>(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<size_t, decltype(process_layer)>(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
|
#endif // PRINTEXPORT_HPP
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
sla::PointSet support_points; // all the support points (manual/auto)
|
sla::PointSet support_points; // all the support points (manual/auto)
|
||||||
SupportTreePtr support_tree_ptr; // the supports
|
SupportTreePtr support_tree_ptr; // the supports
|
||||||
SlicedSupports support_slices; // sliced supports
|
SlicedSupports support_slices; // sliced supports
|
||||||
|
std::vector<LevelID> level_ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
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
|
// 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)
|
// 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));
|
auto sih = LevelID(scale_(ilh));
|
||||||
|
|
||||||
// For all print objects, go through its initial layers and place them
|
// 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
|
// It is important that the next levels match the levels in
|
||||||
// model_slice method. Only difference is that here it works with
|
// model_slice method. Only difference is that here it works with
|
||||||
// scaled coordinates
|
// scaled coordinates
|
||||||
std::vector<LevelID> levelids;
|
auto& levelids = po.m_level_ids; levelids.clear();
|
||||||
if(sminZ >= smodelgnd) levelids.emplace_back(sminZ);
|
if(sminZ >= smodelgnd) levelids.emplace_back(sminZ);
|
||||||
for(LevelID h = sminZ + sih; h < smaxZ; h += slh)
|
for(LevelID h = sminZ + sih; h < smaxZ; h += slh)
|
||||||
if(h >= smodelgnd) levelids.emplace_back(h);
|
if(h >= smodelgnd) levelids.emplace_back(h);
|
||||||
@ -615,11 +615,9 @@ void SLAPrint::process()
|
|||||||
|
|
||||||
// shortcut for empty index into the slice vectors
|
// shortcut for empty index into the slice vectors
|
||||||
static const auto EMPTY_SLICE = SLAPrintObject::SliceRecord::NONE;
|
static const auto EMPTY_SLICE = SLAPrintObject::SliceRecord::NONE;
|
||||||
|
|
||||||
for(int i = 0; i < oslices.size(); ++i) {
|
for(int i = 0; i < oslices.size(); ++i) {
|
||||||
LevelID h = levelids[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);
|
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
|
if(po.m_supportdata) { // deal with the support slices if present
|
||||||
auto& sslices = po.m_supportdata->support_slices;
|
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) {
|
for(int i = 0; i < sslices.size(); ++i) {
|
||||||
int a = i == 0 ? 0 : 1;
|
int a = i == 0 ? 0 : 1;
|
||||||
int b = i == 0 ? 0 : i - 1;
|
int b = i == 0 ? 0 : i - 1;
|
||||||
LevelID h = sminZ + a * sih + b * slh;
|
LevelID h = sminZ + a * sih + b * slh;
|
||||||
|
po.m_supportdata->level_ids.emplace_back(h);
|
||||||
auto& lyrs = levels[h];
|
|
||||||
lyrs.emplace_back(sslices[i], po.m_instances);
|
|
||||||
|
|
||||||
float fh = float(double(h) * SCALING_FACTOR);
|
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
|
// Rasterizing the model objects, and their supports
|
||||||
auto rasterize = [this, ilh, ilhd, max_objstatus, &levels]() {
|
auto rasterize = [this, ilh, ilhd, max_objstatus, &levels]() {
|
||||||
if(canceled()) return;
|
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
|
// collect all the keys
|
||||||
std::vector<long long> keys; keys.reserve(levels.size());
|
std::vector<long long> keys; keys.reserve(levels.size());
|
||||||
for(auto& e : levels) keys.emplace_back(e.first);
|
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.
|
// Draw all the polygons in the slice to the actual layer.
|
||||||
for(auto& cp : copies) {
|
for(auto& cp : copies) {
|
||||||
for(ExPolygon slice : sl) {
|
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.rotate(cp.rotation);
|
||||||
|
slice.translate(cp.shift(X), cp.shift(Y));
|
||||||
printer.draw_polygon(slice, level_id);
|
printer.draw_polygon(slice, level_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,10 @@ class GLCanvas;
|
|||||||
using _SLAPrintObjectBase =
|
using _SLAPrintObjectBase =
|
||||||
PrintObjectBaseWithState<SLAPrint, SLAPrintObjectStep, slaposCount>;
|
PrintObjectBaseWithState<SLAPrint, SLAPrintObjectStep, slaposCount>;
|
||||||
|
|
||||||
|
// 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
|
class SLAPrintObject : public _SLAPrintObjectBase
|
||||||
{
|
{
|
||||||
private: // Prevents erroneous use by other classes.
|
private: // Prevents erroneous use by other classes.
|
||||||
@ -93,7 +97,6 @@ public:
|
|||||||
// to the z coordinate of the object coordinate system.
|
// to the z coordinate of the object coordinate system.
|
||||||
struct SliceRecord {
|
struct SliceRecord {
|
||||||
using Key = float;
|
using Key = float;
|
||||||
// inline static float scale_back(Key h) { return float(h * SCALING_FACTOR); }
|
|
||||||
|
|
||||||
using Idx = size_t;
|
using Idx = size_t;
|
||||||
static const Idx NONE = Idx(-1); // this will be the max limit of size_t
|
static const Idx NONE = Idx(-1); // this will be the max limit of size_t
|
||||||
@ -145,6 +148,7 @@ private:
|
|||||||
std::vector<bool> m_stepmask;
|
std::vector<bool> m_stepmask;
|
||||||
std::vector<ExPolygons> m_model_slices;
|
std::vector<ExPolygons> m_model_slices;
|
||||||
SliceIndex m_slice_index;
|
SliceIndex m_slice_index;
|
||||||
|
std::vector<LevelID> m_level_ids;
|
||||||
|
|
||||||
// Caching the transformed (m_trafo) raw mesh of the object
|
// Caching the transformed (m_trafo) raw mesh of the object
|
||||||
mutable CachedObject<TriangleMesh> m_transformed_rmesh;
|
mutable CachedObject<TriangleMesh> m_transformed_rmesh;
|
||||||
@ -214,10 +218,6 @@ private:
|
|||||||
lref(std::cref(lyr)), copies(std::cref(cp)) {}
|
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
|
// One level may contain multiple slices from multiple objects and their
|
||||||
// supports
|
// supports
|
||||||
using LayerRefs = std::vector<LayerRef>;
|
using LayerRefs = std::vector<LayerRef>;
|
||||||
|
@ -71,14 +71,12 @@ int ProgressStatusBar::get_progress() const
|
|||||||
void ProgressStatusBar::set_progress(int val)
|
void ProgressStatusBar::set_progress(int val)
|
||||||
{
|
{
|
||||||
if(!m_prog->IsShown()) show_progress(true);
|
if(!m_prog->IsShown()) show_progress(true);
|
||||||
|
if(val < 0) return;
|
||||||
|
|
||||||
if(val == m_prog->GetRange()) {
|
if(val == m_prog->GetRange()) {
|
||||||
m_prog->SetValue(0);
|
m_prog->SetValue(0);
|
||||||
show_progress(false);
|
show_progress(false);
|
||||||
}
|
}
|
||||||
else if(val < 0) {
|
|
||||||
m_prog->Pulse();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
m_prog->SetValue(val);
|
m_prog->SetValue(val);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ public:
|
|||||||
~ProgressStatusBar();
|
~ProgressStatusBar();
|
||||||
|
|
||||||
int get_progress() const;
|
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);
|
void set_progress(int);
|
||||||
int get_range() const;
|
int get_range() const;
|
||||||
void set_range(int = 100);
|
void set_range(int = 100);
|
||||||
|
Loading…
Reference in New Issue
Block a user