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); } }
public void Deleted(Vertex v) { }
public void Added(Vertex v) { //changes.Push(new AddVertex(v)); }
public EndSplitMidpointHalfEdge(HalfEdge e, Vertex m) { //throw new NotImplementedException(); }
public AddVertex(Vertex v) { Position = v.Position; }
public void SplitMidpointEnd(Face f, Vertex mid) { throw new NotImplementedException(); }
public void SplitMidpointEnd(HalfEdge e, Vertex mid) { changes.Push(new EndSplitMidpointHalfEdge(e, mid)); }
public void SplitMidpointBegin(HalfEdge e, Vertex mid) { changes.Push(new BeginSplitMidpointHalfEdge(e, mid)); }
public static Mesh Cylinder(int segments, int slices, float radius, float height, Mesh m = null) { if (slices < 2) throw new ArgumentException("Must be more than 2 slices"); height /= 2f; m = m ?? new Mesh(); Vertex[][] sliceVerts = new Vertex[slices][]; for (int i = 0; i < slices; i++) sliceVerts[i] = new Vertex[segments]; float angle = 0; float step = MathHelper.TwoPi / (float)segments; for (int segment = 0; segment < segments; segment++) { Vector2 xy = new Vector2((float)Math.Sin(angle), (float)Math.Cos(angle)); for (int slice = 0; slice < slices; slice++) { float l = slice / (float)slices; float z = MathHelper.Lerp(-height, height, l); sliceVerts[slice][segment] = m.GetVertex(new Vector3(xy, z), "slice:" + slice + " seg:" + segment); } angle += step; } m.GetFace(sliceVerts[0].Reverse()); m.GetFace(sliceVerts[slices - 1]); for (int segment = 0; segment < segments; segment++) { for (int slice = 0; slice < slices - 1; slice++) { m.GetFace( sliceVerts[slice][segment], sliceVerts[slice][(segment + 1) % segments], sliceVerts[slice + 1][(segment + 1) % segments], sliceVerts[slice + 1][segment] ); } } return m; }
public HalfEdge Split(Vertex midpoint) { Mesh.InformSplitMidpointBegin(this, midpoint); if (midpoint.Equals(End) || midpoint.Equals(Twin.End)) return this; var a = Twin.End; var m = midpoint; var b = End; Twin.End = m; var bm = Twin; var mb = this; var am = Mesh.GetEdge(a, m, Face, Face == null ? null : mb, mb.Twin.Face, mb.Twin.Next); var ma = am.Twin; if (Face != null) { bm.Next = ma; Face.Edges.Where(e => e.Next == this).First().Next = am; } if (Twin.Face != null) { Twin.Face.Edges.Where(e => e.Next == Twin).First().Next = bm; } Mesh.InformSplitMidpointEnd(this, midpoint); return am; }
/// <summary> /// Inserts a midpoint into this face /// Deletes this face /// </summary> /// <param name="midpoint">The midpoint.</param> public void InsertMidpoint(Vertex midpoint) { Mesh.InformSplitMidpointBegin(this, midpoint); var edges = Edges.ToArray(); Delete(); for (int i = 0; i < edges.Length; i++) { var v1 = edges[i].End; var v2 = edges[(i + 1) % edges.Length].End; Mesh.GetFace(v1, v2, midpoint); } Mesh.InformSplitMidpointEnd(this, midpoint); }
public HalfEdge GetEdge(Vertex a, Vertex b, Face abf, HalfEdge abNext, Face baf, HalfEdge baNext) { throw new NotImplementedException(); }