From 20eae961e90303e378f70392e1003361da67db95 Mon Sep 17 00:00:00 2001 From: Tongg Date: Fri, 13 Dec 2024 14:38:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=203D=E6=A8=A1=E5=9E=8B=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E8=A1=A5=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Language/zh_CN.xaml | 3 + Views/UserControl/Viewport3D.xaml | 29 +++-- Views/UserControl/Viewport3D.xaml.cs | 106 +++++++++++++++++- .../ViewportData/Helper/ViewportHelperPro.cs | 15 +-- .../ViewportData/Helper/ViewportManager.cs | 7 ++ .../UserControl/ViewportData/ViewportData.cs | 25 +++++ 6 files changed, 169 insertions(+), 16 deletions(-) diff --git a/Language/zh_CN.xaml b/Language/zh_CN.xaml index a974480..62e8c3e 100644 --- a/Language/zh_CN.xaml +++ b/Language/zh_CN.xaml @@ -114,4 +114,7 @@ 显示选择面的同类面 显示瑕疵面 显示正方向标识 + 保存成功 + 保存失败 + 选择路径 \ No newline at end of file diff --git a/Views/UserControl/Viewport3D.xaml b/Views/UserControl/Viewport3D.xaml index 0a52865..628695b 100644 --- a/Views/UserControl/Viewport3D.xaml +++ b/Views/UserControl/Viewport3D.xaml @@ -22,6 +22,7 @@ + + - - diff --git a/Views/UserControl/Viewport3D.xaml.cs b/Views/UserControl/Viewport3D.xaml.cs index c43d73e..01028a7 100644 --- a/Views/UserControl/Viewport3D.xaml.cs +++ b/Views/UserControl/Viewport3D.xaml.cs @@ -5,7 +5,9 @@ using System.Windows.Input; using System.Windows.Media.Media3D; using HandyControl.Controls; using HelixToolkit.Wpf.SharpDX; +using Microsoft.Win32; using SharpDX; +using SparkClient.Model.Helper; using SparkClient.Views.UserControl.ViewportData.Entity; using SparkClient.Views.UserControl.ViewportData.Enum; using SparkClient.Views.UserControl.ViewportData.Helper; @@ -134,6 +136,46 @@ public partial class Viewport3D } camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); } + /// + /// 顶部按钮 - 功能 + /// + /// + /// + /// + private async void BtnFunction_OnClick(object sender, RoutedEventArgs e) + { + var directionName = ((Button)sender).Name.ToString(); + var directionValue = (int) TbCustomizeRevolve.Value; + + + + switch (directionName) + { + case "BtnFcuntion1View": + //测 + + break; + case "BtnFcuntion2View": + //顶 + + break; + case "BtnFcuntion3View": + //低 + var center = ViewportManager.ModelBounds.Center; + var maxDimension = ViewportManager.ModelBounds.Size.Length(); + var distance = maxDimension *1.2; // 调整相机到模型的距离,保证视野范围内 + var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; + camera.Position = new Point3D(center.X, center.Y, center.Z + distance); // 从前面看,Z轴正方向 + camera.UpDirection = new Vector3D(0, -1, 0); + camera.LookDirection = new Vector3D(center.X - camera.Position.X, center.Y - camera.Position.Y, center.Z - camera.Position.Z); + ViewportHelperPro.RotateModel(new Vector3D(0,-1,0)); + await Task.Delay(5000); + ViewportHelperPro.RotateModel(new Vector3D(-1,0,0)); + break; + + } + + } /// /// 按钮调整相机方向[底部按钮] @@ -143,23 +185,56 @@ public partial class Viewport3D private void BtnDirection_OnClick(object sender, RoutedEventArgs e) { var directionName = ((Button)sender).Name.ToString(); - var directionValue = (int) TbCustomizeRevolve.Value; + var directionValue = (int)TbCustomizeRevolve.Value; // 旋转角度(单位:度) + + // 获取当前相机和模型中心 + var camera = Viewport3Dx.Camera as HelixToolkit.Wpf.SharpDX.PerspectiveCamera; + if (camera == null) return; + + var modelCenter = ViewportManager.CenterVector; // 模型中心 + var currentPosition = camera.Position; + + // 将相机位置转换为极坐标 + var dx = currentPosition.X - modelCenter.X; + var dy = currentPosition.Y - modelCenter.Y; + var dz = currentPosition.Z - modelCenter.Z; + + var radius = Math.Sqrt(dx * dx + dy * dy + dz * dz); // 相机与模型中心的距离 + var azimuth = Math.Atan2(dz, dx) * 180.0 / Math.PI; // 方位角(水平平面上的角度) + var elevation = Math.Atan2(dy, Math.Sqrt(dx * dx + dz * dz)) * 180.0 / Math.PI; // 仰角(垂直方向的角度) switch (directionName) { case "BtnTop": //上 + elevation += directionValue; break; case "BtnBottom": //下 + elevation -= directionValue; break; case "BtnLeft": //左 + azimuth -= directionValue; break; case "BtnRight": //右 + azimuth += directionValue; break; } + // 限制仰角范围在 -89.9 到 89.9 度,避免超出范围导致位置错误 + elevation = Math.Clamp(elevation, -89.9, 89.9); + azimuth = (azimuth + 360) % 360; // 方位角在 0 到 360 范围内循环 + + // 将极坐标转换回直角坐标 + var newX = modelCenter.X + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Cos(azimuth * Math.PI / 180.0); + var newY = modelCenter.Y + radius * Math.Sin(elevation * Math.PI / 180.0); + var newZ = modelCenter.Z + radius * Math.Cos(elevation * Math.PI / 180.0) * Math.Sin(azimuth * Math.PI / 180.0); + + // 更新相机位置和视角 + camera.Position = new Point3D(newX, newY, newZ); + camera.LookDirection = new Vector3D(modelCenter.X - newX, modelCenter.Y - newY, modelCenter.Z - newZ); + camera.UpDirection = new Vector3D(0, 1, 0); // 保持 Y 轴为上方向 } @@ -247,11 +322,38 @@ public partial class Viewport3D break; case "ViewportRightMenuSaveViewToPNG": //保存图片 + var saveFileDialog = new SaveFileDialog + { + Filter = "PNG Files (*.png)|*.png", + Title = MultilingualHelper.getString("ViewportSelectPath"), + DefaultExt = "png" + }; + + if (saveFileDialog.ShowDialog() != true) + { + return; // 用户取消 + } + + string filePath = saveFileDialog.FileName; + + try + { + ViewportHelperPro.SaveViewportAsImage(Viewport3Dx, filePath); + System.Windows.MessageBox.Show(MultilingualHelper.getString("ViewportSaveSucceed")); + } + catch (Exception ex) + { + System.Windows.MessageBox.Show($"{MultilingualHelper.getString("ViewportSaveFail")}:{ex.Message}", MultilingualHelper.getString("ViewportSaveFail"), System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); + } + + break; } } #endregion - + // 保存成功 + // 保存失败 + // 选择路径 #region 页面隐式交互 diff --git a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs index 3d59451..e2db11a 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportHelperPro.cs @@ -113,6 +113,8 @@ public class ViewportHelperPro /// public static void ExportModelsToStl(Viewport3DX viewport, string filePath) { + if (viewport == null) + viewport = ViewportManager.GetViewport3D(); // 打开文件写入流 using (StreamWriter writer = new StreamWriter(filePath)) { @@ -400,11 +402,11 @@ public class ViewportHelperPro /// 中心 /// 是否包含线 /// 旋转时间 秒 - public static void RotateModel(Vector3D axis, bool hasLine = true, int speed = 5) + public static void RotateModel(Vector3D axis, bool hasLine = true, int speed = 5, int to = 360) { // 设置旋转的中心点和旋转轴 var rotateTransform = new RotateTransform3D(); - var rotation = new AxisAngleRotation3D(axis, 0); // 初始角度为 0 + var rotation = new AxisAngleRotation3D(axis, 0); rotateTransform.Rotation = rotation; rotateTransform.CenterX = ViewportManager.CenterVector.X; rotateTransform.CenterY = ViewportManager.CenterVector.Y; @@ -414,11 +416,13 @@ public class ViewportHelperPro ViewportManager.MainModel3D.Transform = rotateTransform; if(hasLine) ViewportManager.MainModelLines.ForEach(e => e.Transform = rotateTransform); + + double currentAngle = rotation.Angle; // 创建旋转动画 var rotateAnimation = new DoubleAnimation { - From = 0, - To = 360, + From = currentAngle, + To = to + currentAngle, Duration = new Duration(TimeSpan.FromSeconds(speed)), FillBehavior = FillBehavior.HoldEnd }; @@ -427,9 +431,6 @@ public class ViewportHelperPro rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, rotateAnimation); } - - - /// /// 在场景中添加文字 /// diff --git a/Views/UserControl/ViewportData/Helper/ViewportManager.cs b/Views/UserControl/ViewportData/Helper/ViewportManager.cs index 371044d..672d5ae 100644 --- a/Views/UserControl/ViewportData/Helper/ViewportManager.cs +++ b/Views/UserControl/ViewportData/Helper/ViewportManager.cs @@ -55,6 +55,13 @@ public class ViewportManager if (_viewport == null) _viewport = viewport3D; + } + public static Viewport3DX GetViewport3D() + { + if (_viewport == null) + throw new Exception("Viewport is not set"); + return _viewport; + } #region 模型选中交互管理 //是否双击选中 diff --git a/Views/UserControl/ViewportData/ViewportData.cs b/Views/UserControl/ViewportData/ViewportData.cs index c0f6147..54a3448 100644 --- a/Views/UserControl/ViewportData/ViewportData.cs +++ b/Views/UserControl/ViewportData/ViewportData.cs @@ -140,4 +140,29 @@ public class ViewportData } + public bool SaveAsToStlFile(string filename) + { + try + { + ViewportHelperPro.ExportModelsToStl(null, filename); + return true; + } + catch + { + return false; + } + } + + public bool SaveAsToVedioFile(string filename) + { + try + { + ViewportHelperPro.ExportModelsToStl(null, filename); + return true; + } + catch + { + return false; + } + } } \ No newline at end of file