Example #1
0
        private static void CreateFaceEdges(Vertex[] verticesToUse, List <MeshEdge> edgesToUse, Face createdFace)
        {
            FaceEdge prevFaceEdge = null;

            for (int i = 0; i < verticesToUse.Length - 1; i++)
            {
                MeshEdge currentMeshEdge = edgesToUse[i];
                FaceEdge currentFaceEdge = new FaceEdge(createdFace, currentMeshEdge, verticesToUse[i]);
                if (i == 0)
                {
                    createdFace.firstFaceEdge = currentFaceEdge;
                }
                else
                {
                    prevFaceEdge.nextFaceEdge    = currentFaceEdge;
                    currentFaceEdge.prevFaceEdge = prevFaceEdge;
                }
                currentFaceEdge.AddToRadialLoop(currentMeshEdge);
                prevFaceEdge = currentFaceEdge;
            }
            // make the last FaceEdge
            {
                MeshEdge currentMeshEdge = edgesToUse[verticesToUse.Length - 1];
                FaceEdge currentFaceEdge = new FaceEdge(createdFace, currentMeshEdge, verticesToUse[verticesToUse.Length - 1]);
                prevFaceEdge.nextFaceEdge              = currentFaceEdge;
                currentFaceEdge.prevFaceEdge           = prevFaceEdge;
                currentFaceEdge.nextFaceEdge           = createdFace.firstFaceEdge;
                createdFace.firstFaceEdge.prevFaceEdge = currentFaceEdge;
                currentFaceEdge.AddToRadialLoop(currentMeshEdge);
            }
        }
Example #2
0
        public void MergeMeshEdges(MeshEdge edgeToKeep, MeshEdge edgeToDelete, bool doActualDeletion = true)
        {
            // make sure they sare vertexes (or they can't be merged)
            if (!edgeToDelete.IsConnectedTo(edgeToKeep.VertexOnEnd[0]) ||
                !edgeToDelete.IsConnectedTo(edgeToKeep.VertexOnEnd[1]))
            {
                throw new Exception("These mesh edges do not share vertexes and can't be merged.");
            }

            edgeToDelete.RemoveFromMeshEdgeLinksOfVertex(edgeToKeep.VertexOnEnd[0]);
            edgeToDelete.RemoveFromMeshEdgeLinksOfVertex(edgeToKeep.VertexOnEnd[1]);

            // fix any face edges that are referencing the edgeToDelete
            foreach (FaceEdge attachedFaceEdge in edgeToDelete.firstFaceEdge.RadialNextFaceEdges())
            {
                attachedFaceEdge.meshEdge = edgeToKeep;
            }

            List <FaceEdge> radialLoopToMove = new List <FaceEdge>();

            foreach (FaceEdge faceEdge in edgeToDelete.firstFaceEdge.RadialNextFaceEdges())
            {
                radialLoopToMove.Add(faceEdge);
            }

            foreach (FaceEdge faceEdge in radialLoopToMove)
            {
                faceEdge.AddToRadialLoop(edgeToKeep);
            }

            if (doActualDeletion)
            {
                MeshEdges.Remove(edgeToDelete);
            }
        }
Example #3
0
        public void AddToMeshEdgeLinksOfVertex(IVertex vertexToAddTo)
        {
            int endIndex = GetVertexEndIndex(vertexToAddTo);

            if (vertexToAddTo.FirstMeshEdge == null)
            {
                // the vertex is not currently part of any edge
                // we are the only edge for this vertex so set its links all to this.
                vertexToAddTo.FirstMeshEdge   = this;
                NextMeshEdgeFromEnd[endIndex] = this;
            }
            else             // the vertex is already part of an edge (or many)
            {
                int endIndexOnFirstMeshEdge = vertexToAddTo.FirstMeshEdge.GetVertexEndIndex(vertexToAddTo);

                // remember what the one that is there is pointing at
                MeshEdge vertexCurrentNext = vertexToAddTo.FirstMeshEdge.NextMeshEdgeFromEnd[endIndexOnFirstMeshEdge];

                // point the one that is there at us
                vertexToAddTo.FirstMeshEdge.NextMeshEdgeFromEnd[endIndexOnFirstMeshEdge] = this;

                // and point the one that are already there at this.
                this.NextMeshEdgeFromEnd[endIndex] = vertexCurrentNext;
            }
        }
        private void DrawMeshEdge(MeshEdge meshEdge)
        {
            Vector2 start = GetImagePosition(meshEdge.VertexOnEnd[0].Position);
            Vector2 end   = GetImagePosition(meshEdge.VertexOnEnd[1].Position);

            DrawEdgeLine(start, end, "{0}".FormatWith(meshEdge.ID), meshEdgeColor);
            if (meshEdge.firstFaceEdge != null)
            {
                WriteStringAtPos("{0}".FormatWith(meshEdge.firstFaceEdge.ID), (start + end) / 2 + new Vector2(0, 12), faceEdgeColor);
            }
            else
            {
                WriteStringAtPos("null", (start + end) / 2 + new Vector2(0, 12), faceEdgeColor);
            }

            Vector2 delta  = end - start;
            Vector2 normal = delta.GetNormal();
            double  length = delta.Length;
            Vector2 left   = normal.GetPerpendicularLeft();

            WriteStringAtPos("{0}".FormatWith(meshEdge.NextMeshEdgeFromEnd[0].ID), start + normal * length * .40, meshEdgeColor);
            WriteStringAtPos("{0}".FormatWith(meshEdge.VertexOnEnd[0].ID), start + normal * length * .10, vertexColor);

            WriteStringAtPos("{0}".FormatWith(meshEdge.NextMeshEdgeFromEnd[1].ID), start + normal * length * .60, meshEdgeColor);
            WriteStringAtPos("{0}".FormatWith(meshEdge.VertexOnEnd[1].ID), start + normal * length * .90, vertexColor);
        }
Example #5
0
        public MeshEdge CreateMeshEdge(Vertex vertex1, Vertex vertex2, CreateOption createOption = CreateOption.ReuseExisting)
        {
            if (false)            //!vertices.Contains(vertex1) || !vertices.Contains(vertex2))
            {
                throw new ArgumentException("the two vertices must be in the vertices list before a mesh edge can be made between them.");
            }

            if (vertex1 == vertex2)
            {
                throw new ArgumentException("Your input vertices must not be the same vertex.");
            }

            if (createOption == CreateOption.ReuseExisting)
            {
                MeshEdge existingMeshEdge = vertex1.GetMeshEdgeConnectedToVertex(vertex2);
                if (existingMeshEdge != null)
                {
                    return(existingMeshEdge);
                }
            }

            MeshEdge createdMeshEdge = new MeshEdge(vertex1, vertex2);

            MeshEdges.Add(createdMeshEdge);

            return(createdMeshEdge);
        }
Example #6
0
        public void UnsplitFace(Face faceToKeep, Face faceToDelete, MeshEdge meshEdgeToDelete)
        {
            if (faceToKeep == faceToDelete)
            {
                throw new Exception("Can't join face to itself");
            }

            // validate the edgeToDelete is in both faces, edgeToDelete is only in these two faces, the two faces only share this one edge and no other edges

            FaceEdge faceEdgeToDeleteOnFaceToKeep   = meshEdgeToDelete.GetFaceEdge(faceToKeep);
            FaceEdge faceEdgeToDeleteOnFaceToDelete = meshEdgeToDelete.GetFaceEdge(faceToDelete);

            if (faceEdgeToDeleteOnFaceToKeep.firstVertex == faceEdgeToDeleteOnFaceToDelete.firstVertex)
            {
                throw new Exception("The faces have oposite windings and you cannot merge the edge");
            }

            faceEdgeToDeleteOnFaceToKeep.prevFaceEdge.nextFaceEdge   = faceEdgeToDeleteOnFaceToDelete.nextFaceEdge;
            faceEdgeToDeleteOnFaceToDelete.nextFaceEdge.prevFaceEdge = faceEdgeToDeleteOnFaceToKeep.prevFaceEdge;

            faceEdgeToDeleteOnFaceToKeep.nextFaceEdge.prevFaceEdge   = faceEdgeToDeleteOnFaceToDelete.prevFaceEdge;
            faceEdgeToDeleteOnFaceToDelete.prevFaceEdge.nextFaceEdge = faceEdgeToDeleteOnFaceToKeep.nextFaceEdge;

            // if the face we are deleting is the one that the face to keep was looking at as its starting face edge, move it to the next face edge
            if (faceToKeep.firstFaceEdge == faceEdgeToDeleteOnFaceToKeep)
            {
                faceToKeep.firstFaceEdge = faceToKeep.firstFaceEdge.nextFaceEdge;
            }

            // make sure the FaceEdges all point to the kept face.
            foreach (FaceEdge faceEdge in faceToKeep.firstFaceEdge.NextFaceEdges())
            {
                faceEdge.containingFace = faceToKeep;
            }

            // make sure we take the mesh edge out of the neighbors pointers
            meshEdgeToDelete.RemoveFromMeshEdgeLinksOfVertex(meshEdgeToDelete.VertexOnEnd[0]);
            meshEdgeToDelete.RemoveFromMeshEdgeLinksOfVertex(meshEdgeToDelete.VertexOnEnd[1]);

            // clear the data on the deleted face edge to help with debugging
            faceEdgeToDeleteOnFaceToKeep.meshEdge.VertexOnEnd[0] = null;
            faceEdgeToDeleteOnFaceToKeep.meshEdge.VertexOnEnd[1] = null;
            faceToDelete.firstFaceEdge = null;
            // take the face out of the face list
            faces.Remove(faceToDelete);

            // clear the data on the deleted mesh edge to help with debugging
            meshEdgeToDelete.firstFaceEdge          = null;
            meshEdgeToDelete.VertexOnEnd[0]         = null;
            meshEdgeToDelete.NextMeshEdgeFromEnd[0] = null;
            meshEdgeToDelete.VertexOnEnd[1]         = null;
            meshEdgeToDelete.NextMeshEdgeFromEnd[1] = null;

            MeshEdges.Remove(meshEdgeToDelete);
        }
Example #7
0
        public FaceEdge(Face face, MeshEdge meshEdge, Vertex vertex)
        {
            this.containingFace = face;
            this.meshEdge = meshEdge;
            this.firstVertex = vertex;

            nextFaceEdge = null;
            prevFaceEdge = null;

            radialNextFaceEdge = radialPrevFaceEdge = this;
        }
Example #8
0
        public FaceEdge(Face face, MeshEdge meshEdge, Vertex vertex)
        {
            this.containingFace = face;
            this.meshEdge       = meshEdge;
            this.firstVertex    = vertex;

            nextFaceEdge = null;
            prevFaceEdge = null;

            radialNextFaceEdge = radialPrevFaceEdge = this;
        }
Example #9
0
        public FaceEdge(Face face, MeshEdge meshEdge, IVertex vertex)
        {
            this.ContainingFace = face;
            this.MeshEdge       = meshEdge;
            this.FirstVertex    = vertex;

            NextFaceEdge = null;
            PrevFaceEdge = null;

            RadialNextFaceEdge = radialPrevFaceEdge = this;
        }
Example #10
0
        private static Dictionary <MeshEdge, int> GetMeshEdgeToIndexDictionary(Mesh meshToCopy, Mesh newMesh)
        {
            Dictionary <MeshEdge, int> meshEdgeIndexDictionary = new Dictionary <MeshEdge, int>(meshToCopy.MeshEdges.Count);

            for (int edgeIndex = 0; edgeIndex < meshToCopy.MeshEdges.Count; edgeIndex++)
            {
                MeshEdge edgeToCopy = meshToCopy.MeshEdges[edgeIndex];
                meshEdgeIndexDictionary.Add(edgeToCopy, edgeIndex);
                newMesh.MeshEdges.Add(new MeshEdge());
            }
            return(meshEdgeIndexDictionary);
        }
Example #11
0
        public void SplitMeshEdge(MeshEdge meshEdgeToSplit, out Vertex vertexCreatedDuringSplit, out MeshEdge meshEdgeCreatedDuringSplit)
        {
            // create our new Vertex and MeshEdge
            {
                // make a new vertex between the existing ones

                // TODO: make this create an interpolated vertex, check if it exits and add it or use the right one.
                //vertexCreatedDuringSplit = meshEdgeToSplit.edgeEndVertex[0].CreateInterpolated(meshEdgeToSplit.edgeEndVertex[1], .5);
                vertexCreatedDuringSplit = CreateVertex((meshEdgeToSplit.VertexOnEnd[0].Position + meshEdgeToSplit.VertexOnEnd[1].Position) / 2);
                // TODO: check if the mesh edge exits and use the existing one (or not)
                meshEdgeCreatedDuringSplit = new MeshEdge();
            }

            // Set the new firstMeshEdge on the new Vertex
            vertexCreatedDuringSplit.firstMeshEdge = meshEdgeCreatedDuringSplit;

            Vertex existingVertexToConectTo = meshEdgeToSplit.VertexOnEnd[1];
            // fix the Vertex references on the MeshEdges
            {
                // and set the edges to point to this new one
                meshEdgeCreatedDuringSplit.VertexOnEnd[0] = vertexCreatedDuringSplit;
                meshEdgeCreatedDuringSplit.VertexOnEnd[1] = existingVertexToConectTo;
                meshEdgeToSplit.VertexOnEnd[1]            = vertexCreatedDuringSplit;
            }

            // fix the MeshEdgeLinks on the MeshEdges
            {
                // set the created edge to be connected to the old edges other mesh edges
                meshEdgeCreatedDuringSplit.NextMeshEdgeFromEnd[0] = meshEdgeToSplit;

                // make anything that pointed to the split edge point to the new mesh edge

                meshEdgeToSplit.NextMeshEdgeFromEnd[1] = meshEdgeCreatedDuringSplit;
            }

            // if the MeshEdge is part of a face than we have to fix the face up
            FaceEdge faceEdgeToSplit = meshEdgeToSplit.firstFaceEdge;

            if (faceEdgeToSplit != null)
            {
                foreach (FaceEdge faceEdge in meshEdgeToSplit.FaceEdgesSharingMeshEdge())
                {
                    Face     currentFace = faceEdge.containingFace;
                    FaceEdge newFaceEdge = new FaceEdge(currentFace, meshEdgeCreatedDuringSplit, vertexCreatedDuringSplit);
                    newFaceEdge.AddToRadialLoop(meshEdgeCreatedDuringSplit);
                    // and inject it into the face loop for this face
                    newFaceEdge.prevFaceEdge           = faceEdge;
                    newFaceEdge.nextFaceEdge           = faceEdge.nextFaceEdge;
                    faceEdge.nextFaceEdge.prevFaceEdge = newFaceEdge;
                    faceEdge.nextFaceEdge = newFaceEdge;
                }
            }
        }
Example #12
0
        public IEnumerable <MeshEdge> ConnectedMeshEdges()
        {
            if (this.firstMeshEdge != null)
            {
                MeshEdge curMeshEdge = this.firstMeshEdge;
                do
                {
                    yield return(curMeshEdge);

                    curMeshEdge = curMeshEdge.GetNextMeshEdgeConnectedTo(this);
                } while (curMeshEdge != this.firstMeshEdge);
            }
        }
Example #13
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;
        }
Example #14
0
        public void MergeMeshEdges(ReportProgressRatio reportProgress = null)
        {
            HashSet <MeshEdge> markedForDeletion = new HashSet <MeshEdge>();
            Stopwatch          maxProgressReport = new Stopwatch();

            maxProgressReport.Start();

            for (int i = 0; i < MeshEdges.Count; i++)
            {
                MeshEdge currentMeshEdge = MeshEdges[i];
                if (!markedForDeletion.Contains(currentMeshEdge))
                {
                    Vertex vertex0 = currentMeshEdge.VertexOnEnd[0];
                    Vertex vertex1 = currentMeshEdge.VertexOnEnd[1];

                    // find out if there is another edge attached to the same vertexes
                    List <MeshEdge> meshEdgesToDelete = FindMeshEdges(vertex0, vertex1);

                    if (meshEdgesToDelete.Count > 1)
                    {
                        foreach (MeshEdge meshEdgeToDelete in meshEdgesToDelete)
                        {
                            if (meshEdgeToDelete != currentMeshEdge)
                            {
                                if (!markedForDeletion.Contains(meshEdgeToDelete))
                                {
                                    MergeMeshEdges(currentMeshEdge, meshEdgeToDelete, false);
                                    markedForDeletion.Add(meshEdgeToDelete);
                                }
                            }
                        }
                    }
                }

                if (reportProgress != null)
                {
                    if (maxProgressReport.ElapsedMilliseconds > 200)
                    {
                        bool continueProcessing;
                        reportProgress(i / (double)MeshEdges.Count, "Merging Mesh Edges", out continueProcessing);
                        maxProgressReport.Restart();
                        if (!continueProcessing)
                        {
                            return;
                        }
                    }
                }
            }

            RemoveMeshEdgesMarkedForDeletion(markedForDeletion);
        }
Example #15
0
        private void RemoveMeshEdgesMarkedForDeletion(HashSet <MeshEdge> markedForDeletion)
        {
            List <MeshEdge> NonDeleteMeshEdges = new List <MeshEdge>();

            for (int i = 0; i < MeshEdges.Count; i++)
            {
                MeshEdge meshEdgeToCheck = MeshEdges[i];
                if (!markedForDeletion.Contains(meshEdgeToCheck))
                {
                    NonDeleteMeshEdges.Add(meshEdgeToCheck);
                }
            }

            meshEdges = NonDeleteMeshEdges;
        }
Example #16
0
        public void AddToRadialLoop(MeshEdge currentMeshEdge)
        {
            if (currentMeshEdge.firstFaceEdge == null)
            {
                // This is the first face edge of this mesh edge.  Add it.
                currentMeshEdge.firstFaceEdge = this;
            }
            else
            {
                // There was a face on this mesh edge so add this one in.
                // First set the new face edge radius pointers
                this.radialPrevFaceEdge = currentMeshEdge.firstFaceEdge;
                this.RadialNextFaceEdge = currentMeshEdge.firstFaceEdge.RadialNextFaceEdge;

                // then fix the insertion point to point to this new face edge.
                this.radialPrevFaceEdge.RadialNextFaceEdge = this;
                this.RadialNextFaceEdge.radialPrevFaceEdge = this;
            }
        }
Example #17
0
 public MeshEdge this[int index]
 {
     get
     {
         if (index == 0)
         {
             return nextMeshEdge0;
         }
         return nextMeshEdge1;
     }
     set
     {
         if (index == 0)
         {
             nextMeshEdge0 = value;
         }
         else
         {
             nextMeshEdge1 = value;
         }
     }
 }
Example #18
0
 public           MeshEdge this[int index]
 {
     get
     {
         if (index == 0)
         {
             return(nextMeshEdge0);
         }
         return(nextMeshEdge1);
     }
     set
     {
         if (index == 0)
         {
             nextMeshEdge0 = value;
         }
         else
         {
             nextMeshEdge1 = value;
         }
     }
 }
Example #19
0
		public void MergeMeshEdges(MeshEdge edgeToKeep, MeshEdge edgeToDelete, bool doActualDeletion = true)
		{
			// make sure they share vertexes (or they can't be merged)
			if (!edgeToDelete.IsConnectedTo(edgeToKeep.VertexOnEnd[0])
				|| !edgeToDelete.IsConnectedTo(edgeToKeep.VertexOnEnd[1]))
			{
				throw new Exception("These mesh edges do not share vertexes and can't be merged.");
			}

			edgeToDelete.RemoveFromMeshEdgeLinksOfVertex(edgeToKeep.VertexOnEnd[0]);
			edgeToDelete.RemoveFromMeshEdgeLinksOfVertex(edgeToKeep.VertexOnEnd[1]);

			// fix any face edges that are referencing the edgeToDelete
			foreach (FaceEdge attachedFaceEdge in edgeToDelete.firstFaceEdge.RadialNextFaceEdges())
			{
				attachedFaceEdge.meshEdge = edgeToKeep;
			}

			List<FaceEdge> radialLoopToMove = new List<FaceEdge>();
			foreach (FaceEdge faceEdge in edgeToDelete.firstFaceEdge.RadialNextFaceEdges())
			{
				radialLoopToMove.Add(faceEdge);
			}

			foreach (FaceEdge faceEdge in radialLoopToMove)
			{
				faceEdge.AddToRadialLoop(edgeToKeep);
			}

			if (doActualDeletion)
			{
				MeshEdges.Remove(edgeToDelete);
			}
		}
Example #20
0
		public void DeleteMeshEdge(MeshEdge meshEdgeToDelete)
		{
			// make sure we take the mesh edge out of the neighbors pointers
			meshEdgeToDelete.RemoveFromMeshEdgeLinksOfVertex(meshEdgeToDelete.VertexOnEnd[0]);
			meshEdgeToDelete.RemoveFromMeshEdgeLinksOfVertex(meshEdgeToDelete.VertexOnEnd[1]);

			// clear the data on the deleted mesh edge to help with debugging
			meshEdgeToDelete.firstFaceEdge = null;
			meshEdgeToDelete.VertexOnEnd[0] = null;
			meshEdgeToDelete.NextMeshEdgeFromEnd[0] = null;
			meshEdgeToDelete.VertexOnEnd[1] = null;
			meshEdgeToDelete.NextMeshEdgeFromEnd[1] = null;

			MeshEdges.Remove(meshEdgeToDelete);
		}
Example #21
0
		public void SplitFace(Face faceToSplit, Vertex splitStartVertex, Vertex splitEndVertex, out MeshEdge meshEdgeCreatedDuringSplit, out Face faceCreatedDuringSplit)
		{
			if (!ContainsVertex(splitStartVertex) || !ContainsVertex(splitEndVertex))
			{
				throw new Exception("The mesh must contain the vertices you intend to split between.");
			}

			// we may want to be able to double up an edge for some operations (we'll have to see).
			if (FindMeshEdges(splitStartVertex, splitEndVertex).Count > 0)
			{
				// this also ensures that the face is more than 2 sided.
				throw new Exception("You cannot split a face on an existing edge.");
			}

			FaceEdge faceEdgeAfterSplitStart = null;
			FaceEdge faceEdgeAfterSplitEnd = null;
			int count = 0;
			foreach (FaceEdge faceEdge in faceToSplit.FaceEdges())
			{
				if (faceEdge.firstVertex == splitStartVertex)
				{
					faceEdgeAfterSplitStart = faceEdge;
					count++;
				}
				else if (faceEdge.firstVertex == splitEndVertex)
				{
					faceEdgeAfterSplitEnd = faceEdge;
					count++;
				}
				if (count == 2)
				{
					break; // stop if we found both face edges
				}
			}

			meshEdgeCreatedDuringSplit = CreateMeshEdge(splitStartVertex, splitEndVertex);
			faceCreatedDuringSplit = new Face(faceToSplit);

			faces.Add(faceCreatedDuringSplit);

			FaceEdge newFaceEdgeExistingFace = new FaceEdge(faceToSplit, meshEdgeCreatedDuringSplit, splitStartVertex);
			FaceEdge newFaceEdgeForNewFace = new FaceEdge(faceCreatedDuringSplit, meshEdgeCreatedDuringSplit, splitEndVertex);

			// get the new edges injected into the existing loop, spliting it in two.
			newFaceEdgeExistingFace.prevFaceEdge = faceEdgeAfterSplitStart.prevFaceEdge;
			newFaceEdgeForNewFace.prevFaceEdge = faceEdgeAfterSplitEnd.prevFaceEdge;

			faceEdgeAfterSplitStart.prevFaceEdge.nextFaceEdge = newFaceEdgeExistingFace;
			faceEdgeAfterSplitEnd.prevFaceEdge.nextFaceEdge = newFaceEdgeForNewFace;

			newFaceEdgeExistingFace.nextFaceEdge = faceEdgeAfterSplitEnd;
			newFaceEdgeForNewFace.nextFaceEdge = faceEdgeAfterSplitStart;

			faceEdgeAfterSplitStart.prevFaceEdge = newFaceEdgeForNewFace;
			faceEdgeAfterSplitEnd.prevFaceEdge = newFaceEdgeExistingFace;

			// make sure the first face edge of each face is valid
			faceToSplit.firstFaceEdge = newFaceEdgeExistingFace;
			faceCreatedDuringSplit.firstFaceEdge = newFaceEdgeForNewFace;

			// make sure the FaceEdges of the new face all point to the new face.
			foreach (FaceEdge faceEdge in faceCreatedDuringSplit.firstFaceEdge.NextFaceEdges())
			{
				faceEdge.containingFace = faceCreatedDuringSplit;
			}

			newFaceEdgeExistingFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
			newFaceEdgeForNewFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
		}
Example #22
0
        public static Mesh Copy(Mesh meshToCopy, ReportProgressRatio progress = null)
        {
            Mesh newMesh = new Mesh();

            if (meshToCopy.Vertices.IsSorted)
            {
                Dictionary <Vertex, int>   vertexIndexDictionary   = GetVertexToIndexDictionary(meshToCopy, newMesh);
                Dictionary <MeshEdge, int> meshEdgeIndexDictionary = GetMeshEdgeToIndexDictionary(meshToCopy, newMesh);

                for (int faceIndex = 0; faceIndex < meshToCopy.Faces.Count; faceIndex++)
                {
                    Face faceToCopy = meshToCopy.Faces[faceIndex];
                    newMesh.Faces.Add(new Face());
                }

                // now set all the data for the new mesh
                newMesh.Vertices.Capacity = meshToCopy.Vertices.Capacity;
                for (int vertexIndex = 0; vertexIndex < meshToCopy.Vertices.Count; vertexIndex++)
                {
                    Vertex vertexToCopy = meshToCopy.Vertices[vertexIndex];
                    // !!!! ON ERROR !!!!! If this throws an error, you likely need to CleanAndMergMesh the mesh before copying
                    int    indexOfFirstMeshEdge = meshEdgeIndexDictionary[vertexToCopy.firstMeshEdge];
                    Vertex newVertex            = newMesh.Vertices[vertexIndex];
                    newVertex.firstMeshEdge = newMesh.MeshEdges[indexOfFirstMeshEdge];
                    newVertex.Normal        = vertexToCopy.Normal;
                }

                newMesh.MeshEdges.Capacity = meshToCopy.MeshEdges.Capacity;
                for (int meshEdgeIndex = 0; meshEdgeIndex < meshToCopy.MeshEdges.Count; meshEdgeIndex++)
                {
                    MeshEdge meshEdgeToCopy = meshToCopy.MeshEdges[meshEdgeIndex];
                    MeshEdge newMeshEdge    = newMesh.MeshEdges[meshEdgeIndex];

                    newMeshEdge.NextMeshEdgeFromEnd[0] = newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeToCopy.NextMeshEdgeFromEnd[0]]];
                    newMeshEdge.NextMeshEdgeFromEnd[1] = newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeToCopy.NextMeshEdgeFromEnd[1]]];

                    newMeshEdge.VertexOnEnd[0] = newMesh.Vertices[vertexIndexDictionary[meshEdgeToCopy.VertexOnEnd[0]]];
                    newMeshEdge.VertexOnEnd[1] = newMesh.Vertices[vertexIndexDictionary[meshEdgeToCopy.VertexOnEnd[1]]];

                    // This will get hooked up when we create radial loops with the face edges below
                    //newMeshEdge.firstFaceEdge;
                    //newMesh.MeshEdges.Add(newMeshEdge);
                }

                newMesh.Faces.Capacity = meshToCopy.Faces.Capacity;
                for (int faceIndex = 0; faceIndex < meshToCopy.faces.Count; faceIndex++)
                {
                    Face faceToCopy = meshToCopy.faces[faceIndex];
                    Face newface    = newMesh.faces[faceIndex];

                    newface.normal = faceToCopy.normal;

                    // hook up the face edges
                    //public FaceEdge firstFaceEdge;
                    List <Vertex> verticesFromCopy = new List <Vertex>();
                    List <Vertex> verticesForNew   = new List <Vertex>();
                    foreach (Vertex vertex in faceToCopy.Vertices())
                    {
                        verticesFromCopy.Add(vertex);
                        verticesForNew.Add(newMesh.Vertices[vertexIndexDictionary[vertex]]);
                    }

                    List <MeshEdge> edgesFromCopy = new List <MeshEdge>();
                    List <MeshEdge> edgesForNew   = new List <MeshEdge>();
                    for (int i = 0; i < verticesForNew.Count - 1; i++)
                    {
                        MeshEdge meshEdgeFromCopy = verticesFromCopy[i].GetMeshEdgeConnectedToVertex(verticesFromCopy[i + 1]);
                        edgesFromCopy.Add(meshEdgeFromCopy);
                        edgesForNew.Add(newMesh.MeshEdges[meshEdgeIndexDictionary[meshEdgeFromCopy]]);
                    }
                    MeshEdge lastMeshEdgeFromCopy = verticesFromCopy[verticesFromCopy.Count - 1].GetMeshEdgeConnectedToVertex(verticesFromCopy[0]);
                    edgesFromCopy.Add(lastMeshEdgeFromCopy);
                    edgesForNew.Add(newMesh.MeshEdges[meshEdgeIndexDictionary[lastMeshEdgeFromCopy]]);

                    CreateFaceEdges(verticesForNew.ToArray(), edgesForNew, newface);
                }
            }
            else
            {
                foreach (Face face in meshToCopy.Faces)
                {
                    List <Vertex> faceVertices = new List <Vertex>();
                    foreach (FaceEdge faceEdgeToAdd in face.FaceEdges())
                    {
                        Vertex newVertex = newMesh.CreateVertex(faceEdgeToAdd.firstVertex.Position, CreateOption.CreateNew, SortOption.WillSortLater);
                        faceVertices.Add(newVertex);
                    }

                    newMesh.CreateFace(faceVertices.ToArray(), CreateOption.CreateNew);
                }

                newMesh.CleanAndMergMesh();
            }

            MeshMaterialData materialDataToCopy = MeshMaterialData.Get(meshToCopy);
            MeshMaterialData newMaterialData    = MeshMaterialData.Get(newMesh);

            newMaterialData.MaterialIndex = materialDataToCopy.MaterialIndex;

            return(newMesh);
        }
		private void DrawMeshEdge(MeshEdge meshEdge)
		{
			Vector2 start = GetImagePosition(meshEdge.VertexOnEnd[0].Position);
			Vector2 end = GetImagePosition(meshEdge.VertexOnEnd[1].Position);
			DrawEdgeLine(start, end, "{0}".FormatWith(meshEdge.Data.ID), meshEdgeColor);
			if (meshEdge.firstFaceEdge != null)
			{
				WriteStringAtPos("{0}".FormatWith(meshEdge.firstFaceEdge.Data.ID), (start + end) / 2 + new Vector2(0, 12), faceEdgeColor);
			}
			else
			{
				WriteStringAtPos("null", (start + end) / 2 + new Vector2(0, 12), faceEdgeColor);
			}

			Vector2 delta = end - start;
			Vector2 normal = delta.GetNormal();
			double length = delta.Length;
			Vector2 left = normal.GetPerpendicularLeft();

			WriteStringAtPos("{0}".FormatWith(meshEdge.NextMeshEdgeFromEnd[0].Data.ID), start + normal * length * .40, meshEdgeColor);
			WriteStringAtPos("{0}".FormatWith(meshEdge.VertexOnEnd[0].Data.ID), start + normal * length * .10, vertexColor);

			WriteStringAtPos("{0}".FormatWith(meshEdge.NextMeshEdgeFromEnd[1].Data.ID), start + normal * length * .60, meshEdgeColor);
			WriteStringAtPos("{0}".FormatWith(meshEdge.VertexOnEnd[1].Data.ID), start + normal * length * .90, vertexColor);
		}
Example #24
0
 public void DeleteMeshEdge(MeshEdge meshEdgeToDelete)
 {
 }
Example #25
0
		public void DeleteMeshEdge(MeshEdge meshEdgeToDelete)
		{
		}
Example #26
0
 public bool DeleteMeshEdgeFromFace(Face faceToDeleteEdgeFrom, MeshEdge meshEdgeToDelete)
 {
     throw new NotImplementedException();
 }
Example #27
0
		public void UnsplitFace(Face faceToKeep, Face faceToDelete, MeshEdge meshEdgeToDelete)
		{
			if (faceToKeep == faceToDelete)
			{
				throw new Exception("Can't join face to itself");
			}

			// validate the edgeToDelete is in both faces, edgeToDelete is only in these two faces, the two faces only share this one edge and no other edges

			FaceEdge faceEdgeToDeleteOnFaceToKeep = meshEdgeToDelete.GetFaceEdge(faceToKeep);
			FaceEdge faceEdgeToDeleteOnFaceToDelete = meshEdgeToDelete.GetFaceEdge(faceToDelete);

			if (faceEdgeToDeleteOnFaceToKeep.firstVertex == faceEdgeToDeleteOnFaceToDelete.firstVertex)
			{
				throw new Exception("The faces have oposite windings and you cannot merge the edge");
			}

			faceEdgeToDeleteOnFaceToKeep.prevFaceEdge.nextFaceEdge = faceEdgeToDeleteOnFaceToDelete.nextFaceEdge;
			faceEdgeToDeleteOnFaceToDelete.nextFaceEdge.prevFaceEdge = faceEdgeToDeleteOnFaceToKeep.prevFaceEdge;

			faceEdgeToDeleteOnFaceToKeep.nextFaceEdge.prevFaceEdge = faceEdgeToDeleteOnFaceToDelete.prevFaceEdge;
			faceEdgeToDeleteOnFaceToDelete.prevFaceEdge.nextFaceEdge = faceEdgeToDeleteOnFaceToKeep.nextFaceEdge;

			// if the face we are deleting is the one that the face to keep was looking at as its starting face edge, move it to the next face edge
			if (faceToKeep.firstFaceEdge == faceEdgeToDeleteOnFaceToKeep)
			{
				faceToKeep.firstFaceEdge = faceToKeep.firstFaceEdge.nextFaceEdge;
			}

			// make sure the FaceEdges all point to the kept face.
			foreach (FaceEdge faceEdge in faceToKeep.firstFaceEdge.NextFaceEdges())
			{
				faceEdge.containingFace = faceToKeep;
			}

			DeleteMeshEdge(meshEdgeToDelete);

			// clear the data on the deleted face edge to help with debugging
			faceEdgeToDeleteOnFaceToKeep.meshEdge.VertexOnEnd[0] = null;
			faceEdgeToDeleteOnFaceToKeep.meshEdge.VertexOnEnd[1] = null;
			faceToDelete.firstFaceEdge = null;
			// take the face out of the face list
			faces.Remove(faceToDelete);
		}
Example #28
0
        public void SplitFace(Face faceToSplit, Vertex splitStartVertex, Vertex splitEndVertex, out MeshEdge meshEdgeCreatedDuringSplit, out Face faceCreatedDuringSplit)
        {
            if (!ContainsVertex(splitStartVertex) || !ContainsVertex(splitEndVertex))
            {
                throw new Exception("The mesh must contain the vertices you intend to split between.");
            }

            // we may want to be able to double up an edge for some operations (we'll have to see).
            if (FindMeshEdges(splitStartVertex, splitEndVertex).Count > 0)
            {
                // this also ensures that the face is more than 2 sided.
                throw new Exception("You cannot split a face on an existing edge.");
            }

            FaceEdge faceEdgeAfterSplitStart = null;
            FaceEdge faceEdgeAfterSplitEnd   = null;
            int      count = 0;

            foreach (FaceEdge faceEdge in faceToSplit.FaceEdges())
            {
                if (faceEdge.firstVertex == splitStartVertex)
                {
                    faceEdgeAfterSplitStart = faceEdge;
                    count++;
                }
                else if (faceEdge.firstVertex == splitEndVertex)
                {
                    faceEdgeAfterSplitEnd = faceEdge;
                    count++;
                }
                if (count == 2)
                {
                    break;                     // stop if we found both face edges
                }
            }

            meshEdgeCreatedDuringSplit = CreateMeshEdge(splitStartVertex, splitEndVertex);
            faceCreatedDuringSplit     = new Face(faceToSplit);

            faces.Add(faceCreatedDuringSplit);

            FaceEdge newFaceEdgeExistingFace = new FaceEdge(faceToSplit, meshEdgeCreatedDuringSplit, splitStartVertex);
            FaceEdge newFaceEdgeForNewFace   = new FaceEdge(faceCreatedDuringSplit, meshEdgeCreatedDuringSplit, splitEndVertex);

            // get the new edges injected into the existing loop, spliting it in two.
            newFaceEdgeExistingFace.prevFaceEdge = faceEdgeAfterSplitStart.prevFaceEdge;
            newFaceEdgeForNewFace.prevFaceEdge   = faceEdgeAfterSplitEnd.prevFaceEdge;

            faceEdgeAfterSplitStart.prevFaceEdge.nextFaceEdge = newFaceEdgeExistingFace;
            faceEdgeAfterSplitEnd.prevFaceEdge.nextFaceEdge   = newFaceEdgeForNewFace;

            newFaceEdgeExistingFace.nextFaceEdge = faceEdgeAfterSplitEnd;
            newFaceEdgeForNewFace.nextFaceEdge   = faceEdgeAfterSplitStart;

            faceEdgeAfterSplitStart.prevFaceEdge = newFaceEdgeForNewFace;
            faceEdgeAfterSplitEnd.prevFaceEdge   = newFaceEdgeExistingFace;

            // make sure the first face edge of each face is valid
            faceToSplit.firstFaceEdge            = newFaceEdgeExistingFace;
            faceCreatedDuringSplit.firstFaceEdge = newFaceEdgeForNewFace;

            // make sure the FaceEdges of the new face all point to the new face.
            foreach (FaceEdge faceEdge in faceCreatedDuringSplit.firstFaceEdge.NextFaceEdges())
            {
                faceEdge.containingFace = faceCreatedDuringSplit;
            }

            newFaceEdgeExistingFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
            newFaceEdgeForNewFace.AddToRadialLoop(meshEdgeCreatedDuringSplit);
        }
Example #29
0
 public bool DeleteVertexFromMeshEdge(MeshEdge meshEdgeDeleteVertexFrom, Vertex vertexToDelete)
 {
     throw new NotImplementedException();
 }
Example #30
0
		public bool DeleteVertexFromMeshEdge(MeshEdge meshEdgeDeleteVertexFrom, Vertex vertexToDelete)
		{
			throw new NotImplementedException();
		}
Example #31
0
        public void AddToRadialLoop(MeshEdge currentMeshEdge)
        {
            if (currentMeshEdge.firstFaceEdge == null)
            {
                // This is the first face edge of this mesh edge.  Add it.
                currentMeshEdge.firstFaceEdge = this;
            }
            else
            {
                // There was a face on this mesh edge so add this one in.
                // First set the new face edge radias pointers
                this.radialPrevFaceEdge = currentMeshEdge.firstFaceEdge;
                this.radialNextFaceEdge = currentMeshEdge.firstFaceEdge.radialNextFaceEdge;

                // then fix the insertion point to point to this new face edge.
                this.radialPrevFaceEdge.radialNextFaceEdge = this;
                this.radialNextFaceEdge.radialPrevFaceEdge = this;
            }
        }
Example #32
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;
		}
Example #33
0
		public MeshEdge CreateMeshEdge(Vertex vertex1, Vertex vertex2, CreateOption createOption = CreateOption.ReuseExisting)
		{
			if (false)//!vertices.Contains(vertex1) || !vertices.Contains(vertex2))
			{
				throw new ArgumentException("the two vertices must be in the vertices list before a mesh edge can be made between them.");
			}

			if (vertex1 == vertex2)
			{
				throw new ArgumentException("Your input vertices must not be the same vertex.");
			}

			if (createOption == CreateOption.ReuseExisting)
			{
				MeshEdge existingMeshEdge = vertex1.GetMeshEdgeConnectedToVertex(vertex2);
				if (existingMeshEdge != null)
				{
					return existingMeshEdge;
				}
			}

			MeshEdge createdMeshEdge = new MeshEdge(vertex1, vertex2);

			MeshEdges.Add(createdMeshEdge);

			return createdMeshEdge;
		}
Example #34
0
 public static IReadOnlyList <MeshEdge> NewMeshEdges(this Mesh mesh)
 {
     return(MeshEdge.CreateMeshEdgeList(mesh, VertexFaceList.CreateVertexFaceList(mesh)));
 }
Example #35
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;
        }
Example #36
0
		public bool DeleteMeshEdgeFromFace(Face faceToDeleteEdgeFrom, MeshEdge meshEdgeToDelete)
		{
			throw new NotImplementedException();
		}
Example #37
0
		public void SplitMeshEdge(MeshEdge meshEdgeToSplit, out Vertex vertexCreatedDuringSplit, out MeshEdge meshEdgeCreatedDuringSplit)
		{
			// create our new Vertex and MeshEdge
			{
				// make a new vertex between the existing ones

				// TODO: make this create an interpolated vertex, check if it exits and add it or use the right one.
				//vertexCreatedDuringSplit = meshEdgeToSplit.edgeEndVertex[0].CreateInterpolated(meshEdgeToSplit.edgeEndVertex[1], .5);
				vertexCreatedDuringSplit = CreateVertex((meshEdgeToSplit.VertexOnEnd[0].Position + meshEdgeToSplit.VertexOnEnd[1].Position) / 2);
				// TODO: check if the mesh edge exits and use the existing one (or not)
				meshEdgeCreatedDuringSplit = new MeshEdge();
			}

			// Set the new firstMeshEdge on the new Vertex
			vertexCreatedDuringSplit.firstMeshEdge = meshEdgeCreatedDuringSplit;

			Vertex existingVertexToConectTo = meshEdgeToSplit.VertexOnEnd[1];
			// fix the Vertex references on the MeshEdges
			{
				// and set the edges to point to this new one
				meshEdgeCreatedDuringSplit.VertexOnEnd[0] = vertexCreatedDuringSplit;
				meshEdgeCreatedDuringSplit.VertexOnEnd[1] = existingVertexToConectTo;
				meshEdgeToSplit.VertexOnEnd[1] = vertexCreatedDuringSplit;
			}

			// fix the MeshEdgeLinks on the MeshEdges
			{
				// set the created edge to be connected to the old edges other mesh edges
				meshEdgeCreatedDuringSplit.NextMeshEdgeFromEnd[0] = meshEdgeToSplit;

				// make anything that pointed to the split edge point to the new mesh edge

				meshEdgeToSplit.NextMeshEdgeFromEnd[1] = meshEdgeCreatedDuringSplit;
			}

			// if the MeshEdge is part of a face than we have to fix the face up
			FaceEdge faceEdgeToSplit = meshEdgeToSplit.firstFaceEdge;
			if (faceEdgeToSplit != null)
			{
				foreach (FaceEdge faceEdge in meshEdgeToSplit.FaceEdgesSharingMeshEdge())
				{
					Face currentFace = faceEdge.containingFace;
					FaceEdge newFaceEdge = new FaceEdge(currentFace, meshEdgeCreatedDuringSplit, vertexCreatedDuringSplit);
					newFaceEdge.AddToRadialLoop(meshEdgeCreatedDuringSplit);
					// and inject it into the face loop for this face
					newFaceEdge.prevFaceEdge = faceEdge;
					newFaceEdge.nextFaceEdge = faceEdge.nextFaceEdge;
					faceEdge.nextFaceEdge.prevFaceEdge = newFaceEdge;
					faceEdge.nextFaceEdge = newFaceEdge;
				}
			}
		}