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); } }
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); }