private void UpdateContourLines() { double minValue = AxesBox.ZAxis1.MinimumValue; double maxValue = AxesBox.ZAxis1.MaximumValue; // First define values for each contour line var contourLineValues = SetupContourLineValues(minValue, maxValue, step: (maxValue - minValue) / 15); // Then use CreateContourLinePositions method to create positions for all contour lines and returns them in one Point3DCollection. var contourLinePositions = HeightMap1.CreateContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map ContourLinesVisual3D.Positions = contourLinePositions; BottomContourLinesVisual3D.Children.Clear(); AxesBox.ShowBottomConnectionLines = false; // Show flattened contour lines at the bottom of the graph if (ShowBottomGridCheckBox.IsChecked ?? false) { if (ContourLinesRadioButton.IsChecked ?? false) { // Get bottom y position of the AxesBox double yPosition = AxesBox.CenterPosition.Y - AxesBox.Size.Y * 0.5; // CreateContourLinePositions creates positions for individual contour lines and returns them in an array of Point3DCollection // (each element in the array represents positions for contour lines each value in _contourLineValues). var individualContourLinePositions = HeightMap1.CreateMultiContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map for (var i = 0; i < contourLineValues.Length; i++) { // Update all position's Y value to yPosition var positions = individualContourLinePositions[i]; for (var j = 0; j < positions.Count; j++) { positions[j] = new Point3D(positions[j].X, yPosition, positions[j].Z); } var color = HeightMap1.GetHeightTextureColor(contourLineValues[i]); var multiLineVisual3D = new MultiLineVisual3D() { Positions = positions, LineThickness = 2, LineColor = color }; BottomContourLinesVisual3D.Children.Add(multiLineVisual3D); } } else if (WireframeRadioButton.IsChecked ?? false) { AxesBox.ShowBottomConnectionLines = true; } } }
private void ChangeDataButton_OnClick(object sender, RoutedEventArgs e) { // This method demonstrates how to update the graph 3D mesh after the data are changed // Similar code can be used to create dynamic height graphs. // But be careful about performance especially when showing 3D lines in height map. // Much better performance can be achieved when 3D lines are not shown. int arraySize = GetSelectedArraySize(); double[,] heightData = HeightMap1.HeightData; for (int z = 0; z < arraySize; z++) { for (int x = 0; x < arraySize; x++) { heightData[z, x] *= 0.95; } } // UpdateContent will recreate the 3D mesh HeightMap1.UpdateContent(); }
private void UpdateGradientTexture() { Rectangle selectedRectangle; if (Gradient1RadioButton.IsChecked ?? false) { selectedRectangle = Rectangle1; } else if (Gradient2RadioButton.IsChecked ?? false) { selectedRectangle = Rectangle2; } else // if (Gradient1RadioButton.IsChecked ?? false) { selectedRectangle = Rectangle3; } // The following call will create the magic: // It will use the height data and the LinearGradientBrush on the selected rectangle // and create the texture bitmap from the data HeightMap1.CreateHeightTextureFromGradient((LinearGradientBrush)selectedRectangle.Fill); }
private void UpdateGradientTexture() { Rectangle selectedRectangle; if (Gradient1RadioButton.IsChecked ?? false) { selectedRectangle = Rectangle1; } else if (Gradient2RadioButton.IsChecked ?? false) { selectedRectangle = Rectangle2; } else // if (Gradient1RadioButton.IsChecked ?? false) { selectedRectangle = Rectangle3; } // The following call will create the magic: // It will use the height data and the LinearGradientBrush on the selected rectangle // and create the texture bitmap from the data HeightMap1.CreateHeightTextureFromGradient((LinearGradientBrush)selectedRectangle.Fill); // This method is internally calling static CreateHeightTexture and GetGradientColorsArray methods on Ab3d.Meshes.HeightMapMesh3D. // It is also possible to create the textures manually (uncomment the following code): // The simple way ////WriteableBitmap texture = Ab3d.Meshes.HeightMapMesh3D.CreateHeightTexture(_data, _minYValue, _maxYValue, (LinearGradientBrush)selectedRectangle.Fill); // An advanced way with first creating an array of colors (with specifying the size of array - by default also 100): ////uint[] gradientColorsArray = Ab3d.Meshes.HeightMapMesh3D.GetGradientColorsArray(selectedRectangle.Fill as LinearGradientBrush, 100); ////WriteableBitmap texture = Ab3d.Meshes.HeightMapMesh3D.CreateHeightTexture(_data, _minYValue, _maxYValue, gradientColorsArray); // After that we set the Material of the HeightMap1 ////HeightMap1.Material = new DiffuseMaterial(new ImageBrush(texture)); }
private void UpdateContourLines() { double minValue = AxesBox.ZAxis1.MinimumValue; double maxValue = AxesBox.ZAxis1.MaximumValue; // First define values for each contour line var contourLineValues = SetupContourLineValues(minValue, maxValue, step: (maxValue - minValue) / 15); // Then use CreateContourLinePositions method to create positions for all contour lines and returns them in one Point3DCollection. // No yOffset when rendered by DXEngine because we will use LineDepthBias instead (see a few lines below): //var contourLinePositions = HeightMap1.CreateContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map var contourLinePositions = HeightMap1.CreateContourLinePositions(contourLineValues); ContourLinesVisual3D.Positions = contourLinePositions; // With DXEngine it is possible to offset the 3D lines from the 3D models in the geometry shader // so that lines are always positioned towards the camera. // This efficiently prevents that lines or parts of lines are hidden by the 3D objects. ContourLinesVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, 0.5f); BottomContourLinesVisual3D.Children.Clear(); AxesBox.ShowBottomConnectionLines = false; // Show flattened contour lines at the bottom of the graph if (ShowBottomGridCheckBox.IsChecked ?? false) { if (ContourLinesRadioButton.IsChecked ?? false) { // Get bottom y position of the AxesBox double yPosition = AxesBox.CenterPosition.Y - AxesBox.Size.Y * 0.5; // CreateContourLinePositions creates positions for individual contour lines and returns them in an array of Point3DCollection // (each element in the array represents positions for contour lines each value in _contourLineValues). var individualContourLinePositions = HeightMap1.CreateMultiContourLinePositions(contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map for (var i = 0; i < contourLineValues.Length; i++) { // Update all position's Y value to yPosition var positions = individualContourLinePositions[i]; for (var j = 0; j < positions.Count; j++) { positions[j] = new Point3D(positions[j].X, yPosition, positions[j].Z); } var color = HeightMap1.GetHeightTextureColor(contourLineValues[i]); var multiLineVisual3D = new MultiLineVisual3D() { Positions = positions, LineThickness = 2, LineColor = color }; BottomContourLinesVisual3D.Children.Add(multiLineVisual3D); } } else if (WireframeRadioButton.IsChecked ?? false) { AxesBox.ShowBottomConnectionLines = true; } } }
private void CreateContourLines() { ContourLinesRootVisual3D.Children.Clear(); // NOTE: // Here we use CreateContourLinePositions and CreateMultiContourLinePositions methods on the HeightMapVisual3D class. // Those methods use the MeshGeometry3D of the height map and also scale the contour lines by the size of the HeightMapVisual3D. // // If you want to create contour lines based on some other geometry, then use the Ab3d.Utilities.ContourLinesFactory class (internally used by HeightMapVisual3D). if (CombineAllContourLinesRadioButton.IsChecked ?? false) { // CreateContourLinePositions creates positions for all contour lines and returns them in one Point3DCollection. var contourLinePositions = HeightMap1.CreateContourLinePositions(_contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map var multiLineVisual3D = new MultiLineVisual3D() { Positions = contourLinePositions, LineColor = Colors.Black, LineThickness = 1 }; ContourLinesRootVisual3D.Children.Add(multiLineVisual3D); _individualContourLinePositions = null; _individualContourLines = null; } else { _individualContourLines = new List <MultiLineVisual3D>(_contourLineValues.Length); // CreateContourLinePositions creates positions for individual contour lines and returns them in an array of Point3DCollection // (each element in the array represents positions for contour lines each value in _contourLineValues). _individualContourLinePositions = HeightMap1.CreateMultiContourLinePositions(_contourLineValues, yOffset: 0.05); // offset the contour lines so they are drawn just slightly on top of the 3D height map for (var i = 0; i < _individualContourLinePositions.Length; i++) { var multiLineVisual3D = new MultiLineVisual3D() { Positions = _individualContourLinePositions[i], }; // Set line thickness (each 5th line is thicker) if ((i % 5) == 0) { multiLineVisual3D.LineThickness = 2; } else { multiLineVisual3D.LineThickness = 0.7; } // Set line color if (ColoredContourLinesRadioButton.IsChecked ?? false) { var color = HeightMap1.GetHeightTextureColor(_contourLineValues[i]); multiLineVisual3D.LineColor = color; } else { multiLineVisual3D.LineColor = Colors.Black; } ContourLinesRootVisual3D.Children.Add(multiLineVisual3D); _individualContourLines.Add(multiLineVisual3D); } } }
private void SetGradientMaterial(bool useGeographicalColors) { GradientStopCollection stops = new GradientStopCollection(); if (GeographicalSmoothColorsRadioButton.IsChecked ?? false) { stops.Add(new GradientStop(Colors.White, 1)); stops.Add(new GradientStop(Colors.Gray, 0.8)); stops.Add(new GradientStop(Colors.SandyBrown, 0.6)); stops.Add(new GradientStop(Colors.LightGreen, 0.4)); stops.Add(new GradientStop(Colors.Aqua, 0.2)); stops.Add(new GradientStop(Colors.Blue, 0)); } else if (GeographicalHardColorsRadioButton.IsChecked ?? false) { // The gradient with hard transition is defined by making the transition from one color to another very small (for example from 0.799 to 0.8) stops.Add(new GradientStop(Colors.White, 1)); stops.Add(new GradientStop(Colors.White, 0.8)); stops.Add(new GradientStop(Colors.SandyBrown, 0.799)); stops.Add(new GradientStop(Colors.SandyBrown, 0.6)); stops.Add(new GradientStop(Colors.LightGreen, 0.599)); stops.Add(new GradientStop(Colors.LightGreen, 0.400)); stops.Add(new GradientStop(Colors.Aqua, 0.399)); stops.Add(new GradientStop(Colors.Aqua, 0.2)); stops.Add(new GradientStop(Colors.Blue, 0.199)); stops.Add(new GradientStop(Colors.Blue, 0)); } else { stops.Add(new GradientStop(Colors.Red, 1)); stops.Add(new GradientStop(Colors.Yellow, 0.75)); stops.Add(new GradientStop(Colors.LightGreen, 0.5)); stops.Add(new GradientStop(Colors.Aqua, 0.25)); stops.Add(new GradientStop(Colors.Blue, 0)); } // NOTE: We do not have to specify the StartPoint and EndPoint // It will be used in the CreateHeightTextureFromGradient method // to create the texture from the actual height map data and with the specified LinearGradientBrush LinearGradientBrush gradient = new LinearGradientBrush(stops); // When using gradient texture, we get better results when UseHeightValuesAsTextureCoordinates is true. // In this case height values are used for texture coordinates - texture coordinate (0, 0.5) is set the minimum height value and texture coordinate (1, 0.5) is set to the maximum height value. // This requires a one dimensional gradient texture and usually produces more accurate results than when UseHeightValuesAsTextureCoordinates is false. // This should not be used for cases when a bitmap is shown on the height map. // See HeightMapSample for more info. // Set this value to false to see the difference. HeightMap1.UseHeightValuesAsTextureCoordinates = true; HeightMap1.CreateHeightTextureFromGradient(gradient); // This method is internally calling static CreateHeightTexture and GetGradientColorsArray methods on Ab3d.Meshes.HeightMapMesh3D. // It is also possible to create the textures manually (uncomment the following code): // The simple way ////WriteableBitmap texture = Ab3d.Meshes.HeightMapMesh3D.CreateHeightTexture(_data, _minYValue, _maxYValue, (LinearGradientBrush)selectedRectangle.Fill); // An advanced way with first creating an array of colors (with specifying the size of array - by default also 100): ////uint[] gradientColorsArray = Ab3d.Meshes.HeightMapMesh3D.GetGradientColorsArray(selectedRectangle.Fill as LinearGradientBrush, 100); ////WriteableBitmap texture = Ab3d.Meshes.HeightMapMesh3D.CreateHeightTexture(_data, _minYValue, _maxYValue, gradientColorsArray); // After that we set the Material of the HeightMap1 ////HeightMap1.Material = new DiffuseMaterial(new ImageBrush(texture)); }