Skip to content

Commit

Permalink
Fix the ear clipping
Browse files Browse the repository at this point in the history
Ear clipping method get sometimes wrong result on some concave polygon.
The original isEar() method only check whether there is any point in
the triangle. It will get wrong result if the triangle don't have
inside point but is a concave point of the polygon. Check the triangle
each time in isEar() will fix this bug.
  • Loading branch information
smallchimney committed Dec 27, 2018
1 parent 43b15dd commit 3d15436
Showing 1 changed file with 8 additions and 10 deletions.
18 changes: 8 additions & 10 deletions surface/src/ear_clipping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pcl::EarClipping::performProcessing (PolygonMesh& output)
void
pcl::EarClipping::triangulate (const Vertices& vertices, PolygonMesh& output)
{
const int n_vertices = static_cast<const int> (vertices.vertices.size ());
const size_t n_vertices = static_cast<size_t> (vertices.vertices.size ());

if (n_vertices < 3)
return;
Expand All @@ -77,11 +77,9 @@ pcl::EarClipping::triangulate (const Vertices& vertices, PolygonMesh& output)
}

std::vector<uint32_t> remaining_vertices (n_vertices);
if (area (vertices.vertices) > 0) // clockwise?
remaining_vertices = vertices.vertices;
else
for (int v = 0; v < n_vertices; v++)
remaining_vertices[v] = vertices.vertices[n_vertices - 1 - v];

// put the clockwise check in the isEar() to fix complex situation's decompose bug
remaining_vertices = _Vertices.vertices;

// Avoid closed loops.
if (remaining_vertices.front () == remaining_vertices.back ())
Expand Down Expand Up @@ -157,12 +155,12 @@ pcl::EarClipping::isEar (int u, int v, int w, const std::vector<uint32_t>& verti
p_w = points_->points[vertices[w]].getVector3fMap();

const float eps = 1e-15f;
Eigen::Vector3f p_uv, p_uw;
p_uv = p_v - p_u;
p_uw = p_w - p_u;
Eigen::Vector3f p_vu, p_vw;
p_vu = p_u - p_v;
p_vw = p_w - p_v;

// Avoid flat triangles.
if ((p_uv.cross(p_uw)).norm() < eps)
if ((p_vu[0] * p_vw[1] - p_vu[1] * p_vw[0] > 0) != ((p_vu.cross(p_vw)).norm() < eps))
return (false);

Eigen::Vector3f p;
Expand Down

0 comments on commit 3d15436

Please sign in to comment.