首次提交: OnebotCatalog 项目代码与文档(含 NX 按需生成服务二期、后台、一键启动)
This commit is contained in:
108
src/App/ViewerControl.cs
Normal file
108
src/App/ViewerControl.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Media3D;
|
||||
using Ounibo.Catalog.Viewer3D;
|
||||
|
||||
namespace Ounibo.Catalog.App
|
||||
{
|
||||
/// <summary>
|
||||
/// 3D 预览控件: Viewport3D + 鼠标左键拖拽旋转 + 滚轮缩放。
|
||||
/// </summary>
|
||||
public class ViewerControl : UserControl
|
||||
{
|
||||
Viewport3D _vp;
|
||||
PerspectiveCamera _cam;
|
||||
Model3DGroup _root;
|
||||
Point _last;
|
||||
double _theta = 0.6, _phi = 0.9, _dist = 300;
|
||||
bool _dragging;
|
||||
|
||||
public ViewerControl()
|
||||
{
|
||||
_root = new Model3DGroup();
|
||||
_root.Children.Add(new DirectionalLight(Colors.White, new Vector3D(-1, -1, -2)));
|
||||
_root.Children.Add(new DirectionalLight(Colors.White, new Vector3D(1, 0.5, 1)));
|
||||
|
||||
_cam = new PerspectiveCamera
|
||||
{
|
||||
Position = new Point3D(0, 0, 300),
|
||||
LookDirection = new Vector3D(0, 0, -1),
|
||||
UpDirection = new Vector3D(0, 1, 0),
|
||||
FieldOfView = 45
|
||||
};
|
||||
_vp = new Viewport3D { Camera = _cam };
|
||||
_vp.Children.Add(new ModelVisual3D { Content = _root });
|
||||
Content = new Border { Background = Brushes.White, Child = _vp };
|
||||
|
||||
_vp.MouseLeftButtonDown += (s, e) => { _dragging = true; _last = e.GetPosition(_vp); _vp.CaptureMouse(); };
|
||||
_vp.MouseMove += (s, e) =>
|
||||
{
|
||||
if (!_dragging) return;
|
||||
var p = e.GetPosition(_vp);
|
||||
var dx = p.X - _last.X;
|
||||
var dy = p.Y - _last.Y;
|
||||
_last = p;
|
||||
_theta -= dx * 0.01;
|
||||
_phi = Math.Max(-1.45, Math.Min(1.45, _phi + dy * 0.01));
|
||||
UpdateCamera();
|
||||
};
|
||||
_vp.MouseLeftButtonUp += (s, e) => { _dragging = false; _vp.ReleaseMouseCapture(); };
|
||||
_vp.MouseWheel += (s, e) =>
|
||||
{
|
||||
_dist *= (e.Delta > 0) ? 0.88 : 1.13;
|
||||
_dist = Math.Max(20, Math.Min(4000, _dist));
|
||||
UpdateCamera();
|
||||
};
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
var lights = new List<Light>();
|
||||
foreach (var m in _root.Children)
|
||||
if (m is Light) lights.Add((Light)m);
|
||||
_root.Children.Clear();
|
||||
foreach (var l in lights) _root.Children.Add(l);
|
||||
}
|
||||
|
||||
/// <summary>加载圆柱列表并自动取景。</summary>
|
||||
public void Load(List<Cyl> cyls)
|
||||
{
|
||||
Clear();
|
||||
if (cyls == null || cyls.Count == 0) return;
|
||||
|
||||
// 颜色: 0 后盖 / 1 缸体 / 2 前盖 / 3 活塞杆
|
||||
var brushes = new[]
|
||||
{
|
||||
new SolidColorBrush(Color.FromRgb(0x8C, 0x8C, 0x8C)),
|
||||
new SolidColorBrush(Color.FromRgb(0x2F, 0x6F, 0xB3)),
|
||||
new SolidColorBrush(Color.FromRgb(0x8C, 0x8C, 0x8C)),
|
||||
new SolidColorBrush(Color.FromRgb(0xC8, 0xC8, 0xC8))
|
||||
};
|
||||
for (int i = 0; i < cyls.Count; i++)
|
||||
{
|
||||
var mesh = StepMesh.BuildMesh(cyls[i]);
|
||||
var mat = new DiffuseMaterial(brushes[i % brushes.Length]);
|
||||
_root.Children.Add(new GeometryModel3D(mesh, mat) { BackMaterial = mat });
|
||||
}
|
||||
|
||||
double cx, cy, cz, r, h;
|
||||
StepMesh.Bounds(cyls, out cx, out cy, out cz, out r, out h);
|
||||
_dist = Math.Max(120, Math.Max(r * 5.0, h * 1.6));
|
||||
_theta = 0.55; _phi = 0.85;
|
||||
UpdateCamera();
|
||||
}
|
||||
|
||||
void UpdateCamera()
|
||||
{
|
||||
double x = _dist * Math.Sin(_theta) * Math.Cos(_phi);
|
||||
double y = _dist * Math.Sin(_phi);
|
||||
double z = _dist * Math.Cos(_theta) * Math.Cos(_phi);
|
||||
_cam.Position = new Point3D(x, y, z);
|
||||
_cam.LookDirection = new Vector3D(-x, -y, -z);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user