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