private static LazyKdTreeSet BuildLazyKdTreeSet(IEnumerable <PatchTree> patches, OpcPaths opcPaths, int level, PositionsType posType, bool overrideExisting, IObserver <float> progressObserver, CancellationToken cancelToken = default(CancellationToken), float maxTriangleSize = float.PositiveInfinity) { var placeHolders = new List <LazyKdTreeSet.KdTreePlaceHolder>(); var progressInc = 1f / patches.Count(); foreach (var p in patches) { cancelToken.ThrowIfCancellationRequested(); var kdtreePath = opcPaths.GetKdTreePath(p.Id, level, posType); if (overrideExisting || !StorageConfig.FileExists(kdtreePath)) { BuildKdTreeForPatch(p.Id, level, p.Info, opcPaths, posType, saveTriangles: false, saveKdTree: true, maxTriangleSize: maxTriangleSize); } // Create place holders placeHolders.Add(new LazyKdTreeSet.KdTreePlaceHolder() { BoundingBox = p.Info.GetGlobalBoundingBox(posType), Affine = p.Info.GetLocal2Global(posType), Path = opcPaths.GetKdTreePath(p.Id, level, posType), ObjectSetPath = p.GetPositionPath(posType) }); if (progressObserver != null) { progressObserver.OnNext(progressInc); } } if (progressObserver != null) { progressObserver.OnCompleted(); } return(new LazyKdTreeSet(placeHolders)); }
/// <summary> /// Builds kdtree for specific patch. /// Kdtree is built according to specified positions type and hierarchy level. /// </summary> private static KdIntersectionTree BuildKdTreeForPatch( string patchName, int level, PatchFileInfo info, OpcPaths paths, PositionsType posType, bool saveTriangles = false, bool saveKdTree = true, float maxTriangleSize = float.PositiveInfinity) { var path = Path.Combine(paths.PatchesSubDir, patchName); var patchGeometry = new TriangleSet(); //var patchGeometryTest = new TriangleSet(); if ((maxTriangleSize < float.PositiveInfinity) && (maxTriangleSize > 0.000001f)) { patchGeometry = PatchLoadingStrategy.LoadPatchTriangleSetWithoutOversizedTriangles(info, path, posType, maxTriangleSize); //patchGeometryTest = PatchLoadingStrategy.LoadPatchTriangleSet(info, path, posType); } else { patchGeometry = PatchLoadingStrategy.LoadPatchTriangleSet(info, path, posType); } KdIntersectionTree kdIntTree = new KdIntersectionTree(patchGeometry, KdIntersectionTree.BuildFlags.MediumIntersection | KdIntersectionTree.BuildFlags.Hierarchical); if (!saveTriangles) { kdIntTree.ObjectSet = null; } if (saveKdTree) { var kdTreePath = paths.GetKdTreePath(patchName, level, posType); kdIntTree.Save(kdTreePath); } return(kdIntTree); }
/// <summary> /// NOT TESTED /// </summary> private static KdTreeSet BuildConcreteKdTreeSet(IEnumerable <PatchTree> patches, OpcPaths opcPaths, int level, PositionsType posType, bool overrideExisting, IObserver <float> progressObserver, CancellationToken cancelToken = default(CancellationToken), float maxTriangleSize = float.PositiveInfinity) { var kdTrees = new List <ConcreteKdIntersectionTree>(); var progressInc = 1f / patches.Count(); foreach (var p in patches) { cancelToken.ThrowIfCancellationRequested(); KdIntersectionTree tree; var kdtreePath = opcPaths.GetKdTreePath(p.Id, level, posType); if (overrideExisting || !StorageConfig.FileExists(kdtreePath)) { tree = BuildKdTreeForPatch(p.Id, level, p.Info, opcPaths, posType, saveTriangles: true, saveKdTree: false, maxTriangleSize: maxTriangleSize); } else { tree = Load.As <KdIntersectionTree>(kdtreePath); } kdTrees.Add(tree.ToConcreteKdIntersectionTree()); if (progressObserver != null) { progressObserver.OnNext(progressInc); } } if (progressObserver != null) { progressObserver.OnCompleted(); } return(new KdTreeSet(kdTrees)); }