build-dxf 0.1.113 → 0.1.114
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/api/index.d.ts +4 -1
- package/src/build.js +233 -165
- package/src/dxf-system/plugins/editor/components/CommandFlow/CFComponent.d.ts +7 -4
- package/src/dxf-system/plugins/editor/components/CommandFlow/{Default.d.ts → DefaultCommand.d.ts} +2 -2
- package/src/dxf-system/plugins/editor/components/CommandFlow/DrawHole.d.ts +37 -0
- package/src/dxf-system/plugins/editor/components/CommandFlow/DrawWindow.d.ts +1 -1
- package/src/dxf-system/plugins/editor/components/CommandFlow/PropertiesPanel.d.ts +1 -1
- package/src/dxf-system/plugins/editor/components/Editor.d.ts +1 -1
- package/src/dxf-system/plugins/editor/components/RenderManager.d.ts +2 -2
- package/src/dxf-system/plugins/editor/components/UIService.d.ts +2 -1
- package/src/dxf-system/plugins/editor/components/index.d.ts +1 -1
- package/src/dxf-system/plugins/editor/pages/EditorTool/EditorTool.vue.d.ts +1 -1
- package/src/dxf-system/plugins/editor/pages/PropertiesPanel.vue.d.ts +1 -1
- package/src/dxf-system/plugins/editor/utils/Wall2D.d.ts +10 -0
- package/src/dxf-system/utils/WallInsertObject.d.ts +6 -0
- package/src/dxf-system/utils/line-pipeline/builtin/door-to-hole.d.ts +1 -1
- package/src/dxf-system/utils/line-pipeline/builtin/double-wall-alignment.d.ts +1 -1
- package/src/index.css +9 -13
- package/src/index3.js +443 -34
- package/src/utils/algorithms/LineSegment.d.ts +22 -16
- package/src/utils/algorithms/Point.d.ts +6 -5
- package/src/utils/algorithms/Rectangle.d.ts +2 -2
- package/src/utils/three-object-3d/LineAlignmentGuide.d.ts +19 -0
- package/src/utils/three-object-3d/Shape2D.d.ts +61 -0
package/src/build.js
CHANGED
|
@@ -187,7 +187,7 @@ function cloneUserData(userData) {
|
|
|
187
187
|
return cloned;
|
|
188
188
|
}
|
|
189
189
|
class Rectangle {
|
|
190
|
-
points;
|
|
190
|
+
points = [Point.zero(), Point.zero(), Point.zero(), Point.zero()];
|
|
191
191
|
get p0() {
|
|
192
192
|
return this.points[0];
|
|
193
193
|
}
|
|
@@ -206,6 +206,11 @@ class Rectangle {
|
|
|
206
206
|
return [p2.x, p2.y, 0, np.x, np.y, 0];
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
|
+
constructor(points) {
|
|
210
|
+
if (points) {
|
|
211
|
+
points.forEach((p2, i) => this.points[i].copy(p2));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
209
214
|
path2D(callback) {
|
|
210
215
|
return this.points.flatMap((p2, i) => {
|
|
211
216
|
const np = this.points[(i + 1) % this.points.length];
|
|
@@ -229,12 +234,6 @@ class Rectangle {
|
|
|
229
234
|
this.p3
|
|
230
235
|
].flatMap((p2) => [p2.x, p2.y, 0]);
|
|
231
236
|
}
|
|
232
|
-
constructor(points) {
|
|
233
|
-
if (points.length !== 4) {
|
|
234
|
-
throw new Error("Rectangle must be defined by exactly 4 points");
|
|
235
|
-
}
|
|
236
|
-
this.points = points;
|
|
237
|
-
}
|
|
238
237
|
/**
|
|
239
238
|
* 判断线段是否与矩形相交
|
|
240
239
|
* @param line 线段
|
|
@@ -400,7 +399,11 @@ class LineSegment {
|
|
|
400
399
|
// line: any
|
|
401
400
|
uuid = uuid();
|
|
402
401
|
_length = 0;
|
|
403
|
-
|
|
402
|
+
/**
|
|
403
|
+
* 线段长度
|
|
404
|
+
* @returns
|
|
405
|
+
*/
|
|
406
|
+
get length() {
|
|
404
407
|
return this._length;
|
|
405
408
|
}
|
|
406
409
|
get start() {
|
|
@@ -414,6 +417,7 @@ class LineSegment {
|
|
|
414
417
|
return this._center.clone();
|
|
415
418
|
}
|
|
416
419
|
_direction = Point.zero();
|
|
420
|
+
onChange;
|
|
417
421
|
constructor(p1, p2) {
|
|
418
422
|
this.set(p1 ?? this.start, p2 ?? this.end);
|
|
419
423
|
this.start.currentData[LineSegment.LINE_SYMBOL] = this;
|
|
@@ -421,13 +425,16 @@ class LineSegment {
|
|
|
421
425
|
this._initLenListener();
|
|
422
426
|
}
|
|
423
427
|
_initLenListener() {
|
|
424
|
-
const
|
|
425
|
-
|
|
428
|
+
const onChange = () => {
|
|
429
|
+
const p0 = this.points[0];
|
|
430
|
+
const p1 = this.points[1];
|
|
431
|
+
this._length = p0.distance(p1);
|
|
432
|
+
this._direction = p1.directionFrom(p0);
|
|
426
433
|
this._center.set(
|
|
427
|
-
|
|
428
|
-
|
|
434
|
+
(p0.x + p1.x) * 0.5,
|
|
435
|
+
(p0.y + p1.y) * 0.5
|
|
429
436
|
);
|
|
430
|
-
this.
|
|
437
|
+
this.onChange?.();
|
|
431
438
|
};
|
|
432
439
|
this.points.forEach((p2) => fields.forEach((k) => {
|
|
433
440
|
let value = p2[k];
|
|
@@ -438,11 +445,11 @@ class LineSegment {
|
|
|
438
445
|
set(v2) {
|
|
439
446
|
if (value === v2) return;
|
|
440
447
|
value = v2;
|
|
441
|
-
|
|
448
|
+
onChange();
|
|
442
449
|
}
|
|
443
450
|
});
|
|
444
451
|
}));
|
|
445
|
-
|
|
452
|
+
onChange();
|
|
446
453
|
}
|
|
447
454
|
set(p1, p2) {
|
|
448
455
|
this.start.copy(p1);
|
|
@@ -454,13 +461,15 @@ class LineSegment {
|
|
|
454
461
|
const half = len * 0.5;
|
|
455
462
|
const dx = direct.x * half;
|
|
456
463
|
const dy = direct.y * half;
|
|
464
|
+
const cx = (this.start.x + this.end.x) * 0.5;
|
|
465
|
+
const cy = (this.start.y + this.end.y) * 0.5;
|
|
457
466
|
this.start.set(
|
|
458
|
-
|
|
459
|
-
|
|
467
|
+
cx - dx,
|
|
468
|
+
cy - dy
|
|
460
469
|
);
|
|
461
470
|
this.end.set(
|
|
462
|
-
|
|
463
|
-
|
|
471
|
+
cx + dx,
|
|
472
|
+
cy + dy
|
|
464
473
|
);
|
|
465
474
|
return this;
|
|
466
475
|
}
|
|
@@ -472,13 +481,6 @@ class LineSegment {
|
|
|
472
481
|
if (point2 === this.start) return this.end;
|
|
473
482
|
else return this.start;
|
|
474
483
|
}
|
|
475
|
-
/**
|
|
476
|
-
* 线段长度
|
|
477
|
-
* @returns
|
|
478
|
-
*/
|
|
479
|
-
length(_ = false) {
|
|
480
|
-
return this._length;
|
|
481
|
-
}
|
|
482
484
|
/** 开始点向线段内收缩 width
|
|
483
485
|
* @param width
|
|
484
486
|
*/
|
|
@@ -556,12 +558,12 @@ class LineSegment {
|
|
|
556
558
|
return this;
|
|
557
559
|
}
|
|
558
560
|
/** 向指定方向移动
|
|
559
|
-
* @param
|
|
561
|
+
* @param dist
|
|
560
562
|
* @param direction
|
|
561
563
|
* @returns
|
|
562
564
|
*/
|
|
563
|
-
translate(
|
|
564
|
-
const step = direction.clone().multiplyScalar(
|
|
565
|
+
translate(dist, direction = this.direction()) {
|
|
566
|
+
const step = direction.clone().multiplyScalar(dist);
|
|
565
567
|
this.start.add(step);
|
|
566
568
|
this.end.add(step);
|
|
567
569
|
return this;
|
|
@@ -621,30 +623,45 @@ class LineSegment {
|
|
|
621
623
|
* @param t
|
|
622
624
|
* @returns
|
|
623
625
|
*/
|
|
624
|
-
pointAt(t2,
|
|
625
|
-
return
|
|
626
|
+
pointAt(t2, out = new Point()) {
|
|
627
|
+
return out.set(this.start.x + (this.end.x - this.start.x) * t2, this.start.y + (this.end.y - this.start.y) * t2);
|
|
626
628
|
}
|
|
627
629
|
/** 膨胀为矩形
|
|
628
|
-
*
|
|
629
630
|
* @param width
|
|
630
|
-
* @
|
|
631
|
+
* @param cap butt: 不延长, square: 延长
|
|
632
|
+
* @returns
|
|
631
633
|
*/
|
|
632
|
-
toRectangle(width = 0.1, cap = "square") {
|
|
633
|
-
const p1 = this.start
|
|
634
|
+
toRectangle(width = 0.1, cap = "square", out = new Rectangle()) {
|
|
635
|
+
const p1 = this.start;
|
|
636
|
+
const p2 = this.end;
|
|
637
|
+
const halfWidth = width * 0.5;
|
|
634
638
|
const normal = p2.leftNormal(p1);
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
639
|
+
let extendX = 0;
|
|
640
|
+
let extendY = 0;
|
|
641
|
+
if (cap === "square") {
|
|
642
|
+
const dir = p2.directionFrom(p1);
|
|
643
|
+
extendX = dir.x * halfWidth;
|
|
644
|
+
extendY = dir.y * halfWidth;
|
|
645
|
+
}
|
|
646
|
+
const offsetX = normal.x * halfWidth;
|
|
647
|
+
const offsetY = normal.y * halfWidth;
|
|
648
|
+
out.p0.set(
|
|
649
|
+
p1.x + offsetX - extendX,
|
|
650
|
+
p1.y + offsetY - extendY
|
|
651
|
+
);
|
|
652
|
+
out.p1.set(
|
|
653
|
+
p2.x + offsetX + extendX,
|
|
654
|
+
p2.y + offsetY + extendY
|
|
655
|
+
);
|
|
656
|
+
out.p2.set(
|
|
657
|
+
p2.x - offsetX + extendX,
|
|
658
|
+
p2.y - offsetY + extendY
|
|
659
|
+
);
|
|
660
|
+
out.p3.set(
|
|
661
|
+
p1.x - offsetX - extendX,
|
|
662
|
+
p1.y - offsetY - extendY
|
|
663
|
+
);
|
|
664
|
+
return out;
|
|
648
665
|
}
|
|
649
666
|
/** 获取点在当前线段的左边还是右边,或者线段上
|
|
650
667
|
* @param point
|
|
@@ -947,7 +964,7 @@ class LineSegment {
|
|
|
947
964
|
containsPoint(pt2) {
|
|
948
965
|
const d1 = pt2.distance(this.start);
|
|
949
966
|
const d2 = pt2.distance(this.end);
|
|
950
|
-
const len = this.length
|
|
967
|
+
const len = this.length;
|
|
951
968
|
return Math.abs(d1 + d2 - len) < 1e-10;
|
|
952
969
|
}
|
|
953
970
|
/**
|
|
@@ -1003,6 +1020,19 @@ class LineSegment {
|
|
|
1003
1020
|
static getSegmentFromPoint(point2) {
|
|
1004
1021
|
return point2.currentData[LINE_SYMBOL] ?? null;
|
|
1005
1022
|
}
|
|
1023
|
+
static axisY(width, out = new LineSegment()) {
|
|
1024
|
+
const helf = width * 0.5;
|
|
1025
|
+
return out.set([0, -helf], [0, helf]);
|
|
1026
|
+
}
|
|
1027
|
+
static axisX(width, out = new LineSegment()) {
|
|
1028
|
+
const helf = width * 0.5;
|
|
1029
|
+
return out.set([-helf, 0], [helf, 0]);
|
|
1030
|
+
}
|
|
1031
|
+
static angleToYAxis(line) {
|
|
1032
|
+
const dx = line.end.x - line.start.x;
|
|
1033
|
+
const dy = line.end.y - line.start.y;
|
|
1034
|
+
return Math.atan2(dx, dy);
|
|
1035
|
+
}
|
|
1006
1036
|
}
|
|
1007
1037
|
const POW10 = [
|
|
1008
1038
|
1,
|
|
@@ -1268,14 +1298,14 @@ class Point {
|
|
|
1268
1298
|
* @param point
|
|
1269
1299
|
* @returns
|
|
1270
1300
|
*/
|
|
1271
|
-
leftNormal(point2) {
|
|
1301
|
+
leftNormal(point2, out = new Point()) {
|
|
1272
1302
|
const dx = this.x - point2.x;
|
|
1273
1303
|
const dy = this.y - point2.y;
|
|
1274
1304
|
const length = Math.sqrt(dx * dx + dy * dy);
|
|
1275
1305
|
if (length === 0) return Point.zero();
|
|
1276
1306
|
const nx = -dy / length;
|
|
1277
1307
|
const ny = dx / length;
|
|
1278
|
-
return
|
|
1308
|
+
return out.set(nx, ny);
|
|
1279
1309
|
}
|
|
1280
1310
|
/**
|
|
1281
1311
|
* 获取由传入的点到该点的单位方向向量
|
|
@@ -1419,8 +1449,13 @@ class Point {
|
|
|
1419
1449
|
* @returns
|
|
1420
1450
|
*/
|
|
1421
1451
|
copy(p2) {
|
|
1422
|
-
|
|
1423
|
-
|
|
1452
|
+
if (p2 && "x" in p2 && "y" in p2) {
|
|
1453
|
+
this.x = Number(p2.x);
|
|
1454
|
+
this.y = Number(p2.y);
|
|
1455
|
+
} else if (Array.isArray(p2)) {
|
|
1456
|
+
this.x = Number(p2[0]);
|
|
1457
|
+
this.y = Number(p2[1]);
|
|
1458
|
+
}
|
|
1424
1459
|
return this;
|
|
1425
1460
|
}
|
|
1426
1461
|
/** 转为数组
|
|
@@ -2353,7 +2388,7 @@ class Quadtree {
|
|
|
2353
2388
|
result.push(...child.queryCircle(pos, radius));
|
|
2354
2389
|
}
|
|
2355
2390
|
}
|
|
2356
|
-
result.sort((l) => l.line.length
|
|
2391
|
+
result.sort((l) => l.line.length);
|
|
2357
2392
|
return result;
|
|
2358
2393
|
}
|
|
2359
2394
|
/**
|
|
@@ -2578,7 +2613,7 @@ class WallInsertObject {
|
|
|
2578
2613
|
const center = Point.from(insertObject.p);
|
|
2579
2614
|
const direct = line.direction();
|
|
2580
2615
|
let width = insertObject.width;
|
|
2581
|
-
if (insertObject.full) width = line.length
|
|
2616
|
+
if (insertObject.full) width = line.length;
|
|
2582
2617
|
return center.expandAsLine(direct, width).translate(-width * 0.5, direct);
|
|
2583
2618
|
}
|
|
2584
2619
|
/** 获取组
|
|
@@ -2676,19 +2711,19 @@ class WallInsertObject {
|
|
|
2676
2711
|
try {
|
|
2677
2712
|
const center = Point.from(w.p);
|
|
2678
2713
|
const windowLine = line.projectLineSegment(wallInsertObjectToLine(line, w));
|
|
2679
|
-
if (windowLine.
|
|
2714
|
+
if (windowLine.length / w.width < 0.4 && !windowLine.containsPoint(center)) {
|
|
2680
2715
|
w.width = 0;
|
|
2681
2716
|
return;
|
|
2682
2717
|
}
|
|
2683
2718
|
if (w.full) {
|
|
2684
2719
|
const center2 = line.center;
|
|
2685
2720
|
w.p = { x: center2?.x ?? 0, y: center2?.y ?? 0, z: w.p.z };
|
|
2686
|
-
w.width = line.length
|
|
2721
|
+
w.width = line.length;
|
|
2687
2722
|
return;
|
|
2688
2723
|
}
|
|
2689
2724
|
let windowCenter = windowLine.center;
|
|
2690
2725
|
w.p = { x: windowCenter.x ?? 0, y: windowCenter.y ?? 0, z: w.p.z };
|
|
2691
|
-
w.width = windowLine.length
|
|
2726
|
+
w.width = windowLine.length;
|
|
2692
2727
|
} catch (error) {
|
|
2693
2728
|
}
|
|
2694
2729
|
});
|
|
@@ -2778,7 +2813,7 @@ class WallInsertObject {
|
|
|
2778
2813
|
line2.currentData.wds.forEach(({ width, p: p2, ...opt1 }) => Object.assign(opt, opt1));
|
|
2779
2814
|
return {
|
|
2780
2815
|
...opt,
|
|
2781
|
-
width: line2.length
|
|
2816
|
+
width: line2.length,
|
|
2782
2817
|
p: line2.center.toJson(line2.currentData.wds[0].p.z)
|
|
2783
2818
|
};
|
|
2784
2819
|
});
|
|
@@ -2806,6 +2841,22 @@ class WallInsertObject {
|
|
|
2806
2841
|
addInsertObject(target, insertObject, type = "passageEntrance") {
|
|
2807
2842
|
return WallInsertObject.addInsertObject(target, insertObject, type);
|
|
2808
2843
|
}
|
|
2844
|
+
/** 移除孔洞
|
|
2845
|
+
* @param target
|
|
2846
|
+
* @param insertObject
|
|
2847
|
+
*/
|
|
2848
|
+
static removeInsertObject(target, insertObject) {
|
|
2849
|
+
this.forEachInsertObjectData(target, (data, key) => {
|
|
2850
|
+
let index2 = data.indexOf(insertObject);
|
|
2851
|
+
if (index2 > -1) {
|
|
2852
|
+
data.splice(index2, 1);
|
|
2853
|
+
}
|
|
2854
|
+
if (target.userData[key]?.length === 0) WallInsertObject.clear(target, key);
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2857
|
+
removeInsertObject(target, insertObject) {
|
|
2858
|
+
return WallInsertObject.removeInsertObject(target, insertObject);
|
|
2859
|
+
}
|
|
2809
2860
|
/** 复制所有孔洞
|
|
2810
2861
|
* @param target
|
|
2811
2862
|
* @param source
|
|
@@ -3094,7 +3145,7 @@ function findDiscretePoint2(lines) {
|
|
|
3094
3145
|
const pointMap = new MapEnhance();
|
|
3095
3146
|
const pvg = createPointSpatialHash(lines);
|
|
3096
3147
|
lines.forEach((line) => {
|
|
3097
|
-
const qr2 = Math.min(1e-3, line.length
|
|
3148
|
+
const qr2 = Math.min(1e-3, line.length * 9e-3);
|
|
3098
3149
|
line.points.forEach((p2) => {
|
|
3099
3150
|
let list = pvg.queryCircle(p2, qr2, true).filter((item) => item.userData !== line);
|
|
3100
3151
|
if (list.length !== 0) return;
|
|
@@ -3240,7 +3291,7 @@ class LineSegmentUtils {
|
|
|
3240
3291
|
let maxLength = -Infinity, maxIndex = -1;
|
|
3241
3292
|
for (let i = 0; i < lines.length; i++) {
|
|
3242
3293
|
if (excludeCallBack && excludeCallBack(lines[i])) continue;
|
|
3243
|
-
const length = lines[i].length
|
|
3294
|
+
const length = lines[i].length;
|
|
3244
3295
|
if (length > maxLength) {
|
|
3245
3296
|
maxLength = length;
|
|
3246
3297
|
maxIndex = i;
|
|
@@ -3256,7 +3307,7 @@ class LineSegmentUtils {
|
|
|
3256
3307
|
let x = 0;
|
|
3257
3308
|
let y = 0;
|
|
3258
3309
|
for (const line of lines) {
|
|
3259
|
-
const len = line.length
|
|
3310
|
+
const len = line.length;
|
|
3260
3311
|
const center = line.center;
|
|
3261
3312
|
x += center.x * len;
|
|
3262
3313
|
y += center.y * len;
|
|
@@ -3459,7 +3510,7 @@ class LineSegmentUtils {
|
|
|
3459
3510
|
*/
|
|
3460
3511
|
static mergeLinesByMaxlength(...lines) {
|
|
3461
3512
|
if (lines.length === 1) return lines[0];
|
|
3462
|
-
const list = lines.slice(0).sort((a2, b4) => b4.length
|
|
3513
|
+
const list = lines.slice(0).sort((a2, b4) => b4.length - a2.length);
|
|
3463
3514
|
const baseLine = list[0];
|
|
3464
3515
|
const principal = baseLine.direction().normalize();
|
|
3465
3516
|
let newStart = baseLine.start.clone();
|
|
@@ -3491,7 +3542,7 @@ class LineSegmentUtils {
|
|
|
3491
3542
|
static mergeCollinearSegments(lines) {
|
|
3492
3543
|
if (lines.length === 1) return lines[0];
|
|
3493
3544
|
let mainLine = lines[0];
|
|
3494
|
-
for (const l of lines) if (l.length
|
|
3545
|
+
for (const l of lines) if (l.length > mainLine.length) mainLine = l;
|
|
3495
3546
|
let maxPValue = -Infinity, minPValue = Infinity;
|
|
3496
3547
|
let maxPoint = null;
|
|
3497
3548
|
let minPoint = null;
|
|
@@ -3677,7 +3728,7 @@ class LineSegmentUtils {
|
|
|
3677
3728
|
for (const [s, e] of merged) {
|
|
3678
3729
|
if (s > prev + eps) {
|
|
3679
3730
|
const newLine = new LineSegment(target.pointAt(prev), target.pointAt(s));
|
|
3680
|
-
if (newLine.length
|
|
3731
|
+
if (newLine.length > 1e-4) {
|
|
3681
3732
|
newLines.push(newLine);
|
|
3682
3733
|
callBack?.(newLine, target);
|
|
3683
3734
|
}
|
|
@@ -3686,7 +3737,7 @@ class LineSegmentUtils {
|
|
|
3686
3737
|
}
|
|
3687
3738
|
if (prev < 1 - eps) {
|
|
3688
3739
|
const newLine = new LineSegment(target.pointAt(prev), target.pointAt(1));
|
|
3689
|
-
if (newLine.length
|
|
3740
|
+
if (newLine.length > 1e-4) {
|
|
3690
3741
|
newLines.push(newLine);
|
|
3691
3742
|
callBack?.(newLine, target);
|
|
3692
3743
|
}
|
|
@@ -3706,8 +3757,8 @@ class LineSegmentUtils {
|
|
|
3706
3757
|
* @returns
|
|
3707
3758
|
*/
|
|
3708
3759
|
static constrainLine(line, base) {
|
|
3709
|
-
const center = line.center, width = line.length
|
|
3710
|
-
if (base.length
|
|
3760
|
+
const center = line.center, width = line.length;
|
|
3761
|
+
if (base.length < width) {
|
|
3711
3762
|
line.start.copy(base.start);
|
|
3712
3763
|
line.end.copy(base.end);
|
|
3713
3764
|
return line;
|
|
@@ -3741,7 +3792,7 @@ class LineSegmentUtils {
|
|
|
3741
3792
|
const quadtree = Quadtree.from(lines), queryLine = new LineSegment(), arrayMap = new ArrayMap();
|
|
3742
3793
|
for (let i = 0; i < lines.length; i++) {
|
|
3743
3794
|
const line = lines[i];
|
|
3744
|
-
queryLine.copy(line).setLength(line.
|
|
3795
|
+
queryLine.copy(line).setLength(line.length + 0.04);
|
|
3745
3796
|
quadtree.queryLineSegment(queryLine).forEach((res) => {
|
|
3746
3797
|
if (res.line === line) return;
|
|
3747
3798
|
if (line.isSameEndpoint(res.line, 1e-4)) return;
|
|
@@ -3773,7 +3824,7 @@ class LineSegmentUtils {
|
|
|
3773
3824
|
new Point(0, 0),
|
|
3774
3825
|
new Point(0, 1)
|
|
3775
3826
|
);
|
|
3776
|
-
const lines = [...lineSegments].sort((a2, b4) => b4.length
|
|
3827
|
+
const lines = [...lineSegments].sort((a2, b4) => b4.length - a2.length).slice(0, 20);
|
|
3777
3828
|
const angles = lines.map((line2) => {
|
|
3778
3829
|
let angle = yAxisLine.angle(line2, { unit: "degree", range: "180" });
|
|
3779
3830
|
if (angle > 90) angle = 180 - angle;
|
|
@@ -3785,7 +3836,7 @@ class LineSegmentUtils {
|
|
|
3785
3836
|
if (!lineMap.has(angle)) lineMap.set(angle, []);
|
|
3786
3837
|
lineMap.get(angle)?.push(lines[index2]);
|
|
3787
3838
|
});
|
|
3788
|
-
const line = [...lineMap.values()].sort((a2, b4) => b4.length - a2.length)[0]?.sort((a2, b4) => b4.length
|
|
3839
|
+
const line = [...lineMap.values()].sort((a2, b4) => b4.length - a2.length)[0]?.sort((a2, b4) => b4.length - a2.length)[0];
|
|
3789
3840
|
return line ?? new LineSegment();
|
|
3790
3841
|
}
|
|
3791
3842
|
/** 创建线段修改管理器
|
|
@@ -3828,7 +3879,7 @@ class LineSegmentUtils {
|
|
|
3828
3879
|
*/
|
|
3829
3880
|
static dash(line, pattern) {
|
|
3830
3881
|
const result = [];
|
|
3831
|
-
const length = line.length
|
|
3882
|
+
const length = line.length;
|
|
3832
3883
|
if (length <= 0 || pattern.length === 0) {
|
|
3833
3884
|
return result;
|
|
3834
3885
|
}
|
|
@@ -5996,7 +6047,7 @@ class Polygon extends Array {
|
|
|
5996
6047
|
const p2 = this[i].clone(), nextP = this[(i + 1) % this.length].clone();
|
|
5997
6048
|
lines.push(new LineSegment(p2, nextP));
|
|
5998
6049
|
}
|
|
5999
|
-
return lines.filter((line) => line.length
|
|
6050
|
+
return lines.filter((line) => line.length > 1e-9);
|
|
6000
6051
|
}
|
|
6001
6052
|
toArrays() {
|
|
6002
6053
|
return this.map((p2) => p2.toArray());
|
|
@@ -6163,21 +6214,21 @@ function lineSegmentClipping(lines, minLen = 1e-9, dedup = true) {
|
|
|
6163
6214
|
lines = LineSegmentUtils.splitIntersections(lines, (line, newLines) => {
|
|
6164
6215
|
newLines.map((newLine) => migration(newLine, line));
|
|
6165
6216
|
if (line.userData.isBayWindow) {
|
|
6166
|
-
newLines.sort((a2, b4) => b4.length
|
|
6217
|
+
newLines.sort((a2, b4) => b4.length - a2.length);
|
|
6167
6218
|
for (let i = 1; i < newLines.length; i++) {
|
|
6168
6219
|
newLines[i].userData.isBayWindow = false;
|
|
6169
6220
|
}
|
|
6170
6221
|
}
|
|
6171
6222
|
if (line.userData.isBalconyRailing) {
|
|
6172
|
-
const len = line.length
|
|
6223
|
+
const len = line.length;
|
|
6173
6224
|
newLines.forEach((line2) => {
|
|
6174
|
-
if (line2.length
|
|
6225
|
+
if (line2.length / len < 0.2) {
|
|
6175
6226
|
delete line2.userData.isBalconyRailing;
|
|
6176
6227
|
}
|
|
6177
6228
|
});
|
|
6178
6229
|
}
|
|
6179
6230
|
});
|
|
6180
|
-
lines = lines.filter((line) => line.length
|
|
6231
|
+
lines = lines.filter((line) => line.length >= minLen);
|
|
6181
6232
|
return dedup ? LineSegmentUtils.deduplication(lines) : lines;
|
|
6182
6233
|
}
|
|
6183
6234
|
class LineIndexGenerator {
|
|
@@ -6648,7 +6699,7 @@ class MiniCircles {
|
|
|
6648
6699
|
}
|
|
6649
6700
|
function mergeLineUserData(newLine, line2) {
|
|
6650
6701
|
if (Array.isArray(line2)) {
|
|
6651
|
-
line2 = [...line2].sort((a2, b4) => a2.length
|
|
6702
|
+
line2 = [...line2].sort((a2, b4) => a2.length - b4.length);
|
|
6652
6703
|
return line2.forEach((l) => mergeLineUserData(newLine, l));
|
|
6653
6704
|
}
|
|
6654
6705
|
if (line2.userData.isBayWindow === false) delete line2.userData.isBayWindow;
|
|
@@ -6683,7 +6734,7 @@ function mergeChains(lines, callBack, removeLines, newLines) {
|
|
|
6683
6734
|
function getDividingLine(lines) {
|
|
6684
6735
|
const maxLine = lines.reduce((maxLine2, line) => {
|
|
6685
6736
|
if (!maxLine2) return line;
|
|
6686
|
-
if (line.length
|
|
6737
|
+
if (line.length > maxLine2.length) return line;
|
|
6687
6738
|
return maxLine2;
|
|
6688
6739
|
});
|
|
6689
6740
|
const normal = maxLine.normal(), size2 = 0.1, axisLine = maxLine.center.expandAsLine(normal, size2).translate(size2 * 0.5, normal.multiplyScalar(-1)), axisValue = axisLine.projectPointValue(maxLine.start);
|
|
@@ -6788,16 +6839,16 @@ function clippingInsertObjectDoubleWall(lines) {
|
|
|
6788
6839
|
if (!poly.pointWithin(center.add(normal.clone().multiplyScalar(1e-6)))) normal.multiplyScalar(-1);
|
|
6789
6840
|
WallInsertObject.forEachInsertObjectData(line, (data) => data.forEach((d2) => {
|
|
6790
6841
|
const wioLine = wallInsertObjectToLine(line, d2);
|
|
6791
|
-
wioLine.setLength(wioLine.
|
|
6792
|
-
const len = wioLine.length
|
|
6842
|
+
wioLine.setLength(wioLine.length - 4e-3);
|
|
6843
|
+
const len = wioLine.length;
|
|
6793
6844
|
let startResults = quadtree.raycaster(wioLine.start, normal, 1e-4, far).filter((item) => item.targetLine.isParallelTo(wioLine));
|
|
6794
6845
|
let endResults = quadtree.raycaster(wioLine.end, normal, 1e-4, far).filter((item) => item.targetLine.isParallelTo(wioLine));
|
|
6795
|
-
if (startResults.length > 1) startResults = startResults.filter((item) => item.targetLine.projectLineSegment(wioLine).length
|
|
6796
|
-
if (endResults.length > 1) endResults = endResults.filter((item) => item.targetLine.projectLineSegment(wioLine).length
|
|
6846
|
+
if (startResults.length > 1) startResults = startResults.filter((item) => item.targetLine.projectLineSegment(wioLine).length / len > 0.01);
|
|
6847
|
+
if (endResults.length > 1) endResults = endResults.filter((item) => item.targetLine.projectLineSegment(wioLine).length / len > 0.01);
|
|
6797
6848
|
if (startResults.length === 0 || endResults.length === 0) return;
|
|
6798
6849
|
const startResult = startResults[0], endResult = endResults[0];
|
|
6799
6850
|
if (startResult.targetLine !== endResult.targetLine) {
|
|
6800
|
-
const pl1 = startResult.targetLine.projectLineSegment(wioLine), pl2 = endResult.targetLine.projectLineSegment(wioLine), finalPl = pl1.length
|
|
6851
|
+
const pl1 = startResult.targetLine.projectLineSegment(wioLine), pl2 = endResult.targetLine.projectLineSegment(wioLine), finalPl = pl1.length > pl2.length ? pl1 : pl2;
|
|
6801
6852
|
polygons.push(new Polygon([
|
|
6802
6853
|
wioLine.projectPoint(finalPl.start, false),
|
|
6803
6854
|
finalPl.start,
|
|
@@ -6816,7 +6867,7 @@ function clippingInsertObjectDoubleWall(lines) {
|
|
|
6816
6867
|
lines.push(...newLines);
|
|
6817
6868
|
PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
|
|
6818
6869
|
lines = lineSegmentClipping(lines.map((line) => line.clone()), 1e-9);
|
|
6819
|
-
lines = mergeChains(lines).filter((line) => line.length
|
|
6870
|
+
lines = mergeChains(lines).filter((line) => line.length > 0);
|
|
6820
6871
|
PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
|
|
6821
6872
|
WallInsertObject.recomputed(lines);
|
|
6822
6873
|
const { circles } = miniCircles.miniCircle(lines);
|
|
@@ -7237,7 +7288,7 @@ class WallInsertObjectDrawData {
|
|
|
7237
7288
|
WallInsertObject.forEachInsertObjectData(line, (data, k) => {
|
|
7238
7289
|
const list = grid && doubleWallPoint$1(grid, line), dwh = defaultWallWidth$1 * 0.5;
|
|
7239
7290
|
data.map(({ full, width, p: p2, height, groundClearance, uuid: uuid2, type }) => {
|
|
7240
|
-
if (full) width = line.length
|
|
7291
|
+
if (full) width = line.length;
|
|
7241
7292
|
const point2 = Point.from(p2), direct = line.direction(), insertObjectLine = point2.expandAsLine(direct, width).translate(-width * 0.5, direct);
|
|
7242
7293
|
insertObjectLine.userData = {
|
|
7243
7294
|
wallWidth: defaultWallWidth$1,
|
|
@@ -7265,7 +7316,7 @@ class WallInsertObjectDrawData {
|
|
|
7265
7316
|
newLines.push(insertObjectLine);
|
|
7266
7317
|
});
|
|
7267
7318
|
});
|
|
7268
|
-
newLines.filter((line2) => line2.length
|
|
7319
|
+
newLines.filter((line2) => line2.length > defaultWallWidth$1);
|
|
7269
7320
|
return newLines;
|
|
7270
7321
|
}
|
|
7271
7322
|
return null;
|
|
@@ -7279,8 +7330,8 @@ class WallInsertObjectDrawData {
|
|
|
7279
7330
|
*/
|
|
7280
7331
|
static doubleDrawLine(lines) {
|
|
7281
7332
|
if (lines.length < 3) return [];
|
|
7282
|
-
lines = [...lines].sort((a2, b4) => a2.length
|
|
7283
|
-
const line1 = lines[0], line2 = lines[1], wallWidth = Math.min(line1.length
|
|
7333
|
+
lines = [...lines].sort((a2, b4) => a2.length - b4.length);
|
|
7334
|
+
const line1 = lines[0], line2 = lines[1], wallWidth = Math.min(line1.length, line2.length);
|
|
7284
7335
|
let wallHeight = 0;
|
|
7285
7336
|
lines.forEach((line) => wallHeight = Math.max(wallHeight, line.userData.height ?? 0));
|
|
7286
7337
|
const newLine = new LineSegment(line1.center.clone(), line2.center.clone());
|
|
@@ -7290,7 +7341,7 @@ class WallInsertObjectDrawData {
|
|
|
7290
7341
|
WallInsertObject.forEachInsertObjectData(newLine, (data, key) => {
|
|
7291
7342
|
data.forEach(({ full, width, p: p2, height, groundClearance, type }) => {
|
|
7292
7343
|
const point2 = Point.from(p2), direct = newLine.direction();
|
|
7293
|
-
if (full) width = newLine.length
|
|
7344
|
+
if (full) width = newLine.length;
|
|
7294
7345
|
const insertObjectLine = point2.expandAsLine(direct, width).translate(-width * 0.5, direct);
|
|
7295
7346
|
try {
|
|
7296
7347
|
insertObjectLine.start.copy(newLine.projectPoint(insertObjectLine.start, false));
|
|
@@ -7307,7 +7358,7 @@ class WallInsertObjectDrawData {
|
|
|
7307
7358
|
newLines.push(insertObjectLine);
|
|
7308
7359
|
});
|
|
7309
7360
|
});
|
|
7310
|
-
return newLines.filter((line) => line.length
|
|
7361
|
+
return newLines.filter((line) => line.length > defaultWallWidth$1);
|
|
7311
7362
|
}
|
|
7312
7363
|
doubleDrawLine(lines) {
|
|
7313
7364
|
return WallInsertObjectDrawData.doubleDrawLine(lines);
|
|
@@ -7448,7 +7499,7 @@ class BayWindowHelper {
|
|
|
7448
7499
|
height1: bayWindowLine.userData.topClearance ?? 0,
|
|
7449
7500
|
height2: height,
|
|
7450
7501
|
height3: groundClearance,
|
|
7451
|
-
depth: deptLine.length
|
|
7502
|
+
depth: deptLine.length,
|
|
7452
7503
|
windowWidth: width,
|
|
7453
7504
|
windowHeight: height,
|
|
7454
7505
|
bayWindowLine,
|
|
@@ -7504,7 +7555,7 @@ class BayWindowHelper {
|
|
|
7504
7555
|
* @returns
|
|
7505
7556
|
*/
|
|
7506
7557
|
static drawDataToModel(drawData) {
|
|
7507
|
-
const pos = drawData.bayWindowLine.center, dirct = drawData.bayWindowLine.direction(), length = drawData.bayWindowLine.length
|
|
7558
|
+
const pos = drawData.bayWindowLine.center, dirct = drawData.bayWindowLine.direction(), length = drawData.bayWindowLine.length, bayWindowLine = Point.zero().expandAsLine(dirct, length).translate(length * 0.5, dirct.multiplyScalar(-1)), winGroup = new THREE.Group(), material = new THREE.MeshBasicMaterial({ color: 16777215 });
|
|
7508
7559
|
winGroup.position.set(pos.x, pos.y, 0);
|
|
7509
7560
|
const rectangle = bayWindowLine.toRectangle(DEFAULT_WALL_WIDTH), extrudeMesh = new ExtrudeMesh(rectangle.points, { depth: drawData.height3 }, material);
|
|
7510
7561
|
winGroup.add(extrudeMesh);
|
|
@@ -9598,7 +9649,9 @@ function buildBayWindowGroup(lines, clear = true) {
|
|
|
9598
9649
|
LineGroupType.set(line, id, "bayWindow", true);
|
|
9599
9650
|
groupedLineSet.add(line);
|
|
9600
9651
|
});
|
|
9601
|
-
} else
|
|
9652
|
+
} else if (clear) {
|
|
9653
|
+
LineGroupType.clear(bayWindowLine);
|
|
9654
|
+
}
|
|
9602
9655
|
});
|
|
9603
9656
|
lines = lines.filter((line) => !removeSet.has(line));
|
|
9604
9657
|
clear && lines.forEach((line) => groupedLineSet.has(line) || LineGroupType.clear(line));
|
|
@@ -9662,7 +9715,7 @@ function getPeDoubleDoorCircles(lines, peDoubleDoorLines) {
|
|
|
9662
9715
|
}
|
|
9663
9716
|
function buildDoubleWallGroup_(lines_, clearInternalLine = false) {
|
|
9664
9717
|
PointUtils.adsorb(lines_.flatMap((line) => line.points), 5e-4);
|
|
9665
|
-
lines_ = lines_.filter((line) => line.length
|
|
9718
|
+
lines_ = lines_.filter((line) => line.length > 1e-7);
|
|
9666
9719
|
const {
|
|
9667
9720
|
doorLines,
|
|
9668
9721
|
otherLines,
|
|
@@ -9769,12 +9822,12 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9769
9822
|
}
|
|
9770
9823
|
let newLine = null;
|
|
9771
9824
|
let wallWidth = 0;
|
|
9772
|
-
lines2 = [...lines2].sort((a2, b4) => a2.length
|
|
9825
|
+
lines2 = [...lines2].sort((a2, b4) => a2.length - b4.length);
|
|
9773
9826
|
const line1 = lines2[0], line2 = lines2[1];
|
|
9774
9827
|
newLine = new LineSegment(line1.center.clone(), line2.center.clone());
|
|
9775
|
-
wallWidth = line1.length
|
|
9828
|
+
wallWidth = line1.length;
|
|
9776
9829
|
mergeLineUserData(newLine, lines2);
|
|
9777
|
-
newLine.setLength(newLine.
|
|
9830
|
+
newLine.setLength(newLine.length + 2e-3);
|
|
9778
9831
|
newLine.userData.wallWidth = wallWidth + 1e-3;
|
|
9779
9832
|
return [newLine];
|
|
9780
9833
|
});
|
|
@@ -9868,7 +9921,7 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9868
9921
|
*/
|
|
9869
9922
|
wallHoleHandle({ data: { lines, json } }) {
|
|
9870
9923
|
lines.forEach((line) => {
|
|
9871
|
-
if (line.length
|
|
9924
|
+
if (line.length < 1e-4) return;
|
|
9872
9925
|
let type = holeTypeMap[line.userData.type] ?? "WALL_HOLE";
|
|
9873
9926
|
const hole = {
|
|
9874
9927
|
id: this.index++,
|
|
@@ -9953,7 +10006,7 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9953
10006
|
if (!Array.isArray(json.placeHolders)) json.placeHolders = [];
|
|
9954
10007
|
const rooms = json.rooms, roomPloys = rooms.map((room) => new Polygon(room.polygon.map((p2) => Point.from(p2))));
|
|
9955
10008
|
if (roomPloys.length === 0) return json;
|
|
9956
|
-
publicInfo
|
|
10009
|
+
publicInfo?.itemInfo?.forEach((item, i) => {
|
|
9957
10010
|
if (!placeHoldersMap[item.category]) return;
|
|
9958
10011
|
const contour = item.quadContour ?? item.contour;
|
|
9959
10012
|
if (contour.length === 0) {
|
|
@@ -10087,7 +10140,7 @@ function toOriginalDataItem(line, originalZAverage = 0, quadtree, lines) {
|
|
|
10087
10140
|
start: line.start.toJson(originalZAverage),
|
|
10088
10141
|
end: line.end.toJson(originalZAverage),
|
|
10089
10142
|
insetionArr,
|
|
10090
|
-
length: line.length
|
|
10143
|
+
length: line.length,
|
|
10091
10144
|
uuid: line.uuid,
|
|
10092
10145
|
drawWindow: drawWindow && drawWindow.map((w) => {
|
|
10093
10146
|
const opt2 = cloneUserData(w);
|
|
@@ -10110,7 +10163,7 @@ function wallInsertObjectToLine(line, insertObject) {
|
|
|
10110
10163
|
const center = Point.from(insertObject.p);
|
|
10111
10164
|
const direct = line.direction();
|
|
10112
10165
|
let width = insertObject.width;
|
|
10113
|
-
if (insertObject.full) width = line.length
|
|
10166
|
+
if (insertObject.full) width = line.length;
|
|
10114
10167
|
return center.expandAsLine(direct, width).translate(-width * 0.5, direct);
|
|
10115
10168
|
}
|
|
10116
10169
|
const tools = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -10213,7 +10266,7 @@ function toDrawData(unit = "Centimeters") {
|
|
|
10213
10266
|
const line = new LineSegment();
|
|
10214
10267
|
function drawRulerLine(p1, p2) {
|
|
10215
10268
|
line.set(p1, p2);
|
|
10216
|
-
const length = line.length
|
|
10269
|
+
const length = line.length;
|
|
10217
10270
|
const angle = line.direction().angle(new Point(0, 1), { unit: "degree", range: "180" });
|
|
10218
10271
|
const p1C = p1.clone();
|
|
10219
10272
|
const p2C = p2.clone();
|
|
@@ -10462,14 +10515,14 @@ class CAD {
|
|
|
10462
10515
|
}), quadtree = createQuadtree(lines), temLine = new LineSegment(), visited = /* @__PURE__ */ new Set();
|
|
10463
10516
|
for (let i = 0; i < lines.length; i++) {
|
|
10464
10517
|
const line = lines[i];
|
|
10465
|
-
const len = line.length
|
|
10518
|
+
const len = line.length;
|
|
10466
10519
|
temLine.copy(line);
|
|
10467
10520
|
const rectangle = temLine.extendAlongDirection(len * 0.01).toRectangle(threshold * 2, "butt");
|
|
10468
10521
|
const results = quadtree.queryRect(rectangle).filter(
|
|
10469
10522
|
(result) => result.line !== line && !visited.has(result.line) && result.line.isParallelTo(line)
|
|
10470
|
-
).sort((a2, b4) => b4.line.length
|
|
10523
|
+
).sort((a2, b4) => b4.line.length - a2.line.length);
|
|
10471
10524
|
if (results.length) {
|
|
10472
|
-
const resultLine = results[0].line, pl1 = resultLine.projectLineSegment(line), pl2 = line.projectLineSegment(resultLine), pLine = pl1.length
|
|
10525
|
+
const resultLine = results[0].line, pl1 = resultLine.projectLineSegment(line), pl2 = line.projectLineSegment(resultLine), pLine = pl1.length > pl2.length ? pl1 : pl2;
|
|
10473
10526
|
polys.push(new Polygon(pLine.toRectangle(threshold * 2, "butt").points));
|
|
10474
10527
|
}
|
|
10475
10528
|
visited.add(line);
|
|
@@ -10732,7 +10785,7 @@ class AxisAlignCorr {
|
|
|
10732
10785
|
if (line.isParallelTo(nextLine)) {
|
|
10733
10786
|
const interPoint2 = nextLine.projectPoint(point2, false);
|
|
10734
10787
|
const newLine = new LineSegment(point2.clone(), interPoint2?.clone() ?? nextPoint.clone());
|
|
10735
|
-
newLine.length
|
|
10788
|
+
newLine.length > 1e-9 && this.newLines.push(newLine);
|
|
10736
10789
|
return;
|
|
10737
10790
|
}
|
|
10738
10791
|
const interPoint = nextLine.projectPoint(point2, false);
|
|
@@ -10826,7 +10879,7 @@ function removeDangline(lines, len = 0.01, consecutive = false) {
|
|
|
10826
10879
|
});
|
|
10827
10880
|
function find(lines2) {
|
|
10828
10881
|
removeLineSet.clear();
|
|
10829
|
-
const shortLine = lines2.filter((line) => line.length
|
|
10882
|
+
const shortLine = lines2.filter((line) => line.length <= len);
|
|
10830
10883
|
for (let i = 0; i < shortLine.length; i++) {
|
|
10831
10884
|
const line = shortLine[i];
|
|
10832
10885
|
const is2 = line.points.some((p2) => grid.queryCircle(p2, 1e-4).filter((item) => item.userData !== line).length === 0);
|
|
@@ -10842,7 +10895,7 @@ function removeDangline(lines, len = 0.01, consecutive = false) {
|
|
|
10842
10895
|
if (!consecutive) break;
|
|
10843
10896
|
}
|
|
10844
10897
|
defaultLines = mergeChains(defaultLines, (newLine, lines2) => {
|
|
10845
|
-
lines2 = lines2.filter((line) => line.length
|
|
10898
|
+
lines2 = lines2.filter((line) => line.length > 0);
|
|
10846
10899
|
mergeLineUserData(newLine, lines2);
|
|
10847
10900
|
newLine.userData.isBayWindow = lines2.some((line) => line.userData.isBayWindow);
|
|
10848
10901
|
});
|
|
@@ -10930,8 +10983,8 @@ class AlignToParallelSegments {
|
|
|
10930
10983
|
* @param gap 平行轴投影区间间隙
|
|
10931
10984
|
*/
|
|
10932
10985
|
static group(lines, parallelAxis, verticalAxis, esp = 0.05, gap = 0.01, onGroup) {
|
|
10933
|
-
esp = esp / verticalAxis.
|
|
10934
|
-
gap = gap / parallelAxis.
|
|
10986
|
+
esp = esp / verticalAxis.length;
|
|
10987
|
+
gap = gap / parallelAxis.length;
|
|
10935
10988
|
const vls = lines.map((line) => [
|
|
10936
10989
|
verticalAxis.projectPointValue(line.start),
|
|
10937
10990
|
line,
|
|
@@ -10986,7 +11039,7 @@ class AlignToParallelSegments {
|
|
|
10986
11039
|
layoutDesign(group, axisLine, intersectPoints, opt);
|
|
10987
11040
|
}
|
|
10988
11041
|
return groups.flat().filter((line) => {
|
|
10989
|
-
if (line.length
|
|
11042
|
+
if (line.length < 1e-9) return false;
|
|
10990
11043
|
if (line.currentData[DELETE_SYMBOL]) {
|
|
10991
11044
|
delete line.currentData[DELETE_SYMBOL];
|
|
10992
11045
|
return false;
|
|
@@ -11004,10 +11057,10 @@ class AlignToParallelSegments {
|
|
|
11004
11057
|
let [pllLines, verticalLines] = LineSegmentUtils.groupByParallelToAxis(lines, axisLine);
|
|
11005
11058
|
const groups = this.group(pllLines, axisLine, axisLineV, esp, gap, opt.onGroup);
|
|
11006
11059
|
pllLines = this.fittingAlignment(groups, verticalLines, opt);
|
|
11007
|
-
verticalLines = verticalLines.filter((line) => line.length
|
|
11060
|
+
verticalLines = verticalLines.filter((line) => line.length > 1e-6);
|
|
11008
11061
|
const groups2 = this.group(verticalLines, axisLineV, axisLine, esp, gap, opt.onGroup);
|
|
11009
11062
|
verticalLines = this.fittingAlignment(groups2, pllLines, opt);
|
|
11010
|
-
pllLines = pllLines.filter((line) => line.length
|
|
11063
|
+
pllLines = pllLines.filter((line) => line.length > 1e-6);
|
|
11011
11064
|
return [
|
|
11012
11065
|
...pllLines,
|
|
11013
11066
|
...verticalLines
|
|
@@ -11028,7 +11081,7 @@ class DoubleWallHelper {
|
|
|
11028
11081
|
let data;
|
|
11029
11082
|
let dist = sourceLineSegment.distanceToSegment(temLineSegment);
|
|
11030
11083
|
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
|
|
11031
|
-
if (p1.length
|
|
11084
|
+
if (p1.length > p2.length) {
|
|
11032
11085
|
data = {
|
|
11033
11086
|
target: temLineSegment,
|
|
11034
11087
|
targetIndex: index2,
|
|
@@ -11049,7 +11102,7 @@ class DoubleWallHelper {
|
|
|
11049
11102
|
minDistance: dist
|
|
11050
11103
|
};
|
|
11051
11104
|
}
|
|
11052
|
-
if (!data || data.project.length
|
|
11105
|
+
if (!data || data.project.length < 0.08 || data.project2.length < 0.08) return;
|
|
11053
11106
|
return data;
|
|
11054
11107
|
}
|
|
11055
11108
|
}
|
|
@@ -11155,7 +11208,7 @@ class DoubleWallHelper {
|
|
|
11155
11208
|
lines.push(...otherLines);
|
|
11156
11209
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
11157
11210
|
PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
|
|
11158
|
-
return lines.filter((line) => line.length
|
|
11211
|
+
return lines.filter((line) => line.length > 1e-9);
|
|
11159
11212
|
}
|
|
11160
11213
|
/**
|
|
11161
11214
|
* 创建分组
|
|
@@ -11197,7 +11250,7 @@ function shortDistanceLink(lines, radius = 0.1) {
|
|
|
11197
11250
|
const targetLine = list[0].userData;
|
|
11198
11251
|
visited.add(point2);
|
|
11199
11252
|
visited.add(targetPoint);
|
|
11200
|
-
const projectLine1 = line.projectLineSegment(targetLine), projectLine2 = targetLine.projectLineSegment(line), len1 = projectLine1.length
|
|
11253
|
+
const projectLine1 = line.projectLineSegment(targetLine), projectLine2 = targetLine.projectLineSegment(line), len1 = projectLine1.length, len2 = projectLine2.length;
|
|
11201
11254
|
if (len1 === 0 && len2 === 0) appendLines.push(new LineSegment(point2.clone(), list[0].point.clone()));
|
|
11202
11255
|
else appendLines.push(new LineSegment(projectLine1.center, projectLine2.center));
|
|
11203
11256
|
}
|
|
@@ -11250,7 +11303,7 @@ function adsorption(lines, option) {
|
|
|
11250
11303
|
function adsorptLine(point2, line) {
|
|
11251
11304
|
const otherPoint = line.getAnotherPoint(point2);
|
|
11252
11305
|
const direct = otherPoint.directionFrom(point2);
|
|
11253
|
-
const len = line.length
|
|
11306
|
+
const len = line.length;
|
|
11254
11307
|
const result = lineQueryer.queryNearestLine(point2, {
|
|
11255
11308
|
radius: threshold,
|
|
11256
11309
|
condition: (node, projPoint) => {
|
|
@@ -11290,36 +11343,49 @@ function breakpointMerging(lines) {
|
|
|
11290
11343
|
function removeShortDoor(lines) {
|
|
11291
11344
|
for (let i = 0; i < lines.length; i++) {
|
|
11292
11345
|
const line = lines[i];
|
|
11293
|
-
if (line.userData.isDoor && line.
|
|
11346
|
+
if (line.userData.isDoor && line.length < WallInsertObject.getMinWidth("passageEntrance", "door")) {
|
|
11294
11347
|
delete line.userData.isDoor;
|
|
11295
11348
|
}
|
|
11296
11349
|
}
|
|
11297
11350
|
return lines;
|
|
11298
11351
|
}
|
|
11352
|
+
function recoveryBayWindow(lines, points) {
|
|
11353
|
+
const quadtree = Quadtree.from(lines);
|
|
11354
|
+
lines.forEach((line) => {
|
|
11355
|
+
line.userData.isBayWindow = false;
|
|
11356
|
+
});
|
|
11357
|
+
points.forEach((p2) => {
|
|
11358
|
+
const list = quadtree.queryCircle(p2, 0.09);
|
|
11359
|
+
if (list.length) {
|
|
11360
|
+
list[0].line.userData.isBayWindow = true;
|
|
11361
|
+
}
|
|
11362
|
+
});
|
|
11363
|
+
return lines;
|
|
11364
|
+
}
|
|
11299
11365
|
function correction(lines, targettLine, option) {
|
|
11300
11366
|
lines = breakpointMerging(lines);
|
|
11301
11367
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
11302
11368
|
lines = preprocessing(lines);
|
|
11303
11369
|
lines = AxisAlignCorr.start(lines, targettLine);
|
|
11370
|
+
const bayWindow = lines.filter((line) => line.userData.isBayWindow).map((line) => line.center);
|
|
11304
11371
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
11305
|
-
lines =
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
});
|
|
11320
|
-
}).merge();
|
|
11372
|
+
lines = AlignToParallelSegments.align(lines, {
|
|
11373
|
+
onMergeLine: mergeLineUserData,
|
|
11374
|
+
onGroup(group, projValues, axis) {
|
|
11375
|
+
if (group.length <= 1) return;
|
|
11376
|
+
const max = Math.max(...projValues);
|
|
11377
|
+
const min = Math.min(...projValues);
|
|
11378
|
+
const dist = precision4((max - min) * axis.length);
|
|
11379
|
+
if (dist < DEFAULT_WALL_WIDTH) return;
|
|
11380
|
+
group.forEach((line) => {
|
|
11381
|
+
line.userData.wallWidth = dist;
|
|
11382
|
+
});
|
|
11383
|
+
}
|
|
11384
|
+
// esp: 0.2
|
|
11385
|
+
});
|
|
11321
11386
|
lines = adsorption(lines, option);
|
|
11322
11387
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
11388
|
+
lines = recoveryBayWindow(lines, bayWindow);
|
|
11323
11389
|
lines = removeDangline(lines, 0.1, false);
|
|
11324
11390
|
lines = removeShortDoor(lines);
|
|
11325
11391
|
lines = LineSegmentUtils.GroupBuilder(LineSegmentUtils.group(lines, (line) => line.userData.isDoor || line.userData.isBalconyRailing ? "otherLines" : "newLines")).handle("newLines", (newLines) => {
|
|
@@ -11334,7 +11400,7 @@ function correction(lines, targettLine, option) {
|
|
|
11334
11400
|
return newLines;
|
|
11335
11401
|
}).merge();
|
|
11336
11402
|
lines = removeDangline(lines, 0.15, true);
|
|
11337
|
-
lines = lines.filter((line) => line.length
|
|
11403
|
+
lines = lines.filter((line) => line.length > 1e-9);
|
|
11338
11404
|
return lines;
|
|
11339
11405
|
}
|
|
11340
11406
|
function axisAlignCorr(lines, option, verticalReferenceLine) {
|
|
@@ -11442,7 +11508,7 @@ class DoorFind {
|
|
|
11442
11508
|
searchedList.forEach((item) => {
|
|
11443
11509
|
if (!item.line || item.found) return;
|
|
11444
11510
|
const dir = item.line?.getAnotherPoint(item.linePoint).directionFrom(item.linePoint);
|
|
11445
|
-
const list = doorGrid.queryCircle(item.point, item.door.length
|
|
11511
|
+
const list = doorGrid.queryCircle(item.point, item.door.length * 2.5).filter((result) => {
|
|
11446
11512
|
const { line } = searchedList[result.userData];
|
|
11447
11513
|
return line.isParallelTo(item.line, 10);
|
|
11448
11514
|
}).filter((result) => {
|
|
@@ -11538,7 +11604,7 @@ class DoorFind {
|
|
|
11538
11604
|
* @returns
|
|
11539
11605
|
*/
|
|
11540
11606
|
adsorpt(dock, line, maxAngle = 70) {
|
|
11541
|
-
const length = line.length
|
|
11607
|
+
const length = line.length, targetDirect = dock.dockLine.getAnotherPoint(dock.dockPoint).directionFrom(dock.dockPoint);
|
|
11542
11608
|
dock.point.copy(dock.dockPoint);
|
|
11543
11609
|
const list = this.grid.queryCircle(dock.point, length * 2, true).map((item) => {
|
|
11544
11610
|
return { ...item };
|
|
@@ -11580,7 +11646,7 @@ class DoorFind {
|
|
|
11580
11646
|
return this.extendLink(dock, line);
|
|
11581
11647
|
}
|
|
11582
11648
|
extendLink(dock, line) {
|
|
11583
|
-
const length = line.length
|
|
11649
|
+
const length = line.length;
|
|
11584
11650
|
const direct = dock.dockPoint.directionFrom(dock.dockLine.getAnotherPoint(dock.dockPoint)), queryLine = new LineSegment(
|
|
11585
11651
|
dock.dockPoint,
|
|
11586
11652
|
dock.dockPoint.clone().add(direct.multiplyScalar(length * 2))
|
|
@@ -11610,7 +11676,7 @@ class DoorFind {
|
|
|
11610
11676
|
}
|
|
11611
11677
|
getLines() {
|
|
11612
11678
|
return this.lines.filter((line) => {
|
|
11613
|
-
if (line.userData.isDoor && line.length
|
|
11679
|
+
if (line.userData.isDoor && line.length < 0.4) return false;
|
|
11614
11680
|
return true;
|
|
11615
11681
|
});
|
|
11616
11682
|
}
|
|
@@ -11686,7 +11752,7 @@ function winDrawLine(line, grid) {
|
|
|
11686
11752
|
WallInsertObject.merge([line]);
|
|
11687
11753
|
const list = grid && doubleWallPoint(grid, line), dwh = defaultWallWidth * 0.5;
|
|
11688
11754
|
return line.userData.drawWindow.map(({ full, width, p: p2, height, groundClearance, uuid: uuid2 }) => {
|
|
11689
|
-
if (full) width = line.length
|
|
11755
|
+
if (full) width = line.length;
|
|
11690
11756
|
const point2 = Point.from(p2), direct = line.direction(), winLine = point2.expandAsLine(direct, width).translate(-width * 0.5, direct);
|
|
11691
11757
|
winLine.userData = { wallWidth: defaultWallWidth, height, groundClearance };
|
|
11692
11758
|
winLine.start.copy(line.projectPoint(winLine.start, false));
|
|
@@ -11705,7 +11771,7 @@ function winDrawLine(line, grid) {
|
|
|
11705
11771
|
winLine.userData.winUuid = uuid2;
|
|
11706
11772
|
winLine.userData.lineUuid = line.userData.uuid;
|
|
11707
11773
|
return winLine;
|
|
11708
|
-
}).filter((line2) => line2.length
|
|
11774
|
+
}).filter((line2) => line2.length > defaultWallWidth);
|
|
11709
11775
|
}
|
|
11710
11776
|
return null;
|
|
11711
11777
|
}
|
|
@@ -21621,13 +21687,13 @@ class SceneAutoGenerat {
|
|
|
21621
21687
|
center: new THREE.Vector3().copy(maxLine.center.toJson(z)),
|
|
21622
21688
|
start: new THREE.Vector3().copy(maxLine.start.toJson(z)),
|
|
21623
21689
|
end: new THREE.Vector3().copy(maxLine.start.toJson(z)),
|
|
21624
|
-
length: maxLine.length
|
|
21690
|
+
length: maxLine.length
|
|
21625
21691
|
},
|
|
21626
21692
|
{
|
|
21627
21693
|
center: new THREE.Vector3().copy(minLine.center.toJson(z)),
|
|
21628
21694
|
start: new THREE.Vector3().copy(minLine.start.toJson(z)),
|
|
21629
21695
|
end: new THREE.Vector3().copy(minLine.start.toJson(z)),
|
|
21630
|
-
length: minLine.length
|
|
21696
|
+
length: minLine.length
|
|
21631
21697
|
},
|
|
21632
21698
|
{
|
|
21633
21699
|
center: zStart.clone().add(zEnd).multiplyScalar(0.5),
|
|
@@ -21662,7 +21728,7 @@ class BoundExt {
|
|
|
21662
21728
|
if (target.line.isParallelTo(line)) {
|
|
21663
21729
|
if (line.distanceToSegment(target.line) < minWidth) {
|
|
21664
21730
|
const projectLine = target.line.projectLineSegment(line);
|
|
21665
|
-
if (projectLine.length
|
|
21731
|
+
if (projectLine.length / line.length > 0.6) return false;
|
|
21666
21732
|
}
|
|
21667
21733
|
}
|
|
21668
21734
|
return true;
|
|
@@ -21742,13 +21808,13 @@ class BoundExt {
|
|
|
21742
21808
|
}
|
|
21743
21809
|
});
|
|
21744
21810
|
appendLines = LineSegmentUtils.mergeParallelSegments(appendLines).lines;
|
|
21745
|
-
lines.push(...appendLines.filter((line) => line.length
|
|
21811
|
+
lines.push(...appendLines.filter((line) => line.length > 1e-9));
|
|
21746
21812
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
21747
21813
|
const doors = lines.filter((line) => line.userData.isDoor);
|
|
21748
21814
|
const walls = lines.filter((line) => !line.userData.isDoor);
|
|
21749
21815
|
lines = [...LineSegmentUtils.mergeCollinearSegmentsAll(walls, mergeLineUserData), ...doors];
|
|
21750
21816
|
WallInsertObject.recomputed(lines);
|
|
21751
|
-
lines = lines.filter((line) => line.length
|
|
21817
|
+
lines = lines.filter((line) => line.length > 1e-4).filter((line) => line.userData.isDoor ? line.length > 0.25 : true);
|
|
21752
21818
|
findCallBack && findCallBack([...exteriorLines, ...appendLines], trajectoryPoints);
|
|
21753
21819
|
return {
|
|
21754
21820
|
lines,
|
|
@@ -21783,7 +21849,7 @@ function doubleWallAlignment(lines) {
|
|
|
21783
21849
|
}
|
|
21784
21850
|
});
|
|
21785
21851
|
const expLines = doubleWall.filter((line) => {
|
|
21786
|
-
if (line.length
|
|
21852
|
+
if (line.length < 1e-3) return false;
|
|
21787
21853
|
for (let i = 0; i < line.points.length; i++) {
|
|
21788
21854
|
const point2 = line.points[i];
|
|
21789
21855
|
let list = grid.queryPoint(point2);
|
|
@@ -21843,12 +21909,12 @@ function doubleWallAlignment(lines) {
|
|
|
21843
21909
|
lines = lineSegmentClipping(lines);
|
|
21844
21910
|
lines.push(...doorLines);
|
|
21845
21911
|
WallInsertObject.recomputed(lines);
|
|
21846
|
-
return lines.filter((line) => line.length
|
|
21912
|
+
return lines.filter((line) => line.length > 1e-4);
|
|
21847
21913
|
}
|
|
21848
21914
|
const point = new Point();
|
|
21849
21915
|
class HeightQuery {
|
|
21850
21916
|
static query(line, rootTopContourInfo) {
|
|
21851
|
-
const inLinePoints = [], len = line.length
|
|
21917
|
+
const inLinePoints = [], len = line.length, newLine = line.clone(), center = line.center;
|
|
21852
21918
|
newLine.startShrink(len * 0.2);
|
|
21853
21919
|
newLine.endShrink(len * 0.2);
|
|
21854
21920
|
inLinePoints.push([center.x, center.y], [newLine.start.x, newLine.start.y], [newLine.end.x, newLine.end.y]);
|
|
@@ -21920,11 +21986,11 @@ function doorSpaceHandle(lineSegments) {
|
|
|
21920
21986
|
return startCount === 0 && endCount === 0 || startCount > 0 && endCount > 0;
|
|
21921
21987
|
}), removeLines = [], appendLines = [];
|
|
21922
21988
|
doors.forEach((doorLine) => {
|
|
21923
|
-
const length = doorLine.length
|
|
21989
|
+
const length = doorLine.length, rectangle = doorLine.clone().extendAlongDirection(-0.1, "all").toRectangle(0.8, "butt"), results = quadtree.queryRect(rectangle).map((item) => {
|
|
21924
21990
|
const projectLine = item.line.projectLineSegment(doorLine);
|
|
21925
|
-
const opt = { ...item, projectLine, plLength: projectLine.length
|
|
21991
|
+
const opt = { ...item, projectLine, plLength: projectLine.length };
|
|
21926
21992
|
return opt;
|
|
21927
|
-
}).filter((opt) => opt.projectLine.length
|
|
21993
|
+
}).filter((opt) => opt.projectLine.length / length > 0.7);
|
|
21928
21994
|
results.sort((a2, b4) => b4.plLength - a2.plLength);
|
|
21929
21995
|
results.forEach(({ line, projectLine }, i) => {
|
|
21930
21996
|
if (i === 0) doorLine.copy(projectLine);
|
|
@@ -21941,7 +22007,7 @@ function doorSpaceHandle(lineSegments) {
|
|
|
21941
22007
|
return lineSegments;
|
|
21942
22008
|
}
|
|
21943
22009
|
function removeShortDoubleWall(lineSegments) {
|
|
21944
|
-
const doubleWalls = LineGroupType.getGroupsByType(lineSegments, "doubleWall"), freePointLines = [...findDiscretePointLine2(lineSegments)].filter((line) => line.length
|
|
22010
|
+
const doubleWalls = LineGroupType.getGroupsByType(lineSegments, "doubleWall"), freePointLines = [...findDiscretePointLine2(lineSegments)].filter((line) => line.length < 0.3), grid = createPointSpatialHash(doubleWalls.flat(4)), lines = freePointLines.filter((line) => grid.queryPoint(line.start).length > 0 || grid.queryPoint(line.end).length > 0), removeSet = new Set(lines);
|
|
21945
22011
|
return lineSegments.filter((line) => !removeSet.has(line));
|
|
21946
22012
|
}
|
|
21947
22013
|
function doorToHole(lines, option) {
|
|
@@ -21951,11 +22017,11 @@ function doorToHole(lines, option) {
|
|
|
21951
22017
|
line.userData.isPassageEntrance = true;
|
|
21952
22018
|
line.userData.passageEntrance = [{
|
|
21953
22019
|
p: line.center.toJson(option?.originalZ),
|
|
21954
|
-
width: line.
|
|
22020
|
+
width: line.length,
|
|
21955
22021
|
full: false,
|
|
21956
22022
|
groundClearance: line.userData.drawDoorData?.groundClearance,
|
|
21957
22023
|
type: "door",
|
|
21958
|
-
height: line.userData.drawDoorData?.height ?? Math.min(2, line.
|
|
22024
|
+
height: line.userData.drawDoorData?.height ?? Math.min(2, line.length * 0.8)
|
|
21959
22025
|
}];
|
|
21960
22026
|
}
|
|
21961
22027
|
});
|
|
@@ -22050,31 +22116,31 @@ class DxfDrawPlugin {
|
|
|
22050
22116
|
const doorThickness = DEFAULT_WALL_WIDTH * 0.2;
|
|
22051
22117
|
const list = [];
|
|
22052
22118
|
setColor("yellow");
|
|
22053
|
-
if (line.length
|
|
22119
|
+
if (line.length < 1.2) {
|
|
22054
22120
|
line.extendAlongDirection(-doorThickness * 0.5);
|
|
22055
22121
|
const normal = lineSegment.normal();
|
|
22056
22122
|
let door = new LineSegment(
|
|
22057
22123
|
line.start.clone(),
|
|
22058
|
-
line.start.clone().add(normal.clone().multiplyScalar(line.length
|
|
22124
|
+
line.start.clone().add(normal.clone().multiplyScalar(line.length))
|
|
22059
22125
|
);
|
|
22060
|
-
const box = door.clone().translate(line.length
|
|
22126
|
+
const box = door.clone().translate(line.length * -0.5, door.normal()).toRectangle(line.length, "butt");
|
|
22061
22127
|
for (let j = 0; j < list.length; j++) {
|
|
22062
22128
|
if (list[j].intersectRectangle(box)) {
|
|
22063
22129
|
door = new LineSegment(
|
|
22064
22130
|
line.start.clone(),
|
|
22065
|
-
line.start.clone().add(normal.clone().multiplyScalar(-line.length
|
|
22131
|
+
line.start.clone().add(normal.clone().multiplyScalar(-line.length))
|
|
22066
22132
|
);
|
|
22067
22133
|
break;
|
|
22068
22134
|
}
|
|
22069
22135
|
}
|
|
22070
22136
|
door.extendAlongDirection(-doorThickness * 0.5).toRectangle(DEFAULT_WALL_WIDTH * 0.2, "butt").path2D((p1, p2) => drawLine(p1, p2));
|
|
22071
|
-
const a2 = line.length
|
|
22137
|
+
const a2 = line.length, b4 = door.length, r2 = (a2 ** 2 + b4 ** 2) / (2 * b4), center = door.end.clone().add(door.direction().multiplyScalar(-r2)), [startAngle, endAngle] = this.getArcAngleRange(center, line.end, door.end);
|
|
22072
22138
|
drawArc(center, r2, Math.min(startAngle, endAngle), Math.max(startAngle, endAngle));
|
|
22073
22139
|
list.push(box);
|
|
22074
22140
|
} else {
|
|
22075
22141
|
line.clone().extendAlongDirection(-DEFAULT_WALL_WIDTH * 0.5).toRectangle(DEFAULT_WALL_WIDTH).path2D((p1, p2) => drawLine(p1, p2));
|
|
22076
|
-
line.clone().translate(doorThickness * 0.5, line.normal()).translate(doorThickness * 0.5, line.direction()).extendAlongDirection(-line.length
|
|
22077
|
-
line.clone().translate(-doorThickness * 0.5, line.normal()).translate(-doorThickness * 0.5, line.direction()).extendAlongDirection(-line.length
|
|
22142
|
+
line.clone().translate(doorThickness * 0.5, line.normal()).translate(doorThickness * 0.5, line.direction()).extendAlongDirection(-line.length * 0.45, "end").translate(doorThickness * 0.5).toRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
22143
|
+
line.clone().translate(-doorThickness * 0.5, line.normal()).translate(-doorThickness * 0.5, line.direction()).extendAlongDirection(-line.length * 0.45, "start").translate(-doorThickness * 0.5).toRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
22078
22144
|
}
|
|
22079
22145
|
});
|
|
22080
22146
|
}
|
|
@@ -22165,7 +22231,7 @@ class DxfDataPlugin {
|
|
|
22165
22231
|
});
|
|
22166
22232
|
cad.addGroup(
|
|
22167
22233
|
balconyRailingLines.flatMap((line) => {
|
|
22168
|
-
const dirct = line.normal(), moveDirct = line.direction(), length = line.length
|
|
22234
|
+
const dirct = line.normal(), moveDirct = line.direction(), length = line.length, newLine = line.start.expandAsLine(dirct, offsetWidth).translate(offsetWidth * 0.5, dirct.multiplyScalar(-1)), distance2 = length / 4, count = Math.floor(length / distance2), lines2 = [];
|
|
22169
22235
|
for (let i = 1; i <= count; i++) {
|
|
22170
22236
|
lines2.push(newLine.clone().translate(i * distance2, moveDirct));
|
|
22171
22237
|
}
|
|
@@ -23120,11 +23186,13 @@ export {
|
|
|
23120
23186
|
ArrayMap as A,
|
|
23121
23187
|
Box2 as B,
|
|
23122
23188
|
Component as C,
|
|
23189
|
+
DEFAULT_WALL_WIDTH as D,
|
|
23123
23190
|
HeightQuery as H,
|
|
23124
23191
|
LineDashed as L,
|
|
23125
23192
|
MiniCircles as M,
|
|
23126
23193
|
PointSpatialHash as P,
|
|
23127
23194
|
Quadtree as Q,
|
|
23195
|
+
Rectangle as R,
|
|
23128
23196
|
SelectLocalFile as S,
|
|
23129
23197
|
ThreeVJia as T,
|
|
23130
23198
|
Variable as V,
|