|
|
@ -17,6 +17,8 @@ using MeshGeometry3D = HelixToolkit.Wpf.SharpDX.MeshGeometry3D; |
|
|
|
using Point = System.Windows.Point; |
|
|
|
using Point = System.Windows.Point; |
|
|
|
using PerspectiveCamera = HelixToolkit.Wpf.SharpDX.PerspectiveCamera; |
|
|
|
using PerspectiveCamera = HelixToolkit.Wpf.SharpDX.PerspectiveCamera; |
|
|
|
using System.Windows.Controls; |
|
|
|
using System.Windows.Controls; |
|
|
|
|
|
|
|
using HelixToolkit.Wpf; |
|
|
|
|
|
|
|
using MeshBuilder = HelixToolkit.Wpf.SharpDX.MeshBuilder; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace SparkClient.Views.UserControl.ViewportData.Helper; |
|
|
|
namespace SparkClient.Views.UserControl.ViewportData.Helper; |
|
|
@ -1270,9 +1272,10 @@ public class ViewportHelperPro |
|
|
|
} |
|
|
|
} |
|
|
|
lights.ForEach(item => viewport.Items.Remove(item)); |
|
|
|
lights.ForEach(item => viewport.Items.Remove(item)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static Dictionary<Guid, Guid> moveLines = new Dictionary<Guid, Guid>(); |
|
|
|
public static List<LineGeometryModel3D> ShowMeshLines(List<Viewport3DTriangleEntity> entities, double thickness = 1.0) |
|
|
|
public static List<LineGeometryModel3D> ShowMeshLines(List<Viewport3DTriangleEntity> entities, double thickness = 1.0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
moveLines = new(); |
|
|
|
List<LineGeometryModel3D> lines = new(); |
|
|
|
List<LineGeometryModel3D> lines = new(); |
|
|
|
var Y = -0.01F; |
|
|
|
var Y = -0.01F; |
|
|
|
var center = ViewportManager.CenterVector; |
|
|
|
var center = ViewportManager.CenterVector; |
|
|
@ -1294,16 +1297,25 @@ public class ViewportHelperPro |
|
|
|
|
|
|
|
|
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)),2)); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)),2)); |
|
|
|
var lineA = DisplayLineModel3D(edgeLines, Color4.Black); |
|
|
|
var lineA = DisplayLineModel3D(edgeLines, XlineColor); |
|
|
|
lines.Add(lineA); |
|
|
|
lines.Add(lineA); |
|
|
|
|
|
|
|
|
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), -2)); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), -2)); |
|
|
|
var lineB = DisplayLineModel3D(edgeLines, XlineColor); |
|
|
|
var lineB = DisplayLineModel3D(edgeLines, XlineColor); |
|
|
|
lines.Add(lineB); |
|
|
|
lines.Add(lineB); |
|
|
|
lineA.MouseDown3D += LineA_MouseDown3D; |
|
|
|
bindingMoveLine(lineA, lineB); |
|
|
|
lineA.MouseUp3D += LineA_MouseUp3D; |
|
|
|
|
|
|
|
lineA.MouseMove3D += LineA_MouseMove3D; |
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
|
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), 4)); |
|
|
|
|
|
|
|
var lineE = DisplayLineModel3D(edgeLines, XlineColor); |
|
|
|
|
|
|
|
lines.Add(lineE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
|
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x1, Y, z1), new Vector3(x2, Y, z2)), -4)); |
|
|
|
|
|
|
|
var lineF = DisplayLineModel3D(edgeLines, XlineColor); |
|
|
|
|
|
|
|
lines.Add(lineF); |
|
|
|
|
|
|
|
bindingMoveLine(lineE, lineF); |
|
|
|
|
|
|
|
|
|
|
|
Color4 YlineColor = new Color4(0F, 80f, 0f, 1f); |
|
|
|
Color4 YlineColor = new Color4(0F, 80f, 0f, 1f); |
|
|
|
var x3 = 5; |
|
|
|
var x3 = 5; |
|
|
@ -1317,16 +1329,42 @@ public class ViewportHelperPro |
|
|
|
|
|
|
|
|
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), 2)); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), 2)); |
|
|
|
lines.Add(DisplayLineModel3D(edgeLines, YlineColor)); |
|
|
|
var lineC = DisplayLineModel3D(edgeLines, YlineColor); |
|
|
|
|
|
|
|
lines.Add(lineC); |
|
|
|
|
|
|
|
|
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), -2)); |
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), -2)); |
|
|
|
lines.Add(DisplayLineModel3D(edgeLines, YlineColor)); |
|
|
|
var lineD = DisplayLineModel3D(edgeLines, YlineColor); |
|
|
|
|
|
|
|
lines.Add(lineD); |
|
|
|
|
|
|
|
bindingMoveLine(lineC, lineD); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
|
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), 4)); |
|
|
|
|
|
|
|
var lineG = DisplayLineModel3D(edgeLines, YlineColor); |
|
|
|
|
|
|
|
lines.Add(lineG); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
edgeLines = new List<Tuple<Vector3, Vector3>>(); |
|
|
|
|
|
|
|
edgeLines.Add(lineCal.calLineOfOffset(new Tuple<Vector3, Vector3>(new Vector3(x3, Y, z3), new Vector3(x4, Y, z4)), -4)); |
|
|
|
|
|
|
|
var lineH = DisplayLineModel3D(edgeLines, YlineColor); |
|
|
|
|
|
|
|
lines.Add(lineH); |
|
|
|
|
|
|
|
bindingMoveLine(lineG, lineH); |
|
|
|
return lines; |
|
|
|
return lines; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void bindingMoveLine(LineGeometryModel3D lineA, LineGeometryModel3D lineB) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
lineA.MouseDown3D += LineA_MouseDown3D; |
|
|
|
|
|
|
|
lineA.MouseUp3D += LineA_MouseUp3D; |
|
|
|
|
|
|
|
lineA.MouseMove3D += LineA_MouseMove3D; |
|
|
|
|
|
|
|
moveLines.Add(lineA.GUID, lineB.GUID); |
|
|
|
|
|
|
|
lineB.MouseDown3D += LineA_MouseDown3D; |
|
|
|
|
|
|
|
lineB.MouseUp3D += LineA_MouseUp3D; |
|
|
|
|
|
|
|
lineB.MouseMove3D += LineA_MouseMove3D; |
|
|
|
|
|
|
|
moveLines.Add(lineB.GUID, lineA.GUID); |
|
|
|
|
|
|
|
} |
|
|
|
private static bool isDrawing = false; |
|
|
|
private static bool isDrawing = false; |
|
|
|
private static Point3D previousMousePosition; |
|
|
|
private static Point3D previousMousePosition; |
|
|
|
private static Vector3D _totalTranslation = new Vector3D(0, 0, 0); |
|
|
|
|
|
|
|
private static void LineA_MouseMove3D(object sender, RoutedEventArgs e) |
|
|
|
private static void LineA_MouseMove3D(object sender, RoutedEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (isDrawing) |
|
|
|
if (isDrawing) |
|
|
@ -1334,40 +1372,43 @@ public class ViewportHelperPro |
|
|
|
if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) |
|
|
|
if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var line = sender as LineGeometryModel3D; |
|
|
|
var line = sender as LineGeometryModel3D; |
|
|
|
var mousePosition = ev.Position; |
|
|
|
// 直线方向分量 |
|
|
|
var hitResult = ev.Viewport.FindNearestPoint(mousePosition); |
|
|
|
|
|
|
|
if (hitResult == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var lineDirection = line.Geometry.Positions[1] - line.Geometry.Positions[0]; |
|
|
|
var lineDirection = line.Geometry.Positions[1] - line.Geometry.Positions[0]; |
|
|
|
lineDirection.Normalize(); |
|
|
|
lineDirection.Normalize(); |
|
|
|
|
|
|
|
// 现在鼠标对于3d模型的位置 |
|
|
|
|
|
|
|
var mousePosition = ev.Position; |
|
|
|
|
|
|
|
var currentMousePosition = Get3DPointFromMouse(mousePosition); |
|
|
|
|
|
|
|
|
|
|
|
Vector3D referenceVector = new Vector3D(0, 1, 0); |
|
|
|
// 计算鼠标移动的方向 |
|
|
|
Vector3D perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), referenceVector); |
|
|
|
var moveDirection = previousMousePosition - currentMousePosition; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算垂直于线的移动分量 |
|
|
|
|
|
|
|
var perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), Vector3D.CrossProduct(moveDirection, lineDirection.ToVector3D())); |
|
|
|
perpendicularDirection.Normalize(); |
|
|
|
perpendicularDirection.Normalize(); |
|
|
|
|
|
|
|
|
|
|
|
var currentMousePosition = Get3DPointFromMouse(mousePosition, ev.Viewport); |
|
|
|
double scaleFactor = 0.1; // 缩放因子 |
|
|
|
//// 计算垂直于线的移动分量 |
|
|
|
// 计算垂直距离 |
|
|
|
//var perpendicularDirection = Vector3.Cross(lineDirection, Vector3.Cross(moveDirection,lineDirection)); |
|
|
|
double perpendicularDistance = Vector3D.DotProduct(moveDirection, perpendicularDirection) * scaleFactor; |
|
|
|
//perpendicularDirection.Normalize(); |
|
|
|
System.Console.WriteLine("距离:"+ perpendicularDistance); |
|
|
|
|
|
|
|
// 垂直方向偏移量 |
|
|
|
var point = hitResult.Value; |
|
|
|
Vector3D projectedVector = perpendicularDistance * perpendicularDirection; |
|
|
|
|
|
|
|
|
|
|
|
var dragVector = point - ev.HitTestResult.PointHit.ToPoint3D(); |
|
|
|
|
|
|
|
double dotProduct = Vector3D.DotProduct(dragVector, perpendicularDirection); |
|
|
|
|
|
|
|
Vector3D projectedVector = dotProduct * perpendicularDirection; |
|
|
|
|
|
|
|
projectedVector.Y = 0; |
|
|
|
projectedVector.Y = 0; |
|
|
|
//// 计算垂直距离 |
|
|
|
|
|
|
|
//float perpendicularDistance = Vector3.Dot(moveDirection, perpendicularDirection); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//line.Geometry.Positions[0] += perpendicularDirection * perpendicularDistance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//line.Geometry.Positions[1] += perpendicularDirection * perpendicularDistance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_totalTranslation += projectedVector; |
|
|
|
|
|
|
|
var transform = new TranslateTransform3D(projectedVector); |
|
|
|
var transform = new TranslateTransform3D(projectedVector); |
|
|
|
line.Transform = transform; |
|
|
|
line.Transform = transform; |
|
|
|
|
|
|
|
// 更新上一帧的鼠标位置 |
|
|
|
|
|
|
|
//previousMousePosition = currentMousePosition; |
|
|
|
|
|
|
|
var otherLineGuid = moveLines[line.GUID]; |
|
|
|
|
|
|
|
var Viewport = ViewportManager.GetViewport3D(); |
|
|
|
|
|
|
|
var otherLine = Viewport.Items.Where(x=>x.GUID == otherLineGuid).FirstOrDefault(); |
|
|
|
|
|
|
|
if (otherLine!= null ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Vector3D projectedVector_other = -perpendicularDistance * perpendicularDirection; |
|
|
|
|
|
|
|
projectedVector_other.Y = 0; |
|
|
|
|
|
|
|
var transform_other = new TranslateTransform3D(projectedVector_other); |
|
|
|
|
|
|
|
otherLine.Transform = transform_other; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1383,33 +1424,37 @@ public class ViewportHelperPro |
|
|
|
if(e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev){ |
|
|
|
if(e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev){ |
|
|
|
// 获取鼠标点击的位置 |
|
|
|
// 获取鼠标点击的位置 |
|
|
|
var mousePosition = ev.Position; |
|
|
|
var mousePosition = ev.Position; |
|
|
|
var a = ev.Viewport; |
|
|
|
previousMousePosition = Get3DPointFromMouse(mousePosition); |
|
|
|
previousMousePosition = Get3DPointFromMouse(mousePosition, a); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var line = sender as LineGeometryModel3D; |
|
|
|
|
|
|
|
//var transform = new TranslateTransform3D(10, 0, 10); |
|
|
|
|
|
|
|
//line.Transform = transform; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
private static Point3D Get3DPointFromMouse(Point mousePosition, Viewport3DX Viewport) |
|
|
|
private static Point3D Get3DPointFromMouse(Point mousePosition) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// 将2D屏幕坐标转换为3D世界坐标 |
|
|
|
// 使用 HelixToolkit 的 Ray3D 和 Plane3D |
|
|
|
var ray = GetRayFromMouse(mousePosition, Viewport); |
|
|
|
var Viewport = ViewportManager.GetViewport3D(); |
|
|
|
var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 0, 1)); // 假设平面为Z=0 |
|
|
|
var camera = Viewport.Camera as PerspectiveCamera; |
|
|
|
var intersection = plane.IntersectWith(ray); |
|
|
|
|
|
|
|
|
|
|
|
// 创建射线 |
|
|
|
|
|
|
|
var ray = new Ray3D( |
|
|
|
|
|
|
|
camera.Position, |
|
|
|
|
|
|
|
new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -(mousePosition.Y - Viewport.ActualHeight / 2), -camera.Position.Z) |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建平面(假设平面为 Y=0) |
|
|
|
|
|
|
|
var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 0, 1)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算射线与平面的交点 |
|
|
|
|
|
|
|
var intersection = GetIntersection(ray, plane); |
|
|
|
|
|
|
|
|
|
|
|
return intersection ?? new Point3D(0, 0, 0); |
|
|
|
return intersection ?? new Point3D(0, 0, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static Ray3D GetRayFromMouse(Point mousePosition, Viewport3DX Viewport) |
|
|
|
private static Point3D? GetIntersection(Ray3D ray, Plane3D plane) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// 获取从相机发出的射线 |
|
|
|
// 将射线转换为直线(起点和终点) |
|
|
|
var camera = Viewport.Camera as PerspectiveCamera; |
|
|
|
Point3D rayEnd = ray.Origin + ray.Direction * 1000; // 延长射线 |
|
|
|
var rayDirection = new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -(mousePosition.Y - Viewport.ActualHeight / 2), -camera.Position.Z); |
|
|
|
|
|
|
|
rayDirection.Normalize(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new Ray3D(camera.Position, rayDirection); |
|
|
|
// 使用 Plane3D.LineIntersection 方法计算交点 |
|
|
|
|
|
|
|
return plane.LineIntersection(ray.Origin, rayEnd); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) |
|
|
|
public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) |
|
|
@ -1699,37 +1744,3 @@ public class ViewportHelperPro |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 辅助类:表示3D射线 |
|
|
|
|
|
|
|
public class Ray3D |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
public Point3D Origin { get; } |
|
|
|
|
|
|
|
public Vector3D Direction { get; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Ray3D(Point3D origin, Vector3D direction) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Origin = origin; |
|
|
|
|
|
|
|
Direction = direction; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助类:表示3D平面 |
|
|
|
|
|
|
|
public class Plane3D |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
public Point3D Point { get; } |
|
|
|
|
|
|
|
public Vector3D Normal { get; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Plane3D(Point3D point, Vector3D normal) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Point = point; |
|
|
|
|
|
|
|
Normal = normal; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Point3D? IntersectWith(Ray3D ray) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var denominator = Vector3D.DotProduct(ray.Direction, Normal); |
|
|
|
|
|
|
|
if (Math.Abs(denominator) < 1e-6) return null; // 平行,无交点 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var t = Vector3D.DotProduct(Point - ray.Origin, Normal) / denominator; |
|
|
|
|
|
|
|
return ray.Origin + t * ray.Direction; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|