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); } }
/// <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); }
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"); }
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; }
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; }
/// <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); }
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; }