示例#1
0
        public MockGridData(GridRange range)
        {
            ColumnHeader = new DefaultHeaderData(range.Columns, DefaultHeaderData.Mode.Column);

            RowHeader = new DefaultHeaderData(range.Rows, DefaultHeaderData.Mode.Row);

            Grid = new Grid <string>(range, (r, c) => Invariant($"{r}:{c}"));
        }
示例#2
0
        protected PointCloudVerticalHistogram GenerateHistogramDefault(DefaultHeaderData headerData, PointCloudBounds bounds)
        {
            var fileName = Path.GetFileName(FilePath);

            long currentOffset = headerData.DataOffset;
            long processed     = 0;

            var result = new PointCloudVerticalHistogram(bounds);

            using (var file = MemoryMappedFile.CreateFromFile(FilePath ?? throw new Exception("Input file not found."), FileMode.Open))
            {
                var batchIndex = 0;

                var maxArraySize    = TreeUtility.CalculateMaxArraySize(headerData.DataStride);
                var totalBatchCount = Mathf.CeilToInt((float)headerData.DataCount / maxArraySize);

                while (processed < headerData.DataCount)
                {
                    var batchCount = Math.Min(maxArraySize, headerData.DataCount - processed);
                    var batchSize  = batchCount * headerData.DataStride;

                    using (var view = file.CreateViewAccessor(currentOffset, batchSize, MemoryMappedFileAccess.Read))
                    {
                        unsafe
                        {
                            batchIndex++;
                            var progressBarTitle =
                                $"Calculating bounds ({fileName}, batch {batchIndex.ToString()}/{totalBatchCount.ToString()})";

                            var batchHistogram = PointImportJobs.GenerateHistogram(view, batchCount,
                                                                                   headerData.DataStride, headerData.Elements, bounds, progressBarTitle);

                            result.AddData(batchHistogram.regions);
                        }
                    }

                    processed     += batchCount;
                    currentOffset += batchSize;
                }
            }

            return(result);
        }
示例#3
0
        /// <summary>
        /// Default <see cref="ConvertPoints"/> implementation for formats using <see cref="DefaultHeaderData"/>.
        /// </summary>
        /// <param name="headerData">Data extracted from file header.</param>
        /// <param name="target">Target processor dispatcher to which transformed points should be passed.</param>
        /// <param name="transformationData">Data used for transformation of the points.</param>
        /// <returns>True if conversion finished successfully, false otherwise.</returns>
        protected bool ConvertPointsDefault(DefaultHeaderData headerData, NodeProcessorDispatcher target,
                                            TransformationData transformationData)
        {
            var fileName = Path.GetFileName(FilePath);

            long currentOffset = headerData.DataOffset;
            long processed     = 0;

            using (var file = MemoryMappedFile.CreateFromFile(FilePath, FileMode.Open))
            {
                var batchIndex = 0;

                var maxArraySize    = TreeUtility.CalculateMaxArraySize(headerData.DataStride);
                var totalBatchCount =
                    Mathf.CeilToInt((float)headerData.DataCount / maxArraySize);

                while (processed < headerData.DataCount)
                {
                    var batchCount = Math.Min(maxArraySize, headerData.DataCount - processed);
                    var batchSize  = batchCount * headerData.DataStride;

                    using (var view = file.CreateViewAccessor(currentOffset, batchSize, MemoryMappedFileAccess.Read))
                    {
                        batchIndex++;
                        var progressBarTitle =
                            $"Converting ({fileName}, batch {batchIndex.ToString()}/{totalBatchCount.ToString()})";
                        var targetBuffer = target.PublicMaxSizeBuffer;

                        PointImportJobs.ConvertData(view, targetBuffer, headerData.Elements, transformationData,
                                                    headerData.DataStride, batchCount, progressBarTitle);

                        target.AddChunk(targetBuffer, (int)batchCount);
                    }

                    processed     += batchCount;
                    currentOffset += batchSize;
                }
            }

            return(true);
        }
示例#4
0
        /// <summary>
        /// Default <see cref="CalculateBounds"/> implementation for formats using <see cref="DefaultHeaderData"/>.
        /// </summary>
        /// <param name="headerData">Data extracted from file header.</param>
        /// <returns>Bounds of points in given file.</returns>
        protected PointCloudBounds CalculateBoundsDefault(DefaultHeaderData headerData)
        {
            var fileName = Path.GetFileName(FilePath);

            long currentOffset = headerData.DataOffset;
            long processed     = 0;

            var result = PointCloudBounds.Empty;

            using (var file = MemoryMappedFile.CreateFromFile(FilePath, FileMode.Open))
            {
                var batchIndex = 0;

                var totalBatchCount =
                    Mathf.CeilToInt((float)headerData.DataCount / TreeUtility.MaxPointCountPerArray);

                while (processed < headerData.DataCount)
                {
                    var batchCount = Math.Min(TreeUtility.MaxPointCountPerArray, headerData.DataCount - processed);
                    var batchSize  = batchCount * headerData.DataStride;

                    using (var view = file.CreateViewAccessor(currentOffset, batchSize, MemoryMappedFileAccess.Read))
                    {
                        batchIndex++;
                        var progressBarTitle =
                            $"Calculating bounds ({fileName}, batch {batchIndex.ToString()}/{totalBatchCount.ToString()})";

                        var batchBounds = PointImportJobs.CalculateBounds(view, batchCount,
                                                                          headerData.DataStride, headerData.Elements, progressBarTitle);

                        result.Encapsulate(batchBounds);
                    }

                    processed     += batchCount;
                    currentOffset += batchSize;
                }
            }

            return(result);
        }
示例#5
0
        /// <summary>
        /// Reads header of associated file and stores results under <see cref="header"/>.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private DefaultHeaderData ReadHeader()
        {
            var result = new DefaultHeaderData();

            using (var file = MemoryMappedFile.CreateFromFile(FilePath, FileMode.Open))
            {
                string[] fields = null;
                string[] sizes  = null;
                string[] types  = null;

                using (var view = file.CreateViewStream(0, 4096, MemoryMappedFileAccess.Read))
                {
                    var buffer = new byte[4096];
                    int length = view.Read(buffer, 0, buffer.Length);
                    using (var stream = new MemoryStream(buffer, 0, length, false))
                    {
                        var byteLine = new byte[128];
                        while (true)
                        {
                            int byteCount = stream.Read(byteLine, 0, byteLine.Length);
                            int index     = -1;
                            for (int i = 0; i < byteCount; i++)
                            {
                                if (byteLine[i] == '\n' || byteLine[i] == '\r')
                                {
                                    index = i;
                                    break;
                                }
                            }

                            if (index == -1)
                            {
                                throw new Exception("Bad PCD file format");
                            }

                            byte next = byteLine[index + 1];
                            stream.Position -= byteLine.Length - (index + (next == '\r' || next == '\n' ? 2 : 1));

                            var line = Encoding.ASCII.GetString(byteLine, 0, index);
                            line = new Regex("#.*$").Replace(line, "").Trim();

                            if (line.Length == 0)
                            {
                                continue;
                            }

                            if (line.StartsWith("VERSION"))
                            {
                                var version = line.Split(new[] { ' ' }, 2);
                                if (version[1] != "0.7")
                                {
                                    throw new Exception($"Unsupported PCD version: {version[1]}");
                                }
                            }
                            else if (line.StartsWith("FIELDS"))
                            {
                                fields = line.Split(' ').Skip(1).ToArray();
                            }
                            else if (line.StartsWith("SIZE"))
                            {
                                sizes = line.Split(' ').Skip(1).ToArray();
                            }
                            else if (line.StartsWith("TYPE"))
                            {
                                types = line.Split(' ').Skip(1).ToArray();
                            }
                            else if (line.StartsWith("COUNT"))
                            {
                                var counts = line.Split(' ');
                                if (counts.Skip(1).Any(c => c != "1"))
                                {
                                    throw new Exception($"Unsupported PCD counts, expected '1' for all fields");
                                }
                            }
                            else if (line.StartsWith("HEIGHT"))
                            {
                                var height = line.Split(new[] { ' ' }, 2);
                                if (height[1] != "1")
                                {
                                    throw new Exception($"Unsupported PCD height: {height[1]}");
                                }
                            }
                            else if (line.StartsWith("POINTS"))
                            {
                                var points = line.Split(new[] { ' ' }, 2);
                                result.DataCount = long.Parse(points[1]);
                            }
                            else if (line.StartsWith("DATA"))
                            {
                                var data = line.Split(new[] { ' ' }, 2);
                                if (data[1] != "binary")
                                {
                                    throw new Exception($"Unsupported PCD data format: {data[1]}");
                                }

                                break;
                            }
                        }

                        result.DataOffset = stream.Position;
                    }
                }

                if (fields == null)
                {
                    throw new Exception("PCD file is missing FIELDS");
                }
                if (sizes == null)
                {
                    throw new Exception("PCD file is missing SIZE");
                }
                if (types == null)
                {
                    throw new Exception("PCD file is missing TYPE");
                }

                if (fields.Length != sizes.Length || fields.Length != types.Length)
                {
                    throw new Exception("PCD file has incorrect type specs");
                }

                int elementOffset = 0;

                for (int i = 0; i < fields.Length; i++)
                {
                    PointElementType?type = null;
                    PointElementName?name = null;

                    int elementSize = int.Parse(sizes[i]);

                    if (fields[i] == "x")
                    {
                        name = PointElementName.X;
                    }
                    if (fields[i] == "y")
                    {
                        name = PointElementName.Y;
                    }
                    if (fields[i] == "z")
                    {
                        name = PointElementName.Z;
                    }
                    if (fields[i] == "intensity")
                    {
                        name = PointElementName.I;
                    }
                    if (fields[i] == "scalar_intensity")
                    {
                        name = PointElementName.I;
                    }

                    if (types[i] == "U" && elementSize == 1)
                    {
                        type = PointElementType.Byte;
                    }
                    if (types[i] == "F" && elementSize == 4)
                    {
                        type = PointElementType.Float;
                    }
                    if (types[i] == "D" && elementSize == 8)
                    {
                        type = PointElementType.Double;
                    }

                    if (type.HasValue && name.HasValue)
                    {
                        result.Elements.Add(new PointElement()
                        {
                            Type = type.Value, Name = name.Value, Offset = elementOffset
                        });
                    }

                    elementOffset += elementSize;
                }

                result.DataStride = elementOffset;
            }

            return(result);
        }
示例#6
0
 public PcdPointProcessor(string filePath) : base(filePath)
 {
     header = ReadHeader();
 }
        private DefaultHeaderData ReadHeader()
        {
            var result = new DefaultHeaderData();

            using (var file = MemoryMappedFile.CreateFromFile(FilePath, FileMode.Open))
            {
                int elementOffset = 0;

                using (var view = file.CreateViewStream(0, 4096, MemoryMappedFileAccess.Read))
                {
                    var buffer = new byte[4096];
                    int length = view.Read(buffer, 0, buffer.Length);
                    using (var stream = new MemoryStream(buffer, 0, length, false))
                    {
                        var  byteLine = new byte[128];
                        bool first    = true;

                        while (true)
                        {
                            int byteCount = stream.Read(byteLine, 0, byteLine.Length);
                            int index     = -1;
                            for (int i = 0; i < byteCount; i++)
                            {
                                if (byteLine[i] == '\n' || byteLine[i] == '\r')
                                {
                                    index = i;
                                    break;
                                }
                            }
                            if (index == -1)
                            {
                                throw new Exception("Bad PLY file");
                            }
                            var  line = Encoding.ASCII.GetString(byteLine, 0, index);
                            byte next = byteLine[index + 1];
                            stream.Position -= byteLine.Length - (index + (next == '\r' || next == '\n' ? 2 : 1));

                            if (first && line != "ply")
                            {
                                throw new Exception("Bad PLY file format");
                            }
                            first = false;

                            if (line.StartsWith("format"))
                            {
                                var format = line.Split(new[] { ' ' });
                                if (format[1] != "binary_little_endian" || format[2] != "1.0")
                                {
                                    throw new Exception($"Unsupported PLY format: {line}");
                                }
                            }
                            else if (line.StartsWith("property"))
                            {
                                var props = line.Split(new[] { ' ' }, 3);
                                if (props[1] != "list")
                                {
                                    PointElementType?type = null;
                                    PointElementName?name = null;

                                    if (props[1] == "uint8")
                                    {
                                        type = PointElementType.Byte;
                                    }
                                    if (props[1] == "float32")
                                    {
                                        type = PointElementType.Float;
                                    }
                                    if (props[1] == "float64")
                                    {
                                        type = PointElementType.Double;
                                    }

                                    if (props[1] == "uchar")
                                    {
                                        type = PointElementType.Byte;
                                    }
                                    if (props[1] == "float")
                                    {
                                        type = PointElementType.Float;
                                    }
                                    if (props[1] == "double")
                                    {
                                        type = PointElementType.Double;
                                    }

                                    if (props[2] == "x")
                                    {
                                        name = PointElementName.X;
                                    }
                                    if (props[2] == "y")
                                    {
                                        name = PointElementName.Y;
                                    }
                                    if (props[2] == "z")
                                    {
                                        name = PointElementName.Z;
                                    }
                                    if (props[2] == "red")
                                    {
                                        name = PointElementName.R;
                                    }
                                    if (props[2] == "green")
                                    {
                                        name = PointElementName.G;
                                    }
                                    if (props[2] == "blue")
                                    {
                                        name = PointElementName.B;
                                    }
                                    if (props[2] == "intensity")
                                    {
                                        name = PointElementName.I;
                                    }
                                    if (props[2] == "scalar_intensity")
                                    {
                                        name = PointElementName.I;
                                    }

                                    if (!type.HasValue)
                                    {
                                        throw new Exception($"PLY file has unsupported property type {props[1]}");
                                    }

                                    if (name.HasValue)
                                    {
                                        result.Elements.Add(new PointElement()
                                        {
                                            Type = type.Value, Name = name.Value, Offset = elementOffset
                                        });
                                    }

                                    elementOffset += PointElement.GetSize(type.Value);
                                }
                            }
                            else if (line.StartsWith("element vertex"))
                            {
                                var vertex = line.Split(new[] { ' ' }, 3);
                                result.DataCount = long.Parse(vertex[2]);
                            }
                            else if (line.StartsWith("end_header"))
                            {
                                break;
                            }
                        }
                        result.DataOffset = stream.Position;
                    }
                }

                result.DataStride = elementOffset;
            }

            return(result);
        }