mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 09:06:02 +08:00
Remove points out of extended part.
Allow multiple sample of the same 2d part of object in multiple heights
This commit is contained in:
parent
d69177f910
commit
88a1ddeb91
@ -18,6 +18,10 @@ namespace {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class NearPoints
|
class NearPoints
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Structure made for KDTree as function to
|
||||||
|
/// acess support point coordinate by index into global support point storage
|
||||||
|
/// </summary>
|
||||||
struct PointAccessor {
|
struct PointAccessor {
|
||||||
// multiple trees points into same data storage of all support points
|
// multiple trees points into same data storage of all support points
|
||||||
LayerSupportPoints *m_supports_ptr;
|
LayerSupportPoints *m_supports_ptr;
|
||||||
@ -39,21 +43,50 @@ public:
|
|||||||
explicit NearPoints(LayerSupportPoints* supports_ptr)
|
explicit NearPoints(LayerSupportPoints* supports_ptr)
|
||||||
: m_points(supports_ptr), m_tree(m_points) {}
|
: m_points(supports_ptr), m_tree(m_points) {}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove support points from KD-Tree which lay out of expolygons
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shapes">Define area where could be support points</param>
|
||||||
|
void remove_out_of(const ExPolygons &shapes) {
|
||||||
|
std::vector<size_t> indices = get_indices();
|
||||||
|
auto it = std::remove_if(indices.begin(), indices.end(),
|
||||||
|
[&pts = *m_points.m_supports_ptr, &shapes](size_t point_index) {
|
||||||
|
const Point& p = pts.at(point_index).position_on_layer;
|
||||||
|
return !std::any_of(shapes.begin(), shapes.end(),
|
||||||
|
[&p](const ExPolygon &shape) {
|
||||||
|
return shape.contains(p);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
indices.erase(it, indices.end());
|
||||||
|
m_tree.clear();
|
||||||
|
m_tree.build(indices); // consume indices
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add point new support point into global storage of support points
|
||||||
|
/// and pointer into tree structure of nearest points
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="point">New added point</param>
|
||||||
void add(LayerSupportPoint &&point) {
|
void add(LayerSupportPoint &&point) {
|
||||||
|
// IMPROVE: only add to existing tree, do not reconstruct tree
|
||||||
|
std::vector<size_t> indices = get_indices();
|
||||||
LayerSupportPoints &pts = *m_points.m_supports_ptr;
|
LayerSupportPoints &pts = *m_points.m_supports_ptr;
|
||||||
size_t index = pts.size();
|
size_t index = pts.size();
|
||||||
pts.emplace_back(std::move(point));
|
pts.emplace_back(std::move(point));
|
||||||
// IMPROVE: only add to existing tree, do not reconstruct tree
|
|
||||||
std::vector<size_t> indices = m_tree.get_nodes(); // copy
|
|
||||||
auto it = std::remove_if(indices.begin(), indices.end(),
|
|
||||||
[index](size_t i) { return i >= index; });
|
|
||||||
indices.erase(it, indices.end());
|
|
||||||
indices.push_back(index);
|
indices.push_back(index);
|
||||||
m_tree.clear();
|
m_tree.clear();
|
||||||
m_tree.build(indices); // consume indices
|
m_tree.build(indices); // consume indices
|
||||||
}
|
}
|
||||||
|
|
||||||
using CheckFnc = std::function<bool(const LayerSupportPoint &, const Point&)>;
|
using CheckFnc = std::function<bool(const LayerSupportPoint &, const Point&)>;
|
||||||
|
/// <summary>
|
||||||
|
/// Iterate over support points in 2d radius and search any of fnc with True.
|
||||||
|
/// Made for check wheather surrounding supports support current point p.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos">Center of search circle</param>
|
||||||
|
/// <param name="radius">Search circle radius</param>
|
||||||
|
/// <param name="fnc">Function to check supports point</param>
|
||||||
|
/// <returns>True wheny any of check function return true, otherwise False</returns>
|
||||||
bool exist_true_in_radius(const Point &pos, coord_t radius, const CheckFnc &fnc) const {
|
bool exist_true_in_radius(const Point &pos, coord_t radius, const CheckFnc &fnc) const {
|
||||||
std::vector<size_t> point_indices = find_nearby_points(m_tree, pos, radius);
|
std::vector<size_t> point_indices = find_nearby_points(m_tree, pos, radius);
|
||||||
return std::any_of(point_indices.begin(), point_indices.end(),
|
return std::any_of(point_indices.begin(), point_indices.end(),
|
||||||
@ -62,25 +95,41 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Merge another tree structure into current one.
|
||||||
|
/// Made for connection of two mesh parts.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="near_point">Another near points</param>
|
||||||
void merge(NearPoints &&near_point) {
|
void merge(NearPoints &&near_point) {
|
||||||
// need to have same global storage of support points
|
// need to have same global storage of support points
|
||||||
assert(m_points.m_supports_ptr == near_point.m_points.m_supports_ptr);
|
assert(m_points.m_supports_ptr == near_point.m_points.m_supports_ptr);
|
||||||
|
|
||||||
// IMPROVE: merge trees instead of rebuild
|
// IMPROVE: merge trees instead of rebuild
|
||||||
std::vector<size_t> indices = m_tree.get_nodes(); // copy
|
std::vector<size_t> indices = get_indices();
|
||||||
const std::vector<size_t>& indices2 = near_point.m_tree.get_nodes();
|
std::vector<size_t> indices2 = near_point.get_indices();
|
||||||
indices.insert(indices.end(), indices2.begin(), indices2.end());
|
// merge
|
||||||
auto it = std::remove_if(indices.begin(), indices.end(),
|
indices.insert(indices.end(),
|
||||||
[size = indices.size()](size_t i) { return i >= size; });
|
std::move_iterator(indices2.begin()),
|
||||||
indices.erase(it, indices.end());
|
std::move_iterator(indices2.end()));
|
||||||
// remove duplicit indices
|
// remove duplicit indices - Diamond case
|
||||||
std::sort(indices.begin(), indices.end());
|
std::sort(indices.begin(), indices.end());
|
||||||
it = std::unique(indices.begin(), indices.end());
|
auto it = std::unique(indices.begin(), indices.end());
|
||||||
indices.erase(it, indices.end());
|
indices.erase(it, indices.end());
|
||||||
// rebuild tree
|
// rebuild tree
|
||||||
m_tree.clear();
|
m_tree.clear();
|
||||||
m_tree.build(indices); // consume indices
|
m_tree.build(indices); // consume indices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<size_t> get_indices() const {
|
||||||
|
std::vector<size_t> indices = m_tree.get_nodes(); // copy
|
||||||
|
// nodes in tree contain "max values for size_t" on unused leaf of tree,
|
||||||
|
// when count of indices is not exactly power of 2
|
||||||
|
auto it = std::remove_if(indices.begin(), indices.end(),
|
||||||
|
[max_index = m_points.m_supports_ptr->size()](size_t i) { return i >= max_index; });
|
||||||
|
indices.erase(it, indices.end());
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -416,6 +465,23 @@ void prepare_supports_for_layer(LayerSupportPoints &supports, float layer_z,
|
|||||||
support.current_radius = static_cast<coord_t>(scale_(a.x() + t * (b.x() - a.x())));
|
support.current_radius = static_cast<coord_t>(scale_(a.x() + t * (b.x() - a.x())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Near points do not have to contain support points out of part.
|
||||||
|
/// Due to be able support in same area again(overhang above another overhang)
|
||||||
|
/// Wanted Side effect, it supports thiny part of overhangs
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="part_grid"></param>
|
||||||
|
/// <param name="part"></param>
|
||||||
|
void remove_supports_out_of_part(NearPoints& part_grid, const LayerPart &part) {
|
||||||
|
|
||||||
|
// Must be greater than surface texture and lower than self supporting area
|
||||||
|
// May be use maximal island distance
|
||||||
|
float delta = scale_(5.);
|
||||||
|
ExPolygons extend_shape = offset_ex(*part.shape, delta, ClipperLib::jtSquare);
|
||||||
|
part_grid.remove_out_of(extend_shape);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#include "libslic3r/Execution/ExecutionSeq.hpp"
|
#include "libslic3r/Execution/ExecutionSeq.hpp"
|
||||||
@ -581,8 +647,10 @@ LayerSupportPoints Slic3r::sla::generate_support_points(
|
|||||||
// first layer should have empty prev_part
|
// first layer should have empty prev_part
|
||||||
assert(layer_id != 0);
|
assert(layer_id != 0);
|
||||||
const LayerParts &prev_layer_parts = layers[layer_id - 1].parts;
|
const LayerParts &prev_layer_parts = layers[layer_id - 1].parts;
|
||||||
grids.push_back(create_part_grid(prev_layer_parts, part, prev_grids));
|
NearPoints part_grid = create_part_grid(prev_layer_parts, part, prev_grids);
|
||||||
support_part_overhangs(part, config, grids.back(), layer.print_z, maximal_radius);
|
remove_supports_out_of_part(part_grid, part);
|
||||||
|
support_part_overhangs(part, config, part_grid, layer.print_z, maximal_radius);
|
||||||
|
grids.push_back(std::move(part_grid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev_grids = std::move(grids);
|
prev_grids = std::move(grids);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user