------------------------------------------------------------------------------ Triangulation method based on ear-cutting. Triangles, or ears, are repeatedly cut off from the polygon based on a measure of the vertex. Vertices must be convex, but different measures will produce different triangulations. While the algorithm works in 3D (the points don't have to be projected into 2D), it is assumed th
| 1610 | // don't have to be projected into 2D), it is assumed the polygon is planar - |
| 1611 | // if not, poor results may occur. |
| 1612 | int vtkPolygon::EarCutTriangulation(vtkIdList* outTris, int measure) |
| 1613 | { |
| 1614 | // Initialize the list of output triangles |
| 1615 | outTris->Reset(); |
| 1616 | |
| 1617 | // Make sure there are at least 3 vertices |
| 1618 | if (this->PointIds->GetNumberOfIds() < 3) |
| 1619 | { |
| 1620 | return (this->SuccessfulTriangulation = 0); |
| 1621 | } |
| 1622 | |
| 1623 | // Compute the tolerance local to this polygon |
| 1624 | this->ComputeTolerance(); |
| 1625 | |
| 1626 | // Check for trivial triangulation cases |
| 1627 | if (::SimpleTriangulation(this->PointIds, this->Points, this->Tol * this->Tol, outTris)) |
| 1628 | { |
| 1629 | return (this->SuccessfulTriangulation = 1); |
| 1630 | } |
| 1631 | |
| 1632 | // If npts is 4 and ::SimpleTriangulation() failed, the quad is poorly shaped. |
| 1633 | // Triangulate by the shorter diagonal |
| 1634 | |
| 1635 | // Establish a more convenient structure for the triangulation process |
| 1636 | vtkPolyVertexList poly(this->PointIds, this->Points, this->Tol * this->Tol, measure); |
| 1637 | vtkLocalPolyVertex* vtx; |
| 1638 | int i, id; |
| 1639 | |
| 1640 | // The polygon normal is needed during triangulation |
| 1641 | // |
| 1642 | if (!poly.ComputeNormal()) |
| 1643 | { |
| 1644 | return (this->SuccessfulTriangulation = 0); |
| 1645 | } |
| 1646 | |
| 1647 | // Now compute the angles between edges incident to each |
| 1648 | // vertex. Place the structure into a priority queue (those |
| 1649 | // vertices with smallest measure are to be removed first). |
| 1650 | // |
| 1651 | vtkPriorityQueue* VertexQueue = vtkPriorityQueue::New(); |
| 1652 | VertexQueue->Allocate(poly.NumberOfVerts); |
| 1653 | for (i = 0, vtx = poly.Head; i < poly.NumberOfVerts; i++, vtx = vtx->next) |
| 1654 | { |
| 1655 | // concave (negative measure) vertices are not eligible for removal |
| 1656 | if (poly.ComputeMeasure(vtx) > 0.0) |
| 1657 | { |
| 1658 | VertexQueue->Insert(vtx->measure, vtx->id); |
| 1659 | } |
| 1660 | } |
| 1661 | |
| 1662 | // For each vertex in the priority queue, and as long as there |
| 1663 | // are three or more vertices, remove the vertex (if possible) |
| 1664 | // and create a new triangle. NOTE: at one time this code checked the |
| 1665 | // number of verts in the removal queue, and if it was equal to the number |
| 1666 | // of remaining vertices, it assumed a convex polygon and indiscrimately |
| 1667 | // removed vertices. This tends to produce bad results as some triangles |
| 1668 | // were nearly flat etc. so the code was removed. |
| 1669 | // |
no test coverage detected