using HelixToolkit.Geometry; using HelixToolkit.Wpf; using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Media3D; namespace Ramitta { public partial class winView3D : UserControl { public HelixViewport3D _viewport3D; public winView3D() { InitializeComponent(); // 默认初始化 Init("Viewport3D"); } public void Init(string name = "Viewport3D") { // 检查是否已有Viewport3D var existingViewport = FindName(name) as HelixViewport3D; if (existingViewport != null) { _viewport3D = existingViewport; return; } try { // 创建新的Viewport3D _viewport3D = new HelixViewport3D { Name = name, //Background = Brushes.White, IsPanEnabled = true, IsRotationEnabled = true, IsZoomEnabled = true, ShowCoordinateSystem = true, ShowViewCube = true, ZoomExtentsWhenLoaded = true }; // 添加到MainGrid(XAML中定义的Grid) MainGrid.Children.Add(_viewport3D); // 注册名称 RegisterName(name, _viewport3D); } catch (Exception ex) { throw new InvalidOperationException($"Failed to initialize 3D view: {ex.Message}", ex); } } /// /// 在两点之间绘制一条3D直线 /// /// 起点 /// 终点 /// 线条颜色(默认红色) /// 线条粗细(默认2.0) /// 创建的线条可视化对象 public LinesVisual3D DrawLineBetweenPoints( Point3D point1, Point3D point2, Color color = default, double thickness = 2.0, bool point1head=false, Color point1color=default, double point1radius = 0.5, bool point2head = false, Color point2color = default, double point2radius = 0.5) { // 如果没有指定颜色,使用红色 if (color == default) color = Colors.Red; var line = new LinesVisual3D { Points = new Point3DCollection { point1, point2 }, Color = color, Thickness = thickness }; _viewport3D.Children.Add(line); if (point1head) { DrawPointAsSphere(point1, color: point1color, radius: point1radius); } if (point2head) { DrawPointAsSphere(point2, color: point2color, radius: point2radius); } return line; } public SphereVisual3D DrawPointAsSphere(Point3D point, Color color = default, double radius = 0.5, int resolution = 10) { if (color == default) color = Colors.Green; var sphere = new SphereVisual3D { Center = point, Radius = radius, ThetaDiv = resolution, PhiDiv = resolution, Material = new DiffuseMaterial(new SolidColorBrush(color)) }; _viewport3D.Children.Add(sphere); return sphere; } // 其他辅助方法 public void ClearAllModels() { if (_viewport3D == null) return; // 保留光源和坐标轴网格,移除其他 for (int i = _viewport3D.Children.Count - 1; i >= 0; i--) { var child = _viewport3D.Children[i]; if (!(child is SunLight || child is GridLinesVisual3D)) { _viewport3D.Children.RemoveAt(i); } } } public void SetCamera(Point3D Position, Vector3D LookDirection) { // 设置相机 - 斜向下视角 var camera = new PerspectiveCamera { // 从右上后方位看向结构中心,并稍微向下倾斜 // 相机位置在结构的右、上、后方,距离根据结构尺寸动态调整 Position = Position, // 看向结构的中心点 LookDirection = LookDirection, UpDirection = new Vector3D(0, 1, 0), // Y轴为上方向 FieldOfView = 45 // 视野角度 }; _viewport3D.Camera = camera; _viewport3D.ZoomExtents(); } public void ZoomToExtents() { _viewport3D?.ZoomExtents(); } public void ResetView() { _viewport3D?.ResetCamera(); } } }