diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index a5ff5a2591..fd23142e0d 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -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) diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp index d38bd2aa83..70dec5dd99 100644 --- a/src/libslic3r/ClipperUtils.hpp +++ b/src/libslic3r/ClipperUtils.hpp @@ -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(). diff --git a/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp b/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp index e45aa8af69..7346773871 100644 --- a/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp +++ b/src/libslic3r/SLA/SupportIslands/SampleIslandUtils.cpp @@ -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(); diff --git a/src/libslic3r/SLA/SupportIslands/VoronoiDiagramCGAL.cpp b/src/libslic3r/SLA/SupportIslands/VoronoiDiagramCGAL.cpp index 412877b412..20ab3761d3 100644 --- a/src/libslic3r/SLA/SupportIslands/VoronoiDiagramCGAL.cpp +++ b/src/libslic3r/SLA/SupportIslands/VoronoiDiagramCGAL.cpp @@ -167,9 +167,9 @@ std::optional 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 diff --git a/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp b/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp index 1103e72d08..66cdd4924f 100644 --- a/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp +++ b/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp @@ -1006,6 +1006,33 @@ std::pair 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() - 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(); + else if (edge_ratio < 0.) + edge_point = v0.cast(); + else { // foot point + edge_point = (v0 + edge_dir * edge_ratio).cast(); + } + return (point - edge_point).cast().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::max(); + double closest_distance_sq = std::numeric_limits::max(); VoronoiGraph::Position closest; std::set 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() - 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(); - else if (edge_ratio < 0.) edge_point = v0.cast(); - else { // foot point - edge_point = (v0 + edge_dir * edge_ratio).cast(); - } - double distance = (point - edge_point).cast().norm(); - return distance; -} - - const VoronoiGraph::Node *VoronoiGraphUtils::getFirstContourNode( const VoronoiGraph &graph) {