build-dxf 0.0.20-23 → 0.0.20-24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +3 -0
  2. package/package.json +6 -5
  3. package/src/build.d.ts +2 -0
  4. package/src/build.js +1375 -1922
  5. package/src/index.css +1 -625
  6. package/src/index.js +7 -7
  7. package/src/index2.js +327 -517
  8. package/src/index3.js +1809 -1715
  9. package/src/selectLocalFile.js +1955 -3145
  10. package/src/utils/CommandManager/CommandFlow.d.ts +17 -0
  11. package/src/utils/CommandManager/CommandManager.d.ts +23 -0
  12. package/src/utils/DxfSystem/components/AngleCorrectionDxf.d.ts +9 -0
  13. package/src/utils/DxfSystem/components/Dxf.d.ts +36 -5
  14. package/src/utils/DxfSystem/components/LineAnalysis.d.ts +3 -1
  15. package/src/utils/DxfSystem/index.d.ts +2 -0
  16. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/CommandFlowComponent.d.ts +4 -1
  17. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/ConnectionLine.d.ts +33 -0
  18. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/Default.d.ts +0 -20
  19. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DeleteSelectLine.d.ts +28 -0
  20. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DeleteSelectWindow.d.ts +33 -0
  21. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawDoorLine.d.ts +24 -4
  22. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawLine.d.ts +20 -4
  23. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawWindow.d.ts +25 -2
  24. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/IntersectionConnectionLine.d.ts +33 -0
  25. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/MergeLine.d.ts +33 -0
  26. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/PointDrag.d.ts +14 -1
  27. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/SelectAll.d.ts +30 -0
  28. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/VerticalCorrection.d.ts +82 -0
  29. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/VerticalReferenceLine.d.ts +21 -0
  30. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/ViewAngle.d.ts +21 -0
  31. package/src/utils/DxfSystem/plugin/Editor/components/RenderManager.d.ts +4 -1
  32. package/src/utils/DxfSystem/plugin/Editor/components/index.d.ts +1 -0
  33. package/src/utils/Quadtree/LineSegment.d.ts +19 -0
  34. package/src/utils/Quadtree/Point.d.ts +9 -2
  35. package/src/utils/deepClone.d.ts +6 -0
package/src/build.js CHANGED
@@ -1,70 +1,55 @@
1
- import * as THREE from "three";
2
- import { EventDispatcher as EventDispatcher$1 } from "three";
3
- import ClipperLib from "clipper-lib";
4
- import Drawing from "dxf-writer";
5
- import { OBJExporter } from "three/examples/jsm/exporters/OBJExporter.js";
6
- import { GLTFExporter } from "three/examples/jsm/exporters/GLTFExporter.js";
7
- function uuid() {
8
- return "xxxx-xxxx-4xxx-yxxx-xxxx".replace(/[xy]/g, function(c) {
9
- var r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8;
10
- return v.toString(16);
1
+ import * as M from "three";
2
+ import { EventDispatcher as tt } from "three";
3
+ import F from "clipper-lib";
4
+ import R from "dxf-writer";
5
+ import { OBJExporter as et } from "three/examples/jsm/exporters/OBJExporter.js";
6
+ import { GLTFExporter as nt } from "three/examples/jsm/exporters/GLTFExporter.js";
7
+ function z() {
8
+ return "xxxx-xxxx-4xxx-yxxx-xxxx".replace(/[xy]/g, function(y) {
9
+ var t = Math.random() * 16 | 0, e = y == "x" ? t : t & 3 | 8;
10
+ return e.toString(16);
11
11
  });
12
12
  }
13
- class EventDispatcher extends EventDispatcher$1 {
14
- uuid = uuid();
15
- addEventListener(type, listener, option) {
16
- const { once = false } = option ?? {};
17
- const callBack = (event) => {
18
- listener(event);
19
- once && canceCallBack();
20
- };
21
- const canceCallBack = () => this.removeEventListener(type, callBack);
22
- super.addEventListener(type, callBack);
23
- return canceCallBack;
13
+ class $ extends tt {
14
+ uuid = z();
15
+ addEventListener(t, e, n) {
16
+ const { once: i = !1 } = n ?? {}, o = (r) => {
17
+ e(r), i && s();
18
+ }, s = () => this.removeEventListener(t, o);
19
+ return super.addEventListener(t, o), s;
24
20
  }
25
21
  eventRecordStack = /* @__PURE__ */ new Map();
26
- addEventRecord(name, ...cancels) {
27
- if (!this.eventRecordStack.has(name)) this.eventRecordStack.set(name, []);
28
- cancels.forEach((cancel) => {
29
- this.eventRecordStack.get(name)?.push(cancel);
22
+ addEventRecord(t, ...e) {
23
+ this.eventRecordStack.has(t) || this.eventRecordStack.set(t, []), e.forEach((i) => {
24
+ this.eventRecordStack.get(t)?.push(i);
30
25
  });
31
- const add = (cancel) => {
32
- this.addEventRecord(name, cancel);
33
- return { add };
34
- };
35
- return { add };
26
+ const n = (i) => (this.addEventRecord(t, i), { add: n });
27
+ return { add: n };
36
28
  }
37
- canceEventRecord(name) {
38
- const list = this.eventRecordStack.get(name);
39
- if (list) {
40
- list.forEach((cancel) => cancel());
41
- this.eventRecordStack.delete(name);
42
- }
29
+ canceEventRecord(t) {
30
+ const e = this.eventRecordStack.get(t);
31
+ e && (e.forEach((n) => n()), this.eventRecordStack.delete(t));
43
32
  }
44
33
  }
45
- class Component extends EventDispatcher {
34
+ class j extends $ {
46
35
  parent;
47
- destroyed = false;
48
- constructor(...arg) {
49
- super();
50
- this.addEventListener("addFromParent", (e) => {
51
- this.parent = e.parent;
52
- this.onAddFromParent(e.parent);
53
- });
54
- this.addEventListener("removeFromParent", (e) => {
55
- this.parent = void 0;
56
- this.onRemoveFromParent(e.parent);
36
+ destroyed = !1;
37
+ constructor(...t) {
38
+ super(), this.addEventListener("addFromParent", (e) => {
39
+ this.parent = e.parent, this.onAddFromParent(e.parent);
40
+ }), this.addEventListener("removeFromParent", (e) => {
41
+ this.parent = void 0, this.onRemoveFromParent(e.parent);
57
42
  });
58
43
  }
59
- onAddFromParent(parent) {
44
+ onAddFromParent(t) {
60
45
  }
61
- onRemoveFromParent(parent) {
46
+ onRemoveFromParent(t) {
62
47
  }
63
48
  destroy() {
64
- this.destroyed = true;
49
+ this.destroyed = !0;
65
50
  }
66
51
  }
67
- class ComponentManager extends EventDispatcher {
52
+ class it extends $ {
68
53
  static EventType = {
69
54
  ADD_COMPONENT: "addComponent"
70
55
  };
@@ -73,75 +58,66 @@ class ComponentManager extends EventDispatcher {
73
58
  * 添加组件
74
59
  * @param component
75
60
  */
76
- addComponent(component) {
77
- if (component) {
78
- this.components.push(component);
79
- this.dispatchEvent({
80
- type: "addComponent",
81
- component
82
- });
83
- component.dispatchEvent({
84
- type: "addFromParent",
85
- parent: this
86
- });
87
- }
88
- return this;
61
+ addComponent(t) {
62
+ return t && (this.components.push(t), this.dispatchEvent({
63
+ type: "addComponent",
64
+ component: t
65
+ }), t.dispatchEvent({
66
+ type: "addFromParent",
67
+ parent: this
68
+ })), this;
89
69
  }
90
70
  /**
91
71
  * 移除组件
92
72
  * @param component
93
73
  */
94
- removeComponent(component) {
95
- if (component instanceof Component) {
96
- const index2 = this.components.indexOf(component);
97
- if (index2 > -1) {
98
- this.components.splice(index2, 1);
99
- this.dispatchEvent({
100
- type: "removeComponent",
101
- component
102
- });
103
- component.dispatchEvent({
104
- type: "removeFromParent",
105
- parent: this
106
- });
107
- }
74
+ removeComponent(t) {
75
+ if (t instanceof j) {
76
+ const e = this.components.indexOf(t);
77
+ e > -1 && (this.components.splice(e, 1), this.dispatchEvent({
78
+ type: "removeComponent",
79
+ component: t
80
+ }), t.dispatchEvent({
81
+ type: "removeFromParent",
82
+ parent: this
83
+ }));
108
84
  }
109
85
  }
110
86
  /**
111
87
  * 查找符合条件的第一个组件
112
88
  * @param callBack
113
89
  */
114
- findComponent(predicate) {
115
- for (let i = 0; i < this.components.length; i++) {
116
- const component = this.components[i];
117
- if (predicate(component, i)) return component;
90
+ findComponent(t) {
91
+ for (let e = 0; e < this.components.length; e++) {
92
+ const n = this.components[e];
93
+ if (t(n, e)) return n;
118
94
  }
119
95
  }
120
96
  /**
121
97
  * 查找所有符合条件的组件
122
98
  * @param callBack
123
99
  */
124
- findComponents(predicate) {
125
- return this.components.filter(predicate);
100
+ findComponents(t) {
101
+ return this.components.filter(t);
126
102
  }
127
103
  /**
128
104
  *
129
105
  * @param type
130
106
  */
131
- findComponentByType(type) {
132
- const component = this.findComponent((c) => c instanceof type);
133
- return component ? component : null;
107
+ findComponentByType(t) {
108
+ const e = this.findComponent((n) => n instanceof t);
109
+ return e || null;
134
110
  }
135
111
  /**
136
112
  *
137
113
  * @param type
138
114
  */
139
- findComponentByName(name) {
140
- const component = this.findComponent((c) => c.constructor.name === name);
141
- return component ? component : null;
115
+ findComponentByName(t) {
116
+ const e = this.findComponent((n) => n.constructor.name === t);
117
+ return e || null;
142
118
  }
143
119
  }
144
- class Point {
120
+ class p {
145
121
  x;
146
122
  y;
147
123
  get X() {
@@ -156,39 +132,32 @@ class Point {
156
132
  * @param x
157
133
  * @param y
158
134
  */
159
- constructor(x = 0, y = 0) {
160
- this.x = x;
161
- this.y = y;
135
+ constructor(t = 0, e = 0) {
136
+ this.x = t, this.y = e;
162
137
  }
163
- set(x, y) {
164
- this.x = x;
165
- this.y = y;
166
- return this;
138
+ set(t, e) {
139
+ return this.x = t, this.y = e, this;
167
140
  }
168
- setX(x) {
169
- this.x = x;
170
- return this;
141
+ setX(t) {
142
+ return this.x = t, this;
171
143
  }
172
- setY(y) {
173
- this.y = y;
174
- return this;
144
+ setY(t) {
145
+ return this.y = t, this;
175
146
  }
176
147
  /**
177
148
  *
178
149
  * @param point
179
150
  * @returns
180
151
  */
181
- equal(point) {
182
- return point.x === this.x && point.y === this.y;
152
+ equal(t) {
153
+ return t.x === this.x && t.y === this.y;
183
154
  }
184
155
  /**
185
156
  *
186
157
  * @param arr
187
158
  */
188
- setByArray(arr) {
189
- this.x = arr[0];
190
- this.y = arr[1];
191
- return this;
159
+ setByArray(t) {
160
+ return this.x = t[0], this.y = t[1], this;
192
161
  }
193
162
  /**
194
163
  *
@@ -200,25 +169,19 @@ class Point {
200
169
  * multiplyScalar
201
170
  * @param scalar
202
171
  */
203
- mutiplyScalar(scalar) {
204
- this.x *= scalar;
205
- this.y *= scalar;
206
- return this;
172
+ mutiplyScalar(t) {
173
+ return this.x *= t, this.y *= t, this;
207
174
  }
208
- multiplyScalar(scalar) {
209
- this.x *= scalar;
210
- this.y *= scalar;
211
- return this;
175
+ multiplyScalar(t) {
176
+ return this.x *= t, this.y *= t, this;
212
177
  }
213
178
  /**
214
179
  *
215
180
  * @param scalar
216
181
  * @returns
217
182
  */
218
- divisionScalar(scalar) {
219
- this.x /= scalar;
220
- this.y /= scalar;
221
- return this;
183
+ divisionScalar(t) {
184
+ return this.x /= t, this.y /= t, this;
222
185
  }
223
186
  /**
224
187
  * 减法
@@ -226,10 +189,8 @@ class Point {
226
189
  * @param point
227
190
  * @returns
228
191
  */
229
- division(point) {
230
- this.x -= point.x;
231
- this.y -= point.y;
232
- return this;
192
+ division(t) {
193
+ return this.x -= t.x, this.y -= t.y, this;
233
194
  }
234
195
  /**
235
196
  * 加法
@@ -237,19 +198,24 @@ class Point {
237
198
  * @param point
238
199
  * @returns
239
200
  */
240
- add(point) {
241
- this.x += point.x;
242
- this.y += point.y;
243
- return this;
201
+ add(t) {
202
+ return this.x += t.x, this.y += t.y, this;
203
+ }
204
+ /**
205
+ * 绕point旋转angle
206
+ * @param point
207
+ * @param angle 旋转角度,单位为弧度
208
+ */
209
+ rotate(t, e) {
210
+ const n = this.x - t.x, i = this.y - t.y, o = Math.cos(e), s = Math.sin(e), r = n * o - i * s, c = n * s + i * o;
211
+ return this.x = r + t.x, this.y = c + t.y, this;
244
212
  }
245
213
  /**
246
214
  * 保留小数位数
247
215
  * @param count
248
216
  */
249
- fixed(count) {
250
- this.x = Number(this.x.toFixed(count));
251
- this.y = Number(this.y.toFixed(count));
252
- return this;
217
+ fixed(t) {
218
+ return this.x = Number(this.x.toFixed(t)), this.y = Number(this.y.toFixed(t)), this;
253
219
  }
254
220
  /**
255
221
  * 归一化
@@ -257,11 +223,8 @@ class Point {
257
223
  * @returns
258
224
  */
259
225
  normalize() {
260
- const length = Math.sqrt(this.x * this.x + this.y * this.y);
261
- if (length === 0) return this;
262
- this.x /= length;
263
- this.y /= length;
264
- return this;
226
+ const t = Math.sqrt(this.x * this.x + this.y * this.y);
227
+ return t === 0 ? this : (this.x /= t, this.y /= t, this);
265
228
  }
266
229
  /**
267
230
  * 获取单位法向量
@@ -269,13 +232,9 @@ class Point {
269
232
  * @param point
270
233
  * @returns
271
234
  */
272
- normal(point) {
273
- const dx = this.x - point.x;
274
- const dy = this.y - point.y;
275
- const length = Math.sqrt(dx * dx + dy * dy);
276
- const nx = -dy / length;
277
- const ny = dx / length;
278
- return new Point(nx, ny);
235
+ normal(t) {
236
+ const e = this.x - t.x, n = this.y - t.y, i = Math.sqrt(e * e + n * n), o = -n / i, s = e / i;
237
+ return new p(o, s);
279
238
  }
280
239
  /**
281
240
  * 获取由传入的点到该点的单位方向向量
@@ -283,12 +242,9 @@ class Point {
283
242
  * @param point
284
243
  * @returns
285
244
  */
286
- direction(point) {
287
- const dx = this.x - point.x;
288
- const dy = this.y - point.y;
289
- const length = Math.sqrt(dx * dx + dy * dy);
290
- if (length === 0) return new Point(0, 0);
291
- return new Point(dx / length, dy / length);
245
+ direction(t) {
246
+ const e = this.x - t.x, n = this.y - t.y, i = Math.sqrt(e * e + n * n);
247
+ return i === 0 ? new p(0, 0) : new p(e / i, n / i);
292
248
  }
293
249
  /**
294
250
  * 计算模长
@@ -302,8 +258,8 @@ class Point {
302
258
  * @param point
303
259
  * @returns
304
260
  */
305
- dot(point) {
306
- return this.x * point.x + this.y * point.y;
261
+ dot(t) {
262
+ return this.x * t.x + this.y * t.y;
307
263
  }
308
264
  /** 求两个点叉积
309
265
  * @description 如果叉积大于 0,a 到 b 为逆时针方向。
@@ -311,8 +267,8 @@ class Point {
311
267
  * @param point
312
268
  * @returns
313
269
  */
314
- cross(point) {
315
- return this.x * point.y - this.y * this.x;
270
+ cross(t) {
271
+ return this.x * t.y - this.y * this.x;
316
272
  }
317
273
  /** 计算两个向量夹角
318
274
  * @description 公式:a · b = |a| × |b| × cosθ
@@ -320,34 +276,25 @@ class Point {
320
276
  * @param point
321
277
  * @returns
322
278
  */
323
- angleBetween(point, type = "radian", angle = "180") {
324
- const dotProduct = this.dot(point);
325
- const magnitude1 = this.magnitude();
326
- const magnitude2 = point.magnitude();
327
- if (magnitude1 === 0 || magnitude2 === 0) return 0;
328
- const cosTheta = dotProduct / (magnitude1 * magnitude2);
329
- const clampedCosTheta = Math.max(-1, Math.min(1, cosTheta));
330
- if (type === "radian") return Math.acos(clampedCosTheta);
331
- if (type === "cos") return clampedCosTheta;
332
- if (angle === "180" || this.cross(point) < 0) return Math.acos(clampedCosTheta) / (Math.PI / 180);
333
- return 360 - Math.acos(clampedCosTheta) / (Math.PI / 180);
279
+ angleBetween(t, e = "radian", n = "180") {
280
+ const i = this.dot(t), o = this.magnitude(), s = t.magnitude();
281
+ if (o === 0 || s === 0) return 0;
282
+ const r = i / (o * s), c = Math.max(-1, Math.min(1, r));
283
+ return e === "radian" ? Math.acos(c) : e === "cos" ? c : n === "180" || this.cross(t) < 0 ? Math.acos(c) / (Math.PI / 180) : 360 - Math.acos(c) / (Math.PI / 180);
334
284
  }
335
285
  /** 获取向量长度
336
286
  */
337
287
  length() {
338
- const magnitude = Math.sqrt(this.x * this.x + this.y * this.y);
339
- if (Math.abs(magnitude - Math.round(magnitude)) < 1e-9) {
340
- return Math.round(magnitude);
341
- }
342
- return magnitude;
288
+ const t = Math.sqrt(this.x * this.x + this.y * this.y);
289
+ return Math.abs(t - Math.round(t)) < 1e-9 ? Math.round(t) : t;
343
290
  }
344
291
  /**
345
292
  * 获取两个点长度
346
293
  * @param point
347
294
  */
348
- distance(point) {
295
+ distance(t) {
349
296
  return Math.sqrt(
350
- (this.x - point.x) * (this.x - point.x) + (this.y - point.y) * (this.y - point.y)
297
+ (this.x - t.x) * (this.x - t.x) + (this.y - t.y) * (this.y - t.y)
351
298
  );
352
299
  }
353
300
  /**
@@ -355,47 +302,40 @@ class Point {
355
302
  * @returns
356
303
  */
357
304
  clone() {
358
- return new Point(this.x, this.y);
305
+ return new p(this.x, this.y);
359
306
  }
360
307
  /**
361
308
  * 克隆
362
309
  * @returns
363
310
  */
364
- copy(p) {
365
- this.x = p.x ?? 0;
366
- this.y = p.y ?? 0;
311
+ copy(t) {
312
+ return this.x = t.x ?? 0, this.y = t.y ?? 0, this;
367
313
  }
368
- toJson() {
314
+ toJson(t = 0) {
369
315
  return {
370
316
  x: this.x,
371
- y: this.y
317
+ y: this.y,
318
+ z: t
372
319
  };
373
320
  }
374
- static from(arr) {
375
- if (Array.isArray(arr)) {
376
- return new Point(arr[0], arr[1]);
377
- } else if ("x" in arr && "y" in arr) {
378
- return new Point(arr.x, arr.y);
379
- } else if ("X" in arr && "Y" in arr) {
380
- return new Point(arr.X, arr.Y);
381
- }
382
- return this.zero();
321
+ static from(t) {
322
+ return Array.isArray(t) ? new p(t[0], t[1]) : "x" in t && "y" in t ? new p(t.x, t.y) : "X" in t && "Y" in t ? new p(t.X, t.Y) : this.zero();
383
323
  }
384
324
  static zero() {
385
- return new Point(0, 0);
325
+ return new p(0, 0);
386
326
  }
387
327
  }
388
- class Box2 {
328
+ class v {
389
329
  minX = 0;
390
330
  maxX = 0;
391
331
  minY = 0;
392
332
  maxY = 0;
393
333
  get points() {
394
334
  return [
395
- new Point(this.minX, this.minY),
396
- new Point(this.maxX, this.minY),
397
- new Point(this.maxX, this.maxY),
398
- new Point(this.minX, this.maxY)
335
+ new p(this.minX, this.minY),
336
+ new p(this.maxX, this.minY),
337
+ new p(this.maxX, this.maxY),
338
+ new p(this.minX, this.maxY)
399
339
  ];
400
340
  }
401
341
  get width() {
@@ -405,163 +345,122 @@ class Box2 {
405
345
  return this.maxY - this.minY;
406
346
  }
407
347
  get center() {
408
- return new Point(
348
+ return new p(
409
349
  this.minX + (this.maxX - this.minX) * 0.5,
410
350
  this.minY + (this.maxY - this.minY) * 0.5
411
351
  );
412
352
  }
413
- constructor(minX = 0, maxX = 0, minY = 0, maxY = 0) {
414
- this.minX = minX;
415
- this.maxX = maxX;
416
- this.minY = minY;
417
- this.maxY = maxY;
353
+ constructor(t = 0, e = 0, n = 0, i = 0) {
354
+ this.minX = t, this.maxX = e, this.minY = n, this.maxY = i;
418
355
  }
419
356
  /**
420
357
  *
421
358
  * @param z
422
359
  * @returns
423
360
  */
424
- getPaths3D(z = 0) {
425
- const points = this.points, list = [];
426
- points.forEach((p, i) => {
427
- const nextP = points[(i + 1) % points.length];
428
- list.push(p.x, p.y, z);
429
- list.push(nextP.x, nextP.y, z);
430
- });
431
- return list;
361
+ getPaths3D(t = 0) {
362
+ const e = this.points, n = [];
363
+ return e.forEach((i, o) => {
364
+ const s = e[(o + 1) % e.length];
365
+ n.push(i.x, i.y, t), n.push(s.x, s.y, t);
366
+ }), n;
432
367
  }
433
368
  /**
434
369
  * 判断线段是与包围盒相交
435
370
  * @description Liang-Barsky算法的变种
436
371
  * @param line
437
372
  */
438
- intersectLineSegment(line) {
439
- const p1 = line.points[0];
440
- const p2 = line.points[1];
441
- const dx = p2.x - p1.x;
442
- const dy = p2.y - p1.y;
443
- if (dx === 0 && dy === 0) {
444
- return this.minX <= p1.x && p1.x <= this.maxX && this.minY <= p1.y && p1.y <= this.maxY;
445
- }
446
- let tNear = Number.NEGATIVE_INFINITY;
447
- let tFar = Number.POSITIVE_INFINITY;
448
- if (dx !== 0) {
449
- const tx1 = (this.minX - p1.x) / dx;
450
- const tx2 = (this.maxX - p1.x) / dx;
451
- tNear = Math.max(tNear, Math.min(tx1, tx2));
452
- tFar = Math.min(tFar, Math.max(tx1, tx2));
453
- } else if (p1.x < this.minX || p1.x > this.maxX) {
454
- return false;
455
- }
456
- if (dy !== 0) {
457
- const ty1 = (this.minY - p1.y) / dy;
458
- const ty2 = (this.maxY - p1.y) / dy;
459
- tNear = Math.max(tNear, Math.min(ty1, ty2));
460
- tFar = Math.min(tFar, Math.max(ty1, ty2));
461
- } else if (p1.y < this.minY || p1.y > this.maxY) {
462
- return false;
463
- }
464
- return tNear <= tFar && tNear <= 1 && tFar >= 0;
373
+ intersectLineSegment(t) {
374
+ const e = t.points[0], n = t.points[1], i = n.x - e.x, o = n.y - e.y;
375
+ if (i === 0 && o === 0)
376
+ return this.minX <= e.x && e.x <= this.maxX && this.minY <= e.y && e.y <= this.maxY;
377
+ let s = Number.NEGATIVE_INFINITY, r = Number.POSITIVE_INFINITY;
378
+ if (i !== 0) {
379
+ const c = (this.minX - e.x) / i, a = (this.maxX - e.x) / i;
380
+ s = Math.max(s, Math.min(c, a)), r = Math.min(r, Math.max(c, a));
381
+ } else if (e.x < this.minX || e.x > this.maxX)
382
+ return !1;
383
+ if (o !== 0) {
384
+ const c = (this.minY - e.y) / o, a = (this.maxY - e.y) / o;
385
+ s = Math.max(s, Math.min(c, a)), r = Math.min(r, Math.max(c, a));
386
+ } else if (e.y < this.minY || e.y > this.maxY)
387
+ return !1;
388
+ return s <= r && s <= 1 && r >= 0;
465
389
  }
466
390
  /**
467
391
  * 判断线段是在包围盒内
468
392
  * @param line
469
393
  */
470
- containsLineSegment(line) {
471
- const [p1, p2] = line.points;
472
- return this.minX <= p1.x && p1.x <= this.maxX && this.minY <= p1.y && p1.y <= this.maxY && this.minX <= p2.x && p2.x <= this.maxX && this.minY <= p2.y && p2.y <= this.maxY;
394
+ containsLineSegment(t) {
395
+ const [e, n] = t.points;
396
+ return this.minX <= e.x && e.x <= this.maxX && this.minY <= e.y && e.y <= this.maxY && this.minX <= n.x && n.x <= this.maxX && this.minY <= n.y && n.y <= this.maxY;
473
397
  }
474
398
  /**
475
399
  * 判断矩形与包围盒相交
476
400
  * @param rectangle
477
401
  */
478
- intersectRectangle(rectangle) {
479
- const isPointInBox = (p) => this.minX <= p.x && p.x <= this.maxX && this.minY <= p.y && p.y <= this.maxY;
480
- const isPointInRect = (point) => {
481
- let sign = 0;
482
- for (let i = 0; i < 4; i++) {
483
- const p1 = rectangle.points[i];
484
- const p2 = rectangle.points[(i + 1) % 4];
485
- const edge = { x: p2.x - p1.x, y: p2.y - p1.y };
486
- const toPoint = { x: point.x - p1.x, y: point.y - p1.y };
487
- const cross = edge.x * toPoint.y - edge.y * toPoint.x;
488
- if (cross === 0) {
489
- const t = edge.x !== 0 ? (point.x - p1.x) / edge.x : (point.y - p1.y) / edge.y;
490
- if (t >= 0 && t <= 1) return true;
402
+ intersectRectangle(t) {
403
+ const e = (s) => this.minX <= s.x && s.x <= this.maxX && this.minY <= s.y && s.y <= this.maxY, n = (s) => {
404
+ let r = 0;
405
+ for (let c = 0; c < 4; c++) {
406
+ const a = t.points[c], h = t.points[(c + 1) % 4], l = { x: h.x - a.x, y: h.y - a.y }, d = { x: s.x - a.x, y: s.y - a.y }, f = l.x * d.y - l.y * d.x;
407
+ if (f === 0) {
408
+ const m = l.x !== 0 ? (s.x - a.x) / l.x : (s.y - a.y) / l.y;
409
+ if (m >= 0 && m <= 1) return !0;
491
410
  } else {
492
- const currentSign = cross > 0 ? 1 : -1;
493
- if (sign === 0) sign = currentSign;
494
- if (sign !== currentSign) return false;
411
+ const m = f > 0 ? 1 : -1;
412
+ if (r === 0 && (r = m), r !== m) return !1;
495
413
  }
496
414
  }
497
- return true;
498
- };
499
- const doIntersect = (l1p1, l1p2, l2p1, l2p2) => {
500
- const orientation = (p, q, r) => {
501
- const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
502
- if (val === 0) return 0;
503
- return val > 0 ? 1 : 2;
504
- };
505
- const onSegment = (p, q, r) => {
506
- return Math.min(p.x, r.x) <= q.x && q.x <= Math.max(p.x, r.x) && Math.min(p.y, r.y) <= q.y && q.y <= Math.max(p.y, r.y);
507
- };
508
- const o1 = orientation(l1p1, l1p2, l2p1);
509
- const o2 = orientation(l1p1, l1p2, l2p2);
510
- const o3 = orientation(l2p1, l2p2, l1p1);
511
- const o4 = orientation(l2p1, l2p2, l1p2);
512
- if (o1 !== o2 && o3 !== o4) return true;
513
- if (o1 === 0 && onSegment(l1p1, l2p1, l1p2)) return true;
514
- if (o2 === 0 && onSegment(l1p1, l2p2, l1p2)) return true;
515
- if (o3 === 0 && onSegment(l2p1, l1p1, l2p2)) return true;
516
- if (o4 === 0 && onSegment(l2p1, l1p2, l2p2)) return true;
517
- return false;
518
- };
519
- const boxPoints = this.points;
520
- for (let i = 0; i < 4; i++) {
521
- const bp1 = boxPoints[i];
522
- const bp2 = boxPoints[(i + 1) % 4];
523
- for (let j = 0; j < 4; j++) {
524
- const rp1 = rectangle.points[j];
525
- const rp2 = rectangle.points[(j + 1) % 4];
526
- if (doIntersect(bp1, bp2, rp1, rp2)) return true;
415
+ return !0;
416
+ }, i = (s, r, c, a) => {
417
+ const h = (u, x, w) => {
418
+ const S = (x.y - u.y) * (w.x - x.x) - (x.x - u.x) * (w.y - x.y);
419
+ return S === 0 ? 0 : S > 0 ? 1 : 2;
420
+ }, l = (u, x, w) => Math.min(u.x, w.x) <= x.x && x.x <= Math.max(u.x, w.x) && Math.min(u.y, w.y) <= x.y && x.y <= Math.max(u.y, w.y), d = h(s, r, c), f = h(s, r, a), m = h(c, a, s), g = h(c, a, r);
421
+ return !!(d !== f && m !== g || d === 0 && l(s, c, r) || f === 0 && l(s, a, r) || m === 0 && l(c, s, a) || g === 0 && l(c, r, a));
422
+ }, o = this.points;
423
+ for (let s = 0; s < 4; s++) {
424
+ const r = o[s], c = o[(s + 1) % 4];
425
+ for (let a = 0; a < 4; a++) {
426
+ const h = t.points[a], l = t.points[(a + 1) % 4];
427
+ if (i(r, c, h, l)) return !0;
527
428
  }
528
429
  }
529
- for (let p of rectangle.points) {
530
- if (isPointInBox(p)) return true;
531
- }
532
- for (let p of boxPoints) {
533
- if (isPointInRect(p)) return true;
534
- }
535
- return false;
430
+ for (let s of t.points)
431
+ if (e(s)) return !0;
432
+ for (let s of o)
433
+ if (n(s)) return !0;
434
+ return !1;
536
435
  }
537
436
  /**
538
437
  * 判断矩形是在包围盒内
539
438
  * @param rectangle
540
439
  */
541
- containsRectangle(rectangle) {
542
- return rectangle.points.every(
543
- (p) => this.minX <= p.x && p.x <= this.maxX && this.minY <= p.y && p.y <= this.maxY
440
+ containsRectangle(t) {
441
+ return t.points.every(
442
+ (e) => this.minX <= e.x && e.x <= this.maxX && this.minY <= e.y && e.y <= this.maxY
544
443
  );
545
444
  }
546
445
  /**
547
446
  * 判断包围盒与包围盒相交
548
447
  * @param box
549
448
  */
550
- intersectBox(box) {
551
- return !(this.maxX < box.minX || this.minX > box.maxX || this.maxY < box.minY || this.minY > box.maxY);
449
+ intersectBox(t) {
450
+ return !(this.maxX < t.minX || this.minX > t.maxX || this.maxY < t.minY || this.minY > t.maxY);
552
451
  }
553
452
  /**
554
453
  * 判断包围盒是在包围盒内
555
454
  * @param box
556
455
  */
557
- containsBox(box) {
558
- return this.minX <= box.minX && box.maxX <= this.maxX && this.minY <= box.minY && box.maxY <= this.maxY;
456
+ containsBox(t) {
457
+ return this.minX <= t.minX && t.maxX <= this.maxX && this.minY <= t.minY && t.maxY <= this.maxY;
559
458
  }
560
459
  /** 判断点是在包围盒内
561
460
  * @param point
562
461
  */
563
- containsPoint(point) {
564
- return point.x >= this.minX && point.x <= this.maxX && point.y >= this.minY && point.y <= this.maxY;
462
+ containsPoint(t) {
463
+ return t.x >= this.minX && t.x <= this.maxX && t.y >= this.minY && t.y <= this.maxY;
565
464
  }
566
465
  /**
567
466
  *
@@ -571,12 +470,8 @@ class Box2 {
571
470
  * @param maxY
572
471
  * @returns
573
472
  */
574
- set(minX, minY, maxX, maxY) {
575
- this.minX = minX;
576
- this.minY = minY;
577
- this.maxX = maxX;
578
- this.maxY = maxY;
579
- return this;
473
+ set(t, e, n, i) {
474
+ return this.minX = t, this.minY = e, this.maxX = n, this.maxY = i, this;
580
475
  }
581
476
  /**
582
477
  *
@@ -585,57 +480,55 @@ class Box2 {
585
480
  * @param mode
586
481
  * @returns
587
482
  */
588
- scaleSize(maxWidth, maxHeight, mode = "min") {
589
- const scaleX = maxWidth / this.width;
590
- const scaleY = maxHeight / this.height;
591
- return Math[mode](scaleX, scaleY);
483
+ scaleSize(t, e, n = "min") {
484
+ const i = t / this.width, o = e / this.height;
485
+ return Math[n](i, o);
592
486
  }
593
487
  /**
594
488
  *
595
489
  * @param scalar
596
490
  * @returns
597
491
  */
598
- multiplyScalar(scalar) {
599
- this.minX *= scalar;
600
- this.minY *= scalar;
601
- this.maxX *= scalar;
602
- this.maxY *= scalar;
603
- return this;
492
+ multiplyScalar(t) {
493
+ return this.minX *= t, this.minY *= t, this.maxX *= t, this.maxY *= t, this;
604
494
  }
605
- expansion(w) {
606
- this.minX -= w;
607
- this.minY -= w;
608
- this.maxX += w;
609
- this.maxY += w;
610
- return this;
495
+ expansion(t) {
496
+ return this.minX -= t, this.minY -= t, this.maxX += t, this.maxY += t, this;
611
497
  }
612
498
  /**
613
499
  *
614
500
  * @returns
615
501
  */
616
502
  clone() {
617
- return new Box2(this.minX, this.maxX, this.minY, this.maxY);
503
+ return new v(this.minX, this.maxX, this.minY, this.maxY);
618
504
  }
619
505
  /**
620
506
  *
621
507
  * @param points
622
508
  * @returns
623
509
  */
624
- static fromByPoints(...points) {
625
- const xList = [], yList = [];
626
- points.forEach((p) => {
627
- xList.push(p.x);
628
- yList.push(p.y);
629
- });
630
- return new Box2(
631
- Math.min(...xList),
632
- Math.max(...xList),
633
- Math.min(...yList),
634
- Math.max(...yList)
510
+ static fromByPoints(...t) {
511
+ const e = [], n = [];
512
+ return t.forEach((i) => {
513
+ e.push(i.x), n.push(i.y);
514
+ }), new v(
515
+ Math.min(...e),
516
+ Math.max(...e),
517
+ Math.min(...n),
518
+ Math.max(...n)
635
519
  );
636
520
  }
637
521
  }
638
- class Rectangle {
522
+ function O(y) {
523
+ if (y === null || typeof y != "object") return y;
524
+ if (y instanceof Date) return new Date(y.getTime());
525
+ if (Array.isArray(y)) return y.map(O);
526
+ const t = {};
527
+ for (const e in y)
528
+ Object.prototype.hasOwnProperty.call(y, e) && (t[e] = O(y[e]));
529
+ return t;
530
+ }
531
+ class N {
639
532
  points;
640
533
  get p0() {
641
534
  return this.points[0];
@@ -650,16 +543,15 @@ class Rectangle {
650
543
  return this.points[3];
651
544
  }
652
545
  get path() {
653
- return this.points.flatMap((p, i) => {
654
- const np = this.points[(i + 1) % this.points.length];
655
- return [p.x, p.y, 0, np.x, np.y, 0];
546
+ return this.points.flatMap((t, e) => {
547
+ const n = this.points[(e + 1) % this.points.length];
548
+ return [t.x, t.y, 0, n.x, n.y, 0];
656
549
  });
657
550
  }
658
- path2D(callback) {
659
- return this.points.flatMap((p, i) => {
660
- const np = this.points[(i + 1) % this.points.length];
661
- callback && callback(new Point(p.x, p.y), new Point(np.x, np.y));
662
- return [p.x, p.y, np.x, np.y];
551
+ path2D(t) {
552
+ return this.points.flatMap((e, n) => {
553
+ const i = this.points[(n + 1) % this.points.length];
554
+ return t && t(new p(e.x, e.y), new p(i.x, i.y)), [e.x, e.y, i.x, i.y];
663
555
  });
664
556
  }
665
557
  createGeometry() {
@@ -670,85 +562,58 @@ class Rectangle {
670
562
  this.p2,
671
563
  this.p0,
672
564
  this.p3
673
- ].flatMap((p) => [p.x, p.y, 0]);
565
+ ].flatMap((t) => [t.x, t.y, 0]);
674
566
  }
675
- constructor(points) {
676
- if (points.length !== 4) {
567
+ constructor(t) {
568
+ if (t.length !== 4)
677
569
  throw new Error("Rectangle must be defined by exactly 4 points");
678
- }
679
- this.points = points;
570
+ this.points = t;
680
571
  }
681
572
  /**
682
573
  * 判断线段是否与矩形相交
683
574
  * @param line 线段
684
575
  * @returns 是否与矩形相交
685
576
  */
686
- intersectLineSegment(line) {
687
- if (line.points.length !== 2) {
577
+ intersectLineSegment(t) {
578
+ if (t.points.length !== 2)
688
579
  throw new Error("LineSegment must have exactly 2 points");
689
- }
690
- const [p1, p2] = line.points;
691
- const doIntersect = (l1p1, l1p2, l2p1, l2p2) => {
692
- const orientation = (p, q, r) => {
693
- const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
694
- if (val === 0) return 0;
695
- return val > 0 ? 1 : 2;
696
- };
697
- const onSegment = (p, q, r) => {
698
- return Math.min(p.x, r.x) <= q.x && q.x <= Math.max(p.x, r.x) && Math.min(p.y, r.y) <= q.y && q.y <= Math.max(p.y, r.y);
699
- };
700
- const o1 = orientation(l1p1, l1p2, l2p1);
701
- const o2 = orientation(l1p1, l1p2, l2p2);
702
- const o3 = orientation(l2p1, l2p2, l1p1);
703
- const o4 = orientation(l2p1, l2p2, l1p2);
704
- if (o1 !== o2 && o3 !== o4) return true;
705
- if (o1 === 0 && onSegment(l1p1, l2p1, l1p2)) return true;
706
- if (o2 === 0 && onSegment(l1p1, l2p2, l1p2)) return true;
707
- if (o3 === 0 && onSegment(l2p1, l1p1, l2p2)) return true;
708
- if (o4 === 0 && onSegment(l2p1, l1p2, l2p2)) return true;
709
- return false;
580
+ const [e, n] = t.points, i = (o, s, r, c) => {
581
+ const a = (g, u, x) => {
582
+ const w = (u.y - g.y) * (x.x - u.x) - (u.x - g.x) * (x.y - u.y);
583
+ return w === 0 ? 0 : w > 0 ? 1 : 2;
584
+ }, h = (g, u, x) => Math.min(g.x, x.x) <= u.x && u.x <= Math.max(g.x, x.x) && Math.min(g.y, x.y) <= u.y && u.y <= Math.max(g.y, x.y), l = a(o, s, r), d = a(o, s, c), f = a(r, c, o), m = a(r, c, s);
585
+ return !!(l !== d && f !== m || l === 0 && h(o, r, s) || d === 0 && h(o, c, s) || f === 0 && h(r, o, c) || m === 0 && h(r, s, c));
710
586
  };
711
- for (let i = 0; i < 4; i++) {
712
- const rectP1 = this.points[i];
713
- const rectP2 = this.points[(i + 1) % 4];
714
- if (doIntersect(p1, p2, rectP1, rectP2)) {
715
- return true;
716
- }
717
- }
718
- if (this.containsLineSegment(line)) {
719
- return true;
587
+ for (let o = 0; o < 4; o++) {
588
+ const s = this.points[o], r = this.points[(o + 1) % 4];
589
+ if (i(e, n, s, r))
590
+ return !0;
720
591
  }
721
- return false;
592
+ return !!this.containsLineSegment(t);
722
593
  }
723
594
  /**
724
595
  * 判断线段是否完全位于矩形内部
725
596
  * @param line 线段
726
597
  * @returns 是否完全在矩形内部
727
598
  */
728
- containsLineSegment(line) {
729
- if (line.points.length !== 2) {
599
+ containsLineSegment(t) {
600
+ if (t.points.length !== 2)
730
601
  throw new Error("LineSegment must have exactly 2 points");
731
- }
732
- const isPointInRectangle = (point) => {
733
- let sign = 0;
734
- for (let i = 0; i < 4; i++) {
735
- const p1 = this.points[i];
736
- const p2 = this.points[(i + 1) % 4];
737
- const edge = { x: p2.x - p1.x, y: p2.y - p1.y };
738
- const toPoint = { x: point.x - p1.x, y: point.y - p1.y };
739
- const cross = edge.x * toPoint.y - edge.y * toPoint.x;
740
- if (cross === 0) {
741
- const t = edge.x !== 0 ? (point.x - p1.x) / edge.x : (point.y - p1.y) / edge.y;
742
- if (t >= 0 && t <= 1) return true;
602
+ const e = (n) => {
603
+ let i = 0;
604
+ for (let o = 0; o < 4; o++) {
605
+ const s = this.points[o], r = this.points[(o + 1) % 4], c = { x: r.x - s.x, y: r.y - s.y }, a = { x: n.x - s.x, y: n.y - s.y }, h = c.x * a.y - c.y * a.x;
606
+ if (h === 0) {
607
+ const l = c.x !== 0 ? (n.x - s.x) / c.x : (n.y - s.y) / c.y;
608
+ if (l >= 0 && l <= 1) return !0;
743
609
  } else {
744
- const currentSign = cross > 0 ? 1 : -1;
745
- if (sign === 0) sign = currentSign;
746
- if (sign !== currentSign) return false;
610
+ const l = h > 0 ? 1 : -1;
611
+ if (i === 0 && (i = l), i !== l) return !1;
747
612
  }
748
613
  }
749
- return true;
614
+ return !0;
750
615
  };
751
- return isPointInRectangle(line.points[0]) && isPointInRectangle(line.points[1]);
616
+ return e(t.points[0]) && e(t.points[1]);
752
617
  }
753
618
  /**
754
619
  * 判断矩形是否与矩形相交
@@ -756,64 +621,53 @@ class Rectangle {
756
621
  * @param rectangle 矩形
757
622
  * @returns 是否与矩形相交
758
623
  */
759
- intersectRectangle(rectangle) {
760
- const axes = [];
761
- for (let i = 0; i < 4; i++) {
762
- const p1 = this.points[i];
763
- const p2 = this.points[(i + 1) % 4];
764
- axes.push(p1.normal(p2));
624
+ intersectRectangle(t) {
625
+ const e = [];
626
+ for (let o = 0; o < 4; o++) {
627
+ const s = this.points[o], r = this.points[(o + 1) % 4];
628
+ e.push(s.normal(r));
765
629
  }
766
- for (let i = 0; i < 4; i++) {
767
- const p1 = rectangle.points[i];
768
- const p2 = rectangle.points[(i + 1) % 4];
769
- axes.push(p1.normal(p2));
630
+ for (let o = 0; o < 4; o++) {
631
+ const s = t.points[o], r = t.points[(o + 1) % 4];
632
+ e.push(s.normal(r));
770
633
  }
771
- function projectRectangle(rect, axis) {
772
- const projections = rect.points.map((point) => point.dot(axis));
773
- return [Math.min(...projections), Math.max(...projections)];
634
+ function n(o, s) {
635
+ const r = o.points.map((c) => c.dot(s));
636
+ return [Math.min(...r), Math.max(...r)];
774
637
  }
775
- function isProjectionOverlap(proj1, proj2) {
776
- return proj1[0] < proj2[1] && proj2[0] < proj1[1];
638
+ function i(o, s) {
639
+ return o[0] < s[1] && s[0] < o[1];
777
640
  }
778
- for (const axis of axes) {
779
- const proj1 = projectRectangle(this, axis);
780
- const proj2 = projectRectangle(rectangle, axis);
781
- if (!isProjectionOverlap(proj1, proj2)) {
782
- return false;
783
- }
641
+ for (const o of e) {
642
+ const s = n(this, o), r = n(t, o);
643
+ if (!i(s, r))
644
+ return !1;
784
645
  }
785
- return true;
646
+ return !0;
786
647
  }
787
648
  /**
788
649
  * 判断点是否完全位于矩形内部
789
650
  * @param point
790
651
  */
791
- containsPoint(point) {
792
- let positiveCount = 0;
793
- let negativeCount = 0;
652
+ containsPoint(t) {
653
+ let e = 0, n = 0;
794
654
  for (let i = 0; i < 4; i++) {
795
- const p1 = this.points[i];
796
- const p2 = this.points[(i + 1) % 4];
797
- const cross = (p2.x - p1.x) * (point.y - p1.y) - (p2.y - p1.y) * (point.x - p1.x);
798
- if (cross > 0) positiveCount++;
799
- else if (cross < 0) negativeCount++;
800
- else return false;
655
+ const o = this.points[i], s = this.points[(i + 1) % 4], r = (s.x - o.x) * (t.y - o.y) - (s.y - o.y) * (t.x - o.x);
656
+ if (r > 0) e++;
657
+ else if (r < 0) n++;
658
+ else return !1;
801
659
  }
802
- return positiveCount === 4 || negativeCount === 4;
660
+ return e === 4 || n === 4;
803
661
  }
804
662
  /**
805
663
  *
806
664
  * @returns
807
665
  */
808
666
  toBox() {
809
- let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
810
- this.points.forEach((p) => {
811
- maxX = Math.max(p.x, maxX);
812
- minX = Math.min(p.x, minX);
813
- maxY = Math.max(p.x, maxY);
814
- minY = Math.min(p.x, minY);
815
- });
816
- return new Box2(minX, maxX, minY, maxY);
667
+ let t = 1 / 0, e = -1 / 0, n = 1 / 0, i = -1 / 0;
668
+ return this.points.forEach((o) => {
669
+ e = Math.max(o.x, e), t = Math.min(o.x, t), i = Math.max(o.x, i), n = Math.min(o.x, n);
670
+ }), new v(t, e, n, i);
817
671
  }
818
672
  /**
819
673
  *
@@ -821,24 +675,22 @@ class Rectangle {
821
675
  * @param width
822
676
  * @returns
823
677
  */
824
- static fromByLineSegment(line, width = 0.1, horizontal = false, hScale = 0.5) {
825
- const p1 = line.points[0], p2 = line.points[1], normal = p2.normal(p1), pDirect = horizontal ? p2.direction(p1).mutiplyScalar(width * hScale) : Point.zero(), nDirect = horizontal ? p1.direction(p2).mutiplyScalar(width * hScale) : Point.zero();
826
- const offsetX = normal.x * width * 0.5;
827
- const offsetY = normal.y * width * 0.5;
828
- return new Rectangle([
829
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
830
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
831
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect),
832
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect)
678
+ static fromByLineSegment(t, e = 0.1, n = !1, i = 0.5) {
679
+ const o = t.points[0], s = t.points[1], r = s.normal(o), c = n ? s.direction(o).mutiplyScalar(e * i) : p.zero(), a = n ? o.direction(s).mutiplyScalar(e * i) : p.zero(), h = r.x * e * 0.5, l = r.y * e * 0.5;
680
+ return new N([
681
+ new p(o.x + h, o.y + l).add(a),
682
+ new p(s.x + h, s.y + l).add(c),
683
+ new p(s.x - h, s.y - l).add(c),
684
+ new p(o.x - h, o.y - l).add(a)
833
685
  ]);
834
686
  }
835
687
  }
836
- class LineSegment {
837
- points = [new Point(), new Point()];
688
+ class L {
689
+ points = [new p(), new p()];
838
690
  userData = {};
839
691
  line;
840
692
  get center() {
841
- return new Point(
693
+ return new p(
842
694
  this.points[0].x + (this.points[1].x - this.points[0].x) * 0.5,
843
695
  this.points[0].y + (this.points[1].y - this.points[0].y) * 0.5
844
696
  );
@@ -849,71 +701,84 @@ class LineSegment {
849
701
  get end() {
850
702
  return this.points[1];
851
703
  }
852
- constructor(p1 = new Point(), p2 = new Point()) {
853
- this.points = [p1, p2];
704
+ constructor(t = new p(), e = new p()) {
705
+ this.points = [t, e];
706
+ }
707
+ set(t, e) {
708
+ return this.start.copy(t), this.end.copy(e), this;
709
+ }
710
+ /**
711
+ * 是否有相同端点
712
+ * @param line
713
+ * @returns
714
+ */
715
+ sameEndpoint(t) {
716
+ return this.start.equal(t.start) || this.start.equal(t.end) || this.end.equal(t.start) || this.end.equal(t.end);
717
+ }
718
+ /**
719
+ * 相同端点是否为开始
720
+ * @param line
721
+ * @returns
722
+ */
723
+ sameEndpointAsStart(t) {
724
+ return this.start.equal(t.start) || this.start.equal(t.end);
725
+ }
726
+ /**
727
+ * 相同端点是否为结束
728
+ * @param line
729
+ * @returns
730
+ */
731
+ sameEndpointAsEnd(t) {
732
+ return this.end.equal(t.start) || this.end.equal(t.end);
854
733
  }
855
734
  /** 膨胀
856
735
  * @description 向线段的两个端点分别膨胀 width
857
736
  * @param width
858
737
  */
859
- expansion(width, direction = "all") {
860
- const step = this.direction().multiplyScalar(width);
861
- if (direction === "end" || direction === "all") this.end.add(step);
862
- if (direction === "start" || direction === "all") this.start.add(step.multiplyScalar(-1));
863
- return this;
738
+ expansion(t, e = "all") {
739
+ const n = this.direction().multiplyScalar(t);
740
+ return (e === "end" || e === "all") && this.end.add(n), (e === "start" || e === "all") && this.start.add(n.multiplyScalar(-1)), this;
864
741
  }
865
742
  /** 向前
866
743
  * @description 向前移动 width
867
744
  * @param width
868
745
  */
869
- forward(width) {
870
- const step = this.direction().multiplyScalar(width);
871
- this.start.add(step);
872
- this.end.add(step);
873
- return this;
746
+ forward(t) {
747
+ const e = this.direction().multiplyScalar(t);
748
+ return this.start.add(e), this.end.add(e), this;
874
749
  }
875
750
  /** 向前
876
751
  * @description 向前移动 width
877
752
  * @param width
878
753
  */
879
- backward(width) {
880
- const step = this.direction().multiplyScalar(-width);
881
- this.start.add(step);
882
- this.end.add(step);
883
- return this;
754
+ backward(t) {
755
+ const e = this.direction().multiplyScalar(-t);
756
+ return this.start.add(e), this.end.add(e), this;
884
757
  }
885
758
  /**
886
759
  * 向指定方向平移
887
760
  * @param direct
888
761
  * @param size
889
762
  */
890
- directionMove(direct, size) {
891
- const step = direct.clone().multiplyScalar(size);
892
- this.start.add(step);
893
- this.end.add(step);
894
- return this;
763
+ directionMove(t, e) {
764
+ const n = t.clone().multiplyScalar(e);
765
+ return this.start.add(n), this.end.add(n), this;
895
766
  }
896
767
  /** 膨胀为矩形
897
768
  *
898
769
  * @param width
899
770
  * @returns {Rectangle}
900
771
  */
901
- expandToRectangle(width = 0.1, direct = "all") {
902
- const p1 = this.start, p2 = this.end;
903
- const normal = p2.normal(p1);
904
- const pDirect = direct === "bothSides" ? Point.zero() : p2.direction(p1).mutiplyScalar(width * 0.5);
905
- const nDirect = direct === "bothSides" ? Point.zero() : p1.direction(p2).mutiplyScalar(width * 0.5);
906
- const offsetX = normal.x * width * 0.5;
907
- const offsetY = normal.y * width * 0.5;
908
- const point = [
772
+ expandToRectangle(t = 0.1, e = "all") {
773
+ const n = this.start, i = this.end, o = i.normal(n), s = e === "bothSides" ? p.zero() : i.direction(n).mutiplyScalar(t * 0.5), r = e === "bothSides" ? p.zero() : n.direction(i).mutiplyScalar(t * 0.5), c = o.x * t * 0.5, a = o.y * t * 0.5, h = [
909
774
  // 第一条线
910
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
911
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
775
+ new p(n.x + c, n.y + a).add(r),
776
+ new p(i.x + c, i.y + a).add(s),
912
777
  // 第二条线
913
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
914
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
778
+ new p(n.x - c, n.y - a).add(r),
779
+ new p(i.x - c, i.y - a).add(s)
915
780
  ];
916
- return new Rectangle([0, 1, 3, 2].map((i) => point[i]));
781
+ return new N([0, 1, 3, 2].map((l) => h[l]));
917
782
  }
918
783
  /**
919
784
  * 计算线段的长度
@@ -947,50 +812,27 @@ class LineSegment {
947
812
  * @param line 要投影的线段
948
813
  * @returns 投影并裁剪后的线段
949
814
  */
950
- projectLineSegment(line) {
951
- if (line.points.length !== 2 || this.points.length !== 2) {
815
+ projectLineSegment(t) {
816
+ if (t.points.length !== 2 || this.points.length !== 2)
952
817
  throw new Error("每条线段必须由两个点定义");
953
- }
954
- const [p1, p2] = line.points;
955
- const [q1, q2] = this.points;
956
- const dir = new Point(q2.x - q1.x, q2.y - q1.y);
957
- if (dir.x === 0 && dir.y === 0) {
818
+ const [e, n] = t.points, [i, o] = this.points, s = new p(o.x - i.x, o.y - i.y);
819
+ if (s.x === 0 && s.y === 0)
958
820
  throw new Error("投影目标线段的两个点不能重合");
959
- }
960
- const projectPoint = (point) => {
961
- const pq = new Point(point.x - q1.x, point.y - q1.y);
962
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
963
- const dotProduct = pq.x * dir.x + pq.y * dir.y;
964
- const t = dotProduct / dirLengthSquared;
965
- const projX = q1.x + t * dir.x;
966
- const projY = q1.y + t * dir.y;
967
- return new Point(projX, projY);
821
+ const r = (m) => {
822
+ const g = new p(m.x - i.x, m.y - i.y), u = s.x * s.x + s.y * s.y, w = (g.x * s.x + g.y * s.y) / u, S = i.x + w * s.x, b = i.y + w * s.y;
823
+ return new p(S, b);
968
824
  };
969
- let projP1 = projectPoint(p1);
970
- let projP2 = projectPoint(p2);
971
- const getT = (point) => {
972
- const pq = new Point(point.x - q1.x, point.y - q1.y);
973
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
974
- return (pq.x * dir.x + pq.y * dir.y) / dirLengthSquared;
825
+ let c = r(e), a = r(n);
826
+ const h = (m) => {
827
+ const g = new p(m.x - i.x, m.y - i.y), u = s.x * s.x + s.y * s.y;
828
+ return (g.x * s.x + g.y * s.y) / u;
975
829
  };
976
- let t1 = getT(projP1);
977
- let t2 = getT(projP2);
978
- const clampPoint = (t) => {
979
- const clampedT = Math.max(0, Math.min(1, t));
980
- const x = q1.x + clampedT * dir.x;
981
- const y = q1.y + clampedT * dir.y;
982
- return new Point(x, y);
830
+ let l = h(c), d = h(a);
831
+ const f = (m) => {
832
+ const g = Math.max(0, Math.min(1, m)), u = i.x + g * s.x, x = i.y + g * s.y;
833
+ return new p(u, x);
983
834
  };
984
- if (t1 < 0 || t1 > 1) {
985
- projP1 = clampPoint(t1);
986
- }
987
- if (t2 < 0 || t2 > 1) {
988
- projP2 = clampPoint(t2);
989
- }
990
- if (projP1.x === projP2.x && projP1.y === projP2.y) {
991
- return new LineSegment(projP1, projP1);
992
- }
993
- return new LineSegment(projP1, projP2);
835
+ return (l < 0 || l > 1) && (c = f(l)), (d < 0 || d > 1) && (a = f(d)), c.x === a.x && c.y === a.y ? new L(c, c) : new L(c, a);
994
836
  }
995
837
  /**
996
838
  * 计算一条线段在另一条直线上的投影
@@ -998,155 +840,107 @@ class LineSegment {
998
840
  * @param clip 是否裁剪超出目标线段的部分,默认裁剪
999
841
  * @returns 投影并裁剪后的线段
1000
842
  */
1001
- projectPoint(p1, clip = true) {
1002
- const [q1, q2] = this.points;
1003
- const dir = new Point(q2.x - q1.x, q2.y - q1.y);
1004
- if (dir.x === 0 && dir.y === 0) {
843
+ projectPoint(t, e = !0) {
844
+ const [n, i] = this.points, o = new p(i.x - n.x, i.y - n.y);
845
+ if (o.x === 0 && o.y === 0)
1005
846
  throw new Error("投影目标线段的两个点不能重合");
1006
- }
1007
- const projectPoint = (point) => {
1008
- const pq = new Point(point.x - q1.x, point.y - q1.y);
1009
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
1010
- const dotProduct = pq.x * dir.x + pq.y * dir.y;
1011
- const t = dotProduct / dirLengthSquared;
1012
- const projX = q1.x + t * dir.x;
1013
- const projY = q1.y + t * dir.y;
1014
- return new Point(projX, projY);
1015
- };
1016
- let projP1 = projectPoint(p1);
1017
- if (!clip) return projP1;
1018
- const getT = (point) => {
1019
- const pq = new Point(point.x - q1.x, point.y - q1.y);
1020
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
1021
- return (pq.x * dir.x + pq.y * dir.y) / dirLengthSquared;
1022
- };
1023
- let t1 = getT(projP1);
1024
- if (t1 < 0 || t1 > 1) {
1025
- return null;
1026
- }
1027
- return projP1;
847
+ let r = ((h) => {
848
+ const l = new p(h.x - n.x, h.y - n.y), d = o.x * o.x + o.y * o.y, m = (l.x * o.x + l.y * o.y) / d, g = n.x + m * o.x, u = n.y + m * o.y;
849
+ return new p(g, u);
850
+ })(t);
851
+ if (!e) return r;
852
+ let a = ((h) => {
853
+ const l = new p(h.x - n.x, h.y - n.y), d = o.x * o.x + o.y * o.y;
854
+ return (l.x * o.x + l.y * o.y) / d;
855
+ })(r);
856
+ return a < 0 || a > 1 ? null : r;
1028
857
  }
1029
858
  /**
1030
859
  * 判断线段是否与另一条线段相交(包含共用端点或部分重合的情况)
1031
860
  * @param line
1032
861
  */
1033
- intersectLineSegment(line) {
1034
- const p1 = this.start;
1035
- const p2 = this.end;
1036
- const p3 = line.start;
1037
- const p4 = line.end;
1038
- function crossProduct(a, b, c) {
1039
- return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
1040
- }
1041
- function isPointOnSegment(pt, segStart, segEnd) {
1042
- return Math.min(segStart.x, segEnd.x) - 1e-10 <= pt.x && pt.x <= Math.max(segStart.x, segEnd.x) + 1e-10 && Math.min(segStart.y, segEnd.y) - 1e-10 <= pt.y && pt.y <= Math.max(segStart.y, segEnd.y) + 1e-10;
1043
- }
1044
- const d1 = crossProduct(p1, p2, p3);
1045
- const d2 = crossProduct(p1, p2, p4);
1046
- const d3 = crossProduct(p3, p4, p1);
1047
- const d4 = crossProduct(p3, p4, p2);
1048
- if (d1 * d2 < 0 && d3 * d4 < 0) {
1049
- return true;
862
+ intersectLineSegment(t) {
863
+ const e = this.start, n = this.end, i = t.start, o = t.end;
864
+ function s(d, f, m) {
865
+ return (f.x - d.x) * (m.y - d.y) - (f.y - d.y) * (m.x - d.x);
1050
866
  }
1051
- if (Math.abs(d1) < 1e-10 && isPointOnSegment(p3, p1, p2)) {
1052
- return true;
867
+ function r(d, f, m) {
868
+ return Math.min(f.x, m.x) - 1e-10 <= d.x && d.x <= Math.max(f.x, m.x) + 1e-10 && Math.min(f.y, m.y) - 1e-10 <= d.y && d.y <= Math.max(f.y, m.y) + 1e-10;
1053
869
  }
1054
- if (Math.abs(d2) < 1e-10 && isPointOnSegment(p4, p1, p2)) {
1055
- return true;
1056
- }
1057
- if (Math.abs(d3) < 1e-10 && isPointOnSegment(p1, p3, p4)) {
1058
- return true;
1059
- }
1060
- if (Math.abs(d4) < 1e-10 && isPointOnSegment(p2, p3, p4)) {
1061
- return true;
1062
- }
1063
- return false;
870
+ const c = s(e, n, i), a = s(e, n, o), h = s(i, o, e), l = s(i, o, n);
871
+ return !!(c * a < 0 && h * l < 0 || Math.abs(c) < 1e-10 && r(i, e, n) || Math.abs(a) < 1e-10 && r(o, e, n) || Math.abs(h) < 1e-10 && r(e, i, o) || Math.abs(l) < 1e-10 && r(n, i, o));
1064
872
  }
1065
873
  /**
1066
874
  * 获取交点
1067
875
  * @param line
1068
876
  * @returns
1069
877
  */
1070
- getIntersection(line) {
1071
- const p1 = this.start;
1072
- const p2 = this.end;
1073
- const p3 = line.start;
1074
- const p4 = line.end;
1075
- const denom = (p1.x - p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x - p4.x);
1076
- if (Math.abs(denom) < 1e-10) {
878
+ getIntersection(t) {
879
+ const e = this.start, n = this.end, i = t.start, o = t.end, s = (e.x - n.x) * (i.y - o.y) - (e.y - n.y) * (i.x - o.x);
880
+ if (Math.abs(s) < 1e-10)
1077
881
  return null;
1078
- }
1079
- const t = ((p1.x - p3.x) * (p3.y - p4.y) - (p1.y - p3.y) * (p3.x - p4.x)) / denom;
1080
- const x = p1.x + t * (p2.x - p1.x);
1081
- const y = p1.y + t * (p2.y - p1.y);
1082
- return new Point(x, y);
882
+ const r = ((e.x - i.x) * (i.y - o.y) - (e.y - i.y) * (i.x - o.x)) / s, c = e.x + r * (n.x - e.x), a = e.y + r * (n.y - e.y);
883
+ return new p(c, a);
1083
884
  }
1084
885
  /**
1085
886
  * 获取两条线段夹角
1086
887
  * @param line
1087
888
  */
1088
- includedAngle(line) {
1089
- const d1 = this.direction(), d2 = line.direction();
1090
- return d1.angleBetween(d2) / (Math.PI / 180);
889
+ includedAngle(t) {
890
+ const e = this.direction(), n = t.direction();
891
+ return e.angleBetween(n) / (Math.PI / 180);
1091
892
  }
1092
893
  /**
1093
894
  * 两条线段方向是否一致
1094
895
  * @param line
1095
896
  */
1096
- directionEqual(line, errAngle = 0.1) {
1097
- return this.includedAngle(line) < errAngle;
897
+ directionEqual(t, e = 0.1) {
898
+ return this.includedAngle(t) < e;
1098
899
  }
1099
900
  /**
1100
901
  * 两条线段方向相反否一致
1101
902
  * @param line
1102
903
  */
1103
- directionOpposite(line, errAngle = 0.1) {
1104
- return 180 - this.includedAngle(line) < errAngle;
904
+ directionOpposite(t, e = 0.1) {
905
+ return 180 - this.includedAngle(t) < e;
1105
906
  }
1106
907
  /**
1107
908
  * 判断两条线是否平行
1108
909
  * @param line
1109
910
  */
1110
- isParallel(line, errAngle = 4) {
1111
- const angle = this.includedAngle(line);
1112
- return angle < errAngle || angle > 180 - errAngle;
911
+ isParallel(t, e = 4) {
912
+ const n = this.includedAngle(t);
913
+ return n < e || n > 180 - e;
1113
914
  }
1114
915
  /**
1115
916
  * 判断两条直线是否重合
1116
917
  * @param line
1117
918
  * @returns
1118
919
  */
1119
- areLinesCoincident(line) {
1120
- const p1 = this.start, p2 = this.end, p3 = line.start, p4 = line.end;
1121
- const m1 = (p2.y - p1.y) / (p2.x - p1.x);
1122
- const b1 = p1.y - m1 * p1.x;
1123
- const m2 = (p4.y - p3.y) / (p4.x - p3.x);
1124
- const b2 = p3.y - m2 * p3.x;
1125
- if (!isFinite(m1) && !isFinite(m2)) {
1126
- return p1.x === p3.x && p2.x === p3.x;
1127
- }
1128
- return Math.abs(m1 - m2) < 1e-3 && Math.abs(b1 - b2) < 1e-3;
920
+ areLinesCoincident(t) {
921
+ const e = this.start, n = this.end, i = t.start, o = t.end, s = (n.y - e.y) / (n.x - e.x), r = e.y - s * e.x, c = (o.y - i.y) / (o.x - i.x), a = i.y - c * i.x;
922
+ return !isFinite(s) && !isFinite(c) ? e.x === i.x && n.x === i.x : Math.abs(s - c) < 1e-3 && Math.abs(r - a) < 1e-3;
1129
923
  }
1130
924
  clone() {
1131
- return new LineSegment(
925
+ const t = new L(
1132
926
  this.points[0].clone(),
1133
927
  this.points[1].clone()
1134
928
  );
929
+ return t.userData = O(this.userData), t;
1135
930
  }
1136
931
  }
1137
- async function include(path, exportDefault = true) {
1138
- if (typeof global !== "undefined" && typeof require !== "undefined") {
1139
- return require(path);
1140
- } else {
1141
- let pack = await import(
932
+ async function G(y, t = !0) {
933
+ if (typeof global < "u" && typeof require < "u")
934
+ return require(y);
935
+ {
936
+ let e = await import(
1142
937
  /* @vite-ignore */
1143
- path
938
+ y
1144
939
  );
1145
- if (exportDefault) pack = pack.default;
1146
- return pack;
940
+ return t && (e = e.default), e;
1147
941
  }
1148
942
  }
1149
- const units = {
943
+ const st = {
1150
944
  Unitless: 1,
1151
945
  // 无单位,1米 = 1(无单位)
1152
946
  Inches: 39.37007874015748,
@@ -1190,31 +984,27 @@ const units = {
1190
984
  Parsecs: 3240779289666404e-32
1191
985
  // 秒差距,1米 ≈ 0.00000000000000003240779289666404秒差距
1192
986
  };
1193
- function pathToLines(path) {
1194
- const lineSegments = [];
1195
- for (let i = 0; i < path.length; i++) {
1196
- lineSegments.push(new LineSegment(
1197
- path[i].clone(),
1198
- path[(i + 1) % path.length].clone()
987
+ function k(y) {
988
+ const t = [];
989
+ for (let e = 0; e < y.length; e++)
990
+ t.push(new L(
991
+ y[e].clone(),
992
+ y[(e + 1) % y.length].clone()
1199
993
  ));
1200
- }
1201
- return lineSegments;
994
+ return t;
1202
995
  }
1203
- function linesToPath(lineSegments) {
1204
- return lineSegments.flatMap((line, index2) => {
1205
- if (index2 === lineSegments.length - 1) [...line.points, lineSegments[0].points[0]];
1206
- return [line.points[0]];
1207
- });
996
+ function J(y) {
997
+ return y.flatMap((t, e) => (e === y.length - 1 && [...t.points, y[0].points[0]], [t.points[0]]));
1208
998
  }
1209
- class Dxf extends Component {
999
+ class X extends j {
1210
1000
  static name = "Dxf";
1211
1001
  shortLine = 0.04;
1212
1002
  width = 0.04;
1213
1003
  scale = 1;
1214
1004
  originalData = [];
1215
1005
  data = [];
1216
- originalBox = new Box2(0, 0, 0, 0);
1217
- box = new Box2(0, 0, 0, 0);
1006
+ originalBox = new v(0, 0, 0, 0);
1007
+ box = new v(0, 0, 0, 0);
1218
1008
  pointsGroups = [];
1219
1009
  wallsGroup = [];
1220
1010
  doors = [];
@@ -1243,11 +1033,8 @@ class Dxf extends Component {
1243
1033
  * @param width 墙体宽度
1244
1034
  * @param scale 缩放比例
1245
1035
  */
1246
- constructor(width = 0.04, scale = 1) {
1247
- super();
1248
- this.width = width;
1249
- this.scale = scale;
1250
- this.shortLine = width * 0.4;
1036
+ constructor(t = 0.04, e = 1) {
1037
+ super(), this.width = t, this.scale = e, this.shortLine = t * 0.4;
1251
1038
  }
1252
1039
  /**
1253
1040
  * 设置
@@ -1255,52 +1042,36 @@ class Dxf extends Component {
1255
1042
  * @param width
1256
1043
  * @param scale
1257
1044
  */
1258
- async set(data, width = this.width, scale = this.scale) {
1259
- if (typeof data === "string") {
1260
- if (typeof global !== "undefined") {
1261
- const packageName = "fs";
1262
- const { default: fs } = await import(
1045
+ async set(t, e = this.width, n = this.scale) {
1046
+ if (typeof t == "string")
1047
+ if (typeof global < "u") {
1048
+ const { default: s } = await import(
1263
1049
  /* @vite-ignore */
1264
- packageName
1265
- );
1266
- const buffer = fs.readFileSync(data);
1267
- const json = JSON.parse(buffer.toString("utf-8"));
1268
- return this.set(json, width, scale);
1269
- } else {
1050
+ "fs"
1051
+ ), r = s.readFileSync(t), c = JSON.parse(r.toString("utf-8"));
1052
+ return this.set(c, e, n);
1053
+ } else
1270
1054
  throw new Error("非node环境不允许使用路径");
1271
- }
1272
- }
1273
- this.scale = scale;
1274
- this.width = width;
1275
- this.originalData = data;
1276
- this.lineSegments.length = 0;
1277
- const zList = [];
1278
- this.data = data.map(({ start, end, insetionArr, isDoor = false, isWindow, drawDoorData }, index2) => {
1279
- zList.push(start.z ?? 0, end.z ?? 0);
1280
- const lineSegment = new LineSegment(
1281
- Point.from(start).mutiplyScalar(scale),
1282
- Point.from(end).mutiplyScalar(scale)
1055
+ this.scale = n, this.width = e, this.originalData = t, this.lineSegments.length = 0;
1056
+ const i = [];
1057
+ this.data = t.map(({ start: o, end: s, insetionArr: r, isDoor: c = !1, ...a }, h) => {
1058
+ i.push(o.z ?? 0, s.z ?? 0);
1059
+ const l = new L(
1060
+ p.from(o).mutiplyScalar(n),
1061
+ p.from(s).mutiplyScalar(n)
1283
1062
  );
1284
- lineSegment.userData = { isDoor, isWindow, drawDoorData };
1285
- this.lineSegments.push(lineSegment);
1286
- return [
1287
- lineSegment.points[0],
1288
- lineSegment.points[1],
1289
- (insetionArr ?? []).map((i) => i.index),
1290
- isDoor,
1291
- index2
1063
+ return l.userData = { isDoor: c, ...a }, this.lineSegments.push(l), [
1064
+ l.points[0],
1065
+ l.points[1],
1066
+ (r ?? []).map((d) => d.index),
1067
+ c,
1068
+ h
1292
1069
  ];
1293
- });
1294
- this.originalZAverage = zList.reduce((count, num) => count + num, 0) / zList.length;
1295
- this.computedOriginalSize(data, this.originalBox);
1296
- this.dispatchEvent({
1070
+ }), this.originalZAverage = i.reduce((o, s) => o + s, 0) / i.length, this.computedOriginalSize(t, this.originalBox), this.dispatchEvent({
1297
1071
  type: "setDta",
1298
1072
  originalData: this.originalData,
1299
1073
  data: this.data
1300
- });
1301
- this.createGroups();
1302
- this.computedSize();
1303
- this.dispatchEvent({
1074
+ }), this.createGroups(), this.computedSize(), this.dispatchEvent({
1304
1075
  type: "createGroup",
1305
1076
  groups: this.pointsGroups
1306
1077
  });
@@ -1310,32 +1081,20 @@ class Dxf extends Component {
1310
1081
  * @returns
1311
1082
  */
1312
1083
  createGroups() {
1313
- const groups = [], visited = /* @__PURE__ */ new Set(), doorSet = /* @__PURE__ */ new Set(), doorVisitedRecord = /* @__PURE__ */ new Map();
1314
- const dfs = (index2, group, preIndex = -1) => {
1315
- const [start, end, insetionArr, isDoor] = this.data[index2];
1316
- visited.add(index2);
1317
- if (isDoor) {
1318
- if (!doorVisitedRecord.has(index2)) doorVisitedRecord.set(index2, []);
1319
- doorVisitedRecord.get(index2)?.push(preIndex);
1320
- return doorSet.add(this.data[index2]);
1321
- }
1322
- group.push([start, end]);
1323
- insetionArr.forEach((i) => {
1324
- if (!visited.has(i)) {
1325
- dfs(i, group, index2);
1326
- }
1084
+ const t = [], e = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map(), o = (s, r, c = -1) => {
1085
+ const [a, h, l, d] = this.data[s];
1086
+ if (e.add(s), d)
1087
+ return i.has(s) || i.set(s, []), i.get(s)?.push(c), n.add(this.data[s]);
1088
+ r.push([a, h]), l.forEach((f) => {
1089
+ e.has(f) || o(f, r, s);
1327
1090
  });
1328
1091
  };
1329
- this.data.forEach((_, index2) => {
1330
- if (!visited.has(index2)) {
1331
- const group = [];
1332
- dfs(index2, group);
1333
- groups.push(group);
1092
+ return this.data.forEach((s, r) => {
1093
+ if (!e.has(r)) {
1094
+ const c = [];
1095
+ o(r, c), t.push(c);
1334
1096
  }
1335
- });
1336
- this.doors = [...doorSet];
1337
- this.pointsGroups = groups;
1338
- return groups;
1097
+ }), this.doors = [...n], this.pointsGroups = t, t;
1339
1098
  }
1340
1099
  /** 计算当前墙体数据的边界框
1341
1100
  * @description 根据分组数据pointsGroups,计算包围盒, pointsGroups数据为缩放后数据。
@@ -1343,224 +1102,163 @@ class Dxf extends Component {
1343
1102
  * @returns
1344
1103
  */
1345
1104
  computedSize() {
1346
- const xArr = this.pointsGroups.flatMap((points) => points.flatMap((p) => [p[0].x, p[1].x]));
1347
- const yArr = this.pointsGroups.flatMap((points) => points.flatMap((p) => [p[0].y, p[1].y]));
1348
- const minX = Math.min(...xArr);
1349
- const minY = Math.min(...yArr);
1350
- const maxX = Math.max(...xArr);
1351
- const maxY = Math.max(...yArr);
1352
- this.box.set(minX, minY, maxX, maxY);
1353
- return this.box;
1105
+ const t = this.pointsGroups.flatMap((r) => r.flatMap((c) => [c[0].x, c[1].x])), e = this.pointsGroups.flatMap((r) => r.flatMap((c) => [c[0].y, c[1].y])), n = Math.min(...t), i = Math.min(...e), o = Math.max(...t), s = Math.max(...e);
1106
+ return this.box.set(n, i, o, s), this.box;
1354
1107
  }
1355
1108
  /** 线路拓扑
1356
1109
  * @description 处理线路拓扑,使线路有序链接,形成长路径
1357
1110
  * @param lines
1358
1111
  */
1359
- lineTopology(lines) {
1360
- const visited = [];
1361
- function dfs(index2, linePath) {
1362
- const [_0, a2] = lines[index2];
1363
- visited[index2] = true;
1364
- linePath.push(a2);
1365
- for (let i = 0; i < lines.length; i++) {
1366
- const [b1, _1] = lines[i];
1367
- if (!visited[i]) {
1368
- if (Math.abs(a2.x - b1.x) < 1e-6 && Math.abs(a2.y - b1.y) < 1e-6) {
1369
- return dfs(i, linePath);
1370
- }
1371
- }
1112
+ lineTopology(t) {
1113
+ const e = [];
1114
+ function n(o, s) {
1115
+ const [r, c] = t[o];
1116
+ e[o] = !0, s.push(c);
1117
+ for (let a = 0; a < t.length; a++) {
1118
+ const [h, l] = t[a];
1119
+ if (!e[a] && Math.abs(c.x - h.x) < 1e-6 && Math.abs(c.y - h.y) < 1e-6)
1120
+ return n(a, s);
1372
1121
  }
1373
1122
  }
1374
- const linePaths = [];
1375
- for (let i = 0; i < lines.length; i++) {
1376
- if (!visited[i]) {
1377
- const linePath = [lines[i][0]];
1378
- dfs(i, linePath);
1379
- linePaths.push(linePath);
1123
+ const i = [];
1124
+ for (let o = 0; o < t.length; o++)
1125
+ if (!e[o]) {
1126
+ const s = [t[o][0]];
1127
+ n(o, s), i.push(s);
1380
1128
  }
1381
- }
1382
- return linePaths;
1129
+ return i;
1383
1130
  }
1384
1131
  /** 合并方向相同的线段
1385
1132
  * @param lines
1386
1133
  * @param errAngle
1387
1134
  */
1388
- mergeSameDirectionLine(lines, errAngle = 3) {
1389
- if (lines[0].includedAngle(lines[lines.length - 1]) < 0.1) {
1390
- const line = lines.pop();
1391
- line.end.copy(lines[0].end);
1392
- lines.splice(0, 1, line);
1135
+ mergeSameDirectionLine(t, e = 3) {
1136
+ if (t[0].includedAngle(t[t.length - 1]) < 0.1) {
1137
+ const i = t.pop();
1138
+ i.end.copy(t[0].end), t.splice(0, 1, i);
1393
1139
  }
1394
- const filterLines = [lines[0]];
1395
- for (let i = 1; i < lines.length; i++) {
1396
- const line = lines[i];
1397
- const preLine = lines[i - 1];
1398
- if (preLine.includedAngle(line) < errAngle) {
1399
- preLine.end.copy(line.end);
1400
- } else {
1401
- filterLines.push(line);
1402
- }
1140
+ const n = [t[0]];
1141
+ for (let i = 1; i < t.length; i++) {
1142
+ const o = t[i], s = t[i - 1];
1143
+ s.includedAngle(o) < e ? s.end.copy(o.end) : n.push(o);
1403
1144
  }
1404
- return filterLines;
1145
+ return n;
1405
1146
  }
1406
1147
  /** etOpenRound 去除毛刺
1407
1148
  * @description 检查连续的短线段数量,去除合并后产生的毛刺
1408
1149
  */
1409
- squareRemoveBurr(path) {
1410
- if (path.length < 3) return path;
1411
- const filterLines = [path[0]];
1412
- for (let i = 1; i < path.length; i++) {
1413
- const prev = path[i - 1];
1414
- const curr = path[i];
1415
- const len = prev.distance(curr);
1416
- if (len < this.width * 0.5) {
1417
- let count = 0;
1418
- for (let j = i + 1; j < path.length; j++) {
1419
- const prev2 = path[j - 1];
1420
- const curr2 = path[j];
1421
- const len2 = prev2.distance(curr2);
1422
- if (len2 < this.width * 0.8) count++;
1150
+ squareRemoveBurr(t) {
1151
+ if (t.length < 3) return t;
1152
+ const e = [t[0]];
1153
+ for (let n = 1; n < t.length; n++) {
1154
+ const i = t[n - 1], o = t[n];
1155
+ if (i.distance(o) < this.width * 0.5) {
1156
+ let r = 0;
1157
+ for (let c = n + 1; c < t.length; c++) {
1158
+ const a = t[c - 1], h = t[c];
1159
+ if (a.distance(h) < this.width * 0.8) r++;
1423
1160
  else break;
1424
1161
  }
1425
- if (count === 0 && i + count === path.length - 1) ;
1426
- else if (i == 1 && count === 1) ;
1427
- else if (count === 3) {
1428
- filterLines.push(path[i + 1]);
1429
- i += count;
1430
- } else if (count === 5) {
1431
- filterLines.push(path[i + 2]);
1432
- i += count;
1433
- } else {
1434
- filterLines.push(curr);
1435
- }
1436
- } else {
1437
- filterLines.push(curr);
1438
- }
1162
+ r === 0 && n + r === t.length - 1 || n == 1 && r === 1 || (r === 3 ? (e.push(t[n + 1]), n += r) : r === 5 ? (e.push(t[n + 2]), n += r) : e.push(o));
1163
+ } else
1164
+ e.push(o);
1439
1165
  }
1440
- return filterLines;
1166
+ return e;
1441
1167
  }
1442
1168
  /**
1443
1169
  * 线段矫直, 线段中心突刺
1444
1170
  * @description 突变长度小于墙体宽度,该线段可能为突起线段,
1445
1171
  * @description 判断后续第2线段与上一条线段是否方向相同,相同就为突刺
1446
1172
  */
1447
- lineSegmentStraightening(path) {
1448
- for (let i = 0; i < path.length; i++) {
1449
- const p1 = path[i];
1450
- const p2 = path[(i + 1) % path.length];
1451
- if (p1.distance(p2) > this.shortLine) {
1452
- path.push(...path.slice(0, i + 1));
1453
- path.splice(0, i + 1);
1173
+ lineSegmentStraightening(t) {
1174
+ for (let i = 0; i < t.length; i++) {
1175
+ const o = t[i], s = t[(i + 1) % t.length];
1176
+ if (o.distance(s) > this.shortLine) {
1177
+ t.push(...t.slice(0, i + 1)), t.splice(0, i + 1);
1454
1178
  break;
1455
1179
  }
1456
1180
  }
1457
- const lines = this.mergeSameDirectionLine(pathToLines(path)), filterLines = [lines[0]];
1458
- for (let i = 1; i < lines.length; i++) {
1459
- const line = lines[i];
1460
- const preLine = lines[(lines.length + i - 1) % lines.length];
1461
- if (line.length() > this.width * 0.9) {
1462
- filterLines.push(line);
1181
+ const e = this.mergeSameDirectionLine(k(t)), n = [e[0]];
1182
+ for (let i = 1; i < e.length; i++) {
1183
+ const o = e[i], s = e[(e.length + i - 1) % e.length];
1184
+ if (o.length() > this.width * 0.9) {
1185
+ n.push(o);
1463
1186
  continue;
1464
1187
  }
1465
- const line1 = lines[i + 1];
1466
- if (line1 && line1.length() > this.width * 0.9) {
1467
- filterLines.push(line);
1468
- filterLines.push(line1);
1469
- i = i + 1;
1188
+ const r = e[i + 1];
1189
+ if (r && r.length() > this.width * 0.9) {
1190
+ n.push(o), n.push(r), i = i + 1;
1470
1191
  continue;
1471
1192
  }
1472
- const line2 = lines[i + 2];
1473
- if (line2 && preLine.includedAngle(line2) < 2) {
1474
- i = i + 2;
1475
- filterLines.push(line2);
1476
- } else filterLines.push(line);
1193
+ const c = e[i + 2];
1194
+ c && s.includedAngle(c) < 2 ? (i = i + 2, n.push(c)) : n.push(o);
1477
1195
  }
1478
- return filterLines.length > 3 ? linesToPath(this.mergeSameDirectionLine(filterLines)) : [];
1196
+ return n.length > 3 ? J(this.mergeSameDirectionLine(n)) : [];
1479
1197
  }
1480
1198
  /**
1481
1199
  * 移除短线段
1482
1200
  * @todo 根据线段两端线段长度,选取参照物_|▔▔
1483
1201
  * @param path
1484
1202
  */
1485
- removeShortLine(path, shortLine = this.shortLine) {
1486
- const lines = pathToLines(path), filterLines = [], PI_1 = Math.PI / 180;
1487
- for (let i = 0; i < lines.length; i++) {
1488
- const line = lines[i], len = line.length(), currentIndex = i;
1489
- if (len > shortLine || filterLines.length === 0) {
1490
- filterLines.push(line);
1203
+ removeShortLine(t, e = this.shortLine) {
1204
+ const n = k(t), i = [], o = Math.PI / 180;
1205
+ for (let s = 0; s < n.length; s++) {
1206
+ const r = n[s], c = r.length(), a = s;
1207
+ if (c > e || i.length === 0) {
1208
+ i.push(r);
1491
1209
  continue;
1492
1210
  }
1493
- let nextline = lines[++i];
1494
- const preLine = filterLines[filterLines.length - 1], d1 = preLine.direction();
1495
- while (i < lines.length) {
1496
- const angle = d1.angleBetween(nextline.direction()) / PI_1;
1497
- if (nextline.length() <= shortLine || angle < 4 || angle > 180 - 4) {
1498
- nextline = lines[++i];
1499
- } else break;
1500
- }
1501
- if (!nextline) continue;
1502
- const targetLine = lines[i - 1];
1503
- if (preLine.length() > targetLine.length()) {
1504
- const intersectPoint = preLine.getIntersection(nextline);
1505
- if (intersectPoint) {
1506
- const p0 = preLine.points[1].clone(), p1 = nextline.points[0].clone();
1507
- preLine.points[1].copy(intersectPoint);
1508
- nextline.points[0].copy(intersectPoint);
1509
- if (preLine.length() < this.width) {
1510
- preLine.points[1].copy(p0);
1511
- nextline.points[0].copy(p0);
1512
- } else if (nextline.length() < this.width) {
1513
- preLine.points[1].copy(p1);
1514
- nextline.points[0].copy(p1);
1515
- }
1516
- } else {
1517
- preLine.points[1].copy(nextline.points[0]);
1518
- }
1519
- filterLines.push(nextline);
1520
- } else {
1521
- i = currentIndex;
1211
+ let h = n[++s];
1212
+ const l = i[i.length - 1], d = l.direction();
1213
+ for (; s < n.length; ) {
1214
+ const m = d.angleBetween(h.direction()) / o;
1215
+ if (h.length() <= e || m < 4 || m > 176)
1216
+ h = n[++s];
1217
+ else break;
1522
1218
  }
1523
- }
1524
- return filterLines.length > 3 ? linesToPath(filterLines) : [];
1219
+ if (!h) continue;
1220
+ const f = n[s - 1];
1221
+ if (l.length() > f.length()) {
1222
+ const m = l.getIntersection(h);
1223
+ if (m) {
1224
+ const g = l.points[1].clone(), u = h.points[0].clone();
1225
+ l.points[1].copy(m), h.points[0].copy(m), l.length() < this.width ? (l.points[1].copy(g), h.points[0].copy(g)) : h.length() < this.width && (l.points[1].copy(u), h.points[0].copy(u));
1226
+ } else
1227
+ l.points[1].copy(h.points[0]);
1228
+ i.push(h);
1229
+ } else
1230
+ s = a;
1231
+ }
1232
+ return i.length > 3 ? J(i) : [];
1525
1233
  }
1526
1234
  /** 线偏移
1527
1235
  * @description 使用 ClipperLib 对每个点组进行线偏移处理,生成具有指定宽度的墙体路径
1528
1236
  */
1529
- lineOffset(endType = Dxf.EndType.etOpenSquare, joinType = Dxf.JoinType.jtMiter, scale = 1e4) {
1530
- let solutions = new ClipperLib.Paths();
1531
- const offset = new ClipperLib.ClipperOffset(20, 0.25);
1532
- this.pointsGroups.forEach((points) => {
1533
- const linePaths = this.lineTopology(points).map((linePath) => linePath.map((p) => p.clone().mutiplyScalar(scale)));
1534
- offset.AddPaths(linePaths, joinType, endType);
1535
- });
1536
- offset.Execute(solutions, this.width / 2 * scale);
1537
- this.wallsGroup = solutions.map((ps) => {
1538
- let path = ps.map((p) => Point.from(p).divisionScalar(scale));
1539
- path = this.lineSegmentStraightening(path);
1540
- if (endType == Dxf.EndType.etOpenSquare) path = this.squareRemoveBurr(path);
1541
- path = this.removeShortLine(path);
1542
- return path;
1543
- });
1544
- this.dispatchEvent({
1237
+ lineOffset(t = X.EndType.etOpenSquare, e = X.JoinType.jtMiter, n = 1e4) {
1238
+ let i = new F.Paths();
1239
+ const o = new F.ClipperOffset(20, 0.25);
1240
+ return this.pointsGroups.forEach((s) => {
1241
+ const r = this.lineTopology(s).map((c) => c.map((a) => a.clone().mutiplyScalar(n)));
1242
+ o.AddPaths(r, e, t);
1243
+ }), o.Execute(i, this.width / 2 * n), this.wallsGroup = i.map((s) => {
1244
+ let r = s.map((c) => p.from(c).divisionScalar(n));
1245
+ return r = this.lineSegmentStraightening(r), t == X.EndType.etOpenSquare && (r = this.squareRemoveBurr(r)), r = this.removeShortLine(r), r;
1246
+ }), this.dispatchEvent({
1545
1247
  type: "lineOffset",
1546
1248
  wallsGroup: this.wallsGroup
1547
- });
1548
- return this.wallsGroup;
1249
+ }), this.wallsGroup;
1549
1250
  }
1550
1251
  /**
1551
1252
  * 将点云结构转换为Float32Array
1552
1253
  */
1553
- to3DArray(scale, z = this.originalZAverage) {
1554
- const array = [];
1555
- this.wallsGroup.forEach((points) => {
1556
- for (let i = 0; i < points.length; i++) {
1557
- const point1 = points[i];
1558
- const nextIndex = i === points.length - 1 ? 0 : i + 1;
1559
- const point2 = points[nextIndex];
1560
- array.push(point1.X * scale, point1.Y * scale, z, point2.X * scale, point2.Y * scale, z);
1254
+ to3DArray(t, e = this.originalZAverage) {
1255
+ const n = [];
1256
+ return this.wallsGroup.forEach((i) => {
1257
+ for (let o = 0; o < i.length; o++) {
1258
+ const s = i[o], r = o === i.length - 1 ? 0 : o + 1, c = i[r];
1259
+ n.push(s.X * t, s.Y * t, e, c.X * t, c.Y * t, e);
1561
1260
  }
1562
- });
1563
- return new Float32Array(array);
1261
+ }), new Float32Array(n);
1564
1262
  }
1565
1263
  /** 获取角度范围
1566
1264
  * @param center
@@ -1568,196 +1266,272 @@ class Dxf extends Component {
1568
1266
  * @param p2
1569
1267
  * @returns
1570
1268
  */
1571
- getArcAngleRange(center, p1, p2) {
1572
- const x1 = p1.x - center.x;
1573
- const y1 = p1.y - center.y;
1574
- const x2 = p2.x - center.x;
1575
- const y2 = p2.y - center.y;
1576
- let angle1 = Math.atan2(y1, x1);
1577
- let angle2 = Math.atan2(y2, x2);
1578
- angle1 = angle1 < 0 ? angle1 + 2 * Math.PI : angle1;
1579
- angle2 = angle2 < 0 ? angle2 + 2 * Math.PI : angle2;
1580
- let r1, r2;
1581
- const diff = Math.abs(angle2 - angle1);
1582
- if (diff <= Math.PI) {
1583
- r1 = Math.min(angle1, angle2);
1584
- r2 = Math.max(angle1, angle2);
1585
- } else {
1586
- r1 = Math.max(angle1, angle2);
1587
- r2 = Math.min(angle1, angle2) + 2 * Math.PI;
1588
- }
1589
- return [r1 / (Math.PI / 180), r2 / (Math.PI / 180)];
1590
- }
1591
- /**
1592
- * 将点云结构转换为string
1593
- */
1594
- toDxfString(unit = "Millimeters") {
1595
- const d = new Drawing();
1596
- d.setUnits("Millimeters");
1597
- const s = units[unit];
1598
- function drawLine(p1, p2) {
1599
- d.drawLine(p1.X * s, p1.Y * s, p2.X * s, p2.Y * s);
1269
+ getArcAngleRange(t, e, n) {
1270
+ const i = e.x - t.x, o = e.y - t.y, s = n.x - t.x, r = n.y - t.y;
1271
+ let c = Math.atan2(o, i), a = Math.atan2(r, s);
1272
+ c = c < 0 ? c + 2 * Math.PI : c, a = a < 0 ? a + 2 * Math.PI : a;
1273
+ let h, l;
1274
+ return Math.abs(a - c) <= Math.PI ? (h = Math.min(c, a), l = Math.max(c, a)) : (h = Math.max(c, a), l = Math.min(c, a) + 2 * Math.PI), [h / (Math.PI / 180), l / (Math.PI / 180)];
1275
+ }
1276
+ /**
1277
+ * 转为绘制数据
1278
+ */
1279
+ toDrawDataJson(t = "Millimeters") {
1280
+ const e = st[t], n = {
1281
+ unit: t,
1282
+ line: [],
1283
+ arc: [],
1284
+ dimensionLine: [],
1285
+ center: this.box.center.toJson(),
1286
+ width: this.box.width * e,
1287
+ height: this.box.height * e,
1288
+ scale: e
1289
+ };
1290
+ let i = "white";
1291
+ function o(a, h) {
1292
+ n.line.push([a.X * e, a.Y * e, h.X * e, h.Y * e, i]);
1293
+ }
1294
+ function s(a, h, l, d) {
1295
+ n.arc.push([
1296
+ a.x * e,
1297
+ a.y * e,
1298
+ h * e,
1299
+ l,
1300
+ d,
1301
+ i
1302
+ ]);
1303
+ }
1304
+ for (let a = 0; a < this.originalData.length; a++) {
1305
+ const h = this.originalData[a];
1306
+ if (h.isVerticalReferenceLine) {
1307
+ n.dimensionLine.push([h.start.x * e, h.start.y * e, h.end.x * e, h.end.y * e]);
1308
+ break;
1309
+ }
1600
1310
  }
1601
- this.wallsGroup.forEach((points) => {
1602
- for (let i = 0; i < points.length; i++) {
1603
- const point1 = points[i];
1604
- const nextIndex = i === points.length - 1 ? 0 : i + 1;
1605
- const point2 = points[nextIndex];
1606
- drawLine(point1, point2);
1311
+ this.wallsGroup.forEach((a) => {
1312
+ for (let h = 0; h < a.length; h++) {
1313
+ const l = a[h], d = h === a.length - 1 ? 0 : h + 1, f = a[d];
1314
+ o(l, f);
1607
1315
  }
1608
1316
  });
1609
- const doorThickness = this.width * 0.2;
1610
- const list = [];
1611
- d.addLayer("l_cyan", Drawing.ACI.CYAN, "DOTTED");
1612
- this.doorLineSegment.forEach((lineSegment) => {
1613
- if (lineSegment.length() < 0.4) return;
1614
- const line = lineSegment.clone().expansion(-this.width * 0.5);
1615
- d.setActiveLayer("l_cyan");
1616
- if (line.length() < 1.2) {
1617
- line.expansion(-doorThickness * 0.5);
1618
- const normal = lineSegment.normal();
1619
- let door = new LineSegment(
1620
- line.start.clone(),
1621
- line.start.clone().add(normal.clone().multiplyScalar(line.length()))
1317
+ const r = this.width * 0.2, c = [];
1318
+ return this.doorLineSegment.forEach((a) => {
1319
+ if (a.length() < 0.4) return;
1320
+ const h = a.clone().expansion(-this.width * 0.5);
1321
+ if (i = "cyan", h.length() < 1.2) {
1322
+ h.expansion(-r * 0.5);
1323
+ const l = a.normal();
1324
+ let d = new L(
1325
+ h.start.clone(),
1326
+ h.start.clone().add(l.clone().multiplyScalar(h.length()))
1622
1327
  );
1623
- const box = door.clone().directionMove(door.normal(), line.length() * -0.5).expandToRectangle(line.length(), "bothSides");
1624
- for (let j = 0; j < list.length; j++) {
1625
- if (list[j].intersectRectangle(box)) {
1626
- door = new LineSegment(
1627
- line.start.clone(),
1628
- line.start.clone().add(normal.clone().multiplyScalar(-line.length()))
1328
+ const f = d.clone().directionMove(d.normal(), h.length() * -0.5).expandToRectangle(h.length(), "bothSides");
1329
+ for (let b = 0; b < c.length; b++)
1330
+ if (c[b].intersectRectangle(f)) {
1331
+ d = new L(
1332
+ h.start.clone(),
1333
+ h.start.clone().add(l.clone().multiplyScalar(-h.length()))
1629
1334
  );
1630
1335
  break;
1631
1336
  }
1632
- }
1633
- door.expansion(-doorThickness * 0.5).expandToRectangle(this.width * 0.2, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
1634
- const a = line.length(), b = door.length(), r = (a ** 2 + b ** 2) / (2 * b), center = door.end.clone().add(door.direction().multiplyScalar(-r)), [startAngle, endAngle] = this.getArcAngleRange(center, line.end, door.end);
1635
- d.drawArc(center.x * s, center.y * s, r * s, Math.min(startAngle, endAngle), Math.max(startAngle, endAngle));
1636
- list.push(box);
1637
- } else {
1638
- line.clone().expansion(-this.width * 0.5).expandToRectangle(this.width).path2D((p1, p2) => drawLine(p1, p2));
1639
- line.clone().directionMove(line.normal(), doorThickness * 0.5).directionMove(line.direction(), doorThickness * 0.5).expansion(-line.length() * 0.45, "end").forward(doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
1640
- line.clone().directionMove(line.normal(), -doorThickness * 0.5).directionMove(line.direction(), -doorThickness * 0.5).expansion(-line.length() * 0.45, "start").forward(-doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
1641
- }
1642
- });
1643
- d.addLayer("l_yellow", Drawing.ACI.YELLOW, "DOTTED");
1644
- d.setActiveLayer("l_yellow");
1645
- this.lineSegments.forEach((line) => {
1646
- if (!line.userData.isWindow) return false;
1647
- if (Array.isArray(line.userData.drawDoorData)) {
1648
- line.userData.drawDoorData.forEach((w) => {
1649
- const { p, width } = w;
1650
- const center = Point.from(p);
1651
- const start = center.clone().add(line.direction().multiplyScalar(width * 0.5));
1652
- const end = center.clone().add(line.direction().multiplyScalar(-width * 0.5));
1653
- const blinds = new LineSegment(start, end);
1654
- drawLine(blinds.start, blinds.end);
1655
- blinds.expandToRectangle(this.width, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
1656
- });
1657
- }
1658
- });
1659
- return d.toDxfString();
1337
+ d.expansion(-r * 0.5).expandToRectangle(this.width * 0.2, "bothSides").path2D((b, P) => o(b, P));
1338
+ const m = h.length(), g = d.length(), u = (m ** 2 + g ** 2) / (2 * g), x = d.end.clone().add(d.direction().multiplyScalar(-u)), [w, S] = this.getArcAngleRange(x, h.end, d.end);
1339
+ s(x, u, Math.min(w, S), Math.max(w, S)), c.push(f);
1340
+ } else
1341
+ h.clone().expansion(-this.width * 0.5).expandToRectangle(this.width).path2D((l, d) => o(l, d)), h.clone().directionMove(h.normal(), r * 0.5).directionMove(h.direction(), r * 0.5).expansion(-h.length() * 0.45, "end").forward(r * 0.5).expandToRectangle(r).path2D((l, d) => o(l, d)), h.clone().directionMove(h.normal(), -r * 0.5).directionMove(h.direction(), -r * 0.5).expansion(-h.length() * 0.45, "start").forward(-r * 0.5).expandToRectangle(r).path2D((l, d) => o(l, d));
1342
+ }), i = "yellow", this.lineSegments.forEach((a) => {
1343
+ if (!a.userData.isWindow) return !1;
1344
+ Array.isArray(a.userData.drawWindow) && a.userData.drawWindow.forEach((h) => {
1345
+ const { p: l, width: d } = h, f = p.from(l), m = f.clone().add(a.direction().multiplyScalar(d * 0.5)), g = f.clone().add(a.direction().multiplyScalar(-d * 0.5)), u = new L(m, g);
1346
+ o(u.start, u.end), u.expandToRectangle(this.width, "bothSides").path2D((x, w) => o(x, w));
1347
+ });
1348
+ }), n;
1349
+ }
1350
+ /**
1351
+ *
1352
+ * @param type
1353
+ */
1354
+ async toDxfImageBlob(t = "Centimeters", e = "image/jpeg") {
1355
+ const n = this.toDrawDataJson(t);
1356
+ let i;
1357
+ if (typeof window < "u")
1358
+ i = document.createElement("canvas");
1359
+ else if (typeof global < "u") {
1360
+ const { createCanvas: c } = await G("canvas");
1361
+ i = c();
1362
+ } else
1363
+ throw new Error("创建画布失败");
1364
+ const o = 2 * n.scale, s = {
1365
+ cyan: "cyan",
1366
+ yellow: "yellow",
1367
+ white: "white"
1368
+ };
1369
+ i.width = n.width + o * 2, i.height = n.height + o * 2;
1370
+ const r = i.getContext("2d");
1371
+ return r.fillRect(0, 0, i.width, i.height), r.translate(n.width * 0.5 + o, n.height * 0.5 + o), n.line.forEach(([c, a, h, l, d]) => {
1372
+ r.strokeStyle = s[d], r.beginPath(), r.moveTo(c, a), r.lineTo(h, l), r.closePath(), r.stroke();
1373
+ }), n.arc.forEach(([c, a, h, l, d, f]) => {
1374
+ r.strokeStyle = s[f], r.beginPath(), r.arc(c, a, h, l * (Math.PI / 180), d * (Math.PI / 180)), r.stroke();
1375
+ }), r.beginPath(), n.dimensionLine.forEach((c) => {
1376
+ let [a, h, l, d] = c;
1377
+ const f = Math.min(h, d), m = Math.max(h, d), g = (i.width * 0.5 - 0.4 * n.scale) * (a < 0 ? -1 : 1), u = (m - f) * 0.45;
1378
+ r.fillStyle = "#fff", r.font = `${0.15 * n.scale}px Arial`, r.textAlign = "center", r.textBaseline = "middle", r.fillText((m - f).toFixed(2) + "cm", g, f + (m - f) * 0.5), r.moveTo(g - 0.1 * n.scale, f), r.lineTo(g + 0.1 * n.scale, f), r.moveTo(g, f), r.lineTo(g, u + f), r.moveTo(g, m), r.lineTo(g, m - u), r.moveTo(g - 0.1 * n.scale, m), r.lineTo(g + 0.1 * n.scale, m);
1379
+ }), r.closePath(), r.strokeStyle = "#fff", r.stroke(), "toBlob" in i ? new Promise((c) => {
1380
+ i.toBlob((a) => {
1381
+ c(a);
1382
+ }, e, 1);
1383
+ }) : i.toBuffer(e, { quality: 1 });
1384
+ }
1385
+ /**
1386
+ * 将点json结构转换为Dxf string
1387
+ */
1388
+ toDxfString(t = "Millimeters") {
1389
+ const e = new R();
1390
+ e.setUnits(t), e.addLayer("cyan", R.ACI.CYAN, "DOTTED"), e.addLayer("yellow", R.ACI.YELLOW, "DOTTED"), e.addLayer("white", R.ACI.WHITE, "DOTTED");
1391
+ const n = this.toDrawDataJson();
1392
+ return n.line.forEach((i) => {
1393
+ let [o, s, r, c, a] = i;
1394
+ e.setActiveLayer(a), e.drawLine(o, s, r, c);
1395
+ }), n.arc.forEach((i) => {
1396
+ const [o, s, r, c, a, h] = i;
1397
+ e.setActiveLayer(h), e.drawArc(o, s, r, c, a);
1398
+ }), e.toDxfString();
1660
1399
  }
1661
1400
  /**
1662
1401
  * 将点云结构转换为DXF格式
1663
1402
  * @returns
1664
1403
  */
1665
- toDxfBlob(unit = "Millimeters") {
1666
- const blob = new Blob([this.toDxfString(unit)]);
1667
- return blob;
1404
+ toDxfBlob(t = "Millimeters") {
1405
+ return new Blob([this.toDxfString(t)]);
1668
1406
  }
1669
1407
  /**
1670
1408
  * 下载
1671
1409
  * @param filename
1672
1410
  */
1673
- async download(filename, unit = "Millimeters") {
1674
- if (typeof window !== "undefined") {
1675
- const blob = this.toDxfBlob(unit);
1676
- const a = document.createElement("a");
1677
- a.href = URL.createObjectURL(blob);
1678
- a.download = filename + ".dxf";
1679
- a.click();
1680
- } else if (typeof global !== "undefined") {
1681
- const fs = await include("fs", false);
1682
- fs.writeFileSync(filename, this.toDxfString(unit));
1683
- }
1411
+ async download(t, e = "Millimeters") {
1412
+ if (typeof window < "u") {
1413
+ const n = this.toDxfBlob(e), i = document.createElement("a");
1414
+ i.href = URL.createObjectURL(n), i.download = t + ".dxf", i.click();
1415
+ } else typeof global < "u" && (await G("fs", !1)).writeFileSync(t, this.toDxfString(e));
1416
+ }
1417
+ /**
1418
+ * 下载
1419
+ * @param filename
1420
+ */
1421
+ async downloadImage(t, e = "Centimeters", n = "image/jpeg") {
1422
+ const i = await this.toDxfImageBlob(e, n);
1423
+ if (!i) return !1;
1424
+ if (typeof window < "u") {
1425
+ const o = document.createElement("a");
1426
+ o.href = URL.createObjectURL(i), o.download = t, o.click();
1427
+ } else typeof global < "u" ? (await G("fs", !1)).writeFileSync(t, i) : console.error("图片下载失败");
1428
+ return !0;
1684
1429
  }
1685
1430
  /**
1686
1431
  * 计算原始数据的边界框
1687
1432
  * @description 计算所有线段的起点和终点的最小最大值,形成一个边界框
1688
1433
  * @returns
1689
1434
  */
1690
- computedOriginalSize(data, originalBox = new Box2(0, 0, 0, 0)) {
1691
- const xArr = data.flatMap((item) => [item.start.x, item.end.x]);
1692
- const yArr = data.flatMap((item) => [item.start.y, item.end.y]);
1693
- const minX = Math.min(...xArr);
1694
- const minY = Math.min(...yArr);
1695
- const maxX = Math.max(...xArr);
1696
- const maxY = Math.max(...yArr);
1697
- originalBox.set(minX, minY, maxX, maxY);
1698
- return originalBox;
1435
+ computedOriginalSize(t, e = new v(0, 0, 0, 0)) {
1436
+ const n = t.flatMap((a) => [a.start.x, a.end.x]), i = t.flatMap((a) => [a.start.y, a.end.y]), o = Math.min(...n), s = Math.min(...i), r = Math.max(...n), c = Math.max(...i);
1437
+ return e.set(o, s, r, c), e;
1699
1438
  }
1700
1439
  /**
1701
1440
  * 创建数据
1702
1441
  * @param pointsGroups
1703
1442
  * @returns
1704
1443
  */
1705
- static createData(pointsGroups, sealed = true) {
1706
- let count = 0;
1707
- const data = pointsGroups.flatMap((points) => {
1708
- const lines = points.map((point, index2) => {
1709
- const nextIndex = index2 === points.length - 1 ? 0 : index2 + 1;
1710
- const nextPoint = points[nextIndex];
1444
+ static createData(t, e = !0) {
1445
+ let n = 0;
1446
+ return t.flatMap((o) => {
1447
+ const s = o.map((r, c) => {
1448
+ const a = c === o.length - 1 ? 0 : c + 1, h = o[a];
1711
1449
  return {
1712
- start: { x: point.x, y: point.y },
1713
- end: { x: nextPoint.x, y: nextPoint.y },
1450
+ start: { x: r.x, y: r.y },
1451
+ end: { x: h.x, y: h.y },
1714
1452
  insetionArr: [
1715
1453
  {
1716
- index: nextIndex + count
1454
+ index: a + n
1717
1455
  }
1718
1456
  ]
1719
1457
  };
1720
1458
  });
1721
- count += points.length;
1722
- if (!sealed) {
1723
- lines.pop();
1724
- lines[lines.length - 1].insetionArr.length = 0;
1725
- count--;
1459
+ return n += o.length, e || (s.pop(), s[s.length - 1].insetionArr.length = 0, n--), s;
1460
+ });
1461
+ }
1462
+ }
1463
+ const I = new L();
1464
+ class ot extends X {
1465
+ static name = "AngleCorrectionDxf";
1466
+ onAddFromParent(t) {
1467
+ const e = t.findComponentByName("Dxf"), n = t.findComponentByName("LineAnalysis");
1468
+ n.addEventListener("analysisCompleted", async () => {
1469
+ let i = 0, o = null;
1470
+ for (let a = 0; a < e.originalData.length; a++) {
1471
+ const h = e.originalData[a];
1472
+ if (I.start.copy(h.start), I.end.copy(h.end), h.isVerticalReferenceLine) {
1473
+ const [l, d] = h.start.y < h.end.y ? [I.start, I.end] : [I.end, I.start];
1474
+ i = -new L(l, d).direction().angleBetween(new p(0, 1), "angle", "360"), o = null;
1475
+ break;
1476
+ }
1477
+ (!o || I.length() > o.length()) && (o = I.clone(), o.userData.index = a);
1478
+ }
1479
+ if (o) {
1480
+ e.originalData[o.userData.index].isVerticalReferenceLine = !0;
1481
+ const [a, h] = o.start.y < o.end.y ? [o.start, o.end] : [o.end, o.start];
1482
+ i = -new L(a, h).direction().angleBetween(new p(0, 1), "angle", "360");
1726
1483
  }
1727
- return lines;
1484
+ const s = e.originalBox.center, r = p.zero(), c = e.originalData.map((a) => {
1485
+ const h = r.copy(a.start).division(s).rotate(p.zero(), i * (Math.PI / 180)).toJson(a.start.z), l = r.copy(a.end).division(s).rotate(p.zero(), i * (Math.PI / 180)).toJson(a.end.z), d = Object.assign(O(a), { start: h, end: l });
1486
+ return d.drawWindow && d.drawWindow.forEach((f) => {
1487
+ f.p = r.copy(f.p).division(s).rotate(p.zero(), i * (Math.PI / 180)).toJson(f.p.z), f.p.y = -f.p.y;
1488
+ }), d;
1489
+ });
1490
+ n.appendLineSegmentList.forEach((a) => {
1491
+ const h = a.clone();
1492
+ h.start.division(s).rotate(p.zero(), i * (Math.PI / 180)), h.end.division(s).rotate(p.zero(), i * (Math.PI / 180)), c.push({
1493
+ start: h.start.toJson(e.originalZAverage),
1494
+ end: h.end.toJson(e.originalZAverage),
1495
+ insetionArr: [],
1496
+ length: h.length()
1497
+ });
1498
+ }), c.forEach((a) => {
1499
+ a.start.y = -a.start.y, a.end.y = -a.end.y;
1500
+ }), await this.set(c, e.width, e.scale), this.lineOffset(), this.doorLineSegment = e.doorLineSegment.map((a) => {
1501
+ const h = a.clone();
1502
+ return h.start.division(s).rotate(p.zero(), i * (Math.PI / 180)), h.end.division(s).rotate(p.zero(), i * (Math.PI / 180)), h.start.y = -h.start.y, h.end.y = -h.end.y, h;
1503
+ });
1728
1504
  });
1729
- return data;
1730
1505
  }
1731
1506
  }
1732
- class Variable extends Component {
1507
+ class _ extends j {
1733
1508
  static name = "Variable";
1734
- originalLineVisible = true;
1735
- dxfVisible = true;
1736
- whiteModelVisible = true;
1737
- isLook = false;
1509
+ originalLineVisible = !0;
1510
+ dxfVisible = !0;
1511
+ whiteModelVisible = !0;
1512
+ isLook = !1;
1738
1513
  currentWheel = 0;
1739
1514
  pointerMove = { x: 0, y: 0 };
1740
1515
  currentKeyUp = "";
1741
1516
  currentKeyDown = "";
1742
1517
  currentMouseUp = "";
1743
1518
  currentMouseDown = "";
1744
- focus = false;
1745
- set(key, value) {
1746
- if (key in this) {
1747
- const oldValue = this[key];
1748
- this[key] = value;
1749
- this.dispatchEvent({
1750
- type: key,
1751
- value,
1752
- oldValue
1519
+ focus = !1;
1520
+ set(t, e) {
1521
+ if (t in this) {
1522
+ const n = this[t];
1523
+ this[t] = e, this.dispatchEvent({
1524
+ type: t,
1525
+ value: e,
1526
+ oldValue: n
1753
1527
  });
1754
1528
  }
1755
1529
  }
1756
- get(key) {
1757
- if (key in this) return this[key];
1530
+ get(t) {
1531
+ if (t in this) return this[t];
1758
1532
  }
1759
1533
  }
1760
- class Quadtree {
1534
+ class q {
1761
1535
  bounds;
1762
1536
  // 包围盒
1763
1537
  capacity;
@@ -1766,7 +1540,7 @@ class Quadtree {
1766
1540
  // 最大深度
1767
1541
  depth;
1768
1542
  // 当前深度
1769
- isLeaf = true;
1543
+ isLeaf = !0;
1770
1544
  // 是否为叶子节点
1771
1545
  children = null;
1772
1546
  // 子节点数组
@@ -1774,110 +1548,72 @@ class Quadtree {
1774
1548
  // 存储的节点
1775
1549
  color = [Math.random(), Math.random(), Math.random()];
1776
1550
  // 颜色
1777
- constructor(bounds, capacity = 8, maxDepth = 10, depth = 1) {
1778
- this.bounds = bounds;
1779
- this.capacity = capacity;
1780
- this.depth = depth;
1781
- this.maxDepth = maxDepth;
1551
+ constructor(t, e = 8, n = 10, i = 1) {
1552
+ this.bounds = t, this.capacity = e, this.depth = i, this.maxDepth = n;
1782
1553
  }
1783
1554
  /**
1784
1555
  * 插入线段节点
1785
1556
  * @param node 线段节点
1786
1557
  */
1787
- insert(node) {
1558
+ insert(t) {
1788
1559
  if (!this.isLeaf) {
1789
- const quadrant = this.getQuadrant(node.line);
1790
- if (quadrant !== -1) {
1791
- this.children[quadrant].insert(node);
1560
+ const e = this.getQuadrant(t.line);
1561
+ if (e !== -1) {
1562
+ this.children[e].insert(t);
1792
1563
  return;
1793
1564
  }
1794
1565
  }
1795
- this.nodes.push(node);
1796
- node.parent = this;
1797
- if (this.isLeaf && this.nodes.length > this.capacity && this.depth < this.maxDepth) {
1566
+ if (this.nodes.push(t), t.parent = this, this.isLeaf && this.nodes.length > this.capacity && this.depth < this.maxDepth) {
1798
1567
  this.subdivide();
1799
- const nodes = this.nodes;
1568
+ const e = this.nodes;
1800
1569
  this.nodes = [];
1801
- for (const n of nodes) {
1802
- const quadrant = this.getQuadrant(n.line);
1803
- if (quadrant !== -1) {
1804
- this.children[quadrant].insert(n);
1805
- } else {
1806
- n.parent = this;
1807
- this.nodes.push(n);
1808
- }
1570
+ for (const n of e) {
1571
+ const i = this.getQuadrant(n.line);
1572
+ i !== -1 ? this.children[i].insert(n) : (n.parent = this, this.nodes.push(n));
1809
1573
  }
1810
1574
  }
1811
1575
  }
1812
1576
  /** 移除
1813
1577
  * @param node
1814
1578
  */
1815
- remove(node) {
1816
- const index2 = node.parent?.nodes.indexOf(node);
1817
- if (index2 > -1) {
1818
- node.parent?.nodes.splice(index2, 1);
1819
- }
1579
+ remove(t) {
1580
+ const e = t.parent?.nodes.indexOf(t);
1581
+ e > -1 && t.parent?.nodes.splice(e, 1);
1820
1582
  }
1821
1583
  /**
1822
1584
  * 获取线段所属的象限
1823
1585
  * @param line 线段
1824
1586
  * @returns 象限索引(0:西北,1:东北,2:西南,3:东南)或-1(跨多个象限)
1825
1587
  */
1826
- getQuadrant(line) {
1827
- const intersectsNW = this.children[0].bounds.intersectLineSegment(line);
1828
- const intersectsNE = this.children[1].bounds.intersectLineSegment(line);
1829
- const intersectsSW = this.children[2].bounds.intersectLineSegment(line);
1830
- const intersectsSE = this.children[3].bounds.intersectLineSegment(line);
1831
- let count = 0;
1832
- let quadrant = -1;
1833
- if (intersectsNW) {
1834
- count++;
1835
- quadrant = 0;
1836
- }
1837
- if (intersectsNE) {
1838
- count++;
1839
- quadrant = 1;
1840
- }
1841
- if (intersectsSW) {
1842
- count++;
1843
- quadrant = 2;
1844
- }
1845
- if (intersectsSE) {
1846
- count++;
1847
- quadrant = 3;
1848
- }
1849
- if (count === 1) return quadrant;
1850
- return -1;
1588
+ getQuadrant(t) {
1589
+ const e = this.children[0].bounds.intersectLineSegment(t), n = this.children[1].bounds.intersectLineSegment(t), i = this.children[2].bounds.intersectLineSegment(t), o = this.children[3].bounds.intersectLineSegment(t);
1590
+ let s = 0, r = -1;
1591
+ return e && (s++, r = 0), n && (s++, r = 1), i && (s++, r = 2), o && (s++, r = 3), s === 1 ? r : -1;
1851
1592
  }
1852
1593
  /**
1853
1594
  * 细分当前节点为四个子节点
1854
1595
  */
1855
1596
  subdivide() {
1856
1597
  if (!this.isLeaf) return;
1857
- this.isLeaf = false;
1858
- this.children = [];
1859
- const midX = (this.bounds.minX + this.bounds.maxX) / 2;
1860
- const midY = (this.bounds.minY + this.bounds.maxY) / 2;
1861
- this.children[0] = new Quadtree(
1862
- new Box2(this.bounds.minX, midX, this.bounds.minY, midY),
1598
+ this.isLeaf = !1, this.children = [];
1599
+ const t = (this.bounds.minX + this.bounds.maxX) / 2, e = (this.bounds.minY + this.bounds.maxY) / 2;
1600
+ this.children[0] = new q(
1601
+ new v(this.bounds.minX, t, this.bounds.minY, e),
1863
1602
  this.capacity,
1864
1603
  this.maxDepth,
1865
1604
  this.depth + 1
1866
- );
1867
- this.children[1] = new Quadtree(
1868
- new Box2(midX, this.bounds.maxX, this.bounds.minY, midY),
1605
+ ), this.children[1] = new q(
1606
+ new v(t, this.bounds.maxX, this.bounds.minY, e),
1869
1607
  this.capacity,
1870
1608
  this.maxDepth,
1871
1609
  this.depth + 1
1872
- );
1873
- this.children[2] = new Quadtree(
1874
- new Box2(this.bounds.minX, midX, midY, this.bounds.maxY),
1610
+ ), this.children[2] = new q(
1611
+ new v(this.bounds.minX, t, e, this.bounds.maxY),
1875
1612
  this.capacity,
1876
1613
  this.maxDepth,
1877
1614
  this.depth + 1
1878
- );
1879
- this.children[3] = new Quadtree(
1880
- new Box2(midX, this.bounds.maxX, midY, this.bounds.maxY),
1615
+ ), this.children[3] = new q(
1616
+ new v(t, this.bounds.maxX, e, this.bounds.maxY),
1881
1617
  this.capacity,
1882
1618
  this.maxDepth,
1883
1619
  this.depth + 1
@@ -1888,22 +1624,16 @@ class Quadtree {
1888
1624
  * @param box2 包围盒
1889
1625
  * @returns 相交的节点数组
1890
1626
  */
1891
- queryBox(box2) {
1892
- const result = [];
1893
- if (!this.bounds.intersectBox(box2)) {
1894
- return result;
1895
- }
1896
- for (const node of this.nodes) {
1897
- if (box2.intersectLineSegment(node.line)) {
1898
- result.push(node);
1899
- }
1900
- }
1901
- if (!this.isLeaf) {
1902
- for (const child of this.children) {
1903
- result.push(...child.queryBox(box2));
1904
- }
1905
- }
1906
- return result;
1627
+ queryBox(t) {
1628
+ const e = [];
1629
+ if (!this.bounds.intersectBox(t))
1630
+ return e;
1631
+ for (const n of this.nodes)
1632
+ t.intersectLineSegment(n.line) && e.push(n);
1633
+ if (!this.isLeaf)
1634
+ for (const n of this.children)
1635
+ e.push(...n.queryBox(t));
1636
+ return e;
1907
1637
  }
1908
1638
  /**
1909
1639
  * 查询与圆形区域相交的线段节点
@@ -1911,81 +1641,58 @@ class Quadtree {
1911
1641
  * @param radius 半径
1912
1642
  * @returns 相交的节点数组
1913
1643
  */
1914
- queryCircle(pos, radius) {
1915
- const result = [];
1916
- const circleBox = new Box2(
1917
- pos.x - radius,
1918
- pos.x + radius,
1919
- pos.y - radius,
1920
- pos.y + radius
1644
+ queryCircle(t, e) {
1645
+ const n = [], i = new v(
1646
+ t.x - e,
1647
+ t.x + e,
1648
+ t.y - e,
1649
+ t.y + e
1921
1650
  );
1922
- if (!this.bounds.intersectBox(circleBox)) {
1923
- return result;
1651
+ if (!this.bounds.intersectBox(i))
1652
+ return n;
1653
+ for (const o of this.nodes) {
1654
+ const [s, r] = o.line.points, c = r.x - s.x, a = r.y - s.y, h = c * c + a * a;
1655
+ let l = ((t.x - s.x) * c + (t.y - s.y) * a) / h;
1656
+ l = Math.max(0, Math.min(1, l));
1657
+ const d = s.x + l * c, f = s.y + l * a;
1658
+ t.distance(new p(d, f)) <= e && n.push(o);
1924
1659
  }
1925
- for (const node of this.nodes) {
1926
- const [p1, p2] = node.line.points;
1927
- const dx = p2.x - p1.x;
1928
- const dy = p2.y - p1.y;
1929
- const l2 = dx * dx + dy * dy;
1930
- let t = ((pos.x - p1.x) * dx + (pos.y - p1.y) * dy) / l2;
1931
- t = Math.max(0, Math.min(1, t));
1932
- const closestX = p1.x + t * dx;
1933
- const closestY = p1.y + t * dy;
1934
- const distance = pos.distance(new Point(closestX, closestY));
1935
- if (distance <= radius) {
1936
- result.push(node);
1937
- }
1938
- }
1939
- if (!this.isLeaf) {
1940
- for (const child of this.children) {
1941
- result.push(...child.queryCircle(pos, radius));
1942
- }
1943
- }
1944
- return result;
1660
+ if (!this.isLeaf)
1661
+ for (const o of this.children)
1662
+ n.push(...o.queryCircle(t, e));
1663
+ return n;
1945
1664
  }
1946
1665
  /**
1947
1666
  * 查询与矩形相交的线段节点
1948
1667
  * @param rectangle 矩形
1949
1668
  * @returns 相交的节点数组
1950
1669
  */
1951
- queryRect(rectangle) {
1952
- const result = [];
1953
- if (!this.bounds.intersectRectangle(rectangle)) {
1954
- return result;
1955
- }
1956
- for (const node of this.nodes) {
1957
- if (rectangle.intersectLineSegment(node.line)) {
1958
- result.push(node);
1959
- }
1960
- }
1961
- if (!this.isLeaf) {
1962
- for (const child of this.children) {
1963
- result.push(...child.queryRect(rectangle));
1964
- }
1965
- }
1966
- return result;
1670
+ queryRect(t) {
1671
+ const e = [];
1672
+ if (!this.bounds.intersectRectangle(t))
1673
+ return e;
1674
+ for (const n of this.nodes)
1675
+ t.intersectLineSegment(n.line) && e.push(n);
1676
+ if (!this.isLeaf)
1677
+ for (const n of this.children)
1678
+ e.push(...n.queryRect(t));
1679
+ return e;
1967
1680
  }
1968
1681
  /**
1969
1682
  * 查询与线段相交的线段节点
1970
1683
  * @param lineSegment 线段
1971
1684
  * @returns 相交的节点数组
1972
1685
  */
1973
- queryLineSegment(lineSegment) {
1974
- const result = [];
1975
- if (!this.bounds.intersectLineSegment(lineSegment)) {
1976
- return result;
1977
- }
1978
- for (const node of this.nodes) {
1979
- if (lineSegment.intersectLineSegment(node.line)) {
1980
- result.push(node);
1981
- }
1982
- }
1983
- if (!this.isLeaf) {
1984
- for (const child of this.children) {
1985
- result.push(...child.queryLineSegment(lineSegment));
1986
- }
1987
- }
1988
- return result;
1686
+ queryLineSegment(t) {
1687
+ const e = [];
1688
+ if (!this.bounds.intersectLineSegment(t))
1689
+ return e;
1690
+ for (const n of this.nodes)
1691
+ t.intersectLineSegment(n.line) && e.push(n);
1692
+ if (!this.isLeaf)
1693
+ for (const n of this.children)
1694
+ e.push(...n.queryLineSegment(t));
1695
+ return e;
1989
1696
  }
1990
1697
  /**
1991
1698
  * 包围盒转换为数组
@@ -1993,96 +1700,80 @@ class Quadtree {
1993
1700
  * @param colors
1994
1701
  * @returns
1995
1702
  */
1996
- boundsToArray(array = [], colors, recursion = true) {
1997
- if (!this.isLeaf && recursion) {
1998
- this.children?.forEach((child) => child.boundsToArray(array, colors));
1999
- }
2000
- array.push(...this.bounds.points.flatMap((p, i, array2) => {
2001
- const np = array2[(i + 1) % array2.length];
2002
- colors?.push(...this.color);
2003
- colors?.push(...this.color);
2004
- return [p.x, p.y, 0, np.x, np.y, 0];
2005
- }));
2006
- return array;
1703
+ boundsToArray(t = [], e, n = !0) {
1704
+ return !this.isLeaf && n && this.children?.forEach((i) => i.boundsToArray(t, e)), t.push(...this.bounds.points.flatMap((i, o, s) => {
1705
+ const r = s[(o + 1) % s.length];
1706
+ return e?.push(...this.color), e?.push(...this.color), [i.x, i.y, 0, r.x, r.y, 0];
1707
+ })), t;
2007
1708
  }
2008
1709
  }
2009
- class PointVirtualGrid {
1710
+ class U {
2010
1711
  map = /* @__PURE__ */ new Map();
2011
1712
  gridSize;
2012
- constructor(gridSize = 2) {
2013
- this.gridSize = gridSize;
1713
+ constructor(t = 2) {
1714
+ this.gridSize = t;
2014
1715
  }
2015
1716
  /**
2016
1717
  * 插入
2017
1718
  * @param point
2018
1719
  * @param userData
2019
1720
  */
2020
- insert(point, userData) {
2021
- if (!point || isNaN(point.x) || isNaN(point.y)) {
1721
+ insert(t, e) {
1722
+ if (!t || isNaN(t.x) || isNaN(t.y))
2022
1723
  throw new Error("无效的点坐标");
2023
- }
2024
- const id = this.getGridId(point);
2025
- if (!this.map.has(id)) this.map.set(id, /* @__PURE__ */ new Set());
2026
- const set = this.map.get(id);
2027
- const target = { point, userData };
2028
- set.add(target);
2029
- point.userData.pointVirtualGrid = { set, target };
1724
+ const n = this.getGridId(t);
1725
+ this.map.has(n) || this.map.set(n, /* @__PURE__ */ new Set());
1726
+ const i = this.map.get(n), o = { point: t, userData: e };
1727
+ i.add(o), t.userData.pointVirtualGrid = { set: i, target: o };
2030
1728
  }
2031
1729
  /**
2032
1730
  * 批量加入
2033
1731
  * @param points
2034
1732
  */
2035
- insertBatch(points) {
2036
- for (const { point, userData } of points) {
2037
- this.insert(point, userData);
2038
- }
1733
+ insertBatch(t) {
1734
+ for (const { point: e, userData: n } of t)
1735
+ this.insert(e, n);
2039
1736
  }
2040
1737
  /** 移除点
2041
1738
  * @param point
2042
1739
  */
2043
- remove(point) {
2044
- const { set, target } = point?.userData?.pointVirtualGrid;
2045
- if (set) {
2046
- set.delete(target);
2047
- delete point?.userData?.pointVirtualGridMap;
2048
- }
1740
+ remove(t) {
1741
+ const { set: e, target: n } = t?.userData?.pointVirtualGrid;
1742
+ e && (e.delete(n), delete t?.userData?.pointVirtualGridMap);
2049
1743
  }
2050
1744
  /**
2051
1745
  * 获取通过坐标,获取唯一网格索引
2052
1746
  * @param point
2053
1747
  * @returns
2054
1748
  */
2055
- getGridId(point) {
2056
- const i = Math.ceil(point.x / this.gridSize), j = Math.ceil(point.y / this.gridSize);
2057
- return `${i}.${j}`;
1749
+ getGridId(t) {
1750
+ const e = Math.ceil(t.x / this.gridSize), n = Math.ceil(t.y / this.gridSize);
1751
+ return `${e}.${n}`;
2058
1752
  }
2059
1753
  /**
2060
1754
  *
2061
1755
  * @param gridId
2062
1756
  * @returns
2063
1757
  */
2064
- decodeGridId(gridId) {
2065
- const [i, j] = gridId.split(".").map(Number);
2066
- return new Point(i, j);
1758
+ decodeGridId(t) {
1759
+ const [e, n] = t.split(".").map(Number);
1760
+ return new p(e, n);
2067
1761
  }
2068
1762
  /**
2069
1763
  * 查询与矩形相交的点
2070
1764
  * @param rectangle 矩形
2071
1765
  * @returns 相交的节点数组
2072
1766
  */
2073
- queryRect(rectangle) {
2074
- const box2 = rectangle.toBox();
2075
- const minI = Math.ceil(box2.minX / this.gridSize), maxI = Math.ceil(box2.maxX / this.gridSize), minJ = Math.ceil(box2.minY / this.gridSize), maxJ = Math.ceil(box2.maxY / this.gridSize);
2076
- for (let i = minI; i <= maxI; i++) {
2077
- for (let j = minJ; j <= maxJ; j++) {
2078
- const id = `${i}.${j}`;
2079
- if (!this.map.has(id)) continue;
2080
- const set = this.map.get(id);
2081
- set?.forEach((item) => {
2082
- if (rectangle.containsPoint(item.point)) ;
1767
+ queryRect(t) {
1768
+ const e = t.toBox(), n = Math.ceil(e.minX / this.gridSize), i = Math.ceil(e.maxX / this.gridSize), o = Math.ceil(e.minY / this.gridSize), s = Math.ceil(e.maxY / this.gridSize);
1769
+ for (let r = n; r <= i; r++)
1770
+ for (let c = o; c <= s; c++) {
1771
+ const a = `${r}.${c}`;
1772
+ if (!this.map.has(a)) continue;
1773
+ this.map.get(a)?.forEach((l) => {
1774
+ t.containsPoint(l.point);
2083
1775
  });
2084
1776
  }
2085
- }
2086
1777
  }
2087
1778
  /**
2088
1779
  * 查询与圆形区域相交的点
@@ -2090,62 +1781,53 @@ class PointVirtualGrid {
2090
1781
  * @param radius 半径
2091
1782
  * @returns 相交的节点数组
2092
1783
  */
2093
- queryCircle(pos, radius) {
2094
- const box2 = new Box2(pos.x - radius, pos.x + radius, pos.y - radius, pos.y + radius);
2095
- const minI = Math.ceil(box2.minX / this.gridSize), maxI = Math.ceil(box2.maxX / this.gridSize), minJ = Math.ceil(box2.minY / this.gridSize), maxJ = Math.ceil(box2.maxY / this.gridSize), list = [];
2096
- for (let i = minI; i <= maxI; i++) {
2097
- for (let j = minJ; j <= maxJ; j++) {
2098
- const id = `${i}.${j}`;
2099
- if (!this.map.has(id)) continue;
2100
- const set = this.map.get(id);
2101
- set?.forEach((item) => {
2102
- if (pos.distance(item.point) <= radius) list.push(item);
1784
+ queryCircle(t, e) {
1785
+ const n = new v(t.x - e, t.x + e, t.y - e, t.y + e), i = Math.ceil(n.minX / this.gridSize), o = Math.ceil(n.maxX / this.gridSize), s = Math.ceil(n.minY / this.gridSize), r = Math.ceil(n.maxY / this.gridSize), c = [];
1786
+ for (let a = i; a <= o; a++)
1787
+ for (let h = s; h <= r; h++) {
1788
+ const l = `${a}.${h}`;
1789
+ if (!this.map.has(l)) continue;
1790
+ this.map.get(l)?.forEach((f) => {
1791
+ t.distance(f.point) <= e && c.push(f);
2103
1792
  });
2104
1793
  }
2105
- }
2106
- return list;
1794
+ return c;
2107
1795
  }
2108
1796
  /**
2109
1797
  * 查询与包围盒相交的点
2110
1798
  * @param box2 包围盒
2111
1799
  * @returns 相交的节点数组
2112
1800
  */
2113
- queryBox(box2) {
2114
- const minI = Math.ceil(box2.minX / this.gridSize), maxI = Math.ceil(box2.maxX / this.gridSize), minJ = Math.ceil(box2.minY / this.gridSize), maxJ = Math.ceil(box2.maxY / this.gridSize), list = [];
2115
- for (let i = minI; i <= maxI; i++) {
2116
- for (let j = minJ; j <= maxJ; j++) {
2117
- const id = `${i}.${j}`;
2118
- if (!this.map.has(id)) continue;
2119
- const set = this.map.get(id);
2120
- set?.forEach((item) => {
2121
- if (box2.containsPoint(item.point)) list.push(item);
1801
+ queryBox(t) {
1802
+ const e = Math.ceil(t.minX / this.gridSize), n = Math.ceil(t.maxX / this.gridSize), i = Math.ceil(t.minY / this.gridSize), o = Math.ceil(t.maxY / this.gridSize), s = [];
1803
+ for (let r = e; r <= n; r++)
1804
+ for (let c = i; c <= o; c++) {
1805
+ const a = `${r}.${c}`;
1806
+ if (!this.map.has(a)) continue;
1807
+ this.map.get(a)?.forEach((l) => {
1808
+ t.containsPoint(l.point) && s.push(l);
2122
1809
  });
2123
1810
  }
2124
- }
2125
- return list;
1811
+ return s;
2126
1812
  }
2127
1813
  /**
2128
1814
  * 查找相同点
2129
1815
  * @param point
2130
1816
  */
2131
- queryPoint(point) {
2132
- const id = this.getGridId(point), list = [];
2133
- if (this.map.has(id)) {
2134
- const set = this.map.get(id);
2135
- set?.forEach((item) => {
2136
- if (point.equal(item.point)) list.push(item);
2137
- });
2138
- }
2139
- return list;
1817
+ queryPoint(t) {
1818
+ const e = this.getGridId(t), n = [];
1819
+ return this.map.has(e) && this.map.get(e)?.forEach((o) => {
1820
+ t.equal(o.point) && n.push(o);
1821
+ }), n;
2140
1822
  }
2141
1823
  }
2142
- class DoorsAnalysis {
1824
+ class rt {
2143
1825
  // 所有可查找的点位
2144
1826
  possibleDoorPoints = [];
2145
1827
  doorPoint = [];
2146
1828
  dxf;
2147
1829
  // 包含所有点的虚拟网格
2148
- pointVirtualGrid = new PointVirtualGrid();
1830
+ pointVirtualGrid = new U();
2149
1831
  // 只包含可查找点的虚拟网格
2150
1832
  findPointVirtualGrid;
2151
1833
  quadtree;
@@ -2156,158 +1838,111 @@ class DoorsAnalysis {
2156
1838
  doorSearchDistance = 2;
2157
1839
  doors = [];
2158
1840
  lineAnalysis;
2159
- continueFind = true;
2160
- constructor(lineAnalysis) {
2161
- this.lineAnalysis = lineAnalysis;
2162
- this.dxf = lineAnalysis.Dxf;
2163
- this.findPointVirtualGrid = new PointVirtualGrid();
2164
- this.quadtree = lineAnalysis.quadtree;
2165
- this.resultList = lineAnalysis.resultList;
2166
- this.lineSegments = lineAnalysis.lineSegmentList;
2167
- this.dxf.doorLineSegment.length = 0;
2168
- this.lineSegments.forEach((line) => {
2169
- this.pointVirtualGrid.insert(line.start, line);
2170
- this.pointVirtualGrid.insert(line.end, line);
2171
- });
2172
- this.doorPoint = this.getDoorPoint();
2173
- if (!this.continueFind) return;
2174
- const excludeIndexMap = this.searchDoubleLinePoint();
2175
- this.addPointsExcludeRule((line, _2, pointIndex) => {
2176
- const index2 = this.lineSegments.indexOf(line);
2177
- const excludeMode = excludeIndexMap.get(index2);
2178
- if (typeof excludeMode === "number") {
2179
- return excludeMode === -1 || excludeMode === pointIndex;
2180
- }
2181
- return false;
2182
- });
2183
- this.addPointsExcludeRule((_1, point) => {
2184
- return !!this.doorPoint.find((p1) => p1.point.equal(point));
2185
- });
2186
- this.possibleDoorPoints = this.getPossiblePoints();
2187
- this.possibleDoorPoints.forEach((p) => this.findPointVirtualGrid.insert(p.point, p.line));
2188
- this.handle();
1841
+ continueFind = !0;
1842
+ constructor(t) {
1843
+ if (this.lineAnalysis = t, this.dxf = t.Dxf, this.findPointVirtualGrid = new U(), this.quadtree = t.quadtree, this.resultList = t.resultList, this.lineSegments = t.lineSegmentList, this.dxf.doorLineSegment.length = 0, this.lineSegments.forEach((n) => {
1844
+ this.pointVirtualGrid.insert(n.start, n), this.pointVirtualGrid.insert(n.end, n);
1845
+ }), this.doorPoint = this.getDoorPoint(), !this.continueFind) return;
1846
+ const e = this.searchDoubleLinePoint();
1847
+ this.addPointsExcludeRule((n, i, o) => {
1848
+ const s = this.lineSegments.indexOf(n), r = e.get(s);
1849
+ return typeof r == "number" ? r === -1 || r === o : !1;
1850
+ }), this.addPointsExcludeRule((n, i) => !!this.doorPoint.find((o) => o.point.equal(i))), this.possibleDoorPoints = this.getPossiblePoints(), this.possibleDoorPoints.forEach((n) => this.findPointVirtualGrid.insert(n.point, n.line)), this.handle();
2189
1851
  }
2190
1852
  handle() {
2191
- this.dxf.doorLineSegment.push(...this.search(this.doorPoint, this.possibleDoorPoints, 0.5));
2192
- if (this.doorPoint.length < 2) this.dxf.doorLineSegment.push(...this.search(this.possibleDoorPoints, this.possibleDoorPoints, 0.6));
2193
- }
2194
- search(doorPoints, possibleDoorPoints = [], minDoorWidth = 0.6, doorSearchDistance = this.doorSearchDistance, doorSearchNearAngle = this.doorSearchNearAngle) {
2195
- const dxf = this.dxf;
2196
- const doors = this.searchNearby(doorPoints, possibleDoorPoints, doorSearchDistance, doorSearchNearAngle);
2197
- doors.push(
2198
- ...doorPoints.map((item) => {
2199
- const res2 = this.searchAlongDirection(item, doorSearchDistance);
2200
- if (res2) return {
2201
- start: item.point,
2202
- end: res2.point
1853
+ this.dxf.doorLineSegment.push(...this.search(this.doorPoint, this.possibleDoorPoints, 0.5)), this.doorPoint.length < 2 && this.dxf.doorLineSegment.push(...this.search(this.possibleDoorPoints, this.possibleDoorPoints, 0.6));
1854
+ }
1855
+ search(t, e = [], n = 0.6, i = this.doorSearchDistance, o = this.doorSearchNearAngle) {
1856
+ const s = this.dxf, r = this.searchNearby(t, e, i, o);
1857
+ r.push(
1858
+ ...t.map((a) => {
1859
+ const h = this.searchAlongDirection(a, i);
1860
+ if (h) return {
1861
+ start: a.point,
1862
+ end: h.point
2203
1863
  };
2204
- const res3 = this.searchAlongNormalDirection(item, doorSearchDistance);
2205
- if (res3) return {
2206
- start: item.point,
2207
- end: res3.point
1864
+ const l = this.searchAlongNormalDirection(a, i);
1865
+ if (l) return {
1866
+ start: a.point,
1867
+ end: l.point
2208
1868
  };
2209
- }).filter((i) => !!i && i.start.distance(i.end) < doorSearchDistance)
1869
+ }).filter((a) => !!a && a.start.distance(a.end) < i)
2210
1870
  );
2211
- const doorLineSegment = [];
2212
- doors.forEach((p) => {
2213
- const line = new LineSegment(p?.start, p?.end);
2214
- const len = line.length();
2215
- if (len < minDoorWidth) return;
2216
- const normal = line.normal(), direction = line.direction(), step = (len - dxf.width * 2) / 2;
2217
- for (let i = 0; i < 3; i++) {
2218
- const point = line.start.clone().add(direction.clone().multiplyScalar(dxf.width + step * i));
2219
- const rLine = new LineSegment(
2220
- point,
2221
- point.clone().add(normal.clone().multiplyScalar(1))
1871
+ const c = [];
1872
+ return r.forEach((a) => {
1873
+ const h = new L(a?.start, a?.end), l = h.length();
1874
+ if (l < n) return;
1875
+ const d = h.normal(), f = h.direction(), m = (l - s.width * 2) / 2;
1876
+ for (let g = 0; g < 3; g++) {
1877
+ const u = h.start.clone().add(f.clone().multiplyScalar(s.width + m * g)), x = new L(
1878
+ u,
1879
+ u.clone().add(d.clone().multiplyScalar(1))
2222
1880
  );
2223
- rLine.directionMove(normal, -0.5);
2224
- const res = this.quadtree.queryLineSegment(rLine);
2225
- if (res.length) return;
1881
+ if (x.directionMove(d, -0.5), this.quadtree.queryLineSegment(x).length) return;
2226
1882
  }
2227
- doorLineSegment.push(line);
2228
- });
2229
- return doorLineSegment;
1883
+ c.push(h);
1884
+ }), c;
2230
1885
  }
2231
1886
  /** 添加可查找点的过滤规则
2232
1887
  * @param rule
2233
1888
  */
2234
- addPointsExcludeRule(rule) {
2235
- this._pointsExcludeRule.push(rule);
1889
+ addPointsExcludeRule(t) {
1890
+ this._pointsExcludeRule.push(t);
2236
1891
  }
2237
1892
  _pointsExcludeRule = [];
2238
1893
  /**
2239
1894
  * 查找所有可能为门的点位
2240
1895
  */
2241
1896
  getPossiblePoints() {
2242
- const doorPoints = [];
2243
- this.lineSegments.forEach((line) => {
2244
- line.points.forEach((p, j) => {
2245
- for (let i = 0; i < this._pointsExcludeRule.length; i++) if (this._pointsExcludeRule[i](line, p, j)) return;
2246
- const res = this.pointVirtualGrid.queryPoint(p).filter((d) => d.userData !== line);
2247
- if (res.length === 0) {
2248
- doorPoints.push({ line, point: p, uuid: uuid() });
2249
- }
1897
+ const t = [];
1898
+ return this.lineSegments.forEach((e) => {
1899
+ e.points.forEach((n, i) => {
1900
+ for (let s = 0; s < this._pointsExcludeRule.length; s++) if (this._pointsExcludeRule[s](e, n, i)) return;
1901
+ this.pointVirtualGrid.queryPoint(n).filter((s) => s.userData !== e).length === 0 && t.push({ line: e, point: n, uuid: z() });
2250
1902
  });
2251
- });
2252
- return doorPoints;
1903
+ }), t;
2253
1904
  }
2254
1905
  /**
2255
1906
  * 查找已知为门的点位
2256
1907
  */
2257
1908
  getDoorPoint() {
2258
- const doorPoints = [], dxf = this.dxf, pointVirtualGrid = this.pointVirtualGrid;
2259
- dxf.doors.forEach((item) => {
2260
- const doorLine = dxf.lineSegments[item[4]];
2261
- const doorData = dxf.originalData[item[4]];
2262
- if (doorData.drawDoorData) {
2263
- const point = Point.from(doorData.drawDoorData.start);
2264
- const direct = Point.from(doorData.drawDoorData.n);
2265
- const resList = pointVirtualGrid.queryPoint(point).filter((res) => {
2266
- if (res.userData === doorLine) return false;
2267
- const line = res.userData;
2268
- const direct2 = line.direction();
2269
- if (line.start.equal(point)) direct2.multiplyScalar(-1);
2270
- const angle = direct.angleBetween(direct2, "angle");
2271
- return angle > 80 || angle < 10;
1909
+ const t = [], e = this.dxf, n = this.pointVirtualGrid;
1910
+ return e.doors.forEach((i) => {
1911
+ const o = e.lineSegments[i[4]], s = e.originalData[i[4]];
1912
+ if (s.drawDoorData) {
1913
+ const r = p.from(s.drawDoorData.start), c = p.from(s.drawDoorData.n), a = n.queryPoint(r).filter((h) => {
1914
+ if (h.userData === o) return !1;
1915
+ const l = h.userData, d = l.direction();
1916
+ l.start.equal(r) && d.multiplyScalar(-1);
1917
+ const f = c.angleBetween(d, "angle");
1918
+ return f > 80 || f < 10;
2272
1919
  });
2273
- if (resList.length) {
2274
- doorPoints.push({
2275
- line: resList[0].userData,
2276
- point,
2277
- uuid: uuid()
2278
- });
2279
- }
2280
- } else if (doorData.doorDirectConnection) {
2281
- this.continueFind = false;
2282
- const line = new LineSegment(Point.from(doorData.start), Point.from(doorData.end));
2283
- line.userData = {
2284
- doorDirectConnection: true,
2285
- isDoor: true
2286
- };
2287
- this.dxf.doorLineSegment.push(line);
2288
- } else {
2289
- console.warn(`门的线段顺序${item[4]} 没有drawDoorData属性`);
2290
- }
2291
- });
2292
- console.log("门点位数量:", doorPoints.length);
2293
- return doorPoints;
1920
+ a.length && t.push({
1921
+ line: a[0].userData,
1922
+ point: r,
1923
+ uuid: z()
1924
+ });
1925
+ } else if (s.doorDirectConnection) {
1926
+ this.continueFind = !1;
1927
+ const r = new L(p.from(s.start), p.from(s.end));
1928
+ r.userData = {
1929
+ doorDirectConnection: !0,
1930
+ isDoor: !0
1931
+ }, this.dxf.doorLineSegment.push(r);
1932
+ } else
1933
+ console.warn(`门的线段顺序${i[4]} 没有drawDoorData属性`);
1934
+ }), t;
2294
1935
  }
2295
1936
  /**
2296
1937
  * 查找双线墙的点位
2297
1938
  * @returns
2298
1939
  */
2299
1940
  searchDoubleLinePoint() {
2300
- const excludeIndexMap = /* @__PURE__ */ new Map();
2301
- this.resultList.flatMap((p) => {
2302
- const line0 = this.lineSegments[p.sourceIndex], line1 = this.lineSegments[p.targetIndex], start0 = line1.projectPoint(line0.start), end0 = line1.projectPoint(line0.end), start1 = line0.projectPoint(line1.start), end1 = line0.projectPoint(line1.end), mode0 = start0 && end0 ? -1 : start0 ? 0 : end0 ? 1 : -1, mode1 = start1 && end1 ? -1 : start1 ? 0 : end1 ? 1 : -1;
2303
- if (excludeIndexMap.has(p.sourceIndex)) {
2304
- if (excludeIndexMap.get(p.sourceIndex) != mode0) excludeIndexMap.set(p.sourceIndex, -1);
2305
- } else excludeIndexMap.set(p.sourceIndex, mode0);
2306
- if (excludeIndexMap.has(p.targetIndex)) {
2307
- if (excludeIndexMap.get(p.targetIndex) != mode1) excludeIndexMap.set(p.targetIndex, -1);
2308
- } else excludeIndexMap.set(p.targetIndex, mode1);
2309
- });
2310
- return excludeIndexMap;
1941
+ const t = /* @__PURE__ */ new Map();
1942
+ return this.resultList.flatMap((e) => {
1943
+ const n = this.lineSegments[e.sourceIndex], i = this.lineSegments[e.targetIndex], o = i.projectPoint(n.start), s = i.projectPoint(n.end), r = n.projectPoint(i.start), c = n.projectPoint(i.end), a = o && s ? -1 : o ? 0 : s ? 1 : -1, h = r && c ? -1 : r ? 0 : c ? 1 : -1;
1944
+ t.has(e.sourceIndex) ? t.get(e.sourceIndex) != a && t.set(e.sourceIndex, -1) : t.set(e.sourceIndex, a), t.has(e.targetIndex) ? t.get(e.targetIndex) != h && t.set(e.targetIndex, -1) : t.set(e.targetIndex, h);
1945
+ }), t;
2311
1946
  }
2312
1947
  /** 查找方案一:最近点查找
2313
1948
  * @description 以点为圆心,查找半径内符合角度的点
@@ -2317,160 +1952,113 @@ class DoorsAnalysis {
2317
1952
  * @param doorSearchNearAngle 查找的角度
2318
1953
  * @returns
2319
1954
  */
2320
- searchNearby(doorPoints, possibleDoorPoints = [], doorSearchDistance = this.doorSearchDistance, doorSearchNearAngle = this.doorSearchNearAngle) {
2321
- const findPointVirtualGrid = this.findPointVirtualGrid, quadtree = this.quadtree;
2322
- function find({ point, line }, doorIndex, record2) {
2323
- const direct = line.direction();
2324
- if (line.start === point) direct.multiplyScalar(-1);
2325
- const res = findPointVirtualGrid.queryCircle(point, doorSearchDistance).filter((r) => r.userData !== line).sort((a, b) => a.point.distance(point) - b.point.distance(point));
2326
- const list = [];
2327
- for (let i = 0; i < res.length; i++) {
2328
- const doorIndex2 = possibleDoorPoints.findIndex((p) => p.point === res[i].point);
2329
- const id1 = doorPoints[doorIndex].uuid, id2 = possibleDoorPoints[doorIndex2].uuid;
2330
- if (record2.has(`${id1}.${id2}`)) continue;
2331
- record2.add(`${id1}.${id2}`);
2332
- record2.add(`${id2}.${id1}`);
2333
- const targetPoint = res[i].point, line2 = new LineSegment(point.clone(), targetPoint.clone()), angle = line2.direction().angleBetween(direct, "angle");
2334
- if (angle < doorSearchNearAngle) {
2335
- const direct2 = doorPoints[doorIndex2].line.direction();
2336
- const line22 = res[i].userData;
2337
- if (line22.start.equal(res[i].point)) direct2.multiplyScalar(-1);
2338
- const angle2 = line2.direction().multiplyScalar(-1).angleBetween(direct2, "angle");
2339
- if (angle2 < doorSearchNearAngle) {
2340
- if (!quadtree.queryLineSegment(line2).length) {
2341
- list.push({
2342
- findData: res[i],
2343
- findUuid: id2,
2344
- doorLine: line2,
2345
- doorUuid: id1
2346
- });
2347
- }
2348
- }
1955
+ searchNearby(t, e = [], n = this.doorSearchDistance, i = this.doorSearchNearAngle) {
1956
+ const o = this.findPointVirtualGrid, s = this.quadtree;
1957
+ function r({ point: u, line: x }, w, S) {
1958
+ const b = x.direction();
1959
+ x.start === u && b.multiplyScalar(-1);
1960
+ const P = o.queryCircle(u, n).filter((D) => D.userData !== x).sort((D, E) => D.point.distance(u) - E.point.distance(u)), A = [];
1961
+ for (let D = 0; D < P.length; D++) {
1962
+ const E = e.findIndex((T) => T.point === P[D].point), B = t[w].uuid, Y = e[E].uuid;
1963
+ if (S.has(`${B}.${Y}`)) continue;
1964
+ S.add(`${B}.${Y}`), S.add(`${Y}.${B}`);
1965
+ const Q = P[D].point, C = new L(u.clone(), Q.clone());
1966
+ if (C.direction().angleBetween(b, "angle") < i) {
1967
+ const T = t[E].line.direction();
1968
+ P[D].userData.start.equal(P[D].point) && T.multiplyScalar(-1), C.direction().multiplyScalar(-1).angleBetween(T, "angle") < i && (s.queryLineSegment(C).length || A.push({
1969
+ findData: P[D],
1970
+ findUuid: Y,
1971
+ doorLine: C,
1972
+ doorUuid: B
1973
+ }));
2349
1974
  }
2350
1975
  }
2351
- return list;
2352
- }
2353
- function deepSearchNearHandle(uuid2, snFindRecord2, list, record2, other) {
2354
- record2.add(uuid2);
2355
- const newList = [];
2356
- if (other) newList.push(other);
2357
- for (let i = 0; i < list.length; i++) {
2358
- const item = list[i];
2359
- if (snFindRecord2.has(item.findUuid)) {
2360
- const list2 = snFindRecord2.get(item.findUuid);
2361
- if (deepSearchNearHandle(item.findUuid, snFindRecord2, list2, record2, item)) newList.push(item);
2362
- } else newList.push(item);
1976
+ return A;
1977
+ }
1978
+ function c(u, x, w, S, b) {
1979
+ S.add(u);
1980
+ const P = [];
1981
+ b && P.push(b);
1982
+ for (let A = 0; A < w.length; A++) {
1983
+ const D = w[A];
1984
+ if (x.has(D.findUuid)) {
1985
+ const E = x.get(D.findUuid);
1986
+ c(D.findUuid, x, E, S, D) && P.push(D);
1987
+ } else P.push(D);
2363
1988
  }
2364
- newList.sort((a, b) => a.doorLine.length() - b.doorLine.length());
2365
- if (other && newList[0] === other) {
2366
- list.splice(0);
2367
- return true;
1989
+ return P.sort((A, D) => A.doorLine.length() - D.doorLine.length()), b && P[0] === b ? (w.splice(0), !0) : (w.splice(1), !1);
1990
+ }
1991
+ const a = /* @__PURE__ */ new Set(), h = /* @__PURE__ */ new Map();
1992
+ t.map((u, x) => {
1993
+ const w = r(u, x, a);
1994
+ w.length && h.set(u.uuid, w);
1995
+ }), a.clear();
1996
+ const l = /* @__PURE__ */ new Map();
1997
+ h.forEach((u, x) => {
1998
+ if (!a.has(x) && u.length && c(x, h, u, a), u.length) {
1999
+ const w = u[0];
2000
+ l.has(w.doorUuid) || l.set(w.doorUuid, []), l.get(w.doorUuid)?.push(w), l.has(w.findUuid) || l.set(w.findUuid, []), l.get(w.findUuid)?.push(w);
2368
2001
  }
2369
- list.splice(1);
2370
- return false;
2371
- }
2372
- const record = /* @__PURE__ */ new Set();
2373
- const snFindRecord = /* @__PURE__ */ new Map();
2374
- doorPoints.map((p, index2) => {
2375
- const list = find(p, index2, record);
2376
- if (list.length) snFindRecord.set(p.uuid, list);
2377
2002
  });
2378
- record.clear();
2379
- const temMap = /* @__PURE__ */ new Map();
2380
- snFindRecord.forEach((list, key) => {
2381
- if (!record.has(key) && list.length) {
2382
- deepSearchNearHandle(key, snFindRecord, list, record);
2383
- }
2384
- if (list.length) {
2385
- const item = list[0];
2386
- if (!temMap.has(item.doorUuid)) temMap.set(item.doorUuid, []);
2387
- temMap.get(item.doorUuid)?.push(item);
2388
- if (!temMap.has(item.findUuid)) temMap.set(item.findUuid, []);
2389
- temMap.get(item.findUuid)?.push(item);
2003
+ const d = /* @__PURE__ */ new Set();
2004
+ l.forEach((u) => {
2005
+ if (u.length > 1) {
2006
+ u.sort((x, w) => x.doorLine.length() - w.doorLine.length());
2007
+ for (let x = 1; x < u.length; x++) d.add(u[x]);
2390
2008
  }
2391
2009
  });
2392
- const deleteSet = /* @__PURE__ */ new Set();
2393
- temMap.forEach((list) => {
2394
- if (list.length > 1) {
2395
- list.sort((a, b) => a.doorLine.length() - b.doorLine.length());
2396
- for (let i = 1; i < list.length; i++) deleteSet.add(list[i]);
2010
+ const f = [], m = [];
2011
+ h.forEach((u) => {
2012
+ if (u.length) {
2013
+ const x = u[0];
2014
+ d.has(x) || (f.push(x), m.push(x.doorUuid, x.findUuid));
2397
2015
  }
2398
2016
  });
2399
- const searchNearRasult = [], removeDoorPointsUuid = [];
2400
- snFindRecord.forEach((list) => {
2401
- if (list.length) {
2402
- const item = list[0];
2403
- if (!deleteSet.has(item)) {
2404
- searchNearRasult.push(item);
2405
- removeDoorPointsUuid.push(item.doorUuid, item.findUuid);
2406
- }
2407
- }
2408
- });
2409
- const doors = [];
2410
- searchNearRasult.forEach((item) => {
2411
- const doorIndex = doorPoints.findIndex((p2) => p2.uuid === item.doorUuid);
2412
- const findDoorIndex = possibleDoorPoints.findIndex((p2) => p2.uuid === item.findUuid);
2413
- const start = doorPoints[doorIndex].point.clone();
2414
- const end = possibleDoorPoints[findDoorIndex].point.clone();
2415
- const startLine = this.findLongLineSegment(doorPoints[doorIndex].line);
2416
- const endLine = this.findLongLineSegment(possibleDoorPoints[findDoorIndex].line);
2417
- const p = startLine.projectPoint(end);
2418
- if (p) {
2419
- start.copy(p);
2420
- const l = new LineSegment(start, end);
2421
- const angle = endLine.includedAngle(l);
2422
- if (angle < 10 || angle > 170 || Math.abs(90 - angle) < 10) {
2423
- doors.push({
2424
- start,
2425
- end
2426
- });
2427
- }
2017
+ const g = [];
2018
+ return f.forEach((u) => {
2019
+ const x = t.findIndex((E) => E.uuid === u.doorUuid), w = e.findIndex((E) => E.uuid === u.findUuid), S = t[x].point.clone(), b = e[w].point.clone(), P = this.findLongLineSegment(t[x].line), A = this.findLongLineSegment(e[w].line), D = P.projectPoint(b);
2020
+ if (D) {
2021
+ S.copy(D);
2022
+ const E = new L(S, b), B = A.includedAngle(E);
2023
+ (B < 10 || B > 170 || Math.abs(90 - B) < 10) && g.push({
2024
+ start: S,
2025
+ end: b
2026
+ });
2428
2027
  } else {
2429
- const p2 = endLine.projectPoint(start);
2430
- if (p2) end.copy(p2);
2431
- const l = new LineSegment(start, end);
2432
- const angle = startLine.includedAngle(l);
2433
- if (angle < 10 || angle > 170 || Math.abs(90 - angle) < 10) {
2434
- doors.push({
2435
- start,
2436
- end
2437
- });
2438
- }
2028
+ const E = A.projectPoint(S);
2029
+ E && b.copy(E);
2030
+ const B = new L(S, b), Y = P.includedAngle(B);
2031
+ (Y < 10 || Y > 170 || Math.abs(90 - Y) < 10) && g.push({
2032
+ start: S,
2033
+ end: b
2034
+ });
2439
2035
  }
2440
- });
2441
- possibleDoorPoints.splice(
2036
+ }), e.splice(
2442
2037
  0,
2443
- possibleDoorPoints.length,
2444
- ...possibleDoorPoints.filter((p) => removeDoorPointsUuid.indexOf(p.uuid) === -1)
2445
- );
2446
- doorPoints.splice(
2038
+ e.length,
2039
+ ...e.filter((u) => m.indexOf(u.uuid) === -1)
2040
+ ), t.splice(
2447
2041
  0,
2448
- doorPoints.length,
2449
- ...doorPoints.filter((p) => removeDoorPointsUuid.indexOf(p.uuid) === -1)
2450
- );
2451
- return doors;
2042
+ t.length,
2043
+ ...t.filter((u) => m.indexOf(u.uuid) === -1)
2044
+ ), g;
2452
2045
  }
2453
2046
  /** 方案二: 沿方向查找
2454
2047
  * @description
2455
2048
  * @param param0
2456
2049
  * @returns
2457
2050
  */
2458
- searchAlongDirection({ point, line }, doorSearchDistance = this.doorSearchDistance) {
2459
- const quadtree = this.quadtree;
2460
- const direct = line.direction();
2461
- if (line.start === point) direct.multiplyScalar(-1);
2462
- const endPoint = point.clone().add(direct.clone().multiplyScalar(doorSearchDistance)), rline = new LineSegment(point.clone(), endPoint), result = quadtree.queryLineSegment(rline).map((l) => {
2463
- const res = l.line.getIntersection(rline);
2464
- return {
2465
- point: res,
2466
- line: l.line
2467
- };
2468
- }).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
2469
- if (result.length) {
2470
- const item = result[0];
2471
- if (Math.abs(90 - item.line.direction().angleBetween(direct, "angle")) < 5) {
2472
- return item;
2473
- }
2051
+ searchAlongDirection({ point: t, line: e }, n = this.doorSearchDistance) {
2052
+ const i = this.quadtree, o = e.direction();
2053
+ e.start === t && o.multiplyScalar(-1);
2054
+ const s = t.clone().add(o.clone().multiplyScalar(n)), r = new L(t.clone(), s), c = i.queryLineSegment(r).map((a) => ({
2055
+ point: a.line.getIntersection(r),
2056
+ line: a.line
2057
+ })).filter((a) => a.point).sort((a, h) => t.distance(a.point) - t.distance(h.point));
2058
+ if (c.length) {
2059
+ const a = c[0];
2060
+ if (Math.abs(90 - a.line.direction().angleBetween(o, "angle")) < 5)
2061
+ return a;
2474
2062
  }
2475
2063
  }
2476
2064
  /** 方案三: 沿法线方向查找
@@ -2479,35 +2067,25 @@ class DoorsAnalysis {
2479
2067
  * @param doorSearchDistance
2480
2068
  * @returns
2481
2069
  */
2482
- searchAlongNormalDirection({ point, line }, doorSearchDistance = this.doorSearchDistance) {
2483
- const pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree, direct = line.direction(), normal = line.start.normal(line.end), prePoint = line.start.clone();
2484
- if (line.start === point) direct.multiplyScalar(-1);
2485
- if (line.start === point) prePoint.copy(line.end);
2486
- const result = pointVirtualGrid.queryPoint(prePoint).filter((r) => r.userData !== line);
2487
- for (let i = 0; i < result.length; i++) {
2488
- const element = result[i];
2489
- const l = element.userData;
2490
- const d1 = l.direction();
2491
- if (l.start === element.point) direct.multiplyScalar(-1);
2492
- const angle = d1.angleBetween(normal) / (Math.PI / 180);
2493
- if (angle > 90) {
2494
- normal.multiplyScalar(-1);
2070
+ searchAlongNormalDirection({ point: t, line: e }, n = this.doorSearchDistance) {
2071
+ const i = this.pointVirtualGrid, o = this.quadtree, s = e.direction(), r = e.start.normal(e.end), c = e.start.clone();
2072
+ e.start === t && s.multiplyScalar(-1), e.start === t && c.copy(e.end);
2073
+ const a = i.queryPoint(c).filter((d) => d.userData !== e);
2074
+ for (let d = 0; d < a.length; d++) {
2075
+ const f = a[d], m = f.userData, g = m.direction();
2076
+ if (m.start === f.point && s.multiplyScalar(-1), g.angleBetween(r) / (Math.PI / 180) > 90) {
2077
+ r.multiplyScalar(-1);
2495
2078
  break;
2496
2079
  }
2497
2080
  }
2498
- const rline3 = new LineSegment(point.clone(), point.clone().add(normal.multiplyScalar(doorSearchDistance)));
2499
- const r3 = quadtree.queryLineSegment(rline3).map((l) => {
2500
- const res = l.line.getIntersection(rline3);
2501
- return {
2502
- point: res,
2503
- line: l.line
2504
- };
2505
- }).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
2506
- if (r3.length) {
2507
- const item = r3[0];
2508
- if (Math.abs(90 - item.line.direction().angleBetween(normal, "angle")) < 5) {
2509
- return item;
2510
- }
2081
+ const h = new L(t.clone(), t.clone().add(r.multiplyScalar(n))), l = o.queryLineSegment(h).map((d) => ({
2082
+ point: d.line.getIntersection(h),
2083
+ line: d.line
2084
+ })).filter((d) => d.point).sort((d, f) => t.distance(d.point) - t.distance(f.point));
2085
+ if (l.length) {
2086
+ const d = l[0];
2087
+ if (Math.abs(90 - d.line.direction().angleBetween(r, "angle")) < 5)
2088
+ return d;
2511
2089
  }
2512
2090
  }
2513
2091
  /**
@@ -2515,37 +2093,31 @@ class DoorsAnalysis {
2515
2093
  * @param line
2516
2094
  * @returns
2517
2095
  */
2518
- findLongLineSegment(line) {
2519
- const resLine = line.clone();
2520
- const res1 = this.pointVirtualGrid.queryPoint(line.start);
2521
- const res2 = this.pointVirtualGrid.queryPoint(line.end);
2522
- for (let i = 0; i < res1.length; i++) {
2523
- const { userData: line2 } = res1[i];
2524
- if (line2 === line) continue;
2525
- if (line2 && line2.directionEqual(line)) {
2526
- if (line2.start.equal(line.start)) resLine.start.copy(line2.end);
2527
- else resLine.start.copy(line2.start);
2096
+ findLongLineSegment(t) {
2097
+ const e = t.clone(), n = this.pointVirtualGrid.queryPoint(t.start), i = this.pointVirtualGrid.queryPoint(t.end);
2098
+ for (let o = 0; o < n.length; o++) {
2099
+ const { userData: s } = n[o];
2100
+ if (s !== t && s && s.directionEqual(t)) {
2101
+ s.start.equal(t.start) ? e.start.copy(s.end) : e.start.copy(s.start);
2528
2102
  break;
2529
2103
  }
2530
2104
  }
2531
- for (let i = 0; i < res2.length; i++) {
2532
- const { userData: line2 } = res2[i];
2533
- if (line2 === line) continue;
2534
- if (line2 && line2.directionEqual(line)) {
2535
- if (line2.end.equal(line.end)) resLine.end.copy(line2.start);
2536
- else resLine.end.copy(line2.end);
2105
+ for (let o = 0; o < i.length; o++) {
2106
+ const { userData: s } = i[o];
2107
+ if (s !== t && s && s.directionEqual(t)) {
2108
+ s.end.equal(t.end) ? e.end.copy(s.start) : e.end.copy(s.end);
2537
2109
  break;
2538
2110
  }
2539
2111
  }
2540
- return resLine;
2112
+ return e;
2541
2113
  }
2542
2114
  }
2543
- class LineAnalysis extends Component {
2115
+ class at extends j {
2544
2116
  static name = "LineAnalysis";
2545
2117
  Dxf = null;
2546
2118
  Variable = null;
2547
2119
  lineSegmentList = [];
2548
- container = new THREE.Group();
2120
+ container = new M.Group();
2549
2121
  // 误差角度
2550
2122
  errorAngle = 4;
2551
2123
  width = 0.4;
@@ -2553,11 +2125,8 @@ class LineAnalysis extends Component {
2553
2125
  *
2554
2126
  * @param parent
2555
2127
  */
2556
- onAddFromParent(parent) {
2557
- this.Dxf = parent.findComponentByType(Dxf);
2558
- this.Variable = this.parent?.findComponentByType(Variable);
2559
- this.Dxf.addEventListener("setDta", this.lineAnalysis.bind(this));
2560
- this.Dxf.addEventListener("createGroup", this.doorsAnalysis.bind(this));
2128
+ onAddFromParent(t) {
2129
+ this.Dxf = t.findComponentByType(X), this.Variable = this.parent?.findComponentByType(_), this.Dxf.addEventListener("setDta", this.lineAnalysis.bind(this)), this.Dxf.addEventListener("createGroup", this.doorsAnalysis.bind(this));
2561
2130
  }
2562
2131
  /**
2563
2132
  *
@@ -2566,20 +2135,16 @@ class LineAnalysis extends Component {
2566
2135
  * @param width
2567
2136
  * @returns
2568
2137
  */
2569
- expandLineSegment(p1, p2, width = 0.1) {
2570
- const normal = p2.normal(p1);
2571
- const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
2572
- const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
2573
- const offsetX = normal.x * width * 0.5;
2574
- const offsetY = normal.y * width * 0.5;
2138
+ expandLineSegment(t, e, n = 0.1) {
2139
+ const i = e.normal(t), o = e.direction(t).mutiplyScalar(n * 0.5), s = t.direction(e).mutiplyScalar(n * 0.5), r = i.x * n * 0.5, c = i.y * n * 0.5;
2575
2140
  return {
2576
2141
  points: [
2577
2142
  // 第一条线
2578
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
2579
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
2143
+ new p(t.x + r, t.y + c).add(s),
2144
+ new p(e.x + r, e.y + c).add(o),
2580
2145
  // 第二条线
2581
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
2582
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
2146
+ new p(t.x - r, t.y - c).add(s),
2147
+ new p(e.x - r, e.y - c).add(o)
2583
2148
  ],
2584
2149
  indices: [0, 1, 1, 3, 3, 2, 2, 0],
2585
2150
  rectIndices: [0, 1, 3, 2, 0]
@@ -2591,31 +2156,25 @@ class LineAnalysis extends Component {
2591
2156
  * @param p1
2592
2157
  * @param p2
2593
2158
  */
2594
- addData(p1, p2) {
2595
- const dxf = this.Dxf;
2596
- dxf.data.push([p1.clone(), p2.clone(), [], false, dxf.data.length]);
2597
- this.appendLineSegmentList.push(new LineSegment(p1.clone(), p2.clone()));
2159
+ addData(t, e) {
2160
+ const n = this.Dxf;
2161
+ n.data.push([t.clone(), e.clone(), [], !1, n.data.length]), this.appendLineSegmentList.push(new L(t.clone(), e.clone()));
2598
2162
  }
2599
2163
  /** 结果分析创建矩形
2600
2164
  * @param result
2601
2165
  */
2602
- createRectangle(result) {
2603
- const dxf = this.Dxf;
2604
- const project0 = result.project, project1 = result.project2;
2605
- if (project0.includedAngle(project1) > 135) {
2606
- project1.points = [project1.points[1], project1.points[0]];
2607
- }
2608
- this.addData(project0.points[0], project1.points[0]);
2609
- this.addData(project0.points[1], project1.points[1]);
2610
- const leftHeight = project0.points[0].distance(project1.points[0]), rightHeight = project0.points[1].distance(project1.points[1]), count = Math.ceil(Math.max(leftHeight, rightHeight) / dxf.width), leftFragment = leftHeight / count, rightFragment = rightHeight / count, leftDirection = project1.points[0].direction(project0.points[0]), rightDirection = project1.points[1].direction(project0.points[1]), leftP = project0.points[0].clone(), rightP = project0.points[1].clone(), direction = rightP.direction(leftP);
2611
- direction.multiplyScalar(dxf.width * 0.5);
2612
- const _leftP = leftP.clone().add(direction), _rightP = rightP.clone().add(direction.multiplyScalar(-1)), d1 = leftP.direction(rightP), d2 = _leftP.direction(_rightP);
2613
- if (d1.x > 0 && d2.x < 0 || d1.x < 0 && d2.x > 0 || d1.y > 0 && d2.y < 0 || d1.y < 0 && d2.y > 0) return;
2614
- leftP.set(_leftP.x, _leftP.y);
2615
- rightP.set(_rightP.x, _rightP.y);
2616
- for (let i = 1; i < count; i++) {
2617
- const left = leftDirection.clone().multiplyScalar(leftFragment * i), right = rightDirection.clone().multiplyScalar(rightFragment * i), p1 = leftP.clone().add(left), p2 = rightP.clone().add(right);
2618
- this.addData(p1, p2);
2166
+ createRectangle(t) {
2167
+ const e = this.Dxf, n = t.project, i = t.project2;
2168
+ n.includedAngle(i) > 135 && (i.points = [i.points[1], i.points[0]]), this.addData(n.points[0], i.points[0]), this.addData(n.points[1], i.points[1]);
2169
+ const o = n.points[0].distance(i.points[0]), s = n.points[1].distance(i.points[1]), r = Math.ceil(Math.max(o, s) / e.width), c = o / r, a = s / r, h = i.points[0].direction(n.points[0]), l = i.points[1].direction(n.points[1]), d = n.points[0].clone(), f = n.points[1].clone(), m = f.direction(d);
2170
+ m.multiplyScalar(e.width * 0.5);
2171
+ const g = d.clone().add(m), u = f.clone().add(m.multiplyScalar(-1)), x = d.direction(f), w = g.direction(u);
2172
+ if (!(x.x > 0 && w.x < 0 || x.x < 0 && w.x > 0 || x.y > 0 && w.y < 0 || x.y < 0 && w.y > 0)) {
2173
+ d.set(g.x, g.y), f.set(u.x, u.y);
2174
+ for (let S = 1; S < r; S++) {
2175
+ const b = h.clone().multiplyScalar(c * S), P = l.clone().multiplyScalar(a * S), A = d.clone().add(b), D = f.clone().add(P);
2176
+ this.addData(A, D);
2177
+ }
2619
2178
  }
2620
2179
  }
2621
2180
  quadtree;
@@ -2623,18 +2182,13 @@ class LineAnalysis extends Component {
2623
2182
  * 构建线段四叉树,快速查找,
2624
2183
  */
2625
2184
  buildQuadtree() {
2626
- const dxf = this.Dxf;
2627
- const lineSegmentList = [];
2628
- this.quadtree = new Quadtree(dxf.originalBox, 2);
2629
- dxf.lineSegments.forEach((lineSegment) => {
2630
- if (lineSegment.userData?.isDoor) return;
2631
- this.quadtree?.insert({
2632
- line: lineSegment,
2633
- userData: lineSegmentList.length
2634
- });
2635
- lineSegmentList.push(lineSegment);
2636
- });
2637
- this.lineSegmentList = lineSegmentList;
2185
+ const t = this.Dxf, e = [];
2186
+ this.quadtree = new q(t.originalBox, 2), t.lineSegments.forEach((n) => {
2187
+ n.userData?.isDoor || (this.quadtree?.insert({
2188
+ line: n,
2189
+ userData: e.length
2190
+ }), e.push(n));
2191
+ }), this.lineSegmentList = e;
2638
2192
  }
2639
2193
  resultList = [];
2640
2194
  mergeWallLines = [];
@@ -2644,24 +2198,18 @@ class LineAnalysis extends Component {
2644
2198
  */
2645
2199
  lineAnalysis() {
2646
2200
  this.buildQuadtree();
2647
- const quadtree = this.quadtree;
2648
- const lineSegmentList = this.lineSegmentList;
2649
- const visited = /* @__PURE__ */ new Set(), resultList = [];
2650
- lineSegmentList.forEach((_0, i) => {
2651
- const sourceLineSegment = lineSegmentList[i], rectangle = Rectangle.fromByLineSegment(sourceLineSegment, this.width * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index2) => index2 !== i);
2652
- ids.forEach((id) => {
2201
+ const t = this.quadtree, e = this.lineSegmentList, n = /* @__PURE__ */ new Set(), i = [];
2202
+ e.forEach((o, s) => {
2203
+ const r = e[s], c = N.fromByLineSegment(r, this.width * 2, !1, -0.01);
2204
+ t.queryRect(c).map((h) => h.userData).filter((h) => h !== s).forEach((h) => {
2653
2205
  try {
2654
- if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
2655
- const res = this.projectionAnalysis(id, i, sourceLineSegment, lineSegmentList);
2656
- if (res) resultList.push(res);
2657
- visited.add(`${i}-${id}`);
2658
- } catch (error) {
2206
+ if (n.has(`${s}-${h}`) || n.has(`${h}-${s}`)) return;
2207
+ const l = this.projectionAnalysis(h, s, r, e);
2208
+ l && i.push(l), n.add(`${s}-${h}`);
2209
+ } catch {
2659
2210
  }
2660
2211
  });
2661
- });
2662
- this.appendLineSegmentList.length = 0;
2663
- resultList.forEach(this.createRectangle.bind(this));
2664
- this.resultList = resultList;
2212
+ }), this.appendLineSegmentList.length = 0, i.forEach(this.createRectangle.bind(this)), this.resultList = i;
2665
2213
  }
2666
2214
  /** 线段投影分析
2667
2215
  * @param index
@@ -2669,43 +2217,40 @@ class LineAnalysis extends Component {
2669
2217
  * @param lineSegmentList
2670
2218
  * @returns
2671
2219
  */
2672
- projectionAnalysis(index2, sourceIndex, sourceLineSegment, lineSegmentList) {
2673
- const temLineSegment = lineSegmentList[index2], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angleBetween(temDirect) / (Math.PI / 180);
2674
- if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
2675
- let data;
2676
- const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
2677
- if (p1.getLength() > p2.getLength()) {
2678
- data = {
2679
- target: temLineSegment,
2680
- targetIndex: index2,
2681
- source: sourceLineSegment,
2682
- sourceIndex,
2683
- project: p1,
2684
- project2: p2
2685
- };
2686
- } else {
2687
- data = {
2688
- target: sourceLineSegment,
2689
- targetIndex: sourceIndex,
2690
- source: temLineSegment,
2691
- sourceIndex: index2,
2692
- project: p2,
2693
- project2: p1
2694
- };
2695
- }
2696
- if (!data || data.project.getLength() < 0.2 || data.project2.getLength() < 0.2) return;
2697
- return data;
2220
+ projectionAnalysis(t, e, n, i) {
2221
+ const o = i[t], s = n.direction(), r = o.direction(), c = s.angleBetween(r) / (Math.PI / 180);
2222
+ if (c < this.errorAngle || c > 180 - this.errorAngle) {
2223
+ let a;
2224
+ const h = o.projectLineSegment(n), l = n.projectLineSegment(o);
2225
+ return h.getLength() > l.getLength() ? a = {
2226
+ target: o,
2227
+ targetIndex: t,
2228
+ source: n,
2229
+ sourceIndex: e,
2230
+ project: h,
2231
+ project2: l
2232
+ } : a = {
2233
+ target: n,
2234
+ targetIndex: e,
2235
+ source: o,
2236
+ sourceIndex: t,
2237
+ project: l,
2238
+ project2: h
2239
+ }, !a || a.project.getLength() < 0.2 || a.project2.getLength() < 0.2 ? void 0 : a;
2698
2240
  }
2699
2241
  }
2700
2242
  doorSearchNearAngle = 110;
2701
2243
  doorSearchDistance = 2;
2702
2244
  doors = [];
2703
2245
  doorsAnalysis() {
2704
- new DoorsAnalysis(this);
2246
+ new rt(this), this.dispatchEvent({
2247
+ type: "analysisCompleted"
2248
+ });
2705
2249
  }
2706
2250
  }
2707
- class DxfSystem extends ComponentManager {
2251
+ class ct extends it {
2708
2252
  Dxf;
2253
+ AngleCorrectionDxf;
2709
2254
  Variable;
2710
2255
  wallWidth;
2711
2256
  environment;
@@ -2713,116 +2258,87 @@ class DxfSystem extends ComponentManager {
2713
2258
  * @param wallWidth 输出墙壁厚度,该墙壁厚度不受缩放影响
2714
2259
  * @param scale 原始数据缩放比例
2715
2260
  */
2716
- constructor(wallWidth = 0.1, scale = 1) {
2717
- super();
2718
- this.environment = typeof window !== "undefined" ? "browser" : typeof global !== "undefined" ? "node" : "unknown";
2719
- this.wallWidth = wallWidth;
2720
- this.Dxf = new Dxf(this.wallWidth, scale);
2721
- this.Variable = new Variable();
2722
- this.addComponent(this.Variable);
2723
- this.addComponent(this.Dxf);
2724
- this.addComponent(new LineAnalysis());
2261
+ constructor(t = 0.1, e = 1) {
2262
+ super(), this.environment = typeof window < "u" ? "browser" : typeof global < "u" ? "node" : "unknown", this.wallWidth = t, this.Dxf = new X(this.wallWidth, e), this.AngleCorrectionDxf = new ot(), this.Variable = new _(), this.addComponent(this.Variable), this.addComponent(this.Dxf), this.addComponent(new at()), this.addComponent(this.AngleCorrectionDxf);
2725
2263
  }
2726
- usePlugin(plugin) {
2727
- if (typeof plugin === "function") plugin.call(this, this);
2728
- return this;
2264
+ usePlugin(t) {
2265
+ return typeof t == "function" && t.call(this, this), this;
2729
2266
  }
2730
2267
  destroy() {
2731
- [...this.components].forEach((com) => {
2732
- com.destroy();
2733
- });
2734
- [...this.components].forEach((com) => {
2735
- this.removeComponent(com);
2268
+ [...this.components].forEach((t) => {
2269
+ t.destroy();
2270
+ }), [...this.components].forEach((t) => {
2271
+ this.removeComponent(t);
2736
2272
  });
2737
2273
  }
2738
2274
  }
2739
- const exporter = new OBJExporter();
2740
- const glbExporter = new GLTFExporter();
2741
- function lineSqueezing(p1, p2, width = 0.1) {
2742
- const normal = p2.normal(p1);
2743
- const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
2744
- const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
2745
- const offsetX = normal.x * width * 0.5;
2746
- const offsetY = normal.y * width * 0.5;
2275
+ const ht = new et(), lt = new nt();
2276
+ function dt(y, t, e = 0.1) {
2277
+ const n = t.normal(y), i = t.direction(y).mutiplyScalar(e * 0.5), o = y.direction(t).mutiplyScalar(e * 0.5), s = n.x * e * 0.5, r = n.y * e * 0.5;
2747
2278
  return {
2748
2279
  points: [
2749
2280
  // 第一条线
2750
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
2751
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
2281
+ new p(y.x + s, y.y + r).add(o),
2282
+ new p(t.x + s, t.y + r).add(i),
2752
2283
  // 第二条线
2753
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
2754
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
2284
+ new p(y.x - s, y.y - r).add(o),
2285
+ new p(t.x - s, t.y - r).add(i)
2755
2286
  ],
2756
2287
  indices: [0, 1, 1, 3, 3, 2, 2, 0],
2757
2288
  rectIndices: [0, 1, 3, 2, 0]
2758
2289
  };
2759
2290
  }
2760
- class WhiteModel extends Component {
2291
+ class H extends j {
2761
2292
  static name = "WhiteModel";
2762
2293
  Dxf = null;
2763
2294
  Variable = null;
2764
2295
  // dxf数据白模
2765
- whiteModelGroup = new THREE.Group();
2296
+ whiteModelGroup = new M.Group();
2766
2297
  // dxf数据白模边缘线
2767
- whiteModelLineGroup = new THREE.Group();
2298
+ whiteModelLineGroup = new M.Group();
2768
2299
  // 原始数据白模
2769
- originalWhiteMode = new THREE.Group();
2770
- material = new THREE.MeshBasicMaterial({ color: 16777215, transparent: true, opacity: 0.8, side: THREE.DoubleSide });
2771
- onAddFromParent(parent) {
2772
- this.Dxf = parent.findComponentByName("Dxf");
2773
- this.Variable = parent.findComponentByName("Variable");
2774
- this.originalWhiteMode.visible = false;
2775
- this.Dxf?.addEventListener("lineOffset", () => {
2300
+ originalWhiteMode = new M.Group();
2301
+ material = new M.MeshBasicMaterial({ color: 16777215, transparent: !0, opacity: 0.8, side: M.DoubleSide });
2302
+ onAddFromParent(t) {
2303
+ this.Dxf = t.findComponentByName("Dxf"), this.Variable = t.findComponentByName("Variable"), this.originalWhiteMode.visible = !1, this.Dxf?.addEventListener("lineOffset", () => {
2776
2304
  this.updateModel();
2777
2305
  });
2778
2306
  }
2779
2307
  updateModel() {
2780
- this.Variable?.set("whiteModelVisible", false);
2781
- const dxf = this.Dxf;
2782
- this.originalWhiteMode.clear();
2783
- this.whiteModelGroup.clear();
2784
- this.whiteModelLineGroup.clear();
2785
- this.whiteModelGroup.add(this.whiteModelLineGroup);
2786
- this.whiteModelGroup.position.z = dxf.originalZAverage;
2787
- this.originalWhiteMode.position.z = dxf.originalZAverage;
2788
- dxf.wallsGroup.forEach((points) => {
2789
- const shape = new THREE.Shape();
2790
- points.forEach((p, i) => i === 0 ? shape.moveTo(p.x / dxf.scale, p.y / dxf.scale) : shape.lineTo(p.x / dxf.scale, p.y / dxf.scale));
2791
- const geometry = new THREE.ExtrudeGeometry(shape, {
2308
+ this.Variable?.set("whiteModelVisible", !1);
2309
+ const t = this.Dxf;
2310
+ this.originalWhiteMode.clear(), this.whiteModelGroup.clear(), this.whiteModelLineGroup.clear(), this.whiteModelGroup.add(this.whiteModelLineGroup), this.whiteModelGroup.position.z = t.originalZAverage, this.originalWhiteMode.position.z = t.originalZAverage, t.wallsGroup.forEach((n) => {
2311
+ const i = new M.Shape();
2312
+ n.forEach((r, c) => c === 0 ? i.moveTo(r.x / t.scale, r.y / t.scale) : i.lineTo(r.x / t.scale, r.y / t.scale));
2313
+ const o = new M.ExtrudeGeometry(i, {
2792
2314
  depth: 2.8,
2793
2315
  bevelSize: 0
2794
- });
2795
- const mesh = new THREE.Mesh(geometry, this.material);
2796
- this.whiteModelGroup.add(mesh);
2797
- this.whiteModelLineGroup.add(
2798
- new THREE.LineSegments(new THREE.EdgesGeometry(geometry), new THREE.LineBasicMaterial({ color: 0 }))
2316
+ }), s = new M.Mesh(o, this.material);
2317
+ this.whiteModelGroup.add(s), this.whiteModelLineGroup.add(
2318
+ new M.LineSegments(new M.EdgesGeometry(o), new M.LineBasicMaterial({ color: 0 }))
2799
2319
  );
2800
- });
2801
- const walls = dxf.originalData.map(({ start, end, insetionArr }) => {
2802
- const startVec3 = new Point(start.x, start.y).mutiplyScalar(dxf.scale), endVec3 = new Point(end.x, end.y).mutiplyScalar(dxf.scale), { points, indices, rectIndices } = lineSqueezing(startVec3, endVec3, dxf.width);
2320
+ }), t.originalData.map(({ start: n, end: i, insetionArr: o }) => {
2321
+ const s = new p(n.x, n.y).mutiplyScalar(t.scale), r = new p(i.x, i.y).mutiplyScalar(t.scale), { points: c, indices: a, rectIndices: h } = dt(s, r, t.width);
2803
2322
  return {
2804
- points,
2805
- indices,
2806
- rectIndices,
2807
- insetions: (insetionArr ?? []).map((insetion) => insetion.index)
2323
+ points: c,
2324
+ indices: a,
2325
+ rectIndices: h,
2326
+ insetions: (o ?? []).map((l) => l.index)
2808
2327
  };
2809
- });
2810
- walls.forEach((wall) => {
2811
- const shape = new THREE.Shape();
2812
- wall.rectIndices.forEach((index2, i) => {
2813
- const p = wall.points[index2];
2814
- if (i === 0) shape.moveTo(p.x, p.y);
2815
- else shape.lineTo(p.x, p.y);
2328
+ }).forEach((n) => {
2329
+ const i = new M.Shape();
2330
+ n.rectIndices.forEach((r, c) => {
2331
+ const a = n.points[r];
2332
+ c === 0 ? i.moveTo(a.x, a.y) : i.lineTo(a.x, a.y);
2816
2333
  });
2817
- const geometry = new THREE.ExtrudeGeometry(shape, {
2334
+ const o = new M.ExtrudeGeometry(i, {
2818
2335
  depth: 2.8,
2819
2336
  bevelSize: 0
2820
2337
  });
2821
- if (geometry.attributes.position.array.filter((num) => Number.isNaN(num)).length) return;
2822
- const mesh = new THREE.Mesh(geometry);
2823
- this.originalWhiteMode?.add(mesh);
2824
- });
2825
- this.dispatchEvent({
2338
+ if (o.attributes.position.array.filter((r) => Number.isNaN(r)).length) return;
2339
+ const s = new M.Mesh(o);
2340
+ this.originalWhiteMode?.add(s);
2341
+ }), this.dispatchEvent({
2826
2342
  type: "updateModel",
2827
2343
  originalWhiteMode: this.originalWhiteMode,
2828
2344
  whiteModelGroup: this.whiteModelGroup
@@ -2833,13 +2349,9 @@ class WhiteModel extends Component {
2833
2349
  * @returns
2834
2350
  */
2835
2351
  toOBJ() {
2836
- return new Promise((resolve) => {
2837
- this.material.opacity = 1;
2838
- this.material.needsUpdate = true;
2839
- setTimeout(() => {
2840
- resolve(exporter.parse(this.whiteModelGroup));
2841
- this.material.opacity = 0.8;
2842
- this.material.transparent = true;
2352
+ return new Promise((t) => {
2353
+ this.material.opacity = 1, this.material.needsUpdate = !0, setTimeout(() => {
2354
+ t(ht.parse(this.whiteModelGroup)), this.material.opacity = 0.8, this.material.transparent = !0;
2843
2355
  }, 20);
2844
2356
  });
2845
2357
  }
@@ -2848,38 +2360,28 @@ class WhiteModel extends Component {
2848
2360
  * @param binary
2849
2361
  * @returns
2850
2362
  */
2851
- toGltf(binary = true) {
2852
- return new Promise((resolve) => {
2853
- this.material.opacity = 1;
2854
- this.material.needsUpdate = true;
2855
- setTimeout(async () => {
2856
- if (typeof window === "object") {
2857
- glbExporter.parse(this.whiteModelGroup.children, (gltf) => {
2858
- resolve(gltf);
2859
- this.material.opacity = 0.8;
2860
- this.material.transparent = true;
2363
+ toGltf(t = !0) {
2364
+ return new Promise((e) => {
2365
+ this.material.opacity = 1, this.material.needsUpdate = !0, setTimeout(async () => {
2366
+ if (typeof window == "object")
2367
+ lt.parse(this.whiteModelGroup.children, (n) => {
2368
+ e(n), this.material.opacity = 0.8, this.material.transparent = !0;
2861
2369
  }, () => {
2862
- resolve(void 0);
2370
+ e(void 0);
2863
2371
  }, {
2864
- binary
2372
+ binary: t
2865
2373
  });
2866
- } else if (typeof global !== "function") {
2374
+ else if (typeof global != "function")
2867
2375
  try {
2868
- const obj2gltf = await include("obj2gltf", true);
2869
- const fs = await include("fs", false);
2870
- const obj = await this.toOBJ();
2871
- fs.writeFileSync(this.uuid, obj);
2872
- const result = await obj2gltf(this.uuid, {
2873
- binary
2376
+ const n = await G("obj2gltf", !0), i = await G("fs", !1), o = await this.toOBJ();
2377
+ i.writeFileSync(this.uuid, o);
2378
+ const s = await n(this.uuid, {
2379
+ binary: t
2874
2380
  });
2875
- fs.unlinkSync(this.uuid);
2876
- if (binary) resolve(result);
2877
- else resolve(JSON.stringify(result));
2878
- } catch (error) {
2879
- resolve(void 0);
2880
- console.log(error);
2381
+ i.unlinkSync(this.uuid), e(t ? s : JSON.stringify(s));
2382
+ } catch (n) {
2383
+ e(void 0), console.log(n);
2881
2384
  }
2882
- }
2883
2385
  }, 20);
2884
2386
  });
2885
2387
  }
@@ -2888,40 +2390,33 @@ class WhiteModel extends Component {
2888
2390
  * @returns
2889
2391
  */
2890
2392
  async toOBJBlob() {
2891
- const buffer = await this.toOBJ();
2892
- if (buffer) {
2893
- return new Blob([buffer], { type: "application/octet-stream" });
2894
- }
2393
+ const t = await this.toOBJ();
2394
+ if (t)
2395
+ return new Blob([t], { type: "application/octet-stream" });
2895
2396
  }
2896
2397
  /**
2897
2398
  * 转为 GltfBlob
2898
2399
  * @returns
2899
2400
  */
2900
- async toGltfBlob(binary = true) {
2901
- const buffer = await this.toGltf(binary);
2902
- if (buffer) {
2903
- return new Blob([buffer], { type: "application/octet-stream" });
2904
- }
2401
+ async toGltfBlob(t = !0) {
2402
+ const e = await this.toGltf(t);
2403
+ if (e)
2404
+ return new Blob([e], { type: "application/octet-stream" });
2905
2405
  }
2906
2406
  /**
2907
2407
  * 下载 OBJ
2908
2408
  * @param filename
2909
2409
  * @returns
2910
2410
  */
2911
- async downloadOBJ(filename) {
2912
- if (typeof window !== "undefined") {
2913
- const blob = await this.toOBJBlob();
2914
- if (!blob) return;
2915
- const a = document.createElement("a");
2916
- a.href = URL.createObjectURL(blob);
2917
- a.download = filename;
2918
- a.click();
2919
- } else if (typeof global !== "undefined") {
2920
- const buffer = await this.toOBJ();
2921
- if (buffer) {
2922
- const fs = await include("fs", false);
2923
- fs.writeFileSync(filename, buffer);
2924
- }
2411
+ async downloadOBJ(t) {
2412
+ if (typeof window < "u") {
2413
+ const e = await this.toOBJBlob();
2414
+ if (!e) return;
2415
+ const n = document.createElement("a");
2416
+ n.href = URL.createObjectURL(e), n.download = t, n.click();
2417
+ } else if (typeof global < "u") {
2418
+ const e = await this.toOBJ();
2419
+ e && (await G("fs", !1)).writeFileSync(t, e);
2925
2420
  }
2926
2421
  }
2927
2422
  /**
@@ -2929,24 +2424,19 @@ class WhiteModel extends Component {
2929
2424
  * @param filename
2930
2425
  * @returns
2931
2426
  */
2932
- async downloadGltf(filename, binary = true) {
2933
- if (typeof window !== "undefined") {
2934
- const blob = await this.toGltfBlob(binary);
2935
- if (!blob) return;
2936
- const a = document.createElement("a");
2937
- a.href = URL.createObjectURL(blob);
2938
- a.download = filename;
2939
- a.click();
2940
- } else if (typeof global !== "undefined") {
2941
- const buffer = await this.toGltf(binary);
2942
- if (buffer) {
2943
- const fs = await include("fs", false);
2944
- fs.writeFileSync(filename, binary ? buffer : Buffer.from(buffer));
2945
- }
2427
+ async downloadGltf(t, e = !0) {
2428
+ if (typeof window < "u") {
2429
+ const n = await this.toGltfBlob(e);
2430
+ if (!n) return;
2431
+ const i = document.createElement("a");
2432
+ i.href = URL.createObjectURL(n), i.download = t, i.click();
2433
+ } else if (typeof global < "u") {
2434
+ const n = await this.toGltf(e);
2435
+ n && (await G("fs", !1)).writeFileSync(t, e ? n : Buffer.from(n));
2946
2436
  }
2947
2437
  }
2948
2438
  }
2949
- class DetailsPoint extends Component {
2439
+ class Z extends j {
2950
2440
  static name = "DetailsPoint";
2951
2441
  Dxf = null;
2952
2442
  WhiteModel = null;
@@ -2954,10 +2444,8 @@ class DetailsPoint extends Component {
2954
2444
  desPoints = [];
2955
2445
  raylines = [];
2956
2446
  data = [];
2957
- onAddFromParent(parent) {
2958
- this.Dxf = parent.findComponentByName("Dxf");
2959
- this.Variable = parent.findComponentByName("Variable");
2960
- this.Dxf?.addEventListener("setDta", () => {
2447
+ onAddFromParent(t) {
2448
+ this.Dxf = t.findComponentByName("Dxf"), this.Variable = t.findComponentByName("Variable"), this.Dxf?.addEventListener("setDta", () => {
2961
2449
  this.updateModel();
2962
2450
  });
2963
2451
  }
@@ -2965,37 +2453,29 @@ class DetailsPoint extends Component {
2965
2453
  * 设置值
2966
2454
  * @param data
2967
2455
  */
2968
- async set(data) {
2969
- if (typeof data === "string") {
2970
- if (typeof global !== "undefined") {
2971
- const packageName = "fs";
2972
- const { default: fs } = await import(
2456
+ async set(t) {
2457
+ if (typeof t == "string")
2458
+ if (typeof global < "u") {
2459
+ const { default: n } = await import(
2973
2460
  /* @vite-ignore */
2974
- packageName
2975
- );
2976
- const buffer = fs.readFileSync(data);
2977
- const json = JSON.parse(buffer.toString("utf-8"));
2978
- this.set(json);
2461
+ "fs"
2462
+ ), i = n.readFileSync(t), o = JSON.parse(i.toString("utf-8"));
2463
+ this.set(o);
2979
2464
  return;
2980
- } else {
2465
+ } else
2981
2466
  throw new Error("非node环境不允许使用路径");
2982
- }
2983
- }
2984
- this.data = data;
2985
- this.updateModel();
2467
+ this.data = t, this.updateModel();
2986
2468
  }
2987
2469
  /**
2988
2470
  * 设置射线辅助
2989
2471
  */
2990
- racasterHelper(position, direction, far) {
2991
- this.raylines.push([
2992
- position.clone(),
2993
- position.clone().add(direction.clone().multiplyScalar(far))
2994
- ]);
2995
- direction.z = 0;
2472
+ racasterHelper(t, e, n) {
2996
2473
  this.raylines.push([
2997
- position.clone(),
2998
- position.clone().add(direction.clone().multiplyScalar(far))
2474
+ t.clone(),
2475
+ t.clone().add(e.clone().multiplyScalar(n))
2476
+ ]), e.z = 0, this.raylines.push([
2477
+ t.clone(),
2478
+ t.clone().add(e.clone().multiplyScalar(n))
2999
2479
  ]);
3000
2480
  }
3001
2481
  _timer = null;
@@ -3003,161 +2483,134 @@ class DetailsPoint extends Component {
3003
2483
  * 更新模型
3004
2484
  */
3005
2485
  updateModel() {
3006
- if (this._timer) clearTimeout(this._timer);
3007
- this._timer = setTimeout(() => {
2486
+ this._timer && clearTimeout(this._timer), this._timer = setTimeout(() => {
3008
2487
  this._timer = null;
3009
- const whiteModel = this.parent?.findComponentByName("WhiteModel");
3010
- this.raylines.length = 0;
3011
- this.desPoints.length = 0;
3012
- this.data.forEach((item) => {
3013
- const position = new THREE.Vector3(
3014
- item.position.x,
3015
- item.position.y,
3016
- item.position.z
3017
- );
3018
- const direction = new THREE.Vector3(
3019
- item.direction.x,
3020
- item.direction.y,
3021
- item.direction.z
3022
- );
3023
- const far = 100;
3024
- this.racasterHelper(position, direction, far);
3025
- direction.z = 0;
3026
- const raycaster = new THREE.Raycaster(position, direction, 0, far);
3027
- const list = raycaster.intersectObject(whiteModel.originalWhiteMode);
3028
- if (list.length) {
3029
- const { point } = list[0];
2488
+ const t = this.parent?.findComponentByName("WhiteModel");
2489
+ this.raylines.length = 0, this.desPoints.length = 0, this.data.forEach((e) => {
2490
+ const n = new M.Vector3(
2491
+ e.position.x,
2492
+ e.position.y,
2493
+ e.position.z
2494
+ ), i = new M.Vector3(
2495
+ e.direction.x,
2496
+ e.direction.y,
2497
+ e.direction.z
2498
+ ), o = 100;
2499
+ this.racasterHelper(n, i, o), i.z = 0;
2500
+ const r = new M.Raycaster(n, i, 0, o).intersectObject(t.originalWhiteMode);
2501
+ if (r.length) {
2502
+ const { point: c } = r[0];
3030
2503
  this.desPoints.push({
3031
- message: item.desc,
3032
- position,
3033
- intersection: point
2504
+ message: e.desc,
2505
+ position: n,
2506
+ intersection: c
3034
2507
  });
3035
2508
  }
3036
- });
3037
- this.dispatchEvent({
2509
+ }), this.dispatchEvent({
3038
2510
  type: "handleSuccess",
3039
2511
  desPoints: this.desPoints
3040
2512
  });
3041
2513
  }, 50);
3042
2514
  }
3043
2515
  }
3044
- class DxfLineModel extends Component {
2516
+ class K extends j {
3045
2517
  static name = "DxfLineModel";
3046
- dxfLineModel = new THREE.LineSegments();
3047
- dxfDoorsLineModel = new THREE.LineSegments();
3048
- dxfModelGroup = new THREE.Group();
3049
- onAddFromParent(parent) {
3050
- const dxf = parent.findComponentByName("Dxf");
3051
- this.dxfModelGroup.add(this.dxfLineModel);
3052
- this.dxfModelGroup.add(this.dxfDoorsLineModel);
3053
- this.dxfDoorsLineModel.material = new THREE.LineBasicMaterial({ color: 16776960, vertexColors: true });
3054
- dxf?.addEventListener("lineOffset", () => this.updateMode());
2518
+ dxfLineModel = new M.LineSegments();
2519
+ dxfDoorsLineModel = new M.LineSegments();
2520
+ dxfModelGroup = new M.Group();
2521
+ onAddFromParent(t) {
2522
+ const e = t.findComponentByName("Dxf");
2523
+ this.dxfModelGroup.add(this.dxfLineModel), this.dxfModelGroup.add(this.dxfDoorsLineModel), this.dxfDoorsLineModel.material = new M.LineBasicMaterial({ color: 16776960, vertexColors: !0 }), e?.addEventListener("lineOffset", () => this.updateMode());
3055
2524
  }
3056
2525
  updateMode() {
3057
- const dxf = this.parent?.findComponentByName("Dxf");
2526
+ const t = this.parent?.findComponentByName("Dxf");
3058
2527
  this.dxfLineModel.clear();
3059
- const dxfArray = dxf.to3DArray(1 / dxf.scale, 0);
3060
- this.dxfLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(dxfArray, 3, true));
3061
- const doorsArray = new Float32Array(
3062
- dxf.doorLineSegment.flatMap(({ start, end }) => [start.x, start.y, 0, end.x, end.y, 0])
3063
- ).map((n) => n / dxf.scale);
3064
- const doorsColorArray = new Float32Array(dxf.doorLineSegment.flatMap(() => [1, 0, 0, 0, 1, 0]));
3065
- this.dxfDoorsLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(doorsArray, 3, true)).setAttribute("color", new THREE.BufferAttribute(doorsColorArray, 3));
3066
- this.dxfModelGroup.position.z = dxf.originalZAverage;
3067
- this.dispatchEvent({
2528
+ const e = t.to3DArray(1 / t.scale, 0);
2529
+ this.dxfLineModel.geometry = new M.BufferGeometry().setAttribute("position", new M.BufferAttribute(e, 3, !0));
2530
+ const n = new Float32Array(
2531
+ t.doorLineSegment.flatMap(({ start: o, end: s }) => [o.x, o.y, 0, s.x, s.y, 0])
2532
+ ).map((o) => o / t.scale), i = new Float32Array(t.doorLineSegment.flatMap(() => [1, 0, 0, 0, 1, 0]));
2533
+ this.dxfDoorsLineModel.geometry = new M.BufferGeometry().setAttribute("position", new M.BufferAttribute(n, 3, !0)).setAttribute("color", new M.BufferAttribute(i, 3)), this.dxfModelGroup.position.z = t.originalZAverage, this.dispatchEvent({
3068
2534
  type: "modelUpdate",
3069
2535
  model: this.dxfModelGroup
3070
2536
  });
3071
2537
  }
3072
2538
  }
3073
- const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2539
+ const ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3074
2540
  __proto__: null,
3075
- DetailsPoint,
3076
- DxfLineModel,
3077
- WhiteModel
2541
+ DetailsPoint: Z,
2542
+ DxfLineModel: K,
2543
+ WhiteModel: H
3078
2544
  }, Symbol.toStringTag, { value: "Module" }));
3079
- function ModelDataPlugin_(dxfSystem, option = {}) {
2545
+ function W(y, t = {}) {
3080
2546
  const {
3081
- detailsPoint = true,
3082
- whiteModel = true,
3083
- dxfLineModel = true
3084
- } = option;
3085
- dxfLineModel && dxfSystem.addComponent(new DxfLineModel());
3086
- whiteModel && dxfSystem.addComponent(new WhiteModel());
3087
- detailsPoint && dxfSystem.addComponent(new DetailsPoint());
2547
+ detailsPoint: e = !0,
2548
+ whiteModel: n = !0,
2549
+ dxfLineModel: i = !0
2550
+ } = t;
2551
+ i && y.addComponent(new K()), n && y.addComponent(new H()), e && y.addComponent(new Z());
3088
2552
  }
3089
- const ModelDataPlugin = Object.assign(ModelDataPlugin_, {
3090
- create(option = {}) {
3091
- return (dxfSystem) => ModelDataPlugin_(dxfSystem, option);
2553
+ const ft = Object.assign(W, {
2554
+ create(y = {}) {
2555
+ return (t) => W(t, y);
3092
2556
  }
3093
- });
3094
- const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2557
+ }), pt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3095
2558
  __proto__: null,
3096
- ModelDataPlugin,
3097
- components: index$1
2559
+ ModelDataPlugin: ft,
2560
+ components: ut
3098
2561
  }, Symbol.toStringTag, { value: "Module" }));
3099
- function loadRenderPlugin() {
2562
+ function mt() {
3100
2563
  return import("./index2.js");
3101
2564
  }
3102
- function loadEditorPlugin() {
2565
+ function xt() {
3103
2566
  return import("./index3.js");
3104
2567
  }
3105
- let gloabalDxfSystem = null;
3106
- async function createEditor(dom, camera, orbitControls = false, viewPermission) {
3107
- const mp = await Promise.resolve().then(() => index);
3108
- const rp = await loadRenderPlugin();
3109
- const editor = await loadEditorPlugin();
3110
- const dxfSystem = new DxfSystem().usePlugin(mp.ModelDataPlugin.create({
3111
- detailsPoint: false,
3112
- whiteModel: true
3113
- })).usePlugin(rp.RenderPlugin.create({
3114
- originalLine: false,
3115
- modelData: false,
3116
- detailsPoint: false,
3117
- orbitControls,
3118
- camera
3119
- })).usePlugin(editor.Editor.create({ viewPermission }));
3120
- const domContainer = dxfSystem.findComponentByType(rp.components.DomContainer);
3121
- domContainer && dom.appendChild(domContainer.domElement);
3122
- gloabalDxfSystem = dxfSystem;
3123
- return {
3124
- dxfSystem,
3125
- getFileAll: () => getFileAll(dxfSystem)
2568
+ let V = null;
2569
+ async function Et(y, t, e = !1, n) {
2570
+ const i = await Promise.resolve().then(() => pt), o = await mt(), s = await xt(), r = new ct().usePlugin(i.ModelDataPlugin.create({
2571
+ detailsPoint: !1,
2572
+ whiteModel: !0
2573
+ })).usePlugin(o.RenderPlugin.create({
2574
+ originalLine: !1,
2575
+ modelData: !1,
2576
+ detailsPoint: !1,
2577
+ orbitControls: e,
2578
+ camera: t
2579
+ })).usePlugin(s.Editor.create({ viewPermission: n })), c = r.findComponentByType(o.components.DomContainer);
2580
+ return c && y.appendChild(c.domElement), V = r, {
2581
+ dxfSystem: r,
2582
+ getFileAll: () => yt(r)
3126
2583
  };
3127
2584
  }
3128
- async function getFileAll(dxfSystem = gloabalDxfSystem) {
3129
- const whiteModel = dxfSystem.findComponentByName("WhiteModel");
3130
- const dxf = new File([dxfSystem.Dxf.toDxfBlob()], "dxf.dxf", { type: "application/dxf" });
3131
- const obj = new File([await whiteModel.toOBJBlob()], "model.obj", { type: "application/octet-stream" });
3132
- const glb = new File([await whiteModel.toGltfBlob(true)], "model.glb", { type: "application/octet-stream" });
3133
- const gltf = new File([await whiteModel.toGltfBlob(false)], "model.gltf", { type: "application/json" });
3134
- const json = new File([JSON.stringify(dxfSystem.Dxf.originalData)], "json.json", { type: "application/json" });
2585
+ async function yt(y = V) {
2586
+ const t = y.findComponentByName("WhiteModel"), e = new File([await y.AngleCorrectionDxf.toDxfImageBlob()], "img.jpg", { type: "image/jpeg" }), n = new File([y.Dxf.toDxfBlob()], "dxf.dxf", { type: "application/dxf" }), i = new File([await t.toOBJBlob()], "model.obj", { type: "application/octet-stream" }), o = new File([await t.toGltfBlob(!0)], "model.glb", { type: "application/octet-stream" }), s = new File([await t.toGltfBlob(!1)], "model.gltf", { type: "application/json" }), r = new File([JSON.stringify(y.Dxf.originalData)], "json.json", { type: "application/json" });
3135
2587
  return {
3136
- dxf,
3137
- obj,
3138
- glb,
3139
- gltf,
3140
- json
2588
+ dxf: n,
2589
+ obj: i,
2590
+ glb: o,
2591
+ gltf: s,
2592
+ json: r,
2593
+ jpg: e
3141
2594
  };
3142
2595
  }
3143
- function getGlobalDxfSystem() {
3144
- return gloabalDxfSystem;
2596
+ function At() {
2597
+ return V;
3145
2598
  }
3146
2599
  export {
3147
- Box2 as B,
3148
- Component as C,
3149
- DxfSystem as D,
3150
- EventDispatcher as E,
3151
- LineSegment as L,
3152
- ModelDataPlugin as M,
3153
- Point as P,
3154
- Quadtree as Q,
3155
- Variable as V,
3156
- WhiteModel as W,
3157
- DetailsPoint as a,
3158
- PointVirtualGrid as b,
3159
- createEditor as c,
3160
- getGlobalDxfSystem as d,
3161
- getFileAll as g,
3162
- index$1 as i
2600
+ v as B,
2601
+ j as C,
2602
+ ct as D,
2603
+ $ as E,
2604
+ L,
2605
+ ft as M,
2606
+ p as P,
2607
+ q as Q,
2608
+ _ as V,
2609
+ H as W,
2610
+ Z as a,
2611
+ U as b,
2612
+ Et as c,
2613
+ At as d,
2614
+ yt as g,
2615
+ ut as i
3163
2616
  };