build-dxf 0.1.113 → 0.1.115
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 +245 -173
- package/src/dxf-system/plugins/editor/components/CommandFlow/CFComponent.d.ts +11 -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 +38 -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 +9 -9
- 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 +13 -13
- package/src/index.js +10 -10
- package/src/index3.js +674 -119
- 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;
|
|
@@ -3271,7 +3322,7 @@ class LineSegmentUtils {
|
|
|
3271
3322
|
static GroupBuilder(groups) {
|
|
3272
3323
|
const builder = {
|
|
3273
3324
|
handle(k, fn2) {
|
|
3274
|
-
groups[k] = fn2(groups[k]
|
|
3325
|
+
if (groups[k]) groups[k] = fn2(groups[k]);
|
|
3275
3326
|
return builder;
|
|
3276
3327
|
},
|
|
3277
3328
|
merge() {
|
|
@@ -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,51 @@ 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 = LineSegmentUtils.GroupBuilder(LineSegmentUtils.group(lines, (line) => line.userData.
|
|
11372
|
+
lines = LineSegmentUtils.GroupBuilder(LineSegmentUtils.group(lines, (line) => line.userData.isBalconyRailing ? "balconyRailing" : "lines")).handle("lines", (lines2) => {
|
|
11306
11373
|
return AlignToParallelSegments.align(lines2, {
|
|
11307
11374
|
onMergeLine: mergeLineUserData,
|
|
11308
11375
|
onGroup(group, projValues, axis) {
|
|
11309
11376
|
if (group.length <= 1) return;
|
|
11310
11377
|
const max = Math.max(...projValues);
|
|
11311
11378
|
const min = Math.min(...projValues);
|
|
11312
|
-
const dist = precision4((max - min) * axis.
|
|
11379
|
+
const dist = precision4((max - min) * axis.length);
|
|
11313
11380
|
if (dist < DEFAULT_WALL_WIDTH) return;
|
|
11314
11381
|
group.forEach((line) => {
|
|
11315
11382
|
line.userData.wallWidth = dist;
|
|
11316
11383
|
});
|
|
11317
11384
|
}
|
|
11318
|
-
// esp: 0.
|
|
11385
|
+
// esp: 0.2
|
|
11319
11386
|
});
|
|
11320
|
-
}).merge();
|
|
11387
|
+
}).handle("balconyRailing", (lines2) => AlignToParallelSegments.align(lines2)).merge();
|
|
11321
11388
|
lines = adsorption(lines, option);
|
|
11322
11389
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
11390
|
+
lines = recoveryBayWindow(lines, bayWindow);
|
|
11323
11391
|
lines = removeDangline(lines, 0.1, false);
|
|
11324
11392
|
lines = removeShortDoor(lines);
|
|
11325
11393
|
lines = LineSegmentUtils.GroupBuilder(LineSegmentUtils.group(lines, (line) => line.userData.isDoor || line.userData.isBalconyRailing ? "otherLines" : "newLines")).handle("newLines", (newLines) => {
|
|
@@ -11334,7 +11402,7 @@ function correction(lines, targettLine, option) {
|
|
|
11334
11402
|
return newLines;
|
|
11335
11403
|
}).merge();
|
|
11336
11404
|
lines = removeDangline(lines, 0.15, true);
|
|
11337
|
-
lines = lines.filter((line) => line.length
|
|
11405
|
+
lines = lines.filter((line) => line.length > 1e-9);
|
|
11338
11406
|
return lines;
|
|
11339
11407
|
}
|
|
11340
11408
|
function axisAlignCorr(lines, option, verticalReferenceLine) {
|
|
@@ -11442,7 +11510,7 @@ class DoorFind {
|
|
|
11442
11510
|
searchedList.forEach((item) => {
|
|
11443
11511
|
if (!item.line || item.found) return;
|
|
11444
11512
|
const dir = item.line?.getAnotherPoint(item.linePoint).directionFrom(item.linePoint);
|
|
11445
|
-
const list = doorGrid.queryCircle(item.point, item.door.length
|
|
11513
|
+
const list = doorGrid.queryCircle(item.point, item.door.length * 2.5).filter((result) => {
|
|
11446
11514
|
const { line } = searchedList[result.userData];
|
|
11447
11515
|
return line.isParallelTo(item.line, 10);
|
|
11448
11516
|
}).filter((result) => {
|
|
@@ -11538,7 +11606,7 @@ class DoorFind {
|
|
|
11538
11606
|
* @returns
|
|
11539
11607
|
*/
|
|
11540
11608
|
adsorpt(dock, line, maxAngle = 70) {
|
|
11541
|
-
const length = line.length
|
|
11609
|
+
const length = line.length, targetDirect = dock.dockLine.getAnotherPoint(dock.dockPoint).directionFrom(dock.dockPoint);
|
|
11542
11610
|
dock.point.copy(dock.dockPoint);
|
|
11543
11611
|
const list = this.grid.queryCircle(dock.point, length * 2, true).map((item) => {
|
|
11544
11612
|
return { ...item };
|
|
@@ -11580,7 +11648,7 @@ class DoorFind {
|
|
|
11580
11648
|
return this.extendLink(dock, line);
|
|
11581
11649
|
}
|
|
11582
11650
|
extendLink(dock, line) {
|
|
11583
|
-
const length = line.length
|
|
11651
|
+
const length = line.length;
|
|
11584
11652
|
const direct = dock.dockPoint.directionFrom(dock.dockLine.getAnotherPoint(dock.dockPoint)), queryLine = new LineSegment(
|
|
11585
11653
|
dock.dockPoint,
|
|
11586
11654
|
dock.dockPoint.clone().add(direct.multiplyScalar(length * 2))
|
|
@@ -11610,7 +11678,7 @@ class DoorFind {
|
|
|
11610
11678
|
}
|
|
11611
11679
|
getLines() {
|
|
11612
11680
|
return this.lines.filter((line) => {
|
|
11613
|
-
if (line.userData.isDoor && line.length
|
|
11681
|
+
if (line.userData.isDoor && line.length < 0.4) return false;
|
|
11614
11682
|
return true;
|
|
11615
11683
|
});
|
|
11616
11684
|
}
|
|
@@ -11686,7 +11754,7 @@ function winDrawLine(line, grid) {
|
|
|
11686
11754
|
WallInsertObject.merge([line]);
|
|
11687
11755
|
const list = grid && doubleWallPoint(grid, line), dwh = defaultWallWidth * 0.5;
|
|
11688
11756
|
return line.userData.drawWindow.map(({ full, width, p: p2, height, groundClearance, uuid: uuid2 }) => {
|
|
11689
|
-
if (full) width = line.length
|
|
11757
|
+
if (full) width = line.length;
|
|
11690
11758
|
const point2 = Point.from(p2), direct = line.direction(), winLine = point2.expandAsLine(direct, width).translate(-width * 0.5, direct);
|
|
11691
11759
|
winLine.userData = { wallWidth: defaultWallWidth, height, groundClearance };
|
|
11692
11760
|
winLine.start.copy(line.projectPoint(winLine.start, false));
|
|
@@ -11705,7 +11773,7 @@ function winDrawLine(line, grid) {
|
|
|
11705
11773
|
winLine.userData.winUuid = uuid2;
|
|
11706
11774
|
winLine.userData.lineUuid = line.userData.uuid;
|
|
11707
11775
|
return winLine;
|
|
11708
|
-
}).filter((line2) => line2.length
|
|
11776
|
+
}).filter((line2) => line2.length > defaultWallWidth);
|
|
11709
11777
|
}
|
|
11710
11778
|
return null;
|
|
11711
11779
|
}
|
|
@@ -21621,13 +21689,13 @@ class SceneAutoGenerat {
|
|
|
21621
21689
|
center: new THREE.Vector3().copy(maxLine.center.toJson(z)),
|
|
21622
21690
|
start: new THREE.Vector3().copy(maxLine.start.toJson(z)),
|
|
21623
21691
|
end: new THREE.Vector3().copy(maxLine.start.toJson(z)),
|
|
21624
|
-
length: maxLine.length
|
|
21692
|
+
length: maxLine.length
|
|
21625
21693
|
},
|
|
21626
21694
|
{
|
|
21627
21695
|
center: new THREE.Vector3().copy(minLine.center.toJson(z)),
|
|
21628
21696
|
start: new THREE.Vector3().copy(minLine.start.toJson(z)),
|
|
21629
21697
|
end: new THREE.Vector3().copy(minLine.start.toJson(z)),
|
|
21630
|
-
length: minLine.length
|
|
21698
|
+
length: minLine.length
|
|
21631
21699
|
},
|
|
21632
21700
|
{
|
|
21633
21701
|
center: zStart.clone().add(zEnd).multiplyScalar(0.5),
|
|
@@ -21662,7 +21730,7 @@ class BoundExt {
|
|
|
21662
21730
|
if (target.line.isParallelTo(line)) {
|
|
21663
21731
|
if (line.distanceToSegment(target.line) < minWidth) {
|
|
21664
21732
|
const projectLine = target.line.projectLineSegment(line);
|
|
21665
|
-
if (projectLine.length
|
|
21733
|
+
if (projectLine.length / line.length > 0.6) return false;
|
|
21666
21734
|
}
|
|
21667
21735
|
}
|
|
21668
21736
|
return true;
|
|
@@ -21742,13 +21810,13 @@ class BoundExt {
|
|
|
21742
21810
|
}
|
|
21743
21811
|
});
|
|
21744
21812
|
appendLines = LineSegmentUtils.mergeParallelSegments(appendLines).lines;
|
|
21745
|
-
lines.push(...appendLines.filter((line) => line.length
|
|
21813
|
+
lines.push(...appendLines.filter((line) => line.length > 1e-9));
|
|
21746
21814
|
lines = lineSegmentClipping(lines, 1e-9);
|
|
21747
21815
|
const doors = lines.filter((line) => line.userData.isDoor);
|
|
21748
21816
|
const walls = lines.filter((line) => !line.userData.isDoor);
|
|
21749
21817
|
lines = [...LineSegmentUtils.mergeCollinearSegmentsAll(walls, mergeLineUserData), ...doors];
|
|
21750
21818
|
WallInsertObject.recomputed(lines);
|
|
21751
|
-
lines = lines.filter((line) => line.length
|
|
21819
|
+
lines = lines.filter((line) => line.length > 1e-4).filter((line) => line.userData.isDoor ? line.length > 0.25 : true);
|
|
21752
21820
|
findCallBack && findCallBack([...exteriorLines, ...appendLines], trajectoryPoints);
|
|
21753
21821
|
return {
|
|
21754
21822
|
lines,
|
|
@@ -21783,7 +21851,7 @@ function doubleWallAlignment(lines) {
|
|
|
21783
21851
|
}
|
|
21784
21852
|
});
|
|
21785
21853
|
const expLines = doubleWall.filter((line) => {
|
|
21786
|
-
if (line.length
|
|
21854
|
+
if (line.length < 1e-3) return false;
|
|
21787
21855
|
for (let i = 0; i < line.points.length; i++) {
|
|
21788
21856
|
const point2 = line.points[i];
|
|
21789
21857
|
let list = grid.queryPoint(point2);
|
|
@@ -21843,12 +21911,12 @@ function doubleWallAlignment(lines) {
|
|
|
21843
21911
|
lines = lineSegmentClipping(lines);
|
|
21844
21912
|
lines.push(...doorLines);
|
|
21845
21913
|
WallInsertObject.recomputed(lines);
|
|
21846
|
-
return lines.filter((line) => line.length
|
|
21914
|
+
return lines.filter((line) => line.length > 1e-4);
|
|
21847
21915
|
}
|
|
21848
21916
|
const point = new Point();
|
|
21849
21917
|
class HeightQuery {
|
|
21850
21918
|
static query(line, rootTopContourInfo) {
|
|
21851
|
-
const inLinePoints = [], len = line.length
|
|
21919
|
+
const inLinePoints = [], len = line.length, newLine = line.clone(), center = line.center;
|
|
21852
21920
|
newLine.startShrink(len * 0.2);
|
|
21853
21921
|
newLine.endShrink(len * 0.2);
|
|
21854
21922
|
inLinePoints.push([center.x, center.y], [newLine.start.x, newLine.start.y], [newLine.end.x, newLine.end.y]);
|
|
@@ -21920,11 +21988,11 @@ function doorSpaceHandle(lineSegments) {
|
|
|
21920
21988
|
return startCount === 0 && endCount === 0 || startCount > 0 && endCount > 0;
|
|
21921
21989
|
}), removeLines = [], appendLines = [];
|
|
21922
21990
|
doors.forEach((doorLine) => {
|
|
21923
|
-
const length = doorLine.length
|
|
21991
|
+
const length = doorLine.length, rectangle = doorLine.clone().extendAlongDirection(-0.1, "all").toRectangle(0.8, "butt"), results = quadtree.queryRect(rectangle).map((item) => {
|
|
21924
21992
|
const projectLine = item.line.projectLineSegment(doorLine);
|
|
21925
|
-
const opt = { ...item, projectLine, plLength: projectLine.length
|
|
21993
|
+
const opt = { ...item, projectLine, plLength: projectLine.length };
|
|
21926
21994
|
return opt;
|
|
21927
|
-
}).filter((opt) => opt.projectLine.length
|
|
21995
|
+
}).filter((opt) => opt.projectLine.length / length > 0.7);
|
|
21928
21996
|
results.sort((a2, b4) => b4.plLength - a2.plLength);
|
|
21929
21997
|
results.forEach(({ line, projectLine }, i) => {
|
|
21930
21998
|
if (i === 0) doorLine.copy(projectLine);
|
|
@@ -21941,7 +22009,7 @@ function doorSpaceHandle(lineSegments) {
|
|
|
21941
22009
|
return lineSegments;
|
|
21942
22010
|
}
|
|
21943
22011
|
function removeShortDoubleWall(lineSegments) {
|
|
21944
|
-
const doubleWalls = LineGroupType.getGroupsByType(lineSegments, "doubleWall"), freePointLines = [...findDiscretePointLine2(lineSegments)].filter((line) => line.length
|
|
22012
|
+
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
22013
|
return lineSegments.filter((line) => !removeSet.has(line));
|
|
21946
22014
|
}
|
|
21947
22015
|
function doorToHole(lines, option) {
|
|
@@ -21951,11 +22019,11 @@ function doorToHole(lines, option) {
|
|
|
21951
22019
|
line.userData.isPassageEntrance = true;
|
|
21952
22020
|
line.userData.passageEntrance = [{
|
|
21953
22021
|
p: line.center.toJson(option?.originalZ),
|
|
21954
|
-
width: line.
|
|
22022
|
+
width: line.length,
|
|
21955
22023
|
full: false,
|
|
21956
22024
|
groundClearance: line.userData.drawDoorData?.groundClearance,
|
|
21957
22025
|
type: "door",
|
|
21958
|
-
height: line.userData.drawDoorData?.height ?? Math.min(2, line.
|
|
22026
|
+
height: line.userData.drawDoorData?.height ?? Math.min(2, line.length * 0.8)
|
|
21959
22027
|
}];
|
|
21960
22028
|
}
|
|
21961
22029
|
});
|
|
@@ -22050,31 +22118,31 @@ class DxfDrawPlugin {
|
|
|
22050
22118
|
const doorThickness = DEFAULT_WALL_WIDTH * 0.2;
|
|
22051
22119
|
const list = [];
|
|
22052
22120
|
setColor("yellow");
|
|
22053
|
-
if (line.length
|
|
22121
|
+
if (line.length < 1.2) {
|
|
22054
22122
|
line.extendAlongDirection(-doorThickness * 0.5);
|
|
22055
22123
|
const normal = lineSegment.normal();
|
|
22056
22124
|
let door = new LineSegment(
|
|
22057
22125
|
line.start.clone(),
|
|
22058
|
-
line.start.clone().add(normal.clone().multiplyScalar(line.length
|
|
22126
|
+
line.start.clone().add(normal.clone().multiplyScalar(line.length))
|
|
22059
22127
|
);
|
|
22060
|
-
const box = door.clone().translate(line.length
|
|
22128
|
+
const box = door.clone().translate(line.length * -0.5, door.normal()).toRectangle(line.length, "butt");
|
|
22061
22129
|
for (let j = 0; j < list.length; j++) {
|
|
22062
22130
|
if (list[j].intersectRectangle(box)) {
|
|
22063
22131
|
door = new LineSegment(
|
|
22064
22132
|
line.start.clone(),
|
|
22065
|
-
line.start.clone().add(normal.clone().multiplyScalar(-line.length
|
|
22133
|
+
line.start.clone().add(normal.clone().multiplyScalar(-line.length))
|
|
22066
22134
|
);
|
|
22067
22135
|
break;
|
|
22068
22136
|
}
|
|
22069
22137
|
}
|
|
22070
22138
|
door.extendAlongDirection(-doorThickness * 0.5).toRectangle(DEFAULT_WALL_WIDTH * 0.2, "butt").path2D((p1, p2) => drawLine(p1, p2));
|
|
22071
|
-
const a2 = line.length
|
|
22139
|
+
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
22140
|
drawArc(center, r2, Math.min(startAngle, endAngle), Math.max(startAngle, endAngle));
|
|
22073
22141
|
list.push(box);
|
|
22074
22142
|
} else {
|
|
22075
22143
|
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
|
|
22144
|
+
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));
|
|
22145
|
+
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
22146
|
}
|
|
22079
22147
|
});
|
|
22080
22148
|
}
|
|
@@ -22165,7 +22233,7 @@ class DxfDataPlugin {
|
|
|
22165
22233
|
});
|
|
22166
22234
|
cad.addGroup(
|
|
22167
22235
|
balconyRailingLines.flatMap((line) => {
|
|
22168
|
-
const dirct = line.normal(), moveDirct = line.direction(), length = line.length
|
|
22236
|
+
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
22237
|
for (let i = 1; i <= count; i++) {
|
|
22170
22238
|
lines2.push(newLine.clone().translate(i * distance2, moveDirct));
|
|
22171
22239
|
}
|
|
@@ -23120,37 +23188,41 @@ export {
|
|
|
23120
23188
|
ArrayMap as A,
|
|
23121
23189
|
Box2 as B,
|
|
23122
23190
|
Component as C,
|
|
23191
|
+
DEFAULT_WALL_WIDTH as D,
|
|
23123
23192
|
HeightQuery as H,
|
|
23124
23193
|
LineDashed as L,
|
|
23125
23194
|
MiniCircles as M,
|
|
23126
23195
|
PointSpatialHash as P,
|
|
23127
23196
|
Quadtree as Q,
|
|
23197
|
+
Rectangle as R,
|
|
23128
23198
|
SelectLocalFile as S,
|
|
23129
23199
|
ThreeVJia as T,
|
|
23130
23200
|
Variable as V,
|
|
23131
|
-
|
|
23201
|
+
WallGroupManager as W,
|
|
23132
23202
|
Point as a,
|
|
23133
|
-
|
|
23203
|
+
Pipeline as b,
|
|
23134
23204
|
cloneUserData as c,
|
|
23135
|
-
|
|
23205
|
+
WallInsertObject as d,
|
|
23136
23206
|
LineSegmentUtils as e,
|
|
23137
|
-
|
|
23207
|
+
LineSegment as f,
|
|
23138
23208
|
getDefaultExportFromCjs as g,
|
|
23139
|
-
|
|
23140
|
-
|
|
23141
|
-
|
|
23142
|
-
|
|
23143
|
-
|
|
23209
|
+
createQuadtree as h,
|
|
23210
|
+
Lines as i,
|
|
23211
|
+
drawText$1 as j,
|
|
23212
|
+
mergeChains as k,
|
|
23213
|
+
mmTom as l,
|
|
23144
23214
|
mToMm as m,
|
|
23145
|
-
|
|
23146
|
-
|
|
23147
|
-
|
|
23148
|
-
|
|
23149
|
-
|
|
23150
|
-
|
|
23151
|
-
|
|
23215
|
+
LinePipeline as n,
|
|
23216
|
+
WhiteModel as o,
|
|
23217
|
+
CommandManager as p,
|
|
23218
|
+
index as q,
|
|
23219
|
+
buildJson as r,
|
|
23220
|
+
createEditor as s,
|
|
23221
|
+
index$2 as t,
|
|
23152
23222
|
uuid as u,
|
|
23153
|
-
|
|
23154
|
-
|
|
23155
|
-
|
|
23223
|
+
getFileAll as v,
|
|
23224
|
+
getGlobalDxfSystem as w,
|
|
23225
|
+
getModels as x,
|
|
23226
|
+
hasCircle as y,
|
|
23227
|
+
index$3 as z
|
|
23156
23228
|
};
|