/// <summary> /// Compact triangles, compute edge error and build reference list. /// </summary> /// <param name="iteration">The iteration index.</param> private void UpdateMesh(int iteration, ref Vector3d vbuff, ref Vector3d vbuff2, ref SymmetricMatrix smbuff) { if (iteration > 0) // compact triangles { int dst = 0; for (int i = 0; i < triangles.Length; i++) { if (!triangles.Data[i].deleted) { if (dst != i) { triangles.Data[dst] = triangles.Data[i]; } dst++; } } triangles.Resize(dst); } // Init Quadrics by Plane & Edge Errors // // required at the beginning ( iteration == 0 ) // recomputing during the simplification is not required, // but mostly improves the result for closed meshes if (iteration == 0) { Vector3d p10 = new Vector3d(); Vector3d p20 = new Vector3d(); for (int i = 0; i < triangles.Length; i++) { int v0 = triangles.Data[i].v0; int v1 = triangles.Data[i].v1; int v2 = triangles.Data[i].v2; Vector3d.Sub(ref vertices.Data[v1].p, ref vertices.Data[v0].p, ref p10); Vector3d.Sub(ref vertices.Data[v2].p, ref vertices.Data[v0].p, ref p20); Vector3d.Cross(ref p10, ref p20, ref triangles.Data[i].n); triangles.Data[i].n.Normalize(); smbuff.Repopulate(ref triangles.Data[i].n, -Vector3d.Dot(ref triangles.Data[i].n, ref vertices.Data[v0].p)); SymmetricMatrix.AddInto(ref vertices.Data[v0].q, ref smbuff); SymmetricMatrix.AddInto(ref vertices.Data[v1].q, ref smbuff); SymmetricMatrix.AddInto(ref vertices.Data[v2].q, ref smbuff); } for (int i = 0; i < triangles.Length; i++) { // Calc Edge Error var t = triangles.Data[i]; CalcFullError(ref t, ref vbuff, ref vbuff2, ref smbuff); triangles.Data[i] = t; } } // Init Reference ID list for (int i = 0; i < vertices.Length; i++) { vertices.Data[i].tstart = 0; vertices.Data[i].tcount = 0; } for (int i = 0; i < triangles.Length; i++) { Triangle t = triangles.Data[i]; vertices.Data[t.v0].tcount++; vertices.Data[t.v1].tcount++; vertices.Data[t.v2].tcount++; } int tstartX = 0; for (int i = 0; i < vertices.Length; i++) { vertices.Data[i].tstart = tstartX; if (vertices.Data[i].tcount > 0) { tstartX += vertices.Data[i].tcount; vertices.Data[i].tcount = 0; } } // Write References refs.Resize(tstartX, tstartX * 2); for (int i = 0; i < triangles.Length; i++) { int v0 = triangles.Data[i].v0; int v1 = triangles.Data[i].v1; int v2 = triangles.Data[i].v2; int start0 = vertices.Data[v0].tstart; int count0 = vertices.Data[v0].tcount; int start1 = vertices.Data[v1].tstart; int count1 = vertices.Data[v1].tcount; int start2 = vertices.Data[v2].tstart; int count2 = vertices.Data[v2].tcount; refs.Data[start0 + count0].tid = i; refs.Data[start0 + count0].tvertex = 0; refs.Data[start1 + count1].tid = i; refs.Data[start1 + count1].tvertex = 1; refs.Data[start2 + count2].tid = i; refs.Data[start2 + count2].tvertex = 2; vertices.Data[v0].tcount++; vertices.Data[v1].tcount++; vertices.Data[v2].tcount++; } }