Пример #1
0
        /// <summary>
        /// Starts tree building process with given settings.
        /// </summary>
        public static void BuildNodeTree(TreeImportSettings settings)
        {
            var processors = new List <PointProcessor>();

            foreach (var inputFile in settings.inputFiles)
            {
                var processor = CreateProcessor(inputFile);
                if (processor != null)
                {
                    processors.Add(processor);
                }
            }

            if (processors.Count == 0)
            {
                Debug.LogError("All of given point cloud files are invalid or unsupported.");
                return;
            }

            var bounds = CalculateBounds(processors);

            var transformationData = new TransformationData(bounds, settings);

            var unityBounds = bounds.GetUnityBounds(settings);
            var transform   = transformationData.TransformationMatrix;

            unityBounds.center  = transform.MultiplyPoint3x4(unityBounds.center);
            unityBounds.extents = transform.MultiplyVector(unityBounds.extents);

            NodeProcessorDispatcher dispatcher;

            try
            {
                EditorUtility.DisplayProgressBar("Creating dispatcher", "Preparing target directory...", 0f);
                dispatcher = new NodeProcessorDispatcher(settings.outputPath, settings);
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }

            foreach (var processor in processors)
            {
                if (!processor.ConvertPoints(dispatcher, transformationData))
                {
                    Debug.Log("Import cancelled.");
                    return;
                }
            }

            if (dispatcher.ProcessPoints(unityBounds))
            {
                Debug.Log("Octree build finished successfully.");
            }
            else
            {
                Debug.Log("Octree build failed.");
            }
        }
Пример #2
0
        protected TreeNodeProcessor(string dataPath, TreeImportSettings settings)
        {
            Settings      = settings;
            this.dataPath = dataPath;

            tmpFolderPath = Path.Combine(dataPath, "tmp");

            stride           = UnsafeUtility.SizeOf <PointCloudPoint>();
            ChildNodeRecords = new List <NodeRecord>();
            inputBuffer      = new PointCloudPoint[settings.chunkSize];
        }
Пример #3
0
        public OctreeNodeProcessor(string dataPath, TreeImportSettings settings, TreeImportData importData) : base(dataPath, settings, importData)
        {
            ChildBuffers = new PointCloudPoint[ChildCount][];
            for (var i = 0; i < ChildCount; ++i)
            {
                ChildBuffers[i] = new PointCloudPoint[settings.chunkSize];
            }

            ChildCounts     = new int[ChildCount];
            ChildFileCounts = new int[ChildCount];
        }
Пример #4
0
        public static float GetStepAtTreeLevel(Bounds rootBounds, TreeImportSettings settings, int level)
        {
            var step = Mathf.Min(rootBounds.size.x, rootBounds.size.z) / settings.rootNodeSubdivision;

            for (var i = 0; i < level - 1; ++i)
            {
                step *= 0.5f;
            }

            return(step);
        }
Пример #5
0
        public MeshBuilder(string dataPath, TreeImportSettings settings, TreeImportData importData)
        {
            this.dataPath   = dataPath;
            this.importData = importData;
            this.settings   = settings;
            tmpDataPath     = Path.Combine(dataPath, "tmp");

            voxelData = new MeshGenerationData();

            for (var i = 1; i < LutOffsets.Length; ++i)
            {
                neighborData.Add(LutOffsets[i], new MeshGenerationData());
            }
        }
Пример #6
0
        private static Matrix4x4 GetTransformationMatrix(TreeImportSettings settings)
        {
            switch (settings.axes)
            {
            case PointCloudImportAxes.X_Right_Y_Up_Z_Forward:
                return(Matrix4x4.identity);

            case PointCloudImportAxes.X_Right_Z_Up_Y_Forward:
                return(new Matrix4x4(new Vector4(1, 0, 0), new Vector4(0, 0, 1), new Vector4(0, 1, 0),
                                     Vector4.zero));

            default:
                Debug.Assert(false);
                return(Matrix4x4.identity);
            }
        }
        public Bounds AlignBounds(TreeImportSettings settings, Bounds bounds)
        {
            var origin        = bounds.min.y;
            var step          = EditorTreeUtility.GetStepAtTreeLevel(bounds, settings, settings.meshDetailLevel);
            var alignedBounds = TreeUtility.GetRoundedAlignedBounds(bounds, bounds.min, step);
            var alignedOrigin = alignedBounds.min.y;
            var peak          = FindPeak();

            var targetCenter = origin + (bounds.size.y / Resolution) * (peak + 0.5f);

            var tmpDst       = float.MaxValue;
            var actualCenter = 0f;

            for (var i = 0; i < (int)(alignedBounds.size.y / step); ++i)
            {
                var pos = alignedOrigin + (i + 0.5f) * step;
                var dst = Mathf.Abs(targetCenter - pos);
                if (dst < tmpDst)
                {
                    actualCenter = pos;
                    tmpDst       = dst;
                }
                else
                {
                    Debug.Log($"Break at i ({actualCenter:F4})");
                    break;
                }
            }


            var diff = targetCenter - actualCenter;

            if (diff > 0)
            {
                diff -= step;
            }

            var height = bounds.max.y - bounds.min.y;

            var alignedMin = alignedBounds.min;

            alignedMin.y     += diff;
            alignedBounds.min = alignedMin;
            Debug.Log($"origin: {origin:F4}, AO: {alignedBounds.min.y:F4}, height: {height:F4}, step: {step:F4}, TC: {targetCenter:F4}, AC: {actualCenter:F4}");

            return(alignedBounds);
        }
Пример #8
0
        public NodeProcessorDispatcher(string outputPath, TreeImportSettings settings)
        {
            this.outputPath = outputPath;
            Settings        = settings;

            if (Directory.Exists(outputPath))
            {
                Directory.Delete(outputPath, true);
            }

            Directory.CreateDirectory(outputPath);

            outputTmpPath = Path.Combine(outputPath, "tmp");
            Directory.CreateDirectory(outputTmpPath);

            points = new PointCloudPoint[settings.chunkSize];

            PublicMaxSizeBuffer = new PointCloudPoint[TreeUtility.MaxPointCountPerArray];
        }
Пример #9
0
        public QuadtreeNodeProcessor(string dataPath, TreeImportSettings settings) : base(dataPath, settings)
        {
            ChildBuffers = new PointCloudPoint[ChildCount][];
            for (var i = 0; i < ChildCount; ++i)
            {
                ChildBuffers[i] = new PointCloudPoint[settings.chunkSize];
            }

            ChildCounts     = new int[ChildCount];
            ChildFileCounts = new int[ChildCount];

            if (settings.sampling == TreeImportSettings.SamplingMethod.CellCenter)
            {
                PointCollection = new CellCenterPointCollection();
            }
            else
            {
                PointCollection = new PoissonDiskPointCollection();
            }

            PointCollection.Initialize(settings);
        }
Пример #10
0
        public NodeProcessorDispatcher(string outputPath, TreeImportSettings settings)
        {
            this.outputPath = outputPath;
            Settings        = settings;

            var pcExtensions = new List <string> {
                TreeUtility.NodeFileExtension, TreeUtility.IndexFileExtension, TreeUtility.MeshFileExtension
            };

            if (Directory.Exists(outputPath))
            {
                var matchingFiles = Directory
                                    .EnumerateFiles(outputPath, "*.*", SearchOption.TopDirectoryOnly)
                                    .Where(x => Path.GetExtension(x) != null &&
                                           pcExtensions.Contains(Path.GetExtension(x).ToLowerInvariant()))
                                    .ToList();

                foreach (var file in matchingFiles)
                {
                    File.Delete(file);
                }
            }

            Directory.CreateDirectory(outputPath);

            outputTmpPath = Path.Combine(outputPath, "tmp");
            if (Directory.Exists(outputTmpPath))
            {
                Directory.Delete(outputTmpPath, true);
            }

            Directory.CreateDirectory(outputTmpPath);

            points = new PointCloudPoint[settings.chunkSize];

            var maxArraySize = TreeUtility.CalculateMaxArraySize(UnsafeUtility.SizeOf <PointCloudPoint>());

            PublicMaxSizeBuffer = new PointCloudPoint[maxArraySize];
        }
Пример #11
0
        /// <summary>
        /// Starts tree building process with given settings.
        /// </summary>
        public static bool BuildNodeTree(TreeImportSettings settings)
        {
            var processors = new List <PointProcessor>();

            foreach (var inputFile in settings.inputFiles)
            {
                var processor = CreateProcessor(Utility.GetFullPath(inputFile));
                if (processor != null)
                {
                    processors.Add(processor);
                }
            }

            if (processors.Count == 0)
            {
                Debug.LogError("All of given point cloud files are invalid or unsupported.");
                return(false);
            }

            var bounds = CalculateBounds(processors);

            var transformationData = new TransformationData(bounds, settings);

            var unityBounds = bounds.GetUnityBounds(settings);
            var transform   = transformationData.TransformationMatrix;

            unityBounds.center  = transform.MultiplyPoint3x4(unityBounds.center);
            unityBounds.extents = transform.MultiplyVector(unityBounds.extents);

            TreeImportData importData = null;

            if (settings.generateMesh && settings.roadOnlyMesh)
            {
                var histogram = GenerateHistogram(processors, bounds);
                importData = new TreeImportData(unityBounds, histogram);
            }
            else
            {
                importData = new TreeImportData(unityBounds);
            }

            NodeProcessorDispatcher dispatcher;
            var fullOutputPath = Utility.GetFullPath(settings.outputPath);

            try
            {
                EditorUtility.DisplayProgressBar("Creating dispatcher", "Preparing target directory...", 0f);
                dispatcher = new NodeProcessorDispatcher(fullOutputPath, settings);
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }

            foreach (var processor in processors)
            {
                if (!processor.ConvertPoints(dispatcher, transformationData))
                {
                    Debug.Log("Import cancelled.");
                    return(false);
                }
            }

            if (dispatcher.ProcessPoints(importData))
            {
                dispatcher.GetPointCountResults(out var total, out var used, out var discarded);
                Debug.Log($"Octree build finished successfully.\n" +
                          $"Used points: {used}/{total} ({discarded} discarded on low tree levels)");
                return(true);
            }
            else
            {
                Debug.Log("Octree build failed.");
                return(false);
            }
        }
Пример #12
0
 ///<inheritdoc/>
 public void Initialize(TreeImportSettings treeSettings, TreeImportData importData)
 {
     rootBounds   = importData.Bounds;
     settings     = treeSettings;
     cellsPerAxis = new int[3];
 }
 ///<inheritdoc/>
 public void Initialize(TreeImportSettings treeSettings)
 {
     settings     = treeSettings;
     cellsPerAxis = new int[3];
 }