Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_perspective_camera

This commit is contained in:
Enrico Turri 2019-06-17 09:34:25 +02:00
commit ddb4c1ff3f
6 changed files with 134 additions and 86 deletions

View File

@ -53,7 +53,7 @@ Contour3D walls(const Polygon& lower, const Polygon& upper,
// Shorthand for the vertex arrays // Shorthand for the vertex arrays
auto& upoints = upper.points, &lpoints = lower.points; auto& upoints = upper.points, &lpoints = lower.points;
auto& rpts = ret.points; auto& rfaces = ret.indices; auto& rpts = ret.points; auto& ind = ret.indices;
// If the Z levels are flipped, or the offset difference is negative, we // If the Z levels are flipped, or the offset difference is negative, we
// will interpret that as the triangles normals should be inverted. // will interpret that as the triangles normals should be inverted.
@ -61,7 +61,7 @@ Contour3D walls(const Polygon& lower, const Polygon& upper,
// Copy the points into the mesh, convert them from 2D to 3D // Copy the points into the mesh, convert them from 2D to 3D
rpts.reserve(upoints.size() + lpoints.size()); rpts.reserve(upoints.size() + lpoints.size());
rfaces.reserve(2*upoints.size() + 2*lpoints.size()); ind.reserve(2*upoints.size() + 2*lpoints.size());
const double sf = SCALING_FACTOR; const double sf = SCALING_FACTOR;
for(auto& p : upoints) rpts.emplace_back(p.x()*sf, p.y()*sf, upper_z_mm); for(auto& p : upoints) rpts.emplace_back(p.x()*sf, p.y()*sf, upper_z_mm);
for(auto& p : lpoints) rpts.emplace_back(p.x()*sf, p.y()*sf, lower_z_mm); for(auto& p : lpoints) rpts.emplace_back(p.x()*sf, p.y()*sf, lower_z_mm);
@ -121,9 +121,9 @@ Contour3D walls(const Polygon& lower, const Polygon& upper,
case Proceed::UPPER: case Proceed::UPPER:
if(!ustarted || uidx != uendidx) { // there are vertices remaining if(!ustarted || uidx != uendidx) { // there are vertices remaining
// Get the 3D vertices in order // Get the 3D vertices in order
const Vec3d& p_up1 = rpts[size_t(uidx)]; const Vec3d& p_up1 = rpts[uidx];
const Vec3d& p_low = rpts[size_t(lidx)]; const Vec3d& p_low = rpts[lidx];
const Vec3d& p_up2 = rpts[size_t(unextidx)]; const Vec3d& p_up2 = rpts[unextidx];
// Calculate fitness: the average of the two connecting edges // Calculate fitness: the average of the two connecting edges
double a = offsdiff2 - (distfn(p_up1, p_low) - zdiff2); double a = offsdiff2 - (distfn(p_up1, p_low) - zdiff2);
@ -133,8 +133,9 @@ Contour3D walls(const Polygon& lower, const Polygon& upper,
if(current_fit > prev_fit) { // fit is worse than previously if(current_fit > prev_fit) { // fit is worse than previously
proceed = Proceed::LOWER; proceed = Proceed::LOWER;
} else { // good to go, create the triangle } else { // good to go, create the triangle
inverted? rfaces.emplace_back(unextidx, lidx, uidx) : inverted
rfaces.emplace_back(uidx, lidx, unextidx) ; ? ind.emplace_back(int(unextidx), int(lidx), int(uidx))
: ind.emplace_back(int(uidx), int(lidx), int(unextidx));
// Increment the iterators, rotate if necessary // Increment the iterators, rotate if necessary
++uidx; ++unextidx; ++uidx; ++unextidx;
@ -150,9 +151,9 @@ Contour3D walls(const Polygon& lower, const Polygon& upper,
case Proceed::LOWER: case Proceed::LOWER:
// Mode with lower segment, upper vertex. Same structure: // Mode with lower segment, upper vertex. Same structure:
if(!lstarted || lidx != lendidx) { if(!lstarted || lidx != lendidx) {
const Vec3d& p_low1 = rpts[size_t(lidx)]; const Vec3d& p_low1 = rpts[lidx];
const Vec3d& p_low2 = rpts[size_t(lnextidx)]; const Vec3d& p_low2 = rpts[lnextidx];
const Vec3d& p_up = rpts[size_t(uidx)]; const Vec3d& p_up = rpts[uidx];
double a = offsdiff2 - (distfn(p_up, p_low1) - zdiff2); double a = offsdiff2 - (distfn(p_up, p_low1) - zdiff2);
double b = offsdiff2 - (distfn(p_up, p_low2) - zdiff2); double b = offsdiff2 - (distfn(p_up, p_low2) - zdiff2);
@ -161,8 +162,9 @@ Contour3D walls(const Polygon& lower, const Polygon& upper,
if(current_fit > prev_fit) { if(current_fit > prev_fit) {
proceed = Proceed::UPPER; proceed = Proceed::UPPER;
} else { } else {
inverted? rfaces.emplace_back(uidx, lnextidx, lidx) : inverted
rfaces.emplace_back(lidx, lnextidx, uidx); ? ind.emplace_back(int(uidx), int(lnextidx), int(lidx))
: ind.emplace_back(int(lidx), int(lnextidx), int(uidx));
++lidx; ++lnextidx; ++lidx; ++lnextidx;
if(lnextidx == rpts.size()) lnextidx = offs; if(lnextidx == rpts.size()) lnextidx = offs;

View File

@ -36,12 +36,10 @@ inline coord_t x(const Vec3crd& p) { return p(0); }
inline coord_t y(const Vec3crd& p) { return p(1); } inline coord_t y(const Vec3crd& p) { return p(1); }
inline coord_t z(const Vec3crd& p) { return p(2); } inline coord_t z(const Vec3crd& p) { return p(2); }
using Indices = std::vector<Vec3crd>;
/// Intermediate struct for a 3D mesh /// Intermediate struct for a 3D mesh
struct Contour3D { struct Contour3D {
Pointf3s points; Pointf3s points;
Indices indices; std::vector<Vec3i> indices;
void merge(const Contour3D& ctr) { void merge(const Contour3D& ctr) {
auto s3 = coord_t(points.size()); auto s3 = coord_t(points.size());

View File

@ -236,13 +236,13 @@ Contour3D cylinder(double r, double h, size_t ssteps, const Vec3d sp = {0,0,0})
// According to the slicing algorithms, we need to aid them with generating // According to the slicing algorithms, we need to aid them with generating
// a watertight body. So we create a triangle fan for the upper and lower // a watertight body. So we create a triangle fan for the upper and lower
// ending of the cylinder to close the geometry. // ending of the cylinder to close the geometry.
points.emplace_back(jp); size_t ci = points.size() - 1; points.emplace_back(jp); int ci = int(points.size() - 1);
for(int i = 0; i < steps - 1; ++i) for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(i + offs + 1, i + offs, ci); indices.emplace_back(i + offs + 1, i + offs, ci);
indices.emplace_back(offs, steps + offs - 1, ci); indices.emplace_back(offs, steps + offs - 1, ci);
points.emplace_back(endp); ci = points.size() - 1; points.emplace_back(endp); ci = int(points.size() - 1);
for(int i = 0; i < steps - 1; ++i) for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(ci, i, i + 1); indices.emplace_back(ci, i, i + 1);

View File

@ -28,14 +28,16 @@ namespace Slic3r {
using SupportTreePtr = std::unique_ptr<sla::SLASupportTree>; using SupportTreePtr = std::unique_ptr<sla::SLASupportTree>;
class SLAPrintObject::SupportData { class SLAPrintObject::SupportData
{
public: public:
sla::EigenMesh3D emesh; // index-triangle representation sla::EigenMesh3D emesh; // index-triangle representation
std::vector<sla::SupportPoint> support_points; // all the support points (manual/auto) std::vector<sla::SupportPoint>
SupportTreePtr support_tree_ptr; // the supports support_points; // all the support points (manual/auto)
SlicedSupports support_slices; // sliced supports SupportTreePtr support_tree_ptr; // the supports
SlicedSupports support_slices; // sliced supports
inline SupportData(const TriangleMesh& trmesh): emesh(trmesh) {} inline SupportData(const TriangleMesh &trmesh) : emesh(trmesh) {}
}; };
namespace { namespace {
@ -666,11 +668,11 @@ void SLAPrint::process()
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);
auto ilhs = coord_t(ilhd / SCALING_FACTOR); auto ilhs = scaled(ilhd);
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 static const unsigned min_objstatus = 0; // where the per object operations start
const unsigned max_objstatus = 50; // where the per object operations end static const unsigned max_objstatus = 50; // where the per object operations end
// the coefficient that multiplies the per object status values which // the coefficient that multiplies the per object status values which
// are set up for <0, 100>. They need to be scaled into the whole process // are set up for <0, 100>. They need to be scaled into the whole process
@ -687,31 +689,32 @@ 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, ilh, ilhd](SLAPrintObject& po) { auto slice_model = [this, ilhs, ilh](SLAPrintObject& po) {
const TriangleMesh& mesh = po.transformed_mesh(); const 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(); double lhd = m_objects.front()->m_config.layer_height.getFloat();
float lh = float(lhd); float lh = float(lhd);
auto lhs = coord_t(lhd / SCALING_FACTOR); auto lhs = scaled(lhd);
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);
auto minZf = float(minZ);
auto minZs = coord_t(minZ / SCALING_FACTOR); auto minZs = scaled(minZ);
auto maxZs = coord_t(maxZ / SCALING_FACTOR); auto maxZs = scaled(maxZ);
po.m_slice_index.clear(); po.m_slice_index.clear();
size_t cap = size_t(1 + (maxZs - minZs - ilhs) / lhs); size_t cap = size_t(1 + (maxZs - minZs - ilhs) / lhs);
po.m_slice_index.reserve(cap); po.m_slice_index.reserve(cap);
po.m_slice_index.emplace_back(minZs + ilhs, minZ + ilhd / 2.0, ilh); po.m_slice_index.emplace_back(minZs + ilhs, minZf + ilh / 2.f, ilh);
for(coord_t h = minZs + ilhs + lhs; h <= maxZs; h += lhs) for(coord_t h = minZs + ilhs + lhs; h <= maxZs; h += lhs)
po.m_slice_index.emplace_back(h, h*SCALING_FACTOR - lhd / 2.0, lh); po.m_slice_index.emplace_back(h, unscaled<float>(h) - lh / 2.f, lh);
// Just get the first record that is form the model: // Just get the first record that is form the model:
auto slindex_it = auto slindex_it =
@ -737,15 +740,15 @@ void SLAPrint::process()
auto mit = slindex_it; auto mit = slindex_it;
double doffs = m_printer_config.absolute_correction.getFloat(); double doffs = m_printer_config.absolute_correction.getFloat();
coord_t clpr_offs = coord_t(doffs / SCALING_FACTOR); coord_t clpr_offs = scaled(doffs);
for(size_t id = 0; for(size_t id = 0;
id < po.m_model_slices.size() && mit != po.m_slice_index.end(); id < po.m_model_slices.size() && mit != po.m_slice_index.end();
id++) id++)
{ {
// We apply the printer correction offset here. // We apply the printer correction offset here.
if(clpr_offs != 0) if(clpr_offs != 0)
po.m_model_slices[id] = po.m_model_slices[id] =
offset_ex(po.m_model_slices[id], clpr_offs); offset_ex(po.m_model_slices[id], float(clpr_offs));
mit->set_model_slice_idx(po, id); ++mit; mit->set_model_slice_idx(po, id); ++mit;
} }
@ -949,15 +952,15 @@ void SLAPrint::process()
} }
double doffs = m_printer_config.absolute_correction.getFloat(); double doffs = m_printer_config.absolute_correction.getFloat();
coord_t clpr_offs = coord_t(doffs / SCALING_FACTOR); coord_t clpr_offs = scaled(doffs);
for(size_t i = 0; for(size_t i = 0;
i < sd->support_slices.size() && i < po.m_slice_index.size(); i < sd->support_slices.size() && i < po.m_slice_index.size();
++i) ++i)
{ {
// We apply the printer correction offset here. // We apply the printer correction offset here.
if(clpr_offs != 0) if(clpr_offs != 0)
sd->support_slices[i] = sd->support_slices[i] =
offset_ex(sd->support_slices[i], clpr_offs); offset_ex(sd->support_slices[i], float(clpr_offs));
po.m_slice_index[i].set_support_slice_idx(po, i); po.m_slice_index[i].set_support_slice_idx(po, i);
} }
@ -1063,8 +1066,8 @@ void SLAPrint::process()
const int fade_layers_cnt = m_default_object_config.faded_layers.getInt();// 10 // [3;20] const int fade_layers_cnt = m_default_object_config.faded_layers.getInt();// 10 // [3;20]
const double width = m_printer_config.display_width.getFloat() / SCALING_FACTOR; const double width = scaled(m_printer_config.display_width.getFloat());
const double height = m_printer_config.display_height.getFloat() / SCALING_FACTOR; const double height = scaled(m_printer_config.display_height.getFloat());
const double display_area = width*height; const double display_area = width*height;
// get polygons for all instances in the object // get polygons for all instances in the object
@ -1170,13 +1173,20 @@ void SLAPrint::process()
ClipperPolygons model_polygons; ClipperPolygons model_polygons;
ClipperPolygons supports_polygons; ClipperPolygons supports_polygons;
size_t c = std::accumulate(layer.slices().begin(), layer.slices().end(), 0u, [](size_t a, const SliceRecord& sr) { size_t c = std::accumulate(layer.slices().begin(),
return a + sr.get_slice(soModel).size(); layer.slices().end(),
size_t(0),
[](size_t a, const SliceRecord &sr) {
return a + sr.get_slice(soModel)
.size();
}); });
model_polygons.reserve(c); model_polygons.reserve(c);
c = std::accumulate(layer.slices().begin(), layer.slices().end(), 0u, [](size_t a, const SliceRecord& sr) { c = std::accumulate(layer.slices().begin(),
layer.slices().end(),
size_t(0),
[](size_t a, const SliceRecord &sr) {
return a + sr.get_slice(soModel).size(); return a + sr.get_slice(soModel).size();
}); });
@ -1264,8 +1274,9 @@ void SLAPrint::process()
// for(size_t i = 0; i < m_printer_input.size(); ++i) printlayerfn(i); // for(size_t i = 0; i < m_printer_input.size(); ++i) printlayerfn(i);
tbb::parallel_for<size_t, decltype(printlayerfn)>(0, m_printer_input.size(), printlayerfn); tbb::parallel_for<size_t, decltype(printlayerfn)>(0, m_printer_input.size(), printlayerfn);
m_print_statistics.support_used_material = supports_volume * SCALING_FACTOR * SCALING_FACTOR; auto SCALING2 = SCALING_FACTOR * SCALING_FACTOR;
m_print_statistics.objects_used_material = models_volume * SCALING_FACTOR * SCALING_FACTOR; m_print_statistics.support_used_material = supports_volume * SCALING2;
m_print_statistics.objects_used_material = models_volume * SCALING2;
// Estimated printing time // Estimated printing time
// A layers count o the highest object // A layers count o the highest object
@ -1281,7 +1292,7 @@ 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]() {
if(canceled()) return; if(canceled()) return;
// collect all the keys // collect all the keys
@ -1376,11 +1387,12 @@ void SLAPrint::process()
tbb::parallel_for<unsigned, decltype(lvlfn)>(0, lvlcnt, lvlfn); tbb::parallel_for<unsigned, decltype(lvlfn)>(0, lvlcnt, lvlfn);
// Set statistics values to the printer // Set statistics values to the printer
m_printer->set_statistics({(m_print_statistics.objects_used_material + m_print_statistics.support_used_material)/1000, m_printer->set_statistics(
double(m_default_object_config.faded_layers.getInt()), {(m_print_statistics.objects_used_material
double(m_print_statistics.slow_layers_count), + m_print_statistics.support_used_material) / 1000,
double(m_print_statistics.fast_layers_count) double(m_default_object_config.faded_layers.getInt()),
}); double(m_print_statistics.slow_layers_count),
double(m_print_statistics.fast_layers_count)});
}; };
using slaposFn = std::function<void(SLAPrintObject&)>; using slaposFn = std::function<void(SLAPrintObject&)>;
@ -1408,25 +1420,36 @@ void SLAPrint::process()
// TODO: this loop could run in parallel but should not exhaust all the CPU // TODO: this loop could run in parallel but should not exhaust all the CPU
// power available // power available
// Calculate the support structures first before slicing the supports, so that the preview will get displayed ASAP for all objects. // Calculate the support structures first before slicing the supports,
std::vector<SLAPrintObjectStep> step_ranges = { slaposObjectSlice, slaposSliceSupports, slaposCount }; // so that the preview will get displayed ASAP for all objects.
for (size_t idx_range = 0; idx_range + 1 < step_ranges.size(); ++ idx_range) { std::vector<SLAPrintObjectStep> step_ranges = {slaposObjectSlice,
for(SLAPrintObject * po : m_objects) { slaposSliceSupports,
slaposCount};
BOOST_LOG_TRIVIAL(info) << "Slicing object " << po->model_object()->name; for (size_t idx_range = 0; idx_range + 1 < step_ranges.size(); ++idx_range) {
for (SLAPrintObject *po : m_objects) {
for (int s = int(step_ranges[idx_range]); s < int(step_ranges[idx_range + 1]); ++s) { BOOST_LOG_TRIVIAL(info)
<< "Slicing object " << po->model_object()->name;
for (int s = int(step_ranges[idx_range]);
s < int(step_ranges[idx_range + 1]);
++s) {
auto currentstep = static_cast<SLAPrintObjectStep>(s); auto currentstep = static_cast<SLAPrintObjectStep>(s);
// Cancellation checking. Each step will check for cancellation // Cancellation checking. Each step will check for
// on its own and return earlier gracefully. Just after it returns // cancellation on its own and return earlier gracefully.
// execution gets to this point and throws the canceled signal. // Just after it returns execution gets to this point and
// throws the canceled signal.
throw_if_canceled(); throw_if_canceled();
st += incr * ostepd; st += incr * ostepd;
if(po->m_stepmask[currentstep] && po->set_started(currentstep)) { if (po->m_stepmask[currentstep]
m_report_status(*this, st, OBJ_STEP_LABELS(currentstep)); && po->set_started(currentstep)) {
m_report_status(*this,
st,
OBJ_STEP_LABELS(currentstep));
pobj_program[currentstep](*po); pobj_program[currentstep](*po);
throw_if_canceled(); throw_if_canceled();
po->set_done(currentstep); po->set_done(currentstep);
@ -1786,8 +1809,8 @@ std::vector<sla::SupportPoint> SLAPrintObject::transformed_support_points() cons
ret.reserve(spts.size()); ret.reserve(spts.size());
for(sla::SupportPoint& sp : spts) { for(sla::SupportPoint& sp : spts) {
Vec3d transformed_pos = trafo() * Vec3d(sp.pos(0), sp.pos(1), sp.pos(2)); Vec3f transformed_pos = trafo().cast<float>() * sp.pos;
ret.emplace_back(transformed_pos(0), transformed_pos(1), transformed_pos(2), sp.head_front_radius, sp.is_new_island); ret.emplace_back(transformed_pos, sp.head_front_radius, sp.is_new_island);
} }
return ret; return ret;

View File

@ -54,15 +54,15 @@ public:
bool is_left_handed() const { return m_left_handed; } bool is_left_handed() const { return m_left_handed; }
struct Instance { struct Instance {
Instance(ModelID instance_id, const Point &shift, float rotation) : instance_id(instance_id), shift(shift), rotation(rotation) {} Instance(ModelID instance_id, const Point &shift, float rotation) : instance_id(instance_id), shift(shift), rotation(rotation) {}
bool operator==(const Instance &rhs) const { return this->instance_id == rhs.instance_id && this->shift == rhs.shift && this->rotation == rhs.rotation; } bool operator==(const Instance &rhs) const { return this->instance_id == rhs.instance_id && this->shift == rhs.shift && this->rotation == rhs.rotation; }
// ID of the corresponding ModelInstance. // ID of the corresponding ModelInstance.
ModelID instance_id; ModelID instance_id;
// Slic3r::Point objects in scaled G-code coordinates // Slic3r::Point objects in scaled G-code coordinates
Point shift; Point shift;
// Rotation along the Z axis, in radians. // Rotation along the Z axis, in radians.
float rotation; float rotation;
}; };
const std::vector<Instance>& instances() const { return m_instances; } const std::vector<Instance>& instances() const { return m_instances; }
bool has_mesh(SLAPrintObjectStep step) const; bool has_mesh(SLAPrintObjectStep step) const;
@ -142,15 +142,19 @@ public:
}; };
private: private:
template<class T> inline static T level(const SliceRecord &sr)
template <class T> inline static T level(const SliceRecord& sr) { {
static_assert(std::is_arithmetic<T>::value, "Arithmetic only!"); static_assert(std::is_arithmetic<T>::value, "Arithmetic only!");
return std::is_integral<T>::value ? T(sr.print_level()) : T(sr.slice_level()); return std::is_integral<T>::value ? T(sr.print_level())
: T(sr.slice_level());
} }
template <class T> inline static SliceRecord create_slice_record(T val) { template<class T> inline static SliceRecord create_slice_record(T val)
{
static_assert(std::is_arithmetic<T>::value, "Arithmetic only!"); static_assert(std::is_arithmetic<T>::value, "Arithmetic only!");
return std::is_integral<T>::value ? SliceRecord{ coord_t(val), 0.f, 0.f } : SliceRecord{ 0, float(val), 0.f }; return std::is_integral<T>::value
? SliceRecord{coord_t(val), 0.f, 0.f}
: SliceRecord{0, float(val), 0.f};
} }
// This is a template method for searching the slice index either by // This is a template method for searching the slice index either by
@ -241,11 +245,11 @@ protected:
~SLAPrintObject(); ~SLAPrintObject();
void config_apply(const ConfigBase &other, bool ignore_nonexistent = false) { this->m_config.apply(other, ignore_nonexistent); } void config_apply(const ConfigBase &other, bool ignore_nonexistent = false) { this->m_config.apply(other, ignore_nonexistent); }
void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false)
{ this->m_config.apply_only(other, keys, ignore_nonexistent); } { this->m_config.apply_only(other, keys, ignore_nonexistent); }
void set_trafo(const Transform3d& trafo, bool left_handed) { void set_trafo(const Transform3d& trafo, bool left_handed) {
m_transformed_rmesh.invalidate([this, &trafo, left_handed](){ m_trafo = trafo; m_left_handed = left_handed; }); m_transformed_rmesh.invalidate([this, &trafo, left_handed](){ m_trafo = trafo; m_left_handed = left_handed; });
} }
template<class InstVec> inline void set_instances(InstVec&& instances) { m_instances = std::forward<InstVec>(instances); } template<class InstVec> inline void set_instances(InstVec&& instances) { m_instances = std::forward<InstVec>(instances); }
@ -380,7 +384,7 @@ public:
void set_task(const TaskParams &params) override; void set_task(const TaskParams &params) override;
void process() override; void process() override;
void finalize() override; void finalize() override;
// Returns true if an object step is done on all objects and there's at least one object. // Returns true if an object step is done on all objects and there's at least one object.
bool is_step_done(SLAPrintObjectStep step) const; bool is_step_done(SLAPrintObjectStep step) const;
// Returns true if the last step was finished with success. // Returns true if the last step was finished with success.
bool finished() const override { return this->is_step_done(slaposSliceSupports) && this->Inherited::is_step_done(slapsRasterize); } bool finished() const override { return this->is_step_done(slaposSliceSupports) && this->Inherited::is_step_done(slapsRasterize); }

View File

@ -48,6 +48,27 @@ typedef double coordf_t;
//FIXME Better to use an inline function with an explicit return type. //FIXME Better to use an inline function with an explicit return type.
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); } //inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
#define scale_(val) ((val) / SCALING_FACTOR) #define scale_(val) ((val) / SCALING_FACTOR)
#if defined(_MSC_VER) && (_MSC_VER < 1910)
template<class Tf> inline coord_t scaled(Tf val)
#else
template<class Tf> inline constexpr coord_t scaled(Tf val)
#endif // _MSC_VER
{
static_assert (std::is_floating_point<Tf>::value, "Floating point only");
return coord_t(val / Tf(SCALING_FACTOR));
}
#if defined(_MSC_VER) && (_MSC_VER < 1910)
template<class Tf> inline Tf unscaled(coord_t val)
#else
template<class Tf> inline constexpr Tf unscaled(coord_t val)
#endif // _MSC_VER
{
static_assert (std::is_floating_point<Tf>::value, "Floating point only");
return Tf(val * Tf(SCALING_FACTOR));
}
#define SCALED_EPSILON scale_(EPSILON) #define SCALED_EPSILON scale_(EPSILON)
#define SLIC3R_DEBUG_OUT_PATH_PREFIX "out/" #define SLIC3R_DEBUG_OUT_PATH_PREFIX "out/"