// assumes PathT is contains set of triangles
        // that are fully connected, ie a flood-fill cannot escape!
        void find_interior_from_tris()
        {
            var pathNbrs = new MeshFaceSelection(Mesh);

            pathNbrs.Select(PathT);
            pathNbrs.ExpandToOneRingNeighbours();
            pathNbrs.Deselect(PathT);

            var connected = new MeshConnectedComponents(Mesh);

            connected.FilterSet = pathNbrs;
            connected.FindConnectedT();
            int N = connected.Count;

            if (N < 2)
            {
                throw new Exception("MeshFacesFromLoop.find_interior: only found one connected component!");
            }

            // only consider 2 largest. somehow we are sometimes getting additional
            // "outside" components, and if we do growing from there, it covers whole mesh??
            connected.SortByCount(false);
            N = 2;

            var selections = new MeshFaceSelection[N];

            bool[] done = new bool[N];
            for (int i = 0; i < N; ++i)
            {
                selections[i] = new MeshFaceSelection(Mesh);
                selections[i].Select(connected.Components[i].Indices);
                done[i] = false;
            }

            var border_tris          = new HashSet <int>(PathT);
            Func <int, bool> borderF = (tid) => { return(border_tris.Contains(tid) == false); };

            // 'largest' flood fill is expensive...if we had a sense of tooth size we could reduce cost?
            for (int i = 0; i < N; ++i)
            {
                selections[i].FloodFill(connected.Components[i].Indices, borderF);
            }
            Array.Sort(selections, (a, b) => { return(a.Count.CompareTo(b.Count)); });
            InteriorT = new List <int>(selections[0]);
        }