public static PointCloudTileSource Open(LASFile file) { var tileSet = file.EVLRs.First(r => r.RecordIdentifier.Equals(new LASRecordIdentifier("Jacere", 0))).Deserialize <PointCloudTileSet>(); var zStats = file.EVLRs.First(r => r.RecordIdentifier.Equals(new LASRecordIdentifier("Jacere", 1))).Deserialize <Statistics>(); var source = new PointCloudTileSource(file, tileSet, zStats); return(source); }
public static void Remove(PointCloudTileSource tileSource) { if (c_sources.ContainsKey(tileSource)) { c_loadedPaths.Remove(c_sources[tileSource].FilePath); c_sources.Remove(tileSource); tileSource.Close(); } }
public PointCloudTileSourceEnumerator(PointCloudTileSource source, ProgressManagerProcess process) { m_source = source; m_buffer = process.AcquireBuffer(source.MaxTileBufferSize, true); m_process = process; m_stream = StreamManager.OpenReadStream(source.FilePath, source.PointDataOffset); Reset(); }
public ProcessingSet(FileHandlerBase inputFile) { m_id = IdentityManager.AcquireIdentity(GetType().Name); m_inputHandler = inputFile; var tiledPath = PointCloudTileSource.GetTileSourcePath(m_inputHandler.FilePath); m_tiledHandler = LASFile.Create(tiledPath, null); Directory.CreateDirectory(Path.GetDirectoryName(m_tiledHandler.FilePath)); }
public GridQuantizedSet(PointCloudTileSource source, ushort maxDimension) { m_source = source; m_grid = m_source.Extent.CreateGridFromDimension(maxDimension, true, (float)m_source.Extent.MinZ - 1.0f); m_gridQuantized = m_grid.Copy(m_source.QuantizedExtent.MinZ); #warning this is a non-square computation m_pixelsOverRangeX = (double)m_grid.SizeX / m_source.QuantizedExtent.RangeX; m_pixelsOverRangeY = (double)m_grid.SizeY / m_source.QuantizedExtent.RangeY; m_minX = m_source.QuantizedExtent.MinX; m_minY = m_source.QuantizedExtent.MinY; }
private static void OnProcessingCompleted(PointCloudTileSource tileSource) { c_isProcessing = false; var handler = ProcessingCompleted; if (handler != null) { handler(tileSource); } if (IsProcessingQueueEmpty) { OnProcessingQueueEmpty(); } }
private static void OnBackgroundRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { var worker = (sender as ManagedBackgroundWorker); if (worker == null) { return; } var inputHandler = worker.Manager.UserState as FileHandlerBase; if (inputHandler == null) { return; } PointCloudTileSource tileSource = null; if ((e.Cancelled)) { OnProcessingProgressChanged(0); } else if (e.Error != null) { } else { // success tileSource = e.Result as PointCloudTileSource; } if (tileSource != null) { AddTileSource(tileSource, inputHandler); } else { c_loadedPaths.Remove(inputHandler.FilePath); } OnProcessingCompleted(tileSource); StartNextInProcessingQueue(); }
private void LoadFromCache(ProgressManager progressManager) { if (PROPERTY_REUSE_TILING.Value) { if (m_tiledHandler.Exists) { progressManager.Log("Loading from Cache: {0}", Path.GetFileNameWithoutExtension(m_tiledHandler.FilePath)); try { m_tileSource = PointCloudTileSource.Open(m_tiledHandler); } catch { progressManager.Log("Cache Invalid; Regenerating."); File.Delete(m_tiledHandler.FilePath); } } } }
public static System.Windows.Media.Media3D.MeshGeometry3D GenerateMesh(this PointCloudTileSource source, Grid <float> grid, Extent3D distributionExtent) { return(GenerateMesh(source, grid, distributionExtent, false)); }
public PointCloudTileSource TilePointFileIndex(LASFile tiledFile, BufferInstance segmentBuffer, ProgressManager progressManager) { var stopwatch = new Stopwatch(); stopwatch.Start(); var analysis = AnalyzePointFile(segmentBuffer.Length, progressManager); var quantizedExtent = m_source.QuantizedExtent; var tileCounts = analysis.Density.GetTileCountsForInitialization(); var fileSize = tiledFile.PointDataOffset + (m_source.PointSizeBytes * m_source.Count); AttemptFastAllocate(tiledFile.FilePath, fileSize); var lowResPointCountMax = PROPERTY_MAX_LOWRES_POINTS.Value; var lowResBuffer = BufferManager.AcquireBuffer(m_id, lowResPointCountMax * m_source.PointSizeBytes); var lowResWrapper = new PointBufferWrapper(lowResBuffer, m_source.PointSizeBytes, lowResPointCountMax); var validTiles = analysis.GridIndex.Sum(r => r.GridRange.ValidCells); var lowResPointsPerTile = lowResPointCountMax / validTiles; var lowResTileSize = (ushort)Math.Sqrt(lowResPointsPerTile); var lowResGrid = Grid <int> .Create(lowResTileSize, lowResTileSize, true, -1); var lowResCounts = tileCounts.Copy <int>(); using (var outputStream = StreamManager.OpenWriteStream(tiledFile.FilePath, fileSize, tiledFile.PointDataOffset)) { var i = 0; foreach (var segment in analysis.GridIndex) { progressManager.Log("~ Processing Index Segment {0}/{1}", ++i, analysis.GridIndex.Count); var sparseSegment = m_source.CreateSparseSegment(segment); var sparseSegmentWrapper = new PointBufferWrapper(segmentBuffer, sparseSegment); var tileRegionFilter = new TileRegionFilter(tileCounts, quantizedExtent, segment.GridRange); // this call will fill the buffer with points, add the counts, and sort QuantTilePointsIndexed(sparseSegment, sparseSegmentWrapper, tileRegionFilter, tileCounts, lowResWrapper, lowResGrid, lowResCounts, progressManager); var segmentFilteredPointCount = tileRegionFilter.GetCellOrdering().Sum(t => tileCounts.Data[t.Row, t.Col]); var segmentFilteredBytes = segmentFilteredPointCount * sparseSegmentWrapper.PointSizeBytes; // write out the buffer using (var process = progressManager.StartProcess("WriteIndexSegment")) { var segmentBufferIndex = 0; foreach (var tile in segment.GridRange.GetCellOrdering()) { var tileCount = tileCounts.Data[tile.Row, tile.Col]; if (tileCount > 0) { var tileSize = (tileCount - lowResCounts.Data[tile.Row, tile.Col]) * sparseSegmentWrapper.PointSizeBytes; outputStream.Write(sparseSegmentWrapper.Data, segmentBufferIndex, tileSize); segmentBufferIndex += tileSize; if (!process.Update((float)segmentBufferIndex / segmentFilteredBytes)) { break; } } } } if (progressManager.IsCanceled()) { break; } } // write low-res var lowResActualPointCount = lowResCounts.Data.Cast <int>().Sum(); outputStream.Write(lowResWrapper.Data, 0, lowResActualPointCount * lowResWrapper.PointSizeBytes); } var actualDensity = new PointCloudTileDensity(tileCounts, m_source.Quantization); var tileSet = new PointCloudTileSet(m_source, actualDensity, tileCounts, lowResCounts); var tileSource = new PointCloudTileSource(tiledFile, tileSet, analysis.Statistics); if (!progressManager.IsCanceled()) { tileSource.IsDirty = false; } tileSource.WriteHeader(); return(tileSource); }
public PointCloudTileSource Process(ProgressManager progressManager) { progressManager.Log("<= {0}", m_inputHandler.FilePath); PerformanceManager.Start(m_inputHandler.FilePath); // check for existing tile source LoadFromCache(progressManager); if (m_tileSource == null) { using (var process = progressManager.StartProcess("ProcessSet")) { m_binarySource = m_inputHandler.GenerateBinarySource(progressManager); m_tiledHandler = LASFile.Create(m_tiledHandler.FilePath, m_binarySource); using (var segmentBuffer = BufferManager.AcquireBuffer(m_id, (int)PROPERTY_SEGMENT_SIZE.Value, true)) { var tileManager = new PointCloudTileManager(m_binarySource); m_tileSource = tileManager.TilePointFileIndex(m_tiledHandler, segmentBuffer, progressManager); } #warning this was for xyz, but I have not yet re-implemented that anyway //if (m_binarySource.FilePath != m_inputHandler.FilePath) // File.Delete(m_binarySource.FilePath); if (m_tileSource.IsDirty) { m_tileSource.Close(); File.Delete(m_tileSource.FilePath); m_tileSource = null; process.LogTime("=> Processing Cancelled"); } else { process.LogTime("=> Processing Completed"); } } GC.Collect(); } TransferRate averageReadSpeed = PerformanceManager.GetReadSpeed(); TransferRate averageWriteSpeed = PerformanceManager.GetWriteSpeed(); Context.WriteLine("IO Read Speed: {0}", averageReadSpeed); Context.WriteLine("IO Write Speed: {0}", averageWriteSpeed); //{ // // test // Stopwatch stopwatch = new Stopwatch(); // stopwatch.Start(); // PointCloudTile tempTile = m_tileSource.TileSet[0, 0]; // Grid<float> grid = new Grid<float>(tempTile.Extent, 540, (float)m_tileSource.Extent.MinZ - 1.0f, true); // Grid<uint> quantizedGrid = new Grid<uint>(grid.SizeX, grid.SizeY, m_tileSource.Extent, true); // using (GridTileSource<float> gridSource = new GridTileSource<float>(m_tiledPath + ".grid", grid.SizeX, grid.SizeY, m_tileSource.TileSet.Cols, m_tileSource.TileSet.Rows)) // { // int tempBufferSize = (int)(m_tileSource.TileSet.Max(t => t.PointCount)); // byte[] tempBuffer = new byte[tempBufferSize * m_tileSource.PointSizeBytes]; // foreach (PointCloudTile tile in m_tileSource) // { // m_tileSource.LoadTileGrid(tile, tempBuffer, grid, quantizedGrid); // gridSource.WriteTile(tile.Col, tile.Row, grid.Data); // if (!progressManager.Update((float)tile.Index / m_tileSource.TileSet.TileCount)) // break; // } // //gridSource.ReadTile(tempTile.Col, tempTile.Row, grid.Data); // } // m_tileSource.Close(); // progressManager.Log(stopwatch, "Generated GRID"); //} return(m_tileSource); }
protected override void OnClosed(EventArgs e) { CurrentTileSource = null; Context.SaveWindowState(this); Context.Log -= OnLog; Context.ProcessingStarted -= OnProcessingStarted; Context.ProcessingCompleted -= OnProcessingCompleted; Context.ProcessingProgressChanged -= OnProcessingProgressChanged; base.OnClosed(e); }
public string GetTileSourcePath(string path, int segmentIndex) { return(string.Format("{0}{1}", PointCloudTileSource.GetTileSourcePath(path), segmentIndex)); }
private void RemoveTileSource(PointCloudTileSource tileSource) { if (tileSource != null) { if (CurrentTileSource == tileSource) UpdateSelection(null); Context.Remove(tileSource); ContentList.Items.Remove(tileSource); UpdateButtonStates(); } }
public static PointCloudTileSource Open(LASFile file) { var tileSet = file.EVLRs.First(r => r.RecordIdentifier.Equals(new LASRecordIdentifier("Jacere", 0))).Deserialize<PointCloudTileSet>(); var zStats = file.EVLRs.First(r => r.RecordIdentifier.Equals(new LASRecordIdentifier("Jacere", 1))).Deserialize<Statistics>(); var source = new PointCloudTileSource(file, tileSet, zStats); return source; }
public PointCloudTileSource Process(ProgressManager progressManager) { progressManager.Log("<= {0}", m_inputHandler.FilePath); PerformanceManager.Start(m_inputHandler.FilePath); // check for existing tile source LoadFromCache(progressManager); if (m_tileSource == null) { using (var process = progressManager.StartProcess("ProcessSet")) { m_binarySource = m_inputHandler.GenerateBinarySource(progressManager); m_tiledHandler = LASFile.Create(m_tiledHandler.FilePath, m_binarySource); using (var segmentBuffer = BufferManager.AcquireBuffer(m_id, (int)PROPERTY_SEGMENT_SIZE.Value, true)) { var tileManager = new PointCloudTileManager(m_binarySource); m_tileSource = tileManager.TilePointFileIndex(m_tiledHandler, segmentBuffer, progressManager); } #warning this was for xyz, but I have not yet re-implemented that anyway //if (m_binarySource.FilePath != m_inputHandler.FilePath) // File.Delete(m_binarySource.FilePath); if (m_tileSource.IsDirty) { m_tileSource.Close(); File.Delete(m_tileSource.FilePath); m_tileSource = null; process.LogTime("=> Processing Cancelled"); } else { process.LogTime("=> Processing Completed"); } } GC.Collect(); } TransferRate averageReadSpeed = PerformanceManager.GetReadSpeed(); TransferRate averageWriteSpeed = PerformanceManager.GetWriteSpeed(); Context.WriteLine("IO Read Speed: {0}", averageReadSpeed); Context.WriteLine("IO Write Speed: {0}", averageWriteSpeed); //{ // // test // Stopwatch stopwatch = new Stopwatch(); // stopwatch.Start(); // PointCloudTile tempTile = m_tileSource.TileSet[0, 0]; // Grid<float> grid = new Grid<float>(tempTile.Extent, 540, (float)m_tileSource.Extent.MinZ - 1.0f, true); // Grid<uint> quantizedGrid = new Grid<uint>(grid.SizeX, grid.SizeY, m_tileSource.Extent, true); // using (GridTileSource<float> gridSource = new GridTileSource<float>(m_tiledPath + ".grid", grid.SizeX, grid.SizeY, m_tileSource.TileSet.Cols, m_tileSource.TileSet.Rows)) // { // int tempBufferSize = (int)(m_tileSource.TileSet.Max(t => t.PointCount)); // byte[] tempBuffer = new byte[tempBufferSize * m_tileSource.PointSizeBytes]; // foreach (PointCloudTile tile in m_tileSource) // { // m_tileSource.LoadTileGrid(tile, tempBuffer, grid, quantizedGrid); // gridSource.WriteTile(tile.Col, tile.Row, grid.Data); // if (!progressManager.Update((float)tile.Index / m_tileSource.TileSet.TileCount)) // break; // } // //gridSource.ReadTile(tempTile.Col, tempTile.Row, grid.Data); // } // m_tileSource.Close(); // progressManager.Log(stopwatch, "Generated GRID"); //} return m_tileSource; }
private void AddTileSource(PointCloudTileSource tileSource) { int index = ContentList.Items.Add(tileSource); ContentList.SelectedIndex = index; ContentList.ScrollIntoView(tileSource); UpdateSelection(tileSource); UpdateButtonStates(); }
private void UpdateSelection(PointCloudTileSource tileSource) { CurrentTileSource = tileSource; if (tileSource != null) m_tabItemOnSelection.IsSelected = true; else m_tabItemOnStarted.IsSelected = true; UpdateTabSelection(); }
public static System.Windows.Media.Media3D.MeshGeometry3D GenerateMesh(this PointCloudTileSource source, Grid <float> grid, Extent3D distributionExtent, bool showBackFaces) { // subtract midpoint to center around (0,0,0) Extent3D centeringExtent = source.Extent; Point3D centerOfMass = source.CenterOfMass; double centerOfMassMinusMin = centerOfMass.Z - centeringExtent.MinZ; var positions = new System.Windows.Media.Media3D.Point3DCollection(grid.CellCount); var indices = new System.Windows.Media.Int32Collection(2 * (grid.SizeX - 1) * (grid.SizeY - 1)); float fillVal = grid.FillVal; for (int x = 0; x < grid.SizeX; x++) { for (int y = 0; y < grid.SizeY; y++) { double value = grid.Data[x, y] - centerOfMassMinusMin; double xCoord = ((double)x / grid.SizeX) * distributionExtent.RangeX + distributionExtent.MinX - distributionExtent.MidpointX; double yCoord = ((double)y / grid.SizeY) * distributionExtent.RangeY + distributionExtent.MinY - distributionExtent.MidpointY; xCoord += (distributionExtent.MidpointX - centeringExtent.MidpointX); yCoord += (distributionExtent.MidpointY - centeringExtent.MidpointY); var point = new System.Windows.Media.Media3D.Point3D(xCoord, yCoord, value); positions.Add(point); if (x > 0 && y > 0) { // add two triangles int currentPosition = x * grid.SizeY + y; int topPosition = currentPosition - 1; int leftPosition = currentPosition - grid.SizeY; int topleftPosition = leftPosition - 1; if (grid.Data[x - 1, y] != fillVal && grid.Data[x, y - 1] != fillVal) { if (grid.Data[x, y] != fillVal) { indices.Add(leftPosition); indices.Add(topPosition); indices.Add(currentPosition); if (showBackFaces) { indices.Add(leftPosition); indices.Add(currentPosition); indices.Add(topPosition); } } if (grid.Data[x - 1, y - 1] != fillVal) { indices.Add(topleftPosition); indices.Add(topPosition); indices.Add(leftPosition); if (showBackFaces) { indices.Add(topleftPosition); indices.Add(leftPosition); indices.Add(topPosition); } } } } } } var normals = new System.Windows.Media.Media3D.Vector3DCollection(positions.Count); for (int i = 0; i < positions.Count; i++) { normals.Add(new System.Windows.Media.Media3D.Vector3D(0, 0, 0)); } for (int i = 0; i < indices.Count; i += 3) { int index1 = indices[i]; int index2 = indices[i + 1]; int index3 = indices[i + 2]; System.Windows.Media.Media3D.Vector3D side1 = positions[index1] - positions[index3]; System.Windows.Media.Media3D.Vector3D side2 = positions[index1] - positions[index2]; System.Windows.Media.Media3D.Vector3D normal = System.Windows.Media.Media3D.Vector3D.CrossProduct(side1, side2); normals[index1] += normal; normals[index2] += normal; normals[index3] += normal; } for (int i = 0; i < normals.Count; i++) { if (normals[i].Length > 0) { var normal = normals[i]; normal.Normalize(); // the fact that this is necessary means I am doing something wrong if (normal.Z < 0) { normal.Negate(); } normals[i] = normal; } } var geometry = new System.Windows.Media.Media3D.MeshGeometry3D { Positions = positions, TriangleIndices = indices, Normals = normals }; return(geometry); }
public PointCloudTileSource TilePointFileIndex(LASFile tiledFile, BufferInstance segmentBuffer, ProgressManager progressManager) { var stopwatch = new Stopwatch(); stopwatch.Start(); var analysis = AnalyzePointFile(segmentBuffer.Length, progressManager); var quantizedExtent = m_source.QuantizedExtent; var tileCounts = analysis.Density.GetTileCountsForInitialization(); var fileSize = tiledFile.PointDataOffset + (m_source.PointSizeBytes * m_source.Count); AttemptFastAllocate(tiledFile.FilePath, fileSize); var lowResPointCountMax = PROPERTY_MAX_LOWRES_POINTS.Value; var lowResBuffer = BufferManager.AcquireBuffer(m_id, lowResPointCountMax * m_source.PointSizeBytes); var lowResWrapper = new PointBufferWrapper(lowResBuffer, m_source.PointSizeBytes, lowResPointCountMax); var validTiles = analysis.GridIndex.Sum(r => r.GridRange.ValidCells); var lowResPointsPerTile = lowResPointCountMax / validTiles; var lowResTileSize = (ushort)Math.Sqrt(lowResPointsPerTile); var lowResGrid = Grid<int>.Create(lowResTileSize, lowResTileSize, true, -1); var lowResCounts = tileCounts.Copy<int>(); using (var outputStream = StreamManager.OpenWriteStream(tiledFile.FilePath, fileSize, tiledFile.PointDataOffset)) { var i = 0; foreach (var segment in analysis.GridIndex) { progressManager.Log("~ Processing Index Segment {0}/{1}", ++i, analysis.GridIndex.Count); var sparseSegment = m_source.CreateSparseSegment(segment); var sparseSegmentWrapper = new PointBufferWrapper(segmentBuffer, sparseSegment); var tileRegionFilter = new TileRegionFilter(tileCounts, quantizedExtent, segment.GridRange); // this call will fill the buffer with points, add the counts, and sort QuantTilePointsIndexed(sparseSegment, sparseSegmentWrapper, tileRegionFilter, tileCounts, lowResWrapper, lowResGrid, lowResCounts, progressManager); var segmentFilteredPointCount = tileRegionFilter.GetCellOrdering().Sum(t => tileCounts.Data[t.Row, t.Col]); var segmentFilteredBytes = segmentFilteredPointCount * sparseSegmentWrapper.PointSizeBytes; // write out the buffer using (var process = progressManager.StartProcess("WriteIndexSegment")) { var segmentBufferIndex = 0; foreach (var tile in segment.GridRange.GetCellOrdering()) { var tileCount = tileCounts.Data[tile.Row, tile.Col]; if (tileCount > 0) { var tileSize = (tileCount - lowResCounts.Data[tile.Row, tile.Col]) * sparseSegmentWrapper.PointSizeBytes; outputStream.Write(sparseSegmentWrapper.Data, segmentBufferIndex, tileSize); segmentBufferIndex += tileSize; if (!process.Update((float)segmentBufferIndex / segmentFilteredBytes)) break; } } } if (progressManager.IsCanceled()) break; } // write low-res var lowResActualPointCount = lowResCounts.Data.Cast<int>().Sum(); outputStream.Write(lowResWrapper.Data, 0, lowResActualPointCount * lowResWrapper.PointSizeBytes); } var actualDensity = new PointCloudTileDensity(tileCounts, m_source.Quantization); var tileSet = new PointCloudTileSet(m_source, actualDensity, tileCounts, lowResCounts); var tileSource = new PointCloudTileSource(tiledFile, tileSet, analysis.Statistics); if (!progressManager.IsCanceled()) tileSource.IsDirty = false; tileSource.WriteHeader(); return tileSource; }
private Model3DGroup GenerateTileStitching(PointCloudTileSource tileSource, TileInfo3D tileInfo) { PointCloudTile tile = tileInfo.Tile; MeshGeometry3D mesh = GetTileMeshGeometry(tileInfo.CurrentGeometry); Grid<float> grid = tileInfo.CurrentGrid; //Model3DGroup stitchingGroup = new Model3DGroup(); bool hasTop = false; bool hasLeft = false; Point3D topCornerPoint = default(Point3D); Point3D leftCornerPoint = default(Point3D); Vector3D topCornerNormal = default(Vector3D); Vector3D leftCornerNormal = default(Vector3D); // connect to left tile (if available) if (tile.Col > 0) { PointCloudTile leftTile = tileSource.TileSet.GetTile(tile.Row, tile.Col - 1); TileInfo3D leftTileInfo = null; if (leftTile != null && m_tileInfo.TryGetValue(leftTile, out leftTileInfo) && leftTileInfo.CurrentGrid == grid) { MeshGeometry3D leftMesh = GetTileMeshGeometry(leftTileInfo.CurrentGeometry); int leftPositionsStart = leftMesh.Positions.Count - grid.SizeY; hasLeft = true; leftCornerPoint = leftMesh.Positions[leftPositionsStart]; leftCornerNormal = leftMesh.Normals[leftPositionsStart]; if (!tileInfo.HasStitching(TileStitchingEdge.Left)) { MeshGeometry3D stitchingMesh = new MeshGeometry3D(); int positionCount = grid.SizeY * 2; Point3DCollection positions = new Point3DCollection(positionCount); Vector3DCollection normals = new Vector3DCollection(positionCount); for (int edgePosition = 0; edgePosition < grid.SizeY; edgePosition++) { positions.Add(leftMesh.Positions[leftPositionsStart + edgePosition]); normals.Add(leftMesh.Normals[leftPositionsStart + edgePosition]); positions.Add(mesh.Positions[edgePosition]); normals.Add(mesh.Normals[edgePosition]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection((grid.SizeY - 1) * 6); for (int i = 0; i < grid.SizeY - 1; i++) { int j = 2 * i; indices.Add(j); indices.Add(j + 1); indices.Add(j + 2); indices.Add(j + 2); indices.Add(j + 1); indices.Add(j + 3); } stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, leftTileInfo.CurrentGrid, TileStitchingEdge.Left); //stitchingGroup.Children.Add(stitchingModel); } } } // connect to top tile (if available) if (tile.Row > 0) { PointCloudTile topTile = tileSource.TileSet.GetTile(tile.Row - 1, tile.Col); TileInfo3D topTileInfo = null; if (topTile != null && m_tileInfo.TryGetValue(topTile, out topTileInfo) && topTileInfo.CurrentGrid == grid) { MeshGeometry3D topMesh = GetTileMeshGeometry(topTileInfo.CurrentGeometry); hasTop = true; topCornerPoint = topMesh.Positions[grid.SizeY - 1]; topCornerNormal = topMesh.Normals[grid.SizeY - 1]; if (!tileInfo.HasStitching(TileStitchingEdge.Top)) { MeshGeometry3D stitchingMesh = new MeshGeometry3D(); int positionCount = grid.SizeX * 2; Point3DCollection positions = new Point3DCollection(positionCount); Vector3DCollection normals = new Vector3DCollection(positionCount); for (int edgePosition = 0; edgePosition < mesh.Positions.Count; edgePosition += grid.SizeY) { positions.Add(topMesh.Positions[edgePosition + grid.SizeY - 1]); normals.Add(topMesh.Normals[edgePosition + grid.SizeY - 1]); positions.Add(mesh.Positions[edgePosition]); normals.Add(mesh.Normals[edgePosition]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection((grid.SizeX - 1) * 6); for (int i = 0; i < grid.SizeX - 1; i++) { int j = 2 * i; indices.Add(j); indices.Add(j + 2); indices.Add(j + 1); indices.Add(j + 2); indices.Add(j + 3); indices.Add(j + 1); } stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, topTileInfo.CurrentGrid, TileStitchingEdge.Top); //stitchingGroup.Children.Add(stitchingModel); } } } // connect to top left tile (if available) if (hasTop && hasLeft && !tileInfo.HasStitching(TileStitchingEdge.TopLeft)) { PointCloudTile topleftTile = tileSource.TileSet.GetTile(tile.Row - 1, tile.Col - 1); TileInfo3D topleftTileInfo = null; if (topleftTile != null && m_tileInfo.TryGetValue(topleftTile, out topleftTileInfo)) { MeshGeometry3D topleftMesh = GetTileMeshGeometry(topleftTileInfo.CurrentGeometry); MeshGeometry3D stitchingMesh = new MeshGeometry3D(); Point3DCollection positions = new Point3DCollection(4); Vector3DCollection normals = new Vector3DCollection(4); { positions.Add(topleftMesh.Positions[topleftMesh.Positions.Count - 1]); normals.Add(topleftMesh.Normals[topleftMesh.Positions.Count - 1]); positions.Add(topCornerPoint); normals.Add(topCornerNormal); positions.Add(leftCornerPoint); normals.Add(leftCornerNormal); positions.Add(mesh.Positions[0]); normals.Add(mesh.Normals[0]); } stitchingMesh.Positions = positions; stitchingMesh.Normals = normals; Int32Collection indices = new Int32Collection(6); indices.Add(0); indices.Add(1); indices.Add(2); indices.Add(2); indices.Add(1); indices.Add(3); stitchingMesh.TriangleIndices = indices; stitchingMesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(stitchingMesh, m_overallCenteredExtent, MathUtils.ZAxis); GeometryModel3D stitchingModel = new GeometryModel3D(stitchingMesh, m_overviewMaterial); stitchingModel.Freeze(); tileInfo.UpdateStitching(stitchingModel, topleftTileInfo.CurrentGrid, TileStitchingEdge.TopLeft); //stitchingGroup.Children.Add(stitchingModel); } } return tileInfo.GetNewStitching(); }
private void OnProcessingCompleted(PointCloudTileSource tileSource) { // this could be determined with additional event info textBlockPreview.Text = "[Queue empty]"; if (tileSource != null) AddTileSource(tileSource); UpdateButtonStates(); }
private static void AddTileSource(PointCloudTileSource tileSource, FileHandlerBase inputHandler) { tileSource.Open(); c_sources.Add(tileSource, inputHandler); }