public List <Vector2[]> TriangulateClipperSolution(ClipperLib.PolyTree solution)
        {
            var tess = new Tess();

            tess.NoEmptyPolygons = true;

            // Add a contour for each part of the solution tree
            ClipperLib.PolyNode node = solution.GetFirst();
            while (node != null)
            {
                // Only interested in closed paths
                if (!node.IsOpen)
                {
                    // Add a new countor. Holes are automatically generated.
                    var vertices = node.Contour.Select(pt => new ContourVertex {
                        Position = new Vec3 {
                            X = pt.X, Y = pt.Y, Z = 0
                        }
                    }).ToArray();
                    tess.AddContour(vertices);
                }
                node = node.GetNext();
            }

            return(TrianglesFromTessellator(tess));
        }
Exemplo n.º 2
0
        private List <Poly2Tri.DelaunayTriangle> GetTriangleListFromClipperSolution(ClipperLib.PolyTree solution)
        {
            Func <ClipperLib.IntPoint, Poly2Tri.PolygonPoint> xfToPolygonPoint = (p) => new Poly2Tri.PolygonPoint(p.X, p.Y);

            Poly2Tri.PolygonSet polygonSet = new Poly2Tri.PolygonSet();

            ClipperLib.PolyNode node = solution.GetFirst();
            while (node != null)
            {
                // Only interested in closed paths
                if (!node.IsOpen)
                {
                    if (node.IsHole)
                    {
                        if (polygonSet.Polygons.Count() > 0)
                        {
                            // Add hole to last polygon entered
                            var polyPoints        = node.Contour.Select(xfToPolygonPoint).ToArray();
                            Poly2Tri.Polygon hole = new Poly2Tri.Polygon(polyPoints);

                            Poly2Tri.Polygon polygon = polygonSet.Polygons.Last();
                            polygon.AddHole(hole);
                        }
                    }
                    else
                    {
                        // Add a new polygon to the set
                        var polyPoints           = node.Contour.Select(xfToPolygonPoint).ToList();
                        Poly2Tri.Polygon polygon = new Poly2Tri.Polygon(polyPoints);
                        polygonSet.Add(polygon);
                    }
                }
                node = node.GetNext();
            }

            // Now triangulate the whole set
            Poly2Tri.P2T.Triangulate(polygonSet);

            // Combine all the triangles into one list
            List <Poly2Tri.DelaunayTriangle> triangles = new List <Poly2Tri.DelaunayTriangle>();

            foreach (var polygon in polygonSet.Polygons)
            {
                triangles.AddRange(polygon.Triangles);
            }

            return(triangles);
        }
Exemplo n.º 3
0
        public List <PointF[]> Triangulate(ClipperLib.PolyTree solution)
        {
            List <PointF[]> triangles = new List <PointF[]>();

            var tess = new LibTessDotNet.Tess();

            tess.NoEmptyPolygons = true;

            // Transformation function from ClipperLip Point to LibTess contour vertex
            Func <ClipperLib.IntPoint, LibTessDotNet.ContourVertex> xfToContourVertex = (p) => new LibTessDotNet.ContourVertex()
            {
                Position = new LibTessDotNet.Vec3 {
                    X = p.X, Y = p.Y, Z = 0
                }
            };

            // Add a contour for each part of the solution tree
            ClipperLib.PolyNode node = solution.GetFirst();
            while (node != null)
            {
                // Only interested in closed paths
                if (!node.IsOpen)
                {
                    // Add a new countor. Holes are automatically generated.
                    var vertices = node.Contour.Select(xfToContourVertex).ToArray();
                    tess.AddContour(vertices);
                }
                node = node.GetNext();
            }

            // Do the tessellation
            tess.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3);

            // Extract the triangles
            int numTriangles = tess.ElementCount;

            for (int i = 0; i < numTriangles; i++)
            {
                var v0 = tess.Vertices[tess.Elements[i * 3 + 0]].Position;
                var v1 = tess.Vertices[tess.Elements[i * 3 + 1]].Position;
                var v2 = tess.Vertices[tess.Elements[i * 3 + 2]].Position;

                List <PointF> triangle = new List <PointF>()
                {
                    new PointF(v0.X, v0.Y),
                    new PointF(v1.X, v1.Y),
                    new PointF(v2.X, v2.Y),
                };

                // Assre each triangle needs to be CCW
                float cross = Geometry.Math.Cross(triangle[0], triangle[1], triangle[2]);
                if (cross > 0)
                {
                    triangle.Reverse();
                }

                triangles.Add(triangle.ToArray());
            }

            return(triangles);
        }