/// <summary> /// Add a new face to this mesh. /// The vertex indices provided should reference valid vertices /// already added to this mesh. /// </summary> /// <param name="vertexIndices">The vertex indices which the /// face should join</param> /// <returns>The index of the new face</returns> public int AddFace(IEnumerable <int> vertexIndices) { var face = new MeshFace(); foreach (int i in vertexIndices) { face.Add(Vertices[i]); } Faces.Add(face); return(Faces.Count - 1); }
/// <summary> /// Convert a set of mesh faces generated via delaunay triangulation into its dual - /// the voronoi diagram of the vertices. /// </summary> /// <param name="triangles"></param> /// <returns></returns> public static Dictionary <Vertex, MeshFace> VoronoiFromDelaunay(VertexCollection vertices, MeshFaceCollection faces, bool weighted = false) { var cells = new Dictionary <Vertex, MeshFace>(); //The generated voronoi cells foreach (Vertex v in vertices) { cells.Add(v, new MeshFace()); //Create empty cells } foreach (MeshFace face in faces) { Vertex newVert; if (weighted) { face.WeightedVoronoiPoints(cells); } else { newVert = new Vertex(face.XYCircumcentre); foreach (Vertex v in face) { if (cells.ContainsKey(v)) { MeshFace cell = cells[v]; cell.Add(newVert); } } } } //TODO: Deal with cells on the edge //Sort cell vertices anticlockwise around vertex foreach (KeyValuePair <Vertex, MeshFace> kvp in cells) { kvp.Value.SortVerticesAntiClockwise(kvp.Key.Position); } return(cells); }
/// <summary> /// Load mesh geometry in Wavefront OBJ format. /// The new geometry will be added to any existing already in this mesh. /// </summary> /// <param name="reader"></param> public void FromOBJ(TextReader reader) { int offset = Vertices.Count; while (reader.Peek() >= 0) { string line = reader.ReadLine().Trim().Before('#'); string[] tokens = line.Split(' '); if (tokens.Length > 0) { string key = tokens[0]; if (key.EqualsIgnoreCase("v")) { // Vertex: Vertex v = new Vertex(Vector.FromTokensList(tokens, 1)); Vertices.Add(v); } else if (key.EqualsIgnoreCase("f")) { // Face: MeshFace face = new MeshFace(); for (int i = 1; i < tokens.Length; i++) { string[] subTokens = tokens[i].Split('/'); if (subTokens.Length > 0) { int vi = subTokens[0].ToInteger(-1); if (vi >= 0 && vi + offset < Vertices.Count) { face.Add(Vertices[vi]); } } } } } } }