Refactoring changes to the slice index.

This commit is contained in:
tamasmeszaros 2019-03-22 15:31:38 +01:00
parent 5e646562cd
commit d165dbb498
5 changed files with 249 additions and 215 deletions

View file

@ -56,6 +56,113 @@ public:
} }
}; };
template<class Vector,
class Value = typename Vector::value_type>
class IndexBasedIterator {
static const size_t NONE = size_t(-1);
std::reference_wrapper<Vector> m_index_ref;
size_t m_idx = NONE;
public:
using value_type = Value;
using pointer = Value *;
using reference = Value &;
using difference_type = long;
using iterator_category = std::random_access_iterator_tag;
inline explicit
IndexBasedIterator(Vector& index, size_t idx):
m_index_ref(index), m_idx(idx) {}
// Post increment
inline IndexBasedIterator operator++(int) {
IndexBasedIterator cpy(*this); ++m_idx; return cpy;
}
inline IndexBasedIterator operator--(int) {
IndexBasedIterator cpy(*this); --m_idx; return cpy;
}
inline IndexBasedIterator& operator++() {
++m_idx; return *this;
}
inline IndexBasedIterator& operator--() {
--m_idx; return *this;
}
inline IndexBasedIterator& operator+=(difference_type l) {
m_idx += size_t(l); return *this;
}
inline IndexBasedIterator operator+(difference_type l) {
auto cpy = *this; cpy += l; return cpy;
}
inline IndexBasedIterator& operator-=(difference_type l) {
m_idx -= size_t(l); return *this;
}
inline IndexBasedIterator operator-(difference_type l) {
auto cpy = *this; cpy -= l; return cpy;
}
operator difference_type() { return difference_type(m_idx); }
inline bool is_end() const { return m_idx >= m_index_ref.get().size();}
inline Value & operator*() const {
assert(m_idx < m_index_ref.get().size());
return m_index_ref.get().operator[](m_idx);
}
inline Value * operator->() const {
assert(m_idx < m_index_ref.get().size());
return &m_index_ref.get().operator[](m_idx);
}
inline bool operator ==(const IndexBasedIterator& other) {
size_t e = m_index_ref.get().size();
return m_idx == other.m_idx || (m_idx >= e && other.m_idx >= e);
}
inline bool operator !=(const IndexBasedIterator& other) {
return !(*this == other);
}
inline bool operator <=(const IndexBasedIterator& other) {
return (m_idx < other.m_idx) || (*this == other);
}
inline bool operator <(const IndexBasedIterator& other) {
return m_idx < other.m_idx && (*this != other);
}
inline bool operator >=(const IndexBasedIterator& other) {
return m_idx > other.m_idx || *this == other;
}
inline bool operator >(const IndexBasedIterator& other) {
return m_idx > other.m_idx && *this != other;
}
};
template<class It> class Range {
It from, to;
public:
It begin() const { return from; }
It end() const { return to; }
using Type = It;
Range() = default;
Range(It &&b, It &&e):
from(std::forward<It>(b)), to(std::forward<It>(e)) {}
inline size_t size() const { return end() - begin(); }
inline bool empty() const { return size() == 0; }
};
} }
#endif // MTUTILS_HPP #endif // MTUTILS_HPP

View file

@ -626,8 +626,8 @@ void SLAPrint::process()
double lhd = m_objects.front()->m_config.layer_height.getFloat(); double lhd = m_objects.front()->m_config.layer_height.getFloat();
float lh = float(lhd); float lh = float(lhd);
LevelID ilhs = ilhd / SCALING_FACTOR; auto ilhs = LevelID(ilhd / SCALING_FACTOR);
LevelID lhs = lhd / SCALING_FACTOR; auto lhs = LevelID(lhd / SCALING_FACTOR);
const size_t objcount = m_objects.size(); const size_t objcount = m_objects.size();
const unsigned min_objstatus = 0; // where the per object operations start const unsigned min_objstatus = 0; // where the per object operations start
@ -657,17 +657,15 @@ void SLAPrint::process()
double minZ = bb3d.min(Z) - po.get_elevation(); double minZ = bb3d.min(Z) - po.get_elevation();
double maxZ = bb3d.max(Z); double maxZ = bb3d.max(Z);
LevelID minZs = minZ / SCALING_FACTOR; auto minZs = LevelID(minZ / SCALING_FACTOR);
LevelID maxZs = maxZ / SCALING_FACTOR; auto maxZs = LevelID(maxZ / SCALING_FACTOR);
auto slh = [](float h) { return LevelID( double(h) / SCALING_FACTOR); };
po.m_slice_index.clear(); po.m_slice_index.clear();
po.m_slice_index.reserve(size_t(maxZs - (minZs + ilhs) / lhs) + 1); po.m_slice_index.reserve(size_t(maxZs - (minZs + ilhs) / lhs) + 1);
po.m_slice_index.emplace_back(minZs + ilhs, minZ + ilh / 2.f, ilh); po.m_slice_index.emplace_back(minZs + ilhs, float(minZ) + ilh / 2.f, ilh);
for(LevelID h = minZs + ilhs + lhs; h <= maxZs; h += lhs) { for(LevelID h = minZs + ilhs + lhs; h <= maxZs; h += lhs) {
po.m_slice_index.emplace_back(h, h*SCALING_FACTOR - lh / 2.f, lh); po.m_slice_index.emplace_back(h, float(h*SCALING_FACTOR) - lh / 2.f, lh);
} }
auto slindex_it = po.search_slice_index(float(bb3d.min(Z))); auto slindex_it = po.search_slice_index(float(bb3d.min(Z)));
@ -867,8 +865,10 @@ void SLAPrint::process()
// be part of the slices) // be part of the slices)
auto slice_supports = [](SLAPrintObject& po) { auto slice_supports = [](SLAPrintObject& po) {
auto& sd = po.m_supportdata; auto& sd = po.m_supportdata;
if(sd) sd->support_slices.clear();
if(sd && sd->support_tree_ptr) { if(sd && sd->support_tree_ptr) {
sd->support_slices.clear();
std::vector<float> heights; heights.reserve(po.m_slice_index.size()); std::vector<float> heights; heights.reserve(po.m_slice_index.size());
@ -891,75 +891,6 @@ void SLAPrint::process()
// 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/*, ilhd*/](SLAPrintObject& /*po*/) { auto index_slices = [this/*, ilhd*/](SLAPrintObject& /*po*/) {
// po.m_slice_index.clear();
// auto sih = LevelID(scale_(ilhd));
// // Establish the slice grid boundaries
// auto bb = po.transformed_mesh().bounding_box();
// double modelgnd = bb.min(Z);
// double elevation = po.get_elevation();
// double lh = po.m_config.layer_height.getFloat();
// double minZ = modelgnd - elevation;
// // scaled values:
// auto sminZ = LevelID(scale_(minZ));
// auto smaxZ = LevelID(scale_(bb.max(Z)));
// auto smodelgnd = LevelID(scale_(modelgnd));
// auto slh = LevelID(scale_(lh));
// // It is important that the next levels match the levels in
// // model_slice method. Only difference is that here it works with
// // scaled coordinates
// po.m_level_ids.clear();
// for(LevelID h = sminZ + sih; h < smaxZ; h += slh)
// if(h >= smodelgnd) po.m_level_ids.emplace_back(h);
// std::vector<ExPolygons>& oslices = po.m_model_slices;
// // If everything went well this code should not run at all, but
// // let's be robust...
// // assert(levelids.size() == oslices.size());
// if(po.m_level_ids.size() < oslices.size()) { // extend the levels until...
// BOOST_LOG_TRIVIAL(warning)
// << "Height level mismatch at rasterization!\n";
// LevelID lastlvl = po.m_level_ids.back();
// while(po.m_level_ids.size() < oslices.size()) {
// lastlvl += slh;
// po.m_level_ids.emplace_back(lastlvl);
// }
// }
// for(size_t i = 0; i < oslices.size(); ++i) {
// LevelID h = po.m_level_ids[i];
// float fh = float(double(h) * SCALING_FACTOR);
// // now for the public slice index:
// SLAPrintObject::SliceRecord& sr = po.m_slice_index[fh];
// // There should be only one slice layer for each print object
// assert(sr.model_slices_idx == SLAPrintObject::SliceRecord::NONE);
// sr.model_slices_idx = i;
// }
// if(po.m_supportdata) { // deal with the support slices if present
// std::vector<ExPolygons>& 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 < int(sslices.size()); ++i) {
// LevelID h = sminZ + sih + i * slh;
// po.m_supportdata->level_ids.emplace_back(h);
// float fh = float(double(h) * SCALING_FACTOR);
// SLAPrintObject::SliceRecord& sr = po.m_slice_index[fh];
// assert(sr.support_slices_idx == SLAPrintObject::SliceRecord::NONE);
// sr.support_slices_idx = SLAPrintObject::SliceRecord::Idx(i);
// }
// }
// Using RELOAD_SLA_PREVIEW to tell the Plater to pass the update status to the 3D preview to load the SLA slices. // Using RELOAD_SLA_PREVIEW to tell the Plater to pass the update status to the 3D preview to load the SLA slices.
report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW);
}; };
@ -975,41 +906,16 @@ void SLAPrint::process()
LevelID gndlvl = o->get_slice_index().front().key(); LevelID gndlvl = o->get_slice_index().front().key();
for(auto& slicerecord : o->get_slice_index()) { for(auto& slicerecord : o->get_slice_index()) {
auto& lyrs = m_printer_input[slicerecord.key() - gndlvl]; auto& lyrs = m_printer_input[slicerecord.key() - gndlvl];
auto objslit = slicerecord.get_slices(*o, soModel);
auto supslit = slicerecord.get_slices(*o, soSupport);
if(objslit != o->get_model_slices().end()) const ExPolygons& objslices = o->get_slices_from_record(slicerecord, soModel);
lyrs.emplace_back(*objslit, o->instances()); const ExPolygons& supslices = o->get_slices_from_record(slicerecord, soSupport);
if(supslit != o->get_support_slices().end()) if(!objslices.empty())
lyrs.emplace_back(*supslit, o->instances()); lyrs.emplace_back(objslices, o->instances());
if(!supslices.empty())
lyrs.emplace_back(supslices, o->instances());
} }
// auto& po = *o;
// std::vector<ExPolygons>& 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.empty() ?
// po.m_supportdata->level_ids.front() : 0;
// LevelID mfirst = po.m_level_ids.empty()? 0 : 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(size_t i = 0; i < oslices.size(); ++i) {
// auto& lyrs = m_printer_input[gndlvl + po.m_level_ids[i]];
// lyrs.emplace_back(oslices[i], po.m_instances);
// }
// if(!po.m_supportdata) continue;
// std::vector<ExPolygons>& sslices = po.m_supportdata->support_slices;
// for(size_t i = 0; i < sslices.size(); ++i) {
// LayerRefs& lyrs =
// m_printer_input[gndlvl + po.m_supportdata->level_ids[i]];
// lyrs.emplace_back(sslices[i], po.m_instances);
// }
} }
// collect all the keys // collect all the keys
@ -1355,13 +1261,13 @@ void SLAPrint::fill_statistics()
record = &(*it); record = &(*it);
} }
auto modelslice_it = record->get_slices(*po, soModel); const ExPolygons &modelslices = po->get_slices_from_record(*record, soModel);
if (modelslice_it != po->get_model_slices().end()) if (!modelslices.empty())
append(model_polygons, get_all_polygons(*modelslice_it, po->instances())); append(model_polygons, get_all_polygons(modelslices, po->instances()));
auto supportslice_it = record->get_slices(*po, soSupport); const ExPolygons &supportslices = po->get_slices_from_record(*record, soSupport);
if (supportslice_it != po->get_support_slices().end()) if (!supportslices.empty())
append(supports_polygons, get_all_polygons(*supportslice_it, po->instances())); append(supports_polygons, get_all_polygons(supportslices, po->instances()));
} }
model_polygons = union_(model_polygons); model_polygons = union_(model_polygons);
@ -1561,6 +1467,7 @@ double SLAPrintObject::get_current_elevation() const
namespace { // dummy empty static containers for return values in some methods namespace { // dummy empty static containers for return values in some methods
const std::vector<ExPolygons> EMPTY_SLICES; const std::vector<ExPolygons> EMPTY_SLICES;
const TriangleMesh EMPTY_MESH; const TriangleMesh EMPTY_MESH;
const ExPolygons EMPTY_SLICE;
} }
const std::vector<sla::SupportPoint>& SLAPrintObject::get_support_points() const const std::vector<sla::SupportPoint>& SLAPrintObject::get_support_points() const
@ -1597,7 +1504,8 @@ SLAPrintObject::search_slice_index(float slice_level) const
} }
SLAPrintObject::SliceIndex::iterator SLAPrintObject::SliceIndex::iterator
SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key) SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key,
bool exact)
{ {
_SliceRecord query(key, 0.f, 0.f); _SliceRecord query(key, 0.f, 0.f);
auto it = std::lower_bound(m_slice_index.begin(), m_slice_index.end(), auto it = std::lower_bound(m_slice_index.begin(), m_slice_index.end(),
@ -1608,13 +1516,15 @@ SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key)
}); });
// Return valid iterator only if the keys really match // Return valid iterator only if the keys really match
if(it != m_slice_index.end() && it->key() != key) it = m_slice_index.end(); if(exact && it != m_slice_index.end() && it->key() != key)
it = m_slice_index.end();
return it; return it;
} }
SLAPrintObject::SliceIndex::const_iterator SLAPrintObject::SliceIndex::const_iterator
SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key) const SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key,
bool exact) const
{ {
_SliceRecord query(key, 0.f, 0.f); _SliceRecord query(key, 0.f, 0.f);
auto it = std::lower_bound(m_slice_index.cbegin(), m_slice_index.cend(), auto it = std::lower_bound(m_slice_index.cbegin(), m_slice_index.cend(),
@ -1625,28 +1535,12 @@ SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key) const
}); });
// Return valid iterator only if the keys really match // Return valid iterator only if the keys really match
if(it != m_slice_index.end() && it->key() != key) it = m_slice_index.end(); if(exact && it != m_slice_index.end() && it->key() != key)
it = m_slice_index.end();
return it; return it;
} }
SliceRange SLAPrintObject::get_slices(SliceOrigin so,
float from_level,
float to_level) const
{
auto it_from = search_slice_index(from_level);
auto it_to = search_slice_index(to_level);
SliceRange ret;
auto endit = so == soModel? get_model_slices().end() : get_support_slices().end();
ret.from = it_from == m_slice_index.end() ? endit : it_from->get_slices(*this, so);
ret.to = it_to == m_slice_index.end() ? endit : it_to->get_slices(*this, so);
return ret;
}
const std::vector<ExPolygons> &SLAPrintObject::get_support_slices() const const std::vector<ExPolygons> &SLAPrintObject::get_support_slices() const
{ {
// assert(is_step_done(slaposSliceSupports)); // assert(is_step_done(slaposSliceSupports));
@ -1654,6 +1548,28 @@ const std::vector<ExPolygons> &SLAPrintObject::get_support_slices() const
return m_supportdata->support_slices; return m_supportdata->support_slices;
} }
const ExPolygons &SLAPrintObject::get_slices_from_record(
const _SliceRecord &rec,
SliceOrigin o) const
{
size_t idx = o == soModel ? rec.get_model_slice_idx() :
rec.get_support_slice_idx();
const std::vector<ExPolygons>& v = o == soModel? get_model_slices() :
get_support_slices();
if(idx >= v.size()) return EMPTY_SLICE;
return idx >= v.size() ? EMPTY_SLICE : v[idx];
}
const ExPolygons &SLAPrintObject::get_slices_from_record(
SLAPrintObject::SliceRecordConstIterator it, SliceOrigin o) const
{
if(it.is_end()) return EMPTY_SLICE;
return get_slices_from_record(*it, o);
}
const std::vector<SLAPrintObject::_SliceRecord>& const std::vector<SLAPrintObject::_SliceRecord>&
SLAPrintObject::get_slice_index() const SLAPrintObject::get_slice_index() const
{ {
@ -1778,18 +1694,4 @@ std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in)
return final_path; return final_path;
} }
SliceIterator SLAPrintObject::_SliceRecord::get_slices(const SLAPrintObject &po,
SliceOrigin so) const
{
const std::vector<ExPolygons>& v = so == soModel? po.get_model_slices() :
po.get_support_slices();
size_t idx = so == soModel ? m_model_slices_idx : m_support_slices_idx;
using DiffT = std::vector<ExPolygons>::const_iterator::difference_type;
return idx == NONE? v.end() : v.begin() + DiffT(idx);
}
} // namespace Slic3r } // namespace Slic3r

View file

@ -6,6 +6,7 @@
#include "PrintExport.hpp" #include "PrintExport.hpp"
#include "Point.hpp" #include "Point.hpp"
#include "MTUtils.hpp" #include "MTUtils.hpp"
#include <iterator>
namespace Slic3r { namespace Slic3r {
@ -35,23 +36,8 @@ using _SLAPrintObjectBase =
// the printer (rasterizer) in the SLAPrint class. // the printer (rasterizer) in the SLAPrint class.
using LevelID = long long; using LevelID = long long;
template<class It> struct Range {
It from, to;
It begin() const { return from; }
It end() const { return to; }
using Type = It;
Range() = default;
explicit Range(It &&b, It &&e):
from(std::forward<It>(b)), to(std::forward<It>(e)) {}
};
enum SliceOrigin { soSupport, soModel }; enum SliceOrigin { soSupport, soModel };
using SliceStore = std::vector<ExPolygons>;
using SliceIterator = SliceStore::const_iterator;
using SliceRange = Range<SliceIterator>;
class SLAPrintObject : public _SLAPrintObjectBase class SLAPrintObject : public _SLAPrintObjectBase
{ {
private: // Prevents erroneous use by other classes. private: // Prevents erroneous use by other classes.
@ -107,12 +93,14 @@ public:
// This method returns the support points of this SLAPrintObject. // This method returns the support points of this SLAPrintObject.
const std::vector<sla::SupportPoint>& get_support_points() const; const std::vector<sla::SupportPoint>& get_support_points() const;
// The public Slice record structure. It corresponds to one printable layer.
// To get the sliced polygons, use SLAPrintObject::get_slices_from_record
class SliceRecord { class SliceRecord {
public: public:
using Key = LevelID; using Key = LevelID;
private: private:
LevelID m_print_z = 0; // Top of the layer Key m_print_z = 0; // Top of the layer
float m_slice_z = 0.f; // Exact level of the slice float m_slice_z = 0.f; // Exact level of the slice
float m_height = 0.f; // Height of the sliced layer float m_height = 0.f; // Height of the sliced layer
@ -139,8 +127,9 @@ private:
// levels of the model in scaled-clipper coordinates. The levels correspond // levels of the model in scaled-clipper coordinates. The levels correspond
// to the z coordinate of the object coordinate system. // to the z coordinate of the object coordinate system.
class _SliceRecord: public SliceRecord { class _SliceRecord: public SliceRecord {
private: public:
static const size_t NONE = size_t(-1); // this will be the max limit of size_t static const size_t NONE = size_t(-1); // this will be the max limit of size_t
private:
size_t m_model_slices_idx = NONE; size_t m_model_slices_idx = NONE;
size_t m_support_slices_idx = NONE; size_t m_support_slices_idx = NONE;
@ -148,14 +137,12 @@ private:
_SliceRecord(Key key, float slicez, float height): _SliceRecord(Key key, float slicez, float height):
SliceRecord(key, slicez, height) {} SliceRecord(key, slicez, height) {}
// Returns the slices for either the model or the supports. The return // Methods for setting the indices into the slice vectors.
// value is an iterator to po.get_model_slices() or po.get_support_slices
// depending on the SliceOrigin parameter.
SliceIterator get_slices(const SLAPrintObject& po, SliceOrigin so) const;
// Methods for setting the indixes into the slice vectors.
void set_model_slice_idx(size_t id) { m_model_slices_idx = id; } void set_model_slice_idx(size_t id) { m_model_slices_idx = id; }
void set_support_slice_idx(size_t id) { m_support_slices_idx = id; } void set_support_slice_idx(size_t id) { m_support_slices_idx = id; }
inline size_t get_model_slice_idx() const { return m_model_slices_idx; }
inline size_t get_support_slice_idx() const { return m_support_slices_idx; }
}; };
// Slice index will be a plain vector sorted by the integer height levels // Slice index will be a plain vector sorted by the integer height levels
@ -171,37 +158,78 @@ private:
// Search the slice index for a particular level in integer coordinates. // Search the slice index for a particular level in integer coordinates.
// If no such layer is present, it will return m_slice_index.end() // If no such layer is present, it will return m_slice_index.end()
SliceIndex::iterator search_slice_index(_SliceRecord::Key key); // This behavior can be suppressed by the second parameter. If it is true
SliceIndex::const_iterator search_slice_index(_SliceRecord::Key key) const; // the method will return the closest (non-equal) record
SliceIndex::iterator search_slice_index(_SliceRecord::Key key, bool exact = false);
SliceIndex::const_iterator search_slice_index(_SliceRecord::Key key, bool = false) const;
const std::vector<ExPolygons>& get_model_slices() const;
const std::vector<ExPolygons>& get_support_slices() const;
public: public:
// ///////////////////////////////////////////////////////////////////////// // Should work as a polymorphic bidirectional iterator to the slice records
// The following methods can be used after the model and the support slicing using SliceRecordConstIterator =
// steps have been succesfully finished. IndexBasedIterator<const SliceIndex, const _SliceRecord>;
// /////////////////////////////////////////////////////////////////////////
// Getting slices (model or supports) for a Z coordinate range. The returned
// iterators should include the slices for the given boundaries as well.
SliceRange get_slices(
SliceOrigin so,
float from_level,
float to_level = std::numeric_limits<float>::infinity()) const;
// /////////////////////////////////////////////////////////////////////////
//
// These two methods should be callable on the client side (e.g. UI thread) // These two methods should be callable on the client side (e.g. UI thread)
// when the appropriate steps slaposObjectSlice and slaposSliceSupports // when the appropriate steps slaposObjectSlice and slaposSliceSupports
// are ready. All the print objects are processed before slapsRasterize so // are ready. All the print objects are processed before slapsRasterize so
// it is safe to call them during and/or after slapsRasterize. // it is safe to call them during and/or after slapsRasterize.
const std::vector<ExPolygons>& get_model_slices() const; //
const std::vector<ExPolygons>& get_support_slices() const; // /////////////////////////////////////////////////////////////////////////
// Returns the total number of slices in the slice grid (model and supports) // Get the slice records from a range of slice levels (inclusive). Floating
inline size_t get_slice_count() const { return m_slice_index.size(); } // point keys are the levels where the model was sliced with the mesh
// slicer. Integral keys are the keys of the slice records, which
// correspond to the top of each layer.. The end() method of the returned
// range points *after* the last valid element. This is for being
// consistent with std and makeing range based for loops work. use
// std::prev(range.end()) or --range.end() to get the last element.
template<class Key> Range<SliceRecordConstIterator>
get_slice_records(Key from, Key to = std::numeric_limits<Key>::max()) const
{
SliceIndex::const_iterator it_from, it_to;
if(std::is_integral<Key>::value) {
it_from = search_slice_index(SliceRecord::Key(from));
it_to = search_slice_index(SliceRecord::Key(to));
} else if(std::is_floating_point<Key>::value) {
it_from = search_slice_index(float(from));
it_to = search_slice_index(float(to));
} else return {
SliceRecordConstIterator(m_slice_index, _SliceRecord::NONE ),
SliceRecordConstIterator(m_slice_index, _SliceRecord::NONE ),
};
inline const SliceRecord& get_slice_record(size_t idx) const { auto start = m_slice_index.begin();
return m_slice_index[idx];
size_t bidx = it_from == m_slice_index.end() ? _SliceRecord::NONE :
size_t(it_from - start);
size_t eidx = it_to == m_slice_index.end() ? _SliceRecord::NONE :
size_t(it_to - start) + 1;
return {
SliceRecordConstIterator(m_slice_index, bidx),
SliceRecordConstIterator(m_slice_index, eidx),
};
} }
// Get all the slice records as a range.
inline Range<SliceRecordConstIterator> get_slice_records() const {
return {
SliceRecordConstIterator(m_slice_index, 0),
SliceRecordConstIterator(m_slice_index, m_slice_index.size())
};
}
const ExPolygons& get_slices_from_record(SliceRecordConstIterator it,
SliceOrigin o) const;
const ExPolygons& get_slices_from_record(const _SliceRecord& rec,
SliceOrigin o) const;
protected: protected:
// to be called from SLAPrint only. // to be called from SLAPrint only.
friend class SLAPrint; friend class SLAPrint;
@ -242,7 +270,7 @@ private:
// Exact (float) height levels mapped to the slices. Each record contains // Exact (float) height levels mapped to the slices. Each record contains
// the index to the model and the support slice vectors. // the index to the model and the support slice vectors.
std::vector<_SliceRecord> m_slice_index; std::vector<_SliceRecord> m_slice_index;
std::vector<float> m_model_height_levels; std::vector<float> m_model_height_levels;
@ -335,11 +363,6 @@ private:
// Invalidate steps based on a set of parameters changed. // Invalidate steps based on a set of parameters changed.
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys); bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
std::vector<float> calculate_heights(const BoundingBoxf3& bb,
float elevation,
float initial_layer_height,
float layer_height) const;
void fill_statistics(); void fill_statistics();
SLAPrintConfig m_print_config; SLAPrintConfig m_print_config;

View file

@ -5014,26 +5014,28 @@ void GLCanvas3D::_render_sla_slices() const
if ((bottom_obj_triangles.empty() || bottom_sup_triangles.empty() || top_obj_triangles.empty() || top_sup_triangles.empty()) && obj->is_step_done(slaposIndexSlices)) if ((bottom_obj_triangles.empty() || bottom_sup_triangles.empty() || top_obj_triangles.empty() || top_sup_triangles.empty()) && obj->is_step_done(slaposIndexSlices))
{ {
// FIXME: is this all right (by Tamas)? // FIXME: is this all right (by Tamas)?
SliceRange obj_range = obj->get_slices(soModel, float(min_z), float(max_z)); auto slice_range = obj->get_slice_records(coord_t(min_z / SCALING_FACTOR),
SliceRange sup_range = obj->get_slices(soSupport, float(min_z), float(max_z)); coord_t(max_z / SCALING_FACTOR));
auto obj_end = obj->get_model_slices().end(); const ExPolygons& obj_bottom = obj->get_slices_from_record(slice_range.begin(), soModel);
auto sup_end = obj->get_support_slices().end(); const ExPolygons& obj_top = obj->get_slices_from_record(std::prev(slice_range.end()), soModel);
const ExPolygons& sup_bottom = obj->get_slices_from_record(slice_range.begin(), soSupport);
const ExPolygons& sup_top = obj->get_slices_from_record(std::prev(slice_range.end()), soSupport);
// calculate model bottom cap // calculate model bottom cap
if(bottom_obj_triangles.empty() && obj_range.from != obj_end) if(bottom_obj_triangles.empty() && !obj_bottom.empty())
bottom_obj_triangles = triangulate_expolygons_3d(*obj_range.from, min_z, true); bottom_obj_triangles = triangulate_expolygons_3d(obj_bottom, min_z, true);
// calculate support bottom cap // calculate support bottom cap
if(bottom_sup_triangles.empty() && sup_range.from != sup_end) if(bottom_sup_triangles.empty() && !sup_bottom.empty())
bottom_sup_triangles = triangulate_expolygons_3d(*sup_range.from, min_z, true); bottom_sup_triangles = triangulate_expolygons_3d(sup_bottom, min_z, true);
// calculate model top cap // calculate model top cap
if(top_obj_triangles.empty() && obj_range.to != obj_end) if(top_obj_triangles.empty() && !obj_top.empty())
top_obj_triangles = triangulate_expolygons_3d(*obj_range.to, max_z, false); top_obj_triangles = triangulate_expolygons_3d(obj_top, max_z, false);
// calculate support top cap // calculate support top cap
if(top_sup_triangles.empty() && sup_range.to != sup_end) if(top_sup_triangles.empty() && !sup_top.empty())
top_sup_triangles = triangulate_expolygons_3d(*sup_range.to, max_z, false); top_sup_triangles = triangulate_expolygons_3d(sup_top, max_z, false);
// const std::vector<ExPolygons>& model_slices = obj->get_model_slices(); // const std::vector<ExPolygons>& model_slices = obj->get_model_slices();
// const std::vector<ExPolygons>& support_slices = obj->get_support_slices(); // const std::vector<ExPolygons>& support_slices = obj->get_support_slices();

View file

@ -775,10 +775,10 @@ void Preview::load_print_as_sla()
double shift_z = obj->get_current_elevation(); double shift_z = obj->get_current_elevation();
if (obj->is_step_done(slaposIndexSlices)) if (obj->is_step_done(slaposIndexSlices))
{ {
size_t cnt = obj->get_slice_count(); auto slicerecords = obj->get_slice_records();
for (size_t i = 0; i < cnt; i++) for (auto& rec : slicerecords)
{ {
zs.insert(shift_z + obj->get_slice_record(i).key() * SCALING_FACTOR); zs.insert(shift_z + /*rec.slice_level()*/ rec.key() * SCALING_FACTOR);
} }
} }
} }