diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 4a1039b56..a92e55194 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -899,6 +899,39 @@ void its_shrink_to_fit(indexed_triangle_set &its) its.vertices.shrink_to_fit(); } +template +Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const TransformVertex &transform_fn, const float z) +{ + Points all_pts; + for (const stl_triangle_vertex_indices &tri : its.indices) { + const Vec3f pts[3] = { transform_fn(its.vertices[tri(0)]), transform_fn(its.vertices[tri(1)]), transform_fn(its.vertices[tri(2)]) }; + int iprev = 3; + for (int iedge = 0; iedge < 3; ++ iedge) { + const Vec3f &p1 = pts[iprev]; + const Vec3f &p2 = pts[iedge]; + if ((p1.z() < z && p2.z() > z) || (p2.z() < z && p1.z() > z)) { + // Edge crosses the z plane. Calculate intersection point with the plane. + float t = z / (p2.z() - p1.z()); + all_pts.emplace_back(scaled(p1.x() + (p2.x() - p1.x()) * t), scaled(p2.x() + (p2.y() - p2.y()) * t)); + } + if (p2.z() > z) + all_pts.emplace_back(scaled(p2.x()), scaled(p2.y())); + iprev = iedge; + } + } + return Geometry::convex_hull(std::move(all_pts)); +} + +Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Matrix3f &m, const float z) +{ + return its_convex_hull_2d_above(its, [m](const Vec3f &p){ return m * p; }, z); +} + +Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Transform3f &t, const float z) +{ + return its_convex_hull_2d_above(its, [t](const Vec3f &p){ return t * p; }, z); +} + // Generate the vertex list for a cube solid of arbitrary size in X/Y/Z. TriangleMesh make_cube(double x, double y, double z) { diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 5d3c15ec1..59a8715a0 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -113,6 +113,9 @@ int its_compactify_vertices(indexed_triangle_set &its, bool shrink_to_fit = true // Shrink the vectors of its.vertices and its.faces to a minimum size by reallocating the two vectors. void its_shrink_to_fit(indexed_triangle_set &its); +Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Matrix3f &m, const float z); +Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Transform3f &t, const float z); + TriangleMesh make_cube(double x, double y, double z); // Generate a TriangleMesh of a cylinder