private static extern unsafe void *GenerateStraightSkeleton(Poly *outer, Poly *holes, int holesCount, Poly *straightSkeleton, Poly *spokesResult);
 private static extern unsafe void FreePolygonStructMembers(Poly *result);
        private static unsafe StraightSkeleton ExtractResult(IReadOnlyList <Vector2> outer, IReadOnlyList <IReadOnlyList <Vector2> > holes, Poly *skeletonResult, Poly *spokesResult, IntPtr handle)
        {
            //Set of all vertices supplied as input
            var inputVertices = new HashSet <Vector2>(outer);

            inputVertices.UnionWith(holes.SelectMany(h => h));

            //An edge is either:
            // - border
            //   - input -> input
            // - spoke
            //   - input -> skeleton
            //   - input -> spoke
            //   - spoke -> skeleton
            // - skeleton
            //   - skeleton -> skeleton
            var borders  = new HashSet <KeyValuePair <Vector2, Vector2> >();
            var spokes   = new HashSet <KeyValuePair <Vector2, Vector2> >();
            var skeleton = new HashSet <KeyValuePair <Vector2, Vector2> >();

            //Extract skeleton edges
            for (var i = 0; i < skeletonResult->VerticesLength / 4; i++)
            {
                skeleton.Add(OrderByHash(
                                 new Vector2(skeletonResult->Vertices[i * 4 + 0], skeletonResult->Vertices[i * 4 + 1]),
                                 new Vector2(skeletonResult->Vertices[i * 4 + 2], skeletonResult->Vertices[i * 4 + 3])
                                 ));
            }

            //Extract spokes
            for (int i = 0; i < spokesResult->VerticesLength / 4; i++)
            {
                spokes.Add(OrderByHash(
                               new Vector2(spokesResult->Vertices[i * 4 + 0], spokesResult->Vertices[i * 4 + 1]),
                               new Vector2(spokesResult->Vertices[i * 4 + 2], spokesResult->Vertices[i * 4 + 3])
                               ));
            }

            //Extract borders
            for (int i = 0; i < outer.Count; i++)
            {
                borders.Add(OrderByHash(
                                outer[i],
                                outer[(i + 1) % outer.Count]
                                ));
            }

            //Extract borders from holes
            foreach (var hole in holes)
            {
                for (int i = 0; i < hole.Count; i++)
                {
                    borders.Add(OrderByHash(
                                    hole[i],
                                    hole[(i + 1) % hole.Count]
                                    ));
                }
            }

            return(new StraightSkeleton(inputVertices, borders, spokes, skeleton, handle));
        }