Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <param name="graph"></param>
        /// <param name="componentIndex"></param>
        /// <param name="edgeIndex"></param>
        /// <param name="setVertex"></param>
        /// <param name="setHedge"></param>
        /// <returns></returns>
        public TG[] CreateConnectedComponents <UV, UE>(HeGraph <UV, UE> graph, Property <UE, int> componentIndex, Property <UE, int> edgeIndex, Action <TV, UV> setVertex = null, Action <TE, UE> setHedge = null)
            where UV : HeGraph <UV, UE> .Vertex
            where UE : HeGraph <UV, UE> .Halfedge
        {
            var vertices = graph.Vertices;
            var hedges   = graph.Halfedges;

            int ncomp = graph.GetEdgeComponentIndices(componentIndex.Set);
            var comps = new TG[ncomp];

            // initialize components
            for (int i = 0; i < comps.Length; i++)
            {
                comps[i] = Create();
            }

            // create component halfedges
            for (int i = 0; i < hedges.Count; i += 2)
            {
                var heA = hedges[i];
                if (heA.IsUnused)
                {
                    continue;
                }

                var comp = comps[componentIndex.Get(heA)];
                var heB  = comp.AddEdge();
                edgeIndex.Set(heA, heB.Index >> 1);
            }

            // set component halfedge->halfedge refs
            for (int i = 0; i < hedges.Count; i++)
            {
                var heA0 = hedges[i];
                if (heA0.IsUnused)
                {
                    continue;
                }

                // the component to which heA0 was copied
                var compHedges = comps[componentIndex.Get(heA0)].Halfedges;
                var heA1       = heA0.NextAtStart;

                // set refs
                var heB0 = compHedges[(edgeIndex.Get(heA0) << 1) + (i & 1)];
                var heB1 = compHedges[(edgeIndex.Get(heA1) << 1) + (heA1.Index & 1)];
                heB0.MakeConsecutive(heB1);

                // transfer attributes
                setHedge?.Invoke(heB0, heA0);
            }

            // create component vertices
            for (int i = 0; i < vertices.Count; i++)
            {
                var vA = vertices[i];
                if (vA.IsUnused)
                {
                    continue;
                }

                var heA  = vA.First;
                var comp = comps[componentIndex.Get(heA)];
                var heB  = comp.Halfedges[(edgeIndex.Get(heA) << 1) + (heA.Index & 1)];

                // set vertex refs
                var vB = comp.AddVertex();
                vB.First = heB;

                foreach (var he in heB.CirculateStart)
                {
                    he.Start = vB;
                }

                // transfer attributes
                setVertex?.Invoke(vB, vA);
            }

            return(comps);
        }