/// <summary> /// /// </summary> /// <param name="path"></param> /// <param name="graph"></param> /// <param name="setVertexAttributes"></param> /// <param name="setHedgeAttributes"></param> public static void ReadFromJson <TV, TE>(string path, HeGraphBase <TV, TE> graph, Action <TV, object[]> setVertexAttributes = null, Action <TE, object[]> setHedgeAttributes = null) where TV : HeGraphBase <TV, TE> .Vertex where TE : HeGraphBase <TV, TE> .Halfedge { var buffer = CoreIO.DeserializeJson <HeJsonBuffer>(path); buffer.ReadTo(graph, setVertexAttributes, setHedgeAttributes); }
/// <summary> /// /// </summary> /// <typeparam name="UV"></typeparam> /// <typeparam name="UE"></typeparam> /// <param name="graph"></param> /// <param name="setVertex"></param> /// <param name="setHedge"></param> /// <returns></returns> public TG CreateCopy <UV, UE>(HeGraphBase <UV, UE> graph, Action <TV, UV> setVertex, Action <TE, UE> setHedge) where UV : HeVertex <UV, UE> where UE : Halfedge <UV, UE> { var copy = Create(graph.Vertices.Capacity, graph.Halfedges.Capacity); copy.Append(graph, setVertex, setHedge); return(copy); }
/// <summary> /// /// </summary> /// <typeparam name="TV"></typeparam> /// <typeparam name="TE"></typeparam> public static void WriteToJson <TV, TE>(HeGraphBase <TV, TE> graph, string path, Func <TV, IEnumerable <object> > getVertexAttributes = null, Func <TE, IEnumerable <object> > getHedgeAttributes = null) where TV : HeGraphBase <TV, TE> .Vertex where TE : HeGraphBase <TV, TE> .Halfedge { var buffer = new HeJsonBuffer(); buffer.WriteFrom(graph, getVertexAttributes, getHedgeAttributes); CoreIO.SerializeJson(buffer, path); }
/// <summary> /// Appends a deep copy of the given graph to this graph. /// Allows projection of element data to a different form. /// </summary> /// <typeparam name="UE"></typeparam> /// <typeparam name="UV"></typeparam> /// <param name="other"></param> /// <param name="setVertex"></param> /// <param name="setHedge"></param> public void Append <UV, UE>(HeGraphBase <UV, UE> other, Action <TV, UV> setVertex, Action <TE, UE> setHedge) where UV : HeVertex <UV, UE> where UE : Halfedge <UV, UE> { var vertsB = other._vertices; var hedgesB = other._hedges; int nvA = _vertices.Count; int nhA = _hedges.Count; // cache in case of appending to self int nvB = vertsB.Count; int nhB = hedgesB.Count; // append new elements for (int i = 0; i < nvB; i++) { AddVertex(); } for (int i = 0; i < nhB; i += 2) { AddEdge(); } // link new vertices to new halfedges for (int i = 0; i < nvB; i++) { var v0 = vertsB[i]; var v1 = _vertices[i + nvA]; setVertex(v1, v0); if (v0.IsRemoved) { continue; } v1.FirstOut = _hedges[v0.FirstOut.Index + nhA]; } // link new halfedges to new vertices and other new halfedges for (int i = 0; i < nhB; i++) { var he0 = hedgesB[i]; var he1 = _hedges[i + nhA]; setHedge(he1, he0); if (he0.IsRemoved) { continue; } he1.PrevAtStart = _hedges[he0.PrevAtStart.Index + nhA]; he1.NextAtStart = _hedges[he0.NextAtStart.Index + nhA]; he1.Start = _vertices[he0.Start.Index + nvA]; } }
/// <summary> /// Writes the given graph to this buffer. /// </summary> /// <param name="graph"></param> public void WriteFrom <TV, TE>(HeGraphBase <TV, TE> graph, Func <TV, IEnumerable <object> > getVertexAttributes = null, Func <TE, IEnumerable <object> > getHedgeAttributes = null) where TV : HeGraphBase <TV, TE> .Vertex where TE : HeGraphBase <TV, TE> .Halfedge { var verts = graph.Vertices; var hedges = graph.Halfedges; _vertexRefs = new int[verts.Count]; _hedgeRefs = new int[hedges.Count][]; // write vertex topology for (int i = 0; i < verts.Count; i++) { var v = verts[i]; _vertexRefs[i] = v.IsUnused ? -1 : v.First; } // write halfedge topology for (int i = 0; i < hedges.Count; i++) { var he = hedges[i]; _hedgeRefs[i] = new int[] { he.PreviousAtStart, he.NextAtStart, he.IsUnused ? -1 : he.Start }; } // write vertex attributes if (getVertexAttributes != null) { _vertexAttributes = new object[verts.Count][]; for (int i = 0; i < verts.Count; i++) { _vertexAttributes[i] = getVertexAttributes(verts[i]).ToArray(); } } // write halfedge attributes if (getHedgeAttributes != null) { _hedgeAttributes = new object[hedges.Count][]; for (int i = 0; i < hedges.Count; i++) { _hedgeAttributes[i] = getHedgeAttributes(hedges[i]).ToArray(); } } }
/// <summary> /// /// </summary> /// <typeparam name="UV"></typeparam> /// <typeparam name="UE"></typeparam> /// <param name="graph"></param> /// <param name="setVertex"></param> /// <param name="setHedge"></param> /// <param name="componentIndices"></param> /// <param name="edgeIndices"></param> /// <returns></returns> public TG[] CreateConnectedComponents <UV, UE>(HeGraphBase <UV, UE> graph, Action <TV, UV> setVertex, Action <TE, UE> setHedge, out int[] componentIndices, out int[] edgeIndices) where UV : HeVertex <UV, UE> where UE : Halfedge <UV, UE> { int ne = graph.Edges.Count; componentIndices = new int[ne]; edgeIndices = new int[ne]; return(CreateConnectedComponents(graph, setVertex, setHedge, ToProp(componentIndices), ToProp(edgeIndices))); Property <UE, T> ToProp <T>(T[] values) { return(Property.Create <UE, T>(he => values[he >> 1], (he, i) => values[he >> 1] = i)); } }
/// <summary> /// /// </summary> /// <typeparam name="UV"></typeparam> /// <typeparam name="UE"></typeparam> /// <param name="graph"></param> /// <param name="setVertex"></param> /// <param name="setHedge"></param> /// <returns></returns> public TG[] CreateConnectedComponents <UV, UE>(HeGraphBase <UV, UE> graph, Action <TV, UV> setVertex, Action <TE, UE> setHedge) where UV : HeVertex <UV, UE> where UE : Halfedge <UV, UE> { return(CreateConnectedComponents(graph, setVertex, setHedge, out int[] compIds, out int[] edgeIds)); }
/// <summary> /// /// </summary> /// <typeparam name="UV"></typeparam> /// <typeparam name="UE"></typeparam> /// <param name="graph"></param> /// <param name="setVertex"></param> /// <param name="setHedge"></param> /// <param name="componentIndex"></param> /// <param name="edgeIndex"></param> /// <returns></returns> public TG[] CreateConnectedComponents <UV, UE>(HeGraphBase <UV, UE> graph, Action <TV, UV> setVertex, Action <TE, UE> setHedge, Property <UE, int> componentIndex, Property <UE, int> edgeIndex) where UV : HeVertex <UV, UE> where UE : Halfedge <UV, UE> { 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.IsRemoved) { 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.IsRemoved) { 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); setHedge(heB0, heA0); } // create component vertices for (int i = 0; i < vertices.Count; i++) { var vA = vertices[i]; if (vA.IsRemoved) { continue; } var heA = vA.FirstOut; 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.FirstOut = heB; foreach (var he in heB.CirculateStart) { he.Start = vB; } setVertex(vB, vA); } return(comps); }
/// <summary> /// Appends a deep copy of the given graph to this graph. /// Allows projection of element data to a different form. /// </summary> /// <typeparam name="UE"></typeparam> /// <typeparam name="UV"></typeparam> /// <param name="other"></param> /// <param name="setVertex"></param> /// <param name="setHedge"></param> public void Append <UV, UE>(HeGraphBase <UV, UE> other, Action <TV, UV> setVertex = null, Action <TE, UE> setHedge = null) where UV : HeGraphBase <UV, UE> .Vertex where UE : HeGraphBase <UV, UE> .Halfedge { if (setVertex == null) { setVertex = delegate { } } ; if (setHedge == null) { setHedge = delegate { } } ; var vertsB = other.Vertices; var hedgesB = other.Halfedges; int nvA = Vertices.Count; int nhA = Halfedges.Count; // cache in case of appending to self int nvB = vertsB.Count; int nhB = hedgesB.Count; // append new elements for (int i = 0; i < nvB; i++) { AddVertex(); } for (int i = 0; i < nhB; i += 2) { AddEdge(); } // link new vertices to new halfedges for (int i = 0; i < nvB; i++) { var v0 = vertsB[i]; var v1 = Vertices[i + nvA]; // transfer attributes setVertex(v1, v0); if (v0.IsUnused) { continue; } v1.First = Halfedges[v0.First.Index + nhA]; } // link new halfedges to new vertices and other new halfedges for (int i = 0; i < nhB; i++) { var he0 = hedgesB[i]; var he1 = Halfedges[i + nhA]; // transfer attributes setHedge(he1, he0); if (he0.IsUnused) { continue; } he1.PreviousAtStart = Halfedges[he0.PreviousAtStart.Index + nhA]; he1.NextAtStart = Halfedges[he0.NextAtStart.Index + nhA]; he1.Start = Vertices[he0.Start.Index + nvA]; } }
/// <summary> /// /// </summary> /// <typeparam name="UV"></typeparam> /// <typeparam name="UE"></typeparam> /// <param name="graph"></param> /// <param name="setVertex"></param> /// <param name="setHedge"></param> /// <returns></returns> public TG[] CreateConnectedComponents <UV, UE>(HeGraphBase <UV, UE> graph, Action <TV, UV> setVertex = null, Action <TE, UE> setHedge = null) where UV : HeGraphBase <UV, UE> .Vertex where UE : HeGraphBase <UV, UE> .Halfedge { return(CreateConnectedComponents(graph, out int[] compIds, out int[] edgeIds, setVertex, setHedge)); }
/// <summary> /// Reads this buffer to the given graph. /// </summary> /// <param name="graph"></param> public void ReadTo <TV, TE>(HeGraphBase <TV, TE> graph, Action <TV, object[]> setVertexAttributes = null, Action <TE, object[]> setHedgeAttributes = null) where TV : HeGraphBase <TV, TE> .Vertex where TE : HeGraphBase <TV, TE> .Halfedge { var verts = graph.Vertices; var hedges = graph.Halfedges; int nv = verts.Count; int nhe = hedges.Count; // add new vertices for (int i = 0; i < _vertexRefs.Length; i++) { graph.AddVertex(); } // add new halfedges for (int i = 0; i < _hedgeRefs.Length; i++) { graph.AddEdge(); } // link up vertices for (int i = 0; i < _vertexRefs.Length; i++) { var v = verts[i + nv]; var first = _vertexRefs[i]; if (first > -1) { v.First = hedges[first + nhe]; } } // link up halfedges for (int i = 0; i < _hedgeRefs.Length; i++) { var he = hedges[i + nhe]; var refs = _hedgeRefs[i]; he.PreviousAtStart = hedges[refs[0] + nhe]; he.NextAtStart = hedges[refs[1] + nhe]; var start = refs[2]; if (start > -1) { he.Start = verts[start + nhe]; } } // TODO validate topology? // set vertex attributes if (setVertexAttributes != null) { for (int i = 0; i < _vertexAttributes.Length; i++) { setVertexAttributes(verts[i + nv], _vertexAttributes[i]); } } // set vertex attributes if (setHedgeAttributes != null) { for (int i = 0; i < _hedgeAttributes.Length; i++) { setHedgeAttributes(hedges[i + nhe], _hedgeAttributes[i]); } } }