Ejemplo n.º 1
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);
        }
        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);
                }
            }
        }
Ejemplo n.º 3
0
        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);
        }