From d4d037792d086b009473eeb3e3bda20e60808f59 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 13 Nov 2019 15:55:37 +0100 Subject: Holes are now visible on slices in preview. --- src/libslic3r/Model.hpp | 6 +-- src/libslic3r/SLA/SupportTreeBuilder.hpp | 2 +- src/libslic3r/SLAPrint.cpp | 39 +++++++++++------ src/libslic3r/SLAPrint.hpp | 3 +- src/libslic3r/SLAPrintSteps.cpp | 72 ++++++++++++++++++++++++-------- 5 files changed, 87 insertions(+), 35 deletions(-) (limited to 'src/libslic3r') diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 9083e35e0..ccc48d52b 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -199,13 +199,13 @@ public: // This vector holds position of selected support points for SLA. The data are // saved in mesh coordinates to allow using them for several instances. // The format is (x, y, z, point_size, supports_island) - std::vector sla_support_points; + sla::SupportPoints sla_support_points; // To keep track of where the points came from (used for synchronization between // the SLA gizmo and the backend). - sla::PointsStatus sla_points_status = sla::PointsStatus::NoPoints; + sla::PointsStatus sla_points_status = sla::PointsStatus::NoPoints; // Holes to be drilled into the object so resin can flow out - std::vector sla_drain_holes; + sla::DrainHoles sla_drain_holes; /* This vector accumulates the total translation applied to the object by the center_around_origin() method. Callers might want to apply the same translation diff --git a/src/libslic3r/SLA/SupportTreeBuilder.hpp b/src/libslic3r/SLA/SupportTreeBuilder.hpp index 4859b004c..90cf417c8 100644 --- a/src/libslic3r/SLA/SupportTreeBuilder.hpp +++ b/src/libslic3r/SLA/SupportTreeBuilder.hpp @@ -74,7 +74,7 @@ Contour3D sphere(double rho, Portion portion = make_portion(0.0, 2.0*PI), // h: Height // ssteps: how many edges will create the base circle // sp: starting point -Contour3D cylinder(double r, double h, size_t ssteps, const Vec3d &sp = {0,0,0}); +Contour3D cylinder(double r, double h, size_t ssteps = 45, const Vec3d &sp = {0,0,0}); const constexpr long ID_UNSET = -1; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 53a0e8223..61723721e 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -414,6 +414,12 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, DynamicPrintConfig con model_object.sla_support_points = model_object_new.sla_support_points; } model_object.sla_points_status = model_object_new.sla_points_status; + + if (model_object.sla_drain_holes.size() != model_object_new.sla_drain_holes.size()) + { + model_object.sla_drain_holes = model_object_new.sla_drain_holes; + update_apply_status(it_print_object_status->print_object->invalidate_step(slaposHollowing)); + } // Copy the ModelObject name, input_file and instances. The instances will compared against PrintObject instances in the next step. model_object.name = model_object_new.name; @@ -1154,23 +1160,32 @@ const TriangleMesh &SLAPrintObject::transformed_mesh() const { return m_transformed_rmesh.get(); } -std::vector SLAPrintObject::transformed_support_points() const +template::value_type> +std::vector transform_pts(It from, It to, Trafo &&tr) { - assert(m_model_object != nullptr); - std::vector& spts = m_model_object->sla_support_points; - - // this could be cached as well - std::vector ret; - ret.reserve(spts.size()); - - for(sla::SupportPoint& sp : spts) { - Vec3f transformed_pos = trafo().cast() * sp.pos; - ret.emplace_back(transformed_pos, sp.head_front_radius, sp.is_new_island); + auto ret = reserve_vector(to - from); + for(auto it = from; it != to; ++it) { + V v = *it; + v.pos = tr * it->pos; + ret.emplace_back(std::move(v)); } - return ret; } +sla::SupportPoints SLAPrintObject::transformed_support_points() const +{ + assert(m_model_object != nullptr); + auto& spts = m_model_object->sla_support_points; + return transform_pts(spts.begin(), spts.end(), trafo().cast()); +} + +sla::DrainHoles SLAPrintObject::transformed_drainhole_points() const +{ + assert(m_model_object != nullptr); + auto& spts = m_model_object->sla_drain_holes; + return transform_pts(spts.begin(), spts.end(), trafo().cast()); +} + DynamicConfig SLAPrintStatistics::config() const { DynamicConfig config; diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 2edede109..8be69545e 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -83,7 +83,8 @@ public: // This will return the transformed mesh which is cached const TriangleMesh& transformed_mesh() const; - std::vector transformed_support_points() const; + sla::SupportPoints transformed_support_points() const; + sla::DrainHoles transformed_drainhole_points() const; // Get the needed Z elevation for the model geometry if supports should be // displayed. This Z offset should also be applied to the support diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp index 09d449576..55359cc5c 100644 --- a/src/libslic3r/SLAPrintSteps.cpp +++ b/src/libslic3r/SLAPrintSteps.cpp @@ -1,5 +1,9 @@ #include + +// Need the cylinder method for the the drainholes in hollowing step +#include + #include #include #include @@ -98,6 +102,42 @@ void SLAPrint::Steps::hollow_model(SLAPrintObject &po) BOOST_LOG_TRIVIAL(warning) << "Hollowed interior is empty!"; } +static void cut_drainholes(std::vector & obj_slices, + const std::vector &slicegrid, + float closing_radius, + const sla::DrainHoles & holes, + std::function thr) +{ + TriangleMesh mesh; + for (const sla::DrainHole &holept : holes) { + auto r = double(holept.radius); + auto h = double(holept.height); + sla::Contour3D hole = sla::cylinder(r, h); + Eigen::Quaterniond q; + q.setFromTwoVectors(Vec3d{0., 0., 1.}, holept.normal.cast()); + for(auto& p : hole.points) p = q * p + holept.pos.cast(); + mesh.merge(sla::to_triangle_mesh(hole)); + } + + if (mesh.empty()) return; + + mesh.require_shared_vertices(); + + TriangleMeshSlicer slicer(&mesh); + + std::vector hole_slices; + slicer.slice(slicegrid, closing_radius, &hole_slices, thr); + + if (obj_slices.size() != hole_slices.size()) + BOOST_LOG_TRIVIAL(warning) + << "Sliced object and drain-holes layer count does not match!"; + + size_t until = std::min(obj_slices.size(), hole_slices.size()); + + for (size_t i = 0; i < until; ++i) + obj_slices[i] = diff_ex(obj_slices[i], hole_slices[i]); +} + // The slicing will be performed on an imaginary 1D grid which starts from // the bottom of the bounding box created around the supported model. So // the first layer which is usually thicker will be part of the supports @@ -107,12 +147,10 @@ void SLAPrint::Steps::hollow_model(SLAPrintObject &po) // of it. In any case, the model and the supports have to be sliced in the // same imaginary grid (the height vector argument to TriangleMeshSlicer). void SLAPrint::Steps::slice_model(SLAPrintObject &po) -{ - +{ TriangleMesh hollowed_mesh; - bool is_hollowing = po.m_config.hollowing_enable.getBool() && - po.m_hollowing_data; + bool is_hollowing = po.m_config.hollowing_enable.getBool() && po.m_hollowing_data; if (is_hollowing) { hollowed_mesh = po.transformed_mesh(); @@ -120,8 +158,7 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) hollowed_mesh.require_shared_vertices(); } - const TriangleMesh &mesh = is_hollowing ? hollowed_mesh : - po.transformed_mesh(); + const TriangleMesh &mesh = is_hollowing ? hollowed_mesh : po.transformed_mesh(); // We need to prepare the slice index... @@ -163,10 +200,13 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) TriangleMeshSlicer slicer(&mesh); po.m_model_slices.clear(); - slicer.slice(po.m_model_height_levels, - float(po.config().slice_closing_radius.value), - &po.m_model_slices, - [this](){ m_print->throw_if_canceled(); }); + float closing_r = float(po.config().slice_closing_radius.value); + auto thr = [this]() { m_print->throw_if_canceled(); }; + auto &slice_grid = po.m_model_height_levels; + slicer.slice(slice_grid, closing_r, &po.m_model_slices, thr); + + sla::DrainHoles drainholes = po.transformed_drainhole_points(); + cut_drainholes(po.m_model_slices, slice_grid, closing_r, drainholes, thr); auto mit = slindex_it; double doffs = m_print->m_printer_config.absolute_correction.getFloat(); @@ -183,8 +223,7 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po) mit->set_model_slice_idx(po, id); ++mit; } - if(po.m_config.supports_enable.getBool() || - po.m_config.pad_enable.getBool()) + if(po.m_config.supports_enable.getBool() || po.m_config.pad_enable.getBool()) { po.m_supportdata.reset( new SLAPrintObject::SupportData(po.transformed_mesh()) ); @@ -324,8 +363,7 @@ void SLAPrint::Steps::generate_pad(SLAPrintObject &po) { // and before the supports had been sliced. (or the slicing has to be // repeated) - if(po.m_config.pad_enable.getBool()) - { + if(po.m_config.pad_enable.getBool()) { // Get the distilled pad configuration from the config sla::PadConfig pcfg = make_pad_cfg(po.m_config); @@ -368,13 +406,11 @@ void SLAPrint::Steps::slice_supports(SLAPrintObject &po) { if(sd) sd->support_slices.clear(); // Don't bother if no supports and no pad is present. - if (!po.m_config.supports_enable.getBool() && - !po.m_config.pad_enable.getBool()) + if (!po.m_config.supports_enable.getBool() && !po.m_config.pad_enable.getBool()) return; if(sd && sd->support_tree_ptr) { - - std::vector heights; heights.reserve(po.m_slice_index.size()); + auto heights = reserve_vector(po.m_slice_index.size()); for(auto& rec : po.m_slice_index) heights.emplace_back(rec.slice_level()); -- cgit v1.2.3