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.
Files changed (2) hide show
  1. package/dist/index.mjs +773 -155
  2. 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
- if (
4546
- /**!isPullOutDoor */
4547
- true
4548
- ) {
4549
- let doorVector1 = new THREE5.Vector3().subVectors(doorTmpSt, doorTmpEd);
4550
- let doorVector2 = new THREE5.Vector3().subVectors(doorTmpEd, doorTmpSt);
4551
- let toDoorStNearDist = Infinity;
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/wall-window-matcher/utils.ts
10832
- function dist2D(a, b) {
10833
- const dx = a.x - b.x;
10834
- const dy = a.y - b.y;
10835
- return Math.sqrt(dx * dx + dy * dy);
10836
- }
10837
- function analyzeQuad(corners) {
10838
- let maxLen = 0;
10839
- let dirX = 0;
10840
- let dirY = 0;
10841
- for (let i = 0; i < 4; i++) {
10842
- const a = corners[i];
10843
- const b = corners[(i + 1) % 4];
10844
- const dx = b.x - a.x;
10845
- const dy = b.y - a.y;
10846
- const len = Math.sqrt(dx * dx + dy * dy);
10847
- if (len > maxLen) {
10848
- maxLen = len;
10849
- dirX = dx / len;
10850
- dirY = dy / len;
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
- return { longSide: maxLen, dirX, dirY };
10854
- }
10855
- function computeLocalFloorZ(walls, cx, cy) {
10856
- const radius = 3;
10857
- const zs = [];
10858
- for (const w of walls) {
10859
- const mx = (w.start.x + w.end.x) / 2;
10860
- const my = (w.start.y + w.end.y) / 2;
10861
- const dx = mx - cx;
10862
- const dy = my - cy;
10863
- if (dx * dx + dy * dy <= radius * radius) {
10864
- zs.push(w.start.z, w.end.z);
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
- if (zs.length === 0) {
10868
- const allZ = [];
10869
- for (const w of walls) allZ.push(w.start.z, w.end.z);
10870
- if (!allZ.length) return -Infinity;
10871
- allZ.sort((a, b) => a - b);
10872
- return allZ[Math.floor(allZ.length / 2)];
10873
- }
10874
- zs.sort((a, b) => a - b);
10875
- return zs[Math.floor(zs.length / 2)];
10876
- }
10877
- function pointToSegmentDist(cx, cy, ax, ay, bx, by) {
10878
- const vx = bx - ax;
10879
- const vy = by - ay;
10880
- const len2 = vx * vx + vy * vy;
10881
- if (len2 < 1e-12) {
10882
- return { dist: Math.sqrt((cx - ax) ** 2 + (cy - ay) ** 2), t: 0 };
10883
- }
10884
- const wx = cx - ax;
10885
- const wy = cy - ay;
10886
- const t = (wx * vx + wy * vy) / len2;
10887
- const projX = ax + t * vx;
10888
- const projY = ay + t * vy;
10889
- const dist3 = Math.sqrt((cx - projX) ** 2 + (cy - projY) ** 2);
10890
- return { dist: dist3, t };
10891
- }
10892
- function pointInQuad(px, py, quad) {
10893
- let sign = 0;
10894
- for (let i = 0; i < 4; i++) {
10895
- const a = quad[i];
10896
- const b = quad[(i + 1) % 4];
10897
- const cross3 = (b.x - a.x) * (py - a.y) - (b.y - a.y) * (px - a.x);
10898
- if (Math.abs(cross3) < 1e-12) continue;
10899
- const s = cross3 > 0 ? 1 : -1;
10900
- if (sign === 0) sign = s;
10901
- else if (sign !== s) return false;
10902
- }
10903
- return true;
10904
- }
10905
- function segSegIntersect(ax, ay, bx, by, cx, cy, dx, dy) {
10906
- const rX = bx - ax;
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 THREE10 from "three";
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 THREE10.Vector3(nline.start.x, nline.start.y, nline.start.z);
12787
- const pt2 = new THREE10.Vector3(nline.end.x, nline.end.y, nline.end.z);
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 THREE10.Vector3(data.start.x, data.start.y, data.start.z);
12792
- const pt4 = new THREE10.Vector3(data.end.x, data.end.y, data.end.z);
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rm-graphical-computing-node",
3
- "version": "1.0.45",
3
+ "version": "1.0.46",
4
4
  "description": "墙体/梁线/点云语义计算库(依赖 Python 与 three.js)",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",