Beispiel #1
0
        public void GridToTINDecimatorTests_BuildMesh_GetTIN()
        {
            var dataStore = new DecimationElevationSubGridTree();

            SubGridUtilities.SubGridDimensionalIterator((x, y) =>
            {
                dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + x, SubGridTreeConsts.DefaultIndexOriginOffset + y] = 100f;
            });

            var decimator = new GridToTINDecimator(dataStore);

            decimator.SetDecimationExtents(DataStoreExtents(dataStore));
            bool result = decimator.BuildMesh();

            result.Should().BeTrue($"Failed to build mesh from data store with a sub grid of points fault code {decimator.BuildMeshFaultCode}");

            decimator.GetTIN().Should().NotBeNull();

            //string fileName = $@"C:\temp\UnitTestExportTTM({DateTime.Now.Ticks}).ttm";
            //decimator.GetTIN().SaveToFile(fileName, true);

            //TrimbleTINModel tin = new TrimbleTINModel();
            //tin.LoadFromFile(fileName);

            decimator.GetTIN().Triangles.Count.Should().Be(3);
            decimator.GetTIN().Triangles[0].Vertices.ForEach(x => x.Z.Should().Be(100f));

            decimator.GetTIN().Vertices.Count.Should().Be(5);
            decimator.GetTIN().Vertices.ForEach(x => x.Z.Should().Be(100.0f));
        }
Beispiel #2
0
        public void GridToTINDecimatorTests_Refresh()
        {
            GridToTINDecimator decimator = new GridToTINDecimator(new DecimationElevationSubGridTree());

            decimator.Refresh();

            Assert.NotNull(decimator);
        }
Beispiel #3
0
        public void GridToTINDecimatorTests_BuildMesh_NoDataSource()
        {
            Action act = () =>
            {
                var decimator = new GridToTINDecimator(null);
            };

            act.Should().Throw <TRexTINException>().WithMessage("No data store provided to decimator");
        }
Beispiel #4
0
        public void GridToTINDecimatorTests_BuildMesh_NonEmptyDestinationTIN()
        {
            GridToTINDecimator decimator = new GridToTINDecimator(new DecimationElevationSubGridTree());

            decimator.GridCalcExtents = new BoundingIntegerExtent2D(0, 0, 100, 100);
            decimator.GetTIN().Triangles.AddTriangle(new TriVertex(0, 0, 0), new TriVertex(1, 1, 1), new TriVertex(0, 0, 1));

            decimator.BuildMesh().Should().BeFalse();
            decimator.BuildMeshFaultCode.Should().Be(DecimationResult.DestinationTINNotEmpty);
        }
Beispiel #5
0
        public void GridToTINDecimatorTests_BuildMesh_SetDecimationExtents()
        {
            GridToTINDecimator decimator = new GridToTINDecimator(new DecimationElevationSubGridTree());

            decimator.SetDecimationExtents(new BoundingWorldExtent3D(0, 0, 100, 100));

            Assert.True(decimator.GridCalcExtents.MinX == 536870912);
            Assert.True(decimator.GridCalcExtents.MaxX == 536871206);
            Assert.True(decimator.GridCalcExtents.MinY == 536870912);
            Assert.True(decimator.GridCalcExtents.MaxY == 536871206);
        }
Beispiel #6
0
        public void GridToTINDecimatorTests_BuildMesh_EmptyDataSource()
        {
            GridToTINDecimator decimator = new GridToTINDecimator(new DecimationElevationSubGridTree());

            decimator.BuildMesh().Should().BeFalse();
            decimator.BuildMeshFaultCode.Should().Be(DecimationResult.NoData);

            decimator.GetTIN().Triangles.Count.Should().Be(0);
            decimator.GetTIN().Vertices.Count.Should().Be(0);
            decimator.GetTIN().Edges.Count.Should().Be(0);
            decimator.GetTIN().StartPoints.Count.Should().Be(0);
        }
Beispiel #7
0
        public void GridToTINDecimatorTests_BuildMesh_SinglePoint()
        {
            DecimationElevationSubGridTree dataStore = new DecimationElevationSubGridTree();

            dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + 100, SubGridTreeConsts.DefaultIndexOriginOffset + 100] = 100.0f;

            GridToTINDecimator decimator = new GridToTINDecimator(dataStore);

            decimator.SetDecimationExtents(DataStoreExtents(dataStore));
            bool result = decimator.BuildMesh();

            Assert.True(result && decimator.GetTIN().Triangles.Count == 0, $"Failed to fail to build mesh from data store with single point fault code {decimator.BuildMeshFaultCode}");
        }
Beispiel #8
0
        public void GridToTINDecimatorTests_BuildMesh_ExceedPointLimit()
        {
            DecimationElevationSubGridTree dataStore = new DecimationElevationSubGridTree();

            dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + 100, SubGridTreeConsts.DefaultIndexOriginOffset + 100] = 100.0f;
            dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + 101, SubGridTreeConsts.DefaultIndexOriginOffset + 101] = 100.0f;
            dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + 101, SubGridTreeConsts.DefaultIndexOriginOffset + 100] = 100.0f;

            GridToTINDecimator decimator = new GridToTINDecimator(dataStore);

            decimator.PointLimit = 2;
            decimator.SetDecimationExtents(DataStoreExtents(dataStore));
            decimator.BuildMesh().Should().BeFalse();
            decimator.BuildMeshFaultCode.Should().Be(DecimationResult.VerticesExceeded);
        }
Beispiel #9
0
        public void GridToTINDecimatorTests_BuildMesh_ThreePoints()
        {
            DecimationElevationSubGridTree dataStore = new DecimationElevationSubGridTree();

            dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + 100, SubGridTreeConsts.DefaultIndexOriginOffset + 100] = 100.0f;
            dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + 101, SubGridTreeConsts.DefaultIndexOriginOffset + 101] = 100.0f;
            dataStore[SubGridTreeConsts.DefaultIndexOriginOffset + 101, SubGridTreeConsts.DefaultIndexOriginOffset + 100] = 100.0f;

            GridToTINDecimator decimator = new GridToTINDecimator(dataStore);

            decimator.SetDecimationExtents(DataStoreExtents(dataStore));
            bool result = decimator.BuildMesh();

            Assert.True(result, $"Failed to build mesh from data store with three points fault code {decimator.BuildMeshFaultCode}");
        }
Beispiel #10
0
        /// <summary>
        /// Executor that implements creation of the TIN surface
        /// </summary>
        public async Task <bool> ExecuteAsync()
        {
            Log.LogInformation($"Performing Execute for DataModel:{_dataModelId}");

            try
            {
                var requestDescriptor = Guid.NewGuid();
                var siteModel         = DIContext.Obtain <ISiteModels>().GetSiteModel(_dataModelId);

                if (siteModel == null)
                {
                    Log.LogError($"Failed to obtain site model for {_dataModelId}");
                    return(false);
                }

                var datastore = new GenericSubGridTree <float, GenericLeafSubGrid <float> >(siteModel.Grid.NumLevels, siteModel.CellSize);

                // Provide the processor with a customised request analyser configured to return a set of sub grids. These sub grids
                // are the feed stock for the generated TIN surface
                using (var processor = DIContext.Obtain <IPipelineProcessorFactory>().NewInstanceNoBuild <SubGridsRequestArgument>(
                           requestDescriptor,
                           _dataModelId,
                           GridDataFromModeConverter.Convert(DisplayMode.Height),
                           SurfaceSubGridsResponse,
                           _filters,
                           new DesignOffset(),
                           DIContext.Obtain <Func <PipelineProcessorTaskStyle, ITRexTask> >()(PipelineProcessorTaskStyle.SurfaceExport),
                           DIContext.Obtain <Func <PipelineProcessorPipelineStyle, ISubGridPipelineBase> >()(PipelineProcessorPipelineStyle.DefaultProgressive),
                           DIContext.Obtain <IRequestAnalyser>(),
                           Rendering.Utilities.DisplayModeRequireSurveyedSurfaceInformation(DisplayMode.Height) && Rendering.Utilities.FilterRequireSurveyedSurfaceInformation(_filters),
                           false, //Rendering.Utilities.RequestRequiresAccessToDesignFileExistenceMap(DisplayMode.Height),
                           BoundingIntegerExtent2D.Inverted(),
                           _liftParams))
                {
                    // Set the surface TRexTask parameters for progressive processing
                    processor.Task.TRexNodeID = RequestingTRexNodeID;

                    if (!processor.Build())
                    {
                        Log.LogError($"Failed to build pipeline processor for request to model {_dataModelId}");
                        return(false);
                    }

                    processor.Process();

                    if (SurfaceSubGridsResponse.ResultStatus != RequestErrorStatus.OK)
                    {
                        Log.LogError($"Sub grids response status not OK: {SurfaceSubGridsResponse.ResultStatus}");
                        return(false);
                    }

                    // Create the TIN decimator and populate it with the retrieved sub grids
                    foreach (var subGrid in ((SurfaceTask)processor.Task).SurfaceSubgrids)
                    {
                        if (!(datastore.ConstructPathToCell(subGrid.OriginX, subGrid.OriginY, SubGridPathConstructionType.CreatePathToLeaf) is INodeSubGrid newGridNode))
                        {
                            Log.LogError($"Result from data store ConstructPathToCell({subGrid.OriginX}, {subGrid.OriginY}) was null. Aborting...");
                            return(false);
                        }

                        subGrid.Owner = datastore;
                        newGridNode.GetSubGridCellIndex(subGrid.OriginX, subGrid.OriginY, out var subGridIndexX, out var subGridIndexY);
                        newGridNode.SetSubGrid(subGridIndexX, subGridIndexY, subGrid);
                    }
                }

                // Obtain the surface export data smoother and apply it to the tree of queried data before passing it to the decimation engine
                var dataSmoother = DIContext.Obtain <Func <DataSmootherOperation, IDataSmoother> >()(DataSmootherOperation.SurfaceExport) as ITreeDataSmoother <float>;

                datastore = dataSmoother?.Smooth(datastore) ?? datastore;

                var extents = DataStoreExtents(datastore);

                // Make sure we don't export too large an area due to data way outside project extents
                if (extents.Area > Common.Consts.MaxExportAreaM2)
                {
                    // First try and use project boundary extents as our data boundary
                    var canExport = siteModel.SiteModelExtent.Area > 0 && siteModel.SiteModelExtent.Area < Common.Consts.MaxExportAreaM2;
                    if (canExport)
                    {
                        // still use min max height extents
                        Log.LogInformation($"Invalid Plan Extent. Data area too large {extents.Area}. Switching to project extents");
                        extents.MinX = siteModel.SiteModelExtent.MinX;
                        extents.MinY = siteModel.SiteModelExtent.MinY;
                        extents.MaxX = siteModel.SiteModelExtent.MaxX;
                        extents.MaxY = siteModel.SiteModelExtent.MaxY;
                    }
                    else
                    {
                        Log.LogError($"Invalid Plan Extent. Data area too large {extents.Area}.");
                        return(false);
                    }
                }

                // Decimate the elevations into a grid
                var decimator = new GridToTINDecimator(datastore)
                {
                    Tolerance = _tolerance
                };
                decimator.SetDecimationExtents(extents);

                if (!decimator.BuildMesh())
                {
                    Log.LogError($"Decimator returned false with error code: {decimator.BuildMeshFaultCode}");
                    return(false);
                }

                // A decimated TIN has been successfully constructed...  Return it!
                SurfaceSubGridsResponse.TIN = decimator.GetTIN();
            }
            catch (Exception e)
            {
                Log.LogError(e, "ExecutePipeline raised Exception:");
                return(false);
            }

            return(true);
        }
Beispiel #11
0
        public void GridToTINDecimatorTests_Creation_WithDataStore()
        {
            GridToTINDecimator decimator = new GridToTINDecimator(new DecimationElevationSubGridTree());

            Assert.NotNull(decimator);
        }