Measurement: prevent ending up in an infinite loop with broken models
This commit is contained in:
parent
d4ad4aff01
commit
b27653493a
@ -189,10 +189,16 @@ void MeasuringImpl::update_planes()
|
||||
he = sm.next_around_target(he);
|
||||
if (he.is_invalid())
|
||||
goto PLANE_FAILURE;
|
||||
|
||||
// For broken meshes, the iteration might never get back to he_orig.
|
||||
// Remember all halfedges we saw to break out of such infinite loops.
|
||||
boost::container::small_vector<Halfedge_index, 10> he_seen;
|
||||
|
||||
while ( (int)m_face_to_plane[sm.face(he)] == plane_id && he != he_orig) {
|
||||
he_seen.emplace_back(he);
|
||||
he = sm.next_around_target(he);
|
||||
if (he.is_invalid())
|
||||
goto PLANE_FAILURE;
|
||||
if (he.is_invalid() || std::find(he_seen.begin(), he_seen.end(), he) != he_seen.end())
|
||||
goto PLANE_FAILURE;
|
||||
}
|
||||
he = sm.opposite(he);
|
||||
if (he.is_invalid())
|
||||
@ -210,6 +216,12 @@ void MeasuringImpl::update_planes()
|
||||
visited[face_it - facets.begin()][he.side()] = true;
|
||||
|
||||
last_border.emplace_back(sm.point(sm.source(he)).cast<double>());
|
||||
|
||||
// In case of broken meshes, this loop might be infinite. Break
|
||||
// out in case it is clearly going bad.
|
||||
if (last_border.size() > 3*facets.size())
|
||||
goto PLANE_FAILURE;
|
||||
|
||||
} while (he != he_start);
|
||||
|
||||
if (last_border.size() == 1)
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <admesh/stl.h>
|
||||
#include <libslic3r/TriangleMesh.hpp>
|
||||
|
||||
#include "boost/container/small_vector.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class TriangleMesh;
|
||||
@ -115,11 +117,18 @@ public:
|
||||
|
||||
size_t degree(Vertex_index v) const
|
||||
{
|
||||
// In case the mesh is broken badly, the loop might end up to be infinite,
|
||||
// never getting back to the first halfedge. Remember list of all half-edges
|
||||
// and trip if any is encountered for the second time.
|
||||
Halfedge_index h_first = halfedge(v);
|
||||
boost::container::small_vector<Halfedge_index, 10> he_visited;
|
||||
Halfedge_index h = next_around_target(h_first);
|
||||
size_t degree = 2;
|
||||
while (! h.is_invalid() && h != h_first) {
|
||||
he_visited.emplace_back(h);
|
||||
h = next_around_target(h);
|
||||
if (std::find(he_visited.begin(), he_visited.end(), h) == he_visited.end())
|
||||
return 0;
|
||||
++degree;
|
||||
}
|
||||
return h.is_invalid() ? 0 : degree - 1;
|
||||
|
Loading…
Reference in New Issue
Block a user