namespace Yw.WpfUI.Hydro
|
{
|
/// <summary>
|
/// 简单几何管理器
|
/// </summary>
|
internal class SimpleGeometryManager
|
{
|
//缓存
|
private readonly ConcurrentDictionary<string, Geometry3D> _cache = new();
|
|
/// <summary>
|
/// 获取几何
|
/// </summary>
|
/// <param name="visual">构件</param>
|
/// <param name="size">尺寸</param>
|
/// <param name="factor">因子</param>
|
/// <returns></returns>
|
public Geometry3D GetGeometry(VisualL3d visual, double size, double factor)
|
{
|
var geometryType = visual.GetSimpleGeometryType();
|
var pts = visual.GetPositions();
|
var cacheKey = CreateCacheKey(geometryType, pts, size, factor);
|
var geometry = _cache.GetOrAdd(cacheKey, CreateGeometry(geometryType, pts, size, factor));
|
return geometry;
|
}
|
|
//创建几何
|
private static Geometry3D CreateGeometry(eSimpleGeometry geometryType, List<PointL3d> pts, double size, double factor)
|
{
|
Geometry3D geometry = null;
|
switch (geometryType)
|
{
|
case eSimpleGeometry.Junction:
|
geometry = CreateJunctionGeometry(pts[0], size, factor);
|
break;
|
case eSimpleGeometry.Source:
|
geometry = CreateSourceGeometry(pts[0], size, factor);
|
break;
|
case eSimpleGeometry.Pipe:
|
geometry = CreatePipeGeometry(pts[0], pts[1], size, factor);
|
break;
|
case eSimpleGeometry.Pump:
|
geometry = CreatePumpGeometry(pts[0], pts[1], size, factor);
|
break;
|
case eSimpleGeometry.Valve:
|
geometry = CreateValveGeometry(pts[0], pts[1], size, factor);
|
break;
|
default: break;
|
}
|
return geometry;
|
}
|
|
//创建连接节点几何
|
private static Geometry3D CreateJunctionGeometry(PointL3d pt, double radiu, double factor)
|
{
|
var builder = new MeshBuilder();
|
builder.AddSphere(pt.ToPoint3D(), radiu * factor);
|
return builder.ToMesh();
|
}
|
|
//创建水源几何
|
private static Geometry3D CreateSourceGeometry(PointL3d pt, double radiu, double factor)
|
{
|
var x = radiu * 4d * factor;
|
var y = radiu * 4d * factor;
|
var z = radiu * 2d * factor;
|
var builder = new MeshBuilder();
|
builder.AddBox(pt.ToPoint3D(), x, y, z);
|
return builder.ToMesh();
|
}
|
|
//创建管道几何
|
private static Geometry3D CreatePipeGeometry(PointL3d start, PointL3d end, double diameter, double factor)
|
{
|
var builder = new MeshBuilder();
|
builder.AddTube(
|
path: new[] { start.ToPoint3D(), end.ToPoint3D() },
|
diameter: diameter * factor, // 线直径(3D空间单位)
|
thetaDiv: 8, // 横截面细分度
|
false
|
);
|
return builder.ToMesh();
|
}
|
|
//创建水泵几何
|
private static Geometry3D CreatePumpGeometry(PointL3d start, PointL3d end, double diameter, double factor)
|
{
|
var sv = start.ToVector3D();
|
var ev = end.ToVector3D();
|
var center = (sv + ev) * 0.5d;
|
var direction = (ev - sv);
|
var length = direction.Length;
|
direction.Normalize();
|
|
//水泵管道
|
var builder = new MeshBuilder();
|
builder.AddTube(
|
path: new[] { start.ToPoint3D(), end.ToPoint3D() },
|
diameter: diameter * factor, // 线直径(3D空间单位)
|
thetaDiv: 8, // 横截面细分度
|
false
|
);
|
|
// 水泵主体(圆柱形)
|
var pumpCenter = sv + direction * (length * 0.5d);
|
builder.AddCylinder(
|
p1: (pumpCenter - direction * (length * 0.3d)).ToPoint3D(),
|
p2: (pumpCenter + direction * (length * 0.3d)).ToPoint3D(),
|
diameter: diameter * factor * 1.5d,
|
thetaDiv: 16);
|
|
double bladeWidth = diameter * factor * 2d;
|
double bladeLength = length * 0.6d;
|
|
// 创建两个交叉的叶片
|
for (int i = 0; i < 2; i++)
|
{
|
var rotation = new RotateTransform3D(
|
new AxisAngleRotation3D(direction, i * 90));
|
|
// 叶片1
|
var p1 = center + rotation.Transform(new Vector3D(-bladeLength / 2, -bladeWidth / 2, 0));
|
var p2 = center + rotation.Transform(new Vector3D(bladeLength / 2, -bladeWidth / 2, 0));
|
var p3 = center + rotation.Transform(new Vector3D(bladeLength / 2, bladeWidth / 2, 0));
|
var p4 = center + rotation.Transform(new Vector3D(-bladeLength / 2, bladeWidth / 2, 0));
|
|
builder.AddQuad(p1.ToPoint3D(), p2.ToPoint3D(), p3.ToPoint3D(), p4.ToPoint3D());
|
}
|
|
return builder.ToMesh();
|
}
|
|
//创建阀门几何
|
private static Geometry3D CreateValveGeometry(PointL3d start, PointL3d end, double diameter, double factor)
|
{
|
var sv = start.ToVector3D();
|
var ev = end.ToVector3D();
|
var center = (sv + ev) * 0.5d;
|
var direction = (ev - sv);
|
var length = direction.Length;
|
direction.Normalize();
|
var size = diameter * factor * 2d;
|
if (size > length)
|
{
|
size = length;
|
}
|
|
//阀门管道
|
var builder = new MeshBuilder();
|
builder.AddTube(
|
path: new[] { start.ToPoint3D(), end.ToPoint3D() },
|
diameter: diameter * factor, // 线直径(3D空间单位)
|
thetaDiv: 8, // 横截面细分度
|
false
|
);
|
|
builder.AddBox(center.ToPoint3D(), size, size, size);
|
|
return builder.ToMesh();
|
}
|
|
//创建缓存键
|
private static string CreateCacheKey(eSimpleGeometry geometryType, List<PointL3d> pts, double size, double factor)
|
{
|
var sb = new StringBuilder();
|
sb.Append(geometryType);
|
sb.Append('-');
|
foreach (var pt in pts)
|
{
|
sb.Append(pt.ToString());
|
sb.Append('-');
|
}
|
sb.Append(size);
|
sb.Append('-');
|
sb.Append(factor);
|
return sb.ToString();
|
}
|
|
|
|
|
}
|
}
|