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); } }
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)); }
public void AddQuadric(ErrorQuadric other) { quadric.Add(other.quadric, quadric); }