build-dxf 0.1.105 → 0.1.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/build.js +206 -64
- package/src/index3.js +2 -2
- package/src/utils/algorithms/LineSegment.d.ts +1 -1
- package/src/utils/algorithms/LineSegmentUtils.d.ts +8 -0
- package/src/utils/algorithms/Point.d.ts +65 -17
- package/src/utils/algorithms/PointUtils.d.ts +5 -1
- package/src/utils/algorithms/precision.d.ts +3 -0
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -316,12 +316,12 @@ class Rectangle {
|
|
|
316
316
|
for (let i = 0; i < 4; i++) {
|
|
317
317
|
const p1 = this.points[i];
|
|
318
318
|
const p2 = this.points[(i + 1) % 4];
|
|
319
|
-
axes.push(p1.
|
|
319
|
+
axes.push(p1.leftNormal(p2));
|
|
320
320
|
}
|
|
321
321
|
for (let i = 0; i < 4; i++) {
|
|
322
322
|
const p1 = rectangle.points[i];
|
|
323
323
|
const p2 = rectangle.points[(i + 1) % 4];
|
|
324
|
-
axes.push(p1.
|
|
324
|
+
axes.push(p1.leftNormal(p2));
|
|
325
325
|
}
|
|
326
326
|
function projectRectangle(rect, axis) {
|
|
327
327
|
const projections = rect.points.map((point2) => point2.dot(axis));
|
|
@@ -377,7 +377,7 @@ class Rectangle {
|
|
|
377
377
|
* @returns
|
|
378
378
|
*/
|
|
379
379
|
static fromByLineSegment(line, width = 0.1, horizontal = false, hScale = 0.5) {
|
|
380
|
-
const p1 = line.points[0], p2 = line.points[1], normal = p2.
|
|
380
|
+
const p1 = line.points[0], p2 = line.points[1], normal = p2.leftNormal(p1), pDirect = horizontal ? p2.directionFrom(p1).multiplyScalar(width * hScale) : Point.zero(), nDirect = horizontal ? p1.directionFrom(p2).multiplyScalar(width * hScale) : Point.zero();
|
|
381
381
|
const offsetX = normal.x * width * 0.5;
|
|
382
382
|
const offsetY = normal.y * width * 0.5;
|
|
383
383
|
return new Rectangle([
|
|
@@ -451,9 +451,17 @@ class LineSegment {
|
|
|
451
451
|
}
|
|
452
452
|
setLength(len) {
|
|
453
453
|
const direct = this.direction();
|
|
454
|
-
const
|
|
455
|
-
const
|
|
456
|
-
|
|
454
|
+
const half = len * 0.5;
|
|
455
|
+
const dx = direct.x * half;
|
|
456
|
+
const dy = direct.y * half;
|
|
457
|
+
this.start.set(
|
|
458
|
+
this.#center.x - dx,
|
|
459
|
+
this.#center.y - dy
|
|
460
|
+
);
|
|
461
|
+
this.end.set(
|
|
462
|
+
this.#center.x + dx,
|
|
463
|
+
this.#center.y + dy
|
|
464
|
+
);
|
|
457
465
|
return this;
|
|
458
466
|
}
|
|
459
467
|
/** 获取另一个点
|
|
@@ -603,10 +611,10 @@ class LineSegment {
|
|
|
603
611
|
return this.#direction.clone();
|
|
604
612
|
}
|
|
605
613
|
/**
|
|
606
|
-
*
|
|
614
|
+
* 获取发向量-左法线
|
|
607
615
|
*/
|
|
608
616
|
normal() {
|
|
609
|
-
return this.points[1].
|
|
617
|
+
return this.points[1].leftNormal(this.points[0]);
|
|
610
618
|
}
|
|
611
619
|
/**
|
|
612
620
|
* @param line
|
|
@@ -623,9 +631,9 @@ class LineSegment {
|
|
|
623
631
|
*/
|
|
624
632
|
toRectangle(width = 0.1, cap = "square") {
|
|
625
633
|
const p1 = this.start, p2 = this.end;
|
|
626
|
-
const normal = p2.
|
|
627
|
-
const pDirect = cap === "butt" ? Point.zero() : p2.directionFrom(p1).
|
|
628
|
-
const nDirect = cap === "butt" ? Point.zero() : p1.directionFrom(p2).
|
|
634
|
+
const normal = p2.leftNormal(p1);
|
|
635
|
+
const pDirect = cap === "butt" ? Point.zero() : p2.directionFrom(p1).multiplyScalar(width * 0.5);
|
|
636
|
+
const nDirect = cap === "butt" ? Point.zero() : p1.directionFrom(p2).multiplyScalar(width * 0.5);
|
|
629
637
|
const offsetX = normal.x * width * 0.5;
|
|
630
638
|
const offsetY = normal.y * width * 0.5;
|
|
631
639
|
const point2 = [
|
|
@@ -995,7 +1003,17 @@ class LineSegment {
|
|
|
995
1003
|
return point2.currentData[LINE_SYMBOL] ?? null;
|
|
996
1004
|
}
|
|
997
1005
|
}
|
|
998
|
-
const
|
|
1006
|
+
const POW10 = [
|
|
1007
|
+
1,
|
|
1008
|
+
10,
|
|
1009
|
+
100,
|
|
1010
|
+
1e3,
|
|
1011
|
+
1e4,
|
|
1012
|
+
1e5,
|
|
1013
|
+
1e6,
|
|
1014
|
+
1e7,
|
|
1015
|
+
1e8
|
|
1016
|
+
];
|
|
999
1017
|
class Point {
|
|
1000
1018
|
x;
|
|
1001
1019
|
y;
|
|
@@ -1051,22 +1069,34 @@ class Point {
|
|
|
1051
1069
|
this.y = arr[1];
|
|
1052
1070
|
return this;
|
|
1053
1071
|
}
|
|
1054
|
-
/**
|
|
1055
|
-
* multiplyScalar
|
|
1072
|
+
/** 乘法
|
|
1056
1073
|
* @param scalar
|
|
1074
|
+
* @returns
|
|
1057
1075
|
*/
|
|
1058
|
-
|
|
1059
|
-
this.x *=
|
|
1060
|
-
this.y *=
|
|
1076
|
+
multiply(point2) {
|
|
1077
|
+
this.x *= point2.x;
|
|
1078
|
+
this.y *= point2.y;
|
|
1061
1079
|
return this;
|
|
1062
1080
|
}
|
|
1081
|
+
/** 乘以一个标量
|
|
1082
|
+
* @param scalar
|
|
1083
|
+
* @returns
|
|
1084
|
+
*/
|
|
1063
1085
|
multiplyScalar(scalar) {
|
|
1064
1086
|
this.x *= scalar;
|
|
1065
1087
|
this.y *= scalar;
|
|
1066
1088
|
return this;
|
|
1067
1089
|
}
|
|
1068
|
-
/**
|
|
1069
|
-
*
|
|
1090
|
+
/** 除法
|
|
1091
|
+
* @param scalar
|
|
1092
|
+
* @returns
|
|
1093
|
+
*/
|
|
1094
|
+
division(point2) {
|
|
1095
|
+
this.x /= point2.x;
|
|
1096
|
+
this.y /= point2.y;
|
|
1097
|
+
return this;
|
|
1098
|
+
}
|
|
1099
|
+
/** 除一个标量
|
|
1070
1100
|
* @param scalar
|
|
1071
1101
|
* @returns
|
|
1072
1102
|
*/
|
|
@@ -1081,20 +1111,20 @@ class Point {
|
|
|
1081
1111
|
* @param point
|
|
1082
1112
|
* @returns
|
|
1083
1113
|
*/
|
|
1084
|
-
|
|
1114
|
+
subtract(point2) {
|
|
1085
1115
|
this.x -= point2.x;
|
|
1086
1116
|
this.y -= point2.y;
|
|
1087
1117
|
return this;
|
|
1088
1118
|
}
|
|
1089
1119
|
/**
|
|
1090
|
-
*
|
|
1120
|
+
* 减一个标量
|
|
1091
1121
|
* @description 将当前点的坐标减去指定点的坐标
|
|
1092
1122
|
* @param point
|
|
1093
1123
|
* @returns
|
|
1094
1124
|
*/
|
|
1095
|
-
|
|
1096
|
-
this.x -=
|
|
1097
|
-
this.y -=
|
|
1125
|
+
subtractScalar(value) {
|
|
1126
|
+
this.x -= value;
|
|
1127
|
+
this.y -= value;
|
|
1098
1128
|
return this;
|
|
1099
1129
|
}
|
|
1100
1130
|
/**
|
|
@@ -1108,8 +1138,7 @@ class Point {
|
|
|
1108
1138
|
this.y += point2.y;
|
|
1109
1139
|
return this;
|
|
1110
1140
|
}
|
|
1111
|
-
/**
|
|
1112
|
-
* 加法
|
|
1141
|
+
/** 加一个标量
|
|
1113
1142
|
* @description 将当前点的坐标加上指定点的坐标
|
|
1114
1143
|
* @param point
|
|
1115
1144
|
* @returns
|
|
@@ -1118,6 +1147,35 @@ class Point {
|
|
|
1118
1147
|
this.x += value;
|
|
1119
1148
|
this.y += value;
|
|
1120
1149
|
}
|
|
1150
|
+
/**
|
|
1151
|
+
* 加法(不可变)
|
|
1152
|
+
* @description 返回当前点与指定点相加后的新点,不修改当前点
|
|
1153
|
+
* @param point
|
|
1154
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
1155
|
+
* @returns 相加后的点
|
|
1156
|
+
*/
|
|
1157
|
+
added(point2, out = new Point()) {
|
|
1158
|
+
return out.set(
|
|
1159
|
+
this.x + point2.x,
|
|
1160
|
+
this.y + point2.y
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* 减法(不可变)
|
|
1165
|
+
* @description 返回当前点减去指定点后的新点,不修改当前点
|
|
1166
|
+
* @param point
|
|
1167
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
1168
|
+
* @returns 相减后的点
|
|
1169
|
+
*/
|
|
1170
|
+
subtracted(point2, out = new Point()) {
|
|
1171
|
+
return out.set(
|
|
1172
|
+
this.x - point2.x,
|
|
1173
|
+
this.y - point2.y
|
|
1174
|
+
);
|
|
1175
|
+
}
|
|
1176
|
+
/** 转为整型
|
|
1177
|
+
* @returns
|
|
1178
|
+
*/
|
|
1121
1179
|
parseInt() {
|
|
1122
1180
|
this.x = ~~this.x;
|
|
1123
1181
|
this.y = ~~this.y;
|
|
@@ -1139,21 +1197,40 @@ class Point {
|
|
|
1139
1197
|
this.y = rotatedY + point2.y;
|
|
1140
1198
|
return this;
|
|
1141
1199
|
}
|
|
1200
|
+
/**
|
|
1201
|
+
* 旋转(不可变)
|
|
1202
|
+
* @description 返回当前点绕指定中心旋转后的新点,不修改当前点
|
|
1203
|
+
* @param center 旋转中心
|
|
1204
|
+
* @param angle 旋转角度(弧度)
|
|
1205
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
1206
|
+
* @returns 旋转后的点
|
|
1207
|
+
*/
|
|
1208
|
+
rotated(center, angle, out = new Point()) {
|
|
1209
|
+
const dx = this.x - center.x;
|
|
1210
|
+
const dy = this.y - center.y;
|
|
1211
|
+
const cos = Math.cos(angle);
|
|
1212
|
+
const sin = Math.sin(angle);
|
|
1213
|
+
return out.set(
|
|
1214
|
+
dx * cos - dy * sin + center.x,
|
|
1215
|
+
dx * sin + dy * cos + center.y
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1142
1218
|
/**
|
|
1143
1219
|
* 保留小数位数
|
|
1144
1220
|
* @param count
|
|
1145
1221
|
*/
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
this.
|
|
1222
|
+
precision(count) {
|
|
1223
|
+
const factor = POW10[count] ?? 10 ** count;
|
|
1224
|
+
this.x = Math.round(this.x * factor) / factor;
|
|
1225
|
+
this.y = Math.round(this.y * factor) / factor;
|
|
1149
1226
|
return this;
|
|
1150
1227
|
}
|
|
1151
|
-
/**
|
|
1228
|
+
/** 保留四位小数
|
|
1152
1229
|
* @returns
|
|
1153
1230
|
*/
|
|
1154
|
-
|
|
1155
|
-
this.x = Math.round(this.x
|
|
1156
|
-
this.y = Math.round(this.y
|
|
1231
|
+
precision4() {
|
|
1232
|
+
this.x = Math.round(this.x * 1e4) / 1e4;
|
|
1233
|
+
this.y = Math.round(this.y * 1e4) / 1e4;
|
|
1157
1234
|
return this;
|
|
1158
1235
|
}
|
|
1159
1236
|
/**
|
|
@@ -1169,12 +1246,28 @@ class Point {
|
|
|
1169
1246
|
return this;
|
|
1170
1247
|
}
|
|
1171
1248
|
/**
|
|
1172
|
-
|
|
1249
|
+
* 归一化(不可变)
|
|
1250
|
+
* @description 返回当前向量归一化后的新点,不修改当前点
|
|
1251
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
1252
|
+
* @returns 单位向量
|
|
1253
|
+
*/
|
|
1254
|
+
normalized(out = new Point()) {
|
|
1255
|
+
const length = Math.hypot(this.x, this.y);
|
|
1256
|
+
if (length === 0) {
|
|
1257
|
+
return out.set(0, 0);
|
|
1258
|
+
}
|
|
1259
|
+
return out.set(
|
|
1260
|
+
this.x / length,
|
|
1261
|
+
this.y / length
|
|
1262
|
+
);
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* 获取单位左法向量
|
|
1173
1266
|
* @description 计算当前点到指定点的方向向量,并返回逆时针旋转90度后的单位法向量
|
|
1174
1267
|
* @param point
|
|
1175
1268
|
* @returns
|
|
1176
1269
|
*/
|
|
1177
|
-
|
|
1270
|
+
leftNormal(point2) {
|
|
1178
1271
|
const dx = this.x - point2.x;
|
|
1179
1272
|
const dy = this.y - point2.y;
|
|
1180
1273
|
const length = Math.sqrt(dx * dx + dy * dy);
|
|
@@ -1329,12 +1422,15 @@ class Point {
|
|
|
1329
1422
|
this.y = p2.y ?? 0;
|
|
1330
1423
|
return this;
|
|
1331
1424
|
}
|
|
1332
|
-
/**
|
|
1333
|
-
*
|
|
1425
|
+
/** 转为数组
|
|
1334
1426
|
*/
|
|
1335
1427
|
toArray() {
|
|
1336
1428
|
return [this.x, this.y];
|
|
1337
1429
|
}
|
|
1430
|
+
/** 转为json
|
|
1431
|
+
* @param z
|
|
1432
|
+
* @returns
|
|
1433
|
+
*/
|
|
1338
1434
|
toJson(z = 0) {
|
|
1339
1435
|
return {
|
|
1340
1436
|
x: this.x,
|
|
@@ -2952,10 +3048,18 @@ class PointUtils {
|
|
|
2952
3048
|
/**保留小数位数
|
|
2953
3049
|
* @param points
|
|
2954
3050
|
*/
|
|
2955
|
-
static
|
|
3051
|
+
static precision(points, count) {
|
|
3052
|
+
for (const p2 of points) {
|
|
3053
|
+
p2.precision(count);
|
|
3054
|
+
}
|
|
3055
|
+
return points;
|
|
3056
|
+
}
|
|
3057
|
+
/**保留四位小数位数
|
|
3058
|
+
* @param points
|
|
3059
|
+
*/
|
|
3060
|
+
static precision4(points) {
|
|
2956
3061
|
for (const p2 of points) {
|
|
2957
|
-
p2.
|
|
2958
|
-
p2.y = Math.round(p2.y * scale2) / scale2;
|
|
3062
|
+
p2.precision4();
|
|
2959
3063
|
}
|
|
2960
3064
|
return points;
|
|
2961
3065
|
}
|
|
@@ -3034,9 +3138,30 @@ class UnionFindSet {
|
|
|
3034
3138
|
}
|
|
3035
3139
|
}
|
|
3036
3140
|
class LineSegmentUtils {
|
|
3141
|
+
// 克隆
|
|
3037
3142
|
clone(lines) {
|
|
3038
3143
|
return lines.map((line) => line.clone());
|
|
3039
3144
|
}
|
|
3145
|
+
/**保留小数位数
|
|
3146
|
+
* @param points
|
|
3147
|
+
*/
|
|
3148
|
+
static precision(lines, count) {
|
|
3149
|
+
for (const l of lines) {
|
|
3150
|
+
l.start.precision(count);
|
|
3151
|
+
l.end.precision(count);
|
|
3152
|
+
}
|
|
3153
|
+
return lines;
|
|
3154
|
+
}
|
|
3155
|
+
/**保留四位小数位数
|
|
3156
|
+
* @param points
|
|
3157
|
+
*/
|
|
3158
|
+
static precision4(lines) {
|
|
3159
|
+
for (const l of lines) {
|
|
3160
|
+
l.start.precision4();
|
|
3161
|
+
l.end.precision4();
|
|
3162
|
+
}
|
|
3163
|
+
return lines;
|
|
3164
|
+
}
|
|
3040
3165
|
/** 获取最长线段索引
|
|
3041
3166
|
* @param lines
|
|
3042
3167
|
*/
|
|
@@ -6428,6 +6553,7 @@ function segmentationPath(lines, clipLine) {
|
|
|
6428
6553
|
function clippingDoubleWall(lines) {
|
|
6429
6554
|
lines = lines.map((line) => line.clone());
|
|
6430
6555
|
lines = mergeChains(lines);
|
|
6556
|
+
if (lines.length === 4) return [lines];
|
|
6431
6557
|
const queue = [lines], groups = [], maxCount2 = 2e4;
|
|
6432
6558
|
let pendingLines, count = 0;
|
|
6433
6559
|
while ((pendingLines = queue.pop()) !== void 0) {
|
|
@@ -6457,6 +6583,7 @@ function clippingDoubleWall(lines) {
|
|
|
6457
6583
|
}
|
|
6458
6584
|
const miniCircles = new MiniCircles();
|
|
6459
6585
|
function clippingInsertObjectDoubleWall(lines) {
|
|
6586
|
+
if (lines.length === 4) return [lines];
|
|
6460
6587
|
const hasInsertObject = lines.some((line) => WallInsertObject.isInsertObject(line));
|
|
6461
6588
|
if (!hasInsertObject) return clippingDoubleWall(lines);
|
|
6462
6589
|
const quadtree = createQuadtree(lines), poly = Polygon.fromByLines2(lines), far = 10;
|
|
@@ -9396,6 +9523,12 @@ class BuildGroup {
|
|
|
9396
9523
|
return buildDoubleWallGroup;
|
|
9397
9524
|
}
|
|
9398
9525
|
}
|
|
9526
|
+
function precision4(value) {
|
|
9527
|
+
return Math.round(value * 1e4) * 1e-4;
|
|
9528
|
+
}
|
|
9529
|
+
function precision4Nullable(value) {
|
|
9530
|
+
return value == null ? void 0 : precision4(value);
|
|
9531
|
+
}
|
|
9399
9532
|
const holeTypeMap = {
|
|
9400
9533
|
door: "DOOR",
|
|
9401
9534
|
RAILING: "RAILING",
|
|
@@ -9433,11 +9566,21 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9433
9566
|
const { door, window: windowLines, passageEntrance, untreatedDoubleWallGroup } = WallInsertObjectDrawData.handleHoleDrawData(groups, []);
|
|
9434
9567
|
const walls = untreatedDoubleWallGroup.flatMap((lines2) => {
|
|
9435
9568
|
if (lines2.length < 4) return lines2;
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
const
|
|
9569
|
+
let newLine = null;
|
|
9570
|
+
let wallWidth = 0;
|
|
9571
|
+
const poly = Polygon.fromByLinePath(lines2).getMinimumBoundingRectangle();
|
|
9572
|
+
if (poly) {
|
|
9573
|
+
const len1 = poly[0].distance(poly[1]), len2 = poly[1].distance(poly[2]), direct = len1 > len2 ? poly[0].directionFrom(poly[1]) : poly[1].directionFrom(poly[2]), center = poly.getCenter();
|
|
9574
|
+
newLine = center.expandAsLine(direct, 1).setLength(Math.max(len1, len2));
|
|
9575
|
+
wallWidth = Math.min(len1, len2);
|
|
9576
|
+
} else {
|
|
9577
|
+
lines2 = [...lines2].sort((a2, b4) => a2.length() - b4.length());
|
|
9578
|
+
const line1 = lines2[0], line2 = lines2[1];
|
|
9579
|
+
newLine = new LineSegment(line1.center.clone(), line2.center.clone());
|
|
9580
|
+
wallWidth = line1.length();
|
|
9581
|
+
}
|
|
9439
9582
|
mergeLineUserData(newLine, lines2);
|
|
9440
|
-
newLine.userData.wallWidth =
|
|
9583
|
+
newLine.userData.wallWidth = wallWidth;
|
|
9441
9584
|
return [newLine];
|
|
9442
9585
|
});
|
|
9443
9586
|
this.manager.add({ type: "wallHole", lines: windowLines });
|
|
@@ -9534,12 +9677,12 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9534
9677
|
const hole = {
|
|
9535
9678
|
id: this.index++,
|
|
9536
9679
|
type,
|
|
9537
|
-
start: line.start.toJson2D(),
|
|
9538
|
-
end: line.end.toJson2D(),
|
|
9539
|
-
depth: line.userData.depth,
|
|
9540
|
-
height: line.userData?.height ?? DEFAULT_DOOR_HEIGHT,
|
|
9541
|
-
sillHeight: line.userData?.groundClearance ?? DOOR_GROUND_CLEARANCE_HEIGHT,
|
|
9542
|
-
groundClearance: line.userData?.groundClearance ?? DOOR_GROUND_CLEARANCE_HEIGHT
|
|
9680
|
+
start: line.start.precision4().toJson2D(),
|
|
9681
|
+
end: line.end.precision4().toJson2D(),
|
|
9682
|
+
depth: precision4Nullable(line.userData.depth),
|
|
9683
|
+
height: precision4Nullable(line.userData?.height ?? DEFAULT_DOOR_HEIGHT),
|
|
9684
|
+
sillHeight: precision4Nullable(line.userData?.groundClearance ?? DOOR_GROUND_CLEARANCE_HEIGHT),
|
|
9685
|
+
groundClearance: precision4Nullable(line.userData?.groundClearance ?? DOOR_GROUND_CLEARANCE_HEIGHT)
|
|
9543
9686
|
// ?非三维家需要数据
|
|
9544
9687
|
};
|
|
9545
9688
|
if (type === "DOOR") Object.assign(hole, { openSide: "RIGHT" });
|
|
@@ -9575,16 +9718,17 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9575
9718
|
};
|
|
9576
9719
|
this.manager.forEach((group) => this.run(group.type, { lines: group.lines, json: option }, cache));
|
|
9577
9720
|
cache.wallLines.forEach((line) => {
|
|
9721
|
+
line.setLength(line.len + 4e-3);
|
|
9578
9722
|
option.walls.push({
|
|
9579
9723
|
ID: this.index++,
|
|
9580
|
-
start: line.start.toJson2D(),
|
|
9581
|
-
end: line.end.toJson2D(),
|
|
9582
|
-
thickness: Math.max(line.userData.wallWidth ? line.userData.wallWidth : 0.12, 0.12),
|
|
9724
|
+
start: line.start.precision4().toJson2D(),
|
|
9725
|
+
end: line.end.precision4().toJson2D(),
|
|
9726
|
+
thickness: precision4(Math.max(line.userData.wallWidth ? line.userData.wallWidth : 0.12, 0.12)),
|
|
9583
9727
|
type: "LINE",
|
|
9584
9728
|
isDoor: false,
|
|
9585
9729
|
loadBearingWall: false,
|
|
9586
9730
|
// height: line.userData.height ?? DEFAULT_WALL_HEIGHT
|
|
9587
|
-
height: line.currentData[WALL_HEIGHT_KEY] ?? this.maxHeight
|
|
9731
|
+
height: precision4(line.currentData[WALL_HEIGHT_KEY] ?? this.maxHeight)
|
|
9588
9732
|
});
|
|
9589
9733
|
});
|
|
9590
9734
|
return option;
|
|
@@ -9638,6 +9782,7 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9638
9782
|
* @returns
|
|
9639
9783
|
*/
|
|
9640
9784
|
static toThreeVJiaJson(lineSegments, angle = 0, updateGroup = true) {
|
|
9785
|
+
angle = precision4(angle);
|
|
9641
9786
|
let centerVec2 = null;
|
|
9642
9787
|
lineSegments = LineSegmentUndirectedGraph.rotate(lineSegments.map((line) => line.clone()), angle, (line, center, angle2) => {
|
|
9643
9788
|
if (!centerVec2) centerVec2 = { x: center.x, y: center.y };
|
|
@@ -9661,7 +9806,7 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
9661
9806
|
});
|
|
9662
9807
|
});
|
|
9663
9808
|
if (heights.length === 0) heights.push(DEFAULT_WALL_HEIGHT);
|
|
9664
|
-
const maxHeight = Math.max(...heights);
|
|
9809
|
+
const maxHeight = precision4(Math.max(...heights));
|
|
9665
9810
|
if (updateGroup) lineSegments = BuildGroup.doubleWall(lineSegments);
|
|
9666
9811
|
const threeVJiaJson = new ThreeVJiaPipeline(lineSegments, maxHeight);
|
|
9667
9812
|
const json = threeVJiaJson.transform();
|
|
@@ -9968,8 +10113,8 @@ class CAD {
|
|
|
9968
10113
|
resetOrigin() {
|
|
9969
10114
|
const lines = this.groups.flatMap((group) => group.lines), box = Box2.fromByLineSegment(...lines), center = box.center;
|
|
9970
10115
|
this.groups.forEach((group) => group.lines.forEach((line) => {
|
|
9971
|
-
line.start.
|
|
9972
|
-
line.end.
|
|
10116
|
+
line.start.subtract(center);
|
|
10117
|
+
line.end.subtract(center);
|
|
9973
10118
|
}));
|
|
9974
10119
|
this.needUpdate = true;
|
|
9975
10120
|
}
|
|
@@ -9981,8 +10126,8 @@ class CAD {
|
|
|
9981
10126
|
const lines = this.groups.flatMap((group) => group.lines), box = Box2.fromByLineSegment(...lines), center = box.center;
|
|
9982
10127
|
this.groups.forEach((group) => group.lines.forEach((line) => {
|
|
9983
10128
|
line.rotate(angle, center);
|
|
9984
|
-
line.start.
|
|
9985
|
-
line.end.
|
|
10129
|
+
line.start.subtract(center);
|
|
10130
|
+
line.end.subtract(center);
|
|
9986
10131
|
}));
|
|
9987
10132
|
this.needUpdate = true;
|
|
9988
10133
|
}
|
|
@@ -10581,9 +10726,6 @@ class DoubleWallHelper {
|
|
|
10581
10726
|
lineSegments = this.complementSide(lineSegments, otherLines);
|
|
10582
10727
|
WIO.recomputed(lineSegments);
|
|
10583
10728
|
lineSegments = BuildGroup.doubleWall(lineSegments, true);
|
|
10584
|
-
PointUtils.round(
|
|
10585
|
-
PointUtils.quantize(LineSegmentUtils.flatPoints(lineSegments), 1e-4)
|
|
10586
|
-
);
|
|
10587
10729
|
return [...lineSegments, ...otherLines];
|
|
10588
10730
|
}
|
|
10589
10731
|
}
|
|
@@ -11314,7 +11456,7 @@ class DoorFind {
|
|
|
11314
11456
|
}).filter((item) => {
|
|
11315
11457
|
return item.point.distance(dock.point) / length > 0.5;
|
|
11316
11458
|
}).filter((item) => {
|
|
11317
|
-
const normal = item.point.
|
|
11459
|
+
const normal = item.point.leftNormal(dock.point), center = new Point((item.point.x + dock.point.x) / 2, (item.point.y + dock.point.y) / 2), length2 = item.point.distance(dock.point);
|
|
11318
11460
|
const normalLine = new LineSegment(
|
|
11319
11461
|
center,
|
|
11320
11462
|
center.clone().add(normal.clone().multiplyScalar(length2))
|
|
@@ -11601,7 +11743,7 @@ class HeightQuery {
|
|
|
11601
11743
|
if (contoursData.length) return contoursData;
|
|
11602
11744
|
points.filter((p2) => {
|
|
11603
11745
|
point.set(p2[0], p2[1]);
|
|
11604
|
-
new Array(...new Set(quadtree?.queryCircle(point, 0.
|
|
11746
|
+
new Array(...new Set(quadtree?.queryCircle(point, 0.6).map((item) => item.line.currentData.contourIndex))).forEach((index2) => {
|
|
11605
11747
|
if (index2 === maxContourIndex) return;
|
|
11606
11748
|
contoursData.push({ i: index2, averagePz: contours[index2].averagePz });
|
|
11607
11749
|
});
|
package/src/index3.js
CHANGED
|
@@ -16415,7 +16415,7 @@ class VerticalCorrContinue extends CommandFlowComponent {
|
|
|
16415
16415
|
}
|
|
16416
16416
|
}
|
|
16417
16417
|
function buildDashedHelperLine$1(start, end, offset = 0.5) {
|
|
16418
|
-
const offsetDistance = end.
|
|
16418
|
+
const offsetDistance = end.leftNormal(start).multiplyScalar(offset);
|
|
16419
16419
|
const startOffPoint = start.clone().add(offsetDistance);
|
|
16420
16420
|
const endOffPoint = end.clone().add(offsetDistance);
|
|
16421
16421
|
return [
|
|
@@ -16494,7 +16494,7 @@ class RayDistance extends CommandFlowComponent {
|
|
|
16494
16494
|
}
|
|
16495
16495
|
}
|
|
16496
16496
|
function buildDashedHelperLine(start, end, offset = 0.5) {
|
|
16497
|
-
const offsetDistance = end.
|
|
16497
|
+
const offsetDistance = end.leftNormal(start).multiplyScalar(offset);
|
|
16498
16498
|
const startOffPoint = start.clone().add(offsetDistance);
|
|
16499
16499
|
const endOffPoint = end.clone().add(offsetDistance);
|
|
16500
16500
|
return [
|
|
@@ -2,6 +2,14 @@ import { LineSegment } from './LineSegment';
|
|
|
2
2
|
import { Point } from './Point';
|
|
3
3
|
export declare class LineSegmentUtils {
|
|
4
4
|
clone(lines: LineSegment[]): LineSegment<Record<string, any>>[];
|
|
5
|
+
/**保留小数位数
|
|
6
|
+
* @param points
|
|
7
|
+
*/
|
|
8
|
+
static precision(lines: LineSegment[], count: number): LineSegment<Record<string, any>>[];
|
|
9
|
+
/**保留四位小数位数
|
|
10
|
+
* @param points
|
|
11
|
+
*/
|
|
12
|
+
static precision4(lines: LineSegment[]): LineSegment<Record<string, any>>[];
|
|
5
13
|
/** 获取最长线段索引
|
|
6
14
|
* @param lines
|
|
7
15
|
*/
|
|
@@ -28,14 +28,22 @@ export declare class Point<T = Record<string, any>> {
|
|
|
28
28
|
* @param arr
|
|
29
29
|
*/
|
|
30
30
|
setByArray(arr: number[]): this;
|
|
31
|
-
/**
|
|
32
|
-
* multiplyScalar
|
|
31
|
+
/** 乘法
|
|
33
32
|
* @param scalar
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
multiply(point: Point): this;
|
|
36
|
+
/** 乘以一个标量
|
|
37
|
+
* @param scalar
|
|
38
|
+
* @returns
|
|
34
39
|
*/
|
|
35
|
-
mutiplyScalar(scalar: number): this;
|
|
36
40
|
multiplyScalar(scalar: number): this;
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
41
|
+
/** 除法
|
|
42
|
+
* @param scalar
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
division(point: Point): this;
|
|
46
|
+
/** 除一个标量
|
|
39
47
|
* @param scalar
|
|
40
48
|
* @returns
|
|
41
49
|
*/
|
|
@@ -46,14 +54,14 @@ export declare class Point<T = Record<string, any>> {
|
|
|
46
54
|
* @param point
|
|
47
55
|
* @returns
|
|
48
56
|
*/
|
|
49
|
-
|
|
57
|
+
subtract(point: Point): this;
|
|
50
58
|
/**
|
|
51
|
-
*
|
|
59
|
+
* 减一个标量
|
|
52
60
|
* @description 将当前点的坐标减去指定点的坐标
|
|
53
61
|
* @param point
|
|
54
62
|
* @returns
|
|
55
63
|
*/
|
|
56
|
-
|
|
64
|
+
subtractScalar(value: number): this;
|
|
57
65
|
/**
|
|
58
66
|
* 加法
|
|
59
67
|
* @description 将当前点的坐标加上指定点的坐标
|
|
@@ -61,13 +69,31 @@ export declare class Point<T = Record<string, any>> {
|
|
|
61
69
|
* @returns
|
|
62
70
|
*/
|
|
63
71
|
add(point: Point): this;
|
|
64
|
-
/**
|
|
65
|
-
* 加法
|
|
72
|
+
/** 加一个标量
|
|
66
73
|
* @description 将当前点的坐标加上指定点的坐标
|
|
67
74
|
* @param point
|
|
68
75
|
* @returns
|
|
69
76
|
*/
|
|
70
77
|
addScalar(value: number): void;
|
|
78
|
+
/**
|
|
79
|
+
* 加法(不可变)
|
|
80
|
+
* @description 返回当前点与指定点相加后的新点,不修改当前点
|
|
81
|
+
* @param point
|
|
82
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
83
|
+
* @returns 相加后的点
|
|
84
|
+
*/
|
|
85
|
+
added(point: Point, out?: Point<Record<string, any>>): Point<Record<string, any>>;
|
|
86
|
+
/**
|
|
87
|
+
* 减法(不可变)
|
|
88
|
+
* @description 返回当前点减去指定点后的新点,不修改当前点
|
|
89
|
+
* @param point
|
|
90
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
91
|
+
* @returns 相减后的点
|
|
92
|
+
*/
|
|
93
|
+
subtracted(point: Point, out?: Point<Record<string, any>>): Point<Record<string, any>>;
|
|
94
|
+
/** 转为整型
|
|
95
|
+
* @returns
|
|
96
|
+
*/
|
|
71
97
|
parseInt(): this;
|
|
72
98
|
/**
|
|
73
99
|
* 绕point旋转angle
|
|
@@ -78,15 +104,27 @@ export declare class Point<T = Record<string, any>> {
|
|
|
78
104
|
x: number;
|
|
79
105
|
y: number;
|
|
80
106
|
}, angle: number): this;
|
|
107
|
+
/**
|
|
108
|
+
* 旋转(不可变)
|
|
109
|
+
* @description 返回当前点绕指定中心旋转后的新点,不修改当前点
|
|
110
|
+
* @param center 旋转中心
|
|
111
|
+
* @param angle 旋转角度(弧度)
|
|
112
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
113
|
+
* @returns 旋转后的点
|
|
114
|
+
*/
|
|
115
|
+
rotated(center: {
|
|
116
|
+
x: number;
|
|
117
|
+
y: number;
|
|
118
|
+
}, angle: number, out?: Point<Record<string, any>>): Point<Record<string, any>>;
|
|
81
119
|
/**
|
|
82
120
|
* 保留小数位数
|
|
83
121
|
* @param count
|
|
84
122
|
*/
|
|
85
|
-
|
|
86
|
-
/**
|
|
123
|
+
precision(count: number): this;
|
|
124
|
+
/** 保留四位小数
|
|
87
125
|
* @returns
|
|
88
126
|
*/
|
|
89
|
-
|
|
127
|
+
precision4(): this;
|
|
90
128
|
/**
|
|
91
129
|
* 归一化
|
|
92
130
|
* @description 将当前点的坐标归一化为单位向量
|
|
@@ -94,12 +132,19 @@ export declare class Point<T = Record<string, any>> {
|
|
|
94
132
|
*/
|
|
95
133
|
normalize(): this;
|
|
96
134
|
/**
|
|
97
|
-
|
|
135
|
+
* 归一化(不可变)
|
|
136
|
+
* @description 返回当前向量归一化后的新点,不修改当前点
|
|
137
|
+
* @param out 输出对象,用于复用对象减少 GC
|
|
138
|
+
* @returns 单位向量
|
|
139
|
+
*/
|
|
140
|
+
normalized(out?: Point<Record<string, any>>): Point<Record<string, any>>;
|
|
141
|
+
/**
|
|
142
|
+
* 获取单位左法向量
|
|
98
143
|
* @description 计算当前点到指定点的方向向量,并返回逆时针旋转90度后的单位法向量
|
|
99
144
|
* @param point
|
|
100
145
|
* @returns
|
|
101
146
|
*/
|
|
102
|
-
|
|
147
|
+
leftNormal(point: Point): Point<Record<string, any>>;
|
|
103
148
|
/**
|
|
104
149
|
* 获取由传入的点到该点的单位方向向量
|
|
105
150
|
* @description 计算当前点到指定点的方向向量,并返回单位方向
|
|
@@ -176,10 +221,13 @@ export declare class Point<T = Record<string, any>> {
|
|
|
176
221
|
x: number;
|
|
177
222
|
y: number;
|
|
178
223
|
}): this;
|
|
179
|
-
/**
|
|
180
|
-
*
|
|
224
|
+
/** 转为数组
|
|
181
225
|
*/
|
|
182
226
|
toArray(): [number, number];
|
|
227
|
+
/** 转为json
|
|
228
|
+
* @param z
|
|
229
|
+
* @returns
|
|
230
|
+
*/
|
|
183
231
|
toJson(z?: number): {
|
|
184
232
|
x: number;
|
|
185
233
|
y: number;
|
|
@@ -8,7 +8,11 @@ export declare class PointUtils {
|
|
|
8
8
|
/**保留小数位数
|
|
9
9
|
* @param points
|
|
10
10
|
*/
|
|
11
|
-
static
|
|
11
|
+
static precision(points: Point[], count: number): Point<Record<string, any>>[];
|
|
12
|
+
/**保留四位小数位数
|
|
13
|
+
* @param points
|
|
14
|
+
*/
|
|
15
|
+
static precision4(points: Point[]): Point<Record<string, any>>[];
|
|
12
16
|
/** 点吸附
|
|
13
17
|
* @param points
|
|
14
18
|
* @param tolerance
|