예제 #1
0
        /// <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++;
            }
        }