Ejemplo n.º 1
0
        /// <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);
        }