Ejemplo n.º 1
0
        /// <param name="level">Selects hierarchy Level the kdtree is built of (-1 shouldn't be used, use BuildKdtreeN instead).</param>
        /// <param name="progressObserver">Reports progress in increments which sum up to 1.</param>
        public static void BuildKdTreeForLevel(
            OpcPaths opcPaths, int level, PositionsType posType,
            bool lazy = true, bool overrideExisting = false, IObserver <float> progressObserver = null,
            CancellationToken cancelToken = default(CancellationToken), PatchHierarchyInfo hierarchyInfo = null,
            float maxTriangleSize         = float.PositiveInfinity)
        {
            #region Preconditions

            if (hierarchyInfo == null)
            {
                hierarchyInfo = PatchHierarchyInfo.BuildOrLoadCache(opcPaths);
            }

            if (posType == PositionsType.V2dPositions && !hierarchyInfo.PatchTree.Info.Has2dData)
            {
                Report.Warn("KdTreeUtils: 2d KdTree needs 2d data to be able to get built.");
                progressObserver.OnNext(1f);
                progressObserver.OnCompleted();
                return;
            }

            opcPaths.SetRootPatchName(hierarchyInfo.RootPatch);

            var kdTreeSetPath = opcPaths.GetAggKdTreePath(level, posType);
            if (!overrideExisting && StorageConfig.FileExists(kdTreeSetPath))
            {
                progressObserver.OnNext(1f);
                progressObserver.OnCompleted();
                return;
            }

            #endregion

            hierarchyInfo.PatchTree.CreatePatchPaths(opcPaths.PatchesSubDir);

            // Get geometry patchinformations for certain level with a valid boundingbox
            var patchTrees = hierarchyInfo.RetrievePatchTreesOfLevel(level)
                             .Where(x => !x.Info.GlobalBoundingBox.IsInvalid);

            IIntersectableObjectSet kdTree;
            var buildFlags =
                KdIntersectionTree.BuildFlags.Hierarchical |
                KdIntersectionTree.BuildFlags.EmptySpaceOptimization;

            // Decide lazy or eager
            if (lazy)
            {
                kdTree      = BuildLazyKdTreeSet(patchTrees, opcPaths, level, posType, overrideExisting, progressObserver, cancelToken, maxTriangleSize);
                buildFlags |= KdIntersectionTree.BuildFlags.OptimalRaytracing;
            }
            else
            {
                kdTree      = BuildConcreteKdTreeSet(patchTrees, opcPaths, level, posType, overrideExisting, progressObserver, cancelToken, maxTriangleSize);
                buildFlags |= KdIntersectionTree.BuildFlags.MediumIntersection;
            }

            // Save Kd-Tree
            var aggrTree = new KdIntersectionTree(kdTree, buildFlags);
            aggrTree.Save(kdTreeSetPath, waitMode: WaitMode.WaitUntilFinished);
        }
Ejemplo n.º 2
0
        public static bool HasKdTreeForLevel(OpcPaths opcPaths, int level, PositionsType posType, PatchHierarchyInfo hierarchyInfo = null)
        {
            if (hierarchyInfo == null)
            {
                hierarchyInfo = PatchHierarchyInfo.BuildOrLoadCache(opcPaths);
            }

            opcPaths.SetRootPatchName(hierarchyInfo.RootPatch);
            var kdTreeSetPath = opcPaths.GetAggKdTreePath(level, posType);

            return(StorageConfig.FileExists(kdTreeSetPath));
        }