This class is used to calculate and store points for a given cell.
        /// <summary>
        /// Sets up a point cloud from an XML root element.
        /// </summary>
        /// <param name="rootElement">The root element.</param>
        protected void SetupFrom(XElement rootElement)
        {
            // Read scale, if it exists.
            foreach (XElement scaleElement in rootElement.Elements("Scale"))
            {
                double scale = XmlUtils.GetDouble(scaleElement);
                if (scale < 0.0)
                {
                    TaskDialog.Show("Scale error", "The value of scale is not a valid number greater than zero.");
                }
                else
                {
                    m_scale = scale;
                }
            }

            // Read cells.
            m_storedCells = new List <PointCloudCellStorage>();
            foreach (XElement cellElement in rootElement.Elements("Cell"))
            {
                PointCloudCellStorage cell = new PointCloudCellStorage(cellElement);
                m_storedCells.Add(cell);
                AddCellToOutline(cell);
                cell.GeneratePoints();
            }
        }
        /// <summary>
        /// Adds a new cell to the point cloud.
        /// </summary>
        /// <param name="lowerLeft">The lower left point.</param>
        /// <param name="upperRight">The upper right point.</param>
        /// <param name="color">The color.</param>
        /// <param name="randomize">True to randomize point number and location, false for a regular arrangement of points.</param>
        protected void AddCell(XYZ lowerLeft, XYZ upperRight, int color, bool randomize)
        {
            PointCloudCellStorage storage = new PointCloudCellStorage(lowerLeft, upperRight, color, randomize);

            storage.GeneratePoints();
            m_storedCells.Add(storage);

            AddCellToOutline(storage);
        }
        /// <summary>
        /// Adds a cell to the stored outline of the point cloud.  If the cell boundaries extend beyond the current outline, the outline
        /// is adjusted.
        /// </summary>
        /// <param name="storage"></param>
        private void AddCellToOutline(PointCloudCellStorage storage)
        {
            XYZ lowerLeft  = storage.LowerLeft;
            XYZ upperRight = storage.UpperRight;

            if (m_outline == null)
            {
                m_outline = new Outline(lowerLeft, upperRight);
            }
            else
            {
                XYZ minimumPoint = m_outline.MinimumPoint;

                m_outline.MinimumPoint = new XYZ(Math.Min(minimumPoint.X, lowerLeft.X),
                                                 Math.Min(minimumPoint.Y, lowerLeft.Y),
                                                 Math.Min(minimumPoint.Z, lowerLeft.Z));

                XYZ maximumPoint = m_outline.MaximumPoint;
                m_outline.MaximumPoint = new XYZ(Math.Max(maximumPoint.X, upperRight.X),
                                                 Math.Max(maximumPoint.Y, upperRight.Y),
                                                 Math.Max(maximumPoint.Z, upperRight.Z));
            }
        }
        /// <summary>
        /// The internal implementation for point cloud read requests from Revit.
        /// </summary>
        /// <remarks>Both IPointCloudAccess.ReadPoints() and IPointSetIterator.ReadPoints() are served by this method.</remarks>
        /// <param name="rFilter">The point cloud filter.</param>
        /// <param name="buffer">The point cloud buffer.</param>
        /// <param name="nBufferSize">The maximum number of points in the buffer.</param>
        /// <param name="startIndex">The start index for points.  Pass 0 if called from IPointCloudAccess.ReadPoints() or if this is the first
        /// call to IPointSetIterator.ReadPoints().  Pass the previous cumulative number of read points for second and successive calls to
        /// IPointSetIterator.ReadPoints().</param>
        /// <returns>The number of points read.</returns>
        protected unsafe int ReadSomePoints(PointCloudFilter rFilter, IntPtr buffer, int nBufferSize, int startIndex)
        {
            // Get the pointer to the buffer.
            CloudPoint *cpBuffer     = (CloudPoint *)buffer.ToPointer();
            int         pointIndex   = 0;
            int         currentIndex = startIndex;
            int         totalPoints  = 0;
            int         startCell    = 0;
            Outline     fullOutline  = GetOutline();

            // Test each cell until the first cell with needed points is found.
            for (int i = 0; i < m_storedCells.Count; i++)
            {
                PointCloudCellStorage cell = m_storedCells[i];

                // Pass the cell outline to the filter.
                int filterResult = rFilter.TestCell(cell.LowerLeft, cell.UpperRight);

                // Filter result == -1 means the cell is completely out of scope for the filter.
                if (filterResult == -1)
                {
                    continue;
                }

                // The cell is at least partially in scope.  If the cell has more points than
                // the number read in previous calls, we should start with this cell.
                // If it has less points than the number read, the cell was already processed and we
                // should move to the next one.
                totalPoints += cell.NumberOfPoints;
                if (currentIndex < totalPoints)
                {
                    startCell    = i;
                    currentIndex = Math.Max(0, startIndex - totalPoints);
                    break;
                }
            }

            // Start with the current candidate cell and read cells until there are no more to read.
            for (int i = startCell; i < m_storedCells.Count; i++)
            {
                // Test the cell against the filter.
                PointCloudCellStorage cell = m_storedCells[i];
                int filterResult           = rFilter.TestCell(cell.LowerLeft, cell.UpperRight);

                // Filter result == -1 means the cell is entirely out of scope, skip it.
                if (filterResult == -1)
                {
                    continue;
                }

                // Filter result == 0 means some part of the cell is in scope.
                // Prepare for cell is called to process the cell's points.
                if (filterResult == 0)
                {
                    rFilter.PrepareForCell(fullOutline.MinimumPoint, fullOutline.MaximumPoint, cell.NumberOfPoints);
                }

                // Loop through all points in the cell.
                for (int j = currentIndex; j < cell.NumberOfPoints; j++)
                {
                    // If we need to test the point for acceptance, use the filter to do so.
                    // If filter result == 1 the entire cell was in scope, no need to test.
                    if (filterResult == 0)
                    {
                        if (!rFilter.TestPoint(cell.PointsBuffer[j]))
                        {
                            continue;
                        }
                    }

                    // Add the point to the buffer and increment the counter
                    *(cpBuffer + pointIndex) = cell.PointsBuffer[j];
                    pointIndex++;

                    // Stop when the max number of points is reached
                    if (pointIndex >= nBufferSize)
                    {
                        break;
                    }
                }

                // Stop when the max number of points is reached
                if (pointIndex >= nBufferSize)
                {
                    break;
                }
                currentIndex = 0;
            }

            return(pointIndex);
        }
Beispiel #5
0
        /// <summary>
        /// Adds a new cell to the point cloud.
        /// </summary>
        /// <param name="lowerLeft">The lower left point.</param>
        /// <param name="upperRight">The upper right point.</param>
        /// <param name="color">The color.</param>
        /// <param name="randomize">True to randomize point number and location, false for a regular arrangement of points.</param>
        protected void AddCell(XYZ lowerLeft, XYZ upperRight, int color, bool randomize)
        {
            PointCloudCellStorage storage = new PointCloudCellStorage(lowerLeft, upperRight, color, randomize);
            storage.GeneratePoints();
            m_storedCells.Add(storage);

            AddCellToOutline(storage);
        }
Beispiel #6
0
        /// <summary>
        /// Adds a cell to the stored outline of the point cloud.  If the cell boundaries extend beyond the current outline, the outline 
        /// is adjusted.
        /// </summary>
        /// <param name="storage"></param>
        private void AddCellToOutline(PointCloudCellStorage storage)
        {
            XYZ lowerLeft = storage.LowerLeft;
            XYZ upperRight = storage.UpperRight;
            if (m_outline == null)
                m_outline = new Outline(lowerLeft, upperRight);
            else
            {
                XYZ minimumPoint = m_outline.MinimumPoint;

                m_outline.MinimumPoint = new XYZ(Math.Min(minimumPoint.X, lowerLeft.X),
                                                Math.Min(minimumPoint.Y, lowerLeft.Y),
                                                Math.Min(minimumPoint.Z, lowerLeft.Z));

                XYZ maximumPoint = m_outline.MaximumPoint;
                m_outline.MaximumPoint = new XYZ(Math.Max(maximumPoint.X, upperRight.X),
                                                Math.Max(maximumPoint.Y, upperRight.Y),
                                                Math.Max(maximumPoint.Z, upperRight.Z));
            }
        }
Beispiel #7
0
        /// <summary>
        /// Sets up a point cloud from an XML root element.
        /// </summary>
        /// <param name="rootElement">The root element.</param>
        protected void SetupFrom(XElement rootElement)
        {
            // Read scale, if it exists.
            foreach (XElement scaleElement in rootElement.Elements("Scale"))
            {
                double scale = XmlUtils.GetDouble(scaleElement);
                if (scale < 0.0)
                {
                    TaskDialog.Show("Scale error", "The value of scale is not a valid number greater than zero.");
                }
                else
                {
                    m_scale = scale;
                }
            }

            // Read cells.
            m_storedCells = new List<PointCloudCellStorage>();
            foreach (XElement cellElement in rootElement.Elements("Cell"))
            {
                PointCloudCellStorage cell = new PointCloudCellStorage(cellElement);
                m_storedCells.Add(cell);
                AddCellToOutline(cell);
                cell.GeneratePoints();
            }
        }