/// <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); }
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)); }
public static void BuildKdtreeN(OpcPaths opcPaths, PositionsType posType, bool overrideExisting = false, float maxTriangleSize = float.PositiveInfinity) { var hierarchyInfo = PatchHierarchyInfo.BuildOrLoadCache(opcPaths); var patchInfo = hierarchyInfo.PatchTree.Info; opcPaths.SetRootPatchName(hierarchyInfo.RootPatch); if (posType == PositionsType.V2dPositions && !patchInfo.Has2dData) { Report.Warn("KdTreeUtils: 2d KdTreeN needs 2d data to be able to get built."); return; } if (overrideExisting || !StorageConfig.FileExists(opcPaths.GetKdTreeNPath(posType))) { BuildKdTreeForPatch(opcPaths.RootPatchName, -1, patchInfo, opcPaths, posType, true, true, maxTriangleSize); } }