You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
8.1 KiB
222 lines
8.1 KiB
using System.Text.Json.Nodes; |
|
using System.Windows; |
|
using System.Windows.Controls; |
|
using System.Windows.Input; |
|
using HandyControl.Controls; |
|
using HelixToolkit.Wpf.SharpDX; |
|
using SharpDX; |
|
using SparkClient.Views.UserControl.ViewportData.Entity; |
|
using SparkClient.Views.UserControl.ViewportData.Enum; |
|
using SparkClient.Views.UserControl.ViewportData.Helper; |
|
|
|
namespace SparkClient.Views.UserControl; |
|
|
|
public partial class Viewport3D |
|
{ |
|
// 注册一个依赖属性,类型是 Viewport3DData |
|
public static readonly DependencyProperty ViewportDataProperty = |
|
DependencyProperty.Register( |
|
nameof(ViewportData), |
|
typeof(ViewportData.ViewportData), |
|
typeof(Viewport3D), |
|
new PropertyMetadata(null, OnViewportDataChanged)); |
|
|
|
// 公开的 CLR 属性包装器 |
|
public ViewportData.ViewportData ViewportData |
|
{ |
|
get => (ViewportData.ViewportData)GetValue(ViewportDataProperty); |
|
set => SetValue(ViewportDataProperty, value); |
|
} |
|
|
|
// 当 ViewportData 属性发生变化时触发 |
|
private static void OnViewportDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
|
{ |
|
if (d is Viewport3D control && e.NewValue is ViewportData.ViewportData data) |
|
{ |
|
control.Initialize(data); |
|
} |
|
} |
|
|
|
|
|
private void Initialize(ViewportData.ViewportData vpData) |
|
{ |
|
// 根据 Viewport3DData 的内容初始化控件 |
|
// 例如:设置控件内部的某些属性,渲染 3D 模型等 |
|
if (!string.IsNullOrEmpty(vpData.DiamondData)) |
|
{ |
|
JsonNode? json = null; |
|
try |
|
{ |
|
json = JsonNode.Parse(vpData.DiamondData); |
|
} |
|
catch |
|
{ |
|
throw new Exception("DiamondData is invalid"); |
|
} |
|
|
|
if(json == null) throw new Exception("DiamondData is invalid"); |
|
|
|
try |
|
{ |
|
List<Viewport3DTriangleEntity> facets = new List<Viewport3DTriangleEntity>(); |
|
if (json.AsObject()["facets"] != null) |
|
{ |
|
JsonArray jsonArray = json.AsObject()["facets"].AsArray(); |
|
foreach (var item in jsonArray) |
|
{ |
|
var value = CommonHelper.CreateByJsonStr(item.ToString()); |
|
facets.Add(value); |
|
} |
|
} |
|
else |
|
{ |
|
throw new Exception("facets is invalid"); |
|
} |
|
|
|
if (json.AsObject()["positive_direction"] != null) |
|
{ |
|
JsonObject positive = json.AsObject()["positive_direction"].AsObject(); |
|
ViewportManager.PositiveDirection.X = float.Parse(positive["x"]?.ToString() ?? "1.0"); |
|
ViewportManager.PositiveDirection.Y = float.Parse(positive["z"]?.ToString() ?? "0"); |
|
ViewportManager.PositiveDirection.Z = float.Parse(positive["y"]?.ToString() ?? "0"); |
|
} |
|
else |
|
{ |
|
ViewportManager.PositiveDirection.X = 1.0f; |
|
ViewportManager.PositiveDirection.Y = 0f; |
|
ViewportManager.PositiveDirection.Z = 0; |
|
} |
|
|
|
var midZ = facets.SelectMany(e => new[] { e.Point1.X, e.Point2.X, e.Point3.X }).OrderBy(z => Math.Abs(z)) |
|
.First(); |
|
List<Viewport3DTriangleEntity> facetsFinal = new List<Viewport3DTriangleEntity>(); |
|
foreach (var item in facets) |
|
{ |
|
var data = ViewportHelperPro.VectorClockwiseSort(new List<Vector3> |
|
{ item.Point1, item.Point2, item.Point3 }); |
|
|
|
if (item.PlaneType == PlaneType.StarFacet || item.PlaneType == PlaneType.UpperGirdleFacet || |
|
item.PlaneType == PlaneType.UpperMainFacet || item.PlaneType == PlaneType.TableFacet) |
|
{ |
|
item.Point1 = data[0]; |
|
item.Point2 = data[1]; |
|
item.Point3 = data[2]; |
|
} |
|
else if (item.PlaneType == PlaneType.Girdle) |
|
{ |
|
var center = ViewportHelperPro.GetCentroid(data); |
|
data.Sort((v1, v2) => |
|
{ |
|
double angle1 = Math.Atan2(v1.Y - center.Y, v1.X - center.X); |
|
double angle2 = Math.Atan2(v2.Y - center.Y, v2.X - center.X); |
|
return angle1.CompareTo(angle2); |
|
}); |
|
if (center.Z >= midZ) |
|
{ |
|
|
|
item.Point1 = data[0]; |
|
item.Point2 = data[1]; |
|
item.Point3 = data[2]; |
|
} |
|
else |
|
{ |
|
item.Point1 = data[2]; |
|
item.Point2 = data[1]; |
|
item.Point3 = data[0]; |
|
|
|
} |
|
} |
|
else |
|
{ |
|
item.Point1 = data[2]; |
|
item.Point2 = data[1]; |
|
item.Point3 = data[0]; |
|
} |
|
|
|
item.TriangleCode = CommonHelper.GenerateTriangleCode(item.Point1, item.Point2, item.Point3); |
|
facetsFinal.Add(item); |
|
} |
|
|
|
// ViewportManager.ViewportTriangle.AddRange(facetsFinal); |
|
ViewportManager.LoadModelByEntities(facetsFinal); |
|
} |
|
catch (Exception ex) |
|
{ |
|
throw new Exception(ex.Message); |
|
} |
|
} |
|
} |
|
|
|
public Viewport3D() |
|
{ |
|
InitializeComponent(); |
|
DataContext = this; |
|
this.Viewport3Dx.EffectsManager = new DefaultEffectsManager(); |
|
ViewportManager.SetViewport3D(Viewport3Dx); |
|
} |
|
|
|
#region 菜单事件绑定 |
|
private void MenuItem_OnChecked(object sender, RoutedEventArgs e) |
|
{ |
|
Growl.InfoGlobal("Viewport is checked" + e.OriginalSource); |
|
} |
|
|
|
private void MenuItem_OnUnchecked(object sender, RoutedEventArgs e) |
|
{ |
|
Growl.InfoGlobal("Viewport is Unchecked" + e.OriginalSource); |
|
} |
|
private void MenuItem_OnClick(object sender, RoutedEventArgs e) |
|
{ |
|
|
|
} |
|
#endregion |
|
|
|
#region 页面隐式交互 |
|
private System.Windows.Point _mouseDownPosition; |
|
private bool _isDragging = false; |
|
private void UIElement_OnPreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e) |
|
{ |
|
if (_isDragging) |
|
{ |
|
// 如果发生拖动,不显示菜单 |
|
_isDragging = false; // 重置拖动状态 |
|
MainBorder.ContextMenu.Visibility = Visibility.Hidden; |
|
MainBorder.ContextMenu.IsOpen = false; |
|
return; |
|
} |
|
MainBorder.ContextMenu.Visibility = Visibility.Visible; |
|
// 未拖动时,显示右键菜单 |
|
MainBorder.ContextMenu.IsOpen = true; |
|
// e.Handled = true; // 阻止事件继续传播 |
|
} |
|
|
|
private void UIElement_OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) |
|
{ |
|
_mouseDownPosition = e.GetPosition(Viewport3Dx); |
|
_isDragging = false; // 重置拖动状态 |
|
|
|
} |
|
#endregion |
|
|
|
private void Viewport3D_OnLoaded(object sender, RoutedEventArgs e) |
|
{ |
|
//ViewportData.LoadData(); |
|
ViewportManager.LoadModelByEntities(new List<Viewport3DTriangleEntity>()); |
|
} |
|
|
|
private void Viewport3Dx_OnPreviewMouseMove(object sender, MouseEventArgs e) |
|
{ |
|
if (e.RightButton == MouseButtonState.Pressed) |
|
{ |
|
// 计算鼠标移动距离 |
|
var currentPosition = e.GetPosition(Viewport3Dx); |
|
var distance = (currentPosition - _mouseDownPosition).Length; |
|
|
|
// 判断是否达到拖动的阈值 |
|
if (distance > 5) // 阈值可根据需要调整 |
|
{ |
|
_isDragging = true; // 标记为拖动 |
|
} |
|
} |
|
} |
|
} |