build-dxf 0.1.153 → 0.1.155
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
|
@@ -9665,148 +9665,6 @@ class BuildGroup {
|
|
|
9665
9665
|
}
|
|
9666
9666
|
}
|
|
9667
9667
|
class DoubleWallFinder {
|
|
9668
|
-
static errorAngle = 4;
|
|
9669
|
-
/** 线段投影分析
|
|
9670
|
-
* @param index
|
|
9671
|
-
* @param sourceLineSegment
|
|
9672
|
-
* @param lineSegmentList
|
|
9673
|
-
* @returns
|
|
9674
|
-
*/
|
|
9675
|
-
static projectionAnalysis(index2, sourceIndex, sourceLineSegment, lineSegmentList) {
|
|
9676
|
-
const temLineSegment = lineSegmentList[index2], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angle(temDirect, { unit: "degree", range: "180" });
|
|
9677
|
-
if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
|
|
9678
|
-
let data;
|
|
9679
|
-
let dist = sourceLineSegment.distanceToSegment(temLineSegment);
|
|
9680
|
-
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
|
|
9681
|
-
if (p1.length > p2.length) {
|
|
9682
|
-
data = {
|
|
9683
|
-
target: temLineSegment,
|
|
9684
|
-
targetIndex: index2,
|
|
9685
|
-
source: sourceLineSegment,
|
|
9686
|
-
sourceIndex,
|
|
9687
|
-
project: p1,
|
|
9688
|
-
project2: p2,
|
|
9689
|
-
minDistance: dist
|
|
9690
|
-
};
|
|
9691
|
-
} else {
|
|
9692
|
-
data = {
|
|
9693
|
-
target: sourceLineSegment,
|
|
9694
|
-
targetIndex: sourceIndex,
|
|
9695
|
-
source: temLineSegment,
|
|
9696
|
-
sourceIndex: index2,
|
|
9697
|
-
project: p2,
|
|
9698
|
-
project2: p1,
|
|
9699
|
-
minDistance: dist
|
|
9700
|
-
};
|
|
9701
|
-
}
|
|
9702
|
-
if (!data || data.project.length < 0.08 || data.project2.length < 0.08) return;
|
|
9703
|
-
return data;
|
|
9704
|
-
}
|
|
9705
|
-
}
|
|
9706
|
-
/** 查找
|
|
9707
|
-
* @param lines
|
|
9708
|
-
* @param wallWidth
|
|
9709
|
-
* @returns
|
|
9710
|
-
*/
|
|
9711
|
-
static findDoubleLine(lines, wallWidth = 0.4) {
|
|
9712
|
-
let walls = lines.filter((line) => !line.userData.isDoor), visited = /* @__PURE__ */ new Set(), resultList = [];
|
|
9713
|
-
walls = walls.filter((line) => !line.userData.isWindowWall);
|
|
9714
|
-
let quadtree = new Quadtree(Box2.fromByLineSegment(...walls));
|
|
9715
|
-
walls.forEach((line, index2) => quadtree.insert({ line, userData: index2 }));
|
|
9716
|
-
walls.forEach((sourceLineSegment, i) => {
|
|
9717
|
-
const rectangle = Rectangle.fromByLineSegment(sourceLineSegment, wallWidth * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index2) => index2 !== i);
|
|
9718
|
-
ids.forEach((id) => {
|
|
9719
|
-
try {
|
|
9720
|
-
if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
|
|
9721
|
-
const res = this.projectionAnalysis(id, i, sourceLineSegment, walls);
|
|
9722
|
-
if (res) resultList.push(res);
|
|
9723
|
-
visited.add(`${i}-${id}`);
|
|
9724
|
-
} catch (error) {
|
|
9725
|
-
console.log(error);
|
|
9726
|
-
}
|
|
9727
|
-
});
|
|
9728
|
-
});
|
|
9729
|
-
resultList.forEach((result) => {
|
|
9730
|
-
const project0 = result.project, project1 = result.project2;
|
|
9731
|
-
if (project0.angle(project1, { unit: "degree", range: "180" }) > 135) {
|
|
9732
|
-
project1.points = [project1.points[1], project1.points[0]];
|
|
9733
|
-
}
|
|
9734
|
-
});
|
|
9735
|
-
return {
|
|
9736
|
-
resultList,
|
|
9737
|
-
walls,
|
|
9738
|
-
quadtree
|
|
9739
|
-
};
|
|
9740
|
-
}
|
|
9741
|
-
/** 补双线墙壁
|
|
9742
|
-
* @param lines
|
|
9743
|
-
* @param wallWidth
|
|
9744
|
-
* @returns
|
|
9745
|
-
*/
|
|
9746
|
-
static complementSide(lines, obstacleAegment = [], wallWidth = 0.4) {
|
|
9747
|
-
const otherLines = [];
|
|
9748
|
-
lines = lines.filter((line) => {
|
|
9749
|
-
if (line.userData.isBayWindow || line.userData.isBalconyRailing || LineGroupType.hasType(line, "bayWindow") && line.userData.isWindow) {
|
|
9750
|
-
otherLines.push(line);
|
|
9751
|
-
return false;
|
|
9752
|
-
}
|
|
9753
|
-
return true;
|
|
9754
|
-
});
|
|
9755
|
-
let { resultList, quadtree } = this.findDoubleLine(lines, wallWidth), removeLines = /* @__PURE__ */ new Set(), clipingMap = /* @__PURE__ */ new Map(), appendLines = [];
|
|
9756
|
-
function addClipingMap(line, line1) {
|
|
9757
|
-
if (!clipingMap.has(line)) clipingMap.set(line, []);
|
|
9758
|
-
const startProj = line.projectPoint(line1.start);
|
|
9759
|
-
const endProj = line.projectPoint(line1.end);
|
|
9760
|
-
const list = clipingMap.get(line);
|
|
9761
|
-
if (startProj) list.push(startProj);
|
|
9762
|
-
if (endProj) list.push(endProj);
|
|
9763
|
-
removeLines.add(line);
|
|
9764
|
-
quadtree.remove(line);
|
|
9765
|
-
}
|
|
9766
|
-
resultList.forEach((result) => {
|
|
9767
|
-
const project0 = result.project, project1 = result.project2, line0 = result.source, line1 = result.target;
|
|
9768
|
-
const newLine1 = new LineSegment(project0.start.clone(), project1.start.clone());
|
|
9769
|
-
const newLine2 = new LineSegment(project0.end.clone(), project1.end.clone());
|
|
9770
|
-
newLine1.userData.height = line0.userData.height;
|
|
9771
|
-
newLine1.userData.rooftopPz = line0.userData.rooftopPz;
|
|
9772
|
-
newLine2.userData.height = line1.userData.height;
|
|
9773
|
-
newLine2.userData.rooftopPz = line1.userData.rooftopPz;
|
|
9774
|
-
appendLines.push(newLine1, newLine2);
|
|
9775
|
-
addClipingMap(line0, project0);
|
|
9776
|
-
addClipingMap(line1, project1);
|
|
9777
|
-
});
|
|
9778
|
-
clipingMap.forEach((list, line) => {
|
|
9779
|
-
const newLines = LineSegmentUtils.clippingByPoints(line, list);
|
|
9780
|
-
newLines.forEach((newLine) => {
|
|
9781
|
-
newLine.userData.height = line.userData.height;
|
|
9782
|
-
newLine.userData.rooftopPz = line.userData.rooftopPz;
|
|
9783
|
-
});
|
|
9784
|
-
lines.push(...newLines);
|
|
9785
|
-
});
|
|
9786
|
-
lines = lines.filter((line) => !removeLines.has(line));
|
|
9787
|
-
quadtree.clear();
|
|
9788
|
-
quadtree = Quadtree.from([...lines, ...otherLines, ...obstacleAegment]);
|
|
9789
|
-
appendLines = splitIntersectedLine(appendLines, 1e-9);
|
|
9790
|
-
appendLines.flatMap((line) => {
|
|
9791
|
-
const queryLines = quadtree.queryRect(line.toRectangle(1e-3, "butt")).filter((item) => item.line.isParallelTo(line)).map((item) => item.line);
|
|
9792
|
-
if (queryLines.length) {
|
|
9793
|
-
const newLines = LineSegmentUtils.clippingByLines(line, queryLines);
|
|
9794
|
-
if (newLines) return newLines.forEach((newLine) => {
|
|
9795
|
-
newLine.userData.height = line.userData.height;
|
|
9796
|
-
newLine.userData.rooftopPz = line.userData.rooftopPz;
|
|
9797
|
-
quadtree.insert(newLine);
|
|
9798
|
-
lines.push(newLine);
|
|
9799
|
-
});
|
|
9800
|
-
}
|
|
9801
|
-
quadtree.insert(line);
|
|
9802
|
-
lines.push(line);
|
|
9803
|
-
});
|
|
9804
|
-
quadtree.clear();
|
|
9805
|
-
lines.push(...otherLines);
|
|
9806
|
-
lines = splitIntersectedLine(lines, 1e-9);
|
|
9807
|
-
PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
|
|
9808
|
-
return lines.filter((line) => line.length > 1e-9);
|
|
9809
|
-
}
|
|
9810
9668
|
/**
|
|
9811
9669
|
* @param lines
|
|
9812
9670
|
* @param parallelAxis
|
|
@@ -9854,7 +9712,7 @@ class DoubleWallFinder {
|
|
|
9854
9712
|
*/
|
|
9855
9713
|
static find(lines, obstacle = [], esp = 0.4) {
|
|
9856
9714
|
lines = LineSegmentUtils.GroupBuilder(LineSegmentUtils.group(lines, (line) => WallHole.isBeam(line) ? "beam" : "lines")).handle("lines", (lines2) => {
|
|
9857
|
-
const parallelAxis = lines2[0], verticalAxis = parallelAxis.clone().rotate(Math.PI * 0.5), [group1, group2] = LineSegmentUtils.groupByParallelToAxis(lines2, lines2[0]), newLines1 = this.group(group1, parallelAxis, verticalAxis, esp), newLines2 = this.group(group2, verticalAxis, parallelAxis, esp), appendLines = newLines1.concat(newLines2);
|
|
9715
|
+
const parallelAxis = lines2[0], verticalAxis = parallelAxis.clone().rotate(Math.PI * 0.5), [group1, group2] = LineSegmentUtils.groupByParallelToAxis(lines2, lines2[0], 5), newLines1 = this.group(group1, parallelAxis, verticalAxis, esp), newLines2 = this.group(group2, verticalAxis, parallelAxis, esp), appendLines = newLines1.concat(newLines2);
|
|
9858
9716
|
lines2 = lines2.concat(appendLines);
|
|
9859
9717
|
return lines2;
|
|
9860
9718
|
}).merge();
|
|
@@ -12140,7 +11998,10 @@ function correction(lines, targettLine, option) {
|
|
|
12140
11998
|
const bayWindow = lines.filter((line) => line.userData.isBayWindow).map((line) => line.center);
|
|
12141
11999
|
lines = splitIntersectedLine(lines, 1e-9);
|
|
12142
12000
|
WallHole.filterIllegal(lines).merge(lines);
|
|
12143
|
-
lines = LineSegmentUtils.GroupBuilder(LineSegmentUtils.group(lines, (line) =>
|
|
12001
|
+
lines = LineSegmentUtils.GroupBuilder(LineSegmentUtils.group(lines, (line) => {
|
|
12002
|
+
if (WallHole.isBeam(line)) return "beam";
|
|
12003
|
+
return line.userData.isBalconyRailing ? "balconyRailing" : "lines";
|
|
12004
|
+
})).handle("lines", (lines2) => {
|
|
12144
12005
|
lines2 = AlignToParallelSegments.align(lines2, {
|
|
12145
12006
|
onMergeLine: mergeLineUserData,
|
|
12146
12007
|
onGroup(group2, projValues, axis) {
|
|
@@ -12729,8 +12590,8 @@ class BayWindow {
|
|
|
12729
12590
|
console.log("夹角异常1", Meshlist);
|
|
12730
12591
|
continue;
|
|
12731
12592
|
}
|
|
12732
|
-
|
|
12733
|
-
|
|
12593
|
+
Scenario.Instance.group.add(Meshlist.mesh1);
|
|
12594
|
+
Scenario.Instance.group.add(Meshlist.mesh2);
|
|
12734
12595
|
}
|
|
12735
12596
|
}
|
|
12736
12597
|
}
|
|
@@ -13393,8 +13254,9 @@ class BayWindow {
|
|
|
13393
13254
|
menModel.rotation.y = angleRad;
|
|
13394
13255
|
menModel.scale.set((distance2 + 0.12) / size2.x, height / size2.y, wallWidth / size2.z);
|
|
13395
13256
|
menModel.position.set(center.x, center.y, groundClearance);
|
|
13396
|
-
|
|
13397
|
-
menModel.
|
|
13257
|
+
Scenario.Instance.windowForm = Scenario.Instance.windowForm + 1;
|
|
13258
|
+
menModel.name = `窗体_${Scenario.Instance.windowForm}`;
|
|
13259
|
+
menModel.userData.category = "windowForm";
|
|
13398
13260
|
menModel.userData.winUuid = data.userData.winUuid;
|
|
13399
13261
|
menModel.userData.lineUuid = data.userData.lineUuid;
|
|
13400
13262
|
menModel.userData.width = distance2;
|
|
@@ -13550,7 +13412,17 @@ class Scenario {
|
|
|
13550
13412
|
box;
|
|
13551
13413
|
singleLineWallValue;
|
|
13552
13414
|
liangNum;
|
|
13415
|
+
// 梁堆叠
|
|
13553
13416
|
zhuNum;
|
|
13417
|
+
// 柱堆叠
|
|
13418
|
+
poortNum;
|
|
13419
|
+
// 垭口堆叠
|
|
13420
|
+
doorNum;
|
|
13421
|
+
// 门堆叠
|
|
13422
|
+
windowNum;
|
|
13423
|
+
// 窗堆叠
|
|
13424
|
+
windowForm;
|
|
13425
|
+
// 飘窗体堆叠
|
|
13554
13426
|
static _instance;
|
|
13555
13427
|
static get Instance() {
|
|
13556
13428
|
return Scenario._instance;
|
|
@@ -13564,6 +13436,10 @@ class Scenario {
|
|
|
13564
13436
|
this.axesHelper = new THREE.AxesHelper(20);
|
|
13565
13437
|
this.liangNum = 0;
|
|
13566
13438
|
this.zhuNum = 0;
|
|
13439
|
+
this.poortNum = 0;
|
|
13440
|
+
this.doorNum = 0;
|
|
13441
|
+
this.windowNum = 0;
|
|
13442
|
+
this.windowForm = 0;
|
|
13567
13443
|
this.scene.add(this.axesHelper);
|
|
13568
13444
|
this.group = null;
|
|
13569
13445
|
this.closedArray = [];
|
|
@@ -13633,6 +13509,10 @@ class Scenario {
|
|
|
13633
13509
|
this.group = new Group$1();
|
|
13634
13510
|
this.liangNum = 0;
|
|
13635
13511
|
this.zhuNum = 0;
|
|
13512
|
+
this.poortNum = 0;
|
|
13513
|
+
this.doorNum = 0;
|
|
13514
|
+
this.windowNum = 0;
|
|
13515
|
+
this.windowForm = 0;
|
|
13636
13516
|
this.expandedList = [];
|
|
13637
13517
|
if (!BayWindow.Instance) new BayWindow();
|
|
13638
13518
|
BayWindow.Instance.bayWindowExpansion = [];
|
|
@@ -13768,8 +13648,11 @@ class Scenario {
|
|
|
13768
13648
|
} else if (doubleLinesWindow[x].userData.type === "door") {
|
|
13769
13649
|
this.singleLineWallMountedDoor(doubleLinesWindow[x], x);
|
|
13770
13650
|
} else if (doubleLinesWindow[x].userData.type === "beam") ;
|
|
13771
|
-
else
|
|
13772
|
-
|
|
13651
|
+
else if (doubleLinesWindow[x].userData.type === "passageEntrance") {
|
|
13652
|
+
this.addThePassModel(doubleLinesWindow[x]);
|
|
13653
|
+
}
|
|
13654
|
+
let mesh = this.windowTreatment(doubleLinesWindow[x], Mesh, wallHeight);
|
|
13655
|
+
this.group.add(mesh);
|
|
13773
13656
|
} else if (houMesh) {
|
|
13774
13657
|
if (Number(x) === doubleLinesWindow.length - 1) {
|
|
13775
13658
|
const edges = new THREE.EdgesGeometry(this.windowTreatment(doubleLinesWindow[x], houMesh, wallHeight).geometry);
|
|
@@ -13779,8 +13662,11 @@ class Scenario {
|
|
|
13779
13662
|
} else if (doubleLinesWindow[x].userData.type === "door") {
|
|
13780
13663
|
this.singleLineWallMountedDoor(doubleLinesWindow[x], x);
|
|
13781
13664
|
} else if (doubleLinesWindow[x].userData.type === "beam") ;
|
|
13782
|
-
else
|
|
13783
|
-
|
|
13665
|
+
else if (doubleLinesWindow[x].userData.type === "passageEntrance") {
|
|
13666
|
+
this.addThePassModel(doubleLinesWindow[x]);
|
|
13667
|
+
}
|
|
13668
|
+
let mesh = this.windowTreatment(doubleLinesWindow[x], houMesh, wallHeight);
|
|
13669
|
+
this.group.add(mesh);
|
|
13784
13670
|
} else {
|
|
13785
13671
|
if (doubleLinesWindow[x].userData.type === "window") {
|
|
13786
13672
|
this.installWindows(doubleLinesWindow[x], x);
|
|
@@ -13788,6 +13674,9 @@ class Scenario {
|
|
|
13788
13674
|
this.singleLineWallMountedDoor(doubleLinesWindow[x], x);
|
|
13789
13675
|
}
|
|
13790
13676
|
if (doubleLinesWindow[x].userData.type === "beam") ;
|
|
13677
|
+
else if (doubleLinesWindow[x].userData.type === "passageEntrance") {
|
|
13678
|
+
this.addThePassModel(doubleLinesWindow[x]);
|
|
13679
|
+
}
|
|
13791
13680
|
houMesh = this.windowTreatment(doubleLinesWindow[x], houMesh, wallHeight);
|
|
13792
13681
|
}
|
|
13793
13682
|
} else {
|
|
@@ -13796,7 +13685,9 @@ class Scenario {
|
|
|
13796
13685
|
} else if (doubleLinesWindow[x].userData.type === "door") {
|
|
13797
13686
|
this.singleLineWallMountedDoor(doubleLinesWindow[x], x);
|
|
13798
13687
|
} else if (doubleLinesWindow[x].userData.type === "beam") ;
|
|
13799
|
-
else
|
|
13688
|
+
else if (doubleLinesWindow[x].userData.type === "passageEntrance") {
|
|
13689
|
+
this.addThePassModel(doubleLinesWindow[x]);
|
|
13690
|
+
}
|
|
13800
13691
|
houMesh = this.windowTreatment(doubleLinesWindow[x], Mesh, wallHeight);
|
|
13801
13692
|
}
|
|
13802
13693
|
}
|
|
@@ -14215,7 +14106,8 @@ class Scenario {
|
|
|
14215
14106
|
menModel.rotation.y = angleRad;
|
|
14216
14107
|
menModel.scale.set(distance2 / size2.x, height / size2.y, wallWidth / size2.z);
|
|
14217
14108
|
menModel.position.set(data.center.x, data.center.y, groundClearance);
|
|
14218
|
-
|
|
14109
|
+
this.windowNum = this.windowNum + 1;
|
|
14110
|
+
menModel.name = `窗_${this.windowNum}`;
|
|
14219
14111
|
menModel.userData.category = "window";
|
|
14220
14112
|
menModel.userData.winUuid = data.userData.winUuid;
|
|
14221
14113
|
menModel.userData.lineUuid = data.userData.lineUuid;
|
|
@@ -14254,7 +14146,8 @@ class Scenario {
|
|
|
14254
14146
|
menModel.rotation.y = angleRad;
|
|
14255
14147
|
menModel.scale.set(distance2 / size2.x, height / size2.y, wallWidth / size2.z);
|
|
14256
14148
|
menModel.position.set(data.center.x, data.center.y, groundClearance);
|
|
14257
|
-
|
|
14149
|
+
this.doorNum = this.doorNum + 1;
|
|
14150
|
+
menModel.name = `门_${this.doorNum}`;
|
|
14258
14151
|
menModel.userData.category = "door";
|
|
14259
14152
|
menModel.userData.winUuid = data.userData.winUuid;
|
|
14260
14153
|
menModel.userData.lineUuid = data.userData.lineUuid;
|
|
@@ -14402,7 +14295,7 @@ class Scenario {
|
|
|
14402
14295
|
const evaluator = new Evaluator();
|
|
14403
14296
|
const result = evaluator.evaluate(brush1, brush2, SUBTRACTION);
|
|
14404
14297
|
result.material = mesh.material;
|
|
14405
|
-
if (mesh.userData.category === "beam") {
|
|
14298
|
+
if (mesh.userData.category === "beam" || mesh.userData.category === "passageEntrance") {
|
|
14406
14299
|
result.name = mesh.name;
|
|
14407
14300
|
result.userData = mesh.userData;
|
|
14408
14301
|
}
|
|
@@ -14511,6 +14404,82 @@ class Scenario {
|
|
|
14511
14404
|
const point22 = new THREE.Vector3(point2.x - x - xOverflow, point2.y + y - YOverflow, wallHeight);
|
|
14512
14405
|
return [point1, point22];
|
|
14513
14406
|
}
|
|
14407
|
+
// 只往长边方向偏移指定距离的新坐标
|
|
14408
|
+
expandRectangleAlongLongSide(p1, p2, p3, p4, expandAmount = 0.01) {
|
|
14409
|
+
const edge12 = new THREE.Vector3().copy(p2).sub(p1);
|
|
14410
|
+
const edge23 = new THREE.Vector3().copy(p3).sub(p2);
|
|
14411
|
+
const edge34 = new THREE.Vector3().copy(p4).sub(p3);
|
|
14412
|
+
const edge41 = new THREE.Vector3().copy(p1).sub(p4);
|
|
14413
|
+
const len12 = edge12.length();
|
|
14414
|
+
const len23 = edge23.length();
|
|
14415
|
+
const len34 = edge34.length();
|
|
14416
|
+
const len41 = edge41.length();
|
|
14417
|
+
let longEdgeDirection;
|
|
14418
|
+
let longEdgeStart1, longEdgeEnd1;
|
|
14419
|
+
let longEdgeStart2, longEdgeEnd2;
|
|
14420
|
+
if (len12 >= len23 && len12 >= len34 && len12 >= len41) {
|
|
14421
|
+
longEdgeDirection = edge12.clone().normalize();
|
|
14422
|
+
edge23.clone().normalize();
|
|
14423
|
+
longEdgeStart1 = p1;
|
|
14424
|
+
longEdgeEnd1 = p2;
|
|
14425
|
+
longEdgeStart2 = p4;
|
|
14426
|
+
longEdgeEnd2 = p3;
|
|
14427
|
+
} else if (len23 >= len12 && len23 >= len34 && len23 >= len41) {
|
|
14428
|
+
longEdgeDirection = edge23.clone().normalize();
|
|
14429
|
+
edge34.clone().normalize();
|
|
14430
|
+
longEdgeStart1 = p2;
|
|
14431
|
+
longEdgeEnd1 = p3;
|
|
14432
|
+
longEdgeStart2 = p1;
|
|
14433
|
+
longEdgeEnd2 = p4;
|
|
14434
|
+
} else if (len34 >= len12 && len34 >= len23 && len34 >= len41) {
|
|
14435
|
+
longEdgeDirection = edge34.clone().normalize();
|
|
14436
|
+
edge41.clone().normalize();
|
|
14437
|
+
longEdgeStart1 = p3;
|
|
14438
|
+
longEdgeEnd1 = p4;
|
|
14439
|
+
longEdgeStart2 = p2;
|
|
14440
|
+
longEdgeEnd2 = p1;
|
|
14441
|
+
} else {
|
|
14442
|
+
longEdgeDirection = edge41.clone().normalize();
|
|
14443
|
+
edge12.clone().normalize();
|
|
14444
|
+
longEdgeStart1 = p4;
|
|
14445
|
+
longEdgeEnd1 = p1;
|
|
14446
|
+
longEdgeStart2 = p3;
|
|
14447
|
+
longEdgeEnd2 = p2;
|
|
14448
|
+
}
|
|
14449
|
+
const newP1 = longEdgeStart1.clone().add(longEdgeDirection.clone().multiplyScalar(-expandAmount));
|
|
14450
|
+
const newP2 = longEdgeEnd1.clone().add(longEdgeDirection.clone().multiplyScalar(expandAmount));
|
|
14451
|
+
const newP3 = longEdgeEnd2.clone().add(longEdgeDirection.clone().multiplyScalar(expandAmount));
|
|
14452
|
+
const newP4 = longEdgeStart2.clone().add(longEdgeDirection.clone().multiplyScalar(-expandAmount));
|
|
14453
|
+
return [newP1, newP2, newP3, newP4];
|
|
14454
|
+
}
|
|
14455
|
+
// 往长边和短边方向都偏移指定距离的新坐标
|
|
14456
|
+
expandRectangleSimple(p1, p2, p3, p4, expandAmount = 0.01) {
|
|
14457
|
+
const edge12 = new THREE.Vector3().copy(p2).sub(p1);
|
|
14458
|
+
const edge14 = new THREE.Vector3().copy(p4).sub(p1);
|
|
14459
|
+
const len12 = edge12.length();
|
|
14460
|
+
const len14 = edge14.length();
|
|
14461
|
+
let longEdgeDir, shortEdgeDir;
|
|
14462
|
+
let halfLong, halfShort;
|
|
14463
|
+
if (len12 >= len14) {
|
|
14464
|
+
longEdgeDir = edge12.clone().normalize();
|
|
14465
|
+
shortEdgeDir = edge14.clone().normalize();
|
|
14466
|
+
halfLong = len12 / 2;
|
|
14467
|
+
halfShort = len14 / 2;
|
|
14468
|
+
} else {
|
|
14469
|
+
longEdgeDir = edge14.clone().normalize();
|
|
14470
|
+
shortEdgeDir = edge12.clone().normalize();
|
|
14471
|
+
halfLong = len14 / 2;
|
|
14472
|
+
halfShort = len12 / 2;
|
|
14473
|
+
}
|
|
14474
|
+
const center = new THREE.Vector3().copy(p1).add(p2).add(p3).add(p4).multiplyScalar(0.25);
|
|
14475
|
+
const newHalfLong = halfLong + expandAmount;
|
|
14476
|
+
const newHalfShort = halfShort + expandAmount;
|
|
14477
|
+
const newP1 = center.clone().addScaledVector(longEdgeDir, -newHalfLong).addScaledVector(shortEdgeDir, -newHalfShort);
|
|
14478
|
+
const newP2 = center.clone().addScaledVector(longEdgeDir, newHalfLong).addScaledVector(shortEdgeDir, -newHalfShort);
|
|
14479
|
+
const newP3 = center.clone().addScaledVector(longEdgeDir, newHalfLong).addScaledVector(shortEdgeDir, newHalfShort);
|
|
14480
|
+
const newP4 = center.clone().addScaledVector(longEdgeDir, -newHalfLong).addScaledVector(shortEdgeDir, newHalfShort);
|
|
14481
|
+
return [newP1, newP2, newP3, newP4];
|
|
14482
|
+
}
|
|
14514
14483
|
// 外扩还是内缩偏移点坐标
|
|
14515
14484
|
xinLine1(x, y, pointa, pointb, num, wallHeight) {
|
|
14516
14485
|
let point1;
|
|
@@ -14722,7 +14691,9 @@ class Scenario {
|
|
|
14722
14691
|
this.installWindows(winDraw[x2], x2);
|
|
14723
14692
|
} else if (winDraw[x2].userData.type === "door") {
|
|
14724
14693
|
this.singleLineWallMountedDoor(winDraw[x2], x2);
|
|
14725
|
-
} else
|
|
14694
|
+
} else if (winDraw[x2].userData.type === "passageEntrance") {
|
|
14695
|
+
this.addThePassModel(winDraw[x2]);
|
|
14696
|
+
}
|
|
14726
14697
|
let mesh = this.windowTreatment(winDraw[x2], Mesh, wallHeight);
|
|
14727
14698
|
this.group.add(mesh);
|
|
14728
14699
|
} else if (houMesh) {
|
|
@@ -14732,7 +14703,9 @@ class Scenario {
|
|
|
14732
14703
|
this.installWindows(winDraw[x2], x2);
|
|
14733
14704
|
} else if (winDraw[x2].userData.type === "door") {
|
|
14734
14705
|
this.singleLineWallMountedDoor(winDraw[x2], x2);
|
|
14735
|
-
} else
|
|
14706
|
+
} else if (winDraw[x2].userData.type === "passageEntrance") {
|
|
14707
|
+
this.addThePassModel(winDraw[x2]);
|
|
14708
|
+
}
|
|
14736
14709
|
new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0 }));
|
|
14737
14710
|
let mesh = this.windowTreatment(winDraw[x2], houMesh, wallHeight);
|
|
14738
14711
|
this.group.add(mesh);
|
|
@@ -14743,7 +14716,9 @@ class Scenario {
|
|
|
14743
14716
|
this.singleLineWallMountedDoor(winDraw[x2], x2);
|
|
14744
14717
|
} else if (winDraw[x2].userData.type === "beam") {
|
|
14745
14718
|
console.log("梁");
|
|
14746
|
-
} else
|
|
14719
|
+
} else if (winDraw[x2].userData.type === "passageEntrance") {
|
|
14720
|
+
this.addThePassModel(winDraw[x2]);
|
|
14721
|
+
}
|
|
14747
14722
|
houMesh = this.windowTreatment(winDraw[x2], houMesh, wallHeight);
|
|
14748
14723
|
}
|
|
14749
14724
|
} else {
|
|
@@ -14753,7 +14728,9 @@ class Scenario {
|
|
|
14753
14728
|
this.singleLineWallMountedDoor(winDraw[x2], x2);
|
|
14754
14729
|
} else if (winDraw[x2].userData.type === "beam") {
|
|
14755
14730
|
console.log("梁");
|
|
14756
|
-
} else
|
|
14731
|
+
} else if (winDraw[x2].userData.type === "passageEntrance") {
|
|
14732
|
+
this.addThePassModel(winDraw[x2]);
|
|
14733
|
+
}
|
|
14757
14734
|
houMesh = this.windowTreatment(winDraw[x2], Mesh, wallHeight);
|
|
14758
14735
|
}
|
|
14759
14736
|
}
|
|
@@ -14767,7 +14744,8 @@ class Scenario {
|
|
|
14767
14744
|
// 生成梁模型
|
|
14768
14745
|
generateBeamModel(line) {
|
|
14769
14746
|
let basePoints;
|
|
14770
|
-
|
|
14747
|
+
let expansionPoints;
|
|
14748
|
+
if (!line.userData.expansionWidth && !line.userData.expansionDirction) {
|
|
14771
14749
|
let wallWidth;
|
|
14772
14750
|
if (line.userData.wallWidth) {
|
|
14773
14751
|
wallWidth = line.userData.wallWidth;
|
|
@@ -14776,17 +14754,19 @@ class Scenario {
|
|
|
14776
14754
|
}
|
|
14777
14755
|
const MobileX = this.angleToXAxisDegrees(line.start.x, line.start.y, line.end.x, line.end.y, wallWidth, true);
|
|
14778
14756
|
const MobileY = this.angleToXAxisDegrees(line.start.x, line.start.y, line.end.x, line.end.y, wallWidth, false);
|
|
14779
|
-
let startingPoint = this.xinLine(MobileX, MobileY, line.start, 0);
|
|
14780
|
-
let finishLine = this.xinLine(MobileX, MobileY, line.end,
|
|
14757
|
+
let startingPoint = this.xinLine(MobileX, MobileY, line.start, this.height ? this.height : 0);
|
|
14758
|
+
let finishLine = this.xinLine(MobileX, MobileY, line.end, this.height ? this.height : 0);
|
|
14781
14759
|
basePoints = [startingPoint[0], startingPoint[1], finishLine[1], finishLine[0]];
|
|
14760
|
+
expansionPoints = this.expandRectangleSimple(startingPoint[0], startingPoint[1], finishLine[1], finishLine[0], 0.01);
|
|
14782
14761
|
} else {
|
|
14783
14762
|
const directionX = line.userData.expansionDirction.x * line.userData.expansionWidth;
|
|
14784
14763
|
const directionY = line.userData.expansionDirction.y * line.userData.expansionWidth;
|
|
14785
|
-
let pointStart = new THREE.Vector3(line.start.x, line.start.y, this.height);
|
|
14786
|
-
let pointEnd = new THREE.Vector3(line.end.x, line.end.y, this.height);
|
|
14787
|
-
let startExpansion = new THREE.Vector3(pointStart.x + directionX, pointStart.y + directionY, this.height);
|
|
14788
|
-
let endExpansion = new THREE.Vector3(pointEnd.x + directionX, pointEnd.y + directionY, this.height);
|
|
14764
|
+
let pointStart = new THREE.Vector3(line.start.x, line.start.y, this.height ? this.height : 0);
|
|
14765
|
+
let pointEnd = new THREE.Vector3(line.end.x, line.end.y, this.height ? this.height : 0);
|
|
14766
|
+
let startExpansion = new THREE.Vector3(pointStart.x + directionX, pointStart.y + directionY, this.height ? this.height : 0);
|
|
14767
|
+
let endExpansion = new THREE.Vector3(pointEnd.x + directionX, pointEnd.y + directionY, this.height ? this.height : 0);
|
|
14789
14768
|
basePoints = [pointStart, pointEnd, endExpansion, startExpansion];
|
|
14769
|
+
expansionPoints = this.expandRectangleSimple(pointStart, pointEnd, endExpansion, startExpansion, 0.01);
|
|
14790
14770
|
}
|
|
14791
14771
|
const geometry = this.createParallelepipedFromBase(basePoints, line.userData.height);
|
|
14792
14772
|
const material = new THREE.MeshStandardMaterial({
|
|
@@ -14795,7 +14775,7 @@ class Scenario {
|
|
|
14795
14775
|
side: THREE.DoubleSide
|
|
14796
14776
|
});
|
|
14797
14777
|
const cube = new THREE.Mesh(geometry, material);
|
|
14798
|
-
const bodyGeometry = this.createParallelepipedFromBase(
|
|
14778
|
+
const bodyGeometry = this.createParallelepipedFromBase(expansionPoints, line.userData.rooftopPz);
|
|
14799
14779
|
const brush1 = new Brush(cube.geometry);
|
|
14800
14780
|
brush1.updateMatrixWorld();
|
|
14801
14781
|
const brush2 = new Brush(bodyGeometry);
|
|
@@ -14814,7 +14794,6 @@ class Scenario {
|
|
|
14814
14794
|
}
|
|
14815
14795
|
// 生成柱模型
|
|
14816
14796
|
generateColumnModel(data, lines, Height) {
|
|
14817
|
-
console.log(lines);
|
|
14818
14797
|
let basePoints = [];
|
|
14819
14798
|
for (const i in data) {
|
|
14820
14799
|
basePoints.push(new THREE.Vector3(data[i].x, data[i].y, this.height ? this.height : 0));
|
|
@@ -14868,6 +14847,32 @@ class Scenario {
|
|
|
14868
14847
|
return cube;
|
|
14869
14848
|
}
|
|
14870
14849
|
}
|
|
14850
|
+
// 安装垭口模型
|
|
14851
|
+
addThePassModel(line) {
|
|
14852
|
+
const MobileX = this.angleToXAxisDegrees(line.start.x, line.start.y, line.end.x, line.end.y, line.userData.wallWidth * 0.5, true);
|
|
14853
|
+
const MobileY = this.angleToXAxisDegrees(line.start.x, line.start.y, line.end.x, line.end.y, line.userData.wallWidth * 0.5, false);
|
|
14854
|
+
let startingPoint = this.xinLine(MobileX, MobileY, line.start, this.height ? this.height : 0);
|
|
14855
|
+
let finishLine = this.xinLine(MobileX, MobileY, line.end, this.height ? this.height : 0);
|
|
14856
|
+
let basePoints = [startingPoint[0], startingPoint[1], finishLine[1], finishLine[0]];
|
|
14857
|
+
const geometry = this.createParallelepipedFromBase(basePoints, line.userData.height);
|
|
14858
|
+
const material = new THREE.MeshStandardMaterial({
|
|
14859
|
+
color: 5214420,
|
|
14860
|
+
transparent: true,
|
|
14861
|
+
opacity: 0,
|
|
14862
|
+
side: THREE.DoubleSide
|
|
14863
|
+
});
|
|
14864
|
+
const cube = new THREE.Mesh(geometry, material);
|
|
14865
|
+
if (line.userData.type === "passageEntrance") {
|
|
14866
|
+
this.poortNum = this.poortNum + 1;
|
|
14867
|
+
cube.name = `垭口_${this.poortNum}`;
|
|
14868
|
+
cube.userData.category = "passageEntrance";
|
|
14869
|
+
cube.userData.height = line.userData.height;
|
|
14870
|
+
cube.userData.width = line.length;
|
|
14871
|
+
cube.userData.depth = line.userData.wallWidth;
|
|
14872
|
+
cube.userData.groundHeight = 0;
|
|
14873
|
+
}
|
|
14874
|
+
this.group.add(cube);
|
|
14875
|
+
}
|
|
14871
14876
|
//
|
|
14872
14877
|
createAPlane(lines, menList) {
|
|
14873
14878
|
const lineList = lines;
|
|
@@ -1,40 +1,6 @@
|
|
|
1
1
|
import { LineSegment } from '../../utils/algorithms/LineSegment';
|
|
2
|
-
import { Quadtree } from '../../utils/algorithms/Quadtree';
|
|
3
2
|
import { LineUserData } from '../type';
|
|
4
|
-
type ProjectionAnalysisResult = {
|
|
5
|
-
source: LineSegment;
|
|
6
|
-
sourceIndex: number;
|
|
7
|
-
target: LineSegment;
|
|
8
|
-
targetIndex: number;
|
|
9
|
-
project: LineSegment;
|
|
10
|
-
project2: LineSegment;
|
|
11
|
-
minDistance: number;
|
|
12
|
-
};
|
|
13
3
|
export declare class DoubleWallFinder {
|
|
14
|
-
static errorAngle: number;
|
|
15
|
-
/** 线段投影分析
|
|
16
|
-
* @param index
|
|
17
|
-
* @param sourceLineSegment
|
|
18
|
-
* @param lineSegmentList
|
|
19
|
-
* @returns
|
|
20
|
-
*/
|
|
21
|
-
private static projectionAnalysis;
|
|
22
|
-
/** 查找
|
|
23
|
-
* @param lines
|
|
24
|
-
* @param wallWidth
|
|
25
|
-
* @returns
|
|
26
|
-
*/
|
|
27
|
-
static findDoubleLine(lines: LineSegment<LineUserData>[], wallWidth?: number): {
|
|
28
|
-
resultList: ProjectionAnalysisResult[];
|
|
29
|
-
walls: LineSegment<LineUserData>[];
|
|
30
|
-
quadtree: Quadtree<number>;
|
|
31
|
-
};
|
|
32
|
-
/** 补双线墙壁
|
|
33
|
-
* @param lines
|
|
34
|
-
* @param wallWidth
|
|
35
|
-
* @returns
|
|
36
|
-
*/
|
|
37
|
-
static complementSide(lines: LineSegment<LineUserData>[], obstacleAegment?: LineSegment[], wallWidth?: number): LineSegment<LineUserData>[];
|
|
38
4
|
/**
|
|
39
5
|
* @param lines
|
|
40
6
|
* @param parallelAxis
|
|
@@ -56,4 +22,3 @@ export declare class DoubleWallFinder {
|
|
|
56
22
|
*/
|
|
57
23
|
static buildGroup(lineSegments: LineSegment<LineUserData>[]): (LineSegment<Record<string, any>> | LineSegment<LineUserData>)[];
|
|
58
24
|
}
|
|
59
|
-
export {};
|
|
@@ -40,6 +40,10 @@ export default class Scenario {
|
|
|
40
40
|
singleLineWallValue: any;
|
|
41
41
|
liangNum: number;
|
|
42
42
|
zhuNum: number;
|
|
43
|
+
poortNum: number;
|
|
44
|
+
doorNum: number;
|
|
45
|
+
windowNum: number;
|
|
46
|
+
windowForm: number;
|
|
43
47
|
private static _instance?;
|
|
44
48
|
static get Instance(): Scenario | undefined;
|
|
45
49
|
constructor(scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer, controls: OrbitControls);
|
|
@@ -62,6 +66,8 @@ export default class Scenario {
|
|
|
62
66
|
doorHoleOpening(wallHeight: number, data: any, data1: any, groundHeight?: number, Height?: number, distance?: number, center?: THREE.Vector3, angleRad?: any, index?: string, doorList?: LineSegment): void;
|
|
63
67
|
angleToXAxisDegrees(x1: number, y1: number, x2: number, y2: number, wide: number, cd: boolean): number;
|
|
64
68
|
xinLine(x: number, y: number, point: THREE.Vector3 | Point, wallHeight: number): THREE.Vector3[];
|
|
69
|
+
expandRectangleAlongLongSide(p1: THREE.Vector3, p2: THREE.Vector3, p3: THREE.Vector3, p4: THREE.Vector3, expandAmount?: number): THREE.Vector3[];
|
|
70
|
+
expandRectangleSimple(p1: THREE.Vector3, p2: THREE.Vector3, p3: THREE.Vector3, p4: THREE.Vector3, expandAmount?: number): THREE.Vector3[];
|
|
65
71
|
xinLine1(x: number, y: number, pointa: THREE.Vector3, pointb: THREE.Vector3, num: number, wallHeight: number): any[];
|
|
66
72
|
createParallelepipedFromBase(points: any, height: number): THREE.ExtrudeGeometry;
|
|
67
73
|
correctionSorting(bitem: any): {
|
|
@@ -76,6 +82,7 @@ export default class Scenario {
|
|
|
76
82
|
overallTreatmentOfSingleLineWalls(data: any): void;
|
|
77
83
|
generateBeamModel(line: any): Brush;
|
|
78
84
|
generateColumnModel(data: any, lines: any, Height: number): THREE.Mesh<THREE.ExtrudeGeometry, THREE.MeshStandardMaterial, THREE.Object3DEventMap> | null;
|
|
85
|
+
addThePassModel(line: LineSegment): void;
|
|
79
86
|
createAPlane(lines: LineSegment<Record<string, any>>[], menList: LineSegment<Record<string, any>>[]): void;
|
|
80
87
|
modelLoader(): Promise<void>;
|
|
81
88
|
windowModelLoader(): Promise<void>;
|