public void AppendUniqueNeighbor(SimplifyVertex vertex) { if (!neighbors.Contains(vertex) && this != vertex) { neighbors.Add(vertex); } }
private float ComputeEdgeCollapseCost(SimplifyVertex u, SimplifyVertex v) { Vector3 tp = v.position - u.position; float edgelength = Vector3.SqrMagnitude(tp); float curvature = 0.0f; // 曲率 List <SimplifyTriangle> sides = new List <SimplifyTriangle>(); // 查找uv为边的三角形 foreach (SimplifyTriangle simplifyTriangle in u.triangles) { if (simplifyTriangle.Contains(v)) { sides.Add(simplifyTriangle); } } foreach (SimplifyTriangle triangle in u.triangles) { float mincurv = 1; foreach (SimplifyTriangle sTriangle in sides) { float dotprod = Vector3.Dot(triangle.normal, sTriangle.normal); mincurv = Mathf.Min(mincurv, (1.0f - dotprod) / 2.0f); } curvature = Mathf.Max(curvature, mincurv); } return(edgelength * curvature); }
public SimplifyTriangle(SimplifyVertex v0, SimplifyVertex v1, SimplifyVertex v2) { this.v0 = v0; this.v1 = v1; this.v2 = v2; this.v0.triangles.Add(this); this.v1.triangles.Add(this); this.v2.triangles.Add(this); ComputeNormal(); }
private SimplifyVertex MiniCostEdge() { SimplifyVertex mn = vertices[0]; foreach (SimplifyVertex v in vertices) { if (!v.isRemoved && v.cost < mn.cost) { mn = v; } } return(mn); }
public void RemvoeIfNonNeighbor(SimplifyVertex vertex) { if (!neighbors.Contains(vertex)) { return; } foreach (SimplifyTriangle triangle in triangles) { if (triangle.Contains(vertex)) { return; } } neighbors.Remove(vertex); }
// u->v 顶点v替换u 移除u private void Collapse(SimplifyVertex u, SimplifyVertex v) { if (v == null) { u.Remove(); vertices.Remove(u); return; } int i; List <SimplifyVertex> tmp = new List <SimplifyVertex>(); SimplifyTriangle simplifyTriangle; for (i = 0; i < u.neighbors.Count; i++) { tmp.Add(u.neighbors[i]); } // 移除包含uv边的三角形 for (i = u.triangles.Count - 1; i >= 0; i--) { if (u.triangles[i].Contains(v)) { simplifyTriangle = u.triangles[i]; triangles.Remove(simplifyTriangle); simplifyTriangle.Remove(); } } // 用v替换u 更新包含u但不包含v的三角形 for (i = u.triangles.Count - 1; i >= 0; i--) { u.triangles[i].ReplaceSimplifyVertex(u, v); } u.Remove(); vertices.Remove(u); for (i = 0; i < tmp.Count; i++) { ComputeEdgeCostAtVertex(tmp[i]); } }
private void ComputeEdgeCostAtVertex(SimplifyVertex v) { if (v.neighbors.Count == 0) { v.collapse = null; v.cost = -0.01f; return; } v.cost = 1000000.0f; v.collapse = null; //if (v.isEdge) return; foreach (SimplifyVertex nVertex in v.neighbors) { float cost = ComputeEdgeCollapseCost(v, nVertex); if (cost < v.cost) { v.collapse = nVertex; v.cost = cost; } } }
public Mesh GetSimplifyMesh(int targetVerNum) { if (m_targetVerNum == targetVerNum) { return(null); } m_targetVerNum = targetVerNum; ComputeAllEdgeCollapseCosts(); while (true) { int vertexCount = vertices.Count; if (vertexCount == 0 || vertexCount <= m_targetVerNum) { break; } SimplifyVertex mn = MiniCostEdge(); //if (mn.isRemoved || mn.cost > 1000000.0f) break; Collapse(mn, mn.collapse); vertices.Remove(mn); } triangles.RemoveAll((triangle) => { return(triangle.isRemoved); }); List <int> indices = new List <int>(); List <Vector3> tVertices = new List <Vector3>(); List <Vector2> tUVS = new List <Vector2>(); Dictionary <int, int> idindex = new Dictionary <int, int>(); int indexV = 0; foreach (SimplifyTriangle triangle in triangles) { if (!idindex.TryGetValue(triangle.v0.id, out indexV)) { indexV = tVertices.Count; idindex.Add(triangle.v0.id, indexV); tVertices.Add(triangle.v0.position); tUVS.Add(triangle.v0.uv); } indices.Add(indexV); if (!idindex.TryGetValue(triangle.v1.id, out indexV)) { indexV = tVertices.Count; idindex.Add(triangle.v1.id, indexV); tVertices.Add(triangle.v1.position); tUVS.Add(triangle.v1.uv); } indices.Add(indexV); if (!idindex.TryGetValue(triangle.v2.id, out indexV)) { indexV = tVertices.Count; idindex.Add(triangle.v2.id, indexV); tVertices.Add(triangle.v2.position); tUVS.Add(triangle.v2.uv); } indices.Add(indexV); } Mesh simplifyMesh = new Mesh(); simplifyMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; simplifyMesh.vertices = tVertices.ToArray(); //simplifyMesh.uv = tUVS.ToArray(); simplifyMesh.triangles = indices.ToArray(); simplifyMesh.RecalculateNormals(); renderVerticesNum = tVertices.Count; renderTrianglesNum = indices.Count / 3; return(simplifyMesh); }
public void ReplaceSimplifyVertex(SimplifyVertex vold, SimplifyVertex vnew) { if (vold == null || vnew == null) { return; } if (vold != v0 && vold != v1 && vold != v2) { return; } if (vnew == v0 || vnew == v1 || vnew == v2) { return; } if (vold == v0) { v0 = vnew; } if (vold == v1) { v1 = vnew; } if (vold == v2) { v2 = vnew; } int i; vold.triangles.Remove(this); if (vnew.triangles.Contains(this)) { return; } vnew.triangles.Add(this); vold.RemoveNeighbor(v0); vold.RemoveNeighbor(v1); vold.RemoveNeighbor(v2); if (v0.GetSimplifyTriangleCount(this) == 1) { v0.AppendUniqueNeighbor(v1); v0.AppendUniqueNeighbor(v2); } if (v1.GetSimplifyTriangleCount(this) == 1) { v1.AppendUniqueNeighbor(v0); v1.AppendUniqueNeighbor(v2); } if (v2.GetSimplifyTriangleCount(this) == 1) { v2.AppendUniqueNeighbor(v0); v2.AppendUniqueNeighbor(v1); } ComputeNormal(); }
public bool Contains(SimplifyVertex v) { return(v == v0 || v == v1 || v == v2); }