private static List <KeyValuePair <Vertex, bool> > OutlineVertices(PolyBoundary polyBoundary) { var outlineVerts = new List <KeyValuePair <Vertex, bool> >(); var handle = 0; if (_geometry.DictVertices.Count != 0) { handle = _geometry.DictVertices.Count; } foreach (var coord in polyBoundary.Points) { bool isOldVert; handle++; var vert = CreateOrFindVertex(coord, out isOldVert, handle); outlineVerts.Add(new KeyValuePair <Vertex, bool>(vert, isOldVert)); } return(outlineVerts); }
private static IEnumerable <BoundaryEdge> CreateHalfEdgesForBoundary(PolyBoundary outline) { var outlineVerts = OutlineVertices(outline); var boundaryEdges = BoundaryEdges(outlineVerts, outline); SetPrevAndNextForBoundary(boundaryEdges); var halfEdgesToUpdate = new List <HalfEdge>(); for (var i = boundaryEdges.Count - 1; i > -1; i--) { var bEdge = boundaryEdges[i]; if (!bEdge.IsOriginOldVert) { continue; //A half-edge can only exist if its source vertex is an old one. } int existingHeHandle; if (!IsEdgeExisting(bEdge.HalfEdge, boundaryEdges, out existingHeHandle)) { continue; //Check the target vertex to identify the existing half edge. } //If the existing half edge is halfedge.IncidentFace.OuterHalfEdge, replace it. var face = _geometry.GetFaceByHandle(bEdge.HalfEdge.IncidentFace); if (face.OuterHalfEdge == bEdge.HalfEdge.Handle) { face.OuterHalfEdge = existingHeHandle; _geometry.ReplaceFace(face); } //If the existing half edge is one of the unbounded faces inner half edges, replace it. var unboundedFace = _geometry.DictFaces[1]; for (var k = 0; k < unboundedFace.InnerHalfEdges.Count; k++) { var heHandle = unboundedFace.InnerHalfEdges[k]; if (heHandle != existingHeHandle) { continue; } var nextHe = _geometry.GetHalfEdgeByHandle(heHandle).NextHalfEdge; unboundedFace.InnerHalfEdges[k] = nextHe; _geometry.DictFaces[1] = unboundedFace; break; } var existingHe = _geometry.GetHalfEdgeByHandle(existingHeHandle); existingHe.NextHalfEdge = bEdge.HalfEdge.NextHalfEdge; existingHe.PrevHalfEdge = bEdge.HalfEdge.PrevHalfEdge; existingHe.IncidentFace = bEdge.HalfEdge.IncidentFace; halfEdgesToUpdate.Add(existingHe); SetPrevAndNextToExistingHalfEdge(bEdge, existingHeHandle, boundaryEdges, halfEdgesToUpdate); boundaryEdges.RemoveAt(i); } if (halfEdgesToUpdate.Count == 0) { return(boundaryEdges); } foreach (var he in halfEdgesToUpdate) { _geometry.ReplaceHalfEdge(he); } return(boundaryEdges); }
private static List <BoundaryEdge> BoundaryEdges(IList <KeyValuePair <Vertex, bool> > outlineVerts, PolyBoundary polyBoundary) { var faceHandle = new int(); var boundaryEdges = new List <BoundaryEdge>(); var halfEdgeHandle = 0; if (_geometry.DictHalfEdges.Count != 0) { halfEdgeHandle = _geometry.DictHalfEdges.Count; } for (var j = 0; j < outlineVerts.Count; j++) { var currentVert = outlineVerts[j]; halfEdgeHandle++; if (!currentVert.Value) { //Only necessary for new vertices. var vert = currentVert.Key; vert.IncidentHalfEdge = halfEdgeHandle; _geometry.DictVertices.Add(vert.Handle, vert); } var halfEdge = new HalfEdge(halfEdgeHandle, currentVert.Key.Handle); halfEdgeHandle++; var twinHalfEdge = new HalfEdge(halfEdgeHandle, outlineVerts[(j + 1) % outlineVerts.Count].Key.Handle, halfEdge.Handle, 0, 0, 1); //The unbounded face is always added at first and therefor has 1 as handle. halfEdge.TwinHalfEdge = twinHalfEdge.Handle; //Assumption: outlines are processed from outer to inner, therefore faceHandle will never has its default value if "else" is hit. if (polyBoundary.IsOuter) { if (faceHandle == default(int)) { Face face; faceHandle = AddFace(halfEdge.Handle, out face); _geometry.DictFaces.Add(face.Handle, face); } } else { if (j == 0) { var lastFace = _geometry.DictFaces[_geometry.DictFaces.Keys.Max()]; lastFace.InnerHalfEdges.Add(halfEdge.Handle); } faceHandle = _geometry.DictFaces.Last().Value.Handle; } halfEdge.IncidentFace = faceHandle; if (!outlineVerts[j].Value) { var unboundFace = _geometry.DictFaces[1]; if (j == 0) { unboundFace.InnerHalfEdges.Add(twinHalfEdge.Handle); _geometry.DictFaces[1] = unboundFace; } } var boundaryEdge = new BoundaryEdge { IsOriginOldVert = currentVert.Value, HalfEdge = halfEdge, TwinHalfEdge = twinHalfEdge }; boundaryEdges.Add(boundaryEdge); } return(boundaryEdges); }