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); } }
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)); }