public void Offset() { var bound = new BoundingIntegerExtent2D(0, 0, 100, 100); bound.Offset(1, 2); bound.Should().BeEquivalentTo(new BoundingIntegerExtent2D(1, 2, 101, 102)); bound.Offset(-1, -2); bound.Should().BeEquivalentTo(new BoundingIntegerExtent2D(0, 0, 100, 100)); }
/// <summary> /// Computes the bounding extent of the cells (bits) in the sub grid that are set to 1 (true) /// </summary> public BoundingIntegerExtent2D ComputeCellsExtents() { BoundingIntegerExtent2D Result = Bits.ComputeCellsExtents(); if (Result.IsValidExtent) { Result.Offset((int)OriginX, (int)OriginY); } return(Result); }
public bool BuildMesh() { BuildMeshFaultCode = DecimationResult.NoError; DateTime StartTime = DateTime.UtcNow; if (Engine.TIN.Vertices.Count > 0 || Engine.TIN.Triangles.Count > 0) { BuildMeshFaultCode = DecimationResult.DestinationTINNotEmpty; return(false); } if (GridCalcExtents.Area() <= 1) { BuildMeshFaultCode = DecimationResult.NoData; return(false); } // Alter the grid extents to that its origin is at (0, 0) GridExtents = GridCalcExtents; // Determine the grid origin offset. GridOriginOffsetX = GridExtents.MinX; GridOriginOffsetY = GridExtents.MinY; GridExtents.Offset(-GridOriginOffsetX, -GridOriginOffsetY); // Initialise the TIN engine to receive the vertices Engine.TIN.Vertices.InitPointSearch(GridExtents.MinX - 100, GridExtents.MinY - 100, GridExtents.MaxX + 100, GridExtents.MaxY + 100, PointLimit * 3); NullVertexHeight = DecimationExtents.MinZ - 100 * Tolerance - 10000.0; ConstructSeedTriangleMesh(); // Engine.TIN.SaveToFile(@"C:\Temp\GRIDToTINDecimator_AfterInitialIntervalTesselation.ttm", true); // Add grid points into the triangle with the largest error (importance) // until there are no triangles whose error falls outside of the tolerance bool finished = false; while (MaxError() > Tolerance && Engine.TIN.Vertices.Count < PointLimit && !Aborted && !finished) { // This logging is very noisy, uncomment out as needed... // Log.LogDebug($"GreedyInsert: Tolerance = {Tolerance}, Triangle count = {Engine.TIN.Triangles.Count}, Vertex count = {Engine.TIN.Vertices.Count}"); finished = !GreedyInsert(); /* This logging is very noisy, uncomment out as needed... * Log.LogDebug($"Mesh size = {Engine.TIN.Triangles.Count} tris. Heap size = {Heap.Count}. Max error = {MaxError()}"); * Log.LogDebug($"ElevationCellValuesRetrieved = {ElevationCellValuesRetrieved}"); * Log.LogDebug($"ElevationCellValuesRetrievedAreNull = {ElevationCellValuesRetrievedAreNull}"); * Log.LogDebug($"ScanTriangleInvocations = {ScanTriangleInvocations}"); * Log.LogDebug($"NumTrivialTrianglesPassedToScanWholeTriangleGeometry = {NumTrivialTrianglesPassedToScanWholeTriangleGeometry}"); */ } Log.LogInformation($"Finished: Mesh = {Engine.TIN.Triangles.Count} tris. Heap = {Heap.Count}. Initial Tolerance = {Tolerance}"); Log.LogInformation($"ElevationCellValuesRetrieved = {ElevationCellValuesRetrieved}"); Log.LogInformation($"ElevationCellValuesRetrievedAreNull = {ElevationCellValuesRetrievedAreNull}"); Log.LogInformation($"ScanTriangleInvocations = {ScanTriangleInvocations}"); Log.LogInformation($"NumTrivialTrianglesPassedToScanWholeTriangleGeometry = {NumTrivialTrianglesPassedToScanWholeTriangleGeometry}"); if (Engine.TIN.Vertices.Count >= PointLimit) { Log.LogInformation($"TIN construction aborted after adding a maximum of {Engine.TIN.Vertices.Count} vertices to the surface being constructed."); BuildMeshFaultCode = DecimationResult.VerticesExceeded; return(false); } //{$IFDEF DEBUG} // AssignFile(F, 'c:\temp\IC_GRIDToTIN_HeapRemainder.txt'); {SKIP} // try // Rewrite(F); // for I := 0 to FHeap.Count - 1 do // Writeln(F, format('HeapNode: %d, MaxError = %.3f', [I, FHeap[I].Import])); // finally // CloseFile(F); // end; //{$ENDIF} //{$IFDEF DEBUG} // FTinningEngine.TIN.SaveToFile('C:\Temp\IC_GRIDToTIN_BeforeNullRemoval.ttm', True); {SKIP} //{$ENDIF} // We have now constructed the surface - now remove all the vertices at elevation NullVertexHeight, // as well as all initial edges and start points as these will now be invalid RemoveCornerAndNullTriangles(); Engine.TIN.Edges.Clear(); Engine.TIN.StartPoints.Clear(); // Now convert all vertex coordinates to their true world positions // Calculate the vertex offset to take into account the local grid origin // offset and the fact the vertex heights are measured at the center of each cell double VertexOffsetX = DataStore.CellSize * (GridOriginOffsetX - DataStore.IndexOriginOffset) + DataStore.CellSize / 2; double VertexOffsetY = DataStore.CellSize * (GridOriginOffsetY - DataStore.IndexOriginOffset) + DataStore.CellSize / 2; for (int I = 0; I < Engine.TIN.Vertices.Count; I++) { Engine.TIN.Vertices[I].X = Engine.TIN.Vertices[I].X * DataStore.CellSize + VertexOffsetX; Engine.TIN.Vertices[I].Y = Engine.TIN.Vertices[I].Y * DataStore.CellSize + VertexOffsetY; } Log.LogInformation($"GridToTIN: {Engine.TIN.Triangles.Count} tris. Seed interval = {SeedPointInterval}. Time = {DateTime.UtcNow - StartTime}"); return(true); }