static bool Test3() { var mesh = new BMesh(); Vertex v0 = mesh.AddVertex(new Vector3(-1, 0, -1)); Vertex v1 = mesh.AddVertex(new Vector3(-1, 0, 1)); Vertex v2 = mesh.AddVertex(new Vector3(1, 0, 1)); Vertex v3 = mesh.AddVertex(new Vector3(1, 0, -1)); Face f0 = mesh.AddFace(v0, v1, v2); Face f1 = mesh.AddFace(v2, v1, v3); Debug.Assert(mesh.vertices.Count == 4, "vert count"); Debug.Assert(mesh.loops.Count == 6, "loop count"); Debug.Assert(mesh.edges.Count == 5, "edge count"); Debug.Assert(mesh.faces.Count == 2, "face count"); Debug.Assert(v0.NeighborFaces().Count == 1, "v0 has one neighbor face (found count: " + v0.NeighborFaces().Count + ")"); Debug.Assert(v1.NeighborFaces().Count == 2, "v1 has two neighbor face (found count: " + v1.NeighborFaces().Count + ")"); foreach (Loop l in mesh.loops) { Debug.Assert(l.next != null, "loop has a next loop"); Debug.Assert(l.prev != null, "loop has a next loop"); } Debug.Assert(f0.Loop(v0) != null, "loop with vertex v0 does not exist in face f0"); Debug.Assert(f0.Loop(v0).vert == v0, "loop with vertex v0 has v0 as corner"); Debug.Assert(f0.Loop(v1) != null, "loop with vertex v1 does not exist in face f0"); Debug.Assert(f0.Loop(v1).vert == v1, "loop with vertex v1 has v1 as corner"); Debug.Assert(f0.Loop(v3) == null, "loop with vertex v3 does not exist in face f0"); Edge e0 = null; foreach (Edge e in mesh.edges) { if ((e.vert1 == v1 && e.vert2 == v2) || (e.vert1 == v2 && e.vert2 == v1)) { e0 = e; break; } } Debug.Assert(e0 != null, "found edge between v1 and v2"); mesh.RemoveEdge(e0); Debug.Assert(mesh.vertices.Count == 4, "vert count after removing edge"); Debug.Assert(mesh.loops.Count == 0, "loop count after removing edge"); Debug.Assert(mesh.edges.Count == 4, "edge count after removing edge"); Debug.Assert(mesh.faces.Count == 0, "face count after removing edge"); foreach (Loop l in mesh.loops) { Debug.Assert(l.next != null, "loop still has a next loop"); Debug.Assert(l.prev != null, "loop still has a next loop"); } Debug.Log("TestBMesh #3 passed."); return(true); }
/////////////////////////////////////////////////////////////////////////// #region [Subdivide] /** * Subdivide a mesh, without smoothing it, trying to interpolate all * available attributes as much as possible. After subdivision, all faces * are quads. * Overriding attributes: edge's id */ public static void Subdivide(BMesh mesh) { int i = 0; var edgeCenters = new Vertex[mesh.edges.Count]; var originalEdges = new Edge[mesh.edges.Count]; foreach (Edge e in mesh.edges) { edgeCenters[i] = mesh.AddVertex(e.Center()); AttributeLerp(mesh, edgeCenters[i], e.vert1, e.vert2, 0.5f); originalEdges[i] = e; e.id = i++; } var originalFaces = new List <Face>(mesh.faces); // copy because mesh.faces changes during iterations foreach (Face f in originalFaces) { Vertex faceCenter = mesh.AddVertex(f.Center()); float w = 0; // Create one quad per loop in the original face Loop it = f.loop; do { w += 1; AttributeLerp(mesh, faceCenter, faceCenter, it.vert, 1 / w); var quad = new Vertex[] { it.vert, edgeCenters[it.edge.id], faceCenter, edgeCenters[it.prev.edge.id] }; mesh.AddFace(quad); it = it.next; } while (it != f.loop); // then get rid of the original face mesh.RemoveFace(f); } // Remove old edges foreach (Edge e in originalEdges) { mesh.RemoveEdge(e); } }
static bool Test3() { var mesh = new BMesh(); Vertex v0 = mesh.AddVertex(new Vector3(-1, 0, -1)); Vertex v1 = mesh.AddVertex(new Vector3(-1, 0, 1)); Vertex v2 = mesh.AddVertex(new Vector3(1, 0, 1)); Vertex v3 = mesh.AddVertex(new Vector3(1, 0, -1)); Face f0 = mesh.AddFace(v0, v1, v2); Face f1 = mesh.AddFace(v2, v1, v3); Debug.Assert(mesh.vertices.Count == 4, "vert count"); Debug.Assert(mesh.loops.Count == 6, "loop count"); Debug.Assert(mesh.edges.Count == 5, "edge count"); Debug.Assert(mesh.faces.Count == 2, "face count"); Edge e0 = null; foreach (Edge e in mesh.edges) { if ((e.vert1 == v1 && e.vert2 == v2) || (e.vert1 == v2 && e.vert2 == v1)) { e0 = e; break; } } Debug.Assert(e0 != null, "found edge between v1 and v2"); mesh.RemoveEdge(e0); Debug.Assert(mesh.vertices.Count == 4, "vert count after removing edge"); Debug.Assert(mesh.loops.Count == 0, "loop count after removing edge"); Debug.Assert(mesh.edges.Count == 4, "edge count after removing edge"); Debug.Assert(mesh.faces.Count == 0, "face count after removing edge"); Debug.Log("TestBMesh #3 passed."); return(true); }
static bool Test2() { var mesh = new BMesh(); Vertex v0 = mesh.AddVertex(new Vector3(-1, 0, -1)); Vertex v1 = mesh.AddVertex(new Vector3(-1, 0, 1)); Vertex v2 = mesh.AddVertex(new Vector3(1, 0, 1)); Vertex v3 = mesh.AddVertex(new Vector3(1, 0, -1)); Face f = mesh.AddFace(v0, v1, v2, v3); Debug.Assert(mesh.vertices.Count == 4, "vert count"); Debug.Assert(mesh.loops.Count == 4, "loop count"); Debug.Assert(mesh.edges.Count == 4, "edge count"); Debug.Assert(mesh.faces.Count == 1, "face count"); // Edges Edge e0 = mesh.FindEdge(v0, v1); Edge e1 = mesh.FindEdge(v1, v2); Edge e2 = mesh.FindEdge(v2, v3); Edge e3 = mesh.FindEdge(v3, v0); Debug.Assert(e0 != null, "found edge v0->v1"); Debug.Assert(e1 != null, "found edge v1->v2"); Debug.Assert(e2 != null, "found edge v2->v3"); Debug.Assert(e3 != null, "found edge v3->v0"); Vector3 expected; expected = new Vector3(-1, 0, 0); Debug.Assert(Vector3.Distance(expected, e0.Center()) < epsilon, "edge 0 center"); expected = new Vector3(0, 0, 1); Debug.Assert(Vector3.Distance(expected, e1.Center()) < epsilon, "edge 1 center"); expected = new Vector3(1, 0, 0); Debug.Assert(Vector3.Distance(expected, e2.Center()) < epsilon, "edge 2 center"); expected = new Vector3(0, 0, -1); Debug.Assert(Vector3.Distance(expected, e3.Center()) < epsilon, "edge 3 center"); // face expected = new Vector3(0, 0, 0); Debug.Assert(Vector3.Distance(expected, f.Center()) < epsilon, "face center"); // Loop consistency v0.id = 0; v1.id = 1; v2.id = 2; v3.id = 3; Loop l = v0.edge.loop; Loop it = l; int prevId = it.prev.vert.id; int forward = (prevId + 1) % 4 == it.vert.id ? 1 : 0; do { Debug.Assert((forward == 1 && (prevId + 1) % 4 == it.vert.id) || (it.vert.id + 1) % 4 == prevId, "valid quad loop order"); prevId = it.vert.id; it = it.next; } while (it != l); for (int i = 0; i < 4; ++i) { var v = mesh.vertices[i]; Debug.Assert(mesh.loops[i].face == f); Debug.Assert(v.edge != null); Debug.Assert(v.edge.vert1 == v || v.edge.vert2 == v); } Debug.Assert(mesh.FindEdge(v0, v1) != null, "edge between v0 and v1"); mesh.RemoveEdge(mesh.edges[0]); Debug.Assert(mesh.vertices.Count == 4, "vert count after removing edge"); Debug.Assert(mesh.loops.Count == 0, "loop count after removing edge"); Debug.Assert(mesh.edges.Count == 3, "edge count after removing edge"); Debug.Assert(mesh.faces.Count == 0, "face count after removing edge"); Debug.Log("TestBMesh #2 passed."); return(true); }