void InitQuadrics()
        {
            Matrix <double>[] faceQuadrics = new Matrix <double> [heMesh.Faces.Length];

            // Compute quadrics for each face
            for (int i = 0; i < faceQuadrics.Length; i++)
            {
                Face f = heMesh.Faces[i];

                if (f.IsBoundary)
                {
                    continue;
                }

                Vector3 normal = f.Normal;
                Vector3 point  = f.anyHalfEdge.tailVertex.position;

                float d = -Vector3.Dot(normal, point);

                DenseVector v = DenseVector.OfArray(new double[] { normal.x, normal.y, normal.z, d });

                faceQuadrics[i] = v.OuterProduct(v);
            }

            // Compute quadrics for each vertex by adding face quadrics
            vertQuadrics = new ErrorQuadric[heMesh.Vertices.Length];

            for (int i = 0; i < vertQuadrics.Length; i++)
            {
                vertQuadrics[i] = new ErrorQuadric();
                Vertex v = heMesh.Vertices[i];

                HalfEdge he    = v.anyHalfEdge;
                HalfEdge start = he;

                do
                {
                    Face f = he.face;
                    if (!f.IsBoundary)
                    {
                        vertQuadrics[i].AddQuadric(faceQuadrics[f.Index]);
                    }
                    he = he.flip.next;
                }while (he != start);
            }

            edgeCosts = new float[heMesh.Edges.Length];
            // Compute initial error values for each edge
            for (int i = 0; i < heMesh.Edges.Length; i++)
            {
                ErrorQuadric Qsum = new ErrorQuadric();
                int          v1   = heMesh.Edges[i].anyHalfEdge.tailVertex.Index;
                int          v2   = heMesh.Edges[i].anyHalfEdge.headVertex.Index;
                Qsum.AddQuadric(vertQuadrics[v1]);
                Qsum.AddQuadric(vertQuadrics[v2]);

                Vector3 opt = Qsum.OptimalPoint(heMesh.Vertices[v1].position, heMesh.Vertices[v2].position);
                edgeCosts[i] = Qsum.ErrorAtPoint(opt);
            }
        }
Ejemplo n.º 2
0
        public static UnionFind <VertexNode> MakeUnionFind(HalfEdgeMesh mesh)
        {
            UnionFind <VertexNode> uf = new UnionFind <VertexNode>(mesh.Vertices.Length);

            Matrix <double>[] faceQuadrics = new Matrix <double> [mesh.Faces.Length];
            for (int i = 0; i < faceQuadrics.Length; i++)
            {
                Face f = mesh.Faces[i];
                if (f.IsBoundary)
                {
                    continue;
                }
                Vector3 normal = f.Normal;
                Vector3 v1     = f.anyHalfEdge.tailVertex.position;

                float d = -Vector3.Dot(v1, normal);

                Vector <double> v = DenseVector.OfArray(new double[] { normal.x, normal.y, normal.z, d });

                faceQuadrics[i] = v.OuterProduct(v);
            }

            for (int i = 0; i < uf.NumNodes; i++)
            {
                VertexNode current = uf[i];
                current.position     = mesh.Vertices[i].position;
                current.containingUF = uf;

                ErrorQuadric vertQuadric = new ErrorQuadric();

                // Iterate over all faces surrounding this vertex and sum up the face quadrics
                HalfEdge start = mesh.Vertices[i].anyHalfEdge;
                HalfEdge he    = start;
                do
                {
                    Face f = he.face;
                    if (!f.IsBoundary)
                    {
                        Matrix <double> faceQuadric = faceQuadrics[he.face.Index];
                        vertQuadric.AddQuadric(faceQuadric);
                    }
                    he = he.flip.next;
                }while (he != start);

                current.quadric      = vertQuadric;
                current.mergedPoints = new HashSet <int>();
                current.mergedPoints.Add(i);
                current.Index = i;
            }

            return(uf);
        }
        float QuadricCostOfEdge(Edge e)
        {
            int v1 = e.anyHalfEdge.tailVertex.Index;
            int v2 = e.anyHalfEdge.headVertex.Index;

            ErrorQuadric Qsum = new ErrorQuadric();

            Qsum.AddQuadric(uf.Find(v1).Quadric);
            Qsum.AddQuadric(uf.Find(v2).Quadric);

            Vector3 optPoint = Qsum.OptimalPoint(heMesh.Vertices[v1].position,
                                                 heMesh.Vertices[v2].position);

            return(Qsum.ErrorAtPoint(optPoint));
        }
Ejemplo n.º 4
0
 public void AddQuadric(ErrorQuadric other)
 {
     quadric.Add(other.quadric, quadric);
 }