Пример #1
0
        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));
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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);
        }