Added anchors for the Lightning infill to better connect the infill and perimeters.

This commit is contained in:
Lukáš Hejl 2022-05-24 14:07:37 +02:00
parent 79b8acb7d5
commit bcd20650bf
8 changed files with 37 additions and 33 deletions

View File

@ -1,20 +1,25 @@
#include "../Print.hpp"
#include "../ShortestPath.hpp"
#include "FillLightning.hpp"
#include "Lightning/Generator.hpp"
#include "../Surface.hpp"
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <numeric>
namespace Slic3r::FillLightning {
Polylines Filler::fill_surface(const Surface *surface, const FillParams &params)
void Filler::_fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon expolygon,
Polylines &polylines_out)
{
const Layer &layer = generator->getTreesForLayer(this->layer_id);
return layer.convertToLines(to_polygons(surface->expolygon), generator->infilll_extrusion_width());
Polylines fill_lines = layer.convertToLines(to_polygons(expolygon), scaled<coord_t>(0.5 * this->spacing - this->overlap));
if (params.dont_connect() || fill_lines.size() <= 1) {
append(polylines_out, chain_polylines(std::move(fill_lines)));
} else
connect_infill(std::move(fill_lines), expolygon, polylines_out, this->spacing, params);
}
void GeneratorDeleter::operator()(Generator *p) {

View File

@ -24,8 +24,13 @@ public:
Generator *generator { nullptr };
protected:
Fill* clone() const override { return new Filler(*this); }
// Perform the fill.
Polylines fill_surface(const Surface *surface, const FillParams &params) override;
void _fill_surface_single(const FillParams &params,
unsigned int thickness_layers,
const std::pair<float, Point> &direction,
ExPolygon expolygon,
Polylines &polylines_out) override;
// Let the G-code export reoder the infill lines.
bool no_sort() const override { return false; }
};

View File

@ -176,7 +176,7 @@ protected:
const Point offset_loc = loc - m_grid_range.min;
const size_t flat_idx = m_grid_size.x() * offset_loc.y() + offset_loc.x();
assert(offset_loc.x() >= 0 && offset_loc.y() >= 0);
assert(flat_idx < m_grid_size.y() * m_grid_size.x());
assert(flat_idx < size_t(m_grid_size.y() * m_grid_size.x()));
return flat_idx;
}
};

View File

@ -7,7 +7,6 @@
#include "../../ClipperUtils.hpp"
#include "../../Layer.hpp"
#include "../../Print.hpp"
#include "../../Surface.hpp"
/* Possible future tasks/optimizations,etc.:
* - Improve connecting heuristic to favor connecting to shorter trees
@ -54,8 +53,6 @@ Generator::Generator(const PrintObject &print_object, const std::function<void()
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{
m_overhang_per_layer.resize(print_object.layers().size());
// FIXME: It can be adjusted to improve bonding between infill and perimeters.
const float infill_wall_offset = 0;// m_infill_extrusion_width;
Polygons infill_area_above;
//Iterate from top to bottom, to subtract the overhang areas above from the overhang areas on the layer below, to get only overhang in the top layer where it is overhanging.
@ -65,7 +62,7 @@ void Generator::generateInitialInternalOverhangs(const PrintObject &print_object
for (const LayerRegion* layerm : print_object.get_layer(layer_nr)->regions())
for (const Surface& surface : layerm->fill_surfaces.surfaces)
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
append(infill_area_here, infill_wall_offset == 0 ? surface.expolygon : offset(surface.expolygon, infill_wall_offset));
infill_area_here.emplace_back(surface.expolygon);
//Remove the part of the infill area that is already supported by the walls.
Polygons overhang = diff(offset(infill_area_here, -float(m_wall_supporting_radius)), infill_area_above);
@ -84,8 +81,6 @@ const Layer& Generator::getTreesForLayer(const size_t& layer_id) const
void Generator::generateTrees(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{
m_lightning_layers.resize(print_object.layers().size());
// FIXME: It can be adjusted to improve bonding between infill and perimeters.
const coord_t infill_wall_offset = 0;// m_infill_extrusion_width;
std::vector<Polygons> infill_outlines(print_object.layers().size(), Polygons());
@ -95,7 +90,7 @@ void Generator::generateTrees(const PrintObject &print_object, const std::functi
for (const LayerRegion *layerm : print_object.get_layer(layer_id)->regions())
for (const Surface &surface : layerm->fill_surfaces.surfaces)
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
append(infill_outlines[layer_id], infill_wall_offset == 0 ? surface.expolygon : offset(surface.expolygon, infill_wall_offset));
infill_outlines[layer_id].emplace_back(surface.expolygon);
}
// For various operations its beneficial to quickly locate nearby features on the polygon:

View File

@ -433,15 +433,14 @@ static unsigned int moveInside(const Polygons& polygons, Point& from, int distan
}
#endif
// Returns 'added someting'.
Polylines Layer::convertToLines(const Polygons& limit_to_outline, const coord_t line_width) const
Polylines Layer::convertToLines(const Polygons& limit_to_outline, const coord_t line_overlap) const
{
if (tree_roots.empty())
return {};
Polylines result_lines;
for (const auto &tree : tree_roots)
tree->convertToPolylines(result_lines, line_width);
tree->convertToPolylines(result_lines, line_overlap);
return intersection_pl(result_lines, limit_to_outline);
}

View File

@ -80,7 +80,7 @@ public:
coord_t wall_supporting_radius
);
Polylines convertToLines(const Polygons& limit_to_outline, coord_t line_width) const;
Polylines convertToLines(const Polygons& limit_to_outline, coord_t line_overlap) const;
coord_t getWeightedDistance(const Point& boundary_loc, const Point& unsupported_location);

View File

@ -347,12 +347,12 @@ coord_t Node::prune(const coord_t& pruning_distance)
return max_distance_pruned;
}
void Node::convertToPolylines(Polylines &output, const coord_t line_width) const
void Node::convertToPolylines(Polylines &output, const coord_t line_overlap) const
{
Polylines result;
result.emplace_back();
convertToPolylines(0, result);
removeJunctionOverlap(result, line_width);
removeJunctionOverlap(result, line_overlap);
append(output, std::move(result));
}
@ -376,9 +376,9 @@ void Node::convertToPolylines(size_t long_line_idx, Polylines &output) const
}
}
void Node::removeJunctionOverlap(Polylines &result_lines, const coord_t line_width) const
void Node::removeJunctionOverlap(Polylines &result_lines, const coord_t line_overlap) const
{
const coord_t reduction = line_width / 2; // TODO make configurable?
const coord_t reduction = line_overlap;
size_t res_line_idx = 0;
while (res_line_idx < result_lines.size()) {
Polyline &polyline = result_lines[res_line_idx];

View File

@ -46,7 +46,7 @@ public:
{
struct EnableMakeShared : public Node
{
EnableMakeShared(Arg&&...arg) : Node(std::forward<Arg>(arg)...) {}
explicit EnableMakeShared(Arg&&...arg) : Node(std::forward<Arg>(arg)...) {}
};
return std::make_shared<EnableMakeShared>(std::forward<Arg>(arg)...);
}
@ -179,16 +179,16 @@ public:
*/
bool hasOffspring(const NodeSPtr& to_be_checked) const;
protected:
Node() = delete; // Don't allow empty contruction
protected:
/*!
* Construct a new node, either for insertion in a tree or as root.
* \param p The physical location in the 2D layer that this node represents.
* Connecting other nodes to this node indicates that a line segment should
* be drawn between those two physical positions.
*/
Node(const Point& p, const std::optional<Point>& last_grounding_location = std::nullopt);
explicit Node(const Point& p, const std::optional<Point>& last_grounding_location = std::nullopt);
/*!
* Copy this node and its entire sub-tree.
@ -239,7 +239,7 @@ public:
*
* \param output all branches in this tree connected into polylines
*/
void convertToPolylines(Polylines &output, coord_t line_width) const;
void convertToPolylines(Polylines &output, coord_t line_overlap) const;
/*! If this was ever a direct child of the root, it'll have a previous grounding location.
*
@ -260,7 +260,7 @@ protected:
*/
void convertToPolylines(size_t long_line_idx, Polylines &output) const;
void removeJunctionOverlap(Polylines &polylines, coord_t line_width) const;
void removeJunctionOverlap(Polylines &polylines, coord_t line_overlap) const;
bool m_is_root;
Point m_p;