
环境 VS2022.Net Framework4.8HelixToolkit3.12这是一个 使用TubeVisual3D构建的3D型材的主体结构一、HelixToolkit包安装通过NuGet包管理器搜索并安装HelixToolkit相关的包。二、结构组成主螺旋管道使用TubeVisual3D构建形成型材的主体结构节点球体在关键路径点使用SphereVisual3D增强视觉效果交叉支撑六边形支撑结构增加模型的工程感底座六边形底座提供稳定的视觉基础三、功能特性旋转功能手动点击按钮旋转30度或勾选自动旋转持续旋转导出模型支持多种格式3DS、STL、OBJ等自适应视图一键调整视图到最佳显示位置交互操作左键旋转、右键平移、滚轮缩放四、MainWindow.xamlWindow x:ClassWpfA_TubeModel.MainWindow xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:xhttp://schemas.microsoft.com/winfx/2006/xaml xmlns:dhttp://schemas.microsoft.com/expression/blend/2008 xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006 xmlns:localclr-namespace:WpfA_TubeModel mc:Ignorabled xmlns:helixhttp://helix-toolkit.org/wpf Title3D型材模型 Height600 Width800 Grid Grid.RowDefinitions RowDefinition HeightAuto/ RowDefinition Height*/ RowDefinition HeightAuto/ /Grid.RowDefinitions !-- 顶部工具栏 -- StackPanel Grid.Row0 OrientationHorizontal Margin5 Button x:NameBtnRotate Content旋转模型 ClickBtnRotate_Click Margin5 Width80/ Button x:NameBtnExport Content导出模型 ClickBtnExport_Click Margin5 Width80/ Button x:NameBtnZoomExtents Content自适应视图 ClickBtnZoomExtents_Click Margin5 Width80/ CheckBox x:NameChkAutoRotate Content自动旋转 Margin5/ /StackPanel !-- 3D视图 -- helix:HelixViewport3D x:NameViewport3D Grid.Row1 ShowCoordinateSystemTrue PanGestureRightClick RotateGestureLeftClick ZoomExtentsWhenLoadedTrue ShowCameraInfoTrue ZoomAroundMouseDownPointTrue RotateAroundMouseDownPointTrue !-- 默认相机设置 -- helix:HelixViewport3D.DefaultCamera PerspectiveCamera LookDirection-5 -5 5 UpDirection0 0 1 FieldOfView45 NearPlaneDistance1/ /helix:HelixViewport3D.DefaultCamera !-- 光源 -- helix:SunLight/ !-- 模型容器 -- ModelVisual3D x:NameModelContainer/ !-- 网格线 -- helix:GridLinesVisual3D Width10 Length10 MajorDistance1 MinorDistance0.2 Thickness0.01/ /helix:HelixViewport3D !-- 底部状态栏 -- StatusBar Grid.Row2 StatusBarItem TextBlock Text就绪 | 左键旋转 | 右键平移 | 滚轮缩放/ /StatusBarItem /StatusBar /Grid /Window五、MainWindow.xaml.csusing HelixToolkit.Wpf; using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Media.Media3D; using Microsoft.Win32; using System.Xml.Serialization; namespace WpfA_TubeModel { /// summary /// MainWindow.xaml 的交互逻辑 /// /summary public partial class MainWindow : Window { private Model3DGroup _modelGroup; private System.Windows.Threading.DispatcherTimer _rotationTimer; private double _rotationAngle 0; private const double ROTATION_SPEED 0.5; // 旋转速度度/帧 public MainWindow() { InitializeComponent(); Loaded MainWindow_Loaded; } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { // 构建3D型材模型 BuildProfileModel(); // 设置自动旋转定时器 SetupRotationTimer(); } /// summary /// 构建3D型材模型 - 使用SphereVisual3D和TubeVisual3D /// /summary private void BuildProfileModel() { _modelGroup new Model3DGroup(); // 1. 构建主路径 - 螺旋型材 var pathPoints GenerateHelixPath(3.0, 1.5, 6, 20); // 2. 创建管道型材主体 var tube new TubeVisual3D { Path pathPoints, Diameter 0.3, ThetaDiv 24, Fill new SolidColorBrush(Colors.DodgerBlue), Material MaterialHelper.CreateMaterial(new SolidColorBrush(Colors.DodgerBlue)) }; _modelGroup.Children.Add(tube.Content); // 3. 在路径关键节点添加球体节点强化效果 var spherePositions new[] { new Point3D(0, 0, 0), new Point3D(3, 0, 0), new Point3D(4.5, 2.598, 0), new Point3D(3, 5.196, 0), new Point3D(0, 5.196, 0), new Point3D(-1.5, 2.598, 0), // 添加一些Z轴方向的节点 new Point3D(1.5, 2.598, 2), new Point3D(1.5, 2.598, 4), new Point3D(3, 0, 3), }; foreach (var pos in spherePositions) { // 只添加在路径上的节点通过路径点检测 if (IsPointOnPath(pos, pathPoints, 0.5)) { var sphere new SphereVisual3D { Center pos, Radius 0.25, Fill new SolidColorBrush(Colors.Orange), Material MaterialHelper.CreateMaterial(new SolidColorBrush(Colors.Orange)) }; _modelGroup.Children.Add(sphere.Content); } } // 4. 添加一些额外的装饰管交叉支撑结构 AddCrossSupports(); // 5. 添加底座 AddBasePlate(); // 将模型添加到视口 ModelContainer.Content _modelGroup; } /// summary /// 生成螺旋路径点 /// /summary private Point3DCollection GenerateHelixPath(double radius, double pitch, double turns, int pointsPerTurn) { var path new Point3DCollection(); int totalPoints (int)(turns * pointsPerTurn) 1; for (int i 0; i totalPoints; i) { double t (double)i / pointsPerTurn; double angle t * 2 * Math.PI; double x radius * Math.Cos(angle); double y radius * Math.Sin(angle); double z t * pitch; path.Add(new Point3D(x, y, z)); } return path; } /// summary /// 检查点是否在路径上用于节点定位 /// /summary private bool IsPointOnPath(Point3D point, Point3DCollection path, double tolerance) { foreach (var p in path) { double dx p.X - point.X; double dy p.Y - point.Y; double dz p.Z - point.Z; if (Math.Sqrt(dx * dx dy * dy dz * dz) tolerance) return true; } return false; } /// summary /// 添加交叉支撑结构 /// /summary private void AddCrossSupports() { // 创建6个支撑管形成六边形结构 double radius 3.0; double height 2.0; for (int i 0; i 6; i) { double angle1 i * Math.PI / 3; double angle2 (i 1) * Math.PI / 3; // 底部节点 var p1 new Point3D(radius * Math.Cos(angle1), radius * Math.Sin(angle1), 0); var p2 new Point3D(radius * Math.Cos(angle2), radius * Math.Sin(angle2), 0); // 顶部节点高度偏移 var p3 new Point3D(radius * Math.Cos(angle1), radius * Math.Sin(angle1), height); var p4 new Point3D(radius * Math.Cos(angle2), radius * Math.Sin(angle2), height); // 底部支撑管 var bottomTube new TubeVisual3D { Path new Point3DCollection { p1, p2 }, Diameter 0.12, ThetaDiv 16, Fill new SolidColorBrush(Colors.LightGray), Material MaterialHelper.CreateMaterial(new SolidColorBrush(Colors.LightGray)) }; _modelGroup.Children.Add(bottomTube.Content); // 顶部支撑管 var topTube new TubeVisual3D { Path new Point3DCollection { p3, p4 }, Diameter 0.12, ThetaDiv 16, Fill new SolidColorBrush(Colors.LightGray), Material MaterialHelper.CreateMaterial(new SolidColorBrush(Colors.LightGray)) }; _modelGroup.Children.Add(topTube.Content); // 垂直支撑管 var verticalTube new TubeVisual3D { Path new Point3DCollection { p1, p3 }, Diameter 0.12, ThetaDiv 16, Fill new SolidColorBrush(Colors.LightGray), Material MaterialHelper.CreateMaterial(new SolidColorBrush(Colors.LightGray)) }; _modelGroup.Children.Add(verticalTube.Content); } } /// summary /// 添加底座 /// /summary private void AddBasePlate() { // 创建六边形底座轮廓 var basePoints new Point3DCollection(); double radius 3.5; int segments 20; for (int i 0; i segments; i) { double angle i * 2 * Math.PI / segments; double x radius * Math.Cos(angle); double y radius * Math.Sin(angle); basePoints.Add(new Point3D(x, y, -0.3)); } // 添加底座管 var baseTube new TubeVisual3D { Path basePoints, Diameter 0.08, ThetaDiv 12, Fill new SolidColorBrush(Colors.DarkGray), Material MaterialHelper.CreateMaterial(new SolidColorBrush(Colors.DarkGray)) }; _modelGroup.Children.Add(baseTube.Content); } /// summary /// 设置自动旋转定时器 /// /summary private void SetupRotationTimer() { _rotationTimer new System.Windows.Threading.DispatcherTimer { Interval TimeSpan.FromMilliseconds(30) }; _rotationTimer.Tick (s, e) { if (ChkAutoRotate.IsChecked true) { RotateModel(new Vector3D(0, 0, 1), ROTATION_SPEED); } }; _rotationTimer.Start(); } /// summary /// 旋转模型 /// /summary private void RotateModel(Vector3D axis, double angle) { if (_modelGroup null) return; var transform _modelGroup.Transform as RotateTransform3D; if (transform null) { transform new RotateTransform3D(new AxisAngleRotation3D(axis, angle)); _modelGroup.Transform transform; } else { var rotation transform.Rotation as AxisAngleRotation3D; if (rotation ! null) { rotation.Axis axis; rotation.Angle (rotation.Angle angle) % 360; } } } /// summary /// 旋转按钮点击事件 /// /summary private void BtnRotate_Click(object sender, RoutedEventArgs e) { RotateModel(new Vector3D(0, 0, 1), 30); } /// summary /// 导出模型按钮点击事件 /// /summary private void BtnExport_Click(object sender, RoutedEventArgs e) { var dialog new SaveFileDialog { Title 导出模型, Filter 3D模型文件 (*.3ds)|*.3ds|STL文件 (*.stl)|*.stl|OBJ文件 (*.obj)|*.obj|XAML文件 (*.xaml)|*.xaml|所有文件 (*.*)|*.*, InitialDirectory Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), RestoreDirectory true }; if (dialog.ShowDialog() true) { try { // 使用 HelixViewport3D 自带的 Export 方法 Viewport3D.Export(dialog.FileName); MessageBox.Show($模型已成功导出到:\n{dialog.FileName}, 导出成功, MessageBoxButton.OK, MessageBoxImage.Information); } catch (Exception ex) { MessageBox.Show($导出失败:\n{ex.Message}, 错误, MessageBoxButton.OK, MessageBoxImage.Error); } } } /// summary /// 自适应视图按钮点击事件 /// /summary private void BtnZoomExtents_Click(object sender, RoutedEventArgs e) { Viewport3D.ZoomExtents(100); } /// summary /// 窗口关闭时清理资源 /// /summary protected override void OnClosed(EventArgs e) { _rotationTimer?.Stop(); base.OnClosed(e); } } }六、资料[【1.9 HelixToolkit学习案例】WPF案例代码解析 - 知乎] (https://zhuanlan.zhihu.com/p/538932951#1)