diff --git a/src/libslic3r/Feature/Interlocking/VoxelUtils.cpp b/src/libslic3r/Feature/Interlocking/VoxelUtils.cpp index 303473ae48..e0f759f693 100644 --- a/src/libslic3r/Feature/Interlocking/VoxelUtils.cpp +++ b/src/libslic3r/Feature/Interlocking/VoxelUtils.cpp @@ -1,6 +1,8 @@ // Copyright (c) 2022 Ultimaker B.V. // CuraEngine is released under the terms of the AGPLv3 or higher. +#include + #include "VoxelUtils.hpp" #include "libslic3r/Geometry.hpp" #include "libslic3r/Fill/FillRectilinear.hpp" @@ -9,9 +11,7 @@ namespace Slic3r { -DilationKernel::DilationKernel(GridPoint3 kernel_size, DilationKernel::Type type) - : kernel_size_(kernel_size) - , type_(type) +DilationKernel::DilationKernel(GridPoint3 kernel_size, DilationKernel::Type type) : kernel_size_(kernel_size) { coord_t mult = kernel_size.x() * kernel_size.y() * kernel_size.z(); // multiplier for division to avoid rounding and to avoid use of floating point numbers relative_cells_.reserve(mult); @@ -129,61 +129,23 @@ bool VoxelUtils::walkDilatedPolygons(const ExPolygon& polys, coord_t z, const Di return walkPolygons(translated, z + translation.z(), dilate(kernel, process_cell_func)); } -bool VoxelUtils::walkAreas(const ExPolygon& polys, coord_t z, const std::function& process_cell_func) const +bool VoxelUtils::_walkAreas(const ExPolygon &ex_polygon, coord_t z, const std::function &process_cell_func) const { - ExPolygon translated = polys; - const Vec3crd translation = -cell_size_ / 2; // offset half a cell so that the dots of spreadDotsArea are centered on the middle of the cell isntead of the lower corners. - if (translation.x() && translation.y()) - { - translated.translate(Point(translation.x(), translation.y())); - } - return _walkAreas(translated, z, process_cell_func); -} - -static Points spreadDotsArea(const ExPolygon& polygons, Point grid_size) -{ - std::unique_ptr filler(Fill::new_from_type(ipAlignedRectilinear)); - filler->angle = Geometry::deg2rad(90.f); - filler->spacing = unscaled(grid_size.x()); - filler->bounding_box = get_extents(polygons); - - FillParams params; - params.density = 1.f; - params.anchor_length_max = 0; - - Surface surface(stInternal, polygons); - auto polylines = filler->fill_surface(&surface, params); - - Points result; - for (const Polyline& line : polylines) { - assert(line.size() == 2); - Point a = line[0]; - Point b = line[1]; - assert(a.x() == b.x()); - if (a.y() > b.y()) { - std::swap(a, b); - } - for (coord_t y = a.y() - (a.y() % grid_size.y()) - grid_size.y(); y < b.y(); y += grid_size.y()) { - if (y < a.y()) - continue; - result.emplace_back(a.x(), y); - } + Points grid_points; + try { + const BoundingBox ex_polygon_bbox = get_extents(ex_polygon); + grid_points = sample_grid_pattern(ex_polygon, cell_size_.x(), ex_polygon_bbox); + } catch (InfillFailedException &) { + BOOST_LOG_TRIVIAL(warning) << "Sampling ExPolygon failed."; } - return result; -} - -bool VoxelUtils::_walkAreas(const ExPolygon& polys, coord_t z, const std::function& process_cell_func) const -{ - Points skin_points = spreadDotsArea(polys, Point(cell_size_.x(), cell_size_.y())); - for (Point p : skin_points) - { - bool continue_ = process_cell_func(toGridPoint(Vec3crd(p.x() + cell_size_.x() / 2, p.y() + cell_size_.y() / 2, z))); - if (! continue_) - { + const Vec3crd grid_point_offset(cell_size_.x() / 2, cell_size_.y() / 2, z); + for (const Point &grid_point : grid_points) { + if (const bool continue_ = process_cell_func(toGridPoint(grid_point, grid_point_offset)); !continue_) { return false; } } + return true; } diff --git a/src/libslic3r/Feature/Interlocking/VoxelUtils.hpp b/src/libslic3r/Feature/Interlocking/VoxelUtils.hpp index 0348b69598..387b2de262 100644 --- a/src/libslic3r/Feature/Interlocking/VoxelUtils.hpp +++ b/src/libslic3r/Feature/Interlocking/VoxelUtils.hpp @@ -48,7 +48,6 @@ struct DilationKernel PRISM }; GridPoint3 kernel_size_; //!< Size of the kernel in number of voxel cells - Type type_; std::vector relative_cells_; //!< All offset positions relative to some reference cell which is to be dilated DilationKernel(GridPoint3 kernel_size, Type type); @@ -120,21 +119,9 @@ private: /*! * \warning the \p polys is assumed to be translated by half the cell_size in xy already */ - bool _walkAreas(const ExPolygon& polys, coord_t z, const std::function& process_cell_func) const; + bool _walkAreas(const ExPolygon &ex_polygon, coord_t z, const std::function &process_cell_func) const; public: - /*! - * Process all voxels inside the area of a polygons object. - * - * \warning The voxels along the area are not processed. Thin areas might not process any voxels at all. - * - * \param polys The area to fill - * \param z The height at which the polygons occur - * \param process_cell_func Function to perform on each voxel cell - * \return Whether executing was stopped short as indicated by the \p cell_processing_function - */ - bool walkAreas(const ExPolygon& polys, coord_t z, const std::function& process_cell_func) const; - /*! * Process all voxels inside the area of a polygons object. * For each voxel inside the polygon we process each of the offset voxels according to the kernel. @@ -170,6 +157,11 @@ public: */ std::function dilate(const DilationKernel& kernel, const std::function& process_cell_func) const; + GridPoint3 toGridPoint(const Point &point, const Vec3crd &offset) const + { + return toGridPoint(Vec3crd(point.x(), point.y(), 0) + offset); + } + GridPoint3 toGridPoint(const Vec3crd& point) const { return GridPoint3(toGridCoord(point.x(), 0), toGridCoord(point.y(), 1), toGridCoord(point.z(), 2));