public GPUSubdivData Next()
        {
            var newTriangles = new int[triangles.Length * 4];
            var newTriArray  = new Triangle_t[triBuffer.count * 4];

            var newEdges = new List <Edge_t>();
            var eoffset  = VertexBuffer.count;

            for (int i = 0, n = triangles.Length; i < n; i += 3)
            {
                int iv0 = triangles[i], iv1 = triangles[i + 1], iv2 = triangles[i + 2];
                var e0 = new Edge_t()
                {
                    v0 = iv0, v1 = iv1
                };
                var e1 = new Edge_t()
                {
                    v0 = iv1, v1 = iv2
                };
                var e2 = new Edge_t()
                {
                    v0 = iv2, v1 = iv0
                };
                int ie0 = edges.IndexOf(e0) + eoffset, ie1 = edges.IndexOf(e1) + eoffset, ie2 = edges.IndexOf(e2) + eoffset;

                int it00 = i * 4, it01 = it00 + 1, it02 = it01 + 1;
                int it10 = it00 + 3, it11 = it10 + 1, it12 = it11 + 1;
                int it20 = it10 + 3, it21 = it20 + 1, it22 = it21 + 1;
                int it30 = it20 + 3, it31 = it30 + 1, it32 = it31 + 1;

                newTriangles[it00] = iv0; newTriangles[it01] = ie0; newTriangles[it02] = ie2;
                newTriangles[it10] = ie0; newTriangles[it11] = iv1; newTriangles[it12] = ie1;
                newTriangles[it20] = ie0; newTriangles[it21] = ie1; newTriangles[it22] = ie2;
                newTriangles[it30] = ie2; newTriangles[it31] = ie1; newTriangles[it32] = iv2;

                int it = (i / 3) * 4;

                // AddTriangle
                newTriArray[it]     = AddTriangle(newEdges, newTriangles[it00], newTriangles[it01], newTriangles[it02]);
                newTriArray[it + 1] = AddTriangle(newEdges, newTriangles[it10], newTriangles[it11], newTriangles[it12]);
                newTriArray[it + 2] = AddTriangle(newEdges, newTriangles[it20], newTriangles[it21], newTriangles[it22]);
                newTriArray[it + 3] = AddTriangle(newEdges, newTriangles[it30], newTriangles[it31], newTriangles[it32]);
            }

            var neBuffer = new ComputeBuffer(newEdges.Count, Marshal.SizeOf(typeof(Edge_t)));

            neBuffer.SetData(newEdges.ToArray());
            var ntriBuffer = new ComputeBuffer(newTriArray.Length, Marshal.SizeOf(typeof(Triangle_t)));

            ntriBuffer.SetData(newTriArray);

            var next = new GPUSubdivData(subdivBuffer, neBuffer, ntriBuffer, newTriangles, newEdges);

            ReleaseBuffer(vertBuffer); vertBuffer = null;
            ReleaseBuffer(edgeBuffer); edgeBuffer = null;
            ReleaseBuffer(triBuffer); triBuffer   = null;
            subdivBuffer = null; // ref to NULL to use it in next GPUSubdivData

            return(next);
        }
        public GPUSubdivData(Mesh source)
        {
            vertBuffer = new ComputeBuffer(source.vertexCount, Marshal.SizeOf(typeof(Vector3)));
            vertBuffer.SetData(source.vertices);

            triangles = source.triangles;
            triBuffer = new ComputeBuffer(triangles.Length / 3, Marshal.SizeOf(typeof(Triangle_t)));
            var triArray = new Triangle_t[triBuffer.count];

            edges = new List <Edge_t>();

            for (int i = 0, n = triangles.Length; i < n; i += 3)
            {
                int iv0 = triangles[i], iv1 = triangles[i + 1], iv2 = triangles[i + 2];
                var e0 = new Edge_t()
                {
                    v0 = iv0, v1 = iv1
                };
                var e1 = new Edge_t()
                {
                    v0 = iv1, v1 = iv2
                };
                var e2 = new Edge_t()
                {
                    v0 = iv2, v1 = iv0
                };

                int ie0, ie1, ie2;

                if (edges.Contains(e0))
                {
                    ie0 = edges.IndexOf(e0);
                }
                else
                {
                    edges.Add(e0);
                    ie0 = edges.Count - 1;
                }

                if (edges.Contains(e1))
                {
                    ie1 = edges.IndexOf(e1);
                }
                else
                {
                    edges.Add(e1);
                    ie1 = edges.Count - 1;
                }

                if (edges.Contains(e2))
                {
                    ie2 = edges.IndexOf(e2);
                }
                else
                {
                    edges.Add(e2);
                    ie2 = edges.Count - 1;
                }

                triArray[i / 3] = new Triangle_t()
                {
                    v0 = iv0, v1 = iv1, v2 = iv2,
                    e0 = ie0, e1 = ie1, e2 = ie2
                };
            }

            edgeBuffer = new ComputeBuffer(edges.Count, Marshal.SizeOf(typeof(Edge_t)));
            edgeBuffer.SetData(edges.ToArray());
            triBuffer.SetData(triArray);
            subdivBuffer = new ComputeBuffer(vertBuffer.count + edgeBuffer.count, Marshal.SizeOf(typeof(Vector3)));
        }