/// <summary>
 /// For row r, find interval that nonzeros lie in
 /// </summary>
 public Interval1i NonZerosRange(int r)
 {
     nonzero[] Row = Rows[r];
     if (Row.Length == 0)
     {
         return(Interval1i.Empty);
     }
     if (Sorted == false)
     {
         Interval1i range = Interval1i.Empty;
         for (int i = 0; i < Row.Length; ++i)
         {
             range.Contain(Row[i].j);
         }
         return(range);
     }
     else
     {
         return(new Interval1i(Row[0].j, Row[Row.Length - 1].j));
     }
 }
Пример #2
0
        public void FindConnectedT()
        {
            Components = new List <Component>();

            int NT = Mesh.MaxTriangleID;

            // [TODO] could use Euler formula to determine if mesh is closed genus-0...

            Func <int, bool> filter_func = (i) => { return(Mesh.IsTriangle(i)); };

            if (FilterF != null)
            {
                filter_func = (i) => { return(Mesh.IsTriangle(i) && FilterF(i)); }
            }
            ;



            // initial active set contains all valid triangles
            byte[]     active      = new byte[Mesh.MaxTriangleID];
            Interval1i activeRange = Interval1i.Empty;

            if (FilterSet != null)
            {
                for (int i = 0; i < NT; ++i)
                {
                    active[i] = 255;
                }
                foreach (int tid in FilterSet)
                {
                    bool bValid = filter_func(tid);
                    if (bValid)
                    {
                        active[tid] = 0;
                        activeRange.Contain(tid);
                    }
                }
            }
            else
            {
                for (int i = 0; i < NT; ++i)
                {
                    bool bValid = filter_func(i);
                    if (bValid)
                    {
                        active[i] = 0;
                        activeRange.Contain(i);
                    }
                    else
                    {
                        active[i] = 255;
                    }
                }
            }

            // temporary buffers
            List <int> queue    = new List <int>(NT / 10);
            List <int> cur_comp = new List <int>(NT / 10);

            // keep finding valid seed triangles and growing connected components
            // until we are done
            IEnumerable <int> range = (FilterSet != null) ? FilterSet : activeRange;

            foreach (int i in range)
            {
                //for ( int i = 0; i < NT; ++i ) {
                if (active[i] == 255)
                {
                    continue;
                }

                int seed_t = i;
                if (SeedFilterF != null && SeedFilterF(seed_t) == false)
                {
                    continue;
                }

                queue.Add(seed_t);
                active[seed_t] = 1;      // in queue

                while (queue.Count > 0)
                {
                    int cur_t = queue[queue.Count - 1];
                    queue.RemoveAt(queue.Count - 1);

                    active[cur_t] = 2;   // tri has been processed
                    cur_comp.Add(cur_t);

                    Index3i nbrs = Mesh.GetTriNeighbourTris(cur_t);
                    for (int j = 0; j < 3; ++j)
                    {
                        int nbr_t = nbrs[j];
                        if (nbr_t != DMesh3.InvalidID && active[nbr_t] == 0)
                        {
                            queue.Add(nbr_t);
                            active[nbr_t] = 1;           // in queue
                        }
                    }
                }


                Component comp = new Component()
                {
                    Indices = cur_comp.ToArray()
                };
                Components.Add(comp);

                // remove tris in this component from active set
                for (int j = 0; j < comp.Indices.Length; ++j)
                {
                    active[comp.Indices[j]] = 255;
                }

                cur_comp.Clear();
                queue.Clear();
            }
        }