Пример #1
0
        public void Update(GridToTINTriangle tri, double import)
        {
            int i = tri.HeapIndex;

            if (i >= Count)
            {
                throw new TRexException($"Attempting to update past end of heap [index = {i}, Count = {Count}");
            }

            if (i == GridToTINHeapNode.NOT_IN_HEAP)
            {
                throw new TRexException("Attempting to update object not in heap");
            }

            if (this[i].Tri != tri)
            {
                throw new TRexException("Inconsistent triangle references");
            }

            double old = this[i].Import;

            this[i].Import = import;

            if (import < old)
            {
                Downheap(i);
            }
            else
            {
                Upheap(i);
            }
        }
Пример #2
0
        /// <summary>
        /// Inserts a new triangle into the heap
        /// </summary>
        /// <param name="tri"></param>
        /// <param name="import"></param>
        public void Insert(GridToTINTriangle tri, double import)
        {
            if (tri.Vertices[0] == null || tri.Vertices[1] == null || tri.Vertices[2] == null)
            {
                throw new TRexException("One or more vertices in triangle is null");
            }

            tri.HeapIndex = Count;
            Add(new GridToTINHeapNode(tri, import));
            Upheap(tri.HeapIndex);
        }
Пример #3
0
        public void CheckConsistency2(GridToTINTriangle tri)
        {
            for (int i = 0; i < Count; i++)
            {
                if (this[i].Tri == tri)
                {
                    return;
                }
            }

            throw new TRexException("Triangle is not in the heap");
        }
Пример #4
0
        private void TriangleUpdated(Triangle tri)
        {
            // Every updated triangle must be rescanned to update its candidate grid point
            ScanTri = (GridToTINTriangle)tri;

            if (ScanTri.Vertices[0] != null)
            {
                Update();
            }

            ScanTri = null;
        }
Пример #5
0
        private void TriangleAdded(Triangle tri)
        {
            // Every new triangle must be added to the heap for consideration in processing
            // ... but only if it is not a nil triangle

            ScanTri = (GridToTINTriangle)tri;

            if (ScanTri.Vertices[0] != null)
            {
                Update();
            }

            ScanTri = null;
        }
Пример #6
0
        /// <summary>
        /// Select 'selects' the given position into the TIN model
        /// </summary>
        private void Select(int sx, int sy, double sz, GridToTINTriangle T)
        {
            //if (IsUsed[(int)sx, (int)sy])
            //  throw new TRexTINException($"Reusing vertex at {sx},{sy}");

            // Noisy logging - reinclude as necessary
            // Log.LogDebug($"Setting IsUSed[{sx},{sy}] to true");

            if (IsUsed[sx, sy])
            {
                // Nothing to do - the grid scanner has selected an existing vertex as the optimal vertex to include
                return;
            }

            IsUsed[sx, sy] = true;

            // Add the new position as a vertex into the model and add that new vertex to the mesh
            Engine.IncorporateCoordIntoTriangle(Engine.AddVertex(sx, sy, sz), T);
        }
Пример #7
0
        void ConstructSeedTriangleMesh()
        {
            double[] _Z1 = new double[1];
            double[] _Z2 = new double[1];
            double[] _Z3 = new double[1];
            double[] _Z4 = new double[1];

            void PerformTriangleAdditionToHeap()
            {
                InitialiseTriangleVertexOrdering();

                Candidate = new Candidate(int.MinValue);

                BoundingIntegerExtent2D Extents = new BoundingIntegerExtent2D(
                    (int)Math.Round(GridOriginOffsetX + Math.Min(Math.Min(v0.X, v1.X), v2.X)),
                    (int)Math.Round(GridOriginOffsetY + v0.Y),
                    (int)Math.Round(GridOriginOffsetX + Math.Max(Math.Max(v0.X, v1.X), v2.X)),
                    (int)Math.Round(GridOriginOffsetY + v2.Y));

                // Determine if there is any data in the grid to be processed
                bool FoundGridData = false;

                DataStore.Root.ScanSubGrids(Extents,
                                            leaf =>
                {
                    FoundGridData = true;
                    return(false); // Terminate the scan
                });

                // If there is some grid data in the triangle area then add the triangle to
                // the heap with a default large error (ie: don't waste time scanning it
                // we know we will be scanning it again later).
                if (FoundGridData)
                {
                    ScanTriangle(true);
                }
            }

            DontScanTriangles = true;
            try
            {
                // Seed the model with a small number of points from the grid

                int NXSeedIntervals = Math.Min(GridExtents.SizeX / SeedPointInterval + 1, kMaxSeedIntervals);
                int NYSeedIntervals = Math.Min(GridExtents.SizeY / SeedPointInterval + 1, kMaxSeedIntervals);

                XSeedIntervalStep = GridExtents.SizeX / NXSeedIntervals + 1;
                YSeedIntervalStep = GridExtents.SizeY / NYSeedIntervals + 1;

                Log.LogInformation($"Creating {(NXSeedIntervals + 1) * (NYSeedIntervals + 1)} seed positions into extent of area being TINNed using X/Y seed intervals of {XSeedIntervalStep}/{YSeedIntervalStep}");

                // Insert the seeds as new grid points into the relevant triangles
                if (NXSeedIntervals > 0 && NYSeedIntervals > 0)
                {
                    for (int I = 0; I <= NXSeedIntervals; I++)
                    {
                        for (int J = 0; J <= NYSeedIntervals; J++)
                        {
                            int _X1 = I * XSeedIntervalStep;
                            int _Y1 = J * YSeedIntervalStep;

                            int _X2 = (I + 1) * XSeedIntervalStep;
                            int _Y2 = J * YSeedIntervalStep;

                            int _X3 = I * XSeedIntervalStep;
                            int _Y3 = (J + 1) * YSeedIntervalStep;

                            int _X4 = (I + 1) * XSeedIntervalStep;
                            int _Y4 = (J + 1) * YSeedIntervalStep;

                            GetHeightForTriangleScan(_X1, _Y1, true, 1, _Z1);
                            GetHeightForTriangleScan(_X2, _Y2, true, 1, _Z2);
                            GetHeightForTriangleScan(_X3, _Y3, true, 1, _Z3);
                            GetHeightForTriangleScan(_X4, _Y4, true, 1, _Z4);

                            // Create both triangles across the panel keeping the vertex order as clockwise
                            ScanTri = (GridToTINTriangle)Engine.TIN.Triangles.AddTriangle
                                          (Engine.TIN.Vertices.AddPoint(_X1, _Y1, _Z1[0]),
                                          Engine.TIN.Vertices.AddPoint(_X2, _Y2, _Z2[0]),
                                          Engine.TIN.Vertices.AddPoint(_X3, _Y3, _Z3[0]));

                            PerformTriangleAdditionToHeap();

                            ScanTri = (GridToTINTriangle)Engine.TIN.Triangles.AddTriangle
                                          (Engine.TIN.Vertices.AddPoint(_X3, _Y3, _Z3[0]),
                                          Engine.TIN.Vertices.AddPoint(_X2, _Y2, _Z2[0]),
                                          Engine.TIN.Vertices.AddPoint(_X4, _Y4, _Z4[0]));

                            PerformTriangleAdditionToHeap();
                        }
                    }
                }
            }
            finally
            {
                DontScanTriangles = false;
            }

            Engine.TIN.BuildTriangleLinks();
            Engine.TIN.BuildEdgeList();

            ScanTri = null;
        }