build-dxf 0.1.16 → 0.1.17
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
CHANGED
package/src/build.js
CHANGED
|
@@ -1491,7 +1491,7 @@ class LineSegment {
|
|
|
1491
1491
|
const p3 = line.start;
|
|
1492
1492
|
const p4 = line.end;
|
|
1493
1493
|
const denom = (p1.x - p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x - p4.x);
|
|
1494
|
-
if (Math.abs(denom) < 1e-
|
|
1494
|
+
if (Math.abs(denom) < 1e-9) {
|
|
1495
1495
|
return null;
|
|
1496
1496
|
}
|
|
1497
1497
|
const t = ((p1.x - p3.x) * (p3.y - p4.y) - (p1.y - p3.y) * (p3.x - p4.x)) / denom;
|
|
@@ -1896,22 +1896,29 @@ class LineSegment {
|
|
|
1896
1896
|
if (start.point.distance(end.point) < distanceThreshold) return [group2];
|
|
1897
1897
|
const maxList = [...list].sort((a, b) => b.line.length() - a.line.length()), first = maxList[0], second = maxList[1], firstLength = first.line.length(), secondLength = second.line.length(), projLine = first.line.projectLineSegment(second.line), projLineLength = projLine.length();
|
|
1898
1898
|
if (first.point.distance(second.point) > distanceThreshold || secondLength / firstLength > 0.5 && projLineLength / secondLength < 0.5) {
|
|
1899
|
-
const
|
|
1899
|
+
const group12 = [first.line], group222 = [second.line];
|
|
1900
1900
|
for (let i = 0; i < list.length; i++) {
|
|
1901
1901
|
const opt = list[i];
|
|
1902
1902
|
if (opt === first || opt === second) continue;
|
|
1903
1903
|
const currentProjectLine = second.line.projectLineSegment(opt.line), len = currentProjectLine.length();
|
|
1904
|
-
if (second.point.distance(opt.point) <= distanceThreshold && len / secondLength > 0)
|
|
1905
|
-
else
|
|
1904
|
+
if (second.point.distance(opt.point) <= distanceThreshold && len / secondLength > 0) group222.push(opt.line);
|
|
1905
|
+
else group12.push(opt.line);
|
|
1906
1906
|
}
|
|
1907
|
-
return [
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
|
-
for (;
|
|
1911
|
-
const { point: point2 } = list[
|
|
1912
|
-
if (list[0].point.distance(point2)
|
|
1907
|
+
return [group12, group222];
|
|
1908
|
+
}
|
|
1909
|
+
const group1 = [list[0].line], group22 = [], startV = principalAxisStartMap.get(list[0].line) ?? 0, endV = principalAxisEndMap.get(list[0].line) ?? 0, min = startV < endV ? startV : endV, max = startV > endV ? startV : endV;
|
|
1910
|
+
for (let i = 1; i < list.length; i++) {
|
|
1911
|
+
const { point: point2, line } = list[i];
|
|
1912
|
+
if (list[0].point.distance(point2) < distanceThreshold) {
|
|
1913
|
+
const startV2 = principalAxisStartMap.get(line) ?? 0, endV2 = principalAxisEndMap.get(line) ?? 0;
|
|
1914
|
+
if (min <= startV2 && startV2 <= max || min <= endV2 && endV2 <= max) {
|
|
1915
|
+
group1.push(list[i].line);
|
|
1916
|
+
continue;
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
group22.push(list[i].line);
|
|
1913
1920
|
}
|
|
1914
|
-
return [
|
|
1921
|
+
return [group1, group22];
|
|
1915
1922
|
}).flat(1);
|
|
1916
1923
|
return groups;
|
|
1917
1924
|
}
|
|
@@ -3616,7 +3623,7 @@ function clippingDoubleWall(lines) {
|
|
|
3616
3623
|
}
|
|
3617
3624
|
return groups;
|
|
3618
3625
|
}
|
|
3619
|
-
const defaultWallWidth
|
|
3626
|
+
const defaultWallWidth = DEFAULT_WALL_WIDTH;
|
|
3620
3627
|
function doubleWallPoint(grid, line) {
|
|
3621
3628
|
const startList = grid.queryPoint(line.start, true).map((item) => {
|
|
3622
3629
|
if (LineGroupType.hasType(item.userData, "doubleWall")) return "doubleWall";
|
|
@@ -3636,11 +3643,11 @@ function doubleWallPoint(grid, line) {
|
|
|
3636
3643
|
function winDrawLine(line, grid) {
|
|
3637
3644
|
if (line.userData.isWindow && Array.isArray(line.userData.drawWindow)) {
|
|
3638
3645
|
mergeWindow(line);
|
|
3639
|
-
const list = grid && doubleWallPoint(grid, line), dwh = defaultWallWidth
|
|
3646
|
+
const list = grid && doubleWallPoint(grid, line), dwh = defaultWallWidth * 0.5;
|
|
3640
3647
|
return line.userData.drawWindow.map(({ full, width, p, height, groundClearance }) => {
|
|
3641
3648
|
if (full) width = line.length();
|
|
3642
3649
|
const point2 = Point.from(p), direct = line.direction(), winLine = point2.expandAsLine(direct, width).directionMove(direct, -width * 0.5);
|
|
3643
|
-
winLine.userData = { wallWidth: defaultWallWidth
|
|
3650
|
+
winLine.userData = { wallWidth: defaultWallWidth, height, groundClearance };
|
|
3644
3651
|
winLine.start.copy(line.projectPoint(winLine.start, false));
|
|
3645
3652
|
winLine.end.copy(line.projectPoint(winLine.end, false));
|
|
3646
3653
|
if (!list) return winLine;
|
|
@@ -3655,7 +3662,7 @@ function winDrawLine(line, grid) {
|
|
|
3655
3662
|
winLine.endShrink(diff);
|
|
3656
3663
|
}
|
|
3657
3664
|
return winLine;
|
|
3658
|
-
}).filter((line2) => line2.length() > defaultWallWidth
|
|
3665
|
+
}).filter((line2) => line2.length() > defaultWallWidth);
|
|
3659
3666
|
}
|
|
3660
3667
|
return null;
|
|
3661
3668
|
}
|
|
@@ -3680,7 +3687,7 @@ function doubleWinDrawLine(lines) {
|
|
|
3680
3687
|
}
|
|
3681
3688
|
winLine2.userData = { wallWidth, height, groundClearance };
|
|
3682
3689
|
return winLine2;
|
|
3683
|
-
}) ?? []).filter((line) => line.length() > defaultWallWidth
|
|
3690
|
+
}) ?? []).filter((line) => line.length() > defaultWallWidth);
|
|
3684
3691
|
}
|
|
3685
3692
|
function getWinDrawData(doubleWallGroup, wall, lines = []) {
|
|
3686
3693
|
const grid = new PointVirtualGrid();
|
|
@@ -3737,7 +3744,6 @@ class Group {
|
|
|
3737
3744
|
return group2;
|
|
3738
3745
|
}
|
|
3739
3746
|
}
|
|
3740
|
-
const defaultWallWidth = 0.12;
|
|
3741
3747
|
const units = {
|
|
3742
3748
|
Unitless: 1,
|
|
3743
3749
|
// 无单位,1米 = 1(无单位)
|
|
@@ -3807,32 +3813,6 @@ class CAD {
|
|
|
3807
3813
|
this.needUpdate = true;
|
|
3808
3814
|
return groups.map((lines) => this.addGroup(lines, type));
|
|
3809
3815
|
}
|
|
3810
|
-
/** 添加组并执行偏移
|
|
3811
|
-
* @description 使用 ClipperLib 对每个点组进行线偏移处理,生成具有指定宽度的墙体路径
|
|
3812
|
-
*/
|
|
3813
|
-
addGroupByOffset2(lines, joinType = "jtMiter", endType = "etOpenButt", scale = 1e5) {
|
|
3814
|
-
const groups = LineSegment.groupByPoint(lines);
|
|
3815
|
-
const polygons = groups.flatMap((group2) => Polygon.multipleFromByLines(group2));
|
|
3816
|
-
for (let i = 0; i < polygons.length; i++) {
|
|
3817
|
-
const polygon2 = polygons[i];
|
|
3818
|
-
polygon2.forEach((p) => p.multiplyScalar(scale));
|
|
3819
|
-
let solutions = new ClipperLib.Paths();
|
|
3820
|
-
const offset2 = new ClipperLib.ClipperOffset(2, 0.25);
|
|
3821
|
-
offset2.AddPath(
|
|
3822
|
-
polygon2,
|
|
3823
|
-
ClipperLib.JoinType[joinType],
|
|
3824
|
-
ClipperLib.EndType[endType]
|
|
3825
|
-
);
|
|
3826
|
-
offset2.Execute(solutions, defaultWallWidth / 2 * scale);
|
|
3827
|
-
solutions = solutions.map((solution) => solution.map((p) => Point.from(p).multiplyScalar(1 / scale)));
|
|
3828
|
-
solutions.forEach((solution) => {
|
|
3829
|
-
const polygon22 = new Polygon(solution);
|
|
3830
|
-
this.addGroup(polygon22.toLines(true), "groupOffset", { polygon: polygon22 });
|
|
3831
|
-
});
|
|
3832
|
-
}
|
|
3833
|
-
this.needUpdate = true;
|
|
3834
|
-
return this;
|
|
3835
|
-
}
|
|
3836
3816
|
/** 添加组并执行偏移
|
|
3837
3817
|
* @description 使用 ClipperLib 对每个点组进行线偏移处理,生成具有指定宽度的墙体路径
|
|
3838
3818
|
*/
|
|
@@ -3850,7 +3830,7 @@ class CAD {
|
|
|
3850
3830
|
ClipperLib.EndType[endType]
|
|
3851
3831
|
);
|
|
3852
3832
|
}
|
|
3853
|
-
offset2.Execute(solutions,
|
|
3833
|
+
offset2.Execute(solutions, DEFAULT_WALL_WIDTH / 2 * scale);
|
|
3854
3834
|
solutions = solutions.map((solution) => solution.map((p) => Point.from(p).multiplyScalar(1 / scale)));
|
|
3855
3835
|
solutions.forEach((solution) => {
|
|
3856
3836
|
const polygon2 = new Polygon(solution);
|
|
@@ -4283,7 +4263,7 @@ class DxfDrawPlugin {
|
|
|
4283
4263
|
group2.lines.forEach((lineSegment) => {
|
|
4284
4264
|
if (lineSegment.length() < 0.4) return;
|
|
4285
4265
|
const line = lineSegment.clone();
|
|
4286
|
-
const doorThickness =
|
|
4266
|
+
const doorThickness = DEFAULT_WALL_WIDTH * 0.2;
|
|
4287
4267
|
const list = [];
|
|
4288
4268
|
setColor("cyan");
|
|
4289
4269
|
if (line.length() < 1.2) {
|
|
@@ -4303,12 +4283,12 @@ class DxfDrawPlugin {
|
|
|
4303
4283
|
break;
|
|
4304
4284
|
}
|
|
4305
4285
|
}
|
|
4306
|
-
door.expansion(-doorThickness * 0.5).expandToRectangle(
|
|
4286
|
+
door.expansion(-doorThickness * 0.5).expandToRectangle(DEFAULT_WALL_WIDTH * 0.2, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
|
|
4307
4287
|
const a = line.length(), b = door.length(), r = (a ** 2 + b ** 2) / (2 * b), center = door.end.clone().add(door.direction().multiplyScalar(-r)), [startAngle, endAngle] = this.getArcAngleRange(center, line.end, door.end);
|
|
4308
4288
|
drawArc(center, r, Math.min(startAngle, endAngle), Math.max(startAngle, endAngle));
|
|
4309
4289
|
list.push(box);
|
|
4310
4290
|
} else {
|
|
4311
|
-
line.clone().expansion(-
|
|
4291
|
+
line.clone().expansion(-DEFAULT_WALL_WIDTH * 0.5).expandToRectangle(DEFAULT_WALL_WIDTH).path2D((p1, p2) => drawLine(p1, p2));
|
|
4312
4292
|
line.clone().directionMove(line.normal(), doorThickness * 0.5).directionMove(line.direction(), doorThickness * 0.5).expansion(-line.length() * 0.45, "end").forward(doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
4313
4293
|
line.clone().directionMove(line.normal(), -doorThickness * 0.5).directionMove(line.direction(), -doorThickness * 0.5).expansion(-line.length() * 0.45, "start").forward(-doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
|
|
4314
4294
|
}
|
|
@@ -4321,7 +4301,7 @@ class DxfDrawPlugin {
|
|
|
4321
4301
|
setColor("yellow");
|
|
4322
4302
|
group2.lines.forEach((line) => {
|
|
4323
4303
|
drawLine(line.start, line.end);
|
|
4324
|
-
line.expandToRectangle(line?.userData?.wallWidth ??
|
|
4304
|
+
line.expandToRectangle(line?.userData?.wallWidth ?? DEFAULT_WALL_WIDTH, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
|
|
4325
4305
|
});
|
|
4326
4306
|
}
|
|
4327
4307
|
});
|
|
@@ -4330,7 +4310,7 @@ class DxfDrawPlugin {
|
|
|
4330
4310
|
handler({ drawDottedLine, setColor, group: group2 }) {
|
|
4331
4311
|
group2.lines.forEach((line) => {
|
|
4332
4312
|
setColor("yellow");
|
|
4333
|
-
line = line.clone().expansion(-
|
|
4313
|
+
line = line.clone().expansion(-DEFAULT_WALL_WIDTH * 0.5);
|
|
4334
4314
|
drawDottedLine(line.start, line.end);
|
|
4335
4315
|
});
|
|
4336
4316
|
}
|
|
@@ -4368,10 +4348,10 @@ class DxfDataPlugin {
|
|
|
4368
4348
|
doors.forEach((line) => {
|
|
4369
4349
|
const startList = quadtree.queryPoint(line.start).filter((item) => item.line !== line && item.line.vertical(line, 35)), endList = quadtree.queryPoint(line.end).filter((item) => item.line !== line && item.line.vertical(line, 35)), direct = line.direction();
|
|
4370
4350
|
if (startList.length && !startList.some((item) => LineGroupType.hasType(item.line, "doubleWall"))) {
|
|
4371
|
-
line.start.add(direct.clone().multiplyScalar(
|
|
4351
|
+
line.start.add(direct.clone().multiplyScalar(DEFAULT_WALL_WIDTH * 0.5));
|
|
4372
4352
|
}
|
|
4373
4353
|
if (endList.length && !endList.some((item) => LineGroupType.hasType(item.line, "doubleWall"))) {
|
|
4374
|
-
line.end.add(direct.clone().multiplyScalar(-
|
|
4354
|
+
line.end.add(direct.clone().multiplyScalar(-DEFAULT_WALL_WIDTH * 0.5));
|
|
4375
4355
|
}
|
|
4376
4356
|
});
|
|
4377
4357
|
cad.addGroupByOffset(wall);
|
|
@@ -4945,6 +4925,9 @@ class DoubleWallHelper {
|
|
|
4945
4925
|
quadtree
|
|
4946
4926
|
};
|
|
4947
4927
|
}
|
|
4928
|
+
// static findDoubleLine2( lines: LineSegment<LineUserData>[], wallWidth = 0.4 ) {
|
|
4929
|
+
// // LineSegment.groupByAxis()
|
|
4930
|
+
// }
|
|
4948
4931
|
/**
|
|
4949
4932
|
* @param lines
|
|
4950
4933
|
* @param wallWidth
|
|
@@ -5008,42 +4991,44 @@ class DoubleWallHelper {
|
|
|
5008
4991
|
quadtree.clear();
|
|
5009
4992
|
return lines;
|
|
5010
4993
|
}
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
line.
|
|
4994
|
+
/**
|
|
4995
|
+
* 创建分组
|
|
4996
|
+
*/
|
|
4997
|
+
static buildGroup(lineSegments) {
|
|
4998
|
+
const doors = [];
|
|
4999
|
+
lineSegments = lineSegments.filter((line) => {
|
|
5000
|
+
if (line.userData.isDoor) {
|
|
5001
|
+
doors.push(line);
|
|
5002
|
+
return false;
|
|
5003
|
+
}
|
|
5004
|
+
return true;
|
|
5018
5005
|
});
|
|
5006
|
+
lineSegments = buildDoubleWallGroup(lineSegments);
|
|
5007
|
+
lineSegments = this.complementSide(lineSegments);
|
|
5008
|
+
lineSegments = buildDoubleWallGroup(lineSegments, doors, true, true);
|
|
5009
|
+
return [...lineSegments, ...doors];
|
|
5019
5010
|
}
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5011
|
+
}
|
|
5012
|
+
function shortDistanceLink(lines, radius = 0.1) {
|
|
5013
|
+
const dpLines = [...findDiscretePointLine2(lines.filter((line) => !line.userData.isDoor), void 0, false)], pointVirtualGrid = createPointVirtualGrid(dpLines), appendLines = [], visited = /* @__PURE__ */ new Set();
|
|
5014
|
+
const getWeight2 = (target, point2, line) => {
|
|
5015
|
+
if (target.weight) return target.weight;
|
|
5016
|
+
const targetLine = target.userData, targetPoint = target.point;
|
|
5017
|
+
const direct1 = line.getAnotherPoint(point2).direction(point2), direct2 = targetLine.getAnotherPoint(targetPoint).direction(targetPoint), direct3 = targetPoint.direction(point2), angle = direct1.angleBetween(direct2), angle2 = direct1.angleBetween(direct3), length = point2.distance(target.point), weight = 1 - length / radius + angle / Math.PI * 1.2 + (1 - angle2 / Math.PI) * 1.2;
|
|
5018
|
+
target.weight = weight;
|
|
5019
|
+
return weight;
|
|
5020
|
+
};
|
|
5021
|
+
for (let i = 0; i < dpLines.length; i++) {
|
|
5022
|
+
const line = dpLines[i];
|
|
5023
5023
|
if (line.userData.isDoor) continue;
|
|
5024
5024
|
line.points.forEach((point2) => {
|
|
5025
5025
|
if (visited.has(point2)) return false;
|
|
5026
|
-
|
|
5027
|
-
const list = pointVirtualGrid.queryCircle(point2, radius).filter((item) => {
|
|
5028
|
-
if (visited.has(item.point)) return false;
|
|
5029
|
-
const resLine = item.userData;
|
|
5030
|
-
if (resLine === line || !line.parallel(resLine, 25)) return false;
|
|
5031
|
-
if (pointVirtualGrid.queryPoint(item.point).length > 1) return false;
|
|
5032
|
-
const distance = point2.distance(item.point);
|
|
5033
|
-
if (distance < 1e-3) return false;
|
|
5034
|
-
const direct1 = point2.direction(line.getAnotherPoint(point2)), direct2 = item.point.direction(resLine.getAnotherPoint(item.point));
|
|
5035
|
-
if (180 - direct1.angleBetween(direct2, "angle") < 25) {
|
|
5036
|
-
distanceMap.set(item.point, distance);
|
|
5037
|
-
return true;
|
|
5038
|
-
}
|
|
5039
|
-
}).sort((a, b) => {
|
|
5040
|
-
const aDistance = distanceMap.get(a.point), bDistance = distanceMap.get(b.point);
|
|
5041
|
-
return aDistance - bDistance;
|
|
5042
|
-
});
|
|
5026
|
+
const list = pointVirtualGrid.queryCircle(point2, radius, true).map((item) => Object.assign({}, item)).sort((a, b) => getWeight2(b, point2, line) - getWeight2(a, point2, line));
|
|
5043
5027
|
if (list.length === 0) return;
|
|
5044
|
-
|
|
5045
|
-
visited.add(list[0].point);
|
|
5028
|
+
const { point: targetPoint } = list[0];
|
|
5046
5029
|
const targetLine = list[0].userData;
|
|
5030
|
+
visited.add(point2);
|
|
5031
|
+
visited.add(targetPoint);
|
|
5047
5032
|
const projectLine1 = line.projectLineSegment(targetLine), projectLine2 = targetLine.projectLineSegment(line), len1 = projectLine1.length(), len2 = projectLine2.length();
|
|
5048
5033
|
if (len1 === 0 && len2 === 0) appendLines.push(new LineSegment(point2.clone(), list[0].point.clone()));
|
|
5049
5034
|
else appendLines.push(new LineSegment(projectLine1.center, projectLine2.center));
|
|
@@ -5068,7 +5053,7 @@ function preprocessing(lines) {
|
|
|
5068
5053
|
if (endIntersection.length) door.userData.endIntersection = endIntersection[0].userData;
|
|
5069
5054
|
else door.userData.endIntersection = quadtree.queryPoint(door.end)[0]?.line;
|
|
5070
5055
|
});
|
|
5071
|
-
lines = shortDistanceLink(lines, 0.4
|
|
5056
|
+
lines = shortDistanceLink(lines, 0.4);
|
|
5072
5057
|
pointVirtualGrid.clear();
|
|
5073
5058
|
quadtree.clear();
|
|
5074
5059
|
return lines;
|
|
@@ -5172,170 +5157,12 @@ function correction$1(targettLine, lines, intersectMap, errAngle = 15) {
|
|
|
5172
5157
|
delayList.forEach((fun) => fun());
|
|
5173
5158
|
return { parallelLines, verticalLines, doorLines, windowLines };
|
|
5174
5159
|
}
|
|
5175
|
-
function
|
|
5176
|
-
const
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
projectPoints.push(point2);
|
|
5182
|
-
crossAxisMap.set(line, point2);
|
|
5183
|
-
}
|
|
5184
|
-
});
|
|
5185
|
-
projectPoints.sort((a, b) => {
|
|
5186
|
-
return b.distance(crossAxis.start) - a.distance(crossAxis.start);
|
|
5187
|
-
});
|
|
5188
|
-
const groups = [], group2 = [];
|
|
5189
|
-
for (let i = 0; i < projectPoints.length; i++) {
|
|
5190
|
-
const point2 = projectPoints[i];
|
|
5191
|
-
if (i === 0) {
|
|
5192
|
-
group2.push(point2);
|
|
5193
|
-
continue;
|
|
5194
|
-
}
|
|
5195
|
-
const prePoint = projectPoints[i - 1];
|
|
5196
|
-
if (prePoint.distance(point2) < crossAxistThreshold) group2.push(point2);
|
|
5197
|
-
else {
|
|
5198
|
-
groups.push([...group2]);
|
|
5199
|
-
group2.length = 0;
|
|
5200
|
-
group2.push(point2);
|
|
5201
|
-
}
|
|
5202
|
-
if (i === projectPoints.length - 1) groups.push(group2);
|
|
5203
|
-
}
|
|
5204
|
-
return groups.flatMap((group3) => {
|
|
5205
|
-
const points = group3.flatMap((point2) => {
|
|
5206
|
-
const line = point2.userData;
|
|
5207
|
-
return line.points.map((p) => {
|
|
5208
|
-
const point22 = principalAxis.projectPoint(p, false);
|
|
5209
|
-
point22.userData = line;
|
|
5210
|
-
return point22;
|
|
5211
|
-
});
|
|
5212
|
-
});
|
|
5213
|
-
points.sort((a, b) => {
|
|
5214
|
-
return a.distance(principalAxis.start) - b.distance(principalAxis.start);
|
|
5215
|
-
});
|
|
5216
|
-
const map = /* @__PURE__ */ new Map(), newGroup = [];
|
|
5217
|
-
let newGroups = [];
|
|
5218
|
-
points.forEach((point2, i) => {
|
|
5219
|
-
if (map.size === 0 && i > 0) {
|
|
5220
|
-
const prePoint = points[i - 1];
|
|
5221
|
-
if (prePoint.distance(point2) > principalAxisThreshold) {
|
|
5222
|
-
newGroups.push([...newGroup]);
|
|
5223
|
-
newGroup.length = 0;
|
|
5224
|
-
}
|
|
5225
|
-
}
|
|
5226
|
-
map.set(point2.userData, (map.get(point2.userData) ?? 0) + 1);
|
|
5227
|
-
for (const v of map.values()) if (v !== 2) return;
|
|
5228
|
-
newGroup.push(...map.keys());
|
|
5229
|
-
map.clear();
|
|
5230
|
-
});
|
|
5231
|
-
newGroups.push([...newGroup]);
|
|
5232
|
-
return newGroups;
|
|
5233
|
-
});
|
|
5234
|
-
}
|
|
5235
|
-
function groupByCrossAxis(lines, principalAxis, crossAxis, crossAxistThreshold) {
|
|
5236
|
-
const crossAxisMap = /* @__PURE__ */ new Map(), crossValueList = [], principalAxisStartMap = /* @__PURE__ */ new Map(), principalAxisEndMap = /* @__PURE__ */ new Map();
|
|
5237
|
-
lines.forEach((line) => {
|
|
5238
|
-
const value = crossAxis.projectValue(line.start);
|
|
5239
|
-
const point2 = crossAxis.projectPoint(line.start, false);
|
|
5240
|
-
const opt = { value, line, point: point2, index: -1 };
|
|
5241
|
-
crossAxisMap.set(line, opt);
|
|
5242
|
-
crossValueList.push(opt);
|
|
5243
|
-
line.points.forEach((p, i) => {
|
|
5244
|
-
const value2 = principalAxis.projectValue(p);
|
|
5245
|
-
if (i === 0) principalAxisStartMap.set(line, value2);
|
|
5246
|
-
else principalAxisEndMap.set(line, value2);
|
|
5247
|
-
});
|
|
5248
|
-
});
|
|
5249
|
-
crossValueList.sort((a, b) => b.value - a.value).forEach((item, i) => item.index = i);
|
|
5250
|
-
const unionFindSet = new UnionFindSet(lines.length), lineIndexGenerator = new LineIndexGenerator(lines);
|
|
5251
|
-
function approach(preCrossOpt, crossOpt) {
|
|
5252
|
-
return preCrossOpt.point.distance(crossOpt.point) <= crossAxistThreshold;
|
|
5253
|
-
}
|
|
5254
|
-
function coincide(preCrossOpt, minPrinValue, maxPrinValue) {
|
|
5255
|
-
const prePrinStartV = principalAxisStartMap.get(preCrossOpt.line), prePrinEndV = principalAxisEndMap.get(preCrossOpt.line), minPrePrinValue = prePrinStartV < prePrinEndV ? prePrinStartV : prePrinEndV, maxPrePrinValue = prePrinStartV > prePrinEndV ? prePrinStartV : prePrinEndV;
|
|
5256
|
-
return minPrePrinValue >= minPrinValue && minPrePrinValue <= maxPrinValue || maxPrePrinValue >= minPrinValue && maxPrePrinValue <= maxPrinValue || minPrinValue >= minPrePrinValue && minPrinValue <= maxPrePrinValue || maxPrinValue >= minPrePrinValue && maxPrinValue <= maxPrePrinValue;
|
|
5257
|
-
}
|
|
5258
|
-
for (let i = 0; i < crossValueList.length; i++) {
|
|
5259
|
-
const crossOpt = crossValueList[i], { line } = crossOpt, prinStartV = principalAxisStartMap.get(line), prinEndV = principalAxisEndMap.get(line), minPrinValue = prinStartV < prinEndV ? prinStartV : prinEndV, maxPrinValue = prinStartV > prinEndV ? prinStartV : prinEndV;
|
|
5260
|
-
for (let j = i - 1; j >= 0; j--) {
|
|
5261
|
-
const pre = crossValueList[j];
|
|
5262
|
-
if (approach(pre, crossOpt)) {
|
|
5263
|
-
if (coincide(pre, minPrinValue, maxPrinValue)) {
|
|
5264
|
-
unionFindSet.union(lineIndexGenerator.getIndex(line), lineIndexGenerator.getIndex(pre.line));
|
|
5265
|
-
break;
|
|
5266
|
-
}
|
|
5267
|
-
} else break;
|
|
5268
|
-
}
|
|
5269
|
-
}
|
|
5270
|
-
let groups = unionFindSet.getAllSets().valueArray.map((group2) => group2.map((index2) => lineIndexGenerator.getLine(index2)));
|
|
5271
|
-
groups = groups.map((group2) => {
|
|
5272
|
-
if (group2.length <= 2) return [group2];
|
|
5273
|
-
const list = group2.map((line) => crossAxisMap.get(line)).sort((a, b) => a.value - b.value), start = list[0], end = list[list.length - 1];
|
|
5274
|
-
if (start.point.distance(end.point) < crossAxistThreshold) return [group2];
|
|
5275
|
-
const maxList = [...list].sort((a, b) => b.line.length() - a.line.length()), first = maxList[0], second = maxList[0], firstLength = first.line.length(), secondLength = second.line.length(), projLine = first.line.projectLineSegment(second.line), projLineLength = projLine.length();
|
|
5276
|
-
if (first.point.distance(second.point) > crossAxistThreshold || secondLength / firstLength > 0.5 && projLineLength / secondLength < 0.5) {
|
|
5277
|
-
const group1 = [first.line], group22 = [second.line];
|
|
5278
|
-
for (let i = 0; i < list.length; i++) {
|
|
5279
|
-
const opt = list[i];
|
|
5280
|
-
if (opt === first || opt === second) continue;
|
|
5281
|
-
const currentProjectLine = second.line.projectLineSegment(opt.line), len = currentProjectLine.length();
|
|
5282
|
-
if (second.point.distance(opt.point) <= crossAxistThreshold && len / secondLength > 0) group22.push(opt.line);
|
|
5283
|
-
else group1.push(opt.line);
|
|
5284
|
-
}
|
|
5285
|
-
return [group1, group22];
|
|
5286
|
-
}
|
|
5287
|
-
let index2 = 1;
|
|
5288
|
-
for (; index2 < list.length; index2++) {
|
|
5289
|
-
const { point: point2 } = list[index2];
|
|
5290
|
-
if (list[0].point.distance(point2) > crossAxistThreshold) break;
|
|
5291
|
-
}
|
|
5292
|
-
return [list.slice(0, index2).map((o) => o.line), list.slice(index2).map((o) => o.line)];
|
|
5293
|
-
}).flat(1);
|
|
5294
|
-
return groups;
|
|
5295
|
-
}
|
|
5296
|
-
function groupByAxisByintersect(lines, intersectionPointInfoMap) {
|
|
5297
|
-
function dfs(line, group2 = /* @__PURE__ */ new Set()) {
|
|
5298
|
-
if (group2.has(line)) return group2;
|
|
5299
|
-
group2.add(line);
|
|
5300
|
-
const infoList = intersectionPointInfoMap.get(line);
|
|
5301
|
-
if (!infoList) return group2;
|
|
5302
|
-
for (let i = 0; i < infoList.length; i++) {
|
|
5303
|
-
const { line: line2, angle } = infoList[i];
|
|
5304
|
-
if (line2.parallel(angle, 0.5)) dfs(line2, group2);
|
|
5305
|
-
}
|
|
5306
|
-
return group2;
|
|
5307
|
-
}
|
|
5308
|
-
const visited = /* @__PURE__ */ new Set(), groups = [];
|
|
5309
|
-
for (let i = 0; i < lines.length; i++) {
|
|
5310
|
-
const line = lines[i];
|
|
5311
|
-
if (visited.has(line)) continue;
|
|
5312
|
-
const group2 = dfs(line);
|
|
5313
|
-
groups.push([...group2]);
|
|
5314
|
-
}
|
|
5315
|
-
return groups;
|
|
5316
|
-
}
|
|
5317
|
-
function group(parallelLines, verticalLines, xAxisLine, yAxisLine2, intersectionPointInfoMap, option) {
|
|
5318
|
-
const {
|
|
5319
|
-
principalAxisThreshold = 0.3,
|
|
5320
|
-
crossAxistThreshold = 0.08,
|
|
5321
|
-
groupMethod = "principalAndCross"
|
|
5322
|
-
} = option ?? {};
|
|
5323
|
-
const methods = {
|
|
5324
|
-
cross: () => [
|
|
5325
|
-
...groupByCrossAxis(parallelLines, yAxisLine2, xAxisLine, crossAxistThreshold),
|
|
5326
|
-
...groupByCrossAxis(verticalLines, xAxisLine, yAxisLine2, crossAxistThreshold)
|
|
5327
|
-
],
|
|
5328
|
-
principalAndCross: () => [
|
|
5329
|
-
...groupByAxis(parallelLines, yAxisLine2, xAxisLine, principalAxisThreshold, crossAxistThreshold),
|
|
5330
|
-
...groupByAxis(verticalLines, xAxisLine, yAxisLine2, principalAxisThreshold, crossAxistThreshold)
|
|
5331
|
-
],
|
|
5332
|
-
originalInterPoint: () => [
|
|
5333
|
-
...groupByAxisByintersect(parallelLines, intersectionPointInfoMap),
|
|
5334
|
-
...groupByAxisByintersect(verticalLines, intersectionPointInfoMap)
|
|
5335
|
-
]
|
|
5336
|
-
};
|
|
5337
|
-
if (methods[groupMethod]) return methods[groupMethod]();
|
|
5338
|
-
return methods.originalInterPoint();
|
|
5160
|
+
function group(parallelLines, verticalLines, xAxisLine, yAxisLine2, option) {
|
|
5161
|
+
const { crossAxistThreshold = 0.08 } = option ?? {};
|
|
5162
|
+
return [
|
|
5163
|
+
...LineSegment.groupByCrossAxis(parallelLines, xAxisLine, crossAxistThreshold),
|
|
5164
|
+
...LineSegment.groupByCrossAxis(verticalLines, yAxisLine2, crossAxistThreshold)
|
|
5165
|
+
];
|
|
5339
5166
|
}
|
|
5340
5167
|
function removeGroupLinkLine(groups, intersectmap) {
|
|
5341
5168
|
const removeSet = /* @__PURE__ */ new Set();
|
|
@@ -5602,7 +5429,7 @@ class AxisAlignCorr {
|
|
|
5602
5429
|
center.clone().add(direction.clone().multiplyScalar(-1e3)),
|
|
5603
5430
|
center.clone().add(direction.clone().multiplyScalar(1e3))
|
|
5604
5431
|
);
|
|
5605
|
-
let groups = group(parallelLines, verticalLines, xAxisLine, yAxisLine2,
|
|
5432
|
+
let groups = group(parallelLines, verticalLines, xAxisLine, yAxisLine2, option);
|
|
5606
5433
|
groups = removeGroupLinkLine(groups, intersectionMap);
|
|
5607
5434
|
let newLines = lineSegmentFitting(groups, 0.1, option);
|
|
5608
5435
|
newLines = LineSegment.brokenLineMerging(newLines, mergeLineUserData);
|
|
@@ -5648,20 +5475,6 @@ function originalDataToLineData(data) {
|
|
|
5648
5475
|
verticalReferenceIndex
|
|
5649
5476
|
};
|
|
5650
5477
|
}
|
|
5651
|
-
function createGroup$1(lineSegments) {
|
|
5652
|
-
const doors = [];
|
|
5653
|
-
lineSegments = lineSegments.filter((line) => {
|
|
5654
|
-
if (line.userData.isDoor) {
|
|
5655
|
-
doors.push(line);
|
|
5656
|
-
return false;
|
|
5657
|
-
}
|
|
5658
|
-
return true;
|
|
5659
|
-
});
|
|
5660
|
-
lineSegments = buildDoubleWallGroup(lineSegments);
|
|
5661
|
-
lineSegments = DoubleWallHelper.complementSide(lineSegments);
|
|
5662
|
-
lineSegments = buildDoubleWallGroup(lineSegments, doors, true, true);
|
|
5663
|
-
return [...lineSegments, ...doors];
|
|
5664
|
-
}
|
|
5665
5478
|
function getIntersection(line, mode, cell) {
|
|
5666
5479
|
return cell.reduce((list, item, i) => {
|
|
5667
5480
|
const currentLine = item.userData;
|
|
@@ -5716,6 +5529,7 @@ function correction(line, wallWidth = 0.12, appendLines, grid, quadtree) {
|
|
|
5716
5529
|
if (line.userData.isDoor) return quadtree.update(line);
|
|
5717
5530
|
if (!doorIntersection.length) return;
|
|
5718
5531
|
doorIntersection.forEach(({ line: doorLine }) => {
|
|
5532
|
+
if (line.parallel(doorLine, 25)) return;
|
|
5719
5533
|
const interPoint = line.getIntersection(doorLine);
|
|
5720
5534
|
if (!interPoint) return;
|
|
5721
5535
|
if (doorLine.start.distance(interPoint) < doorLine.end.distance(interPoint)) {
|
|
@@ -5794,7 +5608,7 @@ class BoundExt {
|
|
|
5794
5608
|
*/
|
|
5795
5609
|
static boundExtbyTraj(opt) {
|
|
5796
5610
|
let { lines, trajectory, wallWidth = 0.12, updateDoubleWallGroup = false, findCallBack } = opt;
|
|
5797
|
-
if (updateDoubleWallGroup) lines =
|
|
5611
|
+
if (updateDoubleWallGroup) lines = DoubleWallHelper.buildGroup(lines);
|
|
5798
5612
|
const trajectoryPoints = Object.keys(trajectory).map((key) => Point.from(trajectory[key]));
|
|
5799
5613
|
const findLines = BoundExt.findExtWallByTraj(lines, trajectoryPoints);
|
|
5800
5614
|
let exteriorLines = findLines.filter((line) => line.userData.expandDirect);
|
|
@@ -5814,22 +5628,8 @@ class BoundExt {
|
|
|
5814
5628
|
};
|
|
5815
5629
|
}
|
|
5816
5630
|
}
|
|
5817
|
-
function createGroup(lineSegments) {
|
|
5818
|
-
const doors = [];
|
|
5819
|
-
lineSegments = lineSegments.filter((line) => {
|
|
5820
|
-
if (line.userData.isDoor) {
|
|
5821
|
-
doors.push(line);
|
|
5822
|
-
return false;
|
|
5823
|
-
}
|
|
5824
|
-
return true;
|
|
5825
|
-
});
|
|
5826
|
-
lineSegments = buildDoubleWallGroup(lineSegments);
|
|
5827
|
-
lineSegments = DoubleWallHelper.complementSide(lineSegments);
|
|
5828
|
-
lineSegments = buildDoubleWallGroup(lineSegments, doors, true, true);
|
|
5829
|
-
return [...lineSegments, ...doors];
|
|
5830
|
-
}
|
|
5831
5631
|
function getGroups(lines, updateGroup = true) {
|
|
5832
|
-
if (updateGroup) lines =
|
|
5632
|
+
if (updateGroup) lines = DoubleWallHelper.buildGroup(lines);
|
|
5833
5633
|
const map = lines.reduce((map2, line) => {
|
|
5834
5634
|
const groups = LineGroupType.get(line);
|
|
5835
5635
|
groups.forEach((group2) => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {
|
|
2
|
+
url: string;
|
|
3
|
+
type?: string | undefined;
|
|
4
|
+
$props: {
|
|
5
|
+
readonly url?: string | undefined;
|
|
6
|
+
readonly type?: string | undefined;
|
|
7
|
+
};
|
|
8
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
|
|
9
|
+
container: HTMLDivElement;
|
|
10
|
+
}, HTMLDivElement>;
|
|
11
|
+
export default _default;
|
|
@@ -62,10 +62,6 @@ export declare class CAD {
|
|
|
62
62
|
* @param type
|
|
63
63
|
*/
|
|
64
64
|
addGroups(groups: LineSegmentType[][], type?: string): Group[];
|
|
65
|
-
/** 添加组并执行偏移
|
|
66
|
-
* @description 使用 ClipperLib 对每个点组进行线偏移处理,生成具有指定宽度的墙体路径
|
|
67
|
-
*/
|
|
68
|
-
addGroupByOffset2(lines: LineSegmentType[], joinType?: JoinType, endType?: EndType, scale?: number): this;
|
|
69
65
|
/** 添加组并执行偏移
|
|
70
66
|
* @description 使用 ClipperLib 对每个点组进行线偏移处理,生成具有指定宽度的墙体路径
|
|
71
67
|
*/
|
|
@@ -29,5 +29,9 @@ export declare class DoubleWallHelper {
|
|
|
29
29
|
* @returns
|
|
30
30
|
*/
|
|
31
31
|
static complementSide(lines: LineSegment<LineUserData>[], wallWidth?: number): LineSegment<LineUserData>[];
|
|
32
|
+
/**
|
|
33
|
+
* 创建分组
|
|
34
|
+
*/
|
|
35
|
+
static buildGroup(lineSegments: LineSegment<LineUserData>[]): (LineSegment<Record<string, any>> | LineSegment<LineUserData>)[];
|
|
32
36
|
}
|
|
33
37
|
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
type ValueType = "number" | "boolean" | "vec2" | "vec3" | "vec4" | "mat3x3" | "mat4x4";
|
|
2
|
+
type OptionType = {
|
|
3
|
+
workgroup_size?: [number, number, number];
|
|
4
|
+
structName?: string;
|
|
5
|
+
dataName?: string;
|
|
6
|
+
globalInvocationIdName?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare class GpuComputed {
|
|
9
|
+
constructor();
|
|
10
|
+
getDevice(): Promise<{
|
|
11
|
+
adapter: GPUAdapter | null;
|
|
12
|
+
device: GPUDevice;
|
|
13
|
+
groupLayout: GPUBindGroupLayout;
|
|
14
|
+
}>;
|
|
15
|
+
createPipleline(code: string, buffer: Float32Array<ArrayBuffer>): Promise<void>;
|
|
16
|
+
buildBuffer(data: Record<string, any>[], keys?: string[], types?: ValueType[]): {
|
|
17
|
+
buffer: number[];
|
|
18
|
+
stride: number;
|
|
19
|
+
layout: {
|
|
20
|
+
name: string;
|
|
21
|
+
type: ValueType;
|
|
22
|
+
offset: number;
|
|
23
|
+
size: number;
|
|
24
|
+
}[];
|
|
25
|
+
count: number;
|
|
26
|
+
};
|
|
27
|
+
private buildCode;
|
|
28
|
+
computed(data: any[], code: string, option?: OptionType): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export {};
|