lixiaojun
2025-04-03 2e52f10a2cccb1471859b05e0d0e9dd9649859c8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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();
        }
 
 
 
 
    }
}