private void RemoveEdgeInternal(EdgeEntry edgeEntry, bool cascade) { if (!cascade) { if (edgeEntry.Faces.Count > 0) { throw new InvalidOperationException("Some faces still depend on this edge."); } } else { foreach (var faceEntry in edgeEntry.Faces) { faces.Remove(faceEntry); foreach (var fve in faceEntry.Vertices) { fve.Faces.Remove(faceEntry); } foreach (var fee in faceEntry.Edges) { fee.Faces.Remove(faceEntry); } FacePool.Put(faceEntry); } } edgeEntry.V0.Edges.Remove(edgeEntry); edgeEntry.V1.Edges.Remove(edgeEntry); }
void IEnumerator.Reset() { if (_version != _graph._version) { throw new VersionChangedException(); } _current = default(EdgeEntry <T, T>); _started = _hasValue = false; _queue.Clear(); _edges.Clear(); _done = _graph.Count == 0; }
internal EdgeEnumerator([NotNull] GraphList <T> graph) { _graph = graph; _version = graph._version; _current = default(EdgeEntry <T, T>); _started = _hasValue = false; _done = _graph.Count == 0; if (_done) { _queue = null; _edges = null; } else { _queue = new Queue <T>(); _edges = new Queue <EdgeEntry <T, T> >(); } }
public bool MoveNext() { if (_version != _graph._version) { throw new VersionChangedException(); } if (_done) { return(false); } if (!_started) { _started = true; foreach (T vertex in _graph.Keys) { _queue.Enqueue(vertex); } } // visit the next queued edge _hasValue = _edges.Count > 0; if (_hasValue) { _current = _edges.Dequeue(); return(true); } // no more vertices to explore if (_queue.Count == 0) { _done = true; return(false); } // Queue the next edges while (_queue.Count > 0) { T from = _queue.Dequeue(); HashSet <T> edges = _graph[from]; if (edges == null || edges.Count == 0) { continue; } foreach (T edge in edges) { _edges.Enqueue(new EdgeEntry <T, T>(from, edge)); } _hasValue = _edges.Count > 0; _current = _edges.Dequeue(); if (_edges.Count > 0) { break; } } return(true); }
/// <summary> /// Computes the <see cref="TriangleNeighbors"/>. /// </summary> private void ComputeTriangleNeighbors() { if (TriangleNeighbors == null) { return; } int numberOfTriangles = Mesh.NumberOfTriangles; // Fill list with -1. TriangleNeighbors.Clear(); TriangleNeighbors.Capacity = numberOfTriangles * 3; for (int i = 0; i < numberOfTriangles * 3; i++) { TriangleNeighbors.Add(-1); } TriangleMesh mesh = Mesh as TriangleMesh; if (mesh != null) { // We have a TriangleMesh. // We use a hash table to store edge info. The edge vertex indices are the key. // There is one entry for each edge. The first neighbor triangle will create the // edge entry. The second triangle will find the edge entry and fill in the // TriangleNeighbors info. var hashTable = new Dictionary <Pair <int, int>, EdgeEntry>(3 * numberOfTriangles); for (int triangleIndex = 0; triangleIndex < numberOfTriangles; triangleIndex++) { for (int i = 0, j = 2; i < 3; j = i, i++) // j is always "1 vertex index behind" i. { // The index of this edge (0, 1, or 2). var edgeIndex = (i + 1) % 3; // Get indices of the edge's vertices. int index0 = mesh.Indices[triangleIndex * 3 + i]; int index1 = mesh.Indices[triangleIndex * 3 + j]; // Sort indices. if (index0 > index1) { MathHelper.Swap(ref index0, ref index1); } EdgeEntry edge; if (hashTable.TryGetValue(new Pair <int, int>(index0, index1), out edge)) { // Found a neighbor triangle! TriangleNeighbors[triangleIndex * 3 + edgeIndex] = edge.TriangleIndex; TriangleNeighbors[edge.TriangleIndex * 3 + edge.EdgeIndex] = triangleIndex; } else { // This is the first entry hashcode. edge = new EdgeEntry { TriangleIndex = triangleIndex, EdgeIndex = edgeIndex, }; hashTable.Add(new Pair <int, int>(index0, index1), edge); } } } } else { // We only have an ITriangleMesh. // Do same as above, but this time we do not have indices. Instead we use vertices // directly. // We can use Pair<T> instead of Pair<T, T> because Pair<Vector3>. We cannot use // Pair<int> above; maybe because the hashcode of two ints is to weak and there are // a lot of collisions in the hashtable. var hashTable = new Dictionary <Pair <Vector3>, EdgeEntry>(3 * numberOfTriangles); for (int triangleIndex = 0; triangleIndex < numberOfTriangles; triangleIndex++) { var triangle = Mesh.GetTriangle(triangleIndex); for (int i = 0, j = 2; i < 3; j = i, i++) // j is always "1 vertex index behind" i. { // The index of this edge (0, 1, or 2). var edgeIndex = (i + 1) % 3; // Get vertices of the edge's vertices. var vertex0 = triangle[i]; var vertex1 = triangle[j]; // Sort vertices. //if (ShouldSwap(vertex0, vertex1)) // MathHelper.Swap(ref vertex0, ref vertex1); EdgeEntry edge; if (hashTable.TryGetValue(new Pair <Vector3>(vertex0, vertex1), out edge)) { // Found a neighbor triangle! TriangleNeighbors[triangleIndex * 3 + edgeIndex] = edge.TriangleIndex; TriangleNeighbors[edge.TriangleIndex * 3 + edge.EdgeIndex] = triangleIndex; } else { // This is the first entry hashcode. edge = new EdgeEntry { TriangleIndex = triangleIndex, EdgeIndex = edgeIndex, }; hashTable.Add(new Pair <Vector3>(vertex0, vertex1), edge); } } } } }
/// <summary> /// Computes the <see cref="TriangleNeighbors"/>. /// </summary> private void ComputeTriangleNeighbors() { if (TriangleNeighbors == null) return; int numberOfTriangles = Mesh.NumberOfTriangles; // Fill list with -1. TriangleNeighbors.Clear(); TriangleNeighbors.Capacity = numberOfTriangles * 3; for (int i = 0; i < numberOfTriangles * 3; i++) TriangleNeighbors.Add(-1); TriangleMesh mesh = Mesh as TriangleMesh; if (mesh != null) { // We have a TriangleMesh. // We use a hash table to store edge info. The edge vertex indices are the key. // There is one entry for each edge. The first neighbor triangle will create the // edge entry. The second triangle will find the edge entry and fill in the // TriangleNeighbors info. var hashTable = new Dictionary<Pair<int, int>, EdgeEntry>(3 * numberOfTriangles); for (int triangleIndex = 0; triangleIndex < numberOfTriangles; triangleIndex++) { for (int i = 0, j = 2; i < 3; j = i, i++) // j is always "1 vertex index behind" i. { // The index of this edge (0, 1, or 2). var edgeIndex = (i + 1) % 3; // Get indices of the edge's vertices. int index0 = mesh.Indices[triangleIndex * 3 + i]; int index1 = mesh.Indices[triangleIndex * 3 + j]; // Sort indices. if (index0 > index1) MathHelper.Swap(ref index0, ref index1); EdgeEntry edge; if (hashTable.TryGetValue(new Pair<int, int>(index0, index1), out edge)) { // Found a neighbor triangle! TriangleNeighbors[triangleIndex * 3 + edgeIndex] = edge.TriangleIndex; TriangleNeighbors[edge.TriangleIndex * 3 + edge.EdgeIndex] = triangleIndex; } else { // This is the first entry hashcode. edge = new EdgeEntry { TriangleIndex = triangleIndex, EdgeIndex = edgeIndex, }; hashTable.Add(new Pair<int, int>(index0, index1), edge); } } } } else { // We only have an ITriangleMesh. // Do same as above, but this time we do not have indices. Instead we use vertices // directly. // We can use Pair<T> instead of Pair<T, T> because Pair<Vector3F>. We cannot use // Pair<int> above; maybe because the hashcode of two ints is to weak and there are // a lot of collisions in the hashtable. var hashTable = new Dictionary<Pair<Vector3F>, EdgeEntry>(3 * numberOfTriangles); for (int triangleIndex = 0; triangleIndex < numberOfTriangles; triangleIndex++) { var triangle = Mesh.GetTriangle(triangleIndex); for (int i = 0, j = 2; i < 3; j = i, i++) // j is always "1 vertex index behind" i. { // The index of this edge (0, 1, or 2). var edgeIndex = (i + 1) % 3; // Get vertices of the edge's vertices. var vertex0 = triangle[i]; var vertex1 = triangle[j]; // Sort vertices. //if (ShouldSwap(vertex0, vertex1)) // MathHelper.Swap(ref vertex0, ref vertex1); EdgeEntry edge; if (hashTable.TryGetValue(new Pair<Vector3F>(vertex0, vertex1), out edge)) { // Found a neighbor triangle! TriangleNeighbors[triangleIndex * 3 + edgeIndex] = edge.TriangleIndex; TriangleNeighbors[edge.TriangleIndex * 3 + edge.EdgeIndex] = triangleIndex; } else { // This is the first entry hashcode. edge = new EdgeEntry { TriangleIndex = triangleIndex, EdgeIndex = edgeIndex, }; hashTable.Add(new Pair<Vector3F>(vertex0, vertex1), edge); } } } } }