From 27ad859d4d49fe4042ef2e366bb93d4a43f9432d Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 14 Dec 2018 16:15:59 +0100 Subject: [PATCH] SLA supports - first attempt at supporting islands --- src/libslic3r/SLA/SLAAutoSupports.cpp | 91 ++++++++++++++++++++++++++- src/libslic3r/SLA/SLAAutoSupports.hpp | 4 +- src/libslic3r/SLAPrint.cpp | 83 +++++++++++++++--------- src/libslic3r/SLAPrint.hpp | 3 +- src/slic3r/GUI/GLGizmo.cpp | 4 +- src/slic3r/GUI/GLGizmo.hpp | 1 - 6 files changed, 152 insertions(+), 34 deletions(-) diff --git a/src/libslic3r/SLA/SLAAutoSupports.cpp b/src/libslic3r/SLA/SLAAutoSupports.cpp index ca04b1bee6..dd737c9886 100644 --- a/src/libslic3r/SLA/SLAAutoSupports.cpp +++ b/src/libslic3r/SLA/SLAAutoSupports.cpp @@ -3,12 +3,15 @@ #include "SLAAutoSupports.hpp" #include "Model.hpp" +#include "ExPolygon.hpp" +#include "SVG.hpp" +#include "Point.hpp" #include namespace Slic3r { - +namespace SLAAutoSupports { SLAAutoSupports::SLAAutoSupports(ModelObject& mo, const SLAAutoSupports::Config& c) : m_model_object(mo), mesh(), m_config(c) {} @@ -152,4 +155,90 @@ float SLAAutoSupports::get_required_density(float angle) const + + + + +void output_expolygons(const ExPolygons& expolys, std::string filename) +{ + BoundingBox bb(Point(-30000000, -30000000), Point(30000000, 30000000)); + Slic3r::SVG svg_cummulative(filename, bb); + for (size_t i = 0; i < expolys.size(); ++ i) { + /*Slic3r::SVG svg("single"+std::to_string(i)+".svg", bb); + svg.draw(expolys[i]); + svg.draw_outline(expolys[i].contour, "black", scale_(0.05)); + svg.draw_outline(expolys[i].holes, "blue", scale_(0.05)); + svg.Close();*/ + + svg_cummulative.draw(expolys[i]); + svg_cummulative.draw_outline(expolys[i].contour, "black", scale_(0.05)); + svg_cummulative.draw_outline(expolys[i].holes, "blue", scale_(0.05)); + } +} + +std::vector find_islands(const std::vector& slices, const std::vector& heights) +{ + std::vector support_points_out; + + struct PointAccessor { + const Point* operator()(const Point &pt) const { return &pt; } + }; + typedef ClosestPointInRadiusLookup ClosestPointLookupType; + + for (unsigned int i = 0; i find_islands(const std::vector& slices, const std::vector& heights); +} // namespace SLAAutoSupports } // namespace Slic3r diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 0c61b591bb..062c759de5 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1,6 +1,7 @@ #include "SLAPrint.hpp" #include "SLA/SLASupportTree.hpp" #include "SLA/SLABasePool.hpp" +#include "SLA/SLAAutoSupports.hpp" #include "MTUtils.hpp" #include @@ -36,8 +37,7 @@ namespace { const std::array OBJ_STEP_LEVELS = { 10, // slaposObjectSlice, - 10, // slaposSupportIslands, - 20, // slaposSupportPoints, + 30, // slaposSupportPoints, 25, // slaposSupportTree, 25, // slaposBasePool, 5, // slaposSliceSupports, @@ -47,8 +47,7 @@ const std::array OBJ_STEP_LEVELS = const std::array OBJ_STEP_LABELS = { L("Slicing model"), // slaposObjectSlice, - L("Generating islands"), // slaposSupportIslands, - L("Scanning model structure"), // slaposSupportPoints, + L("Generating support points"), // slaposSupportPoints, L("Generating support tree"), // slaposSupportTree, L("Generating base pool"), // slaposBasePool, L("Slicing supports"), // slaposSliceSupports, @@ -420,6 +419,24 @@ void swapXY(ExPolygon& expoly) { } +std::vector SLAPrint::calculate_heights(const BoundingBoxf3& bb3d, float elevation, float initial_layer_height, float layer_height) const +{ + std::vector heights; + float minZ = float(bb3d.min(Z)) - float(elevation); + float maxZ = float(bb3d.max(Z)) ; + auto flh = float(layer_height); + auto gnd = float(bb3d.min(Z)); + + // The first layer (the one before the initial height) is added only + // if there is no pad and no elevation value + if(minZ >= gnd) heights.emplace_back(minZ); + + for(float h = minZ + initial_layer_height; h < maxZ; h += flh) + if(h >= gnd) heights.emplace_back(h); + return heights; +} + + void SLAPrint::process() { using namespace sla; @@ -455,24 +472,9 @@ void SLAPrint::process() TriangleMesh mesh = po.transformed_mesh(); TriangleMeshSlicer slicer(&mesh); - auto bb3d = mesh.bounding_box(); - - double elevation = po.get_elevation(); - - float minZ = float(bb3d.min(Z)) - float(elevation); - float maxZ = float(bb3d.max(Z)) ; - auto flh = float(lh); - auto gnd = float(bb3d.min(Z)); // The 1D grid heights - std::vector heights; - - // The first layer (the one before the initial height) is added only - // if there is no pad and no elevation value - if(minZ >= gnd) heights.emplace_back(minZ); - - for(float h = minZ + ilh; h < maxZ; h += flh) - if(h >= gnd) heights.emplace_back(h); + std::vector heights = calculate_heights(mesh.bounding_box(), po.get_elevation(), ilh, lh); auto& layers = po.m_model_slices; layers.clear(); slicer.slice(heights, &layers, [this](){ throw_if_canceled(); }); @@ -480,8 +482,8 @@ void SLAPrint::process() // this procedure simply converts the points and copies them into // the support data cache - auto support_points = [](SLAPrintObject& po) { - ModelObject& mo = *po.m_model_object; + /*auto support_points = [](SLAPrintObject& po) { + const ModelObject& mo = *po.m_model_object; po.m_supportdata.reset(new SLAPrintObject::SupportData()); if(!mo.sla_support_points.empty()) { @@ -497,6 +499,36 @@ void SLAPrint::process() " Hint: create some support points or disable support " "creation.")); } + };*/ + + // In this step we check the slices, identify island and cover them with + // support points. Then we sprinkle the rest of the mesh. + auto support_points = [this, ilh](SLAPrintObject& po) { + // find islands to support + double lh = po.m_config.layer_height.getFloat(); + std::vector heights = calculate_heights(po.transformed_mesh().bounding_box(), po.get_elevation(), ilh, lh); + //SLAAutoSupports auto_supports(po.get_model_slices(), heights, *po.m_model_object); + std::vector points = SLAAutoSupports::find_islands(po.get_model_slices(), heights); + + // TODO: + + // create mesh in igl format + + // cover the islands with points, use igl to get precise z coordinate + + // sprinkle the mesh with points (SLAAutoSupports::generate()) + + + /*for (const auto& p: points) + std::cout << p(0) << " " << p(1) << " " << p(2) << std::endl; + std::cout << std::endl; + */ + //for (auto& p: points) + // p = po.trafo().inverse() * p; + + po.m_supportdata.reset(new SLAPrintObject::SupportData()); + po.m_supportdata->emesh = sla::to_eigenmesh(po.transformed_mesh()); + po.m_supportdata->support_points = sla::to_point_set(points); }; // In this step we create the supports @@ -803,8 +835,7 @@ void SLAPrint::process() // This is the actual order of steps done on each PrintObject std::array objectsteps = { - slaposObjectSlice, // Support Islands will need this step - slaposSupportIslands, + slaposObjectSlice, // SupportPoints will need this step slaposSupportPoints, slaposSupportTree, slaposBasePool, @@ -815,7 +846,6 @@ void SLAPrint::process() std::array pobj_program = { slice_model, - [](SLAPrintObject&){}, // slaposSupportIslands now empty support_points, support_tree, base_pool, @@ -1014,9 +1044,6 @@ bool SLAPrintObject::invalidate_step(SLAPrintObjectStep step) // propagate to dependent steps if (step == slaposObjectSlice) { invalidated |= this->invalidate_all_steps(); - } else if (step == slaposSupportIslands) { - invalidated |= this->invalidate_steps({ slaposSupportPoints, slaposSupportTree, slaposBasePool, slaposSliceSupports, slaposIndexSlices }); - invalidated |= m_print->invalidate_step(slapsRasterize); } else if (step == slaposSupportPoints) { invalidated |= this->invalidate_steps({ slaposSupportTree, slaposBasePool, slaposSliceSupports, slaposIndexSlices }); invalidated |= m_print->invalidate_step(slapsRasterize); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 4a08767676..3c05b49324 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -18,7 +18,6 @@ enum SLAPrintStep : unsigned int { enum SLAPrintObjectStep : unsigned int { slaposObjectSlice, - slaposSupportIslands, slaposSupportPoints, slaposSupportTree, slaposBasePool, @@ -226,6 +225,8 @@ private: lref(std::cref(lyr)), copies(std::cref(cp)) {} }; + std::vector calculate_heights(const BoundingBoxf3& bb, float elevation, float initial_layer_height, float layer_height) const; + // One level may contain multiple slices from multiple objects and their // supports using LayerRefs = std::vector; diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index 7f62d09011..2ed7fa1816 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -2189,12 +2189,12 @@ void GLGizmoSlaSupports::on_render_input_window(float x, float y, const GLCanvas if (generate) { const DynamicPrintConfig& cfg = *wxGetApp().get_tab(Preset::TYPE_SLA_PRINT)->get_config(); - SLAAutoSupports::Config config; + SLAAutoSupports::SLAAutoSupports::Config config; config.density_at_horizontal = cfg.opt_int("support_density_at_horizontal") / 10000.f; config.density_at_45 = cfg.opt_int("support_density_at_45") / 10000.f; config.minimal_z = cfg.opt_float("support_minimal_z"); - SLAAutoSupports sas(*m_model_object, config); + SLAAutoSupports::SLAAutoSupports sas(*m_model_object, config); sas.generate(); m_grabbers.clear(); for (const Vec3f& point : m_model_object->sla_support_points) { diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index bfec0965e4..2588080b26 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -436,7 +436,6 @@ protected: class GLGizmoSlaSupports : public GLGizmoBase { private: - SLAAutoSupports* m_sas = nullptr; ModelObject* m_model_object = nullptr; #if ENABLE_SLA_SUPPORT_GIZMO_MOD ModelObject* m_old_model_object = nullptr;