Ejemplo n.º 1
0
        public void RemoveFromMeshEdgeLinksOfVertex(IVertex vertexToRemoveFrom)
        {
            // lets first fix up the MeshEdge pointed to by the vertexToRemoveFrom
            if (vertexToRemoveFrom.FirstMeshEdge == this)
            {
                MeshEdge nextMeshEdgeConnectedToThisVertex = vertexToRemoveFrom.FirstMeshEdge.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);
                // if this is a radial loop
                if (nextMeshEdgeConnectedToThisVertex == vertexToRemoveFrom.FirstMeshEdge)
                {
                    // the vertex is connected to no edges
                    vertexToRemoveFrom.FirstMeshEdge = null;
                    return;
                }
                else
                {
                    // hook it up to the next connected mesh edge
                    vertexToRemoveFrom.FirstMeshEdge = nextMeshEdgeConnectedToThisVertex;
                }
            }

            // now lets clean up the edge links on the mesh edges that are still connected to the vertexToRemoveFrom
            MeshEdge nextEdgeThisConnectedTo = GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);

            if (nextEdgeThisConnectedTo == this)
            {
                throw new Exception("You can't disconnect when you are the only mesh edge.");
            }

            MeshEdge edgeAfterEdgeWeAreConnectedTo = nextEdgeThisConnectedTo.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);

            if (edgeAfterEdgeWeAreConnectedTo == this)
            {
                // if only 2 edges (this and other) then set the other one to a circular reference to itself
                int indexOnEdgeWeAreConnectedTo = nextEdgeThisConnectedTo.GetVertexEndIndex(vertexToRemoveFrom);
                nextEdgeThisConnectedTo.NextMeshEdgeFromEnd[indexOnEdgeWeAreConnectedTo] = nextEdgeThisConnectedTo;
            }
            else
            {
                // we need to find the edge that has a reference to this one
                MeshEdge edgeConnectedToThis = edgeAfterEdgeWeAreConnectedTo;
                while (edgeConnectedToThis.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom) != this)
                {
                    edgeConnectedToThis = edgeConnectedToThis.GetNextMeshEdgeConnectedTo(vertexToRemoveFrom);
                }
                int indexOfThisOnOther = edgeConnectedToThis.GetVertexEndIndex(vertexToRemoveFrom);
                edgeConnectedToThis.NextMeshEdgeFromEnd[indexOfThisOnOther] = nextEdgeThisConnectedTo;
            }

            // and set this one to null (it has no vertices)
            VertexOnEnd[GetVertexEndIndex(vertexToRemoveFrom)] = null;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Unsplit (merge) the edgeToJoin and the edge that it is connected to through vertexToDelete.
        /// Only unsplit the edge if we are reversing what would have been a split (a single vertex connecting only two edges).
        /// </summary>
        /// <param name="edgeToJoin"></param>
        /// <param name="vertexToDelete"></param>
        /// <returns></returns>
        public void UnsplitMeshEdge(MeshEdge edgeToJoin, Vertex vertexToDelete)
        {
            int endToJoinIndex = edgeToJoin.GetVertexEndIndex(vertexToDelete);

            MeshEdge edgeToDelete = edgeToJoin.GetNextMeshEdgeConnectedTo(vertexToDelete);

            if (edgeToDelete.GetNextMeshEdgeConnectedTo(vertexToDelete) != edgeToJoin)
            {
                // make sure the edgeToJoin is a valid unsplit (only one connection)
                throw new Exception("The edge that is being unsplit must be connected to only one other MeshEdge across the vertexToDelete.");
            }

            int      otherEndOfEdgeToDelete = edgeToDelete.GetOpositeVertexEndIndex(vertexToDelete);
            MeshEdge edgeToJoinTo           = edgeToDelete.NextMeshEdgeFromEnd[otherEndOfEdgeToDelete];

            // if the MeshEdge is part of any faces than we have to fix the faces.
            if (edgeToJoin.firstFaceEdge != null)
            {
                // The edge we split was part of one or more faces, we need to fix the FaceEdge loops
                foreach (FaceEdge faceEdge in edgeToJoin.FaceEdgesSharingMeshEdge())
                {
                    FaceEdge faceEdgeToDelete = null;
                    if (faceEdge.nextFaceEdge.meshEdge == edgeToDelete)
                    {
                        faceEdgeToDelete = faceEdge.nextFaceEdge;
                        FaceEdge newNextFaceEdge = faceEdgeToDelete.nextFaceEdge;
                        newNextFaceEdge.prevFaceEdge = faceEdge;
                        faceEdge.nextFaceEdge        = newNextFaceEdge;
                    }
                    else if (faceEdge.prevFaceEdge.meshEdge == edgeToDelete)
                    {
                        faceEdgeToDelete = faceEdge.prevFaceEdge;
                        FaceEdge newPrevFaceEdge = faceEdgeToDelete.prevFaceEdge;
                        newPrevFaceEdge.nextFaceEdge = faceEdge;
                        faceEdge.prevFaceEdge        = newPrevFaceEdge;
                    }
                    else
                    {
                        throw new Exception("Either the next or prev edge must be the same as the edge to delete.");
                    }

                    // if the FaceEdge we are deleting is the one that the face was using as its firstFaceEdge, change it.
                    if (faceEdge.containingFace.firstFaceEdge == faceEdgeToDelete)
                    {
                        faceEdge.containingFace.firstFaceEdge = faceEdge;
                    }

                    // and clear out the FaceEdge we are deleting to help debugging and other references to it.
                    faceEdgeToDelete.nextFaceEdge       = null;
                    faceEdgeToDelete.prevFaceEdge       = null;
                    faceEdgeToDelete.radialNextFaceEdge = null;
                    faceEdgeToDelete.radialPrevFaceEdge = null;
                    faceEdgeToDelete.meshEdge           = null;
                    faceEdgeToDelete.containingFace     = null;
                    faceEdgeToDelete.firstVertex        = null;
                }
            }

            // fix the MeshEdgeLinks on the edgeToJoin
            {
                edgeToJoin.VertexOnEnd[endToJoinIndex]         = edgeToDelete.VertexOnEnd[otherEndOfEdgeToDelete];
                edgeToJoin.NextMeshEdgeFromEnd[endToJoinIndex] = edgeToDelete.NextMeshEdgeFromEnd[otherEndOfEdgeToDelete];
            }

            // Clear all  the data on the deleted vertex and edge so we have less code that will work if it continues to use them.
            vertexToDelete.firstMeshEdge        = null;
            edgeToDelete.firstFaceEdge          = null;
            edgeToDelete.VertexOnEnd[0]         = null;
            edgeToDelete.NextMeshEdgeFromEnd[0] = null;
            edgeToDelete.VertexOnEnd[1]         = null;
            edgeToDelete.NextMeshEdgeFromEnd[1] = null;
        }
Ejemplo n.º 3
0
		/// <summary>
		/// Unsplit (merge) the edgeToJoin and the edge that it is connected to through vertexToDelete.
		/// Only unsplit the edge if we are reversing what would have been a split (a single vertex connecting only two edges).
		/// </summary>
		/// <param name="edgeToJoin"></param>
		/// <param name="vertexToDelete"></param>
		/// <returns></returns>
		public void UnsplitMeshEdge(MeshEdge edgeToJoin, Vertex vertexToDelete)
		{
			int endToJoinIndex = edgeToJoin.GetVertexEndIndex(vertexToDelete);

			MeshEdge edgeToDelete = edgeToJoin.GetNextMeshEdgeConnectedTo(vertexToDelete);
			if (edgeToDelete.GetNextMeshEdgeConnectedTo(vertexToDelete) != edgeToJoin)
			{
				// make sure the edgeToJoin is a valid unsplit (only one connection)
				throw new Exception("The edge that is being unsplit must be connected to only one other MeshEdge across the vertexToDelete.");
			}

			int otherEndOfEdgeToDelete = edgeToDelete.GetOpositeVertexEndIndex(vertexToDelete);
			MeshEdge edgeToJoinTo = edgeToDelete.NextMeshEdgeFromEnd[otherEndOfEdgeToDelete];

			// if the MeshEdge is part of any faces than we have to fix the faces.
			if (edgeToJoin.firstFaceEdge != null)
			{
				// The edge we split was part of one or more faces, we need to fix the FaceEdge loops
				foreach (FaceEdge faceEdge in edgeToJoin.FaceEdgesSharingMeshEdge())
				{
					FaceEdge faceEdgeToDelete = null;
					if (faceEdge.nextFaceEdge.meshEdge == edgeToDelete)
					{
						faceEdgeToDelete = faceEdge.nextFaceEdge;
						FaceEdge newNextFaceEdge = faceEdgeToDelete.nextFaceEdge;
						newNextFaceEdge.prevFaceEdge = faceEdge;
						faceEdge.nextFaceEdge = newNextFaceEdge;
					}
					else if (faceEdge.prevFaceEdge.meshEdge == edgeToDelete)
					{
						faceEdgeToDelete = faceEdge.prevFaceEdge;
						FaceEdge newPrevFaceEdge = faceEdgeToDelete.prevFaceEdge;
						newPrevFaceEdge.nextFaceEdge = faceEdge;
						faceEdge.prevFaceEdge = newPrevFaceEdge;
					}
					else
					{
						throw new Exception("Either the next or prev edge must be the same as the edge to delete.");
					}

					// if the FaceEdge we are deleting is the one that the face was using as its firstFaceEdge, change it.
					if (faceEdge.containingFace.firstFaceEdge == faceEdgeToDelete)
					{
						faceEdge.containingFace.firstFaceEdge = faceEdge;
					}

					// and clear out the FaceEdge we are deleting to help debugging and other references to it.
					faceEdgeToDelete.nextFaceEdge = null;
					faceEdgeToDelete.prevFaceEdge = null;
					faceEdgeToDelete.radialNextFaceEdge = null;
					faceEdgeToDelete.radialPrevFaceEdge = null;
					faceEdgeToDelete.meshEdge = null;
					faceEdgeToDelete.containingFace = null;
					faceEdgeToDelete.firstVertex = null;
				}
			}

			// fix the MeshEdgeLinks on the edgeToJoin
			{
				edgeToJoin.VertexOnEnd[endToJoinIndex] = edgeToDelete.VertexOnEnd[otherEndOfEdgeToDelete];
				edgeToJoin.NextMeshEdgeFromEnd[endToJoinIndex] = edgeToDelete.NextMeshEdgeFromEnd[otherEndOfEdgeToDelete];
			}

			// Clear all  the data on the deleted vertex and edge so we have less code that will work if it continues to use them.
			vertexToDelete.firstMeshEdge = null;
			edgeToDelete.firstFaceEdge = null;
			edgeToDelete.VertexOnEnd[0] = null;
			edgeToDelete.NextMeshEdgeFromEnd[0] = null;
			edgeToDelete.VertexOnEnd[1] = null;
			edgeToDelete.NextMeshEdgeFromEnd[1] = null;
		}