Speed up support alignment

This commit is contained in:
Filip Sykala - NTB T15p 2024-10-08 12:01:44 +02:00 committed by Lukas Matena
parent ed3178f1c1
commit 02ca74cced
5 changed files with 37 additions and 33 deletions

View File

@ -726,6 +726,8 @@ Slic3r::Polygons diff(const Slic3r::Surfaces &subject, const Slic3r::Polygons &c
{ return _clipper(ClipperLib::ctDifference, ClipperUtils::SurfacesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::SinglePathProvider(subject.points), ClipperUtils::SinglePathProvider(clip.points), do_safety_offset); }
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::SinglePathProvider(subject.points), ClipperUtils::ExPolygonProvider(clip), do_safety_offset); }
Slic3r::Polygons intersection_clipped(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return intersection(subject, ClipperUtils::clip_clipper_polygons_with_subject_bbox(clip, get_extents(subject).inflated(SCALED_EPSILON)), do_safety_offset); }
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset)

View File

@ -477,6 +477,7 @@ inline Slic3r::Lines diff_ln(const Slic3r::Lines &subject, const Slic3r::Polygon
// Safety offset is applied to the clipping polygons only.
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
// Optimized version clipping the "clipping" polygon using clip_clipper_polygon_with_subject_bbox().

View File

@ -579,7 +579,7 @@ coord_t SampleIslandUtils::align_once(
continue; // do not align point with invalid cell
// IMPROVE: add intersection polygon with expolygon
Polygons intersections = Slic3r::intersection(island, ExPolygon(cell_polygon));
Polygons intersections = Slic3r::intersection(cell_polygon, island);
const Polygon *island_cell = nullptr;
if (intersections.size() == 1) {
island_cell = &intersections.front();

View File

@ -167,9 +167,9 @@ std::optional<Slic3r::Line> to_line(
const Halfedge_handle &edge,
double maximal_distance
) {
// validation slow down a lot, Never appear during algorithm tunning
assert(edge->is_valid());
if (!edge->is_valid())
return {};
//if (!edge->is_valid()) return {};
if (edge->has_source()) {
// source point of edge

View File

@ -1006,6 +1006,33 @@ std::pair<Slic3r::Point, Slic3r::Point> VoronoiGraphUtils::point_on_lines(
return {point_on_line(edge), point_on_line(edge->twin())};
}
namespace{
using namespace Slic3r;
using VD = Slic3r::Geometry::VoronoiDiagram;
double get_distance_sq(const VD::edge_type &edge, const Point &point, double &edge_ratio) {
// TODO: find closest point on curve edge
// if (edge.is_linear()) {
// get line foot point, inspired Geometry::foot_pt
Vec2d v0 = VoronoiGraphUtils::to_point_d(edge.vertex0());
Vec2d v = point.cast<double>() - v0;
Vec2d v1 = VoronoiGraphUtils::to_point_d(edge.vertex1());
Vec2d edge_dir = v1 - v0;
double l2 = edge_dir.squaredNorm();
edge_ratio = v.dot(edge_dir) / l2;
// IMPROVE: not neccesary to calculate point if (edge_ratio > 1 || edge_ratio < 0)
Point edge_point;
if (edge_ratio > 1.)
edge_point = v1.cast<coord_t>();
else if (edge_ratio < 0.)
edge_point = v0.cast<coord_t>();
else { // foot point
edge_point = (v0 + edge_dir * edge_ratio).cast<coord_t>();
}
return (point - edge_point).cast<double>().squaredNorm();
}
}
VoronoiGraph::Position VoronoiGraphUtils::align(
const VoronoiGraph::Position &position, const Point &to, double max_distance)
{
@ -1036,7 +1063,7 @@ VoronoiGraph::Position VoronoiGraphUtils::align(
process.emplace(node, max_distance);
}
double closest_distance = std::numeric_limits<double>::max();
double closest_distance_sq = std::numeric_limits<double>::max();
VoronoiGraph::Position closest;
std::set<const VoronoiGraph::Node *> done;
@ -1048,9 +1075,9 @@ VoronoiGraph::Position VoronoiGraphUtils::align(
for (const auto &neighbor : nd.node->neighbors) {
if (done.find(neighbor.node) != done.end()) continue;
double ratio;
double distance = get_distance(*neighbor.edge, to, ratio);
if (closest_distance > distance) {
closest_distance = distance;
double distance_sq = get_distance_sq(*neighbor.edge, to, ratio);
if (closest_distance_sq > distance_sq) {
closest_distance_sq = distance_sq;
closest = VoronoiGraph::Position(&neighbor, ratio);
}
double from_start = nd.distance + neighbor.length();
@ -1061,32 +1088,6 @@ VoronoiGraph::Position VoronoiGraphUtils::align(
return closest;
}
double VoronoiGraphUtils::get_distance(const VD::edge_type &edge,
const Point & point,
double & edge_ratio)
{
// TODO: find closest point on curve edge
//if (edge.is_linear()) {
// get line foot point, inspired Geometry::foot_pt
Vec2d v0 = to_point_d(edge.vertex0());
Vec2d v = point.cast<double>() - v0;
Vec2d v1 = to_point_d(edge.vertex1());
Vec2d edge_dir = v1 - v0;
double l2 = edge_dir.squaredNorm();
edge_ratio = v.dot(edge_dir) / l2;
// IMPROVE: not neccesary to calculate point if (edge_ratio > 1 || edge_ratio < 0)
Point edge_point;
if (edge_ratio > 1.) edge_point = v1.cast<coord_t>();
else if (edge_ratio < 0.) edge_point = v0.cast<coord_t>();
else { // foot point
edge_point = (v0 + edge_dir * edge_ratio).cast<coord_t>();
}
double distance = (point - edge_point).cast<double>().norm();
return distance;
}
const VoronoiGraph::Node *VoronoiGraphUtils::getFirstContourNode(
const VoronoiGraph &graph)
{