using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using _3DTools;
using DevExpress.Xpf.Charts;
using DevExpress.Xpf.Charts.Native;
namespace zybio.DMP.Client.Commons
{
public class Chart3DContainerEx : Chart3DContainer
{
Viewport3D viewport3D
{
get
{
var prop = typeof(Chart3DContainer).GetField("viewport3D", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (prop != null)
{
return prop.GetValue(this) as Viewport3D;
}
return null;
}
}
Chart3DControlEx chart3dControl;
public Chart3DContainerEx(Chart3DControlEx chart) : base(chart)
{
chart3dControl = chart;
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
viewport3D.Children.Clear();
XYZChartDomainEx domain = CreateDomain(viewport3D);
domain.ValidateSeriesPointsCache();
domain.Render(viewport3D);
}
XYZChartDomainEx CreateDomain(Viewport3D visualContainer)
{
return new XYZChartDomainEx(chart3dControl, new Rect(0, 0, visualContainer.RenderSize.Width, visualContainer.RenderSize.Height), new XYZChartBox(chart3dControl));
}
}
public class XYZChartDomainEx : XYZChartDomain
{
public new Chart3DControlEx Chart { get; }
double PlaneDepthFixed { get { return Chart.PlaneDepthFixed; } }
XYZAxis3DInfo axisXInfo
{
get
{
var field = typeof(XYZChartDomain).GetField("axisXInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return field.GetValue(this) as XYZAxis3DInfo;
}
return null;
}
set
{
var field = typeof(XYZChartDomain).GetField("axisXInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
field.SetValue(this, value);
}
}
}
XYZAxis3DInfo axisZInfo
{
get
{
var field = typeof(XYZChartDomain).GetField("axisZInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return field.GetValue(this) as XYZAxis3DInfo;
}
return null;
}
set
{
var field = typeof(XYZChartDomain).GetField("axisZInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
field.SetValue(this, value);
}
}
}
XYZAxis3DInfo axisYInfo
{
get
{
var field = typeof(XYZChartDomain).GetField("axisYInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return field.GetValue(this) as XYZAxis3DInfo;
}
return null;
}
set
{
var field = typeof(XYZChartDomain).GetField("axisYInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
field.SetValue(this, value);
}
}
}
List<Series3DLabelData> SeriesLabelDataList
{
get
{
var field = typeof(XYZChartDomain).GetField("seriesLabelDataList", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return field.GetValue(this) as List<Series3DLabelData>;
}
return null;
}
set
{
var field = typeof(XYZChartDomain).GetField("seriesLabelDataList", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
field.SetValue(this, value);
}
}
}
public AxesBoxCreator BoxCreator
{
get
{
var field = typeof(XYZChartDomain).GetField("boxCreator", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return field.GetValue(this) as AxesBoxCreator;
}
return null;
}
set
{
var field = typeof(XYZChartDomain).GetField("boxCreator", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
field.SetValue(this, value);
}
}
}
private BoxPlane VisiblePlanes
{
get
{
var field = typeof(XYZChartDomain).GetField("visiblePlanes", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return (BoxPlane)field.GetValue(this);
}
return BoxPlane.Back | BoxPlane.Bottom | BoxPlane.Fore | BoxPlane.Left | BoxPlane.Right | BoxPlane.Top;
}
set
{
var field = typeof(XYZChartDomain).GetField("visiblePlanes", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
field.SetValue(this, value);
}
}
}
public XYZChartDomainEx(Chart3DControlEx chart, Rect viewport, XYZChartBox chartBox)
: base(chart, viewport, chartBox)
{
Chart = chart;
if (Chart.AxisMode == EnAxisMode.Cube)
{
BoxCreator = new CubeXYZAxesBoxCreator(this, chart.Cache, DiagramBox);
}
else
{
BoxCreator = new XYZAxesBoxCreator(this, chart.Cache, DiagramBox, VisiblePlanes);
}
}
public new void Render(Viewport3D visualContainer)
{
ModelVisual3D modelVisual = new ModelVisual3D();
Model3DGroup modelHolder = new Model3DGroup();
modelHolder.Transform = ModelTransform;
Render3DContent(modelHolder, visualContainer);
Model3DGroup group = new Model3DGroup();
group.Children.Add(CreateLighting());
group.Children.Add(modelHolder);
modelVisual.Content = group;
visualContainer.Camera = Camera;
visualContainer.Children.Add(modelVisual);
visualContainer.Clip = new RectangleGeometry(Viewport);
}
void Render3DContent(Model3DGroup modelHolder, Viewport3D visualContainer)
{
Crosshair3DHolder crosshairHolder = CreateCrosshair3DHolder();
if (Chart.AxisMode == EnAxisMode.Cube)
{
((CubeXYZAxesBoxCreator)BoxCreator).CreateDiagramModel(modelHolder, visualContainer);
}
else
{
BoxCreator.CreateDiagramModel(modelHolder);
}
CreateSeriesModel(modelHolder);
BoxCreator.CreateAxesLabels(modelHolder);
CreateSeriesLabelsModel(modelHolder);
CreateCrosshairModel(modelHolder, crosshairHolder);
Chart.Cache.ProjectionContainer.ApplyProjectionPosition(VisiblePlanes, DiagramBox);
}
Crosshair3DHolder CreateCrosshair3DHolder()
{
if (Chart.Cache.Crosshair3DHolder == null)
Chart.Cache.Crosshair3DHolder = new Crosshair3DHolder();
Chart.Cache.Crosshair3DHolder.AxisXInfo = axisXInfo;
Chart.Cache.Crosshair3DHolder.AxisZInfo = axisZInfo;
Chart.Cache.Crosshair3DHolder.AxisYInfo = axisYInfo;
Chart.Cache.Crosshair3DHolder.ScaleFactor = CrosshairScaleFactor;
return Chart.Cache.Crosshair3DHolder;
}
void CreateSeriesModel(Model3DGroup modelHolder)
{
if (Chart.Cache.SeriesModel == null)
{
var method = typeof(XYZChartDomain).GetMethod("CreateSeriesModel", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.ExactBinding);
var obj = method.Invoke(this, new object[] { Chart.Cache.ProjectionContainer });
if (obj is Model3D seriesModel)
{
Chart.Cache.SeriesModel = seriesModel;
}
}
//Chart.Cache.SeriesModel = CreateSeriesModel();
modelHolder.Children.Add(Chart.Cache.SeriesModel);
}
void CreateSeriesLabelsModel(Model3DGroup modelHolder)
{
List<LabelModelContainer> labelContainers = new List<LabelModelContainer>();
foreach (Series3DLabelData seriesData in SeriesLabelDataList)
seriesData.CreateLabelsModel(this, modelHolder, labelContainers, Chart.ViewController.GetRefinedSeries(seriesData.Series));
foreach (LabelModelContainer modelContainer in labelContainers)
modelHolder.Children.Add(modelContainer.Model);
}
void CreateCrosshairModel(Model3DGroup modelHolder, Crosshair3DHolder crosshairHolder)
{
Model3D model = CreateCrosshairModel();
crosshairHolder.CrosshairModel = model;
modelHolder.Children.Add(model);
}
Model3D CreateCrosshairModel()
{
Model3DGroup marker = new Model3DGroup();
if (Chart.ActualCrosshairOptions.ShowMarker)
{
var markerModel = Chart.ActualCrosshairOptions.MarkerModel ?? CreateDefaultMarkerModel();
marker.Children.Add(markerModel);
}
marker.Transform = new ScaleTransform3D(0, 0, 0);
AssignTagObjectToMeshModel(marker, new CrosshairMarker3D());
return marker;
}
Model3D CreateDefaultMarkerModel()
{
SphereModelCalculator sphereModelCalculator = new SphereModelCalculator(8);
GeometryInfo geometry = sphereModelCalculator.GetGeometry(1);
MeshGeometry3D marker1 = new MeshGeometry3D() { Positions = geometry.Points, TriangleIndices = geometry.TriangleIndices };
MaterialGroup material = new MaterialGroup();
material.Children.Add(new DiffuseMaterial(new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xDE, 0x39, 0xCD))));
material.Children.Add(new SpecularMaterial(new SolidColorBrush(System.Windows.Media.Color.FromRgb(229, 229, 229)), 20.0));
return new GeometryModel3D(marker1, material);
}
void AssignTagObjectToMeshModel(Model3D model, object tag)
{
Model3DGroup model3DGroup = model as Model3DGroup;
if (model3DGroup != null)
{
foreach (Model3D child in model3DGroup.Children)
AssignTagObjectToMeshModel(child, tag);
}
else
{
GeometryModel3D geometryModel3D = model as GeometryModel3D;
if (geometryModel3D != null)
{
MeshGeometry3D meshGeometry3D = geometryModel3D.Geometry as MeshGeometry3D;
if (meshGeometry3D != null)
meshGeometry3D.SetValue(FrameworkElement.TagProperty, tag);
}
}
}
}
public class Chart3DControlEx : DevExpress.Xpf.Charts.Chart3DControl
{
public Chart3DControlEx() : base()
{
var diagramContainer = new Chart3DContainerEx(this);
var prop = typeof(DevExpress.Xpf.Charts.Chart3DControl).GetField("diagramContainer", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
prop.SetValue(this, diagramContainer);
}
public new ViewController ViewController
{
get
{
var field = typeof(DevExpress.Xpf.Charts.Chart3DControl).GetField("viewController", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return field.GetValue(this) as ViewController;
}
return null;
}
}
public XYZChartCache Cache
{
get
{
var field = typeof(DevExpress.Xpf.Charts.Chart3DControl).GetProperty("Cache", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.ExactBinding);
if (field != null)
{
return field.GetValue(this) as XYZChartCache;
}
return null;
}
}
public Crosshair3DOptions ActualCrosshairOptions
{
get { return CrosshairOptions ?? new Crosshair3DOptions(); }
}
public EnAxisMode AxisMode { get; set; } = EnAxisMode.Cube;
}
public enum EnAxisMode
{
Panel = 0,
Cube = 1
}
/// <summary>
/// 顯示立方體座標
/// </summary>
public class CubeXYZAxesBoxCreator : XYZAxesBoxCreator
{
IDomainBox3D _domain;
XYZChartCache _cache;
Diagram3DBox _diagramBox;
ScreenSpaceLines3D AxisX1 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisX2 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisX3 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisX4 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisY1 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisY2 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisY3 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisY4 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisZ1 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisZ2 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisZ3 { get; set; } = new ScreenSpaceLines3D();
ScreenSpaceLines3D AxisZ4 { get; set; } = new ScreenSpaceLines3D();
public CubeXYZAxesBoxCreator(IDomainBox3D domain, XYZChartCache cache, Diagram3DBox diagramBox)
: base(domain, cache, diagramBox, BoxPlane.None)
{
_domain = domain;
_cache = cache;
_diagramBox = diagramBox;
}
public void CreateDiagramModel(Model3DGroup modelHolder, Viewport3D visualContainer)
{
CalcDiagramPlanes(modelHolder.Transform);
visualContainer.Children.Add(AxisX1);
visualContainer.Children.Add(AxisX2);
visualContainer.Children.Add(AxisX3);
visualContainer.Children.Add(AxisX4);
visualContainer.Children.Add(AxisY1);
visualContainer.Children.Add(AxisY2);
visualContainer.Children.Add(AxisY3);
visualContainer.Children.Add(AxisY4);
visualContainer.Children.Add(AxisZ1);
visualContainer.Children.Add(AxisZ2);
visualContainer.Children.Add(AxisZ3);
visualContainer.Children.Add(AxisZ4);
}
void CalcDiagramPlanes(Transform3D trans)
{
double correction = Diagram3DBox.DiagramPlanesCorrection;
Point3D zeroPoint = new Point3D(-correction, -correction, -correction);
zeroPoint = new Point3D(zeroPoint.X, zeroPoint.Y, zeroPoint.Z);
correction *= 2;
double width = _diagramBox.InnerWidth + correction;
double height = _diagramBox.InnerHeight + correction;
double depth = _diagramBox.InnerDepth + correction;
double xMin = zeroPoint.X, yMin = zeroPoint.Y, zMin = zeroPoint.Z;
double xMax = width, yMax = height, zMax = depth;
//座標軸顏色,採取Chart的DomainBrush屬性
var brush = ((XYZChartDomainEx)_domain).Chart.DomainBrush;
System.Windows.Media.Color axisColor = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(brush.ToString());
AxisX1.Color = axisColor;
AxisX1.Transform = trans;
AxisX1.Points.Add(new Point3D(xMin, yMin, zMin));
AxisX1.Points.Add(new Point3D(xMax, yMin, zMin));
AxisX2.Color = axisColor;
AxisX2.Transform = trans;
AxisX2.Points.Add(new Point3D(xMin, yMin, zMax));
AxisX2.Points.Add(new Point3D(xMax, yMin, zMax));
AxisX3.Color = axisColor;
AxisX3.Transform = trans;
AxisX3.Points.Add(new Point3D(xMin, yMax, zMax));
AxisX3.Points.Add(new Point3D(xMax, yMax, zMax));
AxisX4.Color = axisColor;
AxisX4.Transform = trans;
AxisX4.Points.Add(new Point3D(xMin, yMax, zMin));
AxisX4.Points.Add(new Point3D(xMax, yMax, zMin));
AxisY1.Color = axisColor;
AxisY1.Transform = trans;
AxisY1.Points.Add(new Point3D(xMin, yMin, zMin));
AxisY1.Points.Add(new Point3D(xMin, yMax, zMin));
AxisY2.Color = axisColor;
AxisY2.Transform = trans;
AxisY2.Points.Add(new Point3D(xMax, yMin, zMin));
AxisY2.Points.Add(new Point3D(xMax, yMax, zMin));
AxisY3.Color = axisColor;
AxisY3.Transform = trans;
AxisY3.Points.Add(new Point3D(xMax, yMin, zMax));
AxisY3.Points.Add(new Point3D(xMax, yMax, zMax));
AxisY4.Color = axisColor;
AxisY4.Transform = trans;
AxisY4.Points.Add(new Point3D(xMin, yMin, zMax));
AxisY4.Points.Add(new Point3D(xMin, yMax, zMax));
AxisZ1.Color = axisColor;
AxisZ1.Transform = trans;
AxisZ1.Points.Add(new Point3D(xMin, yMin, zMin));
AxisZ1.Points.Add(new Point3D(xMin, yMin, zMax));
AxisZ2.Color = axisColor;
AxisZ2.Transform = trans;
AxisZ2.Points.Add(new Point3D(xMax, yMin, zMin));
AxisZ2.Points.Add(new Point3D(xMax, yMin, zMax));
AxisZ3.Color = axisColor;
AxisZ3.Transform = trans;
AxisZ3.Points.Add(new Point3D(xMax, yMax, zMin));
AxisZ3.Points.Add(new Point3D(xMax, yMax, zMax));
AxisZ4.Color = axisColor;
AxisZ4.Transform = trans;
AxisZ4.Points.Add(new Point3D(xMin, yMax, zMin));
AxisZ4.Points.Add(new Point3D(xMin, yMax, zMax));
}
}
}
DevExpress_Chart3DEX
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.