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