public void MergeEdgesAroundALoneFace() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(0, 0, 1), "a"); var b = m.GetVertex(new Vector3(0, 0, 2), "b"); var c = m.GetVertex(new Vector3(0, 0, 3), "c"); var d = m.GetVertex(new Vector3(0, 0, 4), "d"); var abcd = m.GetFace(a, b, c, d); var ab = m.GetEdge(a, b); Assert.AreEqual(8, m.HalfEdges.Count()); ab.Merge(); Assert.AreEqual(c, ab.End); Assert.AreEqual(ab.Next, m.GetEdge(c, d, false)); Assert.IsNull(m.GetEdge(a, b, false)); Assert.AreEqual(ab, m.GetEdge(d, a, false).Next); Assert.AreEqual(6, m.HalfEdges.Count()); Assert.AreEqual(3, m.HalfEdges.Where(e => e.Face == null).Count()); Assert.AreEqual(0, m.HalfEdges.Where(e => e.Face != null && e.Next == null).Count()); Assert.AreEqual(0, m.HalfEdges.Where(e => e.Face == null && e.Next != null).Count()); }
public void ConstructTriangle() { Mesh m = new Mesh(); //oh hai var a = m.GetVertex(Vector3.Zero); var b = m.GetVertex(Vector3.Zero); var c = m.GetVertex(Vector3.Zero); var f = m.GetFace(a, b, c); }
public void EdgesEnumerator() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0)); var b = m.GetVertex(new Vector3(2, 0, 0)); var c = m.GetVertex(new Vector3(3, 0, 0)); var f = m.GetFace(a, b, c); var edges = f.Edges.ToArray(); var abc = m.GetEdge(a, b) == edges[0] && m.GetEdge(b, c) == edges[1] && m.GetEdge(c, a) == edges[2]; var bca = m.GetEdge(a, b) == edges[1] && m.GetEdge(b, c) == edges[2] && m.GetEdge(c, a) == edges[0]; var cab = m.GetEdge(a, b) == edges[2] && m.GetEdge(b, c) == edges[0] && m.GetEdge(c, a) == edges[1]; Assert.IsTrue(abc ^ bca ^ cab); }
public void DeleteLoneFace() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0)); var b = m.GetVertex(new Vector3(2, 0, 0)); var c = m.GetVertex(new Vector3(3, 0, 0)); var f = m.GetFace(a, b, c); f.Delete(); foreach (var edge in m.HalfEdges) { Assert.IsNull(edge.Face); Assert.IsNull(edge.Next); Assert.IsNull(edge.Twin.Face); Assert.IsNull(edge.Twin.Next); } Assert.AreEqual(0, m.Faces.Count()); }
public static Mesh Icosahedron(Func<Vector3, Vertex> factory = null) { Mesh m = new Mesh(factory ?? defaultFactory); var vertices = icosahedronVertices.Select(a => m.GetVertex(a)).ToArray(); for (int i = 0; i < icosahedronIndices.Length; i += 3) { var a = vertices[icosahedronIndices[i]]; var b = vertices[icosahedronIndices[i + 1]]; var c = vertices[icosahedronIndices[i + 2]]; Face f = m.GetFace(a, b, c); } return m; }
public static Mesh Icosahedron(Mesh m = null) { m = m ?? new Mesh(); var vertices = icosahedronVertices.Select((a, i) => m.GetVertex(a, i.ToString())).ToArray(); for (int i = 0; i < icosahedronIndices.Length; i += 3) { var a = vertices[icosahedronIndices[i + 2]]; var b = vertices[icosahedronIndices[i + 1]]; var c = vertices[icosahedronIndices[i]]; Face f = m.GetFace(a, b, c); } return(m); }
/// <summary> /// Construct a cuboid graph on the given vertices, winding around { top1, top2, top3, top4 } and then all neighbours accordingly /// </summary> /// <param name="top1"></param> /// <param name="top2"></param> /// <param name="top3"></param> /// <param name="top4"></param> /// <param name="bottom1"></param> /// <param name="bottom2"></param> /// <param name="bottom3"></param> /// <param name="bottom4"></param> /// <param name="factory"></param> /// <returns></returns> public static Mesh Cuboid(Vector3 top1, Vector3 top2, Vector3 top3, Vector3 top4, Vector3 bottom1, Vector3 bottom2, Vector3 bottom3, Vector3 bottom4, Mesh m = null) { m = m ?? new Mesh(); Vertex t1 = m.GetVertex(top1); Vertex t2 = m.GetVertex(top2); Vertex t3 = m.GetVertex(top3); Vertex t4 = m.GetVertex(top4); Vertex b5 = m.GetVertex(bottom1); Vertex b6 = m.GetVertex(bottom2); Vertex b7 = m.GetVertex(bottom3); Vertex b8 = m.GetVertex(bottom4); Face t1234 = m.GetFace(t4, t3, t2, t1); Face t21b56 = m.GetFace(b6, b5, t1, t2); Face t32b67 = m.GetFace(b7, b6, t2, t3); Face t43b78 = m.GetFace(b8, b7, t3, t4); Face t14b85 = m.GetFace(b5, b8, t4, t1); Face b6587 = m.GetFace(b7, b8, b5, b6); return(m); }
/// <summary> /// Construct a cuboid graph on the given vertices, winding around { top1, top2, top3, top4 } and then all neighbours accordingly /// </summary> /// <param name="top1"></param> /// <param name="top2"></param> /// <param name="top3"></param> /// <param name="top4"></param> /// <param name="bottom1"></param> /// <param name="bottom2"></param> /// <param name="bottom3"></param> /// <param name="bottom4"></param> /// <param name="factory"></param> /// <returns></returns> public static Mesh Cuboid(Vector3 top1, Vector3 top2, Vector3 top3, Vector3 top4, Vector3 bottom1, Vector3 bottom2, Vector3 bottom3, Vector3 bottom4, Mesh m = null) { m = m ?? new Mesh(); Vertex t1 = m.GetVertex(top1); Vertex t2 = m.GetVertex(top2); Vertex t3 = m.GetVertex(top3); Vertex t4 = m.GetVertex(top4); Vertex b5 = m.GetVertex(bottom1); Vertex b6 = m.GetVertex(bottom2); Vertex b7 = m.GetVertex(bottom3); Vertex b8 = m.GetVertex(bottom4); Face t1234 = m.GetFace(t4, t3, t2, t1); Face t21b56 = m.GetFace(b6, b5, t1, t2); Face t32b67 = m.GetFace(b7, b6, t2, t3); Face t43b78 = m.GetFace(b8, b7, t3, t4); Face t14b85 = m.GetFace(b5, b8, t4, t1); Face b6587 = m.GetFace(b7, b8, b5, b6); return m; }
public void DeleteAndReplaceSurroundedFace() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0)); var abp = m.GetVertex(new Vector3(0, 1, 0)); var b = m.GetVertex(new Vector3(2, 0, 0)); var bcp = m.GetVertex(new Vector3(0, 2, 0)); var c = m.GetVertex(new Vector3(3, 0, 0)); var cap = m.GetVertex(new Vector3(0, 3, 0)); var f = m.GetFace(a, b, c); var ab = m.GetFace(a, abp, b); var bc = m.GetFace(b, bcp, c); var ca = m.GetFace(c, cap, a); var fEdges = f.Edges.ToList(); f.Delete(); Assert.AreEqual(3, m.Faces.Count()); foreach (var e in fEdges) { Assert.IsNull(e.Face); Assert.IsNull(e.Next); } foreach (var e in fEdges) { Assert.IsNotNull(e.Twin.Face); Assert.IsNotNull(e.Twin.Next); } f = m.GetFace(b, c, m.GetVertex(Vector3.Zero)); }
public void SplitEdgeWithDuplicatePoint() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(0, 0, 1), "a"); var b = m.GetVertex(new Vector3(0, 0, 2), "b"); var ab = m.GetEdge(a, b); var mid = m.GetVertex(new Vector3(0, 0, 2), "mid"); ab.Split(mid); Assert.IsNull(ab.Face); Assert.IsNull(ab.Next); Assert.IsNull(ab.Twin.Face); Assert.IsNull(ab.Twin.Next); Assert.AreEqual(1, a.OutgoingEdges.Count()); Assert.AreEqual(1, a.IncomingEdges.Count()); Assert.AreEqual(1, b.OutgoingEdges.Count()); Assert.AreEqual(1, b.IncomingEdges.Count()); Assert.AreEqual(1, mid.OutgoingEdges.Count()); Assert.AreEqual(1, mid.IncomingEdges.Count()); Assert.AreEqual(2, m.HalfEdges.Count()); Assert.AreEqual(2, m.Vertices.Count()); Assert.AreEqual(0, m.Faces.Count()); }
public void SplitFloatingEdge() { Mesh m = new Mesh(); var a = m.GetVertex(Vector3.Zero, "a"); var b = m.GetVertex(Vector3.One, "b"); var ab = m.GetEdge(a, b); var mid = m.GetVertex(Vector3.Up, "mid"); var splitResult = ab.Split(mid); Assert.AreEqual(ab.End, b); Assert.AreEqual(ab.Twin.End, mid); Assert.AreEqual(splitResult.End, mid); Assert.AreEqual(splitResult.Twin.End, a); Assert.IsNull(ab.Face); Assert.IsNull(ab.Next); Assert.IsNull(ab.Twin.Face); Assert.IsNull(ab.Twin.Next); Assert.AreEqual(1, a.OutgoingEdges.Count()); Assert.AreEqual(1, a.IncomingEdges.Count()); Assert.AreEqual(1, b.OutgoingEdges.Count()); Assert.AreEqual(1, b.IncomingEdges.Count()); Assert.AreEqual(2, mid.OutgoingEdges.Count()); Assert.AreEqual(2, mid.IncomingEdges.Count()); }
public void VerticesEnumerator() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0)); var b = m.GetVertex(new Vector3(2, 0, 0)); var c = m.GetVertex(new Vector3(3, 0, 0)); var f = m.GetFace(a, b, c); var vertices = f.Vertices.ToArray(); var abc = vertices[0] == a && vertices[1] == b && vertices[2] == c; var bca = vertices[1] == a && vertices[2] == b && vertices[0] == c; var cab = vertices[2] == a && vertices[0] == b && vertices[1] == c; Assert.IsTrue(abc ^ bca ^ cab); }
public void InsertMidpoint() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0)); var b = m.GetVertex(new Vector3(2, 0, 0)); var c = m.GetVertex(new Vector3(3, 0, 0)); var f = m.GetFace(a, b, c); f.InsertMidpoint(m.GetVertex(new Vector3(4, 0, 0))); Assert.AreEqual(3, m.Faces.Count()); }
public void SplitHalfEdgeOnASingleFace() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0), "a"); var b = m.GetVertex(new Vector3(2, 0, 0), "b"); var c = m.GetVertex(new Vector3(3, 0, 0), "c"); var f = m.GetFace(a, b, c); var mid = m.GetVertex(new Vector3(4, 0, 0), "mid"); var ab = m.GetEdge(a, b); ab.Split(mid); Assert.AreEqual(4, f.Edges.Count()); Assert.AreEqual(4, f.Vertices.Count()); Assert.AreEqual(0, f.Neighbours.Count()); var ba = m.GetEdge(b, a); Assert.IsNull(ba.Face); Assert.IsNull(ba.Next); }
public void SplitEdgeCheckUpdatedIndices() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0), "a"); var b = m.GetVertex(new Vector3(2, 0, 0), "b"); var c = m.GetVertex(new Vector3(3, 0, 0), "c"); var d = m.GetVertex(new Vector3(4, 0, 0), "d"); Face abc = m.GetFace(a, b, c); Face bcd = m.GetFace(c, b, d); var bc = m.GetEdge(b, c); var mid = m.GetVertex(new Vector3(5, 0, 0), "m"); bc.Split(mid); Assert.AreEqual(2, mid.Neighbours.Count()); Assert.IsTrue(mid.Neighbours.Contains(abc)); Assert.IsTrue(mid.Neighbours.Contains(bcd)); }
public override void Undo(Mesh mesh, Stack<Change> changes) { var f = mesh.GetFace(Border.Select(a => mesh.GetVertex(a))); }
public override void Undo(Mesh mesh, Stack<Change> changes) { mesh.GetEdge(mesh.GetVertex(Start), mesh.GetVertex(End)).Delete(); }
public static Mesh Icosahedron(Mesh m = null) { m = m ?? new Mesh(); var vertices = icosahedronVertices.Select((a, i) => m.GetVertex(a, i.ToString())).ToArray(); for (int i = 0; i < icosahedronIndices.Length; i += 3) { var a = vertices[icosahedronIndices[i + 2]]; var b = vertices[icosahedronIndices[i + 1]]; var c = vertices[icosahedronIndices[i]]; Face f = m.GetFace(a, b, c); } return m; }
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 void FacesEnumerator() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0)); var abp = m.GetVertex(new Vector3(0, 1, 0)); var b = m.GetVertex(new Vector3(2, 0, 0)); var bcp = m.GetVertex(new Vector3(0, 2, 0)); var c = m.GetVertex(new Vector3(3, 0, 0)); var cap = m.GetVertex(new Vector3(0, 3, 0)); var f = m.GetFace(a, b, c); var ab = m.GetFace(a, abp, b); var bc = m.GetFace(b, bcp, c); var ca = m.GetFace(c, cap, a); var faces = f.Neighbours.ToArray(); var abc = faces[0] == ab && faces[1] == bc && faces[2] == ca; var bca = faces[1] == ab && faces[2] == bc && faces[0] == ca; var cab = faces[2] == ab && faces[0] == bc && faces[1] == ca; Assert.IsTrue(abc ^ bca ^ cab); }
public override void Undo(Mesh mesh, Stack<Change> changes) { AddHalfEdge h = (AddHalfEdge)changes.Pop(); BeginSplitMidpointHalfEdge b = (BeginSplitMidpointHalfEdge)changes.Pop(); mesh.GetEdge(mesh.GetVertex(h.Start), mesh.GetVertex(h.End), false).Merge(); mesh.CleanEdges(); mesh.CleanVertices(); }
public void GetSameFaceTwiceWithDifferentVertexIndices() { Mesh m = new Mesh(); Vertex a = m.GetVertex(new Vector3(0, 0, 1)); Vertex b = m.GetVertex(new Vector3(0, 0, 2)); Vertex c = m.GetVertex(new Vector3(0, 0, 3)); Vertex d = m.GetVertex(new Vector3(0, 0, 4)); Face abcd = m.GetFace(a, b, c, d); Face bcda = m.GetFace(b, c, d, a); Face cdab = m.GetFace(c, d, a, b); Face dabc = m.GetFace(d, a, b, c); Assert.AreEqual(abcd, bcda); Assert.AreEqual(abcd, cdab); Assert.AreEqual(abcd, dabc); }
public override void Undo(Mesh mesh, Stack<Change> changes) { if (!Skip) mesh.GetEdge(mesh.GetVertex(Start), mesh.GetVertex(End)); }
public void SplitHalfEdgeBetweenTwoFaces() { Mesh m = new Mesh(); var a = m.GetVertex(new Vector3(1, 0, 0), "a"); var b = m.GetVertex(new Vector3(2, 0, 0), "b"); var c = m.GetVertex(new Vector3(3, 0, 0), "c"); var d = m.GetVertex(new Vector3(4, 0, 0), "d"); Face abc = m.GetFace(a, b, c); Face bcd = m.GetFace(c, b, d); var bc = m.GetEdge(b, c); bc.Split(m.GetVertex(new Vector3(5, 0, 0), "m")); foreach (var face in m.Faces) { foreach (var edge in face.Edges) Assert.AreEqual(edge.End, edge.Next.Twin.End); } Assert.AreEqual(4, abc.Edges.Count()); Assert.AreEqual(1, abc.Neighbours.Count()); Assert.AreEqual(4, abc.Vertices.Count()); Assert.AreEqual(4, bcd.Edges.Count()); Assert.AreEqual(1, bcd.Neighbours.Count()); Assert.AreEqual(4, bcd.Vertices.Count()); }