From 9a71d6deb98f81a7838975726807a30a406e2799 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Thu, 28 Jan 2021 18:59:53 +0100 Subject: [PATCH] Fix of #4654 #5122 #5668 #5811 #5895 Fixing model import of models with nearly degenerate triangles, which degenerate after transformation (translation or rotation). There was certainly a bug in PrusaSlicer, however this bug was triggered mostly by the ASCII STL files generated by OpenSCAD, likely due to insufficient number of decimal digits when saving an ASCII STL, see [openscad/openscad] STL export should contain single precision floats (#2651) --- src/libslic3r/PrintObject.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 99b4130f4..ed17676e0 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2139,6 +2139,16 @@ std::vector PrintObject::slice_support_volumes(const ModelVolumeType return this->slice_volumes(zs, SlicingMode::Regular, volumes); } +//FIXME The admesh repair function may break the face connectivity, rather refresh it here as the slicing code relies on it. +static void fix_mesh_connectivity(TriangleMesh &mesh) +{ + auto nr_degenerated = mesh.stl.stats.degenerate_facets; + stl_check_facets_exact(&mesh.stl); + if (nr_degenerated != mesh.stl.stats.degenerate_facets) + // stl_check_facets_exact() removed some newly degenerated faces. Some faces could become degenerate after some mesh transformation. + stl_generate_shared_vertices(&mesh.stl, mesh.its); +} + std::vector PrintObject::slice_volumes( const std::vector &z, SlicingMode mode, size_t slicing_mode_normal_below_layer, SlicingMode mode_below, @@ -2151,10 +2161,8 @@ std::vector PrintObject::slice_volumes( TriangleMesh mesh(volumes.front()->mesh()); mesh.transform(volumes.front()->get_matrix(), true); assert(mesh.repaired); - if (volumes.size() == 1 && mesh.repaired) { - //FIXME The admesh repair function may break the face connectivity, rather refresh it here as the slicing code relies on it. - stl_check_facets_exact(&mesh.stl); - } + if (volumes.size() == 1 && mesh.repaired) + fix_mesh_connectivity(mesh); for (size_t idx_volume = 1; idx_volume < volumes.size(); ++ idx_volume) { const ModelVolume &model_volume = *volumes[idx_volume]; TriangleMesh vol_mesh(model_volume.mesh()); @@ -2187,10 +2195,8 @@ std::vector PrintObject::slice_volume(const std::vector &z, S //FIXME better to split the mesh into separate shells, perform slicing over each shell separately and then to use a Boolean operation to merge them. TriangleMesh mesh(volume.mesh()); mesh.transform(volume.get_matrix(), true); - if (mesh.repaired) { - //FIXME The admesh repair function may break the face connectivity, rather refresh it here as the slicing code relies on it. - stl_check_facets_exact(&mesh.stl); - } + if (mesh.repaired) + fix_mesh_connectivity(mesh); if (mesh.stl.stats.number_of_facets > 0) { mesh.transform(m_trafo, true); // apply XY shift