rm-graphical-computing-node 1.0.44 → 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 +798 -196
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -3782,7 +3782,7 @@ function getTrendLineEndpoints(points, options = {}) {
3782
3782
  }
3783
3783
 
3784
3784
  // src/geometry/beamLine.mjs
3785
- import { Line as Line2 } from "three";
3785
+ import { Const } from "three/tsl";
3786
3786
  var getBeamLine = async (lines, runDataList, pcdData, lineReader, lineEditor, onProgress = null) => {
3787
3787
  removeNoisePoints(lines, lineReader, lineEditor);
3788
3788
  if (lines.length <= 0 || runDataList.length <= 0)
@@ -3939,11 +3939,11 @@ var getBeamLine = async (lines, runDataList, pcdData, lineReader, lineEditor, on
3939
3939
  let dist1 = door.doorStartPt.distanceTo(door.doorEndPt);
3940
3940
  let dist22 = newDoorSt.distanceTo(newDoorEd);
3941
3941
  let res = getParallelism(door.doorStartPt, door.doorEndPt, newDoorSt, newDoorEd);
3942
- if (Math.abs(dist22 - dist1) < 0.5 && res && res.angleDeg < 15) {
3942
+ if (Math.abs(dist22 - dist1) < 0.5 && res && res.angleDeg < 10) {
3943
3943
  door.doorStartPt = new THREE5.Vector3(lines[u4].start.x, lines[u4].start.y, 0);
3944
3944
  door.doorEndPt = new THREE5.Vector3(lines[u4].end.x, lines[u4].end.y, 0);
3945
3945
  break;
3946
- } else if (Math.abs(dist22 - dist1) > 1.3 && res && res.angleDeg < 15) {
3946
+ } else if (Math.abs(dist22 - dist1) > 1.3 && res && res.angleDeg < 10) {
3947
3947
  let restmp = classifySegments(door.doorStartPt, door.doorEndPt, newDoorSt, newDoorEd, { parallelAngleMax: THREE5.MathUtils.degToRad(15) });
3948
3948
  let dist11 = door.doorStartPt.distanceTo(newDoorSt);
3949
3949
  let dist12 = door.doorStartPt.distanceTo(newDoorEd);
@@ -4543,84 +4543,13 @@ var getBeamLine = async (lines, runDataList, pcdData, lineReader, lineEditor, on
4543
4543
  }
4544
4544
  }
4545
4545
  if (addData) {
4546
- if (
4547
- /**!isPullOutDoor */
4548
- true
4549
- ) {
4550
- let doorVector1 = new THREE5.Vector3().subVectors(doorTmpSt, doorTmpEd);
4551
- let doorVector2 = new THREE5.Vector3().subVectors(doorTmpEd, doorTmpSt);
4552
- let toDoorStNearDist = Infinity;
4553
- let toDoorEdNearDist = Infinity;
4554
- let newDoorTmpSt = doorTmpSt.clone();
4555
- let newDoorTmpEd = doorTmpEd.clone();
4556
- const nearFloorPoints = [];
4557
- const nearTopPoints = [];
4558
- let topDoorSegLine = new THREE5.Line3(beamTmpSt, beamTmpEd);
4559
- let tmpTarget33 = new THREE5.Vector3();
4560
- let addHeight = 999999;
4561
- line2.originalPoints.forEach((point2) => {
4562
- if (point2.z - doorTmpSt.z < height / 2 + 0.1 && point2.z - doorTmpSt.z > height / 2 - 0.1) {
4563
- nearFloorPoints.push(point2);
4564
- }
4565
- if (point2.z > beamTmpSt.z) {
4566
- let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(point2, true, tmpTarget33);
4567
- let tmpVec1 = new THREE5.Vector3().subVectors(ptCloseTmp33, beamTmpSt);
4568
- let tmpVec2 = new THREE5.Vector3().subVectors(ptCloseTmp33, beamTmpEd);
4569
- let resP1 = isParallel(doorVector1, tmpVec2);
4570
- let resP2 = isParallel(doorVector2, tmpVec1);
4571
- if (resP1 && resP1.parallel && !resP1.sameDirection && resP2 && resP2.parallel && !resP2.sameDirection) {
4572
- nearTopPoints.push(point2);
4573
- }
4574
- }
4575
- });
4576
- if (nearFloorPoints.length > 0) {
4577
- const { newProjectPoints } = getProjectedPointOnLine(doorTmpSt, doorTmpEd, nearFloorPoints);
4578
- for (const point2 of newProjectPoints) {
4579
- point2.z = doorTmpSt.z;
4580
- }
4581
- newProjectPoints.forEach((point2) => {
4582
- let newPt = new THREE5.Vector3(point2.x, point2.y, doorTmpSt.z);
4583
- let tmpDoorVec1 = new THREE5.Vector3().subVectors(newPt, doorTmpEd);
4584
- let tmpDoorVec2 = new THREE5.Vector3().subVectors(newPt, doorTmpSt);
4585
- let resP1 = isParallel(doorVector1, tmpDoorVec2);
4586
- let resP2 = isParallel(doorVector2, tmpDoorVec1);
4587
- if (resP1 && resP1.parallel && resP1.sameDirection) {
4588
- let tmpDist = newPt.distanceTo(doorTmpSt);
4589
- if (tmpDist < toDoorStNearDist) {
4590
- toDoorStNearDist = tmpDist;
4591
- newDoorTmpSt = newPt;
4592
- }
4593
- } else if (resP2 && resP2.parallel && resP2.sameDirection) {
4594
- let tmpDist = newPt.distanceTo(doorTmpEd);
4595
- if (tmpDist < toDoorEdNearDist) {
4596
- toDoorEdNearDist = tmpDist;
4597
- newDoorTmpEd = newPt;
4598
- }
4599
- }
4600
- });
4601
- }
4602
- if (!newDoorTmpSt.equals(doorTmpSt)) {
4603
- doorTmpSt = newDoorTmpSt;
4604
- beamTmpEd = new THREE5.Vector3(doorTmpSt.x, doorTmpSt.y, beamTmpEd.z);
4605
- }
4606
- if (!newDoorTmpEd.equals(doorTmpEd)) {
4607
- doorTmpEd = newDoorTmpEd;
4608
- beamTmpSt = new THREE5.Vector3(doorTmpEd.x, doorTmpEd.y, beamTmpSt.z);
4609
- }
4610
- if (nearTopPoints.length > 10) {
4611
- const { newOnLinePoints } = getProjectedPointOnLine(beamTmpEd, beamTmpSt, nearTopPoints);
4612
- for (let n = 0; n < newOnLinePoints.length; n++) {
4613
- let ptCloseTmp33 = topDoorSegLine.closestPointToPoint(newOnLinePoints[n], true, tmpTarget33);
4614
- let add = ptCloseTmp33.distanceTo(newOnLinePoints[n]);
4615
- if (add > 0.02) {
4616
- if (addHeight > add)
4617
- addHeight = add;
4618
- }
4619
- }
4620
- beamTmpSt.z += addHeight;
4621
- beamTmpEd.z += addHeight;
4622
- height += addHeight;
4623
- }
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;
4624
4553
  }
4625
4554
  let isOverlap = false;
4626
4555
  for (let m = 0; m < allDoorLines1.length; m++) {
@@ -5317,6 +5246,89 @@ var checkBeamIsReasonable = async (lines, lineReader) => {
5317
5246
  }
5318
5247
  }
5319
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
+ };
5320
5332
 
5321
5333
  // src/geometry/colLine.mjs
5322
5334
  import * as THREE6 from "three";
@@ -10829,83 +10841,686 @@ var getFlatSlabData = (lines, runDataList, pointCloudCluster = null) => {
10829
10841
  return slabDatas;
10830
10842
  };
10831
10843
 
10832
- // src/wall-window-matcher/utils.ts
10833
- function dist2D(a, b) {
10834
- const dx = a.x - b.x;
10835
- const dy = a.y - b.y;
10836
- return Math.sqrt(dx * dx + dy * dy);
10837
- }
10838
- function analyzeQuad(corners) {
10839
- let maxLen = 0;
10840
- let dirX = 0;
10841
- let dirY = 0;
10842
- for (let i = 0; i < 4; i++) {
10843
- const a = corners[i];
10844
- const b = corners[(i + 1) % 4];
10845
- const dx = b.x - a.x;
10846
- const dy = b.y - a.y;
10847
- const len = Math.sqrt(dx * dx + dy * dy);
10848
- if (len > maxLen) {
10849
- maxLen = len;
10850
- dirX = dx / len;
10851
- 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);
10852
10936
  }
10937
+ line2.mergeCheckRegion = allRegion;
10853
10938
  }
10854
- return { longSide: maxLen, dirX, dirY };
10855
- }
10856
- function computeLocalFloorZ(walls, cx, cy) {
10857
- const radius = 3;
10858
- const zs = [];
10859
- for (const w of walls) {
10860
- const mx = (w.start.x + w.end.x) / 2;
10861
- const my = (w.start.y + w.end.y) / 2;
10862
- const dx = mx - cx;
10863
- const dy = my - cy;
10864
- if (dx * dx + dy * dy <= radius * radius) {
10865
- 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
+ });
10866
10972
  }
10867
10973
  }
10868
- if (zs.length === 0) {
10869
- const allZ = [];
10870
- for (const w of walls) allZ.push(w.start.z, w.end.z);
10871
- if (!allZ.length) return -Infinity;
10872
- allZ.sort((a, b) => a - b);
10873
- return allZ[Math.floor(allZ.length / 2)];
10874
- }
10875
- zs.sort((a, b) => a - b);
10876
- return zs[Math.floor(zs.length / 2)];
10877
- }
10878
- function pointToSegmentDist(cx, cy, ax, ay, bx, by) {
10879
- const vx = bx - ax;
10880
- const vy = by - ay;
10881
- const len2 = vx * vx + vy * vy;
10882
- if (len2 < 1e-12) {
10883
- return { dist: Math.sqrt((cx - ax) ** 2 + (cy - ay) ** 2), t: 0 };
10884
- }
10885
- const wx = cx - ax;
10886
- const wy = cy - ay;
10887
- const t = (wx * vx + wy * vy) / len2;
10888
- const projX = ax + t * vx;
10889
- const projY = ay + t * vy;
10890
- const dist3 = Math.sqrt((cx - projX) ** 2 + (cy - projY) ** 2);
10891
- return { dist: dist3, t };
10892
- }
10893
- function pointInQuad(px, py, quad) {
10894
- let sign = 0;
10895
- for (let i = 0; i < 4; i++) {
10896
- const a = quad[i];
10897
- const b = quad[(i + 1) % 4];
10898
- const cross3 = (b.x - a.x) * (py - a.y) - (b.y - a.y) * (px - a.x);
10899
- if (Math.abs(cross3) < 1e-12) continue;
10900
- const s = cross3 > 0 ? 1 : -1;
10901
- if (sign === 0) sign = s;
10902
- else if (sign !== s) return false;
10903
- }
10904
- return true;
10905
- }
10906
- function segSegIntersect(ax, ay, bx, by, cx, cy, dx, dy) {
10907
- const rX = bx - ax;
10908
- const rY = by - ay;
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;
11523
+ const rY = by - ay;
10909
11524
  const sX = dx - cx;
10910
11525
  const sY = dy - cy;
10911
11526
  const denom = rX * sY - rY * sX;
@@ -11938,6 +12553,9 @@ function processData(wallSegments, objects, options) {
11938
12553
  return { segments: finalSegments, matches };
11939
12554
  }
11940
12555
 
12556
+ // src/wall-door-matcher/matcher.ts
12557
+ import * as THREE11 from "three";
12558
+
11941
12559
  // src/wall-door-matcher/utils.ts
11942
12560
  function dist2D2(a, b) {
11943
12561
  const dx = a.x - b.x;
@@ -12777,7 +13395,26 @@ function collectCandidates2(candidateSegments, doorLong, doorDirX, doorDirY, che
12777
13395
  for (const attempt of matchAttempts) {
12778
13396
  if (passingCandidates.length > 0) break;
12779
13397
  for (const seg of candidateSegments) {
12780
- const { start, end } = seg;
13398
+ const { start, end, isLine2, passageEntrance } = seg;
13399
+ if (isLine2)
13400
+ continue;
13401
+ if (passageEntrance) {
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);
13404
+ let isOverLap = false;
13405
+ for (let v2 = 0; v2 < passageEntrance.length; v2++) {
13406
+ const data = passageEntrance[v2];
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);
13409
+ let resultTmp = classifySegments(pt1, pt2, pt3, pt4);
13410
+ if (resultTmp.type == "collinear_overlap" && resultTmp.maxPerpendicularDistance < 0.1) {
13411
+ isOverLap = true;
13412
+ break;
13413
+ }
13414
+ }
13415
+ if (isOverLap)
13416
+ continue;
13417
+ }
12781
13418
  let validPoint = false;
12782
13419
  let minDist = Infinity;
12783
13420
  for (const pt of checkPoints) {
@@ -12924,8 +13561,6 @@ function mergeSourceData2(ws, srcIdxs, wallSegments) {
12924
13561
  if (boxData) ws.boxData = boxData;
12925
13562
  if (maxRooftopPz !== void 0) ws.rooftopPz = maxRooftopPz;
12926
13563
  }
12927
- function logDrawDoorSummary(mergedSegments) {
12928
- }
12929
13564
  function detectPerpendicularWalls2(match, mergedSegments, angleTol = 10, distTol = 0.2, perpDistTol = 0.2) {
12930
13565
  const results = [];
12931
13566
  if (!match.DrawDoor) return results;
@@ -13123,16 +13758,6 @@ function findDoorWalls(doorObjs, wallSegments, options, preMerged) {
13123
13758
  const checkPoints = getCheckPoints2(corners, centerX, centerY);
13124
13759
  debugScanDoor(door.name, candidateSegments, centerX, centerY, checkPoints, doorLong, doorDirX, doorDirY, opts);
13125
13760
  let passingCandidates = collectCandidates2(candidateSegments, actualDoorWidth, doorDirX, doorDirY, checkPoints, opts, door.name, verticalEdges, door.nline);
13126
- if (passingCandidates.length > 0) {
13127
- for (let ci = 0; ci < passingCandidates.length; ci++) {
13128
- const pc = passingCandidates[ci];
13129
- const seg = pc.seg;
13130
- const hasHinge = !!pc.hingeInfo?.hingePoint;
13131
- const isClosed = pc.hingeInfo?.isClosed;
13132
- const hDist = pc.hingeInfo?.hingeDist ?? -1;
13133
- const centerProj = pointToSegmentDist2(checkPoints[0].x, checkPoints[0].y, seg.start.x, seg.start.y, seg.end.x, seg.end.y);
13134
- }
13135
- }
13136
13761
  passingCandidates = rankCandidates2(passingCandidates, checkPoints, wallSegments, door.name);
13137
13762
  if (passingCandidates.length === 0) {
13138
13763
  for (const seg of candidateSegments) {
@@ -13221,9 +13846,6 @@ function findDoorWalls(doorObjs, wallSegments, options, preMerged) {
13221
13846
  };
13222
13847
  }
13223
13848
  }
13224
- if (door.name.includes("door_002")) {
13225
- window.__doorLog = true;
13226
- }
13227
13849
  ;
13228
13850
  pc.densityScore = densityScore.score;
13229
13851
  pc.densityOverlap = densityScore.bestOverlap;
@@ -13242,19 +13864,6 @@ function findDoorWalls(doorObjs, wallSegments, options, preMerged) {
13242
13864
  pc.densityScore = -1;
13243
13865
  }
13244
13866
  }
13245
- if (door.name.includes("door_002")) {
13246
- for (let pi = 0; pi < passingCandidates.length; pi++) {
13247
- const pc = passingCandidates[pi];
13248
- const s = pc.seg;
13249
- const segIdx = candidateSegments.findIndex(
13250
- (cs) => Math.abs(cs.start.x - s.start.x) < 1e-3 && Math.abs(cs.start.y - s.start.y) < 1e-3 && Math.abs(cs.end.x - s.end.x) < 1e-3 && Math.abs(cs.end.y - s.end.y) < 1e-3
13251
- );
13252
- const origIndices = segIdx >= 0 ? mergeSourceMap[segIdx] || [] : [];
13253
- for (const oi of origIndices) {
13254
- const orig = wallSegments[oi];
13255
- }
13256
- }
13257
- }
13258
13867
  passingCandidates.sort((a, b) => {
13259
13868
  const da2 = a.densityScore >= 0 ? a.densityScore : -Infinity;
13260
13869
  const db = b.densityScore >= 0 ? b.densityScore : -Infinity;
@@ -13271,14 +13880,6 @@ function findDoorWalls(doorObjs, wallSegments, options, preMerged) {
13271
13880
  if (ha !== hb) return hb - ha;
13272
13881
  return a.minDist - b.minDist;
13273
13882
  });
13274
- if (passingCandidates.length > 0) {
13275
- for (let ci = 0; ci < passingCandidates.length; ci++) {
13276
- const pc = passingCandidates[ci];
13277
- const s = pc.seg;
13278
- const ratio = pc.ratio || s.length / doorWidth;
13279
- const ratioDiff = Math.abs(ratio - 1);
13280
- }
13281
- }
13282
13883
  let bestSeg = null;
13283
13884
  let bestDist = Infinity;
13284
13885
  let bestRatio = 0;
@@ -13400,7 +14001,6 @@ function findDoorWalls(doorObjs, wallSegments, options, preMerged) {
13400
14001
  if (!srcIdxs || srcIdxs.length <= 1) continue;
13401
14002
  mergeSourceData2(ws, srcIdxs, wallSegments);
13402
14003
  }
13403
- logDrawDoorSummary(mergedSegments);
13404
14004
  return results;
13405
14005
  }
13406
14006
 
@@ -13922,10 +14522,10 @@ function normalizeAngles(lines) {
13922
14522
  hist[binIdx] += len;
13923
14523
  }
13924
14524
  const smooth = new Array(bins).fill(0);
13925
- const window2 = 5;
14525
+ const window = 5;
13926
14526
  for (let i = 0; i < bins; i++) {
13927
14527
  let sum2 = 0;
13928
- for (let j = -window2; j <= window2; j++) {
14528
+ for (let j = -window; j <= window; j++) {
13929
14529
  let idx = i + j;
13930
14530
  if (idx < 0) idx += bins;
13931
14531
  if (idx >= bins) idx -= bins;
@@ -16346,10 +16946,10 @@ function normalizeAngles2(lines) {
16346
16946
  hist[binIdx] += len;
16347
16947
  }
16348
16948
  const smooth = new Array(bins).fill(0);
16349
- const window2 = 5;
16949
+ const window = 5;
16350
16950
  for (let i = 0; i < bins; i++) {
16351
16951
  let sum2 = 0;
16352
- for (let j = -window2; j <= window2; j++) {
16952
+ for (let j = -window; j <= window; j++) {
16353
16953
  let idx = i + j;
16354
16954
  if (idx < 0) idx += bins;
16355
16955
  if (idx >= bins) idx -= bins;
@@ -17034,6 +17634,7 @@ export {
17034
17634
  detectPerpWalls,
17035
17635
  detectPerpendicularWalls,
17036
17636
  drawStaircase,
17637
+ expansionLine,
17037
17638
  filterFalseArcCurves,
17038
17639
  filterWalls,
17039
17640
  filterWallsHard,
@@ -17050,6 +17651,7 @@ export {
17050
17651
  getOneLineClusterResults,
17051
17652
  getSlabData,
17052
17653
  getStaircase,
17654
+ getWindowData,
17053
17655
  isRawLineNearArc,
17054
17656
  logArcRawSegments,
17055
17657
  matchWalls,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rm-graphical-computing-node",
3
- "version": "1.0.44",
3
+ "version": "1.0.46",
4
4
  "description": "墙体/梁线/点云语义计算库(依赖 Python 与 three.js)",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",