Added anchors for the Lightning infill to better connect the infill and perimeters.
This commit is contained in:
parent
79b8acb7d5
commit
bcd20650bf
@ -1,20 +1,25 @@
|
|||||||
#include "../Print.hpp"
|
#include "../Print.hpp"
|
||||||
|
#include "../ShortestPath.hpp"
|
||||||
|
|
||||||
#include "FillLightning.hpp"
|
#include "FillLightning.hpp"
|
||||||
#include "Lightning/Generator.hpp"
|
#include "Lightning/Generator.hpp"
|
||||||
#include "../Surface.hpp"
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cmath>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
namespace Slic3r::FillLightning {
|
namespace Slic3r::FillLightning {
|
||||||
|
|
||||||
Polylines Filler::fill_surface(const Surface *surface, const FillParams ¶ms)
|
void Filler::_fill_surface_single(
|
||||||
|
const FillParams ¶ms,
|
||||||
|
unsigned int thickness_layers,
|
||||||
|
const std::pair<float, Point> &direction,
|
||||||
|
ExPolygon expolygon,
|
||||||
|
Polylines &polylines_out)
|
||||||
{
|
{
|
||||||
const Layer &layer = generator->getTreesForLayer(this->layer_id);
|
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) {
|
void GeneratorDeleter::operator()(Generator *p) {
|
||||||
|
@ -24,8 +24,13 @@ public:
|
|||||||
Generator *generator { nullptr };
|
Generator *generator { nullptr };
|
||||||
protected:
|
protected:
|
||||||
Fill* clone() const override { return new Filler(*this); }
|
Fill* clone() const override { return new Filler(*this); }
|
||||||
// Perform the fill.
|
|
||||||
Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override;
|
void _fill_surface_single(const FillParams ¶ms,
|
||||||
|
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.
|
// Let the G-code export reoder the infill lines.
|
||||||
bool no_sort() const override { return false; }
|
bool no_sort() const override { return false; }
|
||||||
};
|
};
|
||||||
|
@ -176,7 +176,7 @@ protected:
|
|||||||
const Point offset_loc = loc - m_grid_range.min;
|
const Point offset_loc = loc - m_grid_range.min;
|
||||||
const size_t flat_idx = m_grid_size.x() * offset_loc.y() + offset_loc.x();
|
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(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;
|
return flat_idx;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include "../../ClipperUtils.hpp"
|
#include "../../ClipperUtils.hpp"
|
||||||
#include "../../Layer.hpp"
|
#include "../../Layer.hpp"
|
||||||
#include "../../Print.hpp"
|
#include "../../Print.hpp"
|
||||||
#include "../../Surface.hpp"
|
|
||||||
|
|
||||||
/* Possible future tasks/optimizations,etc.:
|
/* Possible future tasks/optimizations,etc.:
|
||||||
* - Improve connecting heuristic to favor connecting to shorter trees
|
* - 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)
|
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||||
{
|
{
|
||||||
m_overhang_per_layer.resize(print_object.layers().size());
|
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;
|
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.
|
//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 LayerRegion* layerm : print_object.get_layer(layer_nr)->regions())
|
||||||
for (const Surface& surface : layerm->fill_surfaces.surfaces)
|
for (const Surface& surface : layerm->fill_surfaces.surfaces)
|
||||||
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
|
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.
|
//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);
|
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)
|
void Generator::generateTrees(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||||
{
|
{
|
||||||
m_lightning_layers.resize(print_object.layers().size());
|
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());
|
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 LayerRegion *layerm : print_object.get_layer(layer_id)->regions())
|
||||||
for (const Surface &surface : layerm->fill_surfaces.surfaces)
|
for (const Surface &surface : layerm->fill_surfaces.surfaces)
|
||||||
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
|
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:
|
// For various operations its beneficial to quickly locate nearby features on the polygon:
|
||||||
|
@ -433,15 +433,14 @@ static unsigned int moveInside(const Polygons& polygons, Point& from, int distan
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Returns 'added someting'.
|
Polylines Layer::convertToLines(const Polygons& limit_to_outline, const coord_t line_overlap) const
|
||||||
Polylines Layer::convertToLines(const Polygons& limit_to_outline, const coord_t line_width) const
|
|
||||||
{
|
{
|
||||||
if (tree_roots.empty())
|
if (tree_roots.empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
Polylines result_lines;
|
Polylines result_lines;
|
||||||
for (const auto &tree : tree_roots)
|
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);
|
return intersection_pl(result_lines, limit_to_outline);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ public:
|
|||||||
coord_t wall_supporting_radius
|
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);
|
coord_t getWeightedDistance(const Point& boundary_loc, const Point& unsupported_location);
|
||||||
|
|
||||||
|
@ -347,12 +347,12 @@ coord_t Node::prune(const coord_t& pruning_distance)
|
|||||||
return max_distance_pruned;
|
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;
|
Polylines result;
|
||||||
result.emplace_back();
|
result.emplace_back();
|
||||||
convertToPolylines(0, result);
|
convertToPolylines(0, result);
|
||||||
removeJunctionOverlap(result, line_width);
|
removeJunctionOverlap(result, line_overlap);
|
||||||
append(output, std::move(result));
|
append(output, std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,10 +376,10 @@ 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;
|
size_t res_line_idx = 0;
|
||||||
while (res_line_idx < result_lines.size()) {
|
while (res_line_idx < result_lines.size()) {
|
||||||
Polyline &polyline = result_lines[res_line_idx];
|
Polyline &polyline = result_lines[res_line_idx];
|
||||||
if (polyline.size() <= 1) {
|
if (polyline.size() <= 1) {
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
{
|
{
|
||||||
struct EnableMakeShared : public Node
|
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)...);
|
return std::make_shared<EnableMakeShared>(std::forward<Arg>(arg)...);
|
||||||
}
|
}
|
||||||
@ -179,16 +179,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool hasOffspring(const NodeSPtr& to_be_checked) const;
|
bool hasOffspring(const NodeSPtr& to_be_checked) const;
|
||||||
|
|
||||||
protected:
|
|
||||||
Node() = delete; // Don't allow empty contruction
|
Node() = delete; // Don't allow empty contruction
|
||||||
|
|
||||||
|
protected:
|
||||||
/*!
|
/*!
|
||||||
* Construct a new node, either for insertion in a tree or as root.
|
* 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.
|
* \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
|
* Connecting other nodes to this node indicates that a line segment should
|
||||||
* be drawn between those two physical positions.
|
* 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.
|
* Copy this node and its entire sub-tree.
|
||||||
@ -239,7 +239,7 @@ public:
|
|||||||
*
|
*
|
||||||
* \param output all branches in this tree connected into polylines
|
* \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.
|
/*! 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 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;
|
bool m_is_root;
|
||||||
Point m_p;
|
Point m_p;
|
||||||
|
Loading…
Reference in New Issue
Block a user