public HalfEdge GetEdge(Vertex a, Vertex b, Face f, HalfEdge abNext) { List<HalfEdge> appropriateEdges; if (edges.ContainsKey(b)) { appropriateEdges = edges[b]; } else { appropriateEdges = new List<HalfEdge>(); edges[b] = appropriateEdges; } var query = appropriateEdges.Where(x => x.Twin.End == a); switch (query.Count()) { case 0: { HalfEdge edge = new HalfEdge(this, null, true); HalfEdge twin = edge.Twin; edge.End = b; twin.End = a; edge.Face = f; edge.Next = abNext; return edge; } case 1: { var edge = query.First(); if (abNext != null && edge.Next != abNext && edge.Next != null) throw new ArgumentException("Edge already attached to edge " + edge.Next); if (f != null && edge.Face != f && edge.Face != null) throw new ArgumentException("Edge already attached to face " + edge.Face); edge.Face = f ?? edge.Face; edge.Next = abNext ?? edge.Next; return edge; } default: throw new MeshMalformedException("More than one edge already exists between " + a + " and " + b); } }
private IEnumerable<ProceduralFace> Split(Face f) { HashSet<HalfEdge> edges = new HashSet<HalfEdge>(); foreach (var edge in f.Edges) { var dir = (edge.End.Position - edge.Twin.End.Position); if (Math.Abs(dir.X) > 0.1f || Math.Abs(dir.Z) > 0.1f) edges.Add(edge); } if (edges.Count != 2) throw new InvalidOperationException("Not 2 edges"); int splits = 2; foreach (var edge in edges) { var dir = edge.End.Position - edge.Twin.End.Position; var step = dir / (float)splits; var start = edge.Twin.End.Position; for (int i = 1; i < splits; i++) edge.Split(Mesh.GetVertex(start + step * i)); } Vertex[] vertices = f.Vertices.ToArray(); f.Delete(); for (int i = 0; i < vertices.Length / 2 - 1; i++) { yield return (ProceduralFace)Mesh.GetFace(vertices[i], vertices[i + 1], vertices[vertices.Length - 2 - i], vertices[vertices.Length - 1 - i]); } //return new List<ProceduralFace>(); }
private IEnumerable<ProceduralFace> Split(Face f) { Vertex[] v = f.Vertices.ToArray(); f.Delete(); Vector3 up = -new Plane(v[0].Position, v[1].Position, v[2].Position).Normal; Vertex a = Mesh.GetVertex(v[0].Position * 0.5f + v[1].Position * 0.5f + up * 2); Vertex b = Mesh.GetVertex(v[2].Position * 0.5f + v[3].Position * 0.5f + up * 2); yield return (ProceduralFace)Mesh.GetFace(v[1], v[2], b, a); yield return (ProceduralFace)Mesh.GetFace(v[3], v[0], a, b); yield return (ProceduralFace)Mesh.GetFace(v[0], v[1], a); yield return (ProceduralFace)Mesh.GetFace(v[2], v[3], b); }
public void Deleted(Face f) { changes.Push(new DeleteFace(f)); }
public void Added(Face f) { changes.Push(new AddFace(f)); }
public DeleteFace(Face f) { Border = f.Vertices.Select(a => a.Position).ToArray(); }
public AddFace(Face f) { Border = f.Vertices.ToArray(); }
public void SplitMidpointEnd(Face f, Vertex mid) { throw new NotImplementedException(); }
public Face GetFace(IEnumerable<Vertex> vertices) { //throw new NotImplementedException("Check if this face already exists"); //throw new NotImplementedException("Check if this face would conflict with an already existing face"); List<HalfEdge> edges = new List<HalfEdge>(); Face f = new Face(); Vertex first = null; Vertex previous = null; foreach (var v in vertices) { if (first == null) first = v; else edges.Add(GetEdge(previous, v, f, null)); previous = v; } edges.Add(GetEdge(previous, first, f, null)); for (int i = 0; i < edges.Count; i++) { var next = edges[(i + 1) % edges.Count]; if (edges[i].Next != null && edges[i].Next != next) throw new InvalidOperationException("Cannot link edges, conflicting link already exists"); edges[i].Next = edges[(i + 1) % edges.Count]; } foreach (var vertex in vertices) { var set = faces.GetOrAdd(vertex, a => new ConcurrentDictionary<Face, bool>()); set.AddOrUpdate(f, true, (a, b) => { throw new InvalidOperationException(); }); } return f; }
public HalfEdge GetEdge(Vertex a, Vertex b, Face abf, HalfEdge abNext, Face baf, HalfEdge baNext) { throw new NotImplementedException(); }