diff --git a/Assets/Scripts/Editor/GeodesicMesh.cs b/Assets/Scripts/Editor/GeodesicMesh.cs index 304e7ad..fc3f5d8 100644 --- a/Assets/Scripts/Editor/GeodesicMesh.cs +++ b/Assets/Scripts/Editor/GeodesicMesh.cs @@ -76,6 +76,15 @@ namespace Metamesh private int HighestCommonFactor(int a, int b) { + while (b != 0) + { + var r = a % b; + a = b; + b = r; + } + + return a; + /* var r = a % b; if (r == 0) { @@ -83,6 +92,7 @@ namespace Metamesh } return HighestCommonFactor(b, r); + */ } @@ -452,14 +462,12 @@ namespace Metamesh var tempVec = x * this.cartesian[i].x + y * this.cartesian[i].y + O; mapped[i] = new List { tempVec.x, tempVec.y, tempVec.z }; idx = faceNb + "|" + this.vertices[i].x + "|" + this.vertices[i].y; + while (this.vecToidx[idx] >= geodesicData.vertex.Count) + geodesicData.vertex.Add(Vector3.zero); geodesicData.vertex[this.vecToidx[idx]] = tempVec; } } - - //statics - /**Creates a primary triangle - * @internal - */ + public PrimaryIsoTriangle Build(int m, int n) { var vertices = new List(); @@ -765,62 +773,27 @@ namespace Metamesh nearTo[12].Add(new List { i, close[i][0] }); } } - - /* - var near = new List(); - for (var i = 0; i < 12; i++) - { - near[i] = i; - } - */ - var near = Enumerable.Range(0, 12).ToList(); + + //var near = Enumerable.Range(0, 12).ToList(); + var near = Enumerable.Range(0, 12).ToDictionary(i => i); var nearIndex = 12; for (var i = 0; i < 12; i++) { nearTo[i].Sort((a, b) => { return a[1] - b[1]; }); - /* - for (var j = 0; j < nearTo[i].Count; j++) - { - near[nearTo[i][j][0]] = nearIndex++; - } - */ + foreach (var item in nearTo[i]) { near[item[0]] = nearIndex++; } } - - /* - for (var j = 0; j < nearTo[12].Count; j++) - { - near[nearTo[12][j][0]] = nearIndex++; - } - */ + foreach (var item in nearTo[12]) { near[item[0]] = nearIndex++; } - - /* - for (var i = 0; i < this.vertex.Count; i++) - { - //FIX - this.vertex[i].Add(near[i]); - } - - this.vertex.Sort((a, b) => - { - return a[3].CompareTo(b[3]); - }); - - for (var i = 0; i < this.vertex.Count; i++) - { - //FIX - this.vertex[i].RemoveAt(this.vertex[i].Count - 1); - } - */ + this.vertex = this.vertex - .Select((v, index) => (Vertex: v, SortKey: near[index])) + .Select((v, i) => (Vertex: v, SortKey: near[i])) .OrderBy(x => x.SortKey) .Select(x => x.Vertex) .ToList(); @@ -919,9 +892,9 @@ namespace Metamesh for (var i = 0; i < 3; i++) { vertex = this.vertex[face[i]]; - cx += vertex[0]; - cy += vertex[1]; - cz += vertex[2]; + cx += vertex.x; + cy += vertex.y; + cz += vertex.z; } var tempVertex = new Vector3(cx / 3, cy / 3, cz / 3); diff --git a/Assets/Scripts/Editor/GoldbergBuilder.cs b/Assets/Scripts/Editor/GoldbergBuilder.cs index ed1430b..fba7930 100644 --- a/Assets/Scripts/Editor/GoldbergBuilder.cs +++ b/Assets/Scripts/Editor/GoldbergBuilder.cs @@ -28,7 +28,7 @@ namespace Metamesh public List uvs; } - public VertexData CreateGoldbergVertexData(GoldbergVertexDataOption options, PolyhedronData goldbergData) + private VertexData CreateGoldbergVertexData(GoldbergVertexDataOption options, PolyhedronData goldbergData) { var size = options.size; var sizeX = options.sizeX;// || size || 1; @@ -57,6 +57,11 @@ namespace Metamesh for (var f = 0; f < goldbergData.face.Count; f++) { var verts = goldbergData.face[f]; + if (verts[0] >= goldbergData.vertex.Count || verts[1] >= goldbergData.vertex.Count || verts[2] >= goldbergData.vertex.Count) + { + Debug.LogWarning($"{verts[0]} | {verts[1]} | {verts[2]} > {goldbergData.vertex.Count}"); + continue; + } var a = goldbergData.vertex[verts[0]]; var b = goldbergData.vertex[verts[2]]; var c = goldbergData.vertex[verts[1]]; diff --git a/Assets/Scripts/Editor/GoldbergPolyhedronImporter.cs b/Assets/Scripts/Editor/GoldbergPolyhedronImporter.cs index c307bd3..b53c9af 100644 --- a/Assets/Scripts/Editor/GoldbergPolyhedronImporter.cs +++ b/Assets/Scripts/Editor/GoldbergPolyhedronImporter.cs @@ -44,21 +44,11 @@ namespace Metamesh private Mesh ImportAsMesh() { - var mesh = new Mesh(); - mesh.name = "Mesh"; - /* - var builder = new IcosphereBuilder(); - for (var i = 1; i < subdivision; ++i) + var mesh = new Mesh { - builder = new IcosphereBuilder(builder); - } - - var vertices = builder.Vertices.Select(v => (Vector3)(v * radius)).ToList(); - var normals = builder.Vertices.Select(v => (Vector3)v).ToList(); - var indices = builder.Indices.ToList(); + name = "Mesh" + }; - ApplyGoldbergTransformation(vertices, normals, indices); - */ var builder = new GoldbergBuilder(); var options = new GoldbergCreationOption() { @@ -82,161 +72,5 @@ namespace Metamesh return mesh; } - - private void ApplyGoldbergTransformation(List vertices, List normals, List indices) - { - var newVertices = new List(); - var newNormals = new List(); - var newIndices = new List(); - - var centers = new Dictionary>(); - var edges = new HashSet(); - - { - var neighbors = FindNeighbors(0, indices); - centers.Add(0, neighbors); - foreach (var i in neighbors) - { - edges.Add(i); - } - } - - int inc = 0; - while (edges.Count + centers.Count < vertices.Count) - { - inc++; - if (inc > 3) break; - - var ccs = FindCenters(edges, indices).Where(c => !centers.ContainsKey(c)).Distinct().ToArray(); - Debug.Log($"while cc in nb: {ccs.Where(c => edges.Contains(c)).Count()}"); - var nbs = ccs.SelectMany(c => - { - var neighbors = FindNeighbors(c, indices); - centers.Add(c, neighbors); - return neighbors; - }).Distinct().Where(i => !edges.Contains(i) && !centers.ContainsKey(i)).ToArray(); - Debug.Log($"while nb in cc: {nbs.Where(c => centers.ContainsKey(c)).Count()}"); - foreach (var i in nbs) - { - edges.Add(i); - } - Debug.Log($"centers: {ccs.Count()}/{centers.Count}, edges: {nbs.Count()}/{edges.Count}, vertices: {vertices.Count}"); - } - - Debug.Log($"cc in nb: {centers.Keys.Where(c => edges.Contains(c)).Count()}"); - Debug.Log($"nb in cc: {edges.Where(c => centers.Keys.Contains(c)).Count()}"); - Debug.Log($"missing: {Enumerable.Range(0, vertices.Count).Where(i => !centers.ContainsKey(i)).Where(i => !edges.Contains(i)).Count()}"); - - var pentagon = 0; - var hexagon = 0; - var start = 0; - foreach (var i in centers.Keys) - { - var neighbors = centers[i].Distinct().ToArray(); - var neighborCount = neighbors.Length; - if (neighborCount != 5 && neighborCount != 6) - { - Debug.Log($"Unexpected number of neighbors: {neighborCount}"); - continue; - } - if (neighborCount == 5) pentagon++; - if (neighborCount == 6) hexagon++; - /* - var p1 = vertices[neighbors[0]]; - var p2 = vertices[neighbors[2]]; - var p3 = vertices[neighbors[4]]; - - var edge1 = p2 - p1; - var edge2 = p3 - p1; - var normal = Vector3.Cross(edge1, edge2).normalized; - - var projection = ProjectPointOntoPlane(p1, normal); - */ - var x = neighbors.Average(i => vertices[i].x); - var y = neighbors.Average(i => vertices[i].y); - var z = neighbors.Average(i => vertices[i].z); - vertices[i] = new Vector3(x, y, z); - var normal = vertices[i]; - - var q = Quaternion.FromToRotation(vertices[i], Vector3.up); - //var mtx = Matrix4x4.TRS(-vertices[i], q, Vector3.one); - var mtx = Matrix4x4.TRS(Vector3.zero, q, Vector3.one) * Matrix4x4.TRS(-vertices[i], Quaternion.identity, Vector3.one); - var sortedNeighbors = neighbors.OrderBy(n => - { - var direction = mtx.MultiplyPoint(vertices[n]).normalized; - var crossProduct = Vector3.Cross(direction, Vector3.up); - return Mathf.Atan2(crossProduct.z, crossProduct.x); - }).ToArray(); - - newVertices.Add(vertices[i]); - newVertices.AddRange(sortedNeighbors.Select(n => vertices[n])); - newNormals.AddRange(Enumerable.Repeat(normal, neighborCount + 1)); - - for (int k = 0; k < neighborCount; ++k) - { - newIndices.Add(start); - newIndices.Add(start + (k + 1) % neighborCount); - newIndices.Add(start + (k + 0) % neighborCount); - } - start += neighborCount + 1; - } - - vertices.Clear(); - vertices.AddRange(newVertices); - normals.Clear(); - normals.AddRange(newNormals); - indices.Clear(); - indices.AddRange(newIndices); - - Debug.Log($"Pentagon: {pentagon}, Hexagon: {hexagon}"); - } - - private Vector3 ProjectPointOntoPlane(Vector3 planePoint, Vector3 planeNormal) - { - float distance = Vector3.Dot(planeNormal, Vector3.zero - planePoint); - Vector3 projection = Vector3.zero - planeNormal * distance; - return projection; - } - - private List FindNeighbors(int index, List indices) - { - var results = new List(); - for (int i = 0; i < indices.Count; i += 3) - { - var i0 = indices[i + 0]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - if (i0 == index) results.AddRange(new[] { i1, i2 }); - if (i1 == index) results.AddRange(new[] { i0, i2 }); - if (i2 == index) results.AddRange(new[] { i0, i1 }); - } - results = results.Distinct().ToList(); - if (results.Count != 5 && results.Count != 6) - Debug.Log($"Center#{index}'s neighbors count is {results.Count}"); - return results; - } - - private List FindCenters(HashSet edges, List indices) - { - var results = new List(); - for (int i = 0; i < indices.Count; i += 3) - { - var i0 = indices[i + 0]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - var notInEdges = new List { i0, i1, i2 } - .Where(v => !edges.Contains(v)) - .ToList(); - if (notInEdges.Count == 1) - { - var candidate = notInEdges[0]; - var neighbors = FindNeighbors(candidate, indices); - if (neighbors.Count != 5 && neighbors.Count != 6) - Debug.Log($"candidate#{candidate}'s neighbors count is {neighbors.Count}"); - results.Add(candidate); - } - } - return results.Distinct().ToList(); - } } } \ No newline at end of file