コード例 #1
0
ファイル: QTreeLeaf.cs プロジェクト: polytronicgr/HydroLiDAR
        /// <summary>
        /// insert points into this node. Method does not check if these points belong here or not
        /// </summary>
        /// <param name="firstPointIndex">index of first point in source array in las file</param>
        /// <param name="source"></param>
        /// <param name="fromIdx"></param>
        /// <returns>next unused point or source.Length if all points were used</returns>
        internal int InsertPreliminary(uint firstPointIndex, Point3D[] source, int fromIdx, float selectionLOD)
        {
            findStepStopWatch.Start();
            int toIndex = findEndWithStep(source, fromIdx, source.Length - 1);

            findStepStopWatch.Stop();

            int sourcePtsLength = toIndex - fromIdx + 1;

            if (numberOfPoints == 0 && sourcePtsLength > 0)
            {
                LasMetrics.GetInstance().numberOfNonEmptyLeafs++;
            }
            numberOfPoints += sourcePtsLength;

            if (toIndex - fromIdx < 0)
            {
                numberOfSmallLists++;
                //do not add
            }
            else
            {
                this.SelectionLOD = selectionLOD;

                ListInfo listInfo = new ListInfo();
                listInfo.numberOfPoints     = (ushort)sourcePtsLength;
                listInfo.startingPointIndex = firstPointIndex + (uint)fromIdx;  //have to add offset to get proper point
                ListInfos.Add(listInfo);
            }

            return(toIndex + 1);        //should be pointing on next available point if any
        }
コード例 #2
0
ファイル: VBOUtils.cs プロジェクト: polytronicgr/HydroLiDAR
        public static void ClearSecondPassQueue()
        {
            secondPassVBOs.Clear();

            LasMetrics.GetInstance().pointsDrawn = pointsDrawnInPass;
            pointsDrawnInPass = 0;
        }
コード例 #3
0
        private void timer1_Tick(object sender, EventArgs e)
        {
            indexing.Text       = LasMetrics.GetInstance().indexing.ToString();
            indexingNoDisk.Text = LasMetrics.GetInstance().indexingNoDisk.ToString();
            avgLoad.Text        = LasMetrics.GetInstance().avgLoad.ToString();
            avgLoadNoDisk.Text  = LasMetrics.GetInstance().avgLoadNoDisk.ToString();
            avgPPL.Text         = LasMetrics.GetInstance().avgPointsPerLeaf.ToString();
            avgPPLactual.Text   = LasMetrics.GetInstance().avgPointsPerLeafActual.ToString();

            numberOfNonEmptyLeafs.Text = LasMetrics.GetInstance().numberOfNonEmptyLeafs.ToString();
            numberOfPoints.Text        = LasMetrics.GetInstance().numberOfPoints.ToString();

            lblNumPointsInVBOs.Text = LasMetrics.GetInstance().numberOfPointsLoadedIntoExistingVBOs.ToString();
            lblNumVBOs.Text         = LasMetrics.GetInstance().numberOfExistingVBOs.ToString();

            lblPointsInsideView.Text = ((double)LasMetrics.GetInstance().pointsInsideViewMilis.TotalMilliseconds / LasMetrics.GetInstance().pointsInsideViewCounted).ToString();

            if (RenderMetrics.getInstance() != null)
            {
                FPS.Text           = RenderMetrics.getInstance().FPS.ToString();
                frameDrawTime.Text = RenderMetrics.getInstance().frameRenderTime.ToString();

                if (LasMetrics.GetInstance().pointsDrawn > 0)
                {
                    pointsDrawn.Text = LasMetrics.GetInstance().pointsDrawn.ToString();
                }

                double copiedToGPU = (double)LasMetrics.GetInstance().bytesTransferedToGPU / (1024.0 * 1024.0);
                lblRAM2GPU.Text = copiedToGPU.ToString();
            }

            tabControl1.SelectedTab.Refresh();
        }
コード例 #4
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);
        }
コード例 #5
0
 private void btnLeafLoading_toggle_Click(object sender, EventArgs e)
 {
     if (btnLeafLoading_toggle.Text == "Start")
     {
         btnLeafLoading_toggle.Text = "Stop";
         LasMetrics.GetInstance().leafLoadToggle = true;
     }
     else
     {
         LasMetrics.GetInstance().leafLoadToggle = false;
         btnLeafLoading_toggle.Text = "Start";
     }
 }
コード例 #6
0
        private void OnPaint(object sender, PaintEventArgs e)
        {
            frameCounter++;

            watch.Stop();
            base.OnPaint(e);

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            RenderScene();

            stopwatch.Stop();

            //this.Text = "Frame rendered in " + stopwatch.ElapsedMilliseconds + " ms. Between frames: "+watch.ElapsedMilliseconds+", points: "+QTreeLeaf.total_drawn_points_in_pass;

            //Console.WriteLine("f#"+frameCounter+" rendered in " + stopwatch.ElapsedMilliseconds + "ms, between frames: " + watch.ElapsedMilliseconds + "ms, points: " + QTreeLeaf.total_drawn_points_in_pass);

            if (frameCounterStopwatch.ElapsedMilliseconds > fpsSampleIntervalMilis)
            {
                frameCounterStopwatch.Stop();

                float fps     = 1000.0f * (float)frameCounter / frameCounterStopwatch.ElapsedMilliseconds;
                float avgTime = (float)frameCounterStopwatch.ElapsedMilliseconds / frameCounter;

                Text = String.Format("FPS: {0}, points drawn: {1}", fps, LasMetrics.GetInstance().pointsDrawn);

                RenderMetrics.getInstance().FPS             = fps;
                RenderMetrics.getInstance().frameRenderTime = avgTime;

                if (updateFormsEvent != null)
                {
                    updateFormsEvent();
                }

                frameCounter = 0;
                frameCounterStopwatch.Reset();
                frameCounterStopwatch.Start();
            }

            watch.Reset();
            watch.Start();
        }
コード例 #7
0
ファイル: VBOUtils.cs プロジェクト: polytronicgr/HydroLiDAR
        public static void DeleteFromGPU(VBOStorageInformation serverBufferIds)
        {
            //free memory on server
            if (serverBufferIds.NumberOfPoints == 0)
            {
                return;
            }
            int[] buffersToDelete = new int[3];
            buffersToDelete[0] = serverBufferIds.VertexVBO;
            buffersToDelete[1] = serverBufferIds.NormalVBO;
            buffersToDelete[2] = serverBufferIds.ColorVBO;
            Gl.glDeleteBuffers(buffersToDelete.Length, buffersToDelete);

            LasMetrics.GetInstance().bytesCurrentlyOnGPURAM -= serverBufferIds.NumberOfPoints * 3 * 4; //3=every point has color, position and normal; 4=every value has 4 bytes
            LasMetrics.GetInstance().numberOfExistingVBOs--;
            LasMetrics.GetInstance().numberOfPointsLoadedIntoExistingVBOs -= serverBufferIds.NumberOfPoints;

            serverBufferIds.ColorVBO       = serverBufferIds.NormalVBO = serverBufferIds.VertexVBO = 0;
            serverBufferIds.NumberOfPoints = 0;
        }
コード例 #8
0
ファイル: VBOUtils.cs プロジェクト: polytronicgr/HydroLiDAR
        /// <summary>
        /// copies points into the VBOs. returns number of points that were copied
        /// </summary>
        /// <param name="nbrPts"></param>
        /// <param name="vertices"></param>
        /// <param name="normals"></param>
        /// <param name="colors"></param>
        /// <param name="serverBufferIds"></param>
        /// <returns></returns>
        unsafe public static void CopyPointsToVBOs(float[] interleavedData, VBOStorageInformation serverBufferIds)
        {
            //create and initialize vertexbuffer
            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, serverBufferIds.InterleavedVBO);
            VBOUtils.CheckGlError("Tried first binding of interleaved VBO during glBegin() and glEnd()");

            long bytesCopied = 0;
            int  size        = 0;

            fixed(float *vptr = interleavedData)
            {
                size         = (sizeof(float) * interleavedData.Length);
                bytesCopied += size;
                Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)size, (IntPtr)vptr, Gl.GL_STATIC_DRAW);
            }

            VBOUtils.CheckGlError("Error copying interleaved data to VBO");

            LasMetrics.GetInstance().bytesTransferedToGPU += bytesCopied;
            LasMetrics.GetInstance().numberOfPointsLoadedIntoExistingVBOs += serverBufferIds.NumberOfPoints;
        }
コード例 #9
0
ファイル: VBOUtils.cs プロジェクト: polytronicgr/HydroLiDAR
        public static void RenderVBOsFastSecondPass()
        {
            if (LasMetrics.GetInstance().renderToggle == false || secondPassVBOs.Count == 0)
            {
                return;
            }

            int numVBOSIs             = secondPassVBOs.Count;
            VBOStorageInformation vbo = null;

            int stride = 40;

            for (int i = 0; i < numVBOSIs; i++)
            {
                vbo = secondPassVBOs[i];
                Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo.InterleavedVBO);

                Gl.glInterleavedArrays(Gl.GL_C4F_N3F_V3F, stride, IntPtr.Zero);
                Gl.glDrawArrays(Gl.GL_POINTS, 0, vbo.NumberOfPoints);
            }
        }
コード例 #10
0
ファイル: VBOUtils.cs プロジェクト: polytronicgr/HydroLiDAR
        public static void RenderVBO(VBOStorageInformation vbo)
        {
            if (LasMetrics.GetInstance().renderToggle == false)
            {
                return;
            }

            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo.InterleavedVBO);

            //array is interleaved like this: VVVNNNCCCC - this is 10*4 bytes.


            //try glInterleavedArrays instead of this three calls, should be faster
            Gl.glInterleavedArrays(Gl.GL_C4F_N3F_V3F, PointInformationSize, IntPtr.Zero);

            Gl.glDrawArrays(Gl.GL_POINTS, 0, vbo.NumberOfPoints);

            pointsDrawnInPass += vbo.NumberOfPoints;

            //add vbo for fast second pass rendering
            secondPassVBOs.Add(vbo);
        }
コード例 #11
0
ファイル: VBOUtils.cs プロジェクト: polytronicgr/HydroLiDAR
        unsafe public static VBOStorageInformation GenerateVBOs(int numberOfPoints)
        {
            //generate free buffer names for 3 different buffers
            int bufferId = 0;

            Gl.glGenBuffers(1, out bufferId);

            VBOUtils.CheckGlError("Tried first binding of VBO during glBegin() and glEnd()");

            if (bufferId == 0)
            {
                throw new ApplicationException("ID of VBO should be set but was not!!!");
            }

            VBOStorageInformation vboSI = new VBOStorageInformation();

            vboSI.InterleavedVBO = bufferId;
            vboSI.NumberOfPoints = numberOfPoints;

            LasMetrics.GetInstance().numberOfExistingVBOs++;
            return(vboSI);
        }
コード例 #12
0
ファイル: QTreeLeaf.cs プロジェクト: polytronicgr/HydroLiDAR
        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();
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// leads leafs in a separate thread
        /// </summary>
        private void LeafLoader()
        {
            TimeSpan  accLoadTime = new TimeSpan();
            long      loadCount   = 0;
            TimeSpan  accReadTime = new TimeSpan();
            TimeSpan  readTemp    = new TimeSpan();
            Stopwatch stopwatch   = new Stopwatch();

            long      accPointsPerLeaf = 0;
            QTreeLeaf leaf             = null;

            while (runLeafLoader)
            {
                if (LasMetrics.GetInstance().leafLoadToggle&& leafLoadRequestQueue.Count > 0)
                {
                    leaf = leafLoadRequestQueue.Dequeue();

                    if (leaf == null)
                    {
                        continue;
                    }

                    if (leaf.State == LoadedState.REQUEST_LOAD)                      //if leaf still wants to be loaded
                    {
                        stopwatch.Start();
                        long readTicks = 0;

                        for (int i = 0; i < leaf.ListInfos.Count; i++)
                        {
                            readTemp = stopwatch.Elapsed;

                            Point3D[] pts = GetPoints(GetQtreeByGuid(leaf.ParentTreeID), leaf.ListInfos[i].startingPointIndex, leaf.ListInfos[i].numberOfPoints);

                            readTicks    = stopwatch.ElapsedTicks;
                            accReadTime += (stopwatch.Elapsed - readTemp);

                            leaf.InsertPoints(i, pts);
                        }

                        if (CALCULATE_NORMALS == true)
                        {
                            leaf.CalculateNormals();
                        }

                        long loadTicks = stopwatch.ElapsedTicks;
                        accLoadTime += stopwatch.Elapsed;

                        stopwatch.Stop();

                        loadCount++;

                        stopwatch.Reset();

                        leaf.State = LoadedState.BUFFERED_IN_RAM;

                        if (loadCount > 0)
                        {
                            double avgLoadTime       = accLoadTime.TotalMilliseconds / loadCount;
                            double avgLoadTimeNoRead = (accLoadTime - accReadTime).TotalMilliseconds / loadCount;

                            //Console.WriteLine("Avg. time from disk to GPU: {0} ms, without disk reads: {1} ms", avgLoadTime, avgLoadTimeNoRead);

                            LasMetrics.GetInstance().avgLoad       = avgLoadTime;
                            LasMetrics.GetInstance().avgLoadNoDisk = avgLoadTimeNoRead;

                            accPointsPerLeaf += leaf.NumberOfPoints;
                            LasMetrics.GetInstance().avgPointsPerLeaf = (double)accPointsPerLeaf / loadCount;
                        }
                    }

                    leaf = null;
                }
                else
                {
                    Thread.Sleep(leafLoaderMSsleepInterval);
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// rendering pass for a node
        /// </summary>
        /// <param name="FOV"></param>
        /// <param name="near"></param>
        /// <param name="far"></param>
        /// <param name="eyeVector"></param>
        /// <param name="position"></param>
        /// <param name="renderOverride">flag that prevents node to be rendered even if in view field, if its too far down the hierarchy</param>
        internal void RenderingPass(float FOV, float near, float far, Vector3f eyeVector, Point2f position, bool renderOverride)
        {
            //new algo: test if three points forming a view triangle lie within the box or only a part if current node
            pointsInsideFOV.Reset();
            pointsInsideFOV.Start();
            int pointsInside = NumberOfPointsInsideFOV(false, far, eyeVector, position);

            pointsInsideFOV.Stop();
            LasMetrics.GetInstance().pointsInsideViewMilis += pointsInsideFOV.Elapsed;
            LasMetrics.GetInstance().pointsInsideViewCounted++;

            //if render override flag was not set to false, check if it can be set here
            //renderOverride set to false prevents node or leaf to be rendered if too far away,
            //although it can still be loaded into memory. This prevents far away regions to be
            //drawn in too much detail that isn't even visible
            if (QTreeNode.PerNodeLOD && renderOverride && !boundingBox.contains(position))
            {
                float closestCorner = position.DistanceTo(boundingBox.Center);

                //check if nearest corner is close enough to warant rendering this level
                for (int i = 0; i < 4; i++)
                {
                    float distToPosition = position.DistanceTo(boundingBox.Corners[i]);

                    if (closestCorner > distToPosition)
                    {
                        closestCorner = distToPosition;
                    }
                }

                //calculate distance relative to the far point. determines which nodes will be drawn and which not
                float relativeDistance = 1.0f - closestCorner / far;

                if (relativeDistance < nodeHierarchyLevel)
                {
                    renderOverride = false;
                }
            }

            if (pointsInside == 3)
            {
                //all points are seen - contents of the node should immediately be drawn without further checks
                if (renderOverride)
                {
                    RenderVisible();
                }
            }
            else if (pointsInside > 0)
            {
                //if only some of the points are inside, checks should be performed in children
                if (renderOverride)
                {
                    Render();
                }

                if (leaf != null)
                {
                    //if only a part is inside, render it anyway.
                    leaf.Render(renderOverride);
                }
                else
                {
                    //render also this node. parts of this node that are visible will be already loaded and therefore visible
                    nodes[NE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                    nodes[NW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                    nodes[SE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                    nodes[SW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                }
            }
            else
            {
                //no points are inside
                //count number of buffered corners. if:
                //- all buffered - place leaf in buffer
                // -some buffered - delve further
                //- none buffered - cascadeInvisibility

                //new values for buffered checks + values are modified with Buffered values

                int bufferedPointsInside = NumberOfPointsInsideFOV(
                    true,
                    far + LasDataManager.BufferedDistance,
                    eyeVector,
                    position - new Point2f(eyeVector.x, eyeVector.z) * LasDataManager.BufferedPositionRadius);

                if (bufferedPointsInside == 3)
                {
                    //all points are within buffer range- buffer all lower nodes and leafs
                    if (leaf != null)
                    {
                        leaf.BufferLeaf();
                    }
                    else
                    {
                        CascadeBuffering();
                    }
                }
                else if (bufferedPointsInside > 0)
                {
                    //if only some of the points are inside, checks should be performed in children
                    if (leaf != null)
                    {
                        //if 2 or more points are inside buffered area buffer it anyways
                        if (bufferedPointsInside > 1)
                        {
                            leaf.BufferLeaf();
                        }
                    }
                    else
                    {
                        nodes[NE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                        nodes[NW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                        nodes[SE].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                        nodes[SW].RenderingPass(FOV, near, far, eyeVector, position, renderOverride);
                    }
                }
                else
                {
                    //none are buffered - remove if in buffer
                    CascadeInvisibility();
                }
            }
        }