Exemplo n.º 1
0
        /// <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);
        }
 public IntPtrCloudPointBuffer(IntPtr buffer, int buffer_size)
 {
     m_buffer      = (CloudPoint *)buffer;
     m_buffer_size = buffer_size;
 }