public HalfEdge CreateHalfEdgeRaw() { var halfEdge = new HalfEdge(this); HalfEdges.Add(halfEdge); return(halfEdge); }
public HalfEdge CreateEdge(Node aNode, Node bNode, bool isDirected = false) { // if (aNode.Edge != null && bNode.Edge != null) // throw new Exception(); var edgeAB = new HalfEdge(this); var edgeBA = new HalfEdge(this); var edge = new Edge(this); var edgePolygon = CreatePolygon(edgeAB); edgeAB.SetOrigin(aNode); edgeBA.SetOrigin(bNode); edgeAB.SetNext(edgeBA); edgeAB.SetPrevious(edgeBA); edgeAB.SetTwin(edgeBA); edgeAB.SetPolygon(edgePolygon); edgeBA.SetPolygon(edgePolygon); if (isDirected) { edgeBA.SetActive(false); } edge.SetPair(edgeAB); Edges.Add(edge); HalfEdges.Add(edgeAB); HalfEdges.Add(edgeBA); return(edgeAB); }
/// <summary> /// Create a subdivision from a single segment (u, v). /// </summary> public DCEL_Subdivision(VecRat2 u, VecRat2 v) : this() { if (u == v) { throw new Exception("Tried to create a DCELSubdivision with a segment of length 0."); } DCEL_Vertex vertex_u = new DCEL_Vertex(u); DCEL_Vertex vertex_v = new DCEL_Vertex(v); DCEL_HalfEdge halfedge_uv = new DCEL_HalfEdge(); DCEL_HalfEdge halfedge_vu = new DCEL_HalfEdge(); DCEL_Face face = new DCEL_Face(); vertex_u.IncidentEdge = halfedge_uv; vertex_v.IncidentEdge = halfedge_vu; halfedge_uv.Origin = vertex_u; halfedge_uv.Twin = halfedge_vu; halfedge_uv.IncidentFace = face; halfedge_uv.Prev = halfedge_vu; halfedge_uv.Next = halfedge_vu; halfedge_vu.Origin = vertex_v; halfedge_vu.Twin = halfedge_uv; halfedge_vu.IncidentFace = face; halfedge_vu.Prev = halfedge_uv; halfedge_vu.Next = halfedge_uv; face.InnerComponents.AddLast(halfedge_uv); Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex_u)); Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex_u)); HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(halfedge_uv)); HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(halfedge_vu)); Faces.Add(new RBTreeSetNode <DCEL_Face>(face)); UnboundedFace = face; }
// Takes a List containing another List per face with the vertex indexes belonging to that face private bool CreateFaces(List <List <int> > faceIndexes) { Dictionary <string, int> edgeCount = new Dictionary <string, int>(); Dictionary <string, MeshHalfEdge> existingHalfEdges = new Dictionary <string, MeshHalfEdge>(); Dictionary <MeshHalfEdge, bool> hasTwinHalfEdge = new Dictionary <MeshHalfEdge, bool>(); // Create the faces, edges and half-edges, non-boundary loops and link references when possible; foreach (List <int> indexes in faceIndexes) { MeshFace f = new MeshFace(); Faces.Add(f); List <MeshHalfEdge> tempHEdges = new List <MeshHalfEdge>(indexes.Count); // Create empty half-edges for (int i = 0; i < indexes.Count; i++) { MeshHalfEdge h = new MeshHalfEdge(); tempHEdges.Add(h); } // Fill out each half edge for (int i = 0; i < indexes.Count; i++) { // Edge goes from v0 to v1 int v0 = indexes[i]; int v1 = indexes[(i + 1) % indexes.Count]; MeshHalfEdge h = tempHEdges[i]; // Set previous and next h.Next = tempHEdges[(i + 1) % indexes.Count]; h.Prev = tempHEdges[(i + indexes.Count - 1) % indexes.Count]; h.OnBoundary = false; hasTwinHalfEdge.Add(h, false); // Set half-edge & vertex mutually h.Vertex = Vertices[v0]; Vertices[v0].HalfEdge = h; // Set half-edge face & vice versa h.Face = f; f.HalfEdge = h; // Reverse v0 and v1 if v0 > v1 if (v0 > v1) { int temp = v0; v0 = v1; v1 = temp; } string key = v0 + " " + v1; if (existingHalfEdges.ContainsKey(key)) { // If this half-edge key already exists, it is the twin of this current half-edge MeshHalfEdge twin = existingHalfEdges[key]; h.Twin = twin; twin.Twin = h; h.Edge = twin.Edge; hasTwinHalfEdge[h] = true; hasTwinHalfEdge[twin] = true; edgeCount[key]++; } else { // Create an edge and set its half-edge MeshEdge e = new MeshEdge(); Edges.Add(e); h.Edge = e; e.HalfEdge = h; // Record the newly created half-edge existingHalfEdges.Add(key, h); edgeCount.Add(key, 1); } } HalfEdges.AddRange(tempHEdges); } // Create boundary edges for (int i = 0; i < HalfEdges.Count; i++) { MeshHalfEdge h = HalfEdges[i]; if (!hasTwinHalfEdge[h]) { MeshFace f = new MeshFace(); Boundaries.Add(f); List <MeshHalfEdge> boundaryCycle = new List <MeshHalfEdge>(); MeshHalfEdge hE = h; do { MeshHalfEdge bH = new MeshHalfEdge(); HalfEdges.Add(bH); boundaryCycle.Add(bH); MeshHalfEdge nextHE = hE.Next; while (hasTwinHalfEdge[nextHE]) { nextHE = nextHE.Twin.Next; } bH.Vertex = nextHE.Vertex; bH.Edge = hE.Edge; bH.OnBoundary = true; bH.Face = f; f.HalfEdge = bH; bH.Twin = hE; hE.Twin = bH; hE = nextHE; }while (hE != h); int n = boundaryCycle.Count; for (int j = 0; j < n; j++) { boundaryCycle[j].Next = boundaryCycle[(j + n - 1) % n]; boundaryCycle[j].Prev = boundaryCycle[(j + 1) % n]; hasTwinHalfEdge[boundaryCycle[j]] = true; hasTwinHalfEdge[boundaryCycle[j].Twin] = true; } } if (!h.OnBoundary) { MeshCorner corner = new MeshCorner { HalfEdge = h, }; h.Corner = corner; Corners.Add(corner); } } // Check mesh for common errors if (HasIsolatedFaces() || HasIsolatedVertices() || HasNonManifoldEdges()) { return(false); } // Index elements IndexElements(); return(true); }