mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
Hypothetical support of different object layer heights.
This commit is contained in:
parent
3f7f8f978e
commit
0d83c7ee9f
3 changed files with 42 additions and 9 deletions
|
@ -56,8 +56,18 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class Vector,
|
/// An std compatible random access iterator which uses indices to the source
|
||||||
class Value = typename Vector::value_type>
|
/// vector thus resistant to invalidation caused by relocations. It also "knows"
|
||||||
|
/// its container. No comparison is neccesary to the container "end()" iterator.
|
||||||
|
/// The template can be instantiated with a different value type than that of
|
||||||
|
/// the container's but the types must be compatible. E.g. a base class of the
|
||||||
|
/// contained objects is compatible.
|
||||||
|
///
|
||||||
|
/// For a constant iterator, one can instantiate this template with a value
|
||||||
|
/// type preceded with 'const'.
|
||||||
|
template<class Vector, // The container type, must be random access...
|
||||||
|
class Value = typename Vector::value_type // The value type
|
||||||
|
>
|
||||||
class IndexBasedIterator {
|
class IndexBasedIterator {
|
||||||
static const size_t NONE = size_t(-1);
|
static const size_t NONE = size_t(-1);
|
||||||
|
|
||||||
|
@ -110,6 +120,8 @@ public:
|
||||||
|
|
||||||
operator difference_type() { return difference_type(m_idx); }
|
operator difference_type() { return difference_type(m_idx); }
|
||||||
|
|
||||||
|
/// Tesing the end of the container... this is not possible with std
|
||||||
|
/// iterators.
|
||||||
inline bool is_end() const { return m_idx >= m_index_ref.get().size();}
|
inline bool is_end() const { return m_idx >= m_index_ref.get().size();}
|
||||||
|
|
||||||
inline Value & operator*() const {
|
inline Value & operator*() const {
|
||||||
|
@ -122,6 +134,7 @@ public:
|
||||||
return &m_index_ref.get().operator[](m_idx);
|
return &m_index_ref.get().operator[](m_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If both iterators point past the container, they are equal...
|
||||||
inline bool operator ==(const IndexBasedIterator& other) {
|
inline bool operator ==(const IndexBasedIterator& other) {
|
||||||
size_t e = m_index_ref.get().size();
|
size_t e = m_index_ref.get().size();
|
||||||
return m_idx == other.m_idx || (m_idx >= e && other.m_idx >= e);
|
return m_idx == other.m_idx || (m_idx >= e && other.m_idx >= e);
|
||||||
|
@ -148,17 +161,23 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A very simple range concept implementation with iterator-like objects.
|
||||||
template<class It> class Range {
|
template<class It> class Range {
|
||||||
It from, to;
|
It from, to;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// The class is ready for range based for loops.
|
||||||
It begin() const { return from; }
|
It begin() const { return from; }
|
||||||
It end() const { return to; }
|
It end() const { return to; }
|
||||||
|
|
||||||
|
// The iterator type can be obtained this way.
|
||||||
using Type = It;
|
using Type = It;
|
||||||
|
|
||||||
Range() = default;
|
Range() = default;
|
||||||
Range(It &&b, It &&e):
|
Range(It &&b, It &&e):
|
||||||
from(std::forward<It>(b)), to(std::forward<It>(e)) {}
|
from(std::forward<It>(b)), to(std::forward<It>(e)) {}
|
||||||
|
|
||||||
|
// Some useful container-like methods...
|
||||||
inline size_t size() const { return end() - begin(); }
|
inline size_t size() const { return end() - begin(); }
|
||||||
inline bool empty() const { return size() == 0; }
|
inline bool empty() const { return size() == 0; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -623,11 +623,8 @@ void SLAPrint::process()
|
||||||
// shortcut to initial layer height
|
// shortcut to initial layer height
|
||||||
double ilhd = m_material_config.initial_layer_height.getFloat();
|
double ilhd = m_material_config.initial_layer_height.getFloat();
|
||||||
auto ilh = float(ilhd);
|
auto ilh = float(ilhd);
|
||||||
double lhd = m_objects.front()->m_config.layer_height.getFloat();
|
|
||||||
float lh = float(lhd);
|
|
||||||
|
|
||||||
auto ilhs = LevelID(ilhd / SCALING_FACTOR);
|
auto ilhs = LevelID(ilhd / 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
|
||||||
|
@ -648,11 +645,15 @@ void SLAPrint::process()
|
||||||
|
|
||||||
// Slicing the model object. This method is oversimplified and needs to
|
// Slicing the model object. This method is oversimplified and needs to
|
||||||
// be compared with the fff slicing algorithm for verification
|
// be compared with the fff slicing algorithm for verification
|
||||||
auto slice_model = [this, ilhs, lhs, ilh, lh](SLAPrintObject& po) {
|
auto slice_model = [this, ilhs, ilh](SLAPrintObject& po) {
|
||||||
TriangleMesh mesh = po.transformed_mesh();
|
TriangleMesh mesh = po.transformed_mesh();
|
||||||
|
|
||||||
// We need to prepare the slice index...
|
// We need to prepare the slice index...
|
||||||
|
|
||||||
|
double lhd = m_objects.front()->m_config.layer_height.getFloat();
|
||||||
|
float lh = float(lhd);
|
||||||
|
auto lhs = LevelID(lhd / SCALING_FACTOR);
|
||||||
|
|
||||||
auto&& bb3d = mesh.bounding_box();
|
auto&& bb3d = mesh.bounding_box();
|
||||||
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);
|
||||||
|
@ -716,6 +717,12 @@ void SLAPrint::process()
|
||||||
// into the backend cache.
|
// into the backend cache.
|
||||||
if (mo.sla_points_status != sla::PointsStatus::UserModified) {
|
if (mo.sla_points_status != sla::PointsStatus::UserModified) {
|
||||||
|
|
||||||
|
// Hypotetical use of the slice index:
|
||||||
|
// auto bb = po.transformed_mesh().bounding_box();
|
||||||
|
// auto range = po.get_slice_records(bb.min(Z));
|
||||||
|
// std::vector<float> heights; heights.reserve(range.size());
|
||||||
|
// for(auto& record : range) heights.emplace_back(record.slice_level());
|
||||||
|
|
||||||
// calculate heights of slices (slices are calculated already)
|
// calculate heights of slices (slices are calculated already)
|
||||||
const std::vector<float>& heights = po.m_model_height_levels;
|
const std::vector<float>& heights = po.m_model_height_levels;
|
||||||
|
|
||||||
|
@ -896,15 +903,22 @@ void SLAPrint::process()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rasterizing the model objects, and their supports
|
// Rasterizing the model objects, and their supports
|
||||||
auto rasterize = [this, max_objstatus]() {
|
auto rasterize = [this, max_objstatus, ilhs]() {
|
||||||
if(canceled()) return;
|
if(canceled()) return;
|
||||||
|
|
||||||
// clear the rasterizer input
|
// clear the rasterizer input
|
||||||
m_printer_input.clear();
|
m_printer_input.clear();
|
||||||
|
auto eps = LevelID(EPSILON / SCALING_FACTOR);
|
||||||
|
|
||||||
for(SLAPrintObject * o : m_objects) {
|
for(SLAPrintObject * o : m_objects) {
|
||||||
LevelID gndlvl = o->get_slice_index().front().key();
|
LevelID gndlvl = o->get_slice_index().front().key() - ilhs;
|
||||||
|
|
||||||
for(auto& slicerecord : o->get_slice_index()) {
|
for(auto& slicerecord : o->get_slice_index()) {
|
||||||
|
LevelID lvlid = slicerecord.key() - gndlvl;
|
||||||
|
|
||||||
|
// Neat trick to round the layer levels to the grid.
|
||||||
|
lvlid = eps * (lvlid / eps);
|
||||||
|
|
||||||
auto& lyrs = m_printer_input[slicerecord.key() - gndlvl];
|
auto& lyrs = m_printer_input[slicerecord.key() - gndlvl];
|
||||||
|
|
||||||
const ExPolygons& objslices = o->get_slices_from_record(slicerecord, soModel);
|
const ExPolygons& objslices = o->get_slices_from_record(slicerecord, soModel);
|
||||||
|
|
|
@ -158,7 +158,7 @@ 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()
|
||||||
// This behavior can be suppressed by the second parameter. If it is true
|
// This behavior can be suppressed by the second parameter. If it is false
|
||||||
// the method will return the closest (non-equal) record
|
// the method will return the closest (non-equal) record
|
||||||
SliceIndex::iterator search_slice_index(_SliceRecord::Key key, bool exact = false);
|
SliceIndex::iterator search_slice_index(_SliceRecord::Key key, bool exact = false);
|
||||||
SliceIndex::const_iterator search_slice_index(_SliceRecord::Key key, bool = false) const;
|
SliceIndex::const_iterator search_slice_index(_SliceRecord::Key key, bool = false) const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue