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