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();
}
}
}