rm-graphical-computing-node 1.0.45 → 1.0.46
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/dist/index.mjs +773 -155
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3782,6 +3782,7 @@ function getTrendLineEndpoints(points, options = {}) {
|
|
|
3782
3782
|
}
|
|
3783
3783
|
|
|
3784
3784
|
// src/geometry/beamLine.mjs
|
|
3785
|
+
import { Const } from "three/tsl";
|
|
3785
3786
|
var getBeamLine = async (lines, runDataList, pcdData, lineReader, lineEditor, onProgress = null) => {
|
|
3786
3787
|
removeNoisePoints(lines, lineReader, lineEditor);
|
|
3787
3788
|
if (lines.length <= 0 || runDataList.length <= 0)
|
|
@@ -4542,84 +4543,13 @@ var getBeamLine = async (lines, runDataList, pcdData, lineReader, lineEditor, on
|
|
|
4542
4543
|
}
|
|
4543
4544
|
}
|
|
4544
4545
|
if (addData) {
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
let toDoorEdNearDist = Infinity;
|
|
4553
|
-
let newDoorTmpSt = doorTmpSt.clone();
|
|
4554
|
-
let newDoorTmpEd = doorTmpEd.clone();
|
|
4555
|
-
const nearFloorPoints = [];
|
|
4556
|
-
const nearTopPoints = [];
|
|
4557
|
-
let topDoorSegLine = new THREE5.Line3(beamTmpSt, beamTmpEd);
|
|
4558
|
-
let tmpTarget33 = new THREE5.Vector3();
|
|
4559
|
-
let addHeight = 999999;
|
|
4560
|
-
line2.originalPoints.forEach((point2) => {
|
|
4561
|
-
if (point2.z - doorTmpSt.z < height / 2 + 0.1 && point2.z - doorTmpSt.z > height / 2 - 0.1) {
|
|
4562
|
-
nearFloorPoints.push(point2);
|
|
4563
|
-
}
|
|
4564
|
-
if (point2.z > beamTmpSt.z) {
|
|
4565
|
-
let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(point2, true, tmpTarget33);
|
|
4566
|
-
let tmpVec1 = new THREE5.Vector3().subVectors(ptCloseTmp33, beamTmpSt);
|
|
4567
|
-
let tmpVec2 = new THREE5.Vector3().subVectors(ptCloseTmp33, beamTmpEd);
|
|
4568
|
-
let resP1 = isParallel(doorVector1, tmpVec2);
|
|
4569
|
-
let resP2 = isParallel(doorVector2, tmpVec1);
|
|
4570
|
-
if (resP1 && resP1.parallel && !resP1.sameDirection && resP2 && resP2.parallel && !resP2.sameDirection) {
|
|
4571
|
-
nearTopPoints.push(point2);
|
|
4572
|
-
}
|
|
4573
|
-
}
|
|
4574
|
-
});
|
|
4575
|
-
if (nearFloorPoints.length > 0) {
|
|
4576
|
-
const { newProjectPoints } = getProjectedPointOnLine(doorTmpSt, doorTmpEd, nearFloorPoints);
|
|
4577
|
-
for (const point2 of newProjectPoints) {
|
|
4578
|
-
point2.z = doorTmpSt.z;
|
|
4579
|
-
}
|
|
4580
|
-
newProjectPoints.forEach((point2) => {
|
|
4581
|
-
let newPt = new THREE5.Vector3(point2.x, point2.y, doorTmpSt.z);
|
|
4582
|
-
let tmpDoorVec1 = new THREE5.Vector3().subVectors(newPt, doorTmpEd);
|
|
4583
|
-
let tmpDoorVec2 = new THREE5.Vector3().subVectors(newPt, doorTmpSt);
|
|
4584
|
-
let resP1 = isParallel(doorVector1, tmpDoorVec2);
|
|
4585
|
-
let resP2 = isParallel(doorVector2, tmpDoorVec1);
|
|
4586
|
-
if (resP1 && resP1.parallel && resP1.sameDirection) {
|
|
4587
|
-
let tmpDist = newPt.distanceTo(doorTmpSt);
|
|
4588
|
-
if (tmpDist < toDoorStNearDist) {
|
|
4589
|
-
toDoorStNearDist = tmpDist;
|
|
4590
|
-
newDoorTmpSt = newPt;
|
|
4591
|
-
}
|
|
4592
|
-
} else if (resP2 && resP2.parallel && resP2.sameDirection) {
|
|
4593
|
-
let tmpDist = newPt.distanceTo(doorTmpEd);
|
|
4594
|
-
if (tmpDist < toDoorEdNearDist) {
|
|
4595
|
-
toDoorEdNearDist = tmpDist;
|
|
4596
|
-
newDoorTmpEd = newPt;
|
|
4597
|
-
}
|
|
4598
|
-
}
|
|
4599
|
-
});
|
|
4600
|
-
}
|
|
4601
|
-
if (!newDoorTmpSt.equals(doorTmpSt)) {
|
|
4602
|
-
doorTmpSt = newDoorTmpSt;
|
|
4603
|
-
beamTmpEd = new THREE5.Vector3(doorTmpSt.x, doorTmpSt.y, beamTmpEd.z);
|
|
4604
|
-
}
|
|
4605
|
-
if (!newDoorTmpEd.equals(doorTmpEd)) {
|
|
4606
|
-
doorTmpEd = newDoorTmpEd;
|
|
4607
|
-
beamTmpSt = new THREE5.Vector3(doorTmpEd.x, doorTmpEd.y, beamTmpSt.z);
|
|
4608
|
-
}
|
|
4609
|
-
if (nearTopPoints.length > 10) {
|
|
4610
|
-
const { newOnLinePoints } = getProjectedPointOnLine(beamTmpEd, beamTmpSt, nearTopPoints);
|
|
4611
|
-
for (let n = 0; n < newOnLinePoints.length; n++) {
|
|
4612
|
-
let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(newOnLinePoints[n], true, tmpTarget33);
|
|
4613
|
-
let add = ptCloseTmp33.distanceTo(newOnLinePoints[n]);
|
|
4614
|
-
if (add > 0.02) {
|
|
4615
|
-
if (addHeight > add)
|
|
4616
|
-
addHeight = add;
|
|
4617
|
-
}
|
|
4618
|
-
}
|
|
4619
|
-
beamTmpSt.z += addHeight;
|
|
4620
|
-
beamTmpEd.z += addHeight;
|
|
4621
|
-
height += addHeight;
|
|
4622
|
-
}
|
|
4546
|
+
const expansionData = expansionLine(doorTmpSt, doorTmpEd, beamTmpSt, beamTmpEd, height, line2.originalPoints);
|
|
4547
|
+
if (expansionData) {
|
|
4548
|
+
doorTmpSt = expansionData.pt1;
|
|
4549
|
+
doorTmpEd = expansionData.pt2;
|
|
4550
|
+
beamTmpSt = expansionData.pt3;
|
|
4551
|
+
beamTmpEd = expansionData.pt4;
|
|
4552
|
+
height = expansionData.height;
|
|
4623
4553
|
}
|
|
4624
4554
|
let isOverlap = false;
|
|
4625
4555
|
for (let m = 0; m < allDoorLines1.length; m++) {
|
|
@@ -5316,6 +5246,89 @@ var checkBeamIsReasonable = async (lines, lineReader) => {
|
|
|
5316
5246
|
}
|
|
5317
5247
|
}
|
|
5318
5248
|
};
|
|
5249
|
+
var expansionLine = (doorTmpSt, doorTmpEd, beamTmpSt, beamTmpEd, height, originalPoints) => {
|
|
5250
|
+
let doorVector1 = new THREE5.Vector3().subVectors(doorTmpSt, doorTmpEd);
|
|
5251
|
+
let doorVector2 = new THREE5.Vector3().subVectors(doorTmpEd, doorTmpSt);
|
|
5252
|
+
let toDoorStNearDist = Infinity;
|
|
5253
|
+
let toDoorEdNearDist = Infinity;
|
|
5254
|
+
let newDoorTmpSt = doorTmpSt.clone();
|
|
5255
|
+
let newDoorTmpEd = doorTmpEd.clone();
|
|
5256
|
+
const nearFloorPoints = [];
|
|
5257
|
+
const nearTopPoints = [];
|
|
5258
|
+
let topDoorSegLine = new THREE5.Line3(beamTmpSt, beamTmpEd);
|
|
5259
|
+
let tmpTarget33 = new THREE5.Vector3();
|
|
5260
|
+
let addHeight = 999999;
|
|
5261
|
+
originalPoints.forEach((point2) => {
|
|
5262
|
+
if (point2.z - doorTmpSt.z < height / 2 + 0.1 && point2.z - doorTmpSt.z > height / 2 - 0.1) {
|
|
5263
|
+
nearFloorPoints.push(point2);
|
|
5264
|
+
}
|
|
5265
|
+
if (point2.z > beamTmpSt.z) {
|
|
5266
|
+
let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(point2, true, tmpTarget33);
|
|
5267
|
+
let tmpVec1 = new THREE5.Vector3().subVectors(ptCloseTmp33, beamTmpSt);
|
|
5268
|
+
let tmpVec2 = new THREE5.Vector3().subVectors(ptCloseTmp33, beamTmpEd);
|
|
5269
|
+
let resP1 = isParallel(doorVector1, tmpVec2);
|
|
5270
|
+
let resP2 = isParallel(doorVector2, tmpVec1);
|
|
5271
|
+
if (resP1 && resP1.parallel && !resP1.sameDirection && resP2 && resP2.parallel && !resP2.sameDirection) {
|
|
5272
|
+
nearTopPoints.push(point2);
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
});
|
|
5276
|
+
if (nearFloorPoints.length > 0) {
|
|
5277
|
+
const { newProjectPoints } = getProjectedPointOnLine(doorTmpSt, doorTmpEd, nearFloorPoints);
|
|
5278
|
+
for (const point2 of newProjectPoints) {
|
|
5279
|
+
point2.z = doorTmpSt.z;
|
|
5280
|
+
}
|
|
5281
|
+
newProjectPoints.forEach((point2) => {
|
|
5282
|
+
let newPt = new THREE5.Vector3(point2.x, point2.y, doorTmpSt.z);
|
|
5283
|
+
let tmpDoorVec1 = new THREE5.Vector3().subVectors(newPt, doorTmpEd);
|
|
5284
|
+
let tmpDoorVec2 = new THREE5.Vector3().subVectors(newPt, doorTmpSt);
|
|
5285
|
+
let resP1 = isParallel(doorVector1, tmpDoorVec2);
|
|
5286
|
+
let resP2 = isParallel(doorVector2, tmpDoorVec1);
|
|
5287
|
+
if (resP1 && resP1.parallel && resP1.sameDirection) {
|
|
5288
|
+
let tmpDist = newPt.distanceTo(doorTmpSt);
|
|
5289
|
+
if (tmpDist < toDoorStNearDist) {
|
|
5290
|
+
toDoorStNearDist = tmpDist;
|
|
5291
|
+
newDoorTmpSt = newPt;
|
|
5292
|
+
}
|
|
5293
|
+
} else if (resP2 && resP2.parallel && resP2.sameDirection) {
|
|
5294
|
+
let tmpDist = newPt.distanceTo(doorTmpEd);
|
|
5295
|
+
if (tmpDist < toDoorEdNearDist) {
|
|
5296
|
+
toDoorEdNearDist = tmpDist;
|
|
5297
|
+
newDoorTmpEd = newPt;
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
});
|
|
5301
|
+
}
|
|
5302
|
+
if (!newDoorTmpSt.equals(doorTmpSt)) {
|
|
5303
|
+
doorTmpSt = newDoorTmpSt;
|
|
5304
|
+
beamTmpEd = new THREE5.Vector3(doorTmpSt.x, doorTmpSt.y, beamTmpEd.z);
|
|
5305
|
+
}
|
|
5306
|
+
if (!newDoorTmpEd.equals(doorTmpEd)) {
|
|
5307
|
+
doorTmpEd = newDoorTmpEd;
|
|
5308
|
+
beamTmpSt = new THREE5.Vector3(doorTmpEd.x, doorTmpEd.y, beamTmpSt.z);
|
|
5309
|
+
}
|
|
5310
|
+
if (nearTopPoints.length > 10) {
|
|
5311
|
+
const { newOnLinePoints } = getProjectedPointOnLine(beamTmpEd, beamTmpSt, nearTopPoints);
|
|
5312
|
+
for (let n = 0; n < newOnLinePoints.length; n++) {
|
|
5313
|
+
let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(newOnLinePoints[n], true, tmpTarget33);
|
|
5314
|
+
let add = ptCloseTmp33.distanceTo(newOnLinePoints[n]);
|
|
5315
|
+
if (add > 0.02) {
|
|
5316
|
+
if (addHeight > add)
|
|
5317
|
+
addHeight = add;
|
|
5318
|
+
}
|
|
5319
|
+
}
|
|
5320
|
+
beamTmpSt.z += addHeight;
|
|
5321
|
+
beamTmpEd.z += addHeight;
|
|
5322
|
+
height += addHeight;
|
|
5323
|
+
}
|
|
5324
|
+
return {
|
|
5325
|
+
pt1: doorTmpSt,
|
|
5326
|
+
pt2: doorTmpEd,
|
|
5327
|
+
pt3: beamTmpSt,
|
|
5328
|
+
pt4: beamTmpEd,
|
|
5329
|
+
height
|
|
5330
|
+
};
|
|
5331
|
+
};
|
|
5319
5332
|
|
|
5320
5333
|
// src/geometry/colLine.mjs
|
|
5321
5334
|
import * as THREE6 from "three";
|
|
@@ -10828,82 +10841,685 @@ var getFlatSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
10828
10841
|
return slabDatas;
|
|
10829
10842
|
};
|
|
10830
10843
|
|
|
10831
|
-
// src/
|
|
10832
|
-
|
|
10833
|
-
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
|
|
10837
|
-
|
|
10838
|
-
let
|
|
10839
|
-
|
|
10840
|
-
|
|
10841
|
-
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
|
|
10845
|
-
|
|
10846
|
-
|
|
10847
|
-
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10844
|
+
// src/geometry/window.mjs
|
|
10845
|
+
import * as THREE10 from "three";
|
|
10846
|
+
import { mergeGeometries as mergeGeometries5 } from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
|
10847
|
+
var getWindowData = async (lines, pcdData) => {
|
|
10848
|
+
if (lines.length <= 0 || !pcdData)
|
|
10849
|
+
return lines;
|
|
10850
|
+
if (!pcdData) pcdData = [];
|
|
10851
|
+
for (let line2 of lines) {
|
|
10852
|
+
let allRegion = [];
|
|
10853
|
+
if (!line2.checkResults || line2.checkResults.length <= 0)
|
|
10854
|
+
continue;
|
|
10855
|
+
for (let r = 0; r < line2.checkResults.length; r++) {
|
|
10856
|
+
let find = function(i) {
|
|
10857
|
+
while (parent[i] !== i) {
|
|
10858
|
+
parent[i] = parent[parent[i]];
|
|
10859
|
+
i = parent[i];
|
|
10860
|
+
}
|
|
10861
|
+
return i;
|
|
10862
|
+
};
|
|
10863
|
+
const result = line2.checkResults[r];
|
|
10864
|
+
if (!result.originalVertices || result.originalVertices.length == 0)
|
|
10865
|
+
continue;
|
|
10866
|
+
const verts = [];
|
|
10867
|
+
result.originalVertices.forEach((pts) => {
|
|
10868
|
+
let ptsTmp = [];
|
|
10869
|
+
pts.forEach((pt) => {
|
|
10870
|
+
ptsTmp.push(new THREE10.Vector3(pt.x, pt.y, pt.z));
|
|
10871
|
+
});
|
|
10872
|
+
verts.push(ptsTmp);
|
|
10873
|
+
});
|
|
10874
|
+
const n = verts.length;
|
|
10875
|
+
const parent = Array.from({ length: n }, (_, i) => i);
|
|
10876
|
+
for (let i = 0; i < n; i++) {
|
|
10877
|
+
for (let j = i + 1; j < n; j++) {
|
|
10878
|
+
const qi = verts[i], qj = verts[j];
|
|
10879
|
+
const touches = qi.some((pi) => qj.some((pj) => pi.equals(pj)));
|
|
10880
|
+
if (touches) {
|
|
10881
|
+
const ri = find(i), rj = find(j);
|
|
10882
|
+
if (ri !== rj) parent[ri] = rj;
|
|
10883
|
+
}
|
|
10884
|
+
}
|
|
10885
|
+
}
|
|
10886
|
+
const groups = /* @__PURE__ */ new Map();
|
|
10887
|
+
let gridWidth = -1;
|
|
10888
|
+
let gridHeight = -1;
|
|
10889
|
+
for (let i = 0; i < n; i++) {
|
|
10890
|
+
const root = find(i);
|
|
10891
|
+
if (!groups.has(root)) groups.set(root, {
|
|
10892
|
+
points: [],
|
|
10893
|
+
area: 0,
|
|
10894
|
+
// originalVertices: [],
|
|
10895
|
+
index: -1,
|
|
10896
|
+
gridWidth: -1,
|
|
10897
|
+
gridHeight: -1,
|
|
10898
|
+
centerPts: [],
|
|
10899
|
+
facePoints: [],
|
|
10900
|
+
boxArea: -1,
|
|
10901
|
+
totalInPlaneNum: -1
|
|
10902
|
+
});
|
|
10903
|
+
const group = groups.get(root);
|
|
10904
|
+
let [pt0, pt1, pt2, pt3] = verts[i];
|
|
10905
|
+
const center = new THREE10.Vector3().add(pt0).add(pt1).add(pt2).add(pt3).multiplyScalar(0.25);
|
|
10906
|
+
group.points.push(...verts[i]);
|
|
10907
|
+
group.area += pt0.distanceTo(pt1) * pt0.distanceTo(pt3);
|
|
10908
|
+
group.index = r;
|
|
10909
|
+
group.centerPts.push(center);
|
|
10910
|
+
if (gridWidth == -1 || gridHeight == -1) {
|
|
10911
|
+
let vecTmp = new THREE10.Vector3().subVectors(pt0, pt1).normalize();
|
|
10912
|
+
gridHeight = pt0.distanceTo(pt3);
|
|
10913
|
+
gridWidth = pt0.distanceTo(pt1);
|
|
10914
|
+
let isP = isParallel(vecTmp, new THREE10.Vector3(0, 0, 1));
|
|
10915
|
+
if (isP && isP.parallel) {
|
|
10916
|
+
[gridHeight, gridWidth] = [gridWidth, gridHeight];
|
|
10917
|
+
}
|
|
10918
|
+
}
|
|
10919
|
+
group.gridWidth = gridWidth;
|
|
10920
|
+
group.gridHeight = gridHeight;
|
|
10921
|
+
}
|
|
10922
|
+
const val = groups.values();
|
|
10923
|
+
for (const val2 of groups.values()) {
|
|
10924
|
+
const { facePoints, boxArea, totalInPlaneNum } = getPointCloudData(
|
|
10925
|
+
val2.points,
|
|
10926
|
+
val2.gridWidth,
|
|
10927
|
+
val2.gridHeight,
|
|
10928
|
+
val2.centerPts
|
|
10929
|
+
);
|
|
10930
|
+
val2.centerPts = null;
|
|
10931
|
+
val2.facePoints = facePoints;
|
|
10932
|
+
val2.boxArea = boxArea;
|
|
10933
|
+
val2.totalInPlaneNum = totalInPlaneNum;
|
|
10934
|
+
}
|
|
10935
|
+
allRegion.push(...val);
|
|
10851
10936
|
}
|
|
10937
|
+
line2.mergeCheckRegion = allRegion;
|
|
10852
10938
|
}
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
|
|
10861
|
-
|
|
10862
|
-
|
|
10863
|
-
|
|
10864
|
-
|
|
10939
|
+
const windowDatas = [];
|
|
10940
|
+
for (let i = 0; i < pcdData.length; i++) {
|
|
10941
|
+
const window = pcdData[i];
|
|
10942
|
+
window.isFindBeam = false;
|
|
10943
|
+
if (window.category == "window") {
|
|
10944
|
+
let boxPoints = [];
|
|
10945
|
+
window.coordinatesByArea.coordinates.forEach((p) => {
|
|
10946
|
+
boxPoints.push(new THREE10.Vector3(p.x, p.y, p.z));
|
|
10947
|
+
});
|
|
10948
|
+
if (boxPoints[0].equals(boxPoints[boxPoints.length - 1]))
|
|
10949
|
+
boxPoints.pop();
|
|
10950
|
+
let length2 = boxPoints[0].distanceTo(boxPoints[1]);
|
|
10951
|
+
let width = boxPoints[0].distanceTo(boxPoints[3]);
|
|
10952
|
+
if (width > length2) {
|
|
10953
|
+
[length2, width] = [width, length2];
|
|
10954
|
+
boxPoints = [boxPoints[0], boxPoints[3], boxPoints[2], boxPoints[1]];
|
|
10955
|
+
}
|
|
10956
|
+
if (length2 < 0.3)
|
|
10957
|
+
continue;
|
|
10958
|
+
let windowStartPt = getMid(boxPoints[0], boxPoints[3], true);
|
|
10959
|
+
let windowEndPt = getMid(boxPoints[1], boxPoints[2], true);
|
|
10960
|
+
windowDatas.push({
|
|
10961
|
+
windowStartPt,
|
|
10962
|
+
windowEndPt,
|
|
10963
|
+
boxPoints,
|
|
10964
|
+
minZ: window.coordinatesByArea.heightData.minZ,
|
|
10965
|
+
maxZ: window.coordinatesByArea.heightData.maxZ,
|
|
10966
|
+
index: i,
|
|
10967
|
+
isFind: false,
|
|
10968
|
+
inWall: false,
|
|
10969
|
+
//是否在墙内
|
|
10970
|
+
name: window.name
|
|
10971
|
+
});
|
|
10865
10972
|
}
|
|
10866
10973
|
}
|
|
10867
|
-
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
|
|
10875
|
-
|
|
10876
|
-
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
10892
|
-
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10974
|
+
let id = 0;
|
|
10975
|
+
let doorBeamDataIndex = [];
|
|
10976
|
+
let findDoorIndexs = [];
|
|
10977
|
+
let allDoorLines1 = [];
|
|
10978
|
+
let nearDist = 0.25;
|
|
10979
|
+
for (let index = 0; index < lines.length; index++) {
|
|
10980
|
+
let line2 = lines[index];
|
|
10981
|
+
if (line2.noDetection) continue;
|
|
10982
|
+
if (!line2.doorAndBeamData)
|
|
10983
|
+
line2.doorAndBeamData = [];
|
|
10984
|
+
if (!line2.doorAndBeamIdToCheckResults)
|
|
10985
|
+
line2.doorAndBeamIdToCheckResults = [];
|
|
10986
|
+
if (!line2.mergeCheckRegion || line2.mergeCheckRegion.length == 0)
|
|
10987
|
+
continue;
|
|
10988
|
+
line2.completePointAreaPercentage = -1;
|
|
10989
|
+
let box = new THREE10.Box3();
|
|
10990
|
+
box.setFromPoints(line2.originalPoints);
|
|
10991
|
+
let maxZ = box.max.z;
|
|
10992
|
+
let minZ = box.min.z;
|
|
10993
|
+
const lineStart = new THREE10.Vector3(line2.start.x, line2.start.y, line2.start.z);
|
|
10994
|
+
const lineEnd = new THREE10.Vector3(line2.end.x, line2.end.y, line2.end.z);
|
|
10995
|
+
let floorHeightTmp = line2.rooftopPz - line2.start.z;
|
|
10996
|
+
let totalArea = 0;
|
|
10997
|
+
for (const region of line2.mergeCheckRegion) {
|
|
10998
|
+
const facePoints = region.facePoints;
|
|
10999
|
+
const boxArea = region.boxArea;
|
|
11000
|
+
const totalInPlaneNum = region.totalInPlaneNum;
|
|
11001
|
+
if (!facePoints || facePoints.length <= 0)
|
|
11002
|
+
continue;
|
|
11003
|
+
let regionLength = facePoints[0].distanceTo(facePoints[1]);
|
|
11004
|
+
let regionHeight = facePoints[0].distanceTo(facePoints[3]);
|
|
11005
|
+
const centerHeight = region.gridHeight * (regionHeight / region.gridHeight / 3 * 2) + region.gridHeight / 2;
|
|
11006
|
+
let linePt1 = new THREE10.Vector3(facePoints[0].x, facePoints[0].y, facePoints[0].z + centerHeight);
|
|
11007
|
+
let linePt2 = new THREE10.Vector3(facePoints[1].x, facePoints[1].y, facePoints[1].z + centerHeight);
|
|
11008
|
+
const centerLine = new THREE10.Line3(linePt1, linePt2);
|
|
11009
|
+
const inLinePts = [];
|
|
11010
|
+
let tmpTargetPt = new THREE10.Vector3();
|
|
11011
|
+
region.points.forEach((pt) => {
|
|
11012
|
+
const tmpClosePt = centerLine.closestPointToPoint(pt, true, tmpTargetPt);
|
|
11013
|
+
if (tmpClosePt.distanceTo(pt) < region.gridHeight + 0.01) {
|
|
11014
|
+
inLinePts.push(pt);
|
|
11015
|
+
}
|
|
11016
|
+
});
|
|
11017
|
+
let lineGroup = [];
|
|
11018
|
+
let isFindPtIndex = [];
|
|
11019
|
+
while (true) {
|
|
11020
|
+
let tmpLine = [];
|
|
11021
|
+
for (let e = 0; e < inLinePts.length; e++) {
|
|
11022
|
+
if (isFindPtIndex.includes(e))
|
|
11023
|
+
continue;
|
|
11024
|
+
if (tmpLine.length == 0) {
|
|
11025
|
+
tmpLine.push(inLinePts[e]);
|
|
11026
|
+
isFindPtIndex.push(e);
|
|
11027
|
+
}
|
|
11028
|
+
}
|
|
11029
|
+
for (let c = 0; c < inLinePts.length; c++) {
|
|
11030
|
+
if (isFindPtIndex.includes(c))
|
|
11031
|
+
continue;
|
|
11032
|
+
for (let e = 0; e < tmpLine.length; e++) {
|
|
11033
|
+
if (inLinePts[c].distanceTo(tmpLine[e]) < region.gridWidth + 0.01) {
|
|
11034
|
+
tmpLine.push(inLinePts[c]);
|
|
11035
|
+
isFindPtIndex.push(c);
|
|
11036
|
+
c = -1;
|
|
11037
|
+
break;
|
|
11038
|
+
}
|
|
11039
|
+
}
|
|
11040
|
+
}
|
|
11041
|
+
if (tmpLine.length == 0)
|
|
11042
|
+
break;
|
|
11043
|
+
lineGroup.push(tmpLine);
|
|
11044
|
+
}
|
|
11045
|
+
const regionData = [];
|
|
11046
|
+
for (let e = 0; e < lineGroup.length; e++) {
|
|
11047
|
+
const obj = {
|
|
11048
|
+
lineSt: new THREE10.Vector3(),
|
|
11049
|
+
lineEd: new THREE10.Vector3(),
|
|
11050
|
+
facePoints: []
|
|
11051
|
+
};
|
|
11052
|
+
let resPts = getFarthestPoints(lineGroup[e]);
|
|
11053
|
+
if (Array.isArray(resPts) && resPts.length == 2) {
|
|
11054
|
+
obj.lineSt = resPts[0];
|
|
11055
|
+
obj.lineEd = resPts[1];
|
|
11056
|
+
obj.facePoints.push(new THREE10.Vector3(resPts[0].x, resPts[0].y, facePoints[0].z));
|
|
11057
|
+
obj.facePoints.push(new THREE10.Vector3(resPts[1].x, resPts[1].y, facePoints[0].z));
|
|
11058
|
+
obj.facePoints.push(new THREE10.Vector3(resPts[1].x, resPts[1].y, facePoints[2].z));
|
|
11059
|
+
obj.facePoints.push(new THREE10.Vector3(resPts[0].x, resPts[0].y, facePoints[2].z));
|
|
11060
|
+
regionData.push(obj);
|
|
11061
|
+
}
|
|
11062
|
+
}
|
|
11063
|
+
totalArea += region.area;
|
|
11064
|
+
let cutRegionArea = 0;
|
|
11065
|
+
if (totalInPlaneNum != 0) {
|
|
11066
|
+
cutRegionArea = region.gridHeight * region.gridWidth * totalInPlaneNum;
|
|
11067
|
+
}
|
|
11068
|
+
let areaPercentage = (region.area - cutRegionArea) / boxArea * 100;
|
|
11069
|
+
if (areaPercentage > 70 && regionData.length == 1 || regionData.length > 1) {
|
|
11070
|
+
for (let w = 0; w < regionData.length; w++) {
|
|
11071
|
+
const tmpRegion = regionData[w];
|
|
11072
|
+
let length2 = tmpRegion.facePoints[0].distanceTo(tmpRegion.facePoints[1]);
|
|
11073
|
+
let height = tmpRegion.facePoints[0].distanceTo(tmpRegion.facePoints[3]);
|
|
11074
|
+
let lengthPercentage = length2 / line2.length * 100;
|
|
11075
|
+
if (length2 < 0.2 || height < 0.2)
|
|
11076
|
+
continue;
|
|
11077
|
+
let addData = false;
|
|
11078
|
+
let isWindow = false;
|
|
11079
|
+
let beforePcdDoorIsFindBeam = false;
|
|
11080
|
+
let doorOpenVector = new THREE10.Vector3(0, 0, 0);
|
|
11081
|
+
let pcbDoorIndexs = [];
|
|
11082
|
+
let beamTmpSt = tmpRegion.facePoints[2].clone();
|
|
11083
|
+
let beamTmpEd = tmpRegion.facePoints[3].clone();
|
|
11084
|
+
let doorTmpSt = tmpRegion.facePoints[0].clone();
|
|
11085
|
+
let doorTmpEd = tmpRegion.facePoints[1].clone();
|
|
11086
|
+
let findDoorDataIndex = -1;
|
|
11087
|
+
if (Math.abs(tmpRegion.facePoints[0].z - line2.start.z) > 0.25 || Math.abs(tmpRegion.facePoints[0].z - line2.start.z) < 0.25 && height > 1) {
|
|
11088
|
+
const { newOriginalPoints } = getProjectedPointOnLine(doorTmpSt, doorTmpEd, line2.originalPoints);
|
|
11089
|
+
const topPoints = [];
|
|
11090
|
+
const bottomPoints = [];
|
|
11091
|
+
newOriginalPoints.forEach((p) => {
|
|
11092
|
+
if (p.z >= beamTmpSt.z)
|
|
11093
|
+
topPoints.push(p);
|
|
11094
|
+
else if (p.z <= doorTmpSt.z)
|
|
11095
|
+
bottomPoints.push(p);
|
|
11096
|
+
});
|
|
11097
|
+
let tmpBeamHeight = line2.rooftopPz - beamTmpSt.z;
|
|
11098
|
+
let otherBeamTmpSt = beamTmpSt.clone();
|
|
11099
|
+
otherBeamTmpSt.z += tmpBeamHeight;
|
|
11100
|
+
let tmpBeamLen = beamTmpSt.distanceTo(beamTmpEd);
|
|
11101
|
+
let tmpBeamVec = new THREE10.Vector3().subVectors(beamTmpEd, beamTmpSt).normalize();
|
|
11102
|
+
let cutNum = Math.round(Math.max(5, Math.min(350, 10 * Math.sqrt(tmpBeamLen))));
|
|
11103
|
+
let addCutLen = tmpBeamLen / cutNum;
|
|
11104
|
+
if (length2 > 0.2) {
|
|
11105
|
+
if (!line2.isLine2) {
|
|
11106
|
+
if (length2 < 3.5) {
|
|
11107
|
+
for (let n = 0; n < windowDatas.length; n++) {
|
|
11108
|
+
if (windowDatas[n].isFind) continue;
|
|
11109
|
+
let doorSt = new THREE10.Vector3(windowDatas[n].windowStartPt.x, windowDatas[n].windowStartPt.y, 0);
|
|
11110
|
+
let doorEd = new THREE10.Vector3(windowDatas[n].windowEndPt.x, windowDatas[n].windowEndPt.y, 0);
|
|
11111
|
+
let beamSt = new THREE10.Vector3(tmpRegion.facePoints[0].x, tmpRegion.facePoints[0].y, 0);
|
|
11112
|
+
let beamEd = new THREE10.Vector3(tmpRegion.facePoints[1].x, tmpRegion.facePoints[1].y, 0);
|
|
11113
|
+
let bIsTrue = tmpRegion.facePoints[2].z < windowDatas[n].maxZ || Math.abs(tmpRegion.facePoints[2].z - windowDatas[n].maxZ) < 0.3;
|
|
11114
|
+
let bIsSoTall = Math.abs(tmpRegion.facePoints[2].z - windowDatas[n].maxZ) > 0.2;
|
|
11115
|
+
if (bIsTrue) {
|
|
11116
|
+
let result = classifySegments(doorSt.clone(), doorEd.clone(), beamSt.clone(), beamEd.clone(), {
|
|
11117
|
+
distanceThreshold: 2
|
|
11118
|
+
});
|
|
11119
|
+
if (result && result.type == "collinear_gap") {
|
|
11120
|
+
let ptCenter = getMid(doorSt, doorEd);
|
|
11121
|
+
let line3 = new THREE10.Line3(new THREE10.Vector3(line2.start.x, line2.start.y, 0), new THREE10.Vector3(line2.end.x, line2.end.y, 0));
|
|
11122
|
+
let targeVec = new THREE10.Vector3();
|
|
11123
|
+
let ptClose = line3.closestPointToPoint(ptCenter, true, targeVec);
|
|
11124
|
+
let dist3 = ptCenter.distanceTo(ptClose);
|
|
11125
|
+
if (dist3 < 0.15) {
|
|
11126
|
+
let dist1 = beamSt.distanceTo(doorSt);
|
|
11127
|
+
let dist22 = beamEd.distanceTo(doorSt);
|
|
11128
|
+
if (dist1 > 0.25 && dist22 > 0.25) {
|
|
11129
|
+
let dist32 = beamSt.distanceTo(doorEd);
|
|
11130
|
+
let dist4 = beamEd.distanceTo(doorEd);
|
|
11131
|
+
if (dist32 > 0.2 && dist4 > 0.2) {
|
|
11132
|
+
continue;
|
|
11133
|
+
}
|
|
11134
|
+
}
|
|
11135
|
+
isWindow = true;
|
|
11136
|
+
pcbDoorIndexs.push(windowDatas[n].index);
|
|
11137
|
+
windowDatas[n].isFind = true;
|
|
11138
|
+
findDoorDataIndex = n;
|
|
11139
|
+
beforePcdDoorIsFindBeam = pcdData[windowDatas[n].index].isFindBeam;
|
|
11140
|
+
pcdData[windowDatas[n].index].isFindBeam = true;
|
|
11141
|
+
let beamVec = new THREE10.Vector3().subVectors(beamSt, beamEd).normalize();
|
|
11142
|
+
let doorLength = doorSt.distanceTo(doorEd) - result.overlap;
|
|
11143
|
+
if (dist22 < dist1)
|
|
11144
|
+
beamVec.negate();
|
|
11145
|
+
if (dist1 > dist22) {
|
|
11146
|
+
beamTmpSt = tmpRegion.facePoints[2].clone().addScaledVector(beamVec, doorLength);
|
|
11147
|
+
beamTmpEd = tmpRegion.facePoints[3].clone();
|
|
11148
|
+
doorTmpSt = beamTmpEd.clone();
|
|
11149
|
+
doorTmpEd = beamTmpSt.clone();
|
|
11150
|
+
doorTmpSt.z = doorTmpEd.z = tmpRegion.facePoints[0].z;
|
|
11151
|
+
} else {
|
|
11152
|
+
beamTmpSt = tmpRegion.facePoints[2].clone();
|
|
11153
|
+
beamTmpEd = tmpRegion.facePoints[3].clone().addScaledVector(beamVec, doorLength);
|
|
11154
|
+
doorTmpSt = beamTmpEd.clone();
|
|
11155
|
+
doorTmpEd = beamTmpSt.clone();
|
|
11156
|
+
doorTmpSt.z = doorTmpEd.z = tmpRegion.facePoints[0].z;
|
|
11157
|
+
}
|
|
11158
|
+
}
|
|
11159
|
+
} else if (result && result.type == "collinear_overlap" && result.maxPerpendicularDistance < 0.35) {
|
|
11160
|
+
let distTmp1 = beamSt.distanceTo(beamEd);
|
|
11161
|
+
let distTmp2 = doorEd.distanceTo(doorSt);
|
|
11162
|
+
if (Math.abs(distTmp1 - result.overlap) < 0.25 || Math.abs(distTmp2 - result.overlap) < 0.25) {
|
|
11163
|
+
if (length2 > 0.3) {
|
|
11164
|
+
isWindow = true;
|
|
11165
|
+
pcbDoorIndexs.push(windowDatas[n].index);
|
|
11166
|
+
windowDatas[n].isFind = true;
|
|
11167
|
+
beforePcdDoorIsFindBeam = pcdData[windowDatas[n].index].isFindBeam;
|
|
11168
|
+
pcdData[windowDatas[n].index].isFindBeam = true;
|
|
11169
|
+
findDoorDataIndex = n;
|
|
11170
|
+
}
|
|
11171
|
+
}
|
|
11172
|
+
}
|
|
11173
|
+
}
|
|
11174
|
+
}
|
|
11175
|
+
}
|
|
11176
|
+
if (length2 < 1.5) {
|
|
11177
|
+
for (let n = 0; n < windowDatas.length; n++) {
|
|
11178
|
+
if (windowDatas[n].inWall || windowDatas[n].isFind) continue;
|
|
11179
|
+
let doorSt = new THREE10.Vector3(windowDatas[n].windowStartPt.x, windowDatas[n].windowStartPt.y, 0);
|
|
11180
|
+
let doorEd = new THREE10.Vector3(windowDatas[n].windowEndPt.x, windowDatas[n].windowEndPt.y, 0);
|
|
11181
|
+
let beamSt = new THREE10.Vector3(beamTmpEd.x, beamTmpEd.y, 0);
|
|
11182
|
+
let beamEd = new THREE10.Vector3(beamTmpSt.x, beamTmpSt.y, 0);
|
|
11183
|
+
let vec1 = new THREE10.Vector3().subVectors(doorSt, doorEd).normalize();
|
|
11184
|
+
let vec2 = new THREE10.Vector3().subVectors(beamSt, beamEd).normalize();
|
|
11185
|
+
let nExtend = 0.25;
|
|
11186
|
+
let doorStExtended = doorSt.clone().addScaledVector(vec1, nExtend);
|
|
11187
|
+
let doorEdExtended = doorEd.clone().addScaledVector(vec1.clone().negate(), nExtend);
|
|
11188
|
+
let beamStExtended = beamSt.clone().addScaledVector(vec2, nExtend);
|
|
11189
|
+
let beamEdExtended = beamEd.clone().addScaledVector(vec2.clone().negate(), nExtend);
|
|
11190
|
+
let isPPP = getParallelism(doorStExtended, doorEdExtended, beamStExtended, beamEdExtended);
|
|
11191
|
+
if (isPPP.isParallel)
|
|
11192
|
+
continue;
|
|
11193
|
+
let insertPt = segmentsIntersect2D(doorStExtended, doorEdExtended, beamStExtended, beamEdExtended);
|
|
11194
|
+
let bIsTrue = true;
|
|
11195
|
+
let dist11 = doorSt.distanceTo(beamSt);
|
|
11196
|
+
let dist22 = doorSt.distanceTo(beamEd);
|
|
11197
|
+
let dist33 = doorEd.distanceTo(beamSt);
|
|
11198
|
+
let dist44 = doorEd.distanceTo(beamEd);
|
|
11199
|
+
let isNear = dist11 < nearDist || dist22 < nearDist || dist33 < nearDist || dist44 < nearDist;
|
|
11200
|
+
if ((isNear || insertPt) && bIsTrue) {
|
|
11201
|
+
beforePcdDoorIsFindBeam = pcdData[windowDatas[n].index].isFindBeam;
|
|
11202
|
+
pcdData[windowDatas[n].index].isFindBeam = true;
|
|
11203
|
+
isWindow = true;
|
|
11204
|
+
windowDatas[n].isFind = true;
|
|
11205
|
+
findDoorDataIndex = n;
|
|
11206
|
+
}
|
|
11207
|
+
}
|
|
11208
|
+
}
|
|
11209
|
+
}
|
|
11210
|
+
if (isWindow) {
|
|
11211
|
+
addData = true;
|
|
11212
|
+
}
|
|
11213
|
+
}
|
|
11214
|
+
}
|
|
11215
|
+
if (addData) {
|
|
11216
|
+
if (true) {
|
|
11217
|
+
let doorVector1 = new THREE10.Vector3().subVectors(doorTmpSt, doorTmpEd);
|
|
11218
|
+
let doorVector2 = new THREE10.Vector3().subVectors(doorTmpEd, doorTmpSt);
|
|
11219
|
+
let toDoorStNearDist = Infinity;
|
|
11220
|
+
let toDoorEdNearDist = Infinity;
|
|
11221
|
+
let newDoorTmpSt = doorTmpSt.clone();
|
|
11222
|
+
let newDoorTmpEd = doorTmpEd.clone();
|
|
11223
|
+
const nearFloorPoints = [];
|
|
11224
|
+
const nearTopPoints = [];
|
|
11225
|
+
let topDoorSegLine = new THREE10.Line3(beamTmpSt, beamTmpEd);
|
|
11226
|
+
let tmpTarget33 = new THREE10.Vector3();
|
|
11227
|
+
let addHeight = 999999;
|
|
11228
|
+
line2.originalPoints.forEach((point2) => {
|
|
11229
|
+
if (point2.z - doorTmpSt.z < height / 2 + 0.1 && point2.z - doorTmpSt.z > height / 2 - 0.1) {
|
|
11230
|
+
nearFloorPoints.push(point2);
|
|
11231
|
+
}
|
|
11232
|
+
if (point2.z > beamTmpSt.z) {
|
|
11233
|
+
let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(point2, true, tmpTarget33);
|
|
11234
|
+
let tmpVec1 = new THREE10.Vector3().subVectors(ptCloseTmp33, beamTmpSt);
|
|
11235
|
+
let tmpVec2 = new THREE10.Vector3().subVectors(ptCloseTmp33, beamTmpEd);
|
|
11236
|
+
let resP1 = isParallel(doorVector1, tmpVec2);
|
|
11237
|
+
let resP2 = isParallel(doorVector2, tmpVec1);
|
|
11238
|
+
if (resP1 && resP1.parallel && !resP1.sameDirection && resP2 && resP2.parallel && !resP2.sameDirection) {
|
|
11239
|
+
nearTopPoints.push(point2);
|
|
11240
|
+
}
|
|
11241
|
+
}
|
|
11242
|
+
});
|
|
11243
|
+
if (nearFloorPoints.length > 0) {
|
|
11244
|
+
const { newProjectPoints } = getProjectedPointOnLine(doorTmpSt, doorTmpEd, nearFloorPoints);
|
|
11245
|
+
for (const point2 of newProjectPoints) {
|
|
11246
|
+
point2.z = doorTmpSt.z;
|
|
11247
|
+
}
|
|
11248
|
+
newProjectPoints.forEach((point2) => {
|
|
11249
|
+
let newPt = new THREE10.Vector3(point2.x, point2.y, doorTmpSt.z);
|
|
11250
|
+
let tmpDoorVec1 = new THREE10.Vector3().subVectors(newPt, doorTmpEd);
|
|
11251
|
+
let tmpDoorVec2 = new THREE10.Vector3().subVectors(newPt, doorTmpSt);
|
|
11252
|
+
let resP1 = isParallel(doorVector1, tmpDoorVec2);
|
|
11253
|
+
let resP2 = isParallel(doorVector2, tmpDoorVec1);
|
|
11254
|
+
if (resP1 && resP1.parallel && resP1.sameDirection) {
|
|
11255
|
+
let tmpDist = newPt.distanceTo(doorTmpSt);
|
|
11256
|
+
if (tmpDist < toDoorStNearDist) {
|
|
11257
|
+
toDoorStNearDist = tmpDist;
|
|
11258
|
+
newDoorTmpSt = newPt;
|
|
11259
|
+
}
|
|
11260
|
+
} else if (resP2 && resP2.parallel && resP2.sameDirection) {
|
|
11261
|
+
let tmpDist = newPt.distanceTo(doorTmpEd);
|
|
11262
|
+
if (tmpDist < toDoorEdNearDist) {
|
|
11263
|
+
toDoorEdNearDist = tmpDist;
|
|
11264
|
+
newDoorTmpEd = newPt;
|
|
11265
|
+
}
|
|
11266
|
+
}
|
|
11267
|
+
});
|
|
11268
|
+
}
|
|
11269
|
+
if (!newDoorTmpSt.equals(doorTmpSt)) {
|
|
11270
|
+
doorTmpSt = newDoorTmpSt;
|
|
11271
|
+
beamTmpEd = new THREE10.Vector3(doorTmpSt.x, doorTmpSt.y, beamTmpEd.z);
|
|
11272
|
+
}
|
|
11273
|
+
if (!newDoorTmpEd.equals(doorTmpEd)) {
|
|
11274
|
+
doorTmpEd = newDoorTmpEd;
|
|
11275
|
+
beamTmpSt = new THREE10.Vector3(doorTmpEd.x, doorTmpEd.y, beamTmpSt.z);
|
|
11276
|
+
}
|
|
11277
|
+
if (nearTopPoints.length > 10) {
|
|
11278
|
+
const { newOnLinePoints } = getProjectedPointOnLine(beamTmpEd, beamTmpSt, nearTopPoints);
|
|
11279
|
+
for (let n = 0; n < newOnLinePoints.length; n++) {
|
|
11280
|
+
let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(newOnLinePoints[n], true, tmpTarget33);
|
|
11281
|
+
let add = ptCloseTmp33.distanceTo(newOnLinePoints[n]);
|
|
11282
|
+
if (add > 0.02) {
|
|
11283
|
+
if (addHeight > add)
|
|
11284
|
+
addHeight = add;
|
|
11285
|
+
}
|
|
11286
|
+
}
|
|
11287
|
+
beamTmpSt.z += addHeight;
|
|
11288
|
+
beamTmpEd.z += addHeight;
|
|
11289
|
+
height += addHeight;
|
|
11290
|
+
}
|
|
11291
|
+
}
|
|
11292
|
+
let isOverlap = false;
|
|
11293
|
+
for (let m = 0; m < allDoorLines1.length; m++) {
|
|
11294
|
+
let result = classifySegments(allDoorLines1[m].start, allDoorLines1[m].end, doorTmpSt, doorTmpEd);
|
|
11295
|
+
if (result && result.type == "collinear_overlap" && result.maxPerpendicularDistance < 0.07) {
|
|
11296
|
+
isOverlap = true;
|
|
11297
|
+
}
|
|
11298
|
+
}
|
|
11299
|
+
if (isOverlap) {
|
|
11300
|
+
if (findDoorDataIndex != -1) {
|
|
11301
|
+
if (!beforePcdDoorIsFindBeam) {
|
|
11302
|
+
pcdData[windowDatas[findDoorDataIndex].index].isFindBeam = false;
|
|
11303
|
+
windowDatas[findDoorDataIndex].isFind = false;
|
|
11304
|
+
}
|
|
11305
|
+
}
|
|
11306
|
+
continue;
|
|
11307
|
+
}
|
|
11308
|
+
let afterDoorLen = doorTmpEd.distanceTo(doorTmpSt);
|
|
11309
|
+
if (afterDoorLen < 0.4 && !isWindow || afterDoorLen < 0.3 && isWindow)
|
|
11310
|
+
continue;
|
|
11311
|
+
const windowLine = new THREE10.Line3(new THREE10.Vector3(doorTmpSt.x, doorTmpSt.y, 0), new THREE10.Vector3(doorTmpEd.x, doorTmpEd.y, 0));
|
|
11312
|
+
const windowPcd = windowDatas[findDoorDataIndex];
|
|
11313
|
+
const windowPcdSt = windowPcd.windowStartPt.clone();
|
|
11314
|
+
const windowPcdEd = windowPcd.windowEndPt.clone();
|
|
11315
|
+
windowPcdSt.z = windowPcdEd.z = doorTmpSt.z;
|
|
11316
|
+
let dist11 = doorTmpSt.distanceTo(windowPcdSt);
|
|
11317
|
+
let dist22 = doorTmpSt.distanceTo(windowPcdEd);
|
|
11318
|
+
let dist33 = doorTmpEd.distanceTo(windowPcdSt);
|
|
11319
|
+
let dist44 = doorTmpEd.distanceTo(windowPcdEd);
|
|
11320
|
+
let minDist = Math.min(dist11, dist22, dist33, dist44);
|
|
11321
|
+
let windowLen = windowPcdSt.distanceTo(windowPcdEd);
|
|
11322
|
+
let wZ = doorTmpSt.z;
|
|
11323
|
+
let ptClose = new THREE10.Vector3();
|
|
11324
|
+
let vec2 = new THREE10.Vector3();
|
|
11325
|
+
if (dist11 == minDist) {
|
|
11326
|
+
ptClose = windowLine.closestPointToPoint(windowPcdSt, false, new THREE10.Vector3());
|
|
11327
|
+
vec2 = new THREE10.Vector3().subVectors(doorTmpEd, doorTmpSt).normalize();
|
|
11328
|
+
} else if (dist22 == minDist) {
|
|
11329
|
+
ptClose = windowLine.closestPointToPoint(windowPcdEd, false, new THREE10.Vector3());
|
|
11330
|
+
vec2 = new THREE10.Vector3().subVectors(doorTmpEd, doorTmpSt).normalize();
|
|
11331
|
+
} else if (dist33 == minDist) {
|
|
11332
|
+
ptClose = windowLine.closestPointToPoint(windowPcdSt, false, new THREE10.Vector3());
|
|
11333
|
+
vec2 = new THREE10.Vector3().subVectors(doorTmpSt, doorTmpEd).normalize();
|
|
11334
|
+
} else if (dist44 == minDist) {
|
|
11335
|
+
ptClose = windowLine.closestPointToPoint(windowPcdEd, false, new THREE10.Vector3());
|
|
11336
|
+
vec2 = new THREE10.Vector3().subVectors(doorTmpSt, doorTmpEd).normalize();
|
|
11337
|
+
}
|
|
11338
|
+
doorTmpSt = ptClose.clone();
|
|
11339
|
+
doorTmpEd = doorTmpSt.clone().addScaledVector(vec2, windowLen);
|
|
11340
|
+
doorTmpSt.z = doorTmpEd.z = windowPcd.minZ;
|
|
11341
|
+
beamTmpSt = doorTmpSt.clone();
|
|
11342
|
+
beamTmpEd = doorTmpEd.clone();
|
|
11343
|
+
beamTmpSt.z = beamTmpEd.z = windowPcd.maxZ;
|
|
11344
|
+
let doorType = "";
|
|
11345
|
+
let groundClearance = doorTmpSt.z - line2.start.z > 1e-4 ? doorTmpSt.z - line2.start.z : 0;
|
|
11346
|
+
let beamHeight = beamTmpSt.z - doorTmpSt.z;
|
|
11347
|
+
let doorAndBeamDataObj = {
|
|
11348
|
+
id,
|
|
11349
|
+
windowTopSt: new THREE10.Vector3(doorTmpSt.x, doorTmpSt.y, doorTmpSt.z + beamHeight),
|
|
11350
|
+
windowTopEd: new THREE10.Vector3(doorTmpEd.x, doorTmpEd.y, doorTmpEd.z + beamHeight),
|
|
11351
|
+
beamHeight,
|
|
11352
|
+
windowBottomSt: doorTmpSt,
|
|
11353
|
+
windowBottomEd: doorTmpEd,
|
|
11354
|
+
// nearId: -1,
|
|
11355
|
+
// type: isExtendBeam ? "extendBeam" : "doorBeam",
|
|
11356
|
+
type: "window",
|
|
11357
|
+
isWindow,
|
|
11358
|
+
pcbDoorIndexs,
|
|
11359
|
+
groundClearance
|
|
11360
|
+
};
|
|
11361
|
+
line2.doorAndBeamIdToCheckResults.push([region.index, id]);
|
|
11362
|
+
line2.doorAndBeamData.push(doorAndBeamDataObj);
|
|
11363
|
+
doorBeamDataIndex.push({
|
|
11364
|
+
linesIndex: index,
|
|
11365
|
+
doorIndex: line2.doorAndBeamData.length - 1
|
|
11366
|
+
});
|
|
11367
|
+
allDoorLines1.push({
|
|
11368
|
+
start: doorTmpSt,
|
|
11369
|
+
end: doorTmpEd,
|
|
11370
|
+
index,
|
|
11371
|
+
id: doorAndBeamDataObj.id
|
|
11372
|
+
});
|
|
11373
|
+
if (!findDoorIndexs.includes(index))
|
|
11374
|
+
findDoorIndexs.push(index);
|
|
11375
|
+
id++;
|
|
11376
|
+
}
|
|
11377
|
+
}
|
|
11378
|
+
}
|
|
11379
|
+
}
|
|
11380
|
+
let faceArea = line2.length * (line2.rooftopPz - line2.start.z);
|
|
11381
|
+
line2.completePointAreaPercentage = totalArea / faceArea * 100;
|
|
11382
|
+
}
|
|
11383
|
+
if (findDoorIndexs.length > 1) {
|
|
11384
|
+
for (let j = 0; j < findDoorIndexs.length; j++) {
|
|
11385
|
+
let savedata2 = [];
|
|
11386
|
+
for (let d = 0; d < lines[findDoorIndexs[j]].doorAndBeamData.length; d++) {
|
|
11387
|
+
if (lines[findDoorIndexs[j]].doorAndBeamData[d].type != "window")
|
|
11388
|
+
continue;
|
|
11389
|
+
let isDel = false;
|
|
11390
|
+
if (!isDel) {
|
|
11391
|
+
let doorSt1 = lines[findDoorIndexs[j]].doorAndBeamData[d].windowBottomSt.clone();
|
|
11392
|
+
let doorEd1 = lines[findDoorIndexs[j]].doorAndBeamData[d].windowBottomEd.clone();
|
|
11393
|
+
doorSt1.z = doorEd1.z = 0;
|
|
11394
|
+
let doorLen1 = doorSt1.distanceTo(doorEd1);
|
|
11395
|
+
for (let b = 0; b < findDoorIndexs.length; b++) {
|
|
11396
|
+
if (j == b) continue;
|
|
11397
|
+
for (let r = 0; r < lines[findDoorIndexs[b]].doorAndBeamData.length; r++) {
|
|
11398
|
+
if (lines[findDoorIndexs[b]].doorAndBeamData[r].type != "window")
|
|
11399
|
+
continue;
|
|
11400
|
+
let doorSt2 = lines[findDoorIndexs[b]].doorAndBeamData[r].windowBottomSt.clone();
|
|
11401
|
+
let doorEd2 = lines[findDoorIndexs[b]].doorAndBeamData[r].windowBottomEd.clone();
|
|
11402
|
+
doorSt2.z = doorEd2.z = 0;
|
|
11403
|
+
let doorLen2 = doorSt2.distanceTo(doorEd2);
|
|
11404
|
+
let resultTmp = classifySegments(doorSt1, doorEd1, doorSt2, doorEd2);
|
|
11405
|
+
if (resultTmp.type == "collinear_overlap" && resultTmp.maxPerpendicularDistance < 0.2) {
|
|
11406
|
+
let line3 = new THREE10.Line3(doorSt2, doorEd2);
|
|
11407
|
+
let ptMid = getMid(doorSt1, doorEd1);
|
|
11408
|
+
let ptClose = line3.closestPointToPoint(ptMid, true, new THREE10.Vector3());
|
|
11409
|
+
let distTmp = ptMid.distanceTo(ptClose);
|
|
11410
|
+
if (Math.abs(doorLen1 - resultTmp.overlap) < 0.1 && distTmp < 0.04) {
|
|
11411
|
+
if (lines[findDoorIndexs[b]].doorAndBeamData[r].nearId == lines[findDoorIndexs[j]].doorAndBeamData[d].id) {
|
|
11412
|
+
lines[findDoorIndexs[b]].doorAndBeamData[r].nearId = -1;
|
|
11413
|
+
}
|
|
11414
|
+
isDel = true;
|
|
11415
|
+
break;
|
|
11416
|
+
}
|
|
11417
|
+
}
|
|
11418
|
+
}
|
|
11419
|
+
}
|
|
11420
|
+
}
|
|
11421
|
+
if (isDel) {
|
|
11422
|
+
for (let z = 0; z < lines[findDoorIndexs[j]].doorAndBeamIdToCheckResults.length; z++) {
|
|
11423
|
+
if (lines[findDoorIndexs[j]].doorAndBeamIdToCheckResults[1] == lines[findDoorIndexs[j]].doorAndBeamData[d].id) {
|
|
11424
|
+
lines[findDoorIndexs[j]].doorAndBeamIdToCheckResults.splice(z, 1);
|
|
11425
|
+
break;
|
|
11426
|
+
}
|
|
11427
|
+
}
|
|
11428
|
+
}
|
|
11429
|
+
if (!isDel) savedata2.push(lines[findDoorIndexs[j]].doorAndBeamData[d]);
|
|
11430
|
+
}
|
|
11431
|
+
if (savedata2.length != lines[findDoorIndexs[j]].doorAndBeamData.length)
|
|
11432
|
+
lines[findDoorIndexs[j]].doorAndBeamData = savedata2;
|
|
11433
|
+
}
|
|
11434
|
+
}
|
|
11435
|
+
let tmpLines = [];
|
|
11436
|
+
for (let i = 0; i < lines.length; i++) {
|
|
11437
|
+
if (!lines[i].isLine2)
|
|
11438
|
+
tmpLines.push(lines[i]);
|
|
11439
|
+
if (lines[i].isLine2 && lines[i].doorAndBeamData.length != 0)
|
|
11440
|
+
tmpLines.push(lines[i]);
|
|
11441
|
+
}
|
|
11442
|
+
lines.length = 0;
|
|
11443
|
+
lines.push(...tmpLines);
|
|
11444
|
+
return { lines, pcdData };
|
|
11445
|
+
};
|
|
11446
|
+
|
|
11447
|
+
// src/wall-window-matcher/utils.ts
|
|
11448
|
+
function dist2D(a, b) {
|
|
11449
|
+
const dx = a.x - b.x;
|
|
11450
|
+
const dy = a.y - b.y;
|
|
11451
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
11452
|
+
}
|
|
11453
|
+
function analyzeQuad(corners) {
|
|
11454
|
+
let maxLen = 0;
|
|
11455
|
+
let dirX = 0;
|
|
11456
|
+
let dirY = 0;
|
|
11457
|
+
for (let i = 0; i < 4; i++) {
|
|
11458
|
+
const a = corners[i];
|
|
11459
|
+
const b = corners[(i + 1) % 4];
|
|
11460
|
+
const dx = b.x - a.x;
|
|
11461
|
+
const dy = b.y - a.y;
|
|
11462
|
+
const len = Math.sqrt(dx * dx + dy * dy);
|
|
11463
|
+
if (len > maxLen) {
|
|
11464
|
+
maxLen = len;
|
|
11465
|
+
dirX = dx / len;
|
|
11466
|
+
dirY = dy / len;
|
|
11467
|
+
}
|
|
11468
|
+
}
|
|
11469
|
+
return { longSide: maxLen, dirX, dirY };
|
|
11470
|
+
}
|
|
11471
|
+
function computeLocalFloorZ(walls, cx, cy) {
|
|
11472
|
+
const radius = 3;
|
|
11473
|
+
const zs = [];
|
|
11474
|
+
for (const w of walls) {
|
|
11475
|
+
const mx = (w.start.x + w.end.x) / 2;
|
|
11476
|
+
const my = (w.start.y + w.end.y) / 2;
|
|
11477
|
+
const dx = mx - cx;
|
|
11478
|
+
const dy = my - cy;
|
|
11479
|
+
if (dx * dx + dy * dy <= radius * radius) {
|
|
11480
|
+
zs.push(w.start.z, w.end.z);
|
|
11481
|
+
}
|
|
11482
|
+
}
|
|
11483
|
+
if (zs.length === 0) {
|
|
11484
|
+
const allZ = [];
|
|
11485
|
+
for (const w of walls) allZ.push(w.start.z, w.end.z);
|
|
11486
|
+
if (!allZ.length) return -Infinity;
|
|
11487
|
+
allZ.sort((a, b) => a - b);
|
|
11488
|
+
return allZ[Math.floor(allZ.length / 2)];
|
|
11489
|
+
}
|
|
11490
|
+
zs.sort((a, b) => a - b);
|
|
11491
|
+
return zs[Math.floor(zs.length / 2)];
|
|
11492
|
+
}
|
|
11493
|
+
function pointToSegmentDist(cx, cy, ax, ay, bx, by) {
|
|
11494
|
+
const vx = bx - ax;
|
|
11495
|
+
const vy = by - ay;
|
|
11496
|
+
const len2 = vx * vx + vy * vy;
|
|
11497
|
+
if (len2 < 1e-12) {
|
|
11498
|
+
return { dist: Math.sqrt((cx - ax) ** 2 + (cy - ay) ** 2), t: 0 };
|
|
11499
|
+
}
|
|
11500
|
+
const wx = cx - ax;
|
|
11501
|
+
const wy = cy - ay;
|
|
11502
|
+
const t = (wx * vx + wy * vy) / len2;
|
|
11503
|
+
const projX = ax + t * vx;
|
|
11504
|
+
const projY = ay + t * vy;
|
|
11505
|
+
const dist3 = Math.sqrt((cx - projX) ** 2 + (cy - projY) ** 2);
|
|
11506
|
+
return { dist: dist3, t };
|
|
11507
|
+
}
|
|
11508
|
+
function pointInQuad(px, py, quad) {
|
|
11509
|
+
let sign = 0;
|
|
11510
|
+
for (let i = 0; i < 4; i++) {
|
|
11511
|
+
const a = quad[i];
|
|
11512
|
+
const b = quad[(i + 1) % 4];
|
|
11513
|
+
const cross3 = (b.x - a.x) * (py - a.y) - (b.y - a.y) * (px - a.x);
|
|
11514
|
+
if (Math.abs(cross3) < 1e-12) continue;
|
|
11515
|
+
const s = cross3 > 0 ? 1 : -1;
|
|
11516
|
+
if (sign === 0) sign = s;
|
|
11517
|
+
else if (sign !== s) return false;
|
|
11518
|
+
}
|
|
11519
|
+
return true;
|
|
11520
|
+
}
|
|
11521
|
+
function segSegIntersect(ax, ay, bx, by, cx, cy, dx, dy) {
|
|
11522
|
+
const rX = bx - ax;
|
|
10907
11523
|
const rY = by - ay;
|
|
10908
11524
|
const sX = dx - cx;
|
|
10909
11525
|
const sY = dy - cy;
|
|
@@ -11938,7 +12554,7 @@ function processData(wallSegments, objects, options) {
|
|
|
11938
12554
|
}
|
|
11939
12555
|
|
|
11940
12556
|
// src/wall-door-matcher/matcher.ts
|
|
11941
|
-
import * as
|
|
12557
|
+
import * as THREE11 from "three";
|
|
11942
12558
|
|
|
11943
12559
|
// src/wall-door-matcher/utils.ts
|
|
11944
12560
|
function dist2D2(a, b) {
|
|
@@ -12783,13 +13399,13 @@ function collectCandidates2(candidateSegments, doorLong, doorDirX, doorDirY, che
|
|
|
12783
13399
|
if (isLine2)
|
|
12784
13400
|
continue;
|
|
12785
13401
|
if (passageEntrance) {
|
|
12786
|
-
const pt1 = new
|
|
12787
|
-
const pt2 = new
|
|
13402
|
+
const pt1 = new THREE11.Vector3(nline.start.x, nline.start.y, nline.start.z);
|
|
13403
|
+
const pt2 = new THREE11.Vector3(nline.end.x, nline.end.y, nline.end.z);
|
|
12788
13404
|
let isOverLap = false;
|
|
12789
13405
|
for (let v2 = 0; v2 < passageEntrance.length; v2++) {
|
|
12790
13406
|
const data = passageEntrance[v2];
|
|
12791
|
-
const pt3 = new
|
|
12792
|
-
const pt4 = new
|
|
13407
|
+
const pt3 = new THREE11.Vector3(data.start.x, data.start.y, data.start.z);
|
|
13408
|
+
const pt4 = new THREE11.Vector3(data.end.x, data.end.y, data.end.z);
|
|
12793
13409
|
let resultTmp = classifySegments(pt1, pt2, pt3, pt4);
|
|
12794
13410
|
if (resultTmp.type == "collinear_overlap" && resultTmp.maxPerpendicularDistance < 0.1) {
|
|
12795
13411
|
isOverLap = true;
|
|
@@ -17018,6 +17634,7 @@ export {
|
|
|
17018
17634
|
detectPerpWalls,
|
|
17019
17635
|
detectPerpendicularWalls,
|
|
17020
17636
|
drawStaircase,
|
|
17637
|
+
expansionLine,
|
|
17021
17638
|
filterFalseArcCurves,
|
|
17022
17639
|
filterWalls,
|
|
17023
17640
|
filterWallsHard,
|
|
@@ -17034,6 +17651,7 @@ export {
|
|
|
17034
17651
|
getOneLineClusterResults,
|
|
17035
17652
|
getSlabData,
|
|
17036
17653
|
getStaircase,
|
|
17654
|
+
getWindowData,
|
|
17037
17655
|
isRawLineNearArc,
|
|
17038
17656
|
logArcRawSegments,
|
|
17039
17657
|
matchWalls,
|