mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 00:37:51 -06:00
Refactoring changes to the slice index.
This commit is contained in:
parent
5e646562cd
commit
d165dbb498
5 changed files with 249 additions and 215 deletions
|
@ -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
|
||||
|
|
|
@ -626,8 +626,8 @@ void SLAPrint::process()
|
|||
double lhd = m_objects.front()->m_config.layer_height.getFloat();
|
||||
float lh = float(lhd);
|
||||
|
||||
LevelID ilhs = ilhd / SCALING_FACTOR;
|
||||
LevelID lhs = lhd / SCALING_FACTOR;
|
||||
auto ilhs = LevelID(ilhd / SCALING_FACTOR);
|
||||
auto lhs = LevelID(lhd / SCALING_FACTOR);
|
||||
const size_t objcount = m_objects.size();
|
||||
|
||||
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 maxZ = bb3d.max(Z);
|
||||
|
||||
LevelID minZs = minZ / SCALING_FACTOR;
|
||||
LevelID maxZs = maxZ / SCALING_FACTOR;
|
||||
|
||||
auto slh = [](float h) { return LevelID( double(h) / SCALING_FACTOR); };
|
||||
auto minZs = LevelID(minZ / SCALING_FACTOR);
|
||||
auto maxZs = LevelID(maxZ / SCALING_FACTOR);
|
||||
|
||||
po.m_slice_index.clear();
|
||||
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) {
|
||||
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)));
|
||||
|
@ -867,8 +865,10 @@ void SLAPrint::process()
|
|||
// be part of the slices)
|
||||
auto slice_supports = [](SLAPrintObject& po) {
|
||||
auto& sd = po.m_supportdata;
|
||||
|
||||
if(sd) sd->support_slices.clear();
|
||||
|
||||
if(sd && sd->support_tree_ptr) {
|
||||
sd->support_slices.clear();
|
||||
|
||||
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
|
||||
// an index where the key is the height level in discrete levels (clipper)
|
||||
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.
|
||||
report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW);
|
||||
};
|
||||
|
@ -975,41 +906,16 @@ void SLAPrint::process()
|
|||
LevelID gndlvl = o->get_slice_index().front().key();
|
||||
for(auto& slicerecord : o->get_slice_index()) {
|
||||
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())
|
||||
lyrs.emplace_back(*objslit, o->instances());
|
||||
const ExPolygons& objslices = o->get_slices_from_record(slicerecord, soModel);
|
||||
const ExPolygons& supslices = o->get_slices_from_record(slicerecord, soSupport);
|
||||
|
||||
if(supslit != o->get_support_slices().end())
|
||||
lyrs.emplace_back(*supslit, o->instances());
|
||||
if(!objslices.empty())
|
||||
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
|
||||
|
@ -1355,13 +1261,13 @@ void SLAPrint::fill_statistics()
|
|||
record = &(*it);
|
||||
}
|
||||
|
||||
auto modelslice_it = record->get_slices(*po, soModel);
|
||||
if (modelslice_it != po->get_model_slices().end())
|
||||
append(model_polygons, get_all_polygons(*modelslice_it, po->instances()));
|
||||
const ExPolygons &modelslices = po->get_slices_from_record(*record, soModel);
|
||||
if (!modelslices.empty())
|
||||
append(model_polygons, get_all_polygons(modelslices, po->instances()));
|
||||
|
||||
auto supportslice_it = record->get_slices(*po, soSupport);
|
||||
if (supportslice_it != po->get_support_slices().end())
|
||||
append(supports_polygons, get_all_polygons(*supportslice_it, po->instances()));
|
||||
const ExPolygons &supportslices = po->get_slices_from_record(*record, soSupport);
|
||||
if (!supportslices.empty())
|
||||
append(supports_polygons, get_all_polygons(supportslices, po->instances()));
|
||||
}
|
||||
|
||||
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
|
||||
const std::vector<ExPolygons> EMPTY_SLICES;
|
||||
const TriangleMesh EMPTY_MESH;
|
||||
const ExPolygons EMPTY_SLICE;
|
||||
}
|
||||
|
||||
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::search_slice_index(SLAPrintObject::_SliceRecord::Key key)
|
||||
SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key,
|
||||
bool exact)
|
||||
{
|
||||
_SliceRecord query(key, 0.f, 0.f);
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
// assert(is_step_done(slaposSliceSupports));
|
||||
|
@ -1654,6 +1548,28 @@ const std::vector<ExPolygons> &SLAPrintObject::get_support_slices() const
|
|||
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>&
|
||||
SLAPrintObject::get_slice_index() const
|
||||
{
|
||||
|
@ -1778,18 +1694,4 @@ std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in)
|
|||
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
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "PrintExport.hpp"
|
||||
#include "Point.hpp"
|
||||
#include "MTUtils.hpp"
|
||||
#include <iterator>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -35,23 +36,8 @@ using _SLAPrintObjectBase =
|
|||
// the printer (rasterizer) in the SLAPrint class.
|
||||
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 };
|
||||
|
||||
using SliceStore = std::vector<ExPolygons>;
|
||||
using SliceIterator = SliceStore::const_iterator;
|
||||
using SliceRange = Range<SliceIterator>;
|
||||
|
||||
class SLAPrintObject : public _SLAPrintObjectBase
|
||||
{
|
||||
private: // Prevents erroneous use by other classes.
|
||||
|
@ -107,12 +93,14 @@ public:
|
|||
// This method returns the support points of this SLAPrintObject.
|
||||
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 {
|
||||
public:
|
||||
using Key = LevelID;
|
||||
|
||||
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_height = 0.f; // Height of the sliced layer
|
||||
|
||||
|
@ -139,8 +127,9 @@ private:
|
|||
// levels of the model in scaled-clipper coordinates. The levels correspond
|
||||
// to the z coordinate of the object coordinate system.
|
||||
class _SliceRecord: public SliceRecord {
|
||||
private:
|
||||
public:
|
||||
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_support_slices_idx = NONE;
|
||||
|
||||
|
@ -148,14 +137,12 @@ private:
|
|||
_SliceRecord(Key key, float slicez, float height):
|
||||
SliceRecord(key, slicez, height) {}
|
||||
|
||||
// Returns the slices for either the model or the supports. The return
|
||||
// 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.
|
||||
// Methods for setting the indices into the slice vectors.
|
||||
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; }
|
||||
|
||||
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
|
||||
|
@ -171,37 +158,78 @@ private:
|
|||
|
||||
// Search the slice index for a particular level in integer coordinates.
|
||||
// If no such layer is present, it will return m_slice_index.end()
|
||||
SliceIndex::iterator search_slice_index(_SliceRecord::Key key);
|
||||
SliceIndex::const_iterator search_slice_index(_SliceRecord::Key key) const;
|
||||
// This behavior can be suppressed by the second parameter. If it is true
|
||||
// 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:
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
// The following methods can be used after the model and the support slicing
|
||||
// steps have been succesfully finished.
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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;
|
||||
// Should work as a polymorphic bidirectional iterator to the slice records
|
||||
using SliceRecordConstIterator =
|
||||
IndexBasedIterator<const SliceIndex, const _SliceRecord>;
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// These two methods should be callable on the client side (e.g. UI thread)
|
||||
// when the appropriate steps slaposObjectSlice and slaposSliceSupports
|
||||
// are ready. All the print objects are processed before slapsRasterize so
|
||||
// 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)
|
||||
inline size_t get_slice_count() const { return m_slice_index.size(); }
|
||||
// Get the slice records from a range of slice levels (inclusive). Floating
|
||||
// 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 {
|
||||
return m_slice_index[idx];
|
||||
auto start = m_slice_index.begin();
|
||||
|
||||
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:
|
||||
// to be called from SLAPrint only.
|
||||
friend class SLAPrint;
|
||||
|
@ -335,11 +363,6 @@ private:
|
|||
// Invalidate steps based on a set of parameters changed.
|
||||
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();
|
||||
|
||||
SLAPrintConfig m_print_config;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
// FIXME: is this all right (by Tamas)?
|
||||
SliceRange obj_range = obj->get_slices(soModel, float(min_z), float(max_z));
|
||||
SliceRange sup_range = obj->get_slices(soSupport, float(min_z), float(max_z));
|
||||
auto obj_end = obj->get_model_slices().end();
|
||||
auto sup_end = obj->get_support_slices().end();
|
||||
auto slice_range = obj->get_slice_records(coord_t(min_z / SCALING_FACTOR),
|
||||
coord_t(max_z / SCALING_FACTOR));
|
||||
const ExPolygons& obj_bottom = obj->get_slices_from_record(slice_range.begin(), soModel);
|
||||
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
|
||||
if(bottom_obj_triangles.empty() && obj_range.from != obj_end)
|
||||
bottom_obj_triangles = triangulate_expolygons_3d(*obj_range.from, min_z, true);
|
||||
if(bottom_obj_triangles.empty() && !obj_bottom.empty())
|
||||
bottom_obj_triangles = triangulate_expolygons_3d(obj_bottom, min_z, true);
|
||||
|
||||
// calculate support bottom cap
|
||||
if(bottom_sup_triangles.empty() && sup_range.from != sup_end)
|
||||
bottom_sup_triangles = triangulate_expolygons_3d(*sup_range.from, min_z, true);
|
||||
if(bottom_sup_triangles.empty() && !sup_bottom.empty())
|
||||
bottom_sup_triangles = triangulate_expolygons_3d(sup_bottom, min_z, true);
|
||||
|
||||
// calculate model top cap
|
||||
if(top_obj_triangles.empty() && obj_range.to != obj_end)
|
||||
top_obj_triangles = triangulate_expolygons_3d(*obj_range.to, max_z, false);
|
||||
if(top_obj_triangles.empty() && !obj_top.empty())
|
||||
top_obj_triangles = triangulate_expolygons_3d(obj_top, max_z, false);
|
||||
|
||||
// calculate support top cap
|
||||
if(top_sup_triangles.empty() && sup_range.to != sup_end)
|
||||
top_sup_triangles = triangulate_expolygons_3d(*sup_range.to, max_z, false);
|
||||
if(top_sup_triangles.empty() && !sup_top.empty())
|
||||
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>& support_slices = obj->get_support_slices();
|
||||
|
|
|
@ -775,10 +775,10 @@ void Preview::load_print_as_sla()
|
|||
double shift_z = obj->get_current_elevation();
|
||||
if (obj->is_step_done(slaposIndexSlices))
|
||||
{
|
||||
size_t cnt = obj->get_slice_count();
|
||||
for (size_t i = 0; i < cnt; i++)
|
||||
auto slicerecords = obj->get_slice_records();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue