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); }
void ConstructAdjacencyLists() { adjacency = new HashSet <int> [heMesh.Vertices.Length]; for (int i = 0; i < heMesh.Vertices.Length; i++) { VertexNode root = uf.Find(i); HashSet <int> points = root.MergedPoints; // If the adjacency set for this equiv. class hasn't been // created yet, create it. if (adjacency[root.Index] == null) { HashSet <int> adj = new HashSet <int>(); // We make sure that every point in this class references // the same set. foreach (int p in points) { adjacency[p] = adj; } } // Add all neighbors from all points in the equiv. class foreach (int p in points) { Vertex thisVert = heMesh.Vertices[p]; HalfEdge startHE = thisVert.anyHalfEdge; HalfEdge he = thisVert.anyHalfEdge; do { int neighborInd = he.headVertex.Index; int neighborRoot = uf.Find(neighborInd).Index; // Only add the neighbor if it isn't in the same equiv. class. if (!points.Contains(neighborRoot)) { adjacency[p].Add(neighborRoot); } he = he.flip.next; }while (he != startHE); } } }
public override void Merge(UnionFindNode child) { VertexNode childNode = child as VertexNode; if (child.Parent != child) { throw new System.Exception("Merge wasn't given parent node"); } quadric.AddQuadric(childNode.quadric); //position = (position + childNode.position) / 2; //position = quadric.OptimalPoint(position, childNode.position); int n1 = mergedPoints.Count; int n2 = childNode.mergedPoints.Count; position = ((n1 * position) + (n2 * childNode.position)) / (n1 + n2); currentCost = Cost(position); mergedPoints.UnionWith(childNode.mergedPoints); }