
I'm curious if I can use Surface Mesh 3D for this. I want to define the ideal 3D points and then shade the measured surface mesh depending on how different the measured is (gradient colors, etc). Is this possible?
Moderator: Arction_LasseP
Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Arction.WPF.LightningChartUltimate;
using Arction.WPF.LightningChartUltimate.Views.View3D;
using Arction.WPF.LightningChartUltimate.Series3D;
namespace WpfSurfaceMesh3DTube
{
public struct RingDataPoint
{
public double X;
public double Y;
public double Z;
public double Value;
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
LightningChartUltimate m_chart;
const int RingCount = 30;
const int PointsInRing = 361; //360 degrees + 1 step to close the ring
const double RingRadius = 10;
RingDataPoint[][] m_rings;
public MainWindow()
{
InitializeComponent();
CreateRings();
CreateChart();
}
void CreateRings()
{
//Create array of rings
m_rings = new RingDataPoint[RingCount][];
Random rand = new Random();
for (int iRing = 0; iRing < RingCount; iRing++)
{
//Create a ring in XZ plane
m_rings[iRing] = new RingDataPoint[PointsInRing];
for (int iPoint = 0; iPoint < PointsInRing; iPoint++)
{
double dAngleRadians = (double)iPoint * Math.PI / 180.0;
m_rings[iRing][iPoint].X = RingRadius * Math.Cos(dAngleRadians);
m_rings[iRing][iPoint].Z = RingRadius * Math.Sin(dAngleRadians);
//Let's use ring index as Y
m_rings[iRing][iPoint].Y = iRing;
//Let's just generate some Value data.
m_rings[iRing][iPoint].Value = 10 + (double)iRing / (double)RingCount * 20.0 * Math.Sin(4 * dAngleRadians)*1.0;
}
}
}
void CreateChart()
{
m_chart = new LightningChartUltimate();
gridMain.Children.Add(m_chart);
m_chart.BeginUpdate();
m_chart.ActiveView = ActiveView.View3D;
//Auxiliary mesh, just to contain a value-range palette that is used for primary mesh coloring
SurfaceMeshSeries3D meshAux = new SurfaceMeshSeries3D(m_chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
meshAux.ContourPalette = CreatePalette(meshAux, 10, 30);
meshAux.ContourLineType = ContourLineType.None;
meshAux.WireframeType = SurfaceWireframeType.None;
m_chart.View3D.SurfaceMeshSeries3D.Add(meshAux);
//Primary mesh to present the tube
SurfaceMeshSeries3D mesh = new SurfaceMeshSeries3D(m_chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
mesh.Title.ShowInLegendBox = false; //don't show this series in the legend box
//mesh.WireframeType = SurfaceWireframeType.WireframeSourcePointColored;
mesh.WireframeType = SurfaceWireframeType.None;
mesh.WireframeLineStyle.Width = 1;
mesh.WireframeLineStyle.Color = Colors.Black;
mesh.ContourLineType = ContourLineType.None;
mesh.Fill = SurfaceFillStyle.FromSurfacePoints;
//mesh.Fill = SurfaceFillStyle.None;
mesh.ColorSaturation = 90;
//Set the rings as mesh data
//Create an array of surface points. First dimension PointsInRing, second dimension RingCount
SurfacePoint[,] meshData = new SurfacePoint[PointsInRing, RingCount];
for (int iRing = 0; iRing < RingCount; iRing++)
{
for (int iPoint = 0; iPoint < PointsInRing; iPoint++)
{
meshData[iPoint, iRing].X = m_rings[iRing][iPoint].X;
meshData[iPoint, iRing].Y = m_rings[iRing][iPoint].Y;
meshData[iPoint, iRing].Z = m_rings[iRing][iPoint].Z;
//Use the auxiliary mesh to convert values into colors
meshAux.ContourPalette.GetColorByValue(m_rings[iRing][iPoint].Value, out meshData[iPoint, iRing].Color);
}
}
mesh.Data = meshData;
m_chart.View3D.SurfaceMeshSeries3D.Add(mesh);
//Set axis ranges
m_chart.View3D.XAxisPrimary3D.SetRange(-RingRadius * 2, RingRadius * 2);
m_chart.View3D.YAxisPrimary3D.SetRange(0, RingCount-1);
m_chart.View3D.ZAxisPrimary3D.SetRange(-RingRadius * 2, RingRadius * 2);
//FromSurfacePoints coloring needs adjusting the lights little bit stronger to show the colors nicely.
mesh.Material.DiffuseColor = Color.FromArgb(255, 200, 200, 200);
m_chart.View3D.SetPredefinedLightingScheme(LightingScheme.DirectionalFromCamera);
m_chart.View3D.Lights[0].DiffuseColor = Color.FromArgb(255, 255, 255, 255);
m_chart.EndUpdate();
}
private ValueRangePalette CreatePalette(SeriesBase3D ownerSeries, double minValue, double maxValue)
{
ValueRangePalette palette = new ValueRangePalette(ownerSeries);
palette.MinValue = minValue;
palette.Steps.Clear();
palette.Steps.Add(new PaletteStep(palette, Colors.Blue, minValue + (maxValue-minValue) * 0.0));
palette.Steps.Add(new PaletteStep(palette, Colors.Yellow, minValue + (maxValue-minValue) * 0.5));
palette.Steps.Add(new PaletteStep(palette, Colors.Red, minValue + (maxValue-minValue) * 1.0));
palette.Type = PaletteType.Gradient;
return palette;
}
}
}