| 17 | namespace tesselator |
| 18 | { |
| 19 | int TesselateInterior(PolygonsT const & polys, TrianglesInfo & info) |
| 20 | { |
| 21 | int constexpr kCoordinatesPerVertex = 2; |
| 22 | int constexpr kVerticesInPolygon = 3; |
| 23 | |
| 24 | auto const deleter = [](TESStesselator * tess) { tessDeleteTess(tess); }; |
| 25 | std::unique_ptr<TESStesselator, decltype(deleter)> tess(tessNewTess(nullptr), deleter); |
| 26 | |
| 27 | for (auto const & contour : polys) |
| 28 | { |
| 29 | tessAddContour(tess.get(), kCoordinatesPerVertex, &contour[0], sizeof(contour[0]), |
| 30 | static_cast<int>(contour.size())); |
| 31 | } |
| 32 | |
| 33 | if (0 == tessTesselate(tess.get(), TESS_WINDING_ODD, TESS_CONSTRAINED_DELAUNAY_TRIANGLES, kVerticesInPolygon, |
| 34 | kCoordinatesPerVertex, nullptr)) |
| 35 | { |
| 36 | LOG(LERROR, ("Tesselator error for polygon", polys)); |
| 37 | return 0; |
| 38 | } |
| 39 | |
| 40 | int const elementCount = tessGetElementCount(tess.get()); |
| 41 | if (elementCount) |
| 42 | { |
| 43 | int const vertexCount = tessGetVertexCount(tess.get()); |
| 44 | TESSreal const * vertices = tessGetVertices(tess.get()); |
| 45 | m2::PointD const * points = reinterpret_cast<m2::PointD const *>(vertices); |
| 46 | info.AssignPoints(points, points + vertexCount); |
| 47 | |
| 48 | // Elements are triplets of vertex indices. |
| 49 | TESSindex const * elements = tessGetElements(tess.get()); |
| 50 | info.Reserve(elementCount); |
| 51 | for (int i = 0; i < elementCount; ++i) |
| 52 | if (!info.Add(elements[i * 3], elements[i * 3 + 1], elements[i * 3 + 2])) |
| 53 | return 0; |
| 54 | } |
| 55 | return elementCount; |
| 56 | } |
| 57 | |
| 58 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 59 | // TrianglesInfo::ListInfo implementation |