/// <summary> /// Generate the Voronoi diagram from given triangle mesh.. /// </summary> /// <param name="triangleNetMesh"></param> /// <param name="bounded"></param> protected void Generate(TriangleNetMesh triangleNetMesh) { triangleNetMesh.Renumber(); edges = new List <HalfEdge>(); rays = new List <HalfEdge>(); // Allocate space for Voronoi diagram. var vertices = new Vertex[triangleNetMesh.triangles.Count + triangleNetMesh.hullsize]; var faces = new Face[triangleNetMesh.vertices.Count]; if (factory == null) { factory = new DefaultVoronoiFactory(); } factory.Initialize(vertices.Length, 2 * triangleNetMesh.NumberOfEdges, faces.Length); // Compute triangles circumcenters. var map = ComputeVertices(triangleNetMesh, vertices); // Create all Voronoi faces. foreach (var vertex in triangleNetMesh.vertices.Values) { faces[vertex.id] = factory.CreateFace(vertex); } ComputeEdges(triangleNetMesh, vertices, faces, map); // At this point all edges are computed, but the (edge.next) pointers aren't set. ConnectEdges(map); this.vertices = new List <Vertex>(vertices); this.faces = new List <Face>(faces); }
public static DcelMesh ToDCEL(TriangleNetMesh triangleNetMesh) { var dcel = new DcelMesh(); var vertices = new HVertex[triangleNetMesh.vertices.Count]; var faces = new Face[triangleNetMesh.triangles.Count]; dcel.HalfEdges.Capacity = 2 * triangleNetMesh.NumberOfEdges; triangleNetMesh.Renumber(); HVertex vertex; foreach (var v in triangleNetMesh.vertices.Values) { vertex = new HVertex(v.x, v.y); vertex.id = v.id; vertex.label = v.label; vertices[v.id] = vertex; } // Maps a triangle to its 3 edges (used to set next pointers). var map = new List <HalfEdge> [triangleNetMesh.triangles.Count]; Face face; foreach (var t in triangleNetMesh.triangles) { face = new Face(null); face.id = t.id; faces[t.id] = face; map[t.id] = new List <HalfEdge>(3); } Otri tri = default(Otri), neighbor = default(Otri); Geometry.Vertex org, dest; int id, nid, count = triangleNetMesh.triangles.Count; HalfEdge edge, twin, next; var edges = dcel.HalfEdges; // Count half-edges (edge ids). int k = 0; // Maps a vertex to its leaving boundary edge. var boundary = new Dictionary <int, HalfEdge>(); foreach (var t in triangleNetMesh.triangles) { id = t.id; tri.tri = t; for (int i = 0; i < 3; i++) { tri.orient = i; tri.Sym(ref neighbor); nid = neighbor.tri.id; if (id < nid || nid < 0) { face = faces[id]; // Get the endpoints of the current triangle edge. org = tri.Org(); dest = tri.Dest(); // Create half-edges. edge = new HalfEdge(vertices[org.id], face); twin = new HalfEdge(vertices[dest.id], nid < 0 ? Face.Empty : faces[nid]); map[id].Add(edge); if (nid >= 0) { map[nid].Add(twin); } else { boundary.Add(dest.id, twin); } // Set leaving edges. edge.origin.leaving = edge; twin.origin.leaving = twin; // Set twin edges. edge.twin = twin; twin.twin = edge; edge.id = k++; twin.id = k++; edges.Add(edge); edges.Add(twin); } } } // Set next pointers for each triangle face. foreach (var t in map) { edge = t[0]; next = t[1]; if (edge.twin.origin.id == next.origin.id) { edge.next = next; next.next = t[2]; t[2].next = edge; } else { edge.next = t[2]; next.next = edge; t[2].next = next; } } // Resolve boundary edges. foreach (var e in boundary.Values) { e.next = boundary[e.twin.origin.id]; } dcel.Vertices.AddRange(vertices); dcel.Faces.AddRange(faces); return(dcel); }