/// <summary> /// Get a face loop or ring from a set of winged edges. /// </summary> /// <param name="wings"></param> /// <param name="face"></param> /// <param name="ring"></param> /// <returns></returns> static HashSet <Face> GetFaceLoop(List <WingedEdge> wings, Face face, bool ring) { HashSet <Face> loop = new HashSet <Face>(); if (face == null) { return(loop); } WingedEdge start = wings.FirstOrDefault(x => x.face == face); if (start == null) { return(loop); } if (ring) { start = start.next ?? start.previous; } for (int i = 0; i < 2; i++) { WingedEdge cur = start; if (i == 1) { if (start.opposite != null && start.opposite.face != null) { cur = start.opposite; } else { break; } } do { if (!loop.Add(cur.face)) { break; } if (cur.Count() != 4) { break; } // count == 4 assures us next.next is valid, but opposite can still be null cur = cur.next.next.opposite; }while (cur != null && cur.face != null); } return(loop); }