private void AddTileSource(PointCloudTileSource tileSource) { int index = ContentList.Items.Add(tileSource); ContentList.SelectedIndex = index; ContentList.ScrollIntoView(tileSource); UpdateSelection(tileSource); UpdateButtonStates(); }
private void OnHeightExaggerationValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs <double> e) { m_heightExaggerationFactor = (float)e.NewValue; PointCloudTileSource source = CurrentTileSource; if (source != null) { CurrentTileSource = null; CurrentTileSource = source; } }
private void OnProcessingCompleted(PointCloudTileSource tileSource) { // this could be determined with additional event info textBlockPreview.Text = "[Queue empty]"; if (tileSource != null) { AddTileSource(tileSource); } UpdateButtonStates(); }
private void OnQualityValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs <double> e) { int quality = (int)e.NewValue; if (quality > 0) { PointCloudTileSource source = CurrentTileSource; if (source != null) { previewImage.Source = source.GeneratePreviewImage(source.Preview.ColorHandler as ColorRamp, CurrentColorUseStdDev, quality); } } }
private void OnStdDevCheckedStateChanged(object sender, RoutedEventArgs e) { bool?useStdDev = (sender as ToggleButton).IsChecked; if (useStdDev.HasValue) { PointCloudTileSource source = CurrentTileSource; if (source != null) { previewImage.Source = source.GeneratePreviewImage(CurrentColorRamp, useStdDev.Value, CurrentColorQuality); } } }
private void OnColorHandlerSelectionChanged(object sender, SelectionChangedEventArgs e) { var ramp = (sender as ComboBox).SelectedItem as ColorRamp; if (ramp != null) { PointCloudTileSource source = CurrentTileSource; if (source != null) { previewImage.Source = source.GeneratePreviewImage(ramp, CurrentColorUseStdDev, CurrentColorQuality); } } }
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 void LoadPreview3D() { PointCloudTileSource tileSource = CurrentTileSource; Jacere.Core.Geometry.Extent3D extent = tileSource.Extent; Model3DGroup modelGroup = new Model3DGroup(); Model3DGroup modelSubGroup = new Model3DGroup(); modelGroup.Children.Add(modelSubGroup); Model3DGroup modelStitchingGroup = new Model3DGroup(); modelGroup.Children.Add(modelStitchingGroup); DirectionalLight lightSource = new DirectionalLight(System.Windows.Media.Colors.White, new Vector3D(-1, -1, -1)); modelGroup.Children.Add(lightSource); ModelVisual3D model = new ModelVisual3D(); model.Content = modelGroup; Jacere.Core.Geometry.Point3D centerOfMass = tileSource.CenterOfMass; Point3D lookatPoint = new Point3D(0, 0, 0); Point3D cameraPoint = new Point3D(0, extent.MinY - centerOfMass.Y, centerOfMass.Z - extent.MinZ + extent.RangeX); Vector3D lookDirection = lookatPoint - cameraPoint; lookDirection.Normalize(); PerspectiveCamera camera = new PerspectiveCamera(); camera.Position = cameraPoint; camera.LookDirection = lookDirection; camera.UpDirection = new Vector3D(0, 0, 1); camera.FieldOfView = 70; RenderOptions.SetEdgeMode(viewport, EdgeMode.Aliased); //viewport.ClipToBounds = false; //viewport.IsHitTestVisible = false; viewport.Camera = camera; viewport.Children.Add(model); m_tileModelCollection = modelSubGroup.Children; m_stitchingModelCollection = modelStitchingGroup.Children; m_backgroundWorker.RunWorkerAsync(CurrentTileSource); }
private void UpdateSelection(PointCloudTileSource tileSource) { CurrentTileSource = tileSource; if (tileSource != null) { m_tabItemOnSelection.IsSelected = true; } else { m_tabItemOnStarted.IsSelected = true; } UpdateTabSelection(); }
private void RemoveTileSource(PointCloudTileSource tileSource) { if (tileSource != null) { if (CurrentTileSource == tileSource) { UpdateSelection(null); } Context.Remove(tileSource); ContentList.Items.Remove(tileSource); UpdateButtonStates(); } }
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 OnBackgroundDoWork(object sender, DoWorkEventArgs e) { PointCloudTileSource tileSource = e.Argument as PointCloudTileSource; Jacere.Core.Geometry.Extent3D extent = tileSource.Extent; m_overviewTextureBrush = new ImageBrush(tileSource.Preview.Image); m_overviewTextureBrush.ViewportUnits = BrushMappingMode.Absolute; m_overviewTextureBrush.Freeze(); m_overviewMaterial = new DiffuseMaterial(m_overviewTextureBrush); m_overviewMaterial.Freeze(); if (tileSource != null) { previewImageGrid.MouseMove -= OnViewportGridMouseMove; Action <string> logAction = value => Context.WriteLine(value); m_progressManager = new BackgroundWorkerProgressManager(m_backgroundWorker, e, logAction, null); m_gridDimensionLowRes = (ushort)Math.Sqrt(VERTEX_COUNT_FAST / tileSource.TileSet.ValidTileCount); //m_gridDimensionHighRes = (ushort)Math.Sqrt(VERTEX_COUNT_LARGE / tileSource.TileSet.ValidTileCount); m_gridDimensionHighRes = (ushort)(Math.Sqrt(tileSource.TileSet.Density.MedianTileCount) / 3); //m_gridDimensionLowRes = (ushort)20; //m_gridDimensionHighRes = (ushort)40; Jacere.Core.Geometry.Point3D centerOfMass = tileSource.CenterOfMass; m_overallCenteredExtent = new Rect3D(extent.MinX - extent.MidpointX, extent.MinY - extent.MidpointY, extent.MinZ - centerOfMass.Z, extent.RangeX, extent.RangeY, extent.RangeZ); // load tiles KeyValuePair <Grid <int>, Grid <float> > gridsLowRes = tileSource.GenerateGrid(m_gridDimensionLowRes); m_gridLowRes = gridsLowRes.Value; m_quantizedGridLowRes = gridsLowRes.Key; KeyValuePair <Grid <int>, Grid <float> > gridsHighRes = tileSource.GenerateGrid(m_gridDimensionHighRes); m_gridHighRes = gridsHighRes.Value; m_quantizedGridHighRes = gridsHighRes.Key; foreach (PointCloudTile tile in tileSource.TileSet) { tileSource.LoadTileGrid(tile, m_buffer, m_gridLowRes, m_quantizedGridLowRes); if (ENABLE_HEIGHT_EXAGGERATION) { m_gridLowRes.Multiply(m_heightExaggerationFactor, (float)centerOfMass.Z); } Jacere.Core.Geometry.Extent3D tileExtent = tile.Extent; MeshGeometry3D mesh = tileSource.GenerateMesh(m_gridLowRes, tileExtent); DiffuseMaterial material = new DiffuseMaterial(); if (USE_LOW_RES_TEXTURE) { material.Brush = m_overviewTextureBrush; mesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(mesh, m_overallCenteredExtent, MathUtils.ZAxis); } else { material.Brush = m_solidBrush; } material.Freeze(); GeometryModel3D geometryModel = new GeometryModel3D(mesh, material); geometryModel.Freeze(); TileInfo3D tileInfo = new TileInfo3D(tile, geometryModel, m_gridLowRes); m_tileInfo.Add(tile, tileInfo); // add mappings m_meshTileMap.Add(geometryModel, tile); //m_lowResMap.Add(tile, geometryModel); if (!m_progressManager.Update(tile, geometryModel)) { break; } } //// test //foreach (double level in new double[] { centerOfMass.Z }) //{ // Grid<float> grid0 = new Grid<float>(20, 20, extent, false); // grid0.FillVal = (float)level; // grid0.Reset(); // grid0.FillVal = float.MinValue; // MeshGeometry3D mesh0 = tileSource.GenerateMesh(grid0, extent); // DiffuseMaterial material0 = new DiffuseMaterial(m_solidBrush); // material0.Freeze(); // GeometryModel3D geometryModel0 = new GeometryModel3D(mesh0, material0); // geometryModel0.Freeze(); // m_progressManager.Update(1.0f, geometryModel0); //} if (ENABLE_STITCHING) { int validStitchingIndex = 0; foreach (PointCloudTile tile in tileSource.TileSet) { TileInfo3D tileInfo = m_tileInfo[tile]; Model3DGroup stitchingGroup = GenerateTileStitching(tileSource, tileInfo); if (stitchingGroup != null) { ++validStitchingIndex; } if (!m_progressManager.Update(1.0f, stitchingGroup)) { break; } } } } }