private RoomData FindVisibility(RoomData rd, ProgressBar progressBar)
        {
            RoomData updatedData = new RoomData(rd);

            try
            {
                LogicalOrFilter      orFilter    = new LogicalOrFilter(categoryFilters);
                ReferenceIntersector intersector = null;
                intersector = new ReferenceIntersector(orFilter, FindReferenceTarget.Face, m_view);
                intersector.FindReferencesInRevitLinks = true;

                Face          face = rd.RoomFace;
                BoundingBoxUV bb   = face.GetBoundingBox();

                IList <UV>           uvPoints = new List <UV>();
                IList <ValueAtPoint> valList  = new List <ValueAtPoint>();

                List <PointData> pointDataList = new List <PointData>();
                double           interval      = analysisSettings.Interval;
                List <double>    uList         = new List <double>();
                List <double>    vList         = new List <double>();
                GetUVArray(bb, interval, out uList, out vList);


                progressBar.Value   = 0;
                progressBar.Minimum = 0;
                progressBar.Maximum = uList.Count * vList.Count;
                UpdateProgressDelegate updateProgressDelegate = new UpdateProgressDelegate(progressBar.SetValue);


                List <XYZ> exteriorPoints = new List <XYZ>();
                List <XYZ> interiorPoints = new List <XYZ>();
                bool       sorted         = SortViewPoints(rd.BoundarySegments, out exteriorPoints, out interiorPoints);

                int    visibleCount  = 0;
                double progressValue = 0;
                foreach (double u in uList) //start from in the middle of grid
                {
                    foreach (double v in vList)
                    {
                        if (AbortFlag.GetAbortFlag())
                        {
                            return(updatedData);
                        }
                        Dispatcher.CurrentDispatcher.Invoke(updateProgressDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { ProgressBar.ValueProperty, progressValue });

                        UV uvPoint = new UV(u, v);
                        if (face.IsInside(uvPoint))
                        {
                            XYZ    evalPoint  = face.Evaluate(uvPoint);
                            XYZ    xyzPoint   = new XYZ(evalPoint.X, evalPoint.Y, evalPoint.Z + offsetHeight); //4.2 inches above from the floor
                            double pointValue = 0;

                            List <XYZ> viewPoints = new List <XYZ>();
                            if (exteriorPoints.Count > 0)
                            {
                                exteriorPoints = exteriorPoints.OrderBy(o => o.DistanceTo(xyzPoint)).ToList();
                                viewPoints.AddRange(exteriorPoints);
                            }
                            if (interiorPoints.Count > 0)
                            {
                                interiorPoints = interiorPoints.OrderBy(o => o.DistanceTo(xyzPoint)).ToList();
                                viewPoints.AddRange(interiorPoints);
                            }

                            if (viewPoints.Count > 0)
                            {
                                bool visible = CheckVisibilityByMaterial(intersector, xyzPoint, viewPoints);
                                if (visible)
                                {
                                    pointValue = 1; visibleCount++;
                                }
                                else
                                {
                                    pointValue = 0;
                                }
                            }

                            PointData pData = new PointData(uvPoint, xyzPoint, pointValue);
                            pointDataList.Add(pData);

                            uvPoints.Add(pData.UVPoint);
                            valList.Add(pData.ValueAtPoint);
                        }
                        progressValue++;
                    }
                }

                rd.PointDataList = pointDataList;
                double ratio = (double)visibleCount / (double)uvPoints.Count;
                rd.VisiblityRatio = ratio;
                rd.AreaWithViews  = rd.RoomArea * ratio;
                rd.SetResultParameterValue(LEEDParameters.LEED_AreaWithViews.ToString(), rd.AreaWithViews);

                //visualize
                Transform transform = Transform.CreateTranslation(new XYZ(0, 0, offsetHeight));

                int index = m_sfm.AddSpatialFieldPrimitive(face, transform);
                FieldDomainPointsByUV domainPoints = new FieldDomainPointsByUV(uvPoints);
                FieldValues           values       = new FieldValues(valList);

                m_sfm.UpdateSpatialFieldPrimitive(index, domainPoints, values, resultIndex);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to find visibility.\n" + ex.Message, "Find Visibility", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(updatedData);
        }