public Vector3 CalcMidpoint() { Vector3 accum = Vector3.zero; int ct = 0; if (edges.Count >= 3) // Sanity check { WEdge eStart = this.edges[0]; accum += eStart.GetEdgeVert(this).position; ++ct; for ( WEdge eIt = eStart.GetConnectingEdge(this); eIt != eStart; eIt = eIt.GetConnectingEdge(this)) { accum += eIt.GetEdgeVert(this).position; ++ct; } } if (ct == 0) { return(Vector3.zero); } return(accum / (float)ct); }
public void SimpleSubdivide() { Dictionary <WEdge, Vert> midEdge = new Dictionary <WEdge, Vert>(); Dictionary <Face, Vert> midFace = new Dictionary <Face, Vert>(); // We need to record what we're starting out with, because as we subdivide, // it's going to change those containers List <WEdge> startingEdges = new List <WEdge>(this.edges); List <Face> startingFaces = new List <Face>(this.faces); // Edge centroids foreach (WEdge e in startingEdges) { this.edges.Remove(e.selfNode); if (e.conA.vert != null) { e.conA.vert.edges.Remove(e); } if (e.conB.vert != null) { e.conB.vert.edges.Remove(e); } // Centroid Vert v = this.AddVertice(e.CalcMidpoint()); midEdge[e] = v; WEdge e1 = this.AddBlankEdge(); WEdge e2 = this.AddBlankEdge(); // Subdivision v.edges.Add(e1); v.edges.Add(e2); // Set them to the old faces (new faces don't exist yet) // we do this, so later on we can identify them. e1.conA.face = e.conA.face; e2.conA.face = e.conA.face; e1.conB.face = e.conB.face; e2.conB.face = e.conB.face; // Define the verts for the edges e1.conA.vert = e.conA.vert; e1.conB.vert = v; // Define the verts for the edges e2.conA.vert = v; e2.conB.vert = e.conB.vert; } // Face centroids foreach (Face f in startingFaces) { this.faces.Remove(f.selfNode); // Create subdivided centroid vert. Vert v = this.AddVertice(f.CalcMidpoint()); midFace[f] = v; foreach (WEdge e in f.edges) { WEdge enew = this.AddBlankEdge(); enew.conA.vert = v; enew.conB.vert = midEdge[e]; v.edges.Add(enew); midEdge[e].edges.Add(enew); } } foreach (Face f in startingFaces) { // The edges in a vertice aren't in a certain order, but // there's a property we can leverage Vert v = midFace[f]; for (int i = 0; i < v.edges.Count; ++i) { int nextIdx = (i + 1) % v.edges.Count; WEdge oldEdge = f.edges[i]; WEdge oldEdgeNext = f.edges[nextIdx]; // the subdividing vert for oldEdge Vert subdivVert = midEdge[oldEdge]; Vert subdivVertNext = midEdge[oldEdgeNext]; // New edge from centroid vert to subdivVert WEdge e0 = v.edges[i]; WEdge e1 = subdivVert.EdgeWithFaceAndNotVert(f, oldEdge.GetEdgeVert(f)); WEdge e2 = subdivVertNext.EdgeWithFaceAndVert(f, oldEdgeNext.GetEdgeVert(f)); WEdge e3 = v.edges[nextIdx]; Face fnew = this.AddBlankFace(); // Add edges fnew.edges.Add(e0); fnew.edges.Add(e1); fnew.edges.Add(e2); fnew.edges.Add(e3); // Assemble the edge loop e0.conA.edge = e1; e0.conA.face = fnew; // e1.ReplaceFace(f, fnew); e1.SetEdgeFromFace(e2, fnew); // e2.ReplaceFace(f, fnew); e2.SetEdgeFromFace(e3, fnew); // e3.conB.edge = e0; e3.conB.face = fnew; } } }