chore: refine

master
uc-hoba 10 months ago
parent 177b58944d
commit 35e7d5478b
  1. 73
      Assets/Scripts/Editor/GeodesicMesh.cs
  2. 7
      Assets/Scripts/Editor/GoldbergBuilder.cs
  3. 172
      Assets/Scripts/Editor/GoldbergPolyhedronImporter.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<float> { 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<IsoVector>();
@ -765,62 +773,27 @@ namespace Metamesh
nearTo[12].Add(new List<int> { i, close[i][0] });
}
}
/*
var near = new List<int>();
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);

@ -28,7 +28,7 @@ namespace Metamesh
public List<Vector2> 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]];

@ -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<Vector3> vertices, List<Vector3> normals, List<int> indices)
{
var newVertices = new List<Vector3>();
var newNormals = new List<Vector3>();
var newIndices = new List<int>();
var centers = new Dictionary<int, List<int>>();
var edges = new HashSet<int>();
{
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<int> FindNeighbors(int index, List<int> indices)
{
var results = new List<int>();
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<int> FindCenters(HashSet<int> edges, List<int> indices)
{
var results = new List<int>();
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<int> { 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();
}
}
}