public void Collect(Transform[] xforms) { for (int i = 0; i < xforms.Length; ++i) { var child = xforms[i]; var region = new Region(); region.name = child.name; regions.Add(region); var mesh = child.GetComponent <MeshFilter>().sharedMesh; int[] tris = mesh.triangles; Vector3[] vertices = Array.ConvertAll(mesh.vertices, v => v + child.localPosition); for (int j = 0; j < tris.Length; j += 3) { Vector2 p0 = vertices[tris[j]]; Vector2 p1 = vertices[tris[j + 1]]; Vector2 p2 = vertices[tris[j + 2]]; var triangle = new Triangle() { region = regions.Count - 1, vertices = new Vector2[] { p0, p1, p2 }, hashes = new long[] { graph.PointHash(p0), graph.PointHash(p1), graph.PointHash(p2) } }; triangles.Add(triangle); region.triangles.Add(triangles.Count - 1); tri2region.Add(triangle, region); } } }
void FindTriangles() { HashSet <long> finishedPoints = new HashSet <long>(); foreach (var kv in adjacents) { long hashCode = kv.Key; var p0 = kv.Value.point; foreach (var p1 in kv.Value.adjacents) { long p1h = PolyGraph.PointHash(p1, size); if (finishedPoints.Contains(p1h)) { continue; } foreach (var p2 in adjacents[p1h].adjacents) { long p2h = PolyGraph.PointHash(p2, size); if (finishedPoints.Contains(p2h) && p2h != hashCode) { continue; } if (-1 != adjacents[p2h].adjacents.FindIndex(v => PolyGraph.PointHash(v, size) == hashCode)) { float cross = Vector3.Cross(p1 - p0, p2 - p0).z; if (cross == 0f) { throw new Exception("Cross Product is zero, we got some degenerated triangles"); } if (cross < 0f) { triangles.Add(new Vector2[] { p0, p1, p2 }); } } } } finishedPoints.Add(hashCode); } }
void AddPoint(Vector2 p0, Vector2 p1) { long p0h = PolyGraph.PointHash(p0, size); long p1h = PolyGraph.PointHash(p1, size); AdjacentPoints ap; if (!adjacents.TryGetValue(p0h, out ap)) { ap = new AdjacentPoints() { point = p0 }; adjacents.Add(p0h, ap); } if (-1 == ap.adjacents.FindIndex(v => PolyGraph.PointHash(v, size) == p1h)) { ap.adjacents.Add(p1); } }
static bool ResolveRegion(PolyGraph graph, Transform xform, ref int nextIndex) { List <Triangle> triangles = new List <Triangle>(); List <List <int> > regions = new List <List <int> >(); var mesh = xform.GetComponent <MeshFilter>().sharedMesh; int[] tris = mesh.triangles; Color[] colors = mesh.colors; Vector2[] uv = mesh.uv; Vector3[] verts = Array.ConvertAll(mesh.vertices, v => v + xform.localPosition); for (int i = 0; i < tris.Length; i += 3) { var triangle = new Triangle() { vertices = new int[] { tris[i], tris[i + 1], tris[i + 2] }, hashes = new long[] { graph.PointHash(verts[tris[i]]), graph.PointHash(verts[tris[i + 1]]), graph.PointHash(verts[tris[i + 2]]) }, adjacents = new List <int>() }; triangles.Add(triangle); } CalculateTriangleAdjacents(triangles); List <int> triIndex = Enumerable.Range(0, triangles.Count).ToList(); while (triIndex.Count > 0) { List <int> region = new List <int>(); Queue <int> queue = new Queue <int>(); queue.Enqueue(triIndex[0]); while (queue.Count > 0) { int i = queue.Dequeue(); triIndex.Remove(i); region.Add(i); var triangle = triangles[i]; foreach (int adj in triangle.adjacents) { if (triIndex.Contains(adj) && !queue.Contains(adj)) { queue.Enqueue(adj); } } } regions.Add(region); } if (regions.Count > 1) { Debug.LogFormat("<color=yellow>{0}: breaking region {1}</color>", graph.name, xform.name); var mat = xform.GetComponent <MeshRenderer>().sharedMaterial; foreach (var region in regions) { Debug.LogFormat("<color=green>{0}: create new region {1}</color>", graph.name, nextIndex); NewRegion(region, triangles, graph, mat, verts, colors, uv, nextIndex++); } GameObject.DestroyImmediate(xform.gameObject); string meshPath = string.Format("{0}/{1}/Meshes/{2}.prefab", Paths.AssetArtworks, graph.name, mesh.name); AssetDatabase.DeleteAsset(meshPath); return(true); } else { return(false); } }