Esempio n. 1
0
        /// <summary>
        /// Deletes *.dds in an opc directory.
        /// </summary>
        public static int DeleteNormals(OpcPaths opcPaths, IProgress <float> progress = null)
        {
            var files = StorageConfig.GetDirectories(opcPaths.PatchesSubDir)
                        .SelectMany(x => StorageConfig.GetFiles(x))
                        .Where(fileWpath => fileWpath.EndsWith("Normals.aara", StringComparison.OrdinalIgnoreCase));

            if (files.IsEmptyOrNull())
            {
                if (progress != null)
                {
                    progress.Report(1f);
                }
                return(0);
            }

            var inc = 1f / files.Count();

            foreach (var f in files)
            {
                File.Delete(f);
                if (progress != null)
                {
                    progress.Report(inc);
                }
            }
            return(files.Count());
        }
Esempio n. 2
0
        public static bool HasNormals(OpcPaths opcPaths)
        {
            var normalFileName = "Normals.aara";

            return(StorageConfig.GetDirectories(opcPaths.PatchesSubDir)
                   .All(dir => StorageConfig.FileExists(dir + "\\" + normalFileName)));
        }
Esempio n. 3
0
        /// <summary>
        /// Creates normals for the OPC in opcBasePath and saves them as Normals.aara.
        /// </summary>
        public static void BuildNormals(OpcPaths opcPaths, bool overrideExisting, IProgress <Tup <float, string> > progress, CancellationToken cancelToken = default(CancellationToken))
        {
            var sub = new Subject <Tup <float, string> >();

            sub.Subscribe(tup => progress.Report(tup));
            BuildNormals(opcPaths, overrideExisting, sub, cancelToken);
        }
Esempio n. 4
0
        public static bool HasKdTreeForGeoResolution(OpcPaths opcPaths, double minGeometricResolution, PositionsType posType)
        {
            var hierarchyInfo = PatchHierarchyInfo.BuildOrLoadCache(opcPaths);
            var level         = GetLevelFromResolution(hierarchyInfo.AvgGeometrySizes, minGeometricResolution);

            return(HasKdTreeForLevel(opcPaths, level, posType, hierarchyInfo));
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
        /// <param name="minGeometricResolution">Used to select an appropriate level in the hierarchy to meet the specified minimum resolution criterion.</param>
        /// <param name="progressObserver">Reports progress in increments which sum up to 1.</param>
        public static void BuildKdTreeForGeoResolution(
            OpcPaths opcPaths, double minGeometricResolution, PositionsType posType,
            bool lazy = true, bool overrideExisting = false, IObserver <float> progressObserver = null,
            CancellationToken cancelToken = default(CancellationToken))
        {
            var hierarchyInfo = PatchHierarchyInfo.BuildOrLoadCache(opcPaths);
            var level         = GetLevelFromResolution(hierarchyInfo.AvgGeometrySizes, minGeometricResolution);

            BuildKdTreeForLevel(opcPaths, level, posType, lazy, overrideExisting, progressObserver, cancelToken, hierarchyInfo);
        }
Esempio n. 7
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));
        }
Esempio n. 8
0
        /// <summary>
        /// Creates normals for the OPC in opcBasePath and saves them as Normals.aara.
        /// </summary>
        public static void BuildNormals(OpcPaths opcPaths, bool overrideExisting = false, IObserver <Tup <float, string> > progress = null, CancellationToken cancelToken = default(CancellationToken))
        {
            var normalFileName = "Normals.aara";

            var posFiles = StorageConfig.GetDirectories(opcPaths.PatchesSubDir)
                           .SelectMany(x => StorageConfig.GetFiles(x))
                           .Where(fileWpath => fileWpath.EndsWith("Positions.aara", StringComparison.OrdinalIgnoreCase));

            foreach (var file in posFiles)
            {
                if (cancelToken.IsCancellationRequested)
                {
                    if (progress != null)
                    {
                        progress.OnNext(Tup.Create(0f, "Building normals cancelled."));
                        progress.OnCompleted();
                    }
                    cancelToken.ThrowIfCancellationRequested();
                }

                var normalsFilePath = Path.Combine(Path.GetDirectoryName(file), normalFileName);

                if (overrideExisting || !StorageConfig.FileExists(normalsFilePath))
                {
                    var posAara  = AaraData.FromFile(file);
                    var tileSize = new V2i(posAara.Size[0], posAara.Size[1]);

                    var posArray = AaraData.ConvertArrayToV3ds[posAara.DataTypeAsSymbol](posAara.LoadElements());

                    var invalidPoints = OpcIndices.GetInvalidPositions(posArray);
                    var indices       = OpcIndices.ComputeIndexArray(tileSize, invalidPoints);
                    var normals       = OpcIndices.GenerateVertexNormals(indices, posArray)
                                        .Select(p => p.ToV3f()).ToArray();

                    WriteV3fArrayAsAara(normalsFilePath, normals, tileSize);
                }

                if (progress != null)
                {
                    progress.OnNext(Tup.Create(1f / posFiles.Count(), ""));
                }
            }

            if (progress != null)
            {
                progress.OnCompleted();
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Loads level N kdtree. If level N kdtree does not exist it is built from rootpatch.
        /// </summary>
        public static KdIntersectionTree BuildOrLoadKdTreeN(OpcPaths opcPaths, PositionsType posType, PatchFileInfo patchFileInfo)
        {
            KdIntersectionTree kdiTree = null;
            var kdTreeNPatch           = opcPaths.GetKdTreeNPath(posType);

            if (!StorageConfig.FileExists(kdTreeNPatch))
            {
                kdiTree = KdTreeUtils.BuildKdTreeForPatch(opcPaths.RootPatchName, -1, patchFileInfo, opcPaths, posType, saveTriangles: true);
                kdiTree.Save(opcPaths.RootPatchName);
            }
            else
            {
                kdiTree = Load.As <KdIntersectionTree>(opcPaths.GetKdTreeNPath(posType));
            }

            return(kdiTree);
        }
Esempio n. 10
0
        public static Subject <float> GetKdTreeProgressObserver(OpcPaths opcPaths, int level, PositionsType posType)
        {
            var   opcName       = Path.GetFileName(opcPaths.BasePath);
            float totalProgress = 0f;

            var progress = new Subject <float>();

            progress.Sample(TimeSpan.FromSeconds(1.0)).Subscribe(inc =>
            {
                totalProgress += inc;
                Report.Line("{0} - {1} - {2} - Progress {3:0.0}%",
                            opcName, level, posType.ToString(), totalProgress * 100.0);

                //Report.ProgressDelta(tup.E1);
            });

            return(progress);
        }
Esempio n. 11
0
        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);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Deletes *.dds in an opc directory (if *.tif exists).
        /// </summary>
        public static int DeleteDDSs(OpcPaths opcPaths, IProgress <Tup <float, string> > progress = null)
        {
            int deleteCounter = 0;

            var files = StorageConfig.GetDirectories(opcPaths.ImagesSubDir)
                        .SelectMany(x => StorageConfig.GetFiles(x))
                        .Where(x => Path.GetExtension(x) == ".dds");

            if (files.IsEmptyOrNull())
            {
                if (progress != null)
                {
                    progress.Report(Tup.Create(1f, "No dds images found."));
                }
                return(0);
            }

            var inc = 1f / files.Count();

            foreach (var f in files)
            {
                string tifPath = Path.ChangeExtension(f, ".tif");
                var    msg     = "";

                if (StorageConfig.FileExists(tifPath))
                {
                    File.Delete(f);
                    deleteCounter++;
                }
                else
                {
                    msg = "dds file not deleted, because it doesn't have a coresponding tif file (" + f + ")";
                }

                if (progress != null)
                {
                    progress.Report(Tup.Create(inc, msg));
                }
            }

            return(deleteCounter);
        }
Esempio n. 13
0
        /// <summary>
        /// Converts .tif to .dds files in an opc directory for straight to gpu uploads of textures.
        /// tiffs are convert asynchrounos in parallel
        /// </summary>
        public static Task <int> ConvertTiffsToDDSsAsync(OpcPaths opcPaths, bool overrideExisting = false, IProgress <float> progress = null, CancellationToken cancelToken = default(CancellationToken))
        {
            var taskSource = new TaskCompletionSource <int>();

            var tiffs = StorageConfig.GetDirectories(opcPaths.ImagesSubDir)
                        .SelectMany(x => StorageConfig.GetFiles(x))
                        .Where(x => Path.GetExtension(x) == ".tif");

            if (tiffs.IsEmptyOrNull())
            {
                if (progress != null)
                {
                    progress.Report(1f);
                }

                taskSource.SetResult(0);
                return(taskSource.Task);
            }

            var inc   = 1f / tiffs.Count();
            var tasks = new List <Task>();

            foreach (var f in tiffs)
            {
                cancelToken.ThrowIfCancellationRequested();

                var task = Task.Run(() =>
                {
                    ConvertTiffToDDS3(f, overrideExisting);
                    if (progress != null)
                    {
                        progress.Report(inc);
                    }
                });
                tasks.Add(task);
            }

            Task.WhenAll(tasks).ContinueWith(_ => taskSource.SetResult(tiffs.Count()));

            return(taskSource.Task);
        }
Esempio n. 14
0
        //private static SlimDX.Direct3D11.Device d = new SlimDX.Direct3D11.Device(SlimDX.Direct3D11.DriverType.Reference, SlimDX.Direct3D11.DeviceCreationFlags.None, new SlimDX.Direct3D11.FeatureLevel[] { SlimDX.Direct3D11.FeatureLevel.Level_9_1 });

        /// <summary>
        /// Converts .tif to .dds files in an opc directory for straight to gpu uploads of textures.
        /// </summary>
        public static int ConvertTiffsToDDSs(OpcPaths opcPaths, bool overrideExisting = false, IObserver <float> progress = null, CancellationToken cancelToken = default(CancellationToken))
        {
            var tiffs = StorageConfig.GetDirectories(opcPaths.ImagesSubDir)
                        .SelectMany(x => StorageConfig.GetFiles(x))
                        .Where(x => Path.GetExtension(x) == ".tif");

            if (tiffs.IsEmptyOrNull())
            {
                if (progress != null)
                {
                    progress.OnNext(1f);
                    progress.OnCompleted();
                }
                return(0);
            }

            var inc = 1f / tiffs.Count();

            foreach (var f in tiffs)
            {
                cancelToken.ThrowIfCancellationRequested();

                //  ConvertTiffToDDS2(f, overrideExisting);
                //  ConvertTiffToDDS(f, overrideExisting);
                ConvertTiffToDDS3(f, overrideExisting);

                if (progress != null)
                {
                    progress.OnNext(inc);
                }
            }

            if (progress != null)
            {
                progress.OnCompleted();
            }
            return(tiffs.Count());
        }
Esempio n. 15
0
        /// <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);
        }
Esempio n. 16
0
        /// <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));
        }
Esempio n. 17
0
        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));
        }
Esempio n. 18
0
        /// <summary>
        /// Builds look up table for profile "intersection" in 2d data.
        /// </summary>
        public static void BuildLookUpTable(OpcPaths opcPaths, bool overrideExisting = false, IObserver <Tup <float, string> > progress = null, CancellationToken cancelToken = default(CancellationToken))
        {
            if (!overrideExisting && StorageConfig.FileExists(opcPaths.ProfileLutPath))
            {
                if (progress != null)
                {
                    progress.OnNext(Tup.Create(1f, ""));
                    progress.OnCompleted();
                }
                Report.Line("LookUpTable already exists at {0}", opcPaths.ProfileLutPath);
            }

            // PatchHierarchyInfo
            var info = PatchHierarchyInfo.BuildOrLoadCache(opcPaths);

            info.PatchTree.CreatePatchPaths(opcPaths.PatchesSubDir);

            // Level 0 Patches
            var lvl0Patches =
                info.RetrievePatchTreesOfLevel(0);

            if (progress != null)
            {
                progress.OnNext(Tup.Create(.1f, ""));
            }

            // group by BB-2d: Min-X, Max-X
            var patchesGroupedByBB = lvl0Patches
                                     .GroupBy(patchTree => Tup.Create(patchTree.Info.GlobalBoundingBox2d.Min.X, patchTree.Info.GlobalBoundingBox2d.Max.X)).ToArray();

            var entries = new List <ProfileLookUpTableEntry>();

            #region Create ProfileLookUpTableEntries

            for (int index = 0; index < patchesGroupedByBB.Count(); index++)
            {
                if (cancelToken.IsCancellationRequested)
                {
                    if (progress != null)
                    {
                        progress.OnNext(Tup.Create(0f, "Building LookUpTabele cancelled."));
                    }
                    cancelToken.ThrowIfCancellationRequested();
                }

                //sort patches according to their b (sv_b_r) value
                var patchesGroupedBySvBR = patchesGroupedByBB[index]
                                           .OrderBy(k => k.Info.GlobalBoundingBox2d.Min.Y);

                var fileHandleList = new List <PatchFileHandle>();
                #region build PatchFileHandles

                foreach (var patchTree in patchesGroupedBySvBR)
                {
                    if (patchTree.Info.Positions2d.IsNullOrEmpty())
                    {
                        Report.Warn("ProfileLutCreation: Skipping Patchtree {0}, because of missing 2d positions.", patchTree.Id);
                        if (progress != null)
                        {
                            progress.OnNext(Tup.Create(0f, "ProfileLutCreation: Skipping Patchtree " + patchTree.Id + ", because of missing 2d positions."));
                        }
                        continue;
                    }
                    var pos2dPath = patchTree.GetPositionPath(PositionsType.V2dPositions);

                    //CAUTION absolute path needs to be repaired during loading
                    var file = AaraData.FromFile(pos2dPath);
                    file.SourceFileName = string.Empty;

                    fileHandleList.Add(new PatchFileHandle()
                    {
                        PatchTree  = patchTree,
                        FileLoader = file,
                    });
                }

                #endregion

                // Create ProfileLookupTableEntries
                var firstPatchBB = patchesGroupedBySvBR.First().Info.GlobalBoundingBox2d;
                entries.Add(new ProfileLookUpTableEntry()
                {
                    Index       = index,
                    SvRange     = new Range1d(firstPatchBB.Min.X, firstPatchBB.Max.X),
                    FileHandles = fileHandleList,
                });

                var progressInc = 0.8f / patchesGroupedByBB.Count();
                if (progress != null)
                {
                    progress.OnNext(Tup.Create(progressInc, ""));
                }
            }
            entries.Reverse();

            #endregion

            #region Save LUT

            var lut = new ProfileLookUpTable()
            {
                SvRange        = new Range1d(info.PatchTree.Info.GlobalBoundingBox2d.Min.X, info.PatchTree.Info.GlobalBoundingBox2d.Max.X),
                Entries        = entries,
                AvgGeomtrySize = info.AvgGeometrySizes.First()
            };

            lut.Save(opcPaths.ProfileLutPath);

            #endregion

            if (progress != null)
            {
                progress.OnNext(Tup.Create(0.1f, ""));
                progress.OnCompleted();
            }
        }