Fixed triangulation of meshes split by the cut tool.

This commit is contained in:
Vojtech Bubnik 2021-09-21 11:07:33 +02:00
parent 40e4116d9a
commit 7e3306c68f
2 changed files with 31 additions and 11 deletions

View file

@ -418,7 +418,7 @@ template<class Tout = double,
class = FloatingOnly<Tout>> class = FloatingOnly<Tout>>
inline constexpr Tout unscaled(const Tin &v) noexcept inline constexpr Tout unscaled(const Tin &v) noexcept
{ {
return Tout(v * Tout(SCALING_FACTOR)); return Tout(v) * Tout(SCALING_FACTOR);
} }
// Unscaling for Eigen vectors. Input base type can be arithmetic, output base // Unscaling for Eigen vectors. Input base type can be arithmetic, output base
@ -432,7 +432,7 @@ template<class Tout = double,
inline constexpr Eigen::Matrix<Tout, N, EigenArgs...> inline constexpr Eigen::Matrix<Tout, N, EigenArgs...>
unscaled(const Eigen::Matrix<Tin, N, EigenArgs...> &v) noexcept unscaled(const Eigen::Matrix<Tin, N, EigenArgs...> &v) noexcept
{ {
return v.template cast<Tout>() * SCALING_FACTOR; return v.template cast<Tout>() * Tout(SCALING_FACTOR);
} }
// Align a coordinate to a grid. The coordinate may be negative, // Align a coordinate to a grid. The coordinate may be negative,

View file

@ -1989,7 +1989,7 @@ static void triangulate_slice(
std::vector<int> map_duplicate_vertex(int(its.vertices.size()) - num_original_vertices, -1); std::vector<int> map_duplicate_vertex(int(its.vertices.size()) - num_original_vertices, -1);
int i = 0; int i = 0;
int k = 0; int k = 0;
for (; i < int(map_vertex_to_index.size()); ++ i) { for (; i < int(map_vertex_to_index.size());) {
map_vertex_to_index[k ++] = map_vertex_to_index[i]; map_vertex_to_index[k ++] = map_vertex_to_index[i];
const Vec2f &ipos = map_vertex_to_index[i].first; const Vec2f &ipos = map_vertex_to_index[i].first;
const int iidx = map_vertex_to_index[i].second; const int iidx = map_vertex_to_index[i].second;
@ -2004,6 +2004,7 @@ static void triangulate_slice(
// map to the first vertex // map to the first vertex
map_duplicate_vertex[jidx - num_original_vertices] = iidx; map_duplicate_vertex[jidx - num_original_vertices] = iidx;
} }
i = j;
} }
map_vertex_to_index.erase(map_vertex_to_index.begin() + k, map_vertex_to_index.end()); map_vertex_to_index.erase(map_vertex_to_index.begin() + k, map_vertex_to_index.end());
for (stl_triangle_vertex_indices &f : its.indices) for (stl_triangle_vertex_indices &f : its.indices)
@ -2097,6 +2098,10 @@ void cut_mesh(const indexed_triangle_set &mesh, float z, indexed_triangle_set *u
lower->indices.reserve(mesh.indices.size()); lower->indices.reserve(mesh.indices.size());
} }
#ifndef NDEBUG
size_t num_open_edges_old = triangulate_caps ? its_num_open_edges(mesh) : 0;
#endif // NDEBUG
// To triangulate the caps after slicing. // To triangulate the caps after slicing.
IntersectionLines upper_lines, lower_lines; IntersectionLines upper_lines, lower_lines;
std::vector<int> upper_slice_vertices, lower_slice_vertices; std::vector<int> upper_slice_vertices, lower_slice_vertices;
@ -2165,11 +2170,12 @@ void cut_mesh(const indexed_triangle_set &mesh, float z, indexed_triangle_set *u
stl_vertex v0v1, v2v0; stl_vertex v0v1, v2v0;
assert(facets_edge_ids[facet_idx](iv) == line.edge_a_id || facets_edge_ids[facet_idx](iv) == line.edge_b_id); assert(facets_edge_ids[facet_idx](iv) == line.edge_a_id || facets_edge_ids[facet_idx](iv) == line.edge_b_id);
if (facets_edge_ids[facet_idx](iv) == line.edge_a_id) { if (facets_edge_ids[facet_idx](iv) == line.edge_a_id) {
v0v1 = to_3d(unscaled<float>(line.a), z); // Unscale to doubles first, then to floats to reach the same accuracy as triangulate_expolygons_2d().
v2v0 = to_3d(unscaled<float>(line.b), z); v0v1 = to_3d(unscaled<double>(line.a).cast<float>().eval(), z);
v2v0 = to_3d(unscaled<double>(line.b).cast<float>().eval(), z);
} else { } else {
v0v1 = to_3d(unscaled<float>(line.b), z); v0v1 = to_3d(unscaled<double>(line.b).cast<float>().eval(), z);
v2v0 = to_3d(unscaled<float>(line.a), z); v2v0 = to_3d(unscaled<double>(line.a).cast<float>().eval(), z);
} }
const stl_vertex &v0 = vertices[iv]; const stl_vertex &v0 = vertices[iv];
const int iv0 = facet[iv]; const int iv0 = facet[iv];
@ -2223,11 +2229,25 @@ void cut_mesh(const indexed_triangle_set &mesh, float z, indexed_triangle_set *u
} }
} }
if (upper != nullptr) if (upper != nullptr) {
triangulate_slice(*upper, upper_lines, upper_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_DOWN); triangulate_slice(*upper, upper_lines, upper_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_DOWN);
#ifndef NDEBUG
if (triangulate_caps) {
size_t num_open_edges_new = its_num_open_edges(*upper);
assert(num_open_edges_new <= num_open_edges_old);
}
#endif // NDEBUG
}
if (lower != nullptr) if (lower != nullptr) {
triangulate_slice(*lower, lower_lines, lower_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_UP); triangulate_slice(*lower, lower_lines, lower_slice_vertices, int(mesh.vertices.size()), z, triangulate_caps, NORMALS_UP);
#ifndef NDEBUG
if (triangulate_caps) {
size_t num_open_edges_new = its_num_open_edges(*lower);
assert(num_open_edges_new <= num_open_edges_old);
}
#endif // NDEBUG
}
} }
} } // namespace Slic3r