public float ComputeEdgeCollapseCost(PRVertex u, PRVertex v) { float edgeLength = MathExtra.GetV3L(u.pos - v.pos); float curvature = 0f; List <PRTriangle> sides = new List <PRTriangle> (); for (int i = 0; i < u.face.Count; i++) { if (u.face [i].HasVertex(v)) { sides.Add(u.face[i]); } } for (int i = 0; i < u.face.Count; i++) { float mincurv = 1f; for (int j = 0; j < sides.Count; j++) { float dotprod = Vector3.Dot(u.face [i].normal, sides [j].normal); mincurv = Mathf.Min(mincurv, (1f - dotprod) * 0.5f); } curvature = Mathf.Max(curvature, mincurv); } return(edgeLength * curvature); }
public void AddNeighbor(PRVertex v) { if ((!neighbor.Contains(v)) && v != this) { neighbor.Add(v); } }
public void ReplaceVertex(PRVertex u, PRVertex v) { v.AddFace(this); if (vertex [0] == u) { vertex [0] = v; } if (vertex [1] == u) { vertex [1] = v; } if (vertex [2] == u) { vertex [2] = v; } for (int i = 0; i < 3; i++) { if (vertex [i].neighbor.Contains(u)) { vertex [i].neighbor.Remove(u); vertex [i].AddNeighbor(v); } v.AddNeighbor(vertex [i]); } ComputeNormal(); }
//replace the point u in the triangle with v public void ReplaceVertex(PRVertex u, PRVertex v) { //add this face to v v.AddFace(this); //replace the point if (vertex[0] == u) { vertex[0] = v; } if (vertex[1] == u) { vertex[1] = v; } if (vertex[2] == u) { vertex[2] = v; } //delete the u //replace all the neighbours of the triangle containing u with v for (int i = 0; i < 3; i++) { if (vertex[i].neighbor.Contains(u)) { vertex[i].neighbor.Remove(u); vertex[i].AddNeighbor(v); } v.AddNeighbor(vertex[i]); } //update the normal ComputeNormal(); }
public PRTriangle(int id, PRVertex v1, PRVertex v2, PRVertex v3) { this.id = id; vertex [0] = v1; vertex [1] = v2; vertex [2] = v3; ComputeNormal(); }
public PRVertex MinimunCostEdge() { PRVertex t = prVertices[0]; for (int i = 0; i < prVertices.Length; i++) { if (prVertices [i].cost < t.cost) { t = prVertices [i]; } } return(t); }
public bool HasVertex(PRVertex v) { if (vertex [0] == v) { return(true); } if (vertex [1] == v) { return(true); } if (vertex [2] == v) { return(true); } return(false); }
public void ComputeEdgeCostAtVertex(PRVertex v) { if (v.neighbor.Count == 0) { v.collapse = null; v.cost = 1000000f; return; } v.cost = 1000000f; v.collapse = null; for (int i = 0; i < v.neighbor.Count; i++) { float c; c = ComputeEdgeCollapseCost(v, v.neighbor[i]); if (c < v.cost) { v.collapse = v.neighbor [i]; v.cost = c; } } }
//Update is called once per frame void Update() { //reductionData.Clear(); //collapse vertex with the least 'collapsePerFrame' cost for (int zx = 0; zx < collapsePerFrame; zx++) { PRVertex mn = MinimunCostEdge(); Collapse(mn, mn.collapse); vertexNum--; } //what dose ReductionData do? [TODO] for (; deleteIndex < reductionData.Count; deleteIndex++) { ApplyData(reductionData[deleteIndex]); } //update the mesh meshToGenerate.vertices = vertices; meshToGenerate.triangles = triangles; GetComponent <MeshFilter>().mesh = meshToGenerate; }
public void Collapse(PRVertex u, PRVertex v) { if (v == null) { Debug.Log("!!!"); //prVertices [u.id] = null; return; } //Debug.Log (u.id.ToString()+" "+v.id.ToString()+" "+u.cost.ToString()); int i; List <PRVertex> tmp = new List <PRVertex> (); for (i = 0; i < u.neighbor.Count; i++) { tmp.Add(u.neighbor[i]); } ReductionData rd = new ReductionData(); rd.vertexU = u.id; rd.vertexV = v.id; v.neighbor.Remove(u); for (i = u.face.Count - 1; i >= 0; i--) { u.face[i].ReplaceVertex(u, v); } for (int j = 0; j < u.face.Count; j++) { rd.triangleID.Add(u.face[j].id); } reductionData.Add(rd); ComputeEdgeCostAtVertex(v); //prVertices [u.id] = null; for (i = 0; i < tmp.Count; i++) { ComputeEdgeCostAtVertex(tmp[i]); } //prVertices [u.id] = null; u.cost = 10000000f; }
//calculate the cost of a single vertex //the cost has direction public void ComputeEdgeCostAtVertex(PRVertex v) { if (v.neighbor.Count == 0) { v.collapse = null; v.cost = 1000000f; return; } v.cost = 1000000f; v.collapse = null; //tranverse all the neighbours of a vertex //use the min valur of the costs of the edges containing that vertex as the cost of the vertex for (int i = 0; i < v.neighbor.Count; i++) { float c; c = ComputeEdgeCollapseCost(v, v.neighbor[i]); if (c < v.cost) { v.collapse = v.neighbor[i]; v.cost = c; } } }
void Generate() { if (meshToGenerate == null) { meshToGenerate = GetComponent <MeshFilter> ().mesh; } meshToGenerate = Object.Instantiate <Mesh> (meshToGenerate); vertices = meshToGenerate.vertices; triangles = meshToGenerate.triangles; normals = meshToGenerate.normals; vertexNum = vertices.Length; prVertices = new PRVertex[vertices.Length]; prTriangle = new PRTriangle[triangles.Length / 3]; int i; int j; for (i = 0; i < vertices.Length; i++) { prVertices [i] = new PRVertex(i, vertices[i]); } for (i = 0, j = 0; i < triangles.Length; i += 3, j += 1) { prTriangle [j] = new PRTriangle(i, prVertices[triangles[i]], prVertices[triangles[i + 1]], prVertices[triangles[i + 2]]); } for (i = 0; i < prTriangle.Length; i++) { prTriangle [i].vertex [0].face.Add(prTriangle [i]); prTriangle [i].vertex [1].face.Add(prTriangle [i]); prTriangle [i].vertex [2].face.Add(prTriangle [i]); for (j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { if (j == k) { continue; } if (!prTriangle [i].vertex [j].neighbor.Contains(prTriangle [i].vertex [k])) { prTriangle [i].vertex [j].neighbor.Add(prTriangle [i].vertex [k]); } } } } for (i = 0; i < prVertices.Length; i++) { ComputeEdgeCostAtVertex(prVertices[i]); } for (int zx = 0; zx < 60; zx++) { PRVertex mn = MinimunCostEdge(); Collapse(mn, mn.collapse); vertexNum--; } for (int C6H14O2 = 0; C6H14O2 < reductionData.Count; C6H14O2++) { ApplyData(reductionData[C6H14O2]); } meshToGenerate.vertices = vertices; meshToGenerate.triangles = triangles; GetComponent <MeshFilter> ().mesh = meshToGenerate; }
//process the mesh void Generate() { vertices = meshToGenerate.vertices; triangles = meshToGenerate.triangles; normals = meshToGenerate.normals; vertexNum = vertices.Length; Debug.Log(triangles.Length); prVertices = new PRVertex[vertices.Length]; prTriangle = new PRTriangle[triangles.Length / 3]; int i; int j; Hashtable pointMap = new Hashtable(); //init the vertexes for (i = 0; i < vertices.Length; i++) { //if (pointMap.Contains(vertices[i])) // prVertices[i] = prVertices[(int)pointMap[vertices[i]]]; //else //{ // prVertices[i] = new PRVertex(i, vertices[i]); // pointMap.Add(vertices[i], i); //} prVertices[i] = new PRVertex(i, vertices[i]); } //init the faces for (i = 0, j = 0; i < triangles.Length; i += 3, j += 1) { prTriangle[j] = new PRTriangle(i, prVertices[triangles[i]], prVertices[triangles[i + 1]], prVertices[triangles[i + 2]]); //Debug.Log(triangles[i] + " " + triangles[i + 1] + " " + triangles[i + 2]); } //update the neighbour faces of 3 vertex of a triangle for (i = 0; i < prTriangle.Length; i++) { prTriangle[i].vertex[0].face.Add(prTriangle[i]); prTriangle[i].vertex[1].face.Add(prTriangle[i]); prTriangle[i].vertex[2].face.Add(prTriangle[i]); //update the neighbour of a point with the other two points in the triangle for (j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { if (j == k) { continue; } if (!prTriangle[i].vertex[j].neighbor.Contains(prTriangle[i].vertex[k])) { prTriangle[i].vertex[j].neighbor.Add(prTriangle[i].vertex[k]); } } } } //calculate all the costs of the vertexes for (i = 0; i < prVertices.Length; i++) { ComputeEdgeCostAtVertex(prVertices[i]); } //collapse vertex with the least 'collapsePerFrame' cost for (int zx = 0; zx < collapsePerFrame; zx++) { PRVertex mn = MinimunCostEdge(); Collapse(mn, mn.collapse); vertexNum--; } //what dose ReductionData do? [TODO] for (; deleteIndex < reductionData.Count; deleteIndex++) { ApplyData(reductionData[deleteIndex]); } //update the mesh meshToGenerate.vertices = vertices; meshToGenerate.triangles = triangles; GetComponent <MeshFilter>().mesh = meshToGenerate; }