mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 12:39:04 +08:00
SPE-2484: Fix "Infill failed" during interlocking generation.
This commit is contained in:
parent
6e5aa4b2e2
commit
3017ea0051
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2022 Ultimaker B.V.
|
// Copyright (c) 2022 Ultimaker B.V.
|
||||||
// CuraEngine is released under the terms of the AGPLv3 or higher.
|
// CuraEngine is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
#include "VoxelUtils.hpp"
|
#include "VoxelUtils.hpp"
|
||||||
#include "libslic3r/Geometry.hpp"
|
#include "libslic3r/Geometry.hpp"
|
||||||
#include "libslic3r/Fill/FillRectilinear.hpp"
|
#include "libslic3r/Fill/FillRectilinear.hpp"
|
||||||
@ -9,9 +11,7 @@
|
|||||||
namespace Slic3r
|
namespace Slic3r
|
||||||
{
|
{
|
||||||
|
|
||||||
DilationKernel::DilationKernel(GridPoint3 kernel_size, DilationKernel::Type type)
|
DilationKernel::DilationKernel(GridPoint3 kernel_size, DilationKernel::Type type) : kernel_size_(kernel_size)
|
||||||
: kernel_size_(kernel_size)
|
|
||||||
, type_(type)
|
|
||||||
{
|
{
|
||||||
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
|
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);
|
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));
|
return walkPolygons(translated, z + translation.z(), dilate(kernel, process_cell_func));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelUtils::walkAreas(const ExPolygon& polys, coord_t z, const std::function<bool(GridPoint3)>& process_cell_func) const
|
bool VoxelUtils::_walkAreas(const ExPolygon &ex_polygon, coord_t z, const std::function<bool(GridPoint3)> &process_cell_func) const
|
||||||
{
|
{
|
||||||
ExPolygon translated = polys;
|
Points grid_points;
|
||||||
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.
|
try {
|
||||||
if (translation.x() && translation.y())
|
const BoundingBox ex_polygon_bbox = get_extents(ex_polygon);
|
||||||
{
|
grid_points = sample_grid_pattern(ex_polygon, cell_size_.x(), ex_polygon_bbox);
|
||||||
translated.translate(Point(translation.x(), translation.y()));
|
} catch (InfillFailedException &) {
|
||||||
}
|
BOOST_LOG_TRIVIAL(warning) << "Sampling ExPolygon failed.";
|
||||||
return _walkAreas(translated, z, process_cell_func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Points spreadDotsArea(const ExPolygon& polygons, Point grid_size)
|
const Vec3crd grid_point_offset(cell_size_.x() / 2, cell_size_.y() / 2, z);
|
||||||
{
|
for (const Point &grid_point : grid_points) {
|
||||||
std::unique_ptr<Fill> filler(Fill::new_from_type(ipAlignedRectilinear));
|
if (const bool continue_ = process_cell_func(toGridPoint(grid_point, grid_point_offset)); !continue_) {
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VoxelUtils::_walkAreas(const ExPolygon& polys, coord_t z, const std::function<bool(GridPoint3)>& 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_)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ struct DilationKernel
|
|||||||
PRISM
|
PRISM
|
||||||
};
|
};
|
||||||
GridPoint3 kernel_size_; //!< Size of the kernel in number of voxel cells
|
GridPoint3 kernel_size_; //!< Size of the kernel in number of voxel cells
|
||||||
Type type_;
|
|
||||||
std::vector<GridPoint3> relative_cells_; //!< All offset positions relative to some reference cell which is to be dilated
|
std::vector<GridPoint3> relative_cells_; //!< All offset positions relative to some reference cell which is to be dilated
|
||||||
|
|
||||||
DilationKernel(GridPoint3 kernel_size, Type type);
|
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
|
* \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<bool(GridPoint3)>& process_cell_func) const;
|
bool _walkAreas(const ExPolygon &ex_polygon, coord_t z, const std::function<bool(GridPoint3)> &process_cell_func) const;
|
||||||
|
|
||||||
public:
|
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<bool(GridPoint3)>& process_cell_func) const;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Process all voxels inside the area of a polygons object.
|
* 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.
|
* For each voxel inside the polygon we process each of the offset voxels according to the kernel.
|
||||||
@ -170,6 +157,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::function<bool(GridPoint3)> dilate(const DilationKernel& kernel, const std::function<bool(GridPoint3)>& process_cell_func) const;
|
std::function<bool(GridPoint3)> dilate(const DilationKernel& kernel, const std::function<bool(GridPoint3)>& 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
|
GridPoint3 toGridPoint(const Vec3crd& point) const
|
||||||
{
|
{
|
||||||
return GridPoint3(toGridCoord(point.x(), 0), toGridCoord(point.y(), 1), toGridCoord(point.z(), 2));
|
return GridPoint3(toGridCoord(point.x(), 0), toGridCoord(point.y(), 1), toGridCoord(point.z(), 2));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user