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)
This commit is contained in:
Vojtech Bubnik 2021-01-28 18:59:53 +01:00
parent 02f97e10a5
commit 9a71d6deb9

View File

@ -2139,6 +2139,16 @@ std::vector<ExPolygons> PrintObject::slice_support_volumes(const ModelVolumeType
return this->slice_volumes(zs, SlicingMode::Regular, volumes); 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<ExPolygons> PrintObject::slice_volumes( std::vector<ExPolygons> PrintObject::slice_volumes(
const std::vector<float> &z, const std::vector<float> &z,
SlicingMode mode, size_t slicing_mode_normal_below_layer, SlicingMode mode_below, SlicingMode mode, size_t slicing_mode_normal_below_layer, SlicingMode mode_below,
@ -2151,10 +2161,8 @@ std::vector<ExPolygons> PrintObject::slice_volumes(
TriangleMesh mesh(volumes.front()->mesh()); TriangleMesh mesh(volumes.front()->mesh());
mesh.transform(volumes.front()->get_matrix(), true); mesh.transform(volumes.front()->get_matrix(), true);
assert(mesh.repaired); assert(mesh.repaired);
if (volumes.size() == 1 && 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. fix_mesh_connectivity(mesh);
stl_check_facets_exact(&mesh.stl);
}
for (size_t idx_volume = 1; idx_volume < volumes.size(); ++ idx_volume) { for (size_t idx_volume = 1; idx_volume < volumes.size(); ++ idx_volume) {
const ModelVolume &model_volume = *volumes[idx_volume]; const ModelVolume &model_volume = *volumes[idx_volume];
TriangleMesh vol_mesh(model_volume.mesh()); TriangleMesh vol_mesh(model_volume.mesh());
@ -2187,10 +2195,8 @@ std::vector<ExPolygons> PrintObject::slice_volume(const std::vector<float> &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. //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()); TriangleMesh mesh(volume.mesh());
mesh.transform(volume.get_matrix(), true); mesh.transform(volume.get_matrix(), true);
if (mesh.repaired) { if (mesh.repaired)
//FIXME The admesh repair function may break the face connectivity, rather refresh it here as the slicing code relies on it. fix_mesh_connectivity(mesh);
stl_check_facets_exact(&mesh.stl);
}
if (mesh.stl.stats.number_of_facets > 0) { if (mesh.stl.stats.number_of_facets > 0) {
mesh.transform(m_trafo, true); mesh.transform(m_trafo, true);
// apply XY shift // apply XY shift