liveElements function
Every live element of level, each exactly once, in id order.
Lazy, so a caller that wants the first ten pays for ten. That is what describeElements's own cap does with it; a selection command that wants all of them walks all of them and allocates nothing but the ids it keeps.
Implementation
Iterable<int> liveElements(EditMesh mesh, ElementLevel level) sync* {
switch (level) {
case ElementLevel.vertex:
for (var vertex = 0; vertex < mesh.vertexSlotCount; vertex++) {
if (mesh.isVertexAlive(vertex)) yield vertex;
}
case ElementLevel.face:
for (var face = 0; face < mesh.faceSlotCount; face++) {
if (mesh.isFaceAlive(face)) yield face;
}
case ElementLevel.edge:
// An edge is not stored — see `EditMesh.edgeOf`. Sweeping the live
// faces' own half-edges and keeping only the canonical one of each
// twinned pair visits every edge exactly once, which is the same walk
// `selection_commands.dart`'s own `_everyEdge` does and for the same
// reason.
final seen = <int>{};
for (var face = 0; face < mesh.faceSlotCount; face++) {
if (!mesh.isFaceAlive(face)) continue;
final List<int> halves = <int>[];
mesh.forEachHalfEdge(face, halves.add);
for (final int half in halves) {
final int edge = mesh.edgeOf(half);
if (seen.add(edge)) yield edge;
}
}
}
}