public override void Do(IDemoChartControl chartControl) { // Generates surface positions. const int resolution = 50; const float r = 0.5f; var center = new Vector3F(0.5f); var vertex = new Vector3F[resolution * resolution]; var index = 0; for (var i = 0; i < resolution; i++) { for (var k = 0; k < resolution; k++) { double t = Math.PI * i / (resolution - 1); double f = Math.PI * 2 * k / (resolution - 1); vertex[index++] = new Vector3F((float)(r * Math.Sin(t) * Math.Cos(f)), (float)(r * Math.Sin(t) * Math.Sin(f)), (float)(r * Math.Cos(t))) + center; } } // Section geometry. var complexGeometry = new CustomVolumeGeometry(new VolumeMesh(vertex, vertex, GridHelper.GetStructuredTriangleListIndices(0, resolution, resolution, 1))); // Demo volumetric binary data from resources. byte[] data = Properties.Resources.skull; // Size of data is the same in all 3 dimensions. var size = (int)Math.Round(Math.Pow(data.Length, 1d / 3d)); // Byte, Short, Float types are supported. var reader = new ByteIntensityImage3DReader(data, size, size, new OneAxisBounds(data.Min(), data.Max())); // Create volume section render data. var section = new VolumeSection { // Set section data reader. Reader = reader, // Set section geometry. Geometry = complexGeometry, // Set section interpolation type. InterpolationType = VolumeInterpolationType.Linear, // Set name. Name = "Section" }; // Enable 3D axis. chartControl.Axes.IsAxes3DVisible = true; // Set chart data source. chartControl.DataSource = new RenderData[] { section }; }
public override void Do(IDemoChartControl chartControl) { // Demo volumetric binary data from resources. byte[] data = Properties.Resources.skull; // Size of data is the same in all 3 dimensions. var size = (int)Math.Round(Math.Pow(data.Length, 1d / 3d)); // Link to data. Several rendering techniques can use the same data. For reader we should specify link to binary data, slice size, and value axis bounds. // For dynamic updates of data you can implement your own reader, basic reader interface provide neccessary methods for updating separate data regions. // Byte, Short, Float types are supported. var reader = new ByteIntensityImage3DReader(data, size, size, new OneAxisBounds(data.Min(), data.Max())); // Geometry specify bounding box to that volume data will be fitted. Geometry can be more complex than just box. // Mostly it does nothave limits, you can specify even sphere. var geometry = new BoxVolumeGeometry { Origin = Vector3F.Zero, Size = new Vector3F(1f), }; // Initialize ray-casting. var rayCasting = new VolumeRayCasting { // Setup it's reader. We'll reuse it for section. Reader = reader, // Setup ray-casting geometry. Geometry = geometry, // Interpolation type between voxels/ InterpolationType = VolumeInterpolationType.Linear, // Parameter for ray casting technique that will specify how much steps will be on a each ray. // Directly effects performance and render quality. By default it is calculated automatically. SamplingStepCount = size, // Threshold for transparent areas that will no be visible for hit testing. // 0 will increase picking performance due to item will be picked by bounding box. HitTestThreshold = 0.25f, // The same as HitTestThreshold, but for highlighting. HighlightThreshold = 0.25f, // Global value transparency scale. ValueScale = 0.3f, // Set name. Name = "Volume", // Don't forget to enable depth-test since we want to visualize section in the ray-casting. IsDepthTestEnabled = true }; List <RenderData> renderDatas = new List <RenderData>(); void SubmitSection(float relativeLocation, int id) { // Initialize volume visual section that takes control over section presentation. var visualSection = new VolumeVisualPlaneSection { // Specify it's parent geometry as ray-casting geometry we want to cross. ParentGeometry = geometry, // Setup section plane origin. Origin = new Vector3F(relativeLocation), // Setup section plane normal. Normal = new Vector3F(1, 1, 1), OutlineThickness = 2.0f, OutlineColor = Colors.Black, IsOutlineVisible = true, FillColor = new Color4(Colors.Blue, 100), IsFillVisible = false, Name = $"Visual {id}" }; renderDatas.Add(visualSection); // Initialize volume section render data. var section = new VolumeSection { // Setup reader. Reader = reader, // Link the section geometry to it's visual section geometry. Geometry = visualSection.SectionGeometry, Name = $"Section {id}" }; renderDatas.Add(section); } // Bounding box. var boundingCube = new Cube { Size = new Vector3F(1f), Position = new Vector3F(0.5f), Color = Colors.Black, PresentationType = PrimitivePresentationType.Wireframe, Name = "Bounds" }; renderDatas.Add(boundingCube); // Add sections. SubmitSection(0.25f, 0); SubmitSection(0.5f, 1); SubmitSection(0.75f, 2); // Place ray-casting as last item to enable depth-test. renderDatas.Add(rayCasting); // Decrease multisampling level to improve interaction experience. chartControl.Multisampling = Multisampling.Low2X; chartControl.Axes.IsAxes3DVisible = true; // Set chart data source. chartControl.DataSource = renderDatas; }
public override void Do(IDemoChartControl chartControl) { // Demo volumetric binary data from resources. byte[] data = Properties.Resources.skull; // Size of data is the same in all 3 dimensions. var size = (int)Math.Round(Math.Pow(data.Length, 1d / 3d)); // Byte, Short, Float types are supported. var reader = new ByteIntensityImage3DReader(data, size, size, new OneAxisBounds(data.Min(), data.Max())); // This function is used for volume section geometry creation. // We just create rectangular geometry moving it along Z axis. VolumeGeometry GetGeometry(float relativePosition) { // Generates surface positions. Vector3F[] positions = { new Vector3F(0.0f, 0.0f, relativePosition), new Vector3F(1f, 0.0f, relativePosition), new Vector3F(0.0f, 1f, relativePosition), new Vector3F(1f, 1f, relativePosition), }; int[] indices = { 0, 1, 2, 2, 3, 1 }; return(new CustomVolumeGeometry(new VolumeMesh(positions, positions, indices))); } VolumeSection GetSection(float relativePosition, float opacity, string name) { // Create volume section render data. return(new VolumeSection { // Set section data reader. Reader = reader, // Set section geometry. Geometry = GetGeometry(relativePosition), // Set section interpolation type. InterpolationType = VolumeInterpolationType.Linear, // Set opacity, Opacity = opacity, // Set name. Name = name }); } // Bounding box. var cube = new Cube { Size = new Vector3F(1f), Position = new Vector3F(0.5f), Color = Colors.Black, PresentationType = PrimitivePresentationType.Wireframe, Name = "Bounds" }; // Enable 3D axis. chartControl.Axes.IsAxes3DVisible = true; // Submit render data-s. List <RenderData> renderDatas = new List <RenderData>(); float sliceStep = 1.0f / (SliceCount + 1); for (int i = 0; i < SliceCount; i++) { float currentPosition = sliceStep * (i + 1); renderDatas.Add(GetSection(currentPosition, 1.0f - currentPosition, $"Section {i}")); } renderDatas.Add(cube); // Set chart data source. chartControl.DataSource = renderDatas; }
public override void Do(IDemoChartControl chartControl) { // Demo volumetric binary data from resources. byte[] data = Properties.Resources.skull; // Size of data is the same in all 3 dimensions. var size = (int)Math.Round(Math.Pow(data.Length, 1d / 3d)); // Link to data. Several rendering techniques can use the same data. For reader we should specify link to binary data, slice size, and value axis bounds. // For dynamic updates of data you can implement your own reader, basic reader interface provide neccessary methods for updating separate data regions. // Byte, Short, Float types are supported. var reader = new ByteIntensityImage3DReader(data, size, size, new OneAxisBounds(data.Min(), data.Max())); // Initialization of rendering technique. var rayCasting = new VolumeIsoRayCasting { // Link to data. Several rendering techniques can use the same data. For reader we should specify link to binary data, slice size, and value axis bounds. // For dynamic updates of datayou can implement your own reader, basic reader interface provide neccessary methods for updating separate data regions. Reader = reader, // Geometry specify bounding box to that volume data will be fitted. Geometry can be more complex than just box. // Mostly it does nothave limits, you can specify even sphere. Geometry = new BoxVolumeGeometry { Origin = Vector3F.Zero, Size = new Vector3F(1f), }, // Parameter for ray casting technique that will specify how much steps will be on a each ray. // Directly effects performance and render quality. By default it is calculated automatically. SamplingStepCount = size, // Interpolation type between voxels. InterpolationType = VolumeInterpolationType.Linear, // Property that define value level for isosurface. IsoValue = reader.ValueRange.Min + (reader.ValueRange.Max - reader.ValueRange.Min) * 0.25f, // Specify iso-surface color. Color = Colors.Red, // For isosurface there is no difference which value is setted. Only 0 or another from 0 have sence. // 0 will increase picking performance due to item will be picked by bounding box. HitTestThreshold = 0.25f, // Set name. Name = "Volume" }; // Setup highlight interactor. rayCasting.Interactor = new HighlightInteractor(rayCasting); // Bounding box. var cube = new Cube { Size = new Vector3F(1f), Position = new Vector3F(0.5f), Color = Colors.Red, PresentationType = PrimitivePresentationType.Wireframe, Name = "Bounds" }; // Decrease multisampling level to improve interaction experience. chartControl.Multisampling = Multisampling.Low2X; // Setup chart data source. chartControl.DataSource = new RenderData[] { rayCasting, cube }; }
public override void Do(IDemoChartControl chartControl) { // Order-Independent transparency requres additional GPU resources, it should be used only when neccessary. // Multisample antialiasing and control resolution have significant effect to OIT performance. chartControl.IsOitEnabled = true; // Demo volumetric binary data from resources var data = Properties.Resources.skull; // Size of data is the same in all 3 dimensions var size = (int)Math.Round(Math.Pow(data.Length, 1d / 3d)); // Link to data. Several rendering techniques can use the same data. For reader we should specify link to binary data, slice size, and value axis bounds. // For dynamic updates of data you can implement your own reader, basic reader interface provide neccessary methods for updating separate data regions. // Byte, Short, Float types are supported. The reader will be used for both ray-casting for efficient memory usage. var reader = new ByteIntensityImage3DReader(data, size, size, new OneAxisBounds(data.Min(), data.Max())); // Create volume geometry object (we'll reuse it for both ray-castings for efficient memory usage). var geometry = new BoxVolumeGeometry { Origin = Vector3F.Zero, Size = new Vector3F(1f) }; float ComputeRelativeIsoValue(float relativeValue) => reader.ValueRange.Min + (reader.ValueRange.Max - reader.ValueRange.Min) * relativeValue; VolumeIsoRayCasting CreateRayCasting(float relativeLevel, Color4 color, string name) { return(new VolumeIsoRayCasting { // Set ray-casting data reader. Reader = reader, // Set ray-casting border geometry. Geometry = geometry, // Set value interpolation type. InterpolationType = VolumeInterpolationType.Linear, // Set iso-value. IsoValue = ComputeRelativeIsoValue(relativeLevel), // Set surface color. Color = color, // Set hit-test threshold value. HitTestThreshold = 0.25f, // Set sampling step count. SamplingStepCount = 500, // Set name. Name = name }); } // Create first ray-casting. VolumeIsoRayCasting rayCasting = CreateRayCasting(0.4f, new Color4(Colors.Red, 125), "Volume 1"); // Create second ray-casting. VolumeIsoRayCasting rayCasting2 = CreateRayCasting(0.15f, new Color4(Colors.White, 125), "Volume 2"); // Create internal cube. var cube = new Cube { Size = new Vector3F(0.5f), Position = new Vector3F(0.5f), Color = new Color4(Colors.Green, 150), Name = "Cube" }; // Create border cube. var borderCube = new Cube { Size = new Vector3F(1f), Position = new Vector3F(0.5f), Color = Colors.Red, PresentationType = PrimitivePresentationType.Wireframe, Name = "Bounds" }; // Decrease multisampling level to improve interaction experience. chartControl.Multisampling = Multisampling.Low2X; // Set chart data source. chartControl.DataSource = new RenderData[] { rayCasting, cube, borderCube, rayCasting2 }; }