diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index fe57e3863b..a4c5abc9b7 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -510,7 +510,8 @@ struct Pad { const PoolConfig& cfg) : zlevel(ground_level + cfg.min_wall_height_mm/2) { ExPolygons basep; - base_plate(object_support_mesh, basep, cfg.min_wall_height_mm/*,layer_height*/); + base_plate(object_support_mesh, basep, + float(cfg.min_wall_height_mm)/*,layer_height*/); for(auto& bp : baseplate) basep.emplace_back(bp); create_base_pool(basep, tmesh, cfg); @@ -796,10 +797,19 @@ public: return meshcache; } + // WITH THE PAD double full_height() const { + double h = mesh_height(); + if(!pad().empty()) h += pad().cfg.min_wall_height_mm / 2; + return h; + } + + // WITHOUT THE PAD!!! + double mesh_height() const { if(!meshcache_valid) merged_mesh(); return model_height; } + }; template @@ -1674,37 +1684,16 @@ void SLASupportTree::merged_mesh_with_pad(TriangleMesh &outmesh) const { outmesh.merge(get_pad()); } -//void slice_mesh(const Contour3D& cntr, -// std::vector& mergev, -// const std::vector& heights) -//{ -// TriangleMesh&& m = mesh(cntr); -// TriangleMeshSlicer slicer(&m); -// SlicedSupports slout; -// slicer.slice(heights, &slout, [](){}); - -// for(size_t i = 0; i < slout.size(); i++) { -// // move the layers obtained from this mesh to the merge area -// mergev[i].emplace_back(std::move(slout[i])); -// } -//} - -//template void slice_part(const T& inp, -// std::vector& mergev, -// const std::vector& heights) -//{ -// for(auto& part : inp) { -// slice_mesh(part.mesh, mergev, heights); -// } -//} - SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const { if(init_layerh < 0) init_layerh = layerh; auto& stree = get(); - const auto modelh = float(stree.full_height()); + const auto modelh = float(stree.full_height()); auto gndlvl = float(this->m_impl->ground_level); + const Pad& pad = m_impl->pad(); + if(!pad.empty()) gndlvl -= float(pad.cfg.min_wall_height_mm/2); + std::vector heights = {gndlvl}; heights.reserve(size_t(modelh/layerh) + 1); @@ -1713,33 +1702,10 @@ SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const } TriangleMesh fullmesh = m_impl->merged_mesh(); + fullmesh.merge(get_pad()); TriangleMeshSlicer slicer(&fullmesh); SlicedSupports ret; - slicer.slice(heights, &ret, [](){}); - -// std::vector mergev(heights.size()); - -// slice_part(stree.heads(), mergev, heights); -// slice_part(stree.pillars(), mergev, heights); -// for(auto& pillar : stree.pillars()) slice_mesh(pillar.base, mergev, heights); -// slice_part(stree.junctions(), mergev, heights); -//// slice_part(stree.bridges(), mergev, heights); -//// slice_part(stree.compact_bridges(), mergev, heights); - -// // TODO: slicing base pool geometry - -// // We could make a union of the slices at the same height level but at the -// // end they will be loaded into the rasterizer and it will unite them -// // anyway. - -// SlicedSupports ret; ret.reserve(mergev.size()); -// for(SlicedSupports& level : mergev) { -// size_t count = 0; -// for(auto& v : level) count += v.size(); -// ret.emplace_back(); auto& merg = ret.back(); merg.reserve(count); -// for(ExPolygons& v : level) -// for(ExPolygon& ex : v) merg.emplace_back(ex); -// } + slicer.slice(heights, &ret, m_ctl.cancelfn); return ret; } @@ -1774,7 +1740,8 @@ double SLASupportTree::get_elevation() const SLASupportTree::SLASupportTree(const Model& model, const SupportConfig& cfg, - const Controller& ctl): m_impl(new Impl()) + const Controller& ctl): + m_impl(new Impl()), m_ctl(ctl) { generate(support_points(model), to_eigenmesh(model), cfg, ctl); } @@ -1782,14 +1749,15 @@ SLASupportTree::SLASupportTree(const Model& model, SLASupportTree::SLASupportTree(const PointSet &points, const EigenMesh3D& emesh, const SupportConfig &cfg, - const Controller &ctl): m_impl(new Impl()) + const Controller &ctl): + m_impl(new Impl()), m_ctl(ctl) { m_impl->ground_level = emesh.ground_level - cfg.object_elevation_mm; generate(points, emesh, cfg, ctl); } SLASupportTree::SLASupportTree(const SLASupportTree &c): - m_impl( new Impl(*c.m_impl)) {} + m_impl(new Impl(*c.m_impl)), m_ctl(c.m_ctl) {} SLASupportTree &SLASupportTree::operator=(const SLASupportTree &c) { diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index f89ff756cf..f0605a356f 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -69,10 +69,19 @@ struct SupportConfig { /// A Control structure for the support calculation. Consists of the status /// indicator callback and the stop condition predicate. struct Controller { + + // This will signal the status of the calculation to the front-end std::function statuscb = [](unsigned, const std::string&){}; + // Returns true if the calculation should be aborted. std::function stopcondition = [](){ return false; }; + + // Similar to cancel callback. This should check the stop condition and + // if true, throw an appropriate exception. (TriangleMeshSlicer needs this) + // consider it a hard abort. stopcondition is permits the algorithm to + // terminate itself + std::function cancelfn = [](){}; }; /// An index-triangle structure for libIGL functions. Also serves as an @@ -124,6 +133,7 @@ public: class SLASupportTree { class Impl; std::unique_ptr m_impl; + Controller m_ctl; Impl& get() { return *m_impl; } const Impl& get() const { return *m_impl; } diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index d5374fad46..da24e71c69 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -128,7 +128,7 @@ void SLAPrint::process() // Slicing the model object. This method is oversimplified and needs to // be compared with the fff slicing algorithm for verification - auto slice_model = [ilh](SLAPrintObject& po) { + auto slice_model = [this, ilh](SLAPrintObject& po) { auto lh = float(po.m_config.layer_height.getFloat()); TriangleMesh mesh = po.transformed_mesh(); @@ -141,7 +141,9 @@ void SLAPrint::process() for(float h = gnd + ilh; h < gnd + H; h += lh) heights.emplace_back(h); auto& layers = po.m_model_slices; - slicer.slice(heights, &layers, [](){}); + slicer.slice(heights, &layers, [this](){ + throw_if_canceled(); + }); }; auto support_points = [](SLAPrintObject& po) { @@ -176,6 +178,7 @@ void SLAPrint::process() set_status(unsigned(stinit + st*d), msg); }; ctl.stopcondition = [this](){ return canceled(); }; + ctl.cancelfn = [this]() { throw_if_canceled(); }; po.m_supportdata->support_tree_ptr.reset( new SLASupportTree(pts, emesh, scfg, ctl)); @@ -242,10 +245,16 @@ void SLAPrint::process() // For all print objects, go through its initial layers and place them // into the layers hash for(SLAPrintObject *o : m_objects) { + + double gndlvl = o->transformed_mesh().bounding_box().min(Z); + double lh = o->m_config.layer_height.getFloat(); SlicedModel & oslices = o->m_model_slices; for(int i = 0; i < oslices.size(); ++i) { - double h = ilh + i * lh; + int a = i == 0 ? 0 : 1; + int b = i == 0 ? 0 : i - 1; + + double h = gndlvl + ilh * a + b * lh; long long lyridx = static_cast(scale_(h)); auto& lyrs = levels[lyridx]; // this initializes a new record lyrs.emplace_back(oslices[i], o->m_instances); @@ -253,9 +262,16 @@ void SLAPrint::process() if(o->m_supportdata) { // deal with the support slices if present auto& sslices = o->m_supportdata->support_slices; + double el = o->m_config.support_object_elevation.getFloat(); + //TODO: remove next line: + el = SupportConfig().object_elevation_mm; for(int i = 0; i < sslices.size(); ++i) { - double h = ilh + i * lh; + int a = i == 0 ? 0 : 1; + int b = i == 0 ? 0 : i - 1; + + double h = gndlvl - el + ilh * a + b * lh; + long long lyridx = static_cast(scale_(h)); auto& lyrs = levels[lyridx]; lyrs.emplace_back(sslices[i], o->m_instances); @@ -392,7 +408,7 @@ void SLAPrint::process() }; // this would disable the rasterization step - m_stepmask[slapsRasterize] = false; +// m_stepmask[slapsRasterize] = false; for(size_t s = 0; s < print_program.size(); ++s) { auto currentstep = printsteps[s];