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)); }
public void GridToTINDecimatorTests_Refresh() { GridToTINDecimator decimator = new GridToTINDecimator(new DecimationElevationSubGridTree()); decimator.Refresh(); Assert.NotNull(decimator); }
public void GridToTINDecimatorTests_BuildMesh_NoDataSource() { Action act = () => { var decimator = new GridToTINDecimator(null); }; act.Should().Throw <TRexTINException>().WithMessage("No data store provided to decimator"); }
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); }
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); }
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); }
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}"); }
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); }
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}"); }
/// <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); }
public void GridToTINDecimatorTests_Creation_WithDataStore() { GridToTINDecimator decimator = new GridToTINDecimator(new DecimationElevationSubGridTree()); Assert.NotNull(decimator); }