Beispiel #1
0
        /// <summary>
        /// serializes qtree to file.
        /// </summary>
        /// <param name="rewriteIfExists"></param>
        private void SerializeQtreeToFile(QTreeWrapper qtree, bool rewriteIfExists)
        {
            Console.WriteLine("Serializing qtree to file");

            string     srlFilename      = qtree.filename + "." + serializiationExtension;
            FileStream fileStreamObject = null;

            if (File.Exists(srlFilename) && !rewriteIfExists)
            {
                Console.WriteLine("File already exists and rewrite flag is set to false. Returning");
                return;
            }

            try
            {
                fileStreamObject = new FileStream(srlFilename, FileMode.Create);
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(fileStreamObject, qtree.qtree);
            }
            finally
            {
                if (fileStreamObject != null)
                {
                    fileStreamObject.Close();
                }
            }

            Console.WriteLine("Serialization finished");
        }
Beispiel #2
0
        /// <summary>
        /// initializes data manager with data from las file and fills QTree structure with preliminary data
        /// </summary>
        public void Initialize(QTreeWrapper qtree, bool forcePreprocessing)
        {
            if (forcePreprocessing)
            {
                Console.WriteLine("Preprocessing forced. Not using serialized even if available");
                PreprocessDataFromFile(qtree);
                SerializeQtreeToFile(qtree, true);
            }
            else
            {
                QTree des = DeserializeQtreeFromFile(qtree.filename);

                if (des == null)
                {
                    Console.WriteLine("Deserialization failed. Preprocessing.");
                    PreprocessDataFromFile(qtree);
                    SerializeQtreeToFile(qtree, true);
                }
                else
                {
                    qtree.qtree = des;
                }
            }

            if (loadingEndedEvent != null)
            {
                loadingEndedEvent(true);
            }
        }
Beispiel #3
0
        /// <summary>
        /// renders the QTree in current openGl context
        /// </summary>
        private void RenderingPass(QTreeWrapper qtree, float FOV, float near, float far, Vector3f eyeVector, Point2f position)
        {
            QTree lasTree = qtree.qtree;

            if (lasTree != null)
            {
                lasTree.RenderingPass(FOV, near, far, eyeVector, position - qtree.positionOffset);

                /*
                 *                      Point3D tempPoint = new Point3D();
                 *                      int pointSize = Marshal.SizeOf(tempPoint);
                 *
                 *                      int allowedPointsInMemory = dedicatedPointMemory / pointSize;
                 *
                 *                      float percent = (float)lasTree.numberOfLoadedPoints / (float)allowedPointsInMemory;
                 *
                 *                      //allow discrepancy of 15%
                 *                      if (Math.Abs(percent - LOD) > 0.1)
                 *                      {
                 *                              LOD = (float)allowedPointsInMemory / (float)qtree.lasFile.header.NumberOfPointRecords;
                 *                              //lasTree.CascadeLOD(LOD);
                 *                      }
                 */
            }
        }
Beispiel #4
0
        /// <summary>
        /// loads and initializes the file
        /// </summary>
        /// <param name="filename"></param>
        public void Load(string filename, bool forcePreprocessing)
        {
            if (loadingStatusEvent != null)
            {
                loadingStatusEvent("Opening LAS file", 0.01f);
            }

            QTreeWrapper tree = AddQtreeFromFile(filename);

            Initialize(tree, forcePreprocessing);
        }
Beispiel #5
0
        private void PreprocessDataFromFile(QTreeWrapper qtreeWrapper)
        {
            Stopwatch initTimer = new Stopwatch();

            initTimer.Start();
            qtreeWrapper.lasFile.PositionAtStartOfPointData();
            uint index        = 0;
            uint numAllPoints = qtreeWrapper.lasFile.header.NumberOfPointRecords;

            Point3D[] lineOfPoints = null;
            int       step         = 100000;

            determineInitialSelectionLOD();

            TimeSpan accReadTime = new TimeSpan();

            while (index < numAllPoints)
            {
                if (loadingStatusEvent != null)
                {
                    loadingStatusEvent("Indexing points..." + index + "/" + numAllPoints, (float)index / (float)numAllPoints);
                }

                TimeSpan before = initTimer.Elapsed;
                lineOfPoints = GetPoints(qtreeWrapper, index, step);
                accReadTime += (initTimer.Elapsed - before);

                if (lineOfPoints != null)
                {
                    qtreeWrapper.qtree.Initialize(index, lineOfPoints, SelectionLOD);
                }

                index       += (uint)lineOfPoints.Length;
                lineOfPoints = null;
            }

            initTimer.Stop();

            LasMetrics.GetInstance().indexing       = initTimer.ElapsedMilliseconds;
            LasMetrics.GetInstance().indexingNoDisk = (initTimer.Elapsed - accReadTime).TotalMilliseconds;


            LasMetrics.GetInstance().avgPointsPerLeafActual = (double)numAllPoints / LasMetrics.GetInstance().numberOfNonEmptyLeafs;
            LasMetrics.GetInstance().numberOfPoints        += numAllPoints;

            Console.WriteLine("lasDataManager.Initialize() took {0} ms for {1} points", initTimer.ElapsedMilliseconds, numAllPoints);
            Console.WriteLine("reading from disk took {0} ms, indexing without reading from disk took {1} ms", accReadTime.TotalMilliseconds, LasMetrics.GetInstance().indexingNoDisk);
            Console.WriteLine("nr. of all points: {0}, avg. points per leaf: {1}, without empty: {2}", numAllPoints, numAllPoints / LasMetrics.GetInstance().numberOfLeafs, LasMetrics.GetInstance().avgPointsPerLeafActual);
            Console.WriteLine("QTreeLeaf.findEnd() took {0} ms", QTreeLeaf.findStepStopWatch.ElapsedMilliseconds);
            Console.WriteLine("array copying() took {0} ms", QTreeLeaf.arrayCompyTimer.ElapsedMilliseconds);
            Console.WriteLine("mem alocated: {0}kb", GC.GetTotalMemory(false) / 1024);
        }
Beispiel #6
0
        /// <summary>
        /// adds qtree to the collection and initializes it
        /// </summary>
        /// <param name="filename"></param>
        protected QTreeWrapper AddQtreeFromFile(string filename)
        {
            Console.WriteLine("Adding qtree from file: {0}", filename);
            QTreeWrapper qtreeWrapper = GetQtreeByFilename(filename);

            if (qtreeWrapper != null)
            {
                Console.WriteLine("Qtree already exists");
                return(qtreeWrapper);
            }

            qtreeWrapper          = new QTreeWrapper();
            qtreeWrapper.filename = filename;
            qtreeWrapper.lasFile  = new LASFile(filename);
            qtreeWrapper.lasFile  = adjustParameters(qtreeWrapper.lasFile);

            if (QTrees.Count == 0)
            {
                Console.WriteLine("First loaded qtree. positioning at (0,0)");
            }
            else
            {
                Console.WriteLine("Not first qtree to be loaded. Setting offset coordinates relative to the first qtree");

                QTreeWrapper first = QTrees[0];
                qtreeWrapper.positionOffset = new Point2f(
                    (float)(qtreeWrapper.lasFile.header.MinX - first.lasFile.header.MinX),
                    (float)(qtreeWrapper.lasFile.header.MinY - first.lasFile.header.MinY));

                Console.WriteLine("Offset coordinates for tree {0} are {1}", QTrees.Count, qtreeWrapper.positionOffset);
            }



            if (loadingStatusEvent != null)
            {
                loadingStatusEvent("Creating quad tree", 0.02f);
            }

            qtreeWrapper.qtree = new QTree(this, qtreeWrapper.lasFile);

            QTrees.Add(qtreeWrapper);
            CalculateGlobalBoundingBox();

            return(qtreeWrapper);
        }
Beispiel #7
0
        public QTreeLeaf(BoundingBox bb, Guid parentTreeID, QTreeNode parentNode)
        {
            ParentTreeID    = parentTreeID;
            this.ParentNode = parentNode;

            QTreeWrapper parent = LasDataManager.GetInstance().GetQtreeByGuid(parentTreeID);

            parentVBOs = new Stack <VBOStorageInformation>(); //stored on this level

            ListInfos = new List <ListInfo>();
            LasMetrics.GetInstance().numberOfLeafs++;

            boundingBox = bb;

            if (randArray == null)
            {
                randArray = new float[3000];

                for (int i = 0; i < randArray.Length; i++)
                {
                    randArray[i] = (float)rand.NextDouble();
                }
            }
        }
Beispiel #8
0
        public Point3D[] GetPoints(QTreeWrapper qtree, uint index, int numberOfPoints)
        {
            //Console.WriteLine("getPoints entry. mem alocated: {0}", GC.GetTotalMemory(false));

            Point3D[] pts = null;

            float minX = (float)((qtree.lasFile.header.MinX - qtree.lasFile.header.OffsetX));
            float minY = (float)((qtree.lasFile.header.MinY - qtree.lasFile.header.OffsetY));
            float minZ = (float)((qtree.lasFile.header.MinZ - qtree.lasFile.header.OffsetZ));

            float scaleX = (float)qtree.lasFile.header.ScaleFactorX;
            float scaleY = (float)qtree.lasFile.header.ScaleFactorY;
            float scaleZ = (float)qtree.lasFile.header.ScaleFactorZ;

            //Console.WriteLine("loading point at index={0}, number to load={1}", index, numberOfPoints);

            if (qtree.lasFile.header.PointDataFormat == 0)
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                LASPointFormat0[] pointArray = (LASPointFormat0[])qtree.lasFile.GetPoints(index, numberOfPoints);
                stopwatch.Stop();
                //Console.WriteLine("loading took: {0} ms", stopwatch.ElapsedMilliseconds);

                long loading = stopwatch.ElapsedMilliseconds;

                stopwatch.Reset();
                stopwatch.Start();

                if (pointArray != null)
                {
                    int count = pointArray.Length;
                    index += (uint)count;
                    pts    = new Point3D[numberOfPoints];

                    for (int i = 0; i < count; i++)
                    {
                        pts[i].x = pointArray[i].X * scaleX * LasDataManager.GlobalPointsScaleFactor.x - minX;
                        pts[i].y = (pointArray[i].Y) * scaleY * LasDataManager.GlobalPointsScaleFactor.y - minY;
                        pts[i].z = (pointArray[i].Z) * scaleZ * LasDataManager.GlobalPointsScaleFactor.z - minZ;

                        pts[i].colorIndex = pointArray[i].Classification;

                        if (pts[i].z < GlobalBoundingCube.minZ)
                        {
                            GlobalBoundingCube.minZ = pts[i].z;
                        }
                        if (pts[i].y > GlobalBoundingCube.maxZ)
                        {
                            GlobalBoundingCube.maxZ = pts[i].z;
                        }
                    }
                }

                pointArray = null;

                stopwatch.Stop();
                long transforming = stopwatch.ElapsedMilliseconds;
                //Console.WriteLine("transforming points: {0} ms", stopwatch.ElapsedMilliseconds);
            }
            else
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                LASPointFormat1[] pointArray = (LASPointFormat1[])qtree.lasFile.GetPoints(index, numberOfPoints);
                stopwatch.Stop();
                //Console.WriteLine("loading poins: {0} ms", stopwatch.ElapsedMilliseconds);
                long loading = stopwatch.ElapsedMilliseconds;
                stopwatch.Reset();
                stopwatch.Start();

                if (pointArray != null)
                {
                    int count = pointArray.Length;
                    index += (uint)count;
                    pts    = new Point3D[numberOfPoints];

                    for (int i = 0; i < count; i++)
                    {
                        pts[i].x = pointArray[i].X * scaleX * LasDataManager.GlobalPointsScaleFactor.x - minX;
                        pts[i].y = (pointArray[i].Y) * scaleY * LasDataManager.GlobalPointsScaleFactor.y - minY;
                        pts[i].z = (pointArray[i].Z) * scaleZ * LasDataManager.GlobalPointsScaleFactor.z - minZ;

                        pts[i].colorIndex = pointArray[i].Classification;

                        if (pts[i].z < GlobalBoundingCube.minZ)
                        {
                            GlobalBoundingCube.minZ = pts[i].z;
                        }
                        if (pts[i].y > GlobalBoundingCube.maxZ)
                        {
                            GlobalBoundingCube.maxZ = pts[i].z;
                        }
                    }
                }

                pointArray = null;

                stopwatch.Stop();
                long transforming = stopwatch.ElapsedMilliseconds;
                //Console.WriteLine("transforming poins: {0} ms", stopwatch.ElapsedMilliseconds);
            }

            //Console.WriteLine("getPoints exit. mem alocated: {0} ", GC.GetTotalMemory(false));

            return(pts);
        }
Beispiel #9
0
        protected unsafe void LoadIntoVBO()
        {
            if (serverBufferId != null)
            {
                throw new ApplicationException("should not occur");
            }

            if (parentVBOs == null)
            {
                parentVBOs = new Stack <VBOStorageInformation>();
            }

            QTreeWrapper parentTree = LasDataManager.GetInstance().GetQtreeByGuid(ParentTreeID);

            #region Create vertex arrays
            //form three arrays to copy to server memory

            ColorPalette pallette = LasDataManager.ColorPallette;

            //code that reduces given points
            //how many points to skip when loading
            int step = (int)Math.Ceiling((1.0 / ReductionToParentCoef));        //be conservative

            int allLevels = parentTree.qtree.NumberOfTreeLevels;

            int pointsOnLevel     = NumberOfPoints / allLevels;
            int pointsOnLastLevel = pointsOnLevel + NumberOfPoints - pointsOnLevel * allLevels;


            if (pointsOnLevel < 5)
            {
                //no need to overburden the system with separate arrays for very small amounts of points
                allLevels         = 1;
                pointsOnLastLevel = NumberOfPoints;
            }

            float[][] interleavedArrayAtLevel = new float[allLevels][];

            int interleavedDataStride = VBOUtils.PointInformationSize;
            int byteStride            = interleavedDataStride / 4;

            for (int i = 0; i < allLevels; i++)
            {
                if (i == (allLevels - 1))
                {
                    //last(leaf) level also contains all remaining points
                    interleavedArrayAtLevel[i] = new float[pointsOnLastLevel * byteStride]; //10 is for 3*V,3*N and 4*C bytes
                }
                else if (pointsOnLevel > 0)
                {
                    interleavedArrayAtLevel[i] = new float[pointsOnLevel * byteStride];
                }
            }

            int currentLevel        = 0;                                                  //we will iterate mod allLevels so the points are distributed fairly
            int pointIndex          = 0;                                                  //point index inside an array for a level. increased only when we return to locating points to the frst level
            int numAllocatedPoints  = 0;                                                  //counts total number of allcoated point
            int lastPointsThreshold = NumberOfPoints - pointsOnLastLevel + pointsOnLevel; //threshold which determines from where on points are only on the last level

            //generate points for all levels in one iteration over all the points
            for (int j = 0; j < ContainedPointLists.Count; j++)
            {
                Point3D[] pts = ContainedPointLists[j];
                int       len = pts.Length;

                for (int k = 0; k < len; k++)
                {
                    Point3D p = pts[k];

                    //C4
                    GetColorFromPalette(interleavedArrayAtLevel[currentLevel], pallette, pointIndex, p);
                    interleavedArrayAtLevel[currentLevel][pointIndex + 3] = 1;

                    //N3
                    interleavedArrayAtLevel[currentLevel][pointIndex + 4] = p.nx;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 5] = p.nz;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 6] = p.ny;

                    //V3
                    interleavedArrayAtLevel[currentLevel][pointIndex + 7] = p.x + parentTree.positionOffset.x;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 8] = p.z;
                    interleavedArrayAtLevel[currentLevel][pointIndex + 9] = p.y + parentTree.positionOffset.y;

                    numAllocatedPoints++; //increased for every point

                    if (numAllocatedPoints < lastPointsThreshold)
                    {
                        currentLevel++;

                        if (currentLevel == allLevels)
                        {
                            //increase point index only when going back to the first level
                            pointIndex  += byteStride; //3 values for vertices, 3 for colors and 3 for normals
                            currentLevel = 0;
                        }
                    }
                    else
                    {
                        currentLevel = allLevels - 1;
                        pointIndex  += byteStride; //point index is always updated, because we only insert points to the last layer now
                    }
                }
            }
            #endregion

            //only if points wil bedistributed between nodes propagate them up the hierarchy
            if (allLevels > 1)
            {
                //load all arrays into VBOStorageInformation objects and pass them along to parents
                Stack <VBOStorageInformation> vbosForParents = new Stack <VBOStorageInformation>(allLevels - 1); //for parents
                parentVBOs.Clear();

                for (int i = 0; i < allLevels - 1; i++)
                {
                    VBOStorageInformation vbos = VBOUtils.GenerateVBOs(pointsOnLevel);

                    VBOUtils.CopyPointsToVBOs(interleavedArrayAtLevel[i], vbos);

                    //insert into stack so parents can take them out
                    vbosForParents.Push(vbos);
                    parentVBOs.Push(vbos);
                }

                ParentNode.AddVBO(vbosForParents);
            }

            //load also into this leafs VBO
            serverBufferId = VBOUtils.GenerateVBOs(pointsOnLastLevel);

            VBOUtils.CopyPointsToVBOs(interleavedArrayAtLevel[allLevels - 1], serverBufferId);

            ClearAllPoints();
            State = LoadedState.BUFFERED_IN_GPU;
        }