namespace Yw.WpfUI.Hydro
|
{
|
/// <summary>
|
/// 编辑绘制3D
|
/// </summary>
|
internal class EditDraw3D : ModelVisual3D, IDisposable
|
{
|
/// <summary>
|
///
|
/// </summary>
|
public EditDraw3D
|
(
|
HelixViewport3D viewport,
|
DrawInitialHelper initialHelper,
|
DrawSelectionHelper selectionHelper
|
)
|
{
|
_viewport = viewport;
|
_initialHelper = initialHelper;
|
_selectionHelper = selectionHelper;
|
Attach();
|
}
|
|
#region 固定资源
|
|
private const double ArrowLength = 5;//箭头长度
|
private const double ArrowDiameter = 0.2;//箭头直径
|
private const double ArrowHeadLength = 3;//箭头头部长度
|
|
#endregion
|
|
#region 事件集合
|
|
/// <summary>
|
/// 编辑改变事件
|
/// </summary>
|
public event Action<List<VisualDraw3D>> EditChangedEvent;
|
|
#endregion
|
|
|
private readonly HelixViewport3D _viewport = null; //三维组件
|
private readonly DrawInitialHelper _initialHelper = null; //初始化辅助类
|
private readonly DrawSelectionHelper _selectionHelper = null;//选择辅助类
|
|
private ArrowVisual3D _xarrow = null; //X轴箭头
|
private ArrowVisual3D _yarrow = null;//y轴箭头
|
private ArrowVisual3D _zarrow = null;//z轴箭头
|
|
private bool _isDragging = false;//是否正在拖动
|
private ArrowVisual3D _currentArrow = null;//当前箭头
|
private Point3D _lastPosition;//最后位置
|
private bool _lastSelectionEnabled = false;//最后选择是否启用
|
|
/// <summary>
|
/// 初始化
|
/// </summary>
|
public void Initial(List<VisualDraw3D> visual3ds)
|
{
|
this.Children.Clear();
|
|
// 计算包围盒
|
var bounds = GetBounds(visual3ds);
|
if (bounds.IsEmpty)
|
{
|
return;
|
}
|
|
var center = bounds.GetCenter();
|
var size = bounds.Size;
|
var length = ((Vector3D)size).Length;
|
|
// 创建X轴箭头(红色)
|
_xarrow = new ArrowVisual3D
|
{
|
Point1 = center + new Vector3D(size.X / 2d, 0, 0),
|
Point2 = center + new Vector3D(size.X / 2d + ArrowLength, 0, 0),
|
Diameter = ArrowDiameter,
|
HeadLength = ArrowHeadLength,
|
Fill = Brushes.Red,
|
};
|
|
// 创建Y轴箭头(绿色)
|
_yarrow = new ArrowVisual3D
|
{
|
Point1 = center + new Vector3D(0, size.Y / 2d, 0),
|
Point2 = center + new Vector3D(0, size.Y / 2d + ArrowLength, 0),
|
Diameter = ArrowDiameter,
|
HeadLength = ArrowHeadLength,
|
Fill = Brushes.Green,
|
};
|
|
// 创建Z轴箭头(蓝色)
|
_zarrow = new ArrowVisual3D
|
{
|
Point1 = center + new Vector3D(0, 0, size.Z / 2d),
|
Point2 = center + new Vector3D(0, 0, size.Z / 2d + ArrowLength),
|
Diameter = ArrowDiameter,
|
HeadLength = ArrowHeadLength,
|
Fill = Brushes.Blue,
|
};
|
|
this.Children.Add(_xarrow);
|
this.Children.Add(_yarrow);
|
this.Children.Add(_zarrow);
|
}
|
|
//处理选择改变
|
private void OnSelectionChanged(List<VisualDraw3D> visual3ds)
|
{
|
Initial(visual3ds);
|
}
|
|
//处理鼠标按下
|
private void OnMouseDown(object sender, MouseButtonEventArgs e)
|
{
|
var mousePos = e.GetPosition(_viewport);
|
var position = _viewport.Viewport.UnProject(mousePos);
|
if (!position.HasValue)
|
{
|
return;
|
}
|
var hits = _viewport.Viewport.FindHits(mousePos);
|
if (hits == null || hits.Count < 1)
|
{
|
return;
|
}
|
var hit = hits.FirstOrDefault(x => x.Visual == _xarrow || x.Visual == _yarrow || x.Visual == _zarrow);
|
if (hit != null)
|
{
|
_isDragging = true;
|
_currentArrow = hit.Visual as ArrowVisual3D;
|
_lastPosition = position.Value;
|
_viewport.Cursor = Cursors.Hand;
|
_lastSelectionEnabled = _selectionHelper.Enabled;
|
_selectionHelper.Enabled = false;
|
}
|
}
|
|
//处理鼠标移动
|
private void OnMouseMove(object sender, MouseEventArgs e)
|
{
|
if (!_isDragging)
|
{
|
return;
|
}
|
|
var mousePos = e.GetPosition(_viewport);
|
var position = _viewport.Viewport.UnProject(mousePos);
|
if (!position.HasValue)
|
{
|
return;
|
}
|
|
// 偏移
|
Vector3D offset = position.Value - _lastPosition;
|
_lastPosition = position.Value;
|
|
if (_currentArrow == _xarrow)
|
{
|
offset.Y = 0;
|
offset.Z = 0;
|
}
|
else if (_currentArrow == _yarrow)
|
{
|
offset.X = 0;
|
offset.Z = 0;
|
}
|
else if (_currentArrow == _zarrow)
|
{
|
offset.X = 0;
|
offset.Y = 0;
|
}
|
|
_selectionHelper.Selection.ForEach(x =>
|
{
|
x.Offset(offset);
|
x.UpdateVisual3D();
|
var visual3ds = _initialHelper.GetConnect3D(x);
|
visual3ds?.ForEach(x =>
|
{
|
x.UpdatePositions();
|
x.UpdateVisual3D();
|
});
|
});
|
|
_xarrow.Point1 += offset;
|
_xarrow.Point2 += offset;
|
_yarrow.Point1 += offset;
|
_yarrow.Point2 += offset;
|
_zarrow.Point1 += offset;
|
_zarrow.Point2 += offset;
|
}
|
|
//处理鼠标弹起
|
private void OnMouseUp(object sender, MouseButtonEventArgs e)
|
{
|
if (_isDragging)
|
{
|
_isDragging = false;
|
_currentArrow = null;
|
_viewport.Cursor = Cursors.Arrow;
|
_selectionHelper.Enabled = _lastSelectionEnabled;
|
OnEditChanged();
|
}
|
}
|
|
//处理编辑改变
|
private void OnEditChanged()
|
{
|
var selection = _selectionHelper.Selection;
|
if (selection == null || selection.Count < 1)
|
{
|
return;
|
}
|
var list = new List<VisualDraw3D>();
|
selection.ForEach(x =>
|
{
|
if (!list.Contains(x))
|
{
|
list.Add(x);
|
var visual3ds = _initialHelper.GetConnect3D(x);
|
visual3ds?.ForEach(y =>
|
{
|
if (!list.Contains(y))
|
{
|
list.Add(y);
|
}
|
});
|
}
|
});
|
this.EditChangedEvent?.Invoke(list);
|
}
|
|
//附加
|
private void Attach()
|
{
|
_selectionHelper.SelectionChangedEvent += OnSelectionChanged;
|
_viewport.MouseDown += OnMouseDown;
|
_viewport.MouseMove += OnMouseMove;
|
_viewport.MouseUp += OnMouseUp;
|
}
|
|
//分离
|
private void Detach()
|
{
|
_selectionHelper.SelectionChangedEvent -= OnSelectionChanged;
|
_viewport.MouseDown -= OnMouseDown;
|
_viewport.MouseMove -= OnMouseMove;
|
_viewport.MouseUp -= OnMouseUp;
|
}
|
|
/// <summary>
|
/// 释放
|
/// </summary>
|
public void Dispose()
|
{
|
Detach();
|
}
|
|
//获取边界
|
private static Rect3D GetBounds(List<VisualDraw3D> visual3ds)
|
{
|
Rect3D bounds = Rect3D.Empty;
|
visual3ds?.ForEach(x => bounds.Union(x.FindBounds(Transform3D.Identity)));
|
return bounds;
|
}
|
|
}
|
}
|