build-dxf 0.0.17 → 0.0.19-1
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/README.md +30 -0
- package/package.json +1 -1
- package/src/build.d.ts +10 -1
- package/src/build.js +556 -450
- package/src/components/Editor.vue.d.ts +26 -0
- package/src/index.js +3 -2
- package/src/index2.js +373 -3426
- package/src/index3.js +1937 -0
- package/src/pages/Editor.vue.d.ts +2 -0
- package/src/pages/Editor02.vue.d.ts +4 -0
- package/src/selectLocalFile.js +3745 -0
- package/src/utils/CommandManager/CommandFlow.d.ts +23 -0
- package/src/utils/CommandManager/CommandManager.d.ts +59 -0
- package/src/utils/CommandManager/index.d.ts +2 -0
- package/src/utils/ComponentManager/EventDispatcher.d.ts +11 -1
- package/src/utils/DxfSystem/components/Dxf.d.ts +15 -12
- package/src/utils/DxfSystem/components/LineAnalysis.d.ts +5 -21
- package/src/utils/DxfSystem/components/Variable.d.ts +8 -0
- package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/CommandFlowComponent.d.ts +36 -0
- package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/Default.d.ts +57 -0
- package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawDoorLine.d.ts +19 -0
- package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawLine.d.ts +20 -0
- package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawWindow.d.ts +25 -0
- package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/PointDrag.d.ts +27 -0
- package/src/utils/DxfSystem/plugin/Editor/components/Editor.d.ts +22 -3
- package/src/utils/DxfSystem/plugin/Editor/components/RenderManager.d.ts +88 -0
- package/src/utils/DxfSystem/plugin/Editor/components/index.d.ts +6 -0
- package/src/utils/DxfSystem/plugin/Editor/pages/EditorTool.vue.d.ts +6 -0
- package/src/utils/DxfSystem/plugin/ModelDataPlugin/components/DxfLineModel.d.ts +7 -3
- package/src/utils/DxfSystem/plugin/ModelDataPlugin/index.d.ts +9 -1
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/DomContainer.d.ts +1 -0
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/DomEventRegister.d.ts +20 -1
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/EventInput.d.ts +74 -0
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/Renderer.d.ts +0 -11
- package/src/utils/DxfSystem/plugin/RenderPlugin/components/index.d.ts +1 -0
- package/src/utils/DxfSystem/plugin/RenderPlugin/index.d.ts +11 -1
- package/src/utils/PointVirtualGrid/index.d.ts +10 -4
- package/src/utils/Quadtree/Box2.d.ts +3 -2
- package/src/utils/Quadtree/LineSegment.d.ts +11 -9
- package/src/utils/Quadtree/Point.d.ts +11 -6
- package/src/utils/Quadtree/Quadtree.d.ts +5 -0
- package/src/utils/Quadtree/Rectangle.d.ts +5 -4
package/src/build.js
CHANGED
|
@@ -12,6 +12,35 @@ function uuid() {
|
|
|
12
12
|
}
|
|
13
13
|
class EventDispatcher extends EventDispatcher$1 {
|
|
14
14
|
uuid = uuid();
|
|
15
|
+
addEventListener(type, listener, option) {
|
|
16
|
+
const { once = false } = option ?? {};
|
|
17
|
+
const callBack = (event) => {
|
|
18
|
+
listener(event);
|
|
19
|
+
once && canceCallBack();
|
|
20
|
+
};
|
|
21
|
+
const canceCallBack = () => this.removeEventListener(type, callBack);
|
|
22
|
+
super.addEventListener(type, callBack);
|
|
23
|
+
return canceCallBack;
|
|
24
|
+
}
|
|
25
|
+
eventRecordStack = /* @__PURE__ */ new Map();
|
|
26
|
+
addEventRecord(name, ...cancels) {
|
|
27
|
+
if (!this.eventRecordStack.has(name)) this.eventRecordStack.set(name, []);
|
|
28
|
+
cancels.forEach((cancel) => {
|
|
29
|
+
this.eventRecordStack.get(name)?.push(cancel);
|
|
30
|
+
});
|
|
31
|
+
const add = (cancel) => {
|
|
32
|
+
this.addEventRecord(name, cancel);
|
|
33
|
+
return { add };
|
|
34
|
+
};
|
|
35
|
+
return { add };
|
|
36
|
+
}
|
|
37
|
+
canceEventRecord(name) {
|
|
38
|
+
const list = this.eventRecordStack.get(name);
|
|
39
|
+
if (list) {
|
|
40
|
+
list.forEach((cancel) => cancel());
|
|
41
|
+
this.eventRecordStack.delete(name);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
15
44
|
}
|
|
16
45
|
class Component extends EventDispatcher {
|
|
17
46
|
parent;
|
|
@@ -119,6 +148,7 @@ class Point {
|
|
|
119
148
|
get Y() {
|
|
120
149
|
return this.y;
|
|
121
150
|
}
|
|
151
|
+
userData = {};
|
|
122
152
|
/**
|
|
123
153
|
*
|
|
124
154
|
* @param x
|
|
@@ -333,6 +363,12 @@ class Point {
|
|
|
333
363
|
this.x = p.x ?? 0;
|
|
334
364
|
this.y = p.y ?? 0;
|
|
335
365
|
}
|
|
366
|
+
toJson() {
|
|
367
|
+
return {
|
|
368
|
+
x: this.x,
|
|
369
|
+
y: this.y
|
|
370
|
+
};
|
|
371
|
+
}
|
|
336
372
|
static from(arr) {
|
|
337
373
|
if (Array.isArray(arr)) {
|
|
338
374
|
return new Point(arr[0], arr[1]);
|
|
@@ -564,12 +600,19 @@ class Box2 {
|
|
|
564
600
|
this.maxY *= scalar;
|
|
565
601
|
return this;
|
|
566
602
|
}
|
|
603
|
+
expansion(w) {
|
|
604
|
+
this.minX -= w;
|
|
605
|
+
this.minY -= w;
|
|
606
|
+
this.maxX += w;
|
|
607
|
+
this.maxY += w;
|
|
608
|
+
return this;
|
|
609
|
+
}
|
|
567
610
|
/**
|
|
568
611
|
*
|
|
569
612
|
* @returns
|
|
570
613
|
*/
|
|
571
614
|
clone() {
|
|
572
|
-
return new Box2(this.minX, this.
|
|
615
|
+
return new Box2(this.minX, this.maxX, this.minY, this.maxY);
|
|
573
616
|
}
|
|
574
617
|
/**
|
|
575
618
|
*
|
|
@@ -617,6 +660,16 @@ class Rectangle {
|
|
|
617
660
|
return [p.x, p.y, np.x, np.y];
|
|
618
661
|
});
|
|
619
662
|
}
|
|
663
|
+
createGeometry() {
|
|
664
|
+
return [
|
|
665
|
+
this.p0,
|
|
666
|
+
this.p2,
|
|
667
|
+
this.p1,
|
|
668
|
+
this.p2,
|
|
669
|
+
this.p0,
|
|
670
|
+
this.p3
|
|
671
|
+
].flatMap((p) => [p.x, p.y, 0]);
|
|
672
|
+
}
|
|
620
673
|
constructor(points) {
|
|
621
674
|
if (points.length !== 4) {
|
|
622
675
|
throw new Error("Rectangle must be defined by exactly 4 points");
|
|
@@ -781,6 +834,7 @@ class Rectangle {
|
|
|
781
834
|
class LineSegment {
|
|
782
835
|
points = [new Point(), new Point()];
|
|
783
836
|
userData = {};
|
|
837
|
+
line;
|
|
784
838
|
get center() {
|
|
785
839
|
return new Point(
|
|
786
840
|
this.points[0].x + (this.points[1].x - this.points[0].x) * 0.5,
|
|
@@ -937,11 +991,12 @@ class LineSegment {
|
|
|
937
991
|
return new LineSegment(projP1, projP2);
|
|
938
992
|
}
|
|
939
993
|
/**
|
|
940
|
-
*
|
|
941
|
-
* @param
|
|
994
|
+
* 计算一条线段在另一条直线上的投影
|
|
995
|
+
* @param p1 要投影的点
|
|
996
|
+
* @param clip 是否裁剪超出目标线段的部分,默认裁剪
|
|
942
997
|
* @returns 投影并裁剪后的线段
|
|
943
998
|
*/
|
|
944
|
-
projectPoint(p1) {
|
|
999
|
+
projectPoint(p1, clip = true) {
|
|
945
1000
|
const [q1, q2] = this.points;
|
|
946
1001
|
const dir = new Point(q2.x - q1.x, q2.y - q1.y);
|
|
947
1002
|
if (dir.x === 0 && dir.y === 0) {
|
|
@@ -957,6 +1012,7 @@ class LineSegment {
|
|
|
957
1012
|
return new Point(projX, projY);
|
|
958
1013
|
};
|
|
959
1014
|
let projP1 = projectPoint(p1);
|
|
1015
|
+
if (!clip) return projP1;
|
|
960
1016
|
const getT = (point) => {
|
|
961
1017
|
const pq = new Point(point.x - q1.x, point.y - q1.y);
|
|
962
1018
|
const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
|
|
@@ -1199,13 +1255,13 @@ class Dxf extends Component {
|
|
|
1199
1255
|
this.originalData = data;
|
|
1200
1256
|
this.lineSegments.length = 0;
|
|
1201
1257
|
const zList = [];
|
|
1202
|
-
this.data = data.map(({ start, end, insetionArr, isDoor = false, isWindow }, index2) => {
|
|
1258
|
+
this.data = data.map(({ start, end, insetionArr, isDoor = false, isWindow, drawDoorData }, index2) => {
|
|
1203
1259
|
zList.push(start.z ?? 0, end.z ?? 0);
|
|
1204
1260
|
const lineSegment = new LineSegment(
|
|
1205
1261
|
Point.from(start).mutiplyScalar(scale),
|
|
1206
1262
|
Point.from(end).mutiplyScalar(scale)
|
|
1207
1263
|
);
|
|
1208
|
-
lineSegment.userData = { isDoor, isWindow };
|
|
1264
|
+
lineSegment.userData = { isDoor, isWindow, drawDoorData };
|
|
1209
1265
|
this.lineSegments.push(lineSegment);
|
|
1210
1266
|
return [
|
|
1211
1267
|
lineSegment.points[0],
|
|
@@ -1470,14 +1526,14 @@ class Dxf extends Component {
|
|
|
1470
1526
|
/**
|
|
1471
1527
|
* 将点云结构转换为Float32Array
|
|
1472
1528
|
*/
|
|
1473
|
-
to3DArray(scale) {
|
|
1529
|
+
to3DArray(scale, z = this.originalZAverage) {
|
|
1474
1530
|
const array = [];
|
|
1475
1531
|
this.wallsGroup.forEach((points) => {
|
|
1476
1532
|
for (let i = 0; i < points.length; i++) {
|
|
1477
1533
|
const point1 = points[i];
|
|
1478
1534
|
const nextIndex = i === points.length - 1 ? 0 : i + 1;
|
|
1479
1535
|
const point2 = points[nextIndex];
|
|
1480
|
-
array.push(point1.X * scale, point1.Y * scale,
|
|
1536
|
+
array.push(point1.X * scale, point1.Y * scale, z, point2.X * scale, point2.Y * scale, z);
|
|
1481
1537
|
}
|
|
1482
1538
|
});
|
|
1483
1539
|
return new Float32Array(array);
|
|
@@ -1562,6 +1618,20 @@ class Dxf extends Component {
|
|
|
1562
1618
|
});
|
|
1563
1619
|
d.addLayer("l_yellow", Drawing.ACI.YELLOW, "DOTTED");
|
|
1564
1620
|
d.setActiveLayer("l_yellow");
|
|
1621
|
+
this.lineSegments.forEach((line) => {
|
|
1622
|
+
if (!line.userData.isWindow) return false;
|
|
1623
|
+
if (Array.isArray(line.userData.drawDoorData)) {
|
|
1624
|
+
line.userData.drawDoorData.forEach((w) => {
|
|
1625
|
+
const { p, width } = w;
|
|
1626
|
+
const center = Point.from(p);
|
|
1627
|
+
const start = center.clone().add(line.direction().multiplyScalar(width * 0.5));
|
|
1628
|
+
const end = center.clone().add(line.direction().multiplyScalar(-width * 0.5));
|
|
1629
|
+
const blinds = new LineSegment(start, end);
|
|
1630
|
+
drawLine(blinds.start, blinds.end);
|
|
1631
|
+
blinds.expandToRectangle(this.width, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1565
1635
|
return d.toDxfString();
|
|
1566
1636
|
}
|
|
1567
1637
|
/**
|
|
@@ -1644,6 +1714,10 @@ class Variable extends Component {
|
|
|
1644
1714
|
currentWheel = 0;
|
|
1645
1715
|
pointerMove = { x: 0, y: 0 };
|
|
1646
1716
|
currentKeyUp = "";
|
|
1717
|
+
currentKeyDown = "";
|
|
1718
|
+
currentMouseUp = "";
|
|
1719
|
+
currentMouseDown = "";
|
|
1720
|
+
focus = false;
|
|
1647
1721
|
set(key, value) {
|
|
1648
1722
|
if (key in this) {
|
|
1649
1723
|
const oldValue = this[key];
|
|
@@ -1695,6 +1769,7 @@ class Quadtree {
|
|
|
1695
1769
|
}
|
|
1696
1770
|
}
|
|
1697
1771
|
this.nodes.push(node);
|
|
1772
|
+
node.parent = this;
|
|
1698
1773
|
if (this.isLeaf && this.nodes.length > this.capacity && this.depth < this.maxDepth) {
|
|
1699
1774
|
this.subdivide();
|
|
1700
1775
|
const nodes = this.nodes;
|
|
@@ -1704,11 +1779,21 @@ class Quadtree {
|
|
|
1704
1779
|
if (quadrant !== -1) {
|
|
1705
1780
|
this.children[quadrant].insert(n);
|
|
1706
1781
|
} else {
|
|
1782
|
+
n.parent = this;
|
|
1707
1783
|
this.nodes.push(n);
|
|
1708
1784
|
}
|
|
1709
1785
|
}
|
|
1710
1786
|
}
|
|
1711
1787
|
}
|
|
1788
|
+
/** 移除
|
|
1789
|
+
* @param node
|
|
1790
|
+
*/
|
|
1791
|
+
remove(node) {
|
|
1792
|
+
const index2 = node.parent?.nodes.indexOf(node);
|
|
1793
|
+
if (index2 > -1) {
|
|
1794
|
+
node.parent?.nodes.splice(index2, 1);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1712
1797
|
/**
|
|
1713
1798
|
* 获取线段所属的象限
|
|
1714
1799
|
* @param line 线段
|
|
@@ -1915,7 +2000,9 @@ class PointVirtualGrid {
|
|
|
1915
2000
|
const id = this.getGridId(point);
|
|
1916
2001
|
if (!this.map.has(id)) this.map.set(id, /* @__PURE__ */ new Set());
|
|
1917
2002
|
const set = this.map.get(id);
|
|
1918
|
-
|
|
2003
|
+
const target = { point, userData };
|
|
2004
|
+
set.add(target);
|
|
2005
|
+
point.userData.pointVirtualGrid = { set, target };
|
|
1919
2006
|
}
|
|
1920
2007
|
/**
|
|
1921
2008
|
* 批量加入
|
|
@@ -1926,6 +2013,16 @@ class PointVirtualGrid {
|
|
|
1926
2013
|
this.insert(point, userData);
|
|
1927
2014
|
}
|
|
1928
2015
|
}
|
|
2016
|
+
/** 移除点
|
|
2017
|
+
* @param point
|
|
2018
|
+
*/
|
|
2019
|
+
remove(point) {
|
|
2020
|
+
const { set, target } = point?.userData?.pointVirtualGrid;
|
|
2021
|
+
if (set) {
|
|
2022
|
+
set.delete(target);
|
|
2023
|
+
delete point?.userData?.pointVirtualGridMap;
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
1929
2026
|
/**
|
|
1930
2027
|
* 获取通过坐标,获取唯一网格索引
|
|
1931
2028
|
* @param point
|
|
@@ -2018,218 +2115,167 @@ class PointVirtualGrid {
|
|
|
2018
2115
|
return list;
|
|
2019
2116
|
}
|
|
2020
2117
|
}
|
|
2021
|
-
class
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
// 误差角度
|
|
2028
|
-
errorAngle = 4;
|
|
2029
|
-
width = 0.4;
|
|
2030
|
-
/**
|
|
2031
|
-
*
|
|
2032
|
-
* @param parent
|
|
2033
|
-
*/
|
|
2034
|
-
onAddFromParent(parent) {
|
|
2035
|
-
this.Dxf = parent.findComponentByType(Dxf);
|
|
2036
|
-
this.Variable = this.parent?.findComponentByType(Variable);
|
|
2037
|
-
this.Dxf.addEventListener("setDta", this.lineAnalysis.bind(this));
|
|
2038
|
-
this.Dxf.addEventListener("createGroup", this.doorsAnalysis.bind(this));
|
|
2039
|
-
}
|
|
2040
|
-
/**
|
|
2041
|
-
*
|
|
2042
|
-
* @param p1
|
|
2043
|
-
* @param p2
|
|
2044
|
-
* @param width
|
|
2045
|
-
* @returns
|
|
2046
|
-
*/
|
|
2047
|
-
expandLineSegment(p1, p2, width = 0.1) {
|
|
2048
|
-
const normal = p2.normal(p1);
|
|
2049
|
-
const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
|
|
2050
|
-
const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
|
|
2051
|
-
const offsetX = normal.x * width * 0.5;
|
|
2052
|
-
const offsetY = normal.y * width * 0.5;
|
|
2053
|
-
return {
|
|
2054
|
-
points: [
|
|
2055
|
-
// 第一条线
|
|
2056
|
-
new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
|
|
2057
|
-
new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
|
|
2058
|
-
// 第二条线
|
|
2059
|
-
new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
|
|
2060
|
-
new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
|
|
2061
|
-
],
|
|
2062
|
-
indices: [0, 1, 1, 3, 3, 2, 2, 0],
|
|
2063
|
-
rectIndices: [0, 1, 3, 2, 0]
|
|
2064
|
-
};
|
|
2065
|
-
}
|
|
2066
|
-
appendLineSegmentList = [];
|
|
2067
|
-
/**
|
|
2068
|
-
* 追加数据
|
|
2069
|
-
* @param p1
|
|
2070
|
-
* @param p2
|
|
2071
|
-
*/
|
|
2072
|
-
addData(p1, p2) {
|
|
2073
|
-
const dxf = this.Dxf;
|
|
2074
|
-
dxf.data.push([p1.clone(), p2.clone(), [], false, dxf.data.length]);
|
|
2075
|
-
this.appendLineSegmentList.push(new LineSegment(p1.clone(), p2.clone()));
|
|
2076
|
-
}
|
|
2077
|
-
/** 结果分析创建矩形
|
|
2078
|
-
* @param result
|
|
2079
|
-
*/
|
|
2080
|
-
createRectangle(result) {
|
|
2081
|
-
const dxf = this.Dxf;
|
|
2082
|
-
const project0 = result.project, project1 = result.project2;
|
|
2083
|
-
if (project0.includedAngle(project1) > 135) {
|
|
2084
|
-
project1.points = [project1.points[1], project1.points[0]];
|
|
2085
|
-
}
|
|
2086
|
-
this.addData(project0.points[0], project1.points[0]);
|
|
2087
|
-
this.addData(project0.points[1], project1.points[1]);
|
|
2088
|
-
const leftHeight = project0.points[0].distance(project1.points[0]), rightHeight = project0.points[1].distance(project1.points[1]), count = Math.ceil(Math.max(leftHeight, rightHeight) / dxf.width), leftFragment = leftHeight / count, rightFragment = rightHeight / count, leftDirection = project1.points[0].direction(project0.points[0]), rightDirection = project1.points[1].direction(project0.points[1]), leftP = project0.points[0].clone(), rightP = project0.points[1].clone(), direction = rightP.direction(leftP);
|
|
2089
|
-
direction.multiplyScalar(dxf.width * 0.5);
|
|
2090
|
-
const _leftP = leftP.clone().add(direction), _rightP = rightP.clone().add(direction.multiplyScalar(-1)), d1 = leftP.direction(rightP), d2 = _leftP.direction(_rightP);
|
|
2091
|
-
if (d1.x > 0 && d2.x < 0 || d1.x < 0 && d2.x > 0 || d1.y > 0 && d2.y < 0 || d1.y < 0 && d2.y > 0) return;
|
|
2092
|
-
leftP.set(_leftP.x, _leftP.y);
|
|
2093
|
-
rightP.set(_rightP.x, _rightP.y);
|
|
2094
|
-
for (let i = 1; i < count; i++) {
|
|
2095
|
-
const left = leftDirection.clone().multiplyScalar(leftFragment * i), right = rightDirection.clone().multiplyScalar(rightFragment * i), p1 = leftP.clone().add(left), p2 = rightP.clone().add(right);
|
|
2096
|
-
this.addData(p1, p2);
|
|
2097
|
-
}
|
|
2098
|
-
}
|
|
2118
|
+
class DoorsAnalysis {
|
|
2119
|
+
// 所有可查找的点位
|
|
2120
|
+
possibleDoorPoints = [];
|
|
2121
|
+
doorPoint = [];
|
|
2122
|
+
dxf;
|
|
2123
|
+
// 包含所有点的虚拟网格
|
|
2099
2124
|
pointVirtualGrid = new PointVirtualGrid();
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2125
|
+
// 只包含可查找点的虚拟网格
|
|
2126
|
+
findPointVirtualGrid;
|
|
2127
|
+
quadtree;
|
|
2128
|
+
resultList;
|
|
2129
|
+
// 已过滤门的线段
|
|
2130
|
+
lineSegments;
|
|
2131
|
+
doorSearchNearAngle = 110;
|
|
2132
|
+
doorSearchDistance = 2;
|
|
2133
|
+
doors = [];
|
|
2134
|
+
lineAnalysis;
|
|
2135
|
+
continueFind = true;
|
|
2136
|
+
constructor(lineAnalysis) {
|
|
2137
|
+
this.lineAnalysis = lineAnalysis;
|
|
2138
|
+
this.dxf = lineAnalysis.Dxf;
|
|
2139
|
+
this.findPointVirtualGrid = new PointVirtualGrid();
|
|
2140
|
+
this.quadtree = lineAnalysis.quadtree;
|
|
2141
|
+
this.resultList = lineAnalysis.resultList;
|
|
2142
|
+
this.lineSegments = lineAnalysis.lineSegmentList;
|
|
2143
|
+
this.dxf.doorLineSegment.length = 0;
|
|
2144
|
+
this.lineSegments.forEach((line) => {
|
|
2145
|
+
this.pointVirtualGrid.insert(line.start, line);
|
|
2146
|
+
this.pointVirtualGrid.insert(line.end, line);
|
|
2147
|
+
});
|
|
2148
|
+
this.doorPoint = this.getDoorPoint();
|
|
2149
|
+
if (!this.continueFind) return;
|
|
2150
|
+
const excludeIndexMap = this.searchDoubleLinePoint();
|
|
2151
|
+
this.addPointsExcludeRule((line, _2, pointIndex) => {
|
|
2152
|
+
const index2 = this.lineSegments.indexOf(line);
|
|
2153
|
+
const excludeMode = excludeIndexMap.get(index2);
|
|
2154
|
+
if (typeof excludeMode === "number") {
|
|
2155
|
+
return excludeMode === -1 || excludeMode === pointIndex;
|
|
2156
|
+
}
|
|
2157
|
+
return false;
|
|
2158
|
+
});
|
|
2159
|
+
this.addPointsExcludeRule((_1, point) => {
|
|
2160
|
+
return !!this.doorPoint.find((p1) => p1.point.equal(point));
|
|
2161
|
+
});
|
|
2162
|
+
this.possibleDoorPoints = this.getPossiblePoints();
|
|
2163
|
+
this.possibleDoorPoints.forEach((p) => this.findPointVirtualGrid.insert(p.point, p.line));
|
|
2164
|
+
this.handle();
|
|
2165
|
+
}
|
|
2166
|
+
handle() {
|
|
2167
|
+
this.dxf.doorLineSegment.push(...this.search(this.doorPoint, this.possibleDoorPoints, 0.5));
|
|
2168
|
+
if (this.doorPoint.length < 2) this.dxf.doorLineSegment.push(...this.search(this.possibleDoorPoints, this.possibleDoorPoints, 0.6));
|
|
2169
|
+
}
|
|
2170
|
+
search(doorPoints, possibleDoorPoints = [], minDoorWidth = 0.6, doorSearchDistance = this.doorSearchDistance, doorSearchNearAngle = this.doorSearchNearAngle) {
|
|
2171
|
+
const dxf = this.dxf;
|
|
2172
|
+
const doors = this.searchNearby(doorPoints, possibleDoorPoints, doorSearchDistance, doorSearchNearAngle);
|
|
2173
|
+
doors.push(
|
|
2174
|
+
...doorPoints.map((item) => {
|
|
2175
|
+
const res2 = this.searchAlongDirection(item, doorSearchDistance);
|
|
2176
|
+
if (res2) return {
|
|
2177
|
+
start: item.point,
|
|
2178
|
+
end: res2.point
|
|
2179
|
+
};
|
|
2180
|
+
const res3 = this.searchAlongNormalDirection(item, doorSearchDistance);
|
|
2181
|
+
if (res3) return {
|
|
2182
|
+
start: item.point,
|
|
2183
|
+
end: res3.point
|
|
2184
|
+
};
|
|
2185
|
+
}).filter((i) => !!i && i.start.distance(i.end) < doorSearchDistance)
|
|
2186
|
+
);
|
|
2187
|
+
const doorLineSegment = [];
|
|
2188
|
+
doors.forEach((p) => {
|
|
2189
|
+
const line = new LineSegment(p?.start, p?.end);
|
|
2190
|
+
const len = line.length();
|
|
2191
|
+
if (len < minDoorWidth) return;
|
|
2192
|
+
const normal = line.normal(), direction = line.direction(), step = (len - dxf.width * 2) / 2;
|
|
2193
|
+
for (let i = 0; i < 3; i++) {
|
|
2194
|
+
const point = line.start.clone().add(direction.clone().multiplyScalar(dxf.width + step * i));
|
|
2195
|
+
const rLine = new LineSegment(
|
|
2196
|
+
point,
|
|
2197
|
+
point.clone().add(normal.clone().multiplyScalar(1))
|
|
2198
|
+
);
|
|
2199
|
+
rLine.directionMove(normal, -0.5);
|
|
2200
|
+
const res = this.quadtree.queryLineSegment(rLine);
|
|
2201
|
+
if (res.length) return;
|
|
2202
|
+
}
|
|
2203
|
+
doorLineSegment.push(line);
|
|
2111
2204
|
});
|
|
2112
|
-
|
|
2205
|
+
return doorLineSegment;
|
|
2113
2206
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
* 构建线段四叉树,快速查找,
|
|
2207
|
+
/** 添加可查找点的过滤规则
|
|
2208
|
+
* @param rule
|
|
2117
2209
|
*/
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
const lineSegmentList = [];
|
|
2121
|
-
this.quadtree = new Quadtree(dxf.originalBox, 2);
|
|
2122
|
-
dxf.lineSegments.forEach((lineSegment) => {
|
|
2123
|
-
if (lineSegment.userData?.isDoor) return;
|
|
2124
|
-
this.quadtree?.insert({
|
|
2125
|
-
line: lineSegment,
|
|
2126
|
-
userData: lineSegmentList.length
|
|
2127
|
-
});
|
|
2128
|
-
lineSegmentList.push(lineSegment);
|
|
2129
|
-
});
|
|
2130
|
-
this.lineSegmentList = lineSegmentList;
|
|
2210
|
+
addPointsExcludeRule(rule) {
|
|
2211
|
+
this._pointsExcludeRule.push(rule);
|
|
2131
2212
|
}
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
* @description 判断两条线段距离是否较短且趋近平行,然后查找两条线段的重合部分的投影线,以此判断两根线是否需要合并
|
|
2136
|
-
* @param data
|
|
2213
|
+
_pointsExcludeRule = [];
|
|
2214
|
+
/**
|
|
2215
|
+
* 查找所有可能为门的点位
|
|
2137
2216
|
*/
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
this.
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
ids.forEach((id) => {
|
|
2147
|
-
try {
|
|
2148
|
-
if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
|
|
2149
|
-
const res = this.projectionAnalysis(id, i, sourceLineSegment, lineSegmentList);
|
|
2150
|
-
if (res) resultList.push(res);
|
|
2151
|
-
visited.add(`${i}-${id}`);
|
|
2152
|
-
} catch (error) {
|
|
2217
|
+
getPossiblePoints() {
|
|
2218
|
+
const doorPoints = [];
|
|
2219
|
+
this.lineSegments.forEach((line) => {
|
|
2220
|
+
line.points.forEach((p, j) => {
|
|
2221
|
+
for (let i = 0; i < this._pointsExcludeRule.length; i++) if (this._pointsExcludeRule[i](line, p, j)) return;
|
|
2222
|
+
const res = this.pointVirtualGrid.queryPoint(p).filter((d) => d.userData !== line);
|
|
2223
|
+
if (res.length === 0) {
|
|
2224
|
+
doorPoints.push({ line, point: p, uuid: uuid() });
|
|
2153
2225
|
}
|
|
2154
2226
|
});
|
|
2155
2227
|
});
|
|
2156
|
-
|
|
2157
|
-
resultList.forEach(this.createRectangle.bind(this));
|
|
2158
|
-
this.resultList = resultList;
|
|
2159
|
-
}
|
|
2160
|
-
/** 线段投影分析
|
|
2161
|
-
* @param index
|
|
2162
|
-
* @param sourceLineSegment
|
|
2163
|
-
* @param lineSegmentList
|
|
2164
|
-
* @returns
|
|
2165
|
-
*/
|
|
2166
|
-
projectionAnalysis(index2, sourceIndex, sourceLineSegment, lineSegmentList) {
|
|
2167
|
-
const temLineSegment = lineSegmentList[index2], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angleBetween(temDirect) / (Math.PI / 180);
|
|
2168
|
-
if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
|
|
2169
|
-
let data;
|
|
2170
|
-
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
|
|
2171
|
-
if (p1.getLength() > p2.getLength()) {
|
|
2172
|
-
data = {
|
|
2173
|
-
target: temLineSegment,
|
|
2174
|
-
targetIndex: index2,
|
|
2175
|
-
source: sourceLineSegment,
|
|
2176
|
-
sourceIndex,
|
|
2177
|
-
project: p1,
|
|
2178
|
-
project2: p2
|
|
2179
|
-
};
|
|
2180
|
-
} else {
|
|
2181
|
-
data = {
|
|
2182
|
-
target: sourceLineSegment,
|
|
2183
|
-
targetIndex: sourceIndex,
|
|
2184
|
-
source: temLineSegment,
|
|
2185
|
-
sourceIndex: index2,
|
|
2186
|
-
project: p2,
|
|
2187
|
-
project2: p1
|
|
2188
|
-
};
|
|
2189
|
-
}
|
|
2190
|
-
if (!data || data.project.getLength() < 0.2 || data.project2.getLength() < 0.2) return;
|
|
2191
|
-
return data;
|
|
2192
|
-
}
|
|
2228
|
+
return doorPoints;
|
|
2193
2229
|
}
|
|
2194
|
-
doorSearchNearAngle = 110;
|
|
2195
|
-
doorSearchDistance = 2;
|
|
2196
|
-
doors = [];
|
|
2197
2230
|
/**
|
|
2198
|
-
*
|
|
2231
|
+
* 查找已知为门的点位
|
|
2199
2232
|
*/
|
|
2200
|
-
|
|
2201
|
-
const
|
|
2202
|
-
|
|
2203
|
-
const
|
|
2204
|
-
const doorData = dxf.originalData[
|
|
2233
|
+
getDoorPoint() {
|
|
2234
|
+
const doorPoints = [], dxf = this.dxf, pointVirtualGrid = this.pointVirtualGrid;
|
|
2235
|
+
dxf.doors.forEach((item) => {
|
|
2236
|
+
const doorLine = dxf.lineSegments[item[4]];
|
|
2237
|
+
const doorData = dxf.originalData[item[4]];
|
|
2205
2238
|
if (doorData.drawDoorData) {
|
|
2206
2239
|
const point = Point.from(doorData.drawDoorData.start);
|
|
2207
2240
|
const direct = Point.from(doorData.drawDoorData.n);
|
|
2208
2241
|
const resList = pointVirtualGrid.queryPoint(point).filter((res) => {
|
|
2209
|
-
if (res.userData
|
|
2210
|
-
const line =
|
|
2242
|
+
if (res.userData === doorLine) return false;
|
|
2243
|
+
const line = res.userData;
|
|
2211
2244
|
const direct2 = line.direction();
|
|
2212
2245
|
if (line.start.equal(point)) direct2.multiplyScalar(-1);
|
|
2213
2246
|
const angle = direct.angleBetween(direct2, "angle");
|
|
2214
2247
|
return angle > 80 || angle < 10;
|
|
2215
2248
|
});
|
|
2216
2249
|
if (resList.length) {
|
|
2217
|
-
const index22 = resList[0].userData?.index;
|
|
2218
2250
|
doorPoints.push({
|
|
2219
|
-
line:
|
|
2220
|
-
point
|
|
2221
|
-
|
|
2222
|
-
direct,
|
|
2223
|
-
sure: true
|
|
2251
|
+
line: resList[0].userData,
|
|
2252
|
+
point,
|
|
2253
|
+
uuid: uuid()
|
|
2224
2254
|
});
|
|
2225
|
-
return [point];
|
|
2226
2255
|
}
|
|
2256
|
+
} else if (doorData.doorDirectConnection) {
|
|
2257
|
+
this.continueFind = false;
|
|
2258
|
+
const line = new LineSegment(Point.from(doorData.start), Point.from(doorData.end));
|
|
2259
|
+
line.userData = {
|
|
2260
|
+
doorDirectConnection: true,
|
|
2261
|
+
isDoor: true
|
|
2262
|
+
};
|
|
2263
|
+
this.dxf.doorLineSegment.push(line);
|
|
2264
|
+
} else {
|
|
2265
|
+
console.warn(`门的线段顺序${item[4]} 没有drawDoorData属性`);
|
|
2227
2266
|
}
|
|
2228
|
-
return [];
|
|
2229
2267
|
});
|
|
2268
|
+
console.log("门点位数量:", doorPoints.length);
|
|
2269
|
+
return doorPoints;
|
|
2270
|
+
}
|
|
2271
|
+
/**
|
|
2272
|
+
* 查找双线墙的点位
|
|
2273
|
+
* @returns
|
|
2274
|
+
*/
|
|
2275
|
+
searchDoubleLinePoint() {
|
|
2230
2276
|
const excludeIndexMap = /* @__PURE__ */ new Map();
|
|
2231
2277
|
this.resultList.flatMap((p) => {
|
|
2232
|
-
const line0 = this.
|
|
2278
|
+
const line0 = this.lineSegments[p.sourceIndex], line1 = this.lineSegments[p.targetIndex], start0 = line1.projectPoint(line0.start), end0 = line1.projectPoint(line0.end), start1 = line0.projectPoint(line1.start), end1 = line0.projectPoint(line1.end), mode0 = start0 && end0 ? -1 : start0 ? 0 : end0 ? 1 : -1, mode1 = start1 && end1 ? -1 : start1 ? 0 : end1 ? 1 : -1;
|
|
2233
2279
|
if (excludeIndexMap.has(p.sourceIndex)) {
|
|
2234
2280
|
if (excludeIndexMap.get(p.sourceIndex) != mode0) excludeIndexMap.set(p.sourceIndex, -1);
|
|
2235
2281
|
} else excludeIndexMap.set(p.sourceIndex, mode0);
|
|
@@ -2237,54 +2283,42 @@ class LineAnalysis extends Component {
|
|
|
2237
2283
|
if (excludeIndexMap.get(p.targetIndex) != mode1) excludeIndexMap.set(p.targetIndex, -1);
|
|
2238
2284
|
} else excludeIndexMap.set(p.targetIndex, mode1);
|
|
2239
2285
|
});
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
});
|
|
2254
|
-
}
|
|
2255
|
-
});
|
|
2256
|
-
});
|
|
2257
|
-
function searchNearby({ point, line, index: index2 }, doorIndex, record2) {
|
|
2286
|
+
return excludeIndexMap;
|
|
2287
|
+
}
|
|
2288
|
+
/** 查找方案一:最近点查找
|
|
2289
|
+
* @description 以点为圆心,查找半径内符合角度的点
|
|
2290
|
+
* @param doorPoints
|
|
2291
|
+
* @param possibleDoorPoints
|
|
2292
|
+
* @param doorSearchDistance 查找的距离(半径)
|
|
2293
|
+
* @param doorSearchNearAngle 查找的角度
|
|
2294
|
+
* @returns
|
|
2295
|
+
*/
|
|
2296
|
+
searchNearby(doorPoints, possibleDoorPoints = [], doorSearchDistance = this.doorSearchDistance, doorSearchNearAngle = this.doorSearchNearAngle) {
|
|
2297
|
+
const findPointVirtualGrid = this.findPointVirtualGrid, quadtree = this.quadtree;
|
|
2298
|
+
function find({ point, line }, doorIndex, record2) {
|
|
2258
2299
|
const direct = line.direction();
|
|
2259
2300
|
if (line.start === point) direct.multiplyScalar(-1);
|
|
2260
|
-
const res =
|
|
2261
|
-
(r) => (
|
|
2262
|
-
// 不能是自己
|
|
2263
|
-
r.userData?.index !== index2 && // 存在于可疑点位内,且不能是已知门的点位
|
|
2264
|
-
!!doorPoints.find((p) => !p.sure && p.point === r.point)
|
|
2265
|
-
)
|
|
2266
|
-
).sort((a, b) => a.point.distance(point) - b.point.distance(point));
|
|
2301
|
+
const res = findPointVirtualGrid.queryCircle(point, doorSearchDistance).filter((r) => r.userData !== line).sort((a, b) => a.point.distance(point) - b.point.distance(point));
|
|
2267
2302
|
const list = [];
|
|
2268
2303
|
for (let i = 0; i < res.length; i++) {
|
|
2269
|
-
const doorIndex2 =
|
|
2270
|
-
|
|
2271
|
-
record2.
|
|
2272
|
-
record2.add(`${
|
|
2304
|
+
const doorIndex2 = possibleDoorPoints.findIndex((p) => p.point === res[i].point);
|
|
2305
|
+
const id1 = doorPoints[doorIndex].uuid, id2 = possibleDoorPoints[doorIndex2].uuid;
|
|
2306
|
+
if (record2.has(`${id1}.${id2}`)) continue;
|
|
2307
|
+
record2.add(`${id1}.${id2}`);
|
|
2308
|
+
record2.add(`${id2}.${id1}`);
|
|
2273
2309
|
const targetPoint = res[i].point, line2 = new LineSegment(point.clone(), targetPoint.clone()), angle = line2.direction().angleBetween(direct, "angle");
|
|
2274
2310
|
if (angle < doorSearchNearAngle) {
|
|
2275
2311
|
const direct2 = doorPoints[doorIndex2].line.direction();
|
|
2276
|
-
const line22 =
|
|
2312
|
+
const line22 = res[i].userData;
|
|
2277
2313
|
if (line22.start.equal(res[i].point)) direct2.multiplyScalar(-1);
|
|
2278
2314
|
const angle2 = line2.direction().multiplyScalar(-1).angleBetween(direct2, "angle");
|
|
2279
2315
|
if (angle2 < doorSearchNearAngle) {
|
|
2280
2316
|
if (!quadtree.queryLineSegment(line2).length) {
|
|
2281
2317
|
list.push({
|
|
2282
2318
|
findData: res[i],
|
|
2283
|
-
|
|
2284
|
-
findAngle: angle2,
|
|
2285
|
-
doorAngle: angle,
|
|
2319
|
+
findUuid: id2,
|
|
2286
2320
|
doorLine: line2,
|
|
2287
|
-
|
|
2321
|
+
doorUuid: id1
|
|
2288
2322
|
});
|
|
2289
2323
|
}
|
|
2290
2324
|
}
|
|
@@ -2292,65 +2326,15 @@ class LineAnalysis extends Component {
|
|
|
2292
2326
|
}
|
|
2293
2327
|
return list;
|
|
2294
2328
|
}
|
|
2295
|
-
function
|
|
2296
|
-
|
|
2297
|
-
if (line.start === point) direct.multiplyScalar(-1);
|
|
2298
|
-
const endPoint = point.clone().add(direct.clone().multiplyScalar(doorSearchDistance)), rline = new LineSegment(point.clone(), endPoint), result = quadtree.queryLineSegment(rline).map((l) => {
|
|
2299
|
-
const res = l.line.getIntersection(rline);
|
|
2300
|
-
return {
|
|
2301
|
-
point: res,
|
|
2302
|
-
line: l.line
|
|
2303
|
-
};
|
|
2304
|
-
}).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
|
|
2305
|
-
if (result.length) {
|
|
2306
|
-
const item = result[0];
|
|
2307
|
-
if (Math.abs(90 - item.line.direction().angleBetween(direct, "angle")) < 5) {
|
|
2308
|
-
return item;
|
|
2309
|
-
}
|
|
2310
|
-
}
|
|
2311
|
-
}
|
|
2312
|
-
function searchAlongNormalDirection({ point, line, index: index2 }) {
|
|
2313
|
-
const direct = line.direction();
|
|
2314
|
-
if (line.start === point) direct.multiplyScalar(-1);
|
|
2315
|
-
const normal = line.start.normal(line.end);
|
|
2316
|
-
const prePoint = line.start.clone();
|
|
2317
|
-
if (line.start === point) prePoint.copy(line.end);
|
|
2318
|
-
const result = pointVirtualGrid.queryPoint(prePoint).filter((r) => r.userData?.index !== index2);
|
|
2319
|
-
for (let i = 0; i < result.length; i++) {
|
|
2320
|
-
const element = result[i];
|
|
2321
|
-
const l = dxf.lineSegments[element.userData?.index ?? 0];
|
|
2322
|
-
const d1 = l.direction();
|
|
2323
|
-
if (l.start === element.point) direct.multiplyScalar(-1);
|
|
2324
|
-
const angle = d1.angleBetween(normal) / (Math.PI / 180);
|
|
2325
|
-
if (angle > 90) {
|
|
2326
|
-
normal.multiplyScalar(-1);
|
|
2327
|
-
break;
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
const rline3 = new LineSegment(point.clone(), point.clone().add(normal.multiplyScalar(doorSearchDistance)));
|
|
2331
|
-
const r3 = quadtree.queryLineSegment(rline3).map((l) => {
|
|
2332
|
-
const res = l.line.getIntersection(rline3);
|
|
2333
|
-
return {
|
|
2334
|
-
point: res,
|
|
2335
|
-
line: l.line
|
|
2336
|
-
};
|
|
2337
|
-
}).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
|
|
2338
|
-
if (r3.length) {
|
|
2339
|
-
const item = r3[0];
|
|
2340
|
-
if (Math.abs(90 - item.line.direction().angleBetween(normal, "angle")) < 5) {
|
|
2341
|
-
return item;
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
}
|
|
2345
|
-
function deepSearchNearHandle(index2, snFindRecord2, list, record2, other) {
|
|
2346
|
-
record2.add(`${index2}`);
|
|
2329
|
+
function deepSearchNearHandle(uuid2, snFindRecord2, list, record2, other) {
|
|
2330
|
+
record2.add(uuid2);
|
|
2347
2331
|
const newList = [];
|
|
2348
2332
|
if (other) newList.push(other);
|
|
2349
2333
|
for (let i = 0; i < list.length; i++) {
|
|
2350
2334
|
const item = list[i];
|
|
2351
|
-
if (snFindRecord2.has(item.
|
|
2352
|
-
const list2 = snFindRecord2.get(item.
|
|
2353
|
-
if (deepSearchNearHandle(item.
|
|
2335
|
+
if (snFindRecord2.has(item.findUuid)) {
|
|
2336
|
+
const list2 = snFindRecord2.get(item.findUuid);
|
|
2337
|
+
if (deepSearchNearHandle(item.findUuid, snFindRecord2, list2, record2, item)) newList.push(item);
|
|
2354
2338
|
} else newList.push(item);
|
|
2355
2339
|
}
|
|
2356
2340
|
newList.sort((a, b) => a.doorLine.length() - b.doorLine.length());
|
|
@@ -2364,22 +2348,21 @@ class LineAnalysis extends Component {
|
|
|
2364
2348
|
const record = /* @__PURE__ */ new Set();
|
|
2365
2349
|
const snFindRecord = /* @__PURE__ */ new Map();
|
|
2366
2350
|
doorPoints.map((p, index2) => {
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
if (list.length) snFindRecord.set(index2, list);
|
|
2351
|
+
const list = find(p, index2, record);
|
|
2352
|
+
if (list.length) snFindRecord.set(p.uuid, list);
|
|
2370
2353
|
});
|
|
2371
2354
|
record.clear();
|
|
2372
2355
|
const temMap = /* @__PURE__ */ new Map();
|
|
2373
2356
|
snFindRecord.forEach((list, key) => {
|
|
2374
|
-
if (!record.has(
|
|
2357
|
+
if (!record.has(key) && list.length) {
|
|
2375
2358
|
deepSearchNearHandle(key, snFindRecord, list, record);
|
|
2376
2359
|
}
|
|
2377
2360
|
if (list.length) {
|
|
2378
2361
|
const item = list[0];
|
|
2379
|
-
if (!temMap.has(item.
|
|
2380
|
-
temMap.get(item.
|
|
2381
|
-
if (!temMap.has(item.
|
|
2382
|
-
temMap.get(item.
|
|
2362
|
+
if (!temMap.has(item.doorUuid)) temMap.set(item.doorUuid, []);
|
|
2363
|
+
temMap.get(item.doorUuid)?.push(item);
|
|
2364
|
+
if (!temMap.has(item.findUuid)) temMap.set(item.findUuid, []);
|
|
2365
|
+
temMap.get(item.findUuid)?.push(item);
|
|
2383
2366
|
}
|
|
2384
2367
|
});
|
|
2385
2368
|
const deleteSet = /* @__PURE__ */ new Set();
|
|
@@ -2389,38 +2372,24 @@ class LineAnalysis extends Component {
|
|
|
2389
2372
|
for (let i = 1; i < list.length; i++) deleteSet.add(list[i]);
|
|
2390
2373
|
}
|
|
2391
2374
|
});
|
|
2392
|
-
const searchNearRasult = [],
|
|
2375
|
+
const searchNearRasult = [], removeDoorPointsUuid = [];
|
|
2393
2376
|
snFindRecord.forEach((list) => {
|
|
2394
2377
|
if (list.length) {
|
|
2395
2378
|
const item = list[0];
|
|
2396
2379
|
if (!deleteSet.has(item)) {
|
|
2397
2380
|
searchNearRasult.push(item);
|
|
2398
|
-
|
|
2381
|
+
removeDoorPointsUuid.push(item.doorUuid, item.findUuid);
|
|
2399
2382
|
}
|
|
2400
2383
|
}
|
|
2401
2384
|
});
|
|
2402
|
-
const
|
|
2403
|
-
if (removeDoorPointsIndex.includes(index2)) return;
|
|
2404
|
-
if (dxf.doors.length >= 2 && !item.sure) return;
|
|
2405
|
-
const res2 = searchAlongDirection(item);
|
|
2406
|
-
if (res2) return {
|
|
2407
|
-
start: item.point,
|
|
2408
|
-
end: res2.point,
|
|
2409
|
-
index: item.index
|
|
2410
|
-
};
|
|
2411
|
-
const res3 = searchAlongNormalDirection(item);
|
|
2412
|
-
if (res3) return {
|
|
2413
|
-
start: item.point,
|
|
2414
|
-
end: res3.point,
|
|
2415
|
-
index: item.index
|
|
2416
|
-
};
|
|
2417
|
-
}).filter((i) => !!i && i.start.distance(i.end) < doorSearchDistance);
|
|
2418
|
-
doors.push(...doors_);
|
|
2385
|
+
const doors = [];
|
|
2419
2386
|
searchNearRasult.forEach((item) => {
|
|
2420
|
-
const
|
|
2421
|
-
const
|
|
2422
|
-
const
|
|
2423
|
-
const
|
|
2387
|
+
const doorIndex = doorPoints.findIndex((p2) => p2.uuid === item.doorUuid);
|
|
2388
|
+
const findDoorIndex = possibleDoorPoints.findIndex((p2) => p2.uuid === item.findUuid);
|
|
2389
|
+
const start = doorPoints[doorIndex].point.clone();
|
|
2390
|
+
const end = possibleDoorPoints[findDoorIndex].point.clone();
|
|
2391
|
+
const startLine = this.findLongLineSegment(doorPoints[doorIndex].line);
|
|
2392
|
+
const endLine = this.findLongLineSegment(possibleDoorPoints[findDoorIndex].line);
|
|
2424
2393
|
const p = startLine.projectPoint(end);
|
|
2425
2394
|
if (p) {
|
|
2426
2395
|
start.copy(p);
|
|
@@ -2429,8 +2398,7 @@ class LineAnalysis extends Component {
|
|
|
2429
2398
|
if (angle < 10 || angle > 170 || Math.abs(90 - angle) < 10) {
|
|
2430
2399
|
doors.push({
|
|
2431
2400
|
start,
|
|
2432
|
-
end
|
|
2433
|
-
index: doorPoints[item.doorIndex].index
|
|
2401
|
+
end
|
|
2434
2402
|
});
|
|
2435
2403
|
}
|
|
2436
2404
|
} else {
|
|
@@ -2441,30 +2409,82 @@ class LineAnalysis extends Component {
|
|
|
2441
2409
|
if (angle < 10 || angle > 170 || Math.abs(90 - angle) < 10) {
|
|
2442
2410
|
doors.push({
|
|
2443
2411
|
start,
|
|
2444
|
-
end
|
|
2445
|
-
index: doorPoints[item.doorIndex].index
|
|
2412
|
+
end
|
|
2446
2413
|
});
|
|
2447
2414
|
}
|
|
2448
2415
|
}
|
|
2449
2416
|
});
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2417
|
+
possibleDoorPoints.splice(
|
|
2418
|
+
0,
|
|
2419
|
+
possibleDoorPoints.length,
|
|
2420
|
+
...possibleDoorPoints.filter((p) => removeDoorPointsUuid.indexOf(p.uuid) === -1)
|
|
2421
|
+
);
|
|
2422
|
+
doorPoints.splice(
|
|
2423
|
+
0,
|
|
2424
|
+
doorPoints.length,
|
|
2425
|
+
...doorPoints.filter((p) => removeDoorPointsUuid.indexOf(p.uuid) === -1)
|
|
2426
|
+
);
|
|
2427
|
+
return doors;
|
|
2428
|
+
}
|
|
2429
|
+
/** 方案二: 沿方向查找
|
|
2430
|
+
* @description
|
|
2431
|
+
* @param param0
|
|
2432
|
+
* @returns
|
|
2433
|
+
*/
|
|
2434
|
+
searchAlongDirection({ point, line }, doorSearchDistance = this.doorSearchDistance) {
|
|
2435
|
+
const quadtree = this.quadtree;
|
|
2436
|
+
const direct = line.direction();
|
|
2437
|
+
if (line.start === point) direct.multiplyScalar(-1);
|
|
2438
|
+
const endPoint = point.clone().add(direct.clone().multiplyScalar(doorSearchDistance)), rline = new LineSegment(point.clone(), endPoint), result = quadtree.queryLineSegment(rline).map((l) => {
|
|
2439
|
+
const res = l.line.getIntersection(rline);
|
|
2440
|
+
return {
|
|
2441
|
+
point: res,
|
|
2442
|
+
line: l.line
|
|
2443
|
+
};
|
|
2444
|
+
}).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
|
|
2445
|
+
if (result.length) {
|
|
2446
|
+
const item = result[0];
|
|
2447
|
+
if (Math.abs(90 - item.line.direction().angleBetween(direct, "angle")) < 5) {
|
|
2448
|
+
return item;
|
|
2465
2449
|
}
|
|
2466
|
-
|
|
2467
|
-
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
/** 方案三: 沿法线方向查找
|
|
2453
|
+
* @description
|
|
2454
|
+
* @param param0
|
|
2455
|
+
* @param doorSearchDistance
|
|
2456
|
+
* @returns
|
|
2457
|
+
*/
|
|
2458
|
+
searchAlongNormalDirection({ point, line }, doorSearchDistance = this.doorSearchDistance) {
|
|
2459
|
+
const pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree, direct = line.direction(), normal = line.start.normal(line.end), prePoint = line.start.clone();
|
|
2460
|
+
if (line.start === point) direct.multiplyScalar(-1);
|
|
2461
|
+
if (line.start === point) prePoint.copy(line.end);
|
|
2462
|
+
const result = pointVirtualGrid.queryPoint(prePoint).filter((r) => r.userData !== line);
|
|
2463
|
+
for (let i = 0; i < result.length; i++) {
|
|
2464
|
+
const element = result[i];
|
|
2465
|
+
const l = element.userData;
|
|
2466
|
+
const d1 = l.direction();
|
|
2467
|
+
if (l.start === element.point) direct.multiplyScalar(-1);
|
|
2468
|
+
const angle = d1.angleBetween(normal) / (Math.PI / 180);
|
|
2469
|
+
if (angle > 90) {
|
|
2470
|
+
normal.multiplyScalar(-1);
|
|
2471
|
+
break;
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
const rline3 = new LineSegment(point.clone(), point.clone().add(normal.multiplyScalar(doorSearchDistance)));
|
|
2475
|
+
const r3 = quadtree.queryLineSegment(rline3).map((l) => {
|
|
2476
|
+
const res = l.line.getIntersection(rline3);
|
|
2477
|
+
return {
|
|
2478
|
+
point: res,
|
|
2479
|
+
line: l.line
|
|
2480
|
+
};
|
|
2481
|
+
}).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
|
|
2482
|
+
if (r3.length) {
|
|
2483
|
+
const item = r3[0];
|
|
2484
|
+
if (Math.abs(90 - item.line.direction().angleBetween(normal, "angle")) < 5) {
|
|
2485
|
+
return item;
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2468
2488
|
}
|
|
2469
2489
|
/**
|
|
2470
2490
|
*
|
|
@@ -2476,8 +2496,7 @@ class LineAnalysis extends Component {
|
|
|
2476
2496
|
const res1 = this.pointVirtualGrid.queryPoint(line.start);
|
|
2477
2497
|
const res2 = this.pointVirtualGrid.queryPoint(line.end);
|
|
2478
2498
|
for (let i = 0; i < res1.length; i++) {
|
|
2479
|
-
const { userData } = res1[i];
|
|
2480
|
-
const line2 = this.lineSegmentList[userData?.index];
|
|
2499
|
+
const { userData: line2 } = res1[i];
|
|
2481
2500
|
if (line2 === line) continue;
|
|
2482
2501
|
if (line2 && line2.directionEqual(line)) {
|
|
2483
2502
|
if (line2.start.equal(line.start)) resLine.start.copy(line2.end);
|
|
@@ -2486,8 +2505,7 @@ class LineAnalysis extends Component {
|
|
|
2486
2505
|
}
|
|
2487
2506
|
}
|
|
2488
2507
|
for (let i = 0; i < res2.length; i++) {
|
|
2489
|
-
const { userData } = res2[i];
|
|
2490
|
-
const line2 = this.lineSegmentList[userData?.index];
|
|
2508
|
+
const { userData: line2 } = res2[i];
|
|
2491
2509
|
if (line2 === line) continue;
|
|
2492
2510
|
if (line2 && line2.directionEqual(line)) {
|
|
2493
2511
|
if (line2.end.equal(line.end)) resLine.end.copy(line2.start);
|
|
@@ -2497,127 +2515,169 @@ class LineAnalysis extends Component {
|
|
|
2497
2515
|
}
|
|
2498
2516
|
return resLine;
|
|
2499
2517
|
}
|
|
2500
|
-
doorsAnalysis2() {
|
|
2501
|
-
const renderer = this.parent?.findComponentByName("Renderer");
|
|
2502
|
-
const dxf = this.Dxf, pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree;
|
|
2503
|
-
this.doorSearchNearAngle;
|
|
2504
|
-
this.doorSearchDistance;
|
|
2505
|
-
const doorsAnalysis = new DoorsAnalysis(dxf, pointVirtualGrid, quadtree, this.resultList, this.lineSegmentList);
|
|
2506
|
-
const possiblePoints = doorsAnalysis.searchPossiblePoints();
|
|
2507
|
-
possiblePoints.forEach((l) => {
|
|
2508
|
-
renderer.createPointMesh(l.point).position.z = dxf.originalZAverage;
|
|
2509
|
-
});
|
|
2510
|
-
}
|
|
2511
2518
|
}
|
|
2512
|
-
class
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
this.
|
|
2527
|
-
this.
|
|
2528
|
-
this.
|
|
2529
|
-
|
|
2530
|
-
this.addPointsExcludeRule((_1, _2, index2, pointIndex) => {
|
|
2531
|
-
const excludeMode = excludeIndexMap.get(index2);
|
|
2532
|
-
if (typeof excludeMode === "number") {
|
|
2533
|
-
return excludeMode === -1 || excludeMode === pointIndex;
|
|
2534
|
-
}
|
|
2535
|
-
return false;
|
|
2536
|
-
});
|
|
2537
|
-
this.doorPoint = this.searchDoorPoint();
|
|
2538
|
-
this.addPointsExcludeRule((_1, point) => {
|
|
2539
|
-
return !!this.doorPoint.find((p1) => p1.point.equal(point));
|
|
2540
|
-
});
|
|
2541
|
-
this.possibleDoorPoints = this.searchPossiblePoints();
|
|
2519
|
+
class LineAnalysis extends Component {
|
|
2520
|
+
static name = "LineAnalysis";
|
|
2521
|
+
Dxf = null;
|
|
2522
|
+
Variable = null;
|
|
2523
|
+
lineSegmentList = [];
|
|
2524
|
+
container = new THREE.Group();
|
|
2525
|
+
// 误差角度
|
|
2526
|
+
errorAngle = 4;
|
|
2527
|
+
width = 0.4;
|
|
2528
|
+
/**
|
|
2529
|
+
*
|
|
2530
|
+
* @param parent
|
|
2531
|
+
*/
|
|
2532
|
+
onAddFromParent(parent) {
|
|
2533
|
+
this.Dxf = parent.findComponentByType(Dxf);
|
|
2534
|
+
this.Variable = this.parent?.findComponentByType(Variable);
|
|
2535
|
+
this.Dxf.addEventListener("setDta", this.lineAnalysis.bind(this));
|
|
2536
|
+
this.Dxf.addEventListener("createGroup", this.doorsAnalysis.bind(this));
|
|
2542
2537
|
}
|
|
2543
2538
|
/**
|
|
2544
2539
|
*
|
|
2545
|
-
* @param
|
|
2540
|
+
* @param p1
|
|
2541
|
+
* @param p2
|
|
2542
|
+
* @param width
|
|
2543
|
+
* @returns
|
|
2546
2544
|
*/
|
|
2547
|
-
|
|
2548
|
-
|
|
2545
|
+
expandLineSegment(p1, p2, width = 0.1) {
|
|
2546
|
+
const normal = p2.normal(p1);
|
|
2547
|
+
const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
|
|
2548
|
+
const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
|
|
2549
|
+
const offsetX = normal.x * width * 0.5;
|
|
2550
|
+
const offsetY = normal.y * width * 0.5;
|
|
2551
|
+
return {
|
|
2552
|
+
points: [
|
|
2553
|
+
// 第一条线
|
|
2554
|
+
new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
|
|
2555
|
+
new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
|
|
2556
|
+
// 第二条线
|
|
2557
|
+
new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
|
|
2558
|
+
new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
|
|
2559
|
+
],
|
|
2560
|
+
indices: [0, 1, 1, 3, 3, 2, 2, 0],
|
|
2561
|
+
rectIndices: [0, 1, 3, 2, 0]
|
|
2562
|
+
};
|
|
2549
2563
|
}
|
|
2550
|
-
|
|
2564
|
+
appendLineSegmentList = [];
|
|
2551
2565
|
/**
|
|
2552
|
-
*
|
|
2566
|
+
* 追加数据
|
|
2567
|
+
* @param p1
|
|
2568
|
+
* @param p2
|
|
2553
2569
|
*/
|
|
2554
|
-
|
|
2555
|
-
const dxf = this.
|
|
2556
|
-
dxf.
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2570
|
+
addData(p1, p2) {
|
|
2571
|
+
const dxf = this.Dxf;
|
|
2572
|
+
dxf.data.push([p1.clone(), p2.clone(), [], false, dxf.data.length]);
|
|
2573
|
+
this.appendLineSegmentList.push(new LineSegment(p1.clone(), p2.clone()));
|
|
2574
|
+
}
|
|
2575
|
+
/** 结果分析创建矩形
|
|
2576
|
+
* @param result
|
|
2577
|
+
*/
|
|
2578
|
+
createRectangle(result) {
|
|
2579
|
+
const dxf = this.Dxf;
|
|
2580
|
+
const project0 = result.project, project1 = result.project2;
|
|
2581
|
+
if (project0.includedAngle(project1) > 135) {
|
|
2582
|
+
project1.points = [project1.points[1], project1.points[0]];
|
|
2583
|
+
}
|
|
2584
|
+
this.addData(project0.points[0], project1.points[0]);
|
|
2585
|
+
this.addData(project0.points[1], project1.points[1]);
|
|
2586
|
+
const leftHeight = project0.points[0].distance(project1.points[0]), rightHeight = project0.points[1].distance(project1.points[1]), count = Math.ceil(Math.max(leftHeight, rightHeight) / dxf.width), leftFragment = leftHeight / count, rightFragment = rightHeight / count, leftDirection = project1.points[0].direction(project0.points[0]), rightDirection = project1.points[1].direction(project0.points[1]), leftP = project0.points[0].clone(), rightP = project0.points[1].clone(), direction = rightP.direction(leftP);
|
|
2587
|
+
direction.multiplyScalar(dxf.width * 0.5);
|
|
2588
|
+
const _leftP = leftP.clone().add(direction), _rightP = rightP.clone().add(direction.multiplyScalar(-1)), d1 = leftP.direction(rightP), d2 = _leftP.direction(_rightP);
|
|
2589
|
+
if (d1.x > 0 && d2.x < 0 || d1.x < 0 && d2.x > 0 || d1.y > 0 && d2.y < 0 || d1.y < 0 && d2.y > 0) return;
|
|
2590
|
+
leftP.set(_leftP.x, _leftP.y);
|
|
2591
|
+
rightP.set(_rightP.x, _rightP.y);
|
|
2592
|
+
for (let i = 1; i < count; i++) {
|
|
2593
|
+
const left = leftDirection.clone().multiplyScalar(leftFragment * i), right = rightDirection.clone().multiplyScalar(rightFragment * i), p1 = leftP.clone().add(left), p2 = rightP.clone().add(right);
|
|
2594
|
+
this.addData(p1, p2);
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
quadtree;
|
|
2598
|
+
/**
|
|
2599
|
+
* 构建线段四叉树,快速查找,
|
|
2600
|
+
*/
|
|
2601
|
+
buildQuadtree() {
|
|
2602
|
+
const dxf = this.Dxf;
|
|
2603
|
+
const lineSegmentList = [];
|
|
2604
|
+
this.quadtree = new Quadtree(dxf.originalBox, 2);
|
|
2605
|
+
dxf.lineSegments.forEach((lineSegment) => {
|
|
2606
|
+
if (lineSegment.userData?.isDoor) return;
|
|
2607
|
+
this.quadtree?.insert({
|
|
2608
|
+
line: lineSegment,
|
|
2609
|
+
userData: lineSegmentList.length
|
|
2568
2610
|
});
|
|
2611
|
+
lineSegmentList.push(lineSegment);
|
|
2569
2612
|
});
|
|
2570
|
-
|
|
2613
|
+
this.lineSegmentList = lineSegmentList;
|
|
2571
2614
|
}
|
|
2572
|
-
|
|
2573
|
-
|
|
2615
|
+
resultList = [];
|
|
2616
|
+
mergeWallLines = [];
|
|
2617
|
+
/** 线段分析
|
|
2618
|
+
* @description 判断两条线段距离是否较短且趋近平行,然后查找两条线段的重合部分的投影线,以此判断两根线是否需要合并
|
|
2619
|
+
* @param data
|
|
2574
2620
|
*/
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
if (
|
|
2585
|
-
const
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
return angle > 80 || angle < 10;
|
|
2590
|
-
});
|
|
2591
|
-
if (resList.length) {
|
|
2592
|
-
const index22 = resList[0].userData?.index;
|
|
2593
|
-
doorPoints.push({
|
|
2594
|
-
line: dxf.lineSegments[index22],
|
|
2595
|
-
point: Point.from(doorData.drawDoorData.start),
|
|
2596
|
-
index: index22,
|
|
2597
|
-
direct,
|
|
2598
|
-
sure: true
|
|
2599
|
-
});
|
|
2621
|
+
lineAnalysis() {
|
|
2622
|
+
this.buildQuadtree();
|
|
2623
|
+
const quadtree = this.quadtree;
|
|
2624
|
+
const lineSegmentList = this.lineSegmentList;
|
|
2625
|
+
const visited = /* @__PURE__ */ new Set(), resultList = [];
|
|
2626
|
+
lineSegmentList.forEach((_0, i) => {
|
|
2627
|
+
const sourceLineSegment = lineSegmentList[i], rectangle = Rectangle.fromByLineSegment(sourceLineSegment, this.width * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index2) => index2 !== i);
|
|
2628
|
+
ids.forEach((id) => {
|
|
2629
|
+
try {
|
|
2630
|
+
if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
|
|
2631
|
+
const res = this.projectionAnalysis(id, i, sourceLineSegment, lineSegmentList);
|
|
2632
|
+
if (res) resultList.push(res);
|
|
2633
|
+
visited.add(`${i}-${id}`);
|
|
2634
|
+
} catch (error) {
|
|
2600
2635
|
}
|
|
2601
|
-
}
|
|
2636
|
+
});
|
|
2602
2637
|
});
|
|
2603
|
-
|
|
2638
|
+
this.appendLineSegmentList.length = 0;
|
|
2639
|
+
resultList.forEach(this.createRectangle.bind(this));
|
|
2640
|
+
this.resultList = resultList;
|
|
2604
2641
|
}
|
|
2605
|
-
/**
|
|
2606
|
-
*
|
|
2642
|
+
/** 线段投影分析
|
|
2643
|
+
* @param index
|
|
2644
|
+
* @param sourceLineSegment
|
|
2645
|
+
* @param lineSegmentList
|
|
2607
2646
|
* @returns
|
|
2608
2647
|
*/
|
|
2609
|
-
|
|
2610
|
-
const
|
|
2611
|
-
this.
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2648
|
+
projectionAnalysis(index2, sourceIndex, sourceLineSegment, lineSegmentList) {
|
|
2649
|
+
const temLineSegment = lineSegmentList[index2], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angleBetween(temDirect) / (Math.PI / 180);
|
|
2650
|
+
if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
|
|
2651
|
+
let data;
|
|
2652
|
+
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
|
|
2653
|
+
if (p1.getLength() > p2.getLength()) {
|
|
2654
|
+
data = {
|
|
2655
|
+
target: temLineSegment,
|
|
2656
|
+
targetIndex: index2,
|
|
2657
|
+
source: sourceLineSegment,
|
|
2658
|
+
sourceIndex,
|
|
2659
|
+
project: p1,
|
|
2660
|
+
project2: p2
|
|
2661
|
+
};
|
|
2662
|
+
} else {
|
|
2663
|
+
data = {
|
|
2664
|
+
target: sourceLineSegment,
|
|
2665
|
+
targetIndex: sourceIndex,
|
|
2666
|
+
source: temLineSegment,
|
|
2667
|
+
sourceIndex: index2,
|
|
2668
|
+
project: p2,
|
|
2669
|
+
project2: p1
|
|
2670
|
+
};
|
|
2671
|
+
}
|
|
2672
|
+
if (!data || data.project.getLength() < 0.2 || data.project2.getLength() < 0.2) return;
|
|
2673
|
+
return data;
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
doorSearchNearAngle = 110;
|
|
2677
|
+
doorSearchDistance = 2;
|
|
2678
|
+
doors = [];
|
|
2679
|
+
doorsAnalysis() {
|
|
2680
|
+
new DoorsAnalysis(this);
|
|
2621
2681
|
}
|
|
2622
2682
|
}
|
|
2623
2683
|
class DxfSystem extends ComponentManager {
|
|
@@ -2970,38 +3030,84 @@ class DxfLineModel extends Component {
|
|
|
2970
3030
|
updateMode() {
|
|
2971
3031
|
const dxf = this.parent?.findComponentByName("Dxf");
|
|
2972
3032
|
this.dxfLineModel.clear();
|
|
2973
|
-
const dxfArray = dxf.to3DArray(1 / dxf.scale);
|
|
3033
|
+
const dxfArray = dxf.to3DArray(1 / dxf.scale, 0);
|
|
2974
3034
|
this.dxfLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(dxfArray, 3, true));
|
|
2975
3035
|
const doorsArray = new Float32Array(
|
|
2976
|
-
dxf.doorLineSegment.flatMap(({ start, end }) => [start.x, start.y,
|
|
3036
|
+
dxf.doorLineSegment.flatMap(({ start, end }) => [start.x, start.y, 0, end.x, end.y, 0])
|
|
2977
3037
|
).map((n) => n / dxf.scale);
|
|
2978
3038
|
const doorsColorArray = new Float32Array(dxf.doorLineSegment.flatMap(() => [1, 0, 0, 0, 1, 0]));
|
|
2979
3039
|
this.dxfDoorsLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(doorsArray, 3, true)).setAttribute("color", new THREE.BufferAttribute(doorsColorArray, 3));
|
|
3040
|
+
this.dxfModelGroup.position.z = dxf.originalZAverage;
|
|
3041
|
+
this.dispatchEvent({
|
|
3042
|
+
type: "modelUpdate",
|
|
3043
|
+
model: this.dxfModelGroup
|
|
3044
|
+
});
|
|
2980
3045
|
}
|
|
2981
3046
|
}
|
|
2982
|
-
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
3047
|
+
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2983
3048
|
__proto__: null,
|
|
2984
3049
|
DetailsPoint,
|
|
2985
3050
|
DxfLineModel,
|
|
2986
3051
|
WhiteModel
|
|
2987
3052
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2988
|
-
function
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
3053
|
+
function ModelDataPlugin_(dxfSystem, option = {}) {
|
|
3054
|
+
const {
|
|
3055
|
+
detailsPoint = true,
|
|
3056
|
+
whiteModel = true,
|
|
3057
|
+
dxfLineModel = true
|
|
3058
|
+
} = option;
|
|
3059
|
+
dxfLineModel && dxfSystem.addComponent(new DxfLineModel());
|
|
3060
|
+
whiteModel && dxfSystem.addComponent(new WhiteModel());
|
|
3061
|
+
detailsPoint && dxfSystem.addComponent(new DetailsPoint());
|
|
2992
3062
|
}
|
|
3063
|
+
const ModelDataPlugin = Object.assign(ModelDataPlugin_, {
|
|
3064
|
+
create(option = {}) {
|
|
3065
|
+
return (dxfSystem) => ModelDataPlugin_(dxfSystem, option);
|
|
3066
|
+
}
|
|
3067
|
+
});
|
|
3068
|
+
const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
3069
|
+
__proto__: null,
|
|
3070
|
+
ModelDataPlugin,
|
|
3071
|
+
components: index$1
|
|
3072
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
2993
3073
|
function loadRenderPlugin() {
|
|
2994
3074
|
return import("./index2.js");
|
|
2995
3075
|
}
|
|
3076
|
+
function loadEditorPlugin() {
|
|
3077
|
+
return import("./index3.js");
|
|
3078
|
+
}
|
|
3079
|
+
async function createEditor(dom, camera) {
|
|
3080
|
+
const mp = await Promise.resolve().then(() => index);
|
|
3081
|
+
const rp = await loadRenderPlugin();
|
|
3082
|
+
const editor = await loadEditorPlugin();
|
|
3083
|
+
const dxfSystem = new DxfSystem().usePlugin(mp.ModelDataPlugin.create({
|
|
3084
|
+
detailsPoint: false,
|
|
3085
|
+
whiteModel: false
|
|
3086
|
+
})).usePlugin(rp.RenderPlugin.create({
|
|
3087
|
+
originalLine: false,
|
|
3088
|
+
modelData: false,
|
|
3089
|
+
detailsPoint: false,
|
|
3090
|
+
camera
|
|
3091
|
+
})).usePlugin(editor.Editor);
|
|
3092
|
+
const domContainer = dxfSystem.findComponentByType(rp.components.DomContainer);
|
|
3093
|
+
domContainer && dom.appendChild(domContainer.domElement);
|
|
3094
|
+
return {
|
|
3095
|
+
dxfSystem
|
|
3096
|
+
};
|
|
3097
|
+
}
|
|
2996
3098
|
export {
|
|
2997
3099
|
Box2 as B,
|
|
2998
3100
|
Component as C,
|
|
2999
3101
|
DxfSystem as D,
|
|
3102
|
+
EventDispatcher as E,
|
|
3103
|
+
LineSegment as L,
|
|
3000
3104
|
ModelDataPlugin as M,
|
|
3001
3105
|
Point as P,
|
|
3106
|
+
Quadtree as Q,
|
|
3002
3107
|
Variable as V,
|
|
3003
3108
|
WhiteModel as W,
|
|
3004
3109
|
DetailsPoint as a,
|
|
3005
|
-
|
|
3006
|
-
|
|
3110
|
+
PointVirtualGrid as b,
|
|
3111
|
+
createEditor as c,
|
|
3112
|
+
index$1 as i
|
|
3007
3113
|
};
|