public void Clear() { Vertices.Clear(); HalfEdges.Clear(); Faces.Clear(); UnboundedFace = null; }
public DCEL_Subdivision() { ID = NextID++; Vertices = new RBTreeSet <DCEL_Vertex>(DCEL_Element.Compare); HalfEdges = new RBTreeSet <DCEL_HalfEdge>(DCEL_Element.Compare); Faces = new RBTreeSet <DCEL_Face>(DCEL_Element.Compare); UnboundedFace = new DCEL_Face(); }
/// <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; }
private void CreateFaces() { RBTreeMap <DCEL_HalfEdge, HalfEdgeData> halfEdgesData = new RBTreeMap <DCEL_HalfEdge, HalfEdgeData>(DCEL_Element.Compare); foreach (DCEL_HalfEdge halfEdge in outputSubdivision.HalfEdges.Keys) { halfEdgesData.Add(new RBTreeMapNode <DCEL_HalfEdge, HalfEdgeData>(halfEdge, new HalfEdgeData())); } RBTreeMap <DCEL_HalfEdge, CycleData> cyclesData = new RBTreeMap <DCEL_HalfEdge, CycleData>(DCEL_Element.Compare); List <bool> visited = outputSubdivision.HalfEdges.Keys.Select(e => false).ToList(); DCEL_Face unboundedFace = new DCEL_Face(); outputSubdivision.UnboundedFace = unboundedFace; outputSubdivision.Faces.Add(new RBTreeSetNode <DCEL_Face>(unboundedFace)); foreach (var halfEdgeNode in halfEdgesData.Nodes) { DCEL_HalfEdge halfEdge = halfEdgeNode.Key; if (halfEdgeNode.Value.Visited) { continue; } DCEL_HalfEdge cycle = halfEdge.CycleNext.Min((a, b) => a.Origin.CompareTo(b.Origin)); { cycle = cycle.CycleNext.Where(e => e.Origin == cycle.Origin).Max(AngleComparisonUpperList_HalfEdge(cycle.Origin.Position)); } CycleType cycleType = GetCycleType(cycle); if (cycleType == CycleType.Interior) { DCEL_Face interiorFace = new DCEL_Face(); outputSubdivision.Faces.Add(new RBTreeSetNode <DCEL_Face>(interiorFace)); interiorFace.OuterComponent = cycle; foreach (DCEL_HalfEdge cycleHalfEdge in cycle.CycleNext) { cycleHalfEdge.IncidentFace = interiorFace; } } cyclesData.Add(new RBTreeMapNode <DCEL_HalfEdge, CycleData>(cycle, new CycleData(cycleType))); foreach (DCEL_HalfEdge cycleHalfEdge in halfEdge.CycleNext) { HalfEdgeData data = halfEdgesData[cycleHalfEdge].Value; data.Cycle = cycle; } } foreach (var cycleNode in cyclesData.Nodes) { if (cycleNode.Value.CycleType == CycleType.Interior) { continue; } DCEL_HalfEdge cycle = cycleNode.Key; DCEL_HalfEdge leftPick = leftPicksMap[cycle.Origin].Value; if (leftPick == null) { unboundedFace.InnerComponents.AddLast(cycle); foreach (DCEL_HalfEdge cycleHalfEdge in cycle.CycleNext) { cycleHalfEdge.IncidentFace = unboundedFace; } continue; } DCEL_HalfEdge leftPickCycle = halfEdgesData[leftPick].Value.Cycle; CycleType leftPickCycleType = cyclesData[leftPickCycle].Value.CycleType; //if (leftPickCycleType == CycleType.Interior) //{ // leftPickCycle.IncidentFace.InnerComponents.AddLast(cycle); // foreach (DCEL_HalfEdge cycleHalfEdge in cycle.CycleNext) // cycleHalfEdge.IncidentFace = leftPickCycle.IncidentFace; //} cyclesData[leftPickCycle].Value.Children.Add(cycle); cycleNode.Value.IsRoot = false; } foreach (var cycleChildrenNode in cyclesData.Nodes) { if (!cycleChildrenNode.Value.IsRoot) { continue; } DCEL_HalfEdge parentCycle = cycleChildrenNode.Key; CycleType parentCycleType = cyclesData[parentCycle].Value.CycleType; DCEL_Face face = parentCycle.IncidentFace; List <DCEL_HalfEdge> childCycles = cycleChildrenNode.Value.Children; Stack <DCEL_HalfEdge> unattachedCycles = new Stack <DCEL_HalfEdge>(); foreach (DCEL_HalfEdge childCycle in childCycles) { unattachedCycles.Push(childCycle); } while (!unattachedCycles.IsEmpty()) { DCEL_HalfEdge exteriorCycle = unattachedCycles.Pop(); face.InnerComponents.AddLast(exteriorCycle); foreach (DCEL_HalfEdge exteriorCycleHalfEdge in exteriorCycle.CycleNext) { exteriorCycleHalfEdge.IncidentFace = face; } foreach (DCEL_HalfEdge child in cyclesData[exteriorCycle].Value.Children) { unattachedCycles.Push(child); } } } }