private static IEnumerable <Vertex> GetLeftChain(IList <Vertex> sortedVerts, Face face) { var heHandle = new int(); var endOfChain = sortedVerts.Last(); var startingAtFirstV = _geometry.GetVertexStartingHalfEdges(sortedVerts[0].Handle).ToList(); if (startingAtFirstV.Count > 1) { foreach (var heh in startingAtFirstV) { var he = heh; if (he.IncidentFace == face.Handle) { heHandle = heh.Handle; } } } else { heHandle = sortedVerts[0].IncidentHalfEdge; } do { var halfEdge = _geometry.GetHalfEdgeByHandle(heHandle); yield return(_geometry.GetVertexByHandle(halfEdge.OriginVertex)); heHandle = halfEdge.NextHalfEdge; } while (_geometry.GetHalfEdgeByHandle(heHandle).OriginVertex != endOfChain.Handle); }
private static bool IsEdgeExisting(HalfEdge halfEdge, IEnumerable <BoundaryEdge> boundaryEdges, out int existingHeHandle) { existingHeHandle = new int(); var newHeTargetVert = new int(); foreach (var be in boundaryEdges) { if (be.HalfEdge.Handle == halfEdge.NextHalfEdge) { newHeTargetVert = be.HalfEdge.OriginVertex; } } if (newHeTargetVert == default(int)) { throw new ArgumentException("Target vertex not found!"); } var heStartingAtOldV = _geometry.GetVertexStartingHalfEdges(halfEdge.OriginVertex).ToList(); foreach (var heHandle in heStartingAtOldV) { var he = heHandle; var oldHeTargetVert = _geometry.GetHalfEdgeByHandle(he.NextHalfEdge).OriginVertex; if (oldHeTargetVert != newHeTargetVert) { continue; } existingHeHandle = heHandle.Handle; return(true); } return(false); }
private static Geometry ExtrudeFaceByHandle(Geometry geometry, int faceHandle, float offset, float3 extrusionVector) { var face = geometry.GetFaceByHandle(faceHandle); //get HE of Face var start = geometry.GetHalfEdgeByHandle(face.OuterHalfEdge); var next = start; var vertexIncHe = new Dictionary <int, List <HalfEdge> >(); var allFaceVertices = geometry.GetFaceVertices(faceHandle); foreach (var vertex in allFaceVertices) { vertexIncHe.Add(vertex.Handle, geometry.GetVertexStartingHalfEdges(vertex.Handle).ToList()); } var allH2NEdges = new List <HalfEdge>(); do { var nextOriginV = geometry.GetVertexByHandle(next.OriginVertex); var newVertex = new Vertex(geometry.CreateVertHandleId(), nextOriginV.VertData.Pos); var twinEdge = geometry.GetHalfEdgeByHandle(next.TwinHalfEdge); var prevEdge = geometry.GetHalfEdgeByHandle(next.PrevHalfEdge); var prevTwinEdge = geometry.GetHalfEdgeByHandle(prevEdge.TwinHalfEdge); nextOriginV.VertData.Pos = nextOriginV.VertData.Pos + extrusionVector * offset; var h4 = new HalfEdge(geometry.CreateHalfEdgeHandleId()); var h2n = new HalfEdge(geometry.CreateHalfEdgeHandleId()); var h1 = new HalfEdge(geometry.CreateHalfEdgeHandleId()); var currentList = vertexIncHe[nextOriginV.Handle]; foreach (var halfEdge in currentList) { if (halfEdge == next) { continue; } var edge = GeomEditing.UpdateHalfEdgeOrigin(halfEdge, newVertex.Handle); geometry.ReplaceHalfEdge(edge); } nextOriginV.IncidentHalfEdge = next.Handle; h4.OriginVertex = nextOriginV.Handle; h2n.OriginVertex = newVertex.Handle; h1.OriginVertex = newVertex.Handle; h4.TwinHalfEdge = h2n.Handle; h2n.TwinHalfEdge = h4.Handle; h4.NextHalfEdge = h1.Handle; h1.PrevHalfEdge = h4.Handle; h1.TwinHalfEdge = next.TwinHalfEdge; twinEdge.TwinHalfEdge = h1.Handle; prevTwinEdge.OriginVertex = newVertex.Handle; newVertex.IncidentHalfEdge = h2n.Handle; geometry.ReplaceHalfEdge(twinEdge); geometry.ReplaceHalfEdge(prevTwinEdge); geometry.ReplaceVertex(nextOriginV); geometry.DictVertices.Add(newVertex.Handle, newVertex); geometry.DictHalfEdges.Add(h4.Handle, h4); geometry.DictHalfEdges.Add(h1.Handle, h1); geometry.DictHalfEdges.Add(h2n.Handle, h2n); allH2NEdges.Add(h2n); next = geometry.GetHalfEdgeByHandle(next.NextHalfEdge); } while (start != next); start = geometry.GetHalfEdgeByHandle(face.OuterHalfEdge); next = start; do { var newFace = new Face(geometry.CreateFaceHandleId()); var twinEdge = geometry.GetHalfEdgeByHandle(next.TwinHalfEdge); var h1 = geometry.GetHalfEdgeByHandle(twinEdge.TwinHalfEdge); var h2 = allH2NEdges.First(n => n.OriginVertex == twinEdge.OriginVertex); var h3 = new HalfEdge(geometry.CreateHalfEdgeHandleId()); var h4 = geometry.GetHalfEdgeByHandle(h1.PrevHalfEdge); //set Face h1.IncidentFace = newFace.Handle; h2.IncidentFace = newFace.Handle; h3.IncidentFace = newFace.Handle; h4.IncidentFace = newFace.Handle; h1.NextHalfEdge = h2.Handle; h2.NextHalfEdge = h3.Handle; h3.NextHalfEdge = h4.Handle; h4.NextHalfEdge = h1.Handle; h1.PrevHalfEdge = h4.Handle; h2.PrevHalfEdge = h1.Handle; h3.PrevHalfEdge = h2.Handle; h4.PrevHalfEdge = h3.Handle; h3.TwinHalfEdge = next.Handle; h3.OriginVertex = geometry.GetHalfEdgeByHandle(next.NextHalfEdge).OriginVertex; next.TwinHalfEdge = h3.Handle; newFace.OuterHalfEdge = h1.Handle; //write all changes geometry.ReplaceHalfEdge(h1); geometry.ReplaceHalfEdge(h2); geometry.ReplaceHalfEdge(h4); geometry.ReplaceHalfEdge(next); geometry.DictHalfEdges.Add(h3.Handle, h3); geometry.DictFaces.Add(newFace.Handle, newFace); newFace.FaceData.FaceNormal = GeometricOperations.CalculateFaceNormal(geometry.GetFaceVertices(newFace.Handle).ToList()); geometry.ReplaceFace(newFace); next = geometry.GetHalfEdgeByHandle(next.NextHalfEdge); } while (start != next); return(geometry); }
/// <summary> /// Inserts a new Vertex between two given exsisting Vertices. /// </summary> /// <param name="geometry">The Geometry to insert a Vertex.</param> /// <param name="p">Handle of Vertex one.</param> /// <param name="q">Handle of Vertex two.</param> /// <param name="pos">Position of the new Vertex</param> /// <returns>New Vertex Handle.</returns> public static int InsertVertex(this Geometry geometry, int p, int q, float3 pos) { var adjacentVertices = geometry.GetVertexAdjacentVertices(p).ToList(); for (var i = 0; i < adjacentVertices.Count; i++) { if (adjacentVertices[i].Handle == q) { break; } if (i == adjacentVertices.Count - 1) { throw new ArgumentException("Vertices with Handle q=" + q + " and p=" + p + " are not adjacent!"); } } var newVertex = new Vertex(geometry.CreateVertHandleId(), pos); //add two new Half Edges var newHalfEdge1 = new HalfEdge(geometry.CreateHalfEdgeHandleId()); var newHalfEdge2 = new HalfEdge(geometry.CreateHalfEdgeHandleId()); //set origin to new Vertex newHalfEdge1.OriginVertex = newVertex.Handle; newHalfEdge2.OriginVertex = newVertex.Handle; newVertex.IncidentHalfEdge = newHalfEdge2.Handle; var vertexP = geometry.GetVertexByHandle(p); var vertexQ = geometry.GetVertexByHandle(q); //Find Half Edge between p and q var incomingEdges = geometry.GetVertexStartingHalfEdges(vertexP.Handle); var he1 = new HalfEdge(); var he2 = new HalfEdge(); foreach (var halfEdge in incomingEdges) { var twinEdge = geometry.GetHalfEdgeByHandle(halfEdge.TwinHalfEdge); if (twinEdge.OriginVertex != vertexQ.Handle) { continue; } he1 = halfEdge; he2 = twinEdge; } var next1 = geometry.GetHalfEdgeByHandle(he2.NextHalfEdge); var next2 = geometry.GetHalfEdgeByHandle(he1.NextHalfEdge); //change Handels he1.TwinHalfEdge = newHalfEdge1.Handle; newHalfEdge1.TwinHalfEdge = he1.Handle; newHalfEdge1.NextHalfEdge = he2.NextHalfEdge; he2.NextHalfEdge = newHalfEdge1.Handle; newHalfEdge1.PrevHalfEdge = he2.Handle; next1.PrevHalfEdge = newHalfEdge1.Handle; he2.TwinHalfEdge = newHalfEdge2.Handle; newHalfEdge2.TwinHalfEdge = he2.Handle; newHalfEdge2.NextHalfEdge = he1.NextHalfEdge; he1.NextHalfEdge = newHalfEdge2.Handle; newHalfEdge2.PrevHalfEdge = he1.Handle; next2.PrevHalfEdge = newHalfEdge2.Handle; //reconnect faces newHalfEdge1.IncidentFace = he2.IncidentFace; newHalfEdge2.IncidentFace = he1.IncidentFace; //replace exsisnting Edges geometry.ReplaceHalfEdge(he1); geometry.ReplaceHalfEdge(he2); geometry.ReplaceHalfEdge(next1); geometry.ReplaceHalfEdge(next2); //add to dict geometry.DictVertices.Add(newVertex.Handle, newVertex); geometry.DictHalfEdges.Add(newHalfEdge1.Handle, newHalfEdge1); geometry.DictHalfEdges.Add(newHalfEdge2.Handle, newHalfEdge2); return(newVertex.Handle); }