rm-graphical-computing 1.0.52 → 1.0.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +229 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +500 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -4279,4 +4279,503 @@ var Kn = (t) => {
|
|
|
4279
4279
|
return i;
|
|
4280
4280
|
};
|
|
4281
4281
|
//#endregion
|
|
4282
|
-
|
|
4282
|
+
//#region src/wall-window-matcher/utils.ts
|
|
4283
|
+
function qn(e, t) {
|
|
4284
|
+
let n = e.x - t.x, r = e.y - t.y;
|
|
4285
|
+
return Math.sqrt(n * n + r * r);
|
|
4286
|
+
}
|
|
4287
|
+
function Jn(e) {
|
|
4288
|
+
let t = 0, n = 0, r = 0;
|
|
4289
|
+
for (let i = 0; i < 4; i++) {
|
|
4290
|
+
let a = e[i], o = e[(i + 1) % 4], s = o.x - a.x, c = o.y - a.y, l = Math.sqrt(s * s + c * c);
|
|
4291
|
+
l > t && (t = l, n = s / l, r = c / l);
|
|
4292
|
+
}
|
|
4293
|
+
return {
|
|
4294
|
+
longSide: t,
|
|
4295
|
+
dirX: n,
|
|
4296
|
+
dirY: r
|
|
4297
|
+
};
|
|
4298
|
+
}
|
|
4299
|
+
function Yn(e, t, n) {
|
|
4300
|
+
let r = [];
|
|
4301
|
+
for (let i of e) {
|
|
4302
|
+
let e = (i.start.x + i.end.x) / 2, a = (i.start.y + i.end.y) / 2, o = e - t, s = a - n;
|
|
4303
|
+
o * o + s * s <= 9 && r.push(i.start.z, i.end.z);
|
|
4304
|
+
}
|
|
4305
|
+
if (r.length === 0) {
|
|
4306
|
+
let t = [];
|
|
4307
|
+
for (let n of e) t.push(n.start.z, n.end.z);
|
|
4308
|
+
return t.length ? (t.sort((e, t) => e - t), t[Math.floor(t.length / 2)]) : -Infinity;
|
|
4309
|
+
}
|
|
4310
|
+
return r.sort((e, t) => e - t), r[Math.floor(r.length / 2)];
|
|
4311
|
+
}
|
|
4312
|
+
function Xn(e, t, n, r, i, a) {
|
|
4313
|
+
let o = i - n, s = a - r, c = o * o + s * s;
|
|
4314
|
+
if (c < 1e-12) return {
|
|
4315
|
+
dist: Math.sqrt((e - n) ** 2 + (t - r) ** 2),
|
|
4316
|
+
t: 0
|
|
4317
|
+
};
|
|
4318
|
+
let l = e - n, u = t - r, d = (l * o + u * s) / c, f = n + d * o, p = r + d * s;
|
|
4319
|
+
return {
|
|
4320
|
+
dist: Math.sqrt((e - f) ** 2 + (t - p) ** 2),
|
|
4321
|
+
t: d
|
|
4322
|
+
};
|
|
4323
|
+
}
|
|
4324
|
+
//#endregion
|
|
4325
|
+
//#region src/wall-window-matcher/scoring.ts
|
|
4326
|
+
function Zn(e, t, n = .15) {
|
|
4327
|
+
let r = 0, i = 0;
|
|
4328
|
+
for (let a of t) a !== e && ((qn(e.start, a.start) <= n || qn(e.start, a.end) <= n) && r++, (qn(e.end, a.start) <= n || qn(e.end, a.end) <= n) && i++);
|
|
4329
|
+
let a = 0;
|
|
4330
|
+
return r >= 1 && i >= 1 ? a = 5 : (r >= 1 || i >= 1) && (a = 2), {
|
|
4331
|
+
left: r,
|
|
4332
|
+
right: i,
|
|
4333
|
+
score: a
|
|
4334
|
+
};
|
|
4335
|
+
}
|
|
4336
|
+
function Qn(e, t) {
|
|
4337
|
+
let n = [], { start: r, end: i } = e;
|
|
4338
|
+
for (let e of t) {
|
|
4339
|
+
let { dist: t } = Xn(e.x, e.y, r.x, r.y, i.x, i.y);
|
|
4340
|
+
n.push(t);
|
|
4341
|
+
}
|
|
4342
|
+
let a = n.reduce((e, t) => e + t, 0) / n.length, o = n.reduce((e, t) => e + (t - a) ** 2, 0) / n.length;
|
|
4343
|
+
return o < .01 ? 3 : o < .05 ? 2 : o < .1 ? 1 : 0;
|
|
4344
|
+
}
|
|
4345
|
+
function $n(e, t, n = .15) {
|
|
4346
|
+
let r = e.end.x - e.start.x, i = e.end.y - e.start.y, a = Math.sqrt(r * r + i * i);
|
|
4347
|
+
if (a < 1e-12) return 0;
|
|
4348
|
+
let o = -i / a, s = r / a, c = [[], []];
|
|
4349
|
+
for (let l = 0; l < 2; l++) {
|
|
4350
|
+
let u = l === 0 ? e.start : e.end;
|
|
4351
|
+
for (let d of t) {
|
|
4352
|
+
if (d === e) continue;
|
|
4353
|
+
let t = qn(u, d.start), f = qn(u, d.end), p = null;
|
|
4354
|
+
if (t <= n ? p = d.end : f <= n && (p = d.start), !p) continue;
|
|
4355
|
+
let m = d.end.x - d.start.x, h = d.end.y - d.start.y, g = Math.sqrt(m * m + h * h);
|
|
4356
|
+
if (g < 1e-12 || Math.abs(r * m + i * h) / (a * g) >= .342) continue;
|
|
4357
|
+
let _ = (p.x - u.x) * o + (p.y - u.y) * s;
|
|
4358
|
+
c[l].push(_ > 0 ? 1 : -1);
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
if (c[0].length === 0 || c[1].length === 0) return 0;
|
|
4362
|
+
let l = [...c[0], ...c[1]];
|
|
4363
|
+
return l.every((e) => e === l[0]) ? 2 : 1;
|
|
4364
|
+
}
|
|
4365
|
+
function er(e, t, n) {
|
|
4366
|
+
let r = Zn(e, n), i = Qn(e, t), a = $n(e, n);
|
|
4367
|
+
return {
|
|
4368
|
+
score: r.score * 3 + i * 2 + a * 2,
|
|
4369
|
+
details: {
|
|
4370
|
+
conn: r.score,
|
|
4371
|
+
variance: i,
|
|
4372
|
+
sameSide: a
|
|
4373
|
+
}
|
|
4374
|
+
};
|
|
4375
|
+
}
|
|
4376
|
+
//#endregion
|
|
4377
|
+
//#region src/wall-window-matcher/merger.ts
|
|
4378
|
+
function tr(e) {
|
|
4379
|
+
let t = e.end.x - e.start.x, n = e.end.y - e.start.y, r = 180 / Math.PI * Math.atan2(n, t);
|
|
4380
|
+
return r < 0 && (r += 180), r;
|
|
4381
|
+
}
|
|
4382
|
+
function nr(e, t) {
|
|
4383
|
+
let n = [];
|
|
4384
|
+
for (let r of e) {
|
|
4385
|
+
let e = !1;
|
|
4386
|
+
for (let i of n) {
|
|
4387
|
+
let n = Math.abs(r.angle - i[0].angle);
|
|
4388
|
+
if (Math.min(n, 180 - n) <= t) {
|
|
4389
|
+
i.push(r), e = !0;
|
|
4390
|
+
break;
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
e || n.push([r]);
|
|
4394
|
+
}
|
|
4395
|
+
return n;
|
|
4396
|
+
}
|
|
4397
|
+
function rr(e, t = .05) {
|
|
4398
|
+
let n = [];
|
|
4399
|
+
for (let r of e) {
|
|
4400
|
+
let e = !1;
|
|
4401
|
+
for (let i of n) if (Math.abs(r.offset - i[0].offset) <= t) {
|
|
4402
|
+
i.push(r), e = !0;
|
|
4403
|
+
break;
|
|
4404
|
+
}
|
|
4405
|
+
e || n.push([r]);
|
|
4406
|
+
}
|
|
4407
|
+
return n;
|
|
4408
|
+
}
|
|
4409
|
+
function ir(e, t, n, r, i) {
|
|
4410
|
+
let a = [];
|
|
4411
|
+
for (let i of e) {
|
|
4412
|
+
let e = i.seg, o = (e.start.x - t.start.x) * n + (e.start.y - t.start.y) * r, s = (e.end.x - t.start.x) * n + (e.end.y - t.start.y) * r;
|
|
4413
|
+
a.push({
|
|
4414
|
+
l: Math.min(o, s),
|
|
4415
|
+
r: Math.max(o, s),
|
|
4416
|
+
idx: i.idx
|
|
4417
|
+
});
|
|
4418
|
+
}
|
|
4419
|
+
a.sort((e, t) => e.l - t.l);
|
|
4420
|
+
let o = [];
|
|
4421
|
+
for (let { l: e, r: t, idx: n } of a) {
|
|
4422
|
+
if (o.length === 0) {
|
|
4423
|
+
o.push({
|
|
4424
|
+
l: e,
|
|
4425
|
+
r: t,
|
|
4426
|
+
srcIdxs: [n]
|
|
4427
|
+
});
|
|
4428
|
+
continue;
|
|
4429
|
+
}
|
|
4430
|
+
let r = o[o.length - 1];
|
|
4431
|
+
e <= r.r + i ? (r.r = Math.max(r.r, t), r.srcIdxs.includes(n) || r.srcIdxs.push(n)) : o.push({
|
|
4432
|
+
l: e,
|
|
4433
|
+
r: t,
|
|
4434
|
+
srcIdxs: [n]
|
|
4435
|
+
});
|
|
4436
|
+
}
|
|
4437
|
+
return o;
|
|
4438
|
+
}
|
|
4439
|
+
function ar(e, t, n, r, i, a, o) {
|
|
4440
|
+
let s = n - t, c = { ...e };
|
|
4441
|
+
return c.start = {
|
|
4442
|
+
x: e.start.x + t * r,
|
|
4443
|
+
y: e.start.y + t * i,
|
|
4444
|
+
z: e.start.z
|
|
4445
|
+
}, c.end = {
|
|
4446
|
+
x: e.start.x + n * r,
|
|
4447
|
+
y: e.start.y + n * i,
|
|
4448
|
+
z: e.start.z
|
|
4449
|
+
}, c.length = s, c.direction = {
|
|
4450
|
+
x: r,
|
|
4451
|
+
y: i,
|
|
4452
|
+
z: 0
|
|
4453
|
+
}, c.rooftopPz = a, c.buildRosource = o, c.isRebuild = !1, c.doorAndBeamData ||= [], c.insetionArr ||= [], c;
|
|
4454
|
+
}
|
|
4455
|
+
function or(e, t) {
|
|
4456
|
+
let n = !0;
|
|
4457
|
+
for (; n;) {
|
|
4458
|
+
n = !1;
|
|
4459
|
+
for (let r = 0; r < e.length; r++) for (let i = r + 1; i < e.length; i++) {
|
|
4460
|
+
let a = e[r], o = e[i];
|
|
4461
|
+
if (a.rooftopPz !== void 0 && o.rooftopPz !== void 0 && Math.abs(a.rooftopPz - o.rooftopPz) > .05) continue;
|
|
4462
|
+
let s = Math.abs(a.end.x - o.start.x) < .001 && Math.abs(a.end.y - o.start.y) < .001, c = Math.abs(a.start.x - o.end.x) < .001 && Math.abs(a.start.y - o.end.y) < .001, l = Math.abs(a.end.x - o.end.x) < .001 && Math.abs(a.end.y - o.end.y) < .001, u = Math.abs(a.start.x - o.start.x) < .001 && Math.abs(a.start.y - o.start.y) < .001;
|
|
4463
|
+
if (!(s || c || l || u) || a.direction.x * o.direction.x + a.direction.y * o.direction.y < .98) continue;
|
|
4464
|
+
let d = a.start, f = a.end;
|
|
4465
|
+
s ? f = o.end : c ? d = o.start : l ? f = o.start : u && (d = o.end);
|
|
4466
|
+
let p = Math.hypot(f.x - d.x, f.y - d.y), m = { ...a };
|
|
4467
|
+
m.start = d, m.end = f, m.length = p, m.direction = {
|
|
4468
|
+
x: (f.x - d.x) / p,
|
|
4469
|
+
y: (f.y - d.y) / p,
|
|
4470
|
+
z: 0
|
|
4471
|
+
}, m.rooftopPz = a.rooftopPz === void 0 ? o.rooftopPz : a.rooftopPz, m.buildRosource = a.buildRosource || o.buildRosource, m.isRebuild = !1, m.doorAndBeamData ||= [], m.insetionArr ||= [], e[r] = m, t[r] = [...new Set([...t[r], ...t[i]])], e.splice(i, 1), t.splice(i, 1), i--, n = !0;
|
|
4472
|
+
}
|
|
4473
|
+
}
|
|
4474
|
+
return {
|
|
4475
|
+
segments: e,
|
|
4476
|
+
sourceMap: t
|
|
4477
|
+
};
|
|
4478
|
+
}
|
|
4479
|
+
function sr(e, t = 5, n = .05) {
|
|
4480
|
+
if (e.length <= 1) return {
|
|
4481
|
+
segments: e,
|
|
4482
|
+
sourceMap: e.map((e, t) => [t])
|
|
4483
|
+
};
|
|
4484
|
+
let r = e.map((e, t) => ({
|
|
4485
|
+
seg: e,
|
|
4486
|
+
angle: tr(e),
|
|
4487
|
+
idx: t
|
|
4488
|
+
}));
|
|
4489
|
+
r.sort((e, t) => e.angle - t.angle);
|
|
4490
|
+
let i = nr(r, t), a = [], o = [], s = [];
|
|
4491
|
+
for (let e of i) {
|
|
4492
|
+
let t = e[0].seg;
|
|
4493
|
+
for (let n of e) n.seg.length > t.length && (t = n.seg);
|
|
4494
|
+
let r = t.end.x - t.start.x, i = t.end.y - t.start.y, c = Math.sqrt(r * r + i * i);
|
|
4495
|
+
if (c < 1e-12) continue;
|
|
4496
|
+
let l = -i / c, u = r / c, d = e.map((e) => {
|
|
4497
|
+
let n = e.seg.start.x - t.start.x, r = e.seg.start.y - t.start.y;
|
|
4498
|
+
return {
|
|
4499
|
+
seg: e.seg,
|
|
4500
|
+
offset: Math.abs(n * l + r * u),
|
|
4501
|
+
idx: e.idx
|
|
4502
|
+
};
|
|
4503
|
+
});
|
|
4504
|
+
d.sort((e, t) => e.offset - t.offset);
|
|
4505
|
+
let f = rr(d);
|
|
4506
|
+
for (let e of f) {
|
|
4507
|
+
let t = e[0].seg;
|
|
4508
|
+
for (let n of e) n.seg.length > t.length && (t = n.seg);
|
|
4509
|
+
let r = t.end.x - t.start.x, i = t.end.y - t.start.y, c = Math.sqrt(r * r + i * i);
|
|
4510
|
+
if (c < 1e-12) continue;
|
|
4511
|
+
let l = r / c, u = i / c, d = e.map((e) => e.seg.rooftopPz ?? 0), f = Math.max(...d), p = [...new Set(d.map((e) => e.toFixed(3)))];
|
|
4512
|
+
if (p.length > 1) {
|
|
4513
|
+
console.warn(`[merge] inconsistent rooftopPz: ${p.join("/")} max=${f.toFixed(3)} count=${e.length}`);
|
|
4514
|
+
let t = e.map((e) => ({
|
|
4515
|
+
idx: e.idx,
|
|
4516
|
+
start: {
|
|
4517
|
+
x: e.seg.start.x,
|
|
4518
|
+
y: e.seg.start.y,
|
|
4519
|
+
z: e.seg.start.z
|
|
4520
|
+
},
|
|
4521
|
+
end: {
|
|
4522
|
+
x: e.seg.end.x,
|
|
4523
|
+
y: e.seg.end.y,
|
|
4524
|
+
z: e.seg.end.z
|
|
4525
|
+
},
|
|
4526
|
+
length: e.seg.length,
|
|
4527
|
+
rooftopPz: e.seg.rooftopPz ?? 0
|
|
4528
|
+
}));
|
|
4529
|
+
s.push({
|
|
4530
|
+
values: [...p],
|
|
4531
|
+
segments: t
|
|
4532
|
+
});
|
|
4533
|
+
}
|
|
4534
|
+
let m = [...new Set(e.map((e) => String(e.seg.buildRosource)))];
|
|
4535
|
+
m.length > 1 && e.length > 1 && console.warn(`[merge] buildRosource src: ${m.join("/")}`);
|
|
4536
|
+
let h = ir(e, t, l, u, n);
|
|
4537
|
+
for (let { l: e, r: n, srcIdxs: r } of h) {
|
|
4538
|
+
if (n - e < .01) continue;
|
|
4539
|
+
let i = ar(t, e, n, l, u, f, t.buildRosource);
|
|
4540
|
+
a.push(i), o.push(r);
|
|
4541
|
+
}
|
|
4542
|
+
}
|
|
4543
|
+
}
|
|
4544
|
+
return {
|
|
4545
|
+
...or(a, o),
|
|
4546
|
+
debugRPZGroups: s
|
|
4547
|
+
};
|
|
4548
|
+
}
|
|
4549
|
+
//#endregion
|
|
4550
|
+
//#region src/wall-window-matcher/matcher.ts
|
|
4551
|
+
function cr(e) {
|
|
4552
|
+
return {
|
|
4553
|
+
minLengthRatio: .95,
|
|
4554
|
+
maxDistance: .5,
|
|
4555
|
+
angleThreshold: 45,
|
|
4556
|
+
projectionMargin: .1,
|
|
4557
|
+
printOnly: !0,
|
|
4558
|
+
...e
|
|
4559
|
+
};
|
|
4560
|
+
}
|
|
4561
|
+
function lr(e, t, n) {
|
|
4562
|
+
return [
|
|
4563
|
+
{
|
|
4564
|
+
x: t,
|
|
4565
|
+
y: n,
|
|
4566
|
+
z: 0
|
|
4567
|
+
},
|
|
4568
|
+
{
|
|
4569
|
+
x: e[0].x,
|
|
4570
|
+
y: e[0].y,
|
|
4571
|
+
z: 0
|
|
4572
|
+
},
|
|
4573
|
+
{
|
|
4574
|
+
x: e[1].x,
|
|
4575
|
+
y: e[1].y,
|
|
4576
|
+
z: 0
|
|
4577
|
+
},
|
|
4578
|
+
{
|
|
4579
|
+
x: e[2].x,
|
|
4580
|
+
y: e[2].y,
|
|
4581
|
+
z: 0
|
|
4582
|
+
},
|
|
4583
|
+
{
|
|
4584
|
+
x: e[3].x,
|
|
4585
|
+
y: e[3].y,
|
|
4586
|
+
z: 0
|
|
4587
|
+
}
|
|
4588
|
+
];
|
|
4589
|
+
}
|
|
4590
|
+
function ur(e, t, n, r, i, a, o, s, c) {
|
|
4591
|
+
if (![
|
|
4592
|
+
"_008",
|
|
4593
|
+
"_002",
|
|
4594
|
+
"_014",
|
|
4595
|
+
"_015",
|
|
4596
|
+
"_020"
|
|
4597
|
+
].some((t) => e.includes(t))) return;
|
|
4598
|
+
let l = t.map((e) => {
|
|
4599
|
+
let { start: t, end: a } = e, c = Xn(n, r, t.x, t.y, a.x, a.y), l = i.map((e) => {
|
|
4600
|
+
let n = Xn(e.x, e.y, t.x, t.y, a.x, a.y);
|
|
4601
|
+
return `t=${n.t.toFixed(3)},d=${n.dist.toFixed(3)}`;
|
|
4602
|
+
}), u = a.x - t.x, d = a.y - t.y, f = Math.sqrt(u * u + d * d) || 1, p = Math.abs(u / f * o + d / f * s), m = 180 / Math.PI * Math.acos(Math.min(p, 1));
|
|
4603
|
+
return {
|
|
4604
|
+
seg: e,
|
|
4605
|
+
lineDist: c.dist,
|
|
4606
|
+
t: c.t,
|
|
4607
|
+
pts: l,
|
|
4608
|
+
angle: m,
|
|
4609
|
+
length: e.length
|
|
4610
|
+
};
|
|
4611
|
+
});
|
|
4612
|
+
l.sort((e, t) => e.lineDist - t.lineDist), console.warn(`[${e}扫查] 按无限直线距离排序的前 15 条候选: (需长≥${(a * c.minLengthRatio).toFixed(2)})`);
|
|
4613
|
+
for (let e = 0; e < Math.min(15, l.length); e++) {
|
|
4614
|
+
let t = l[e], n = t.length >= a * c.minLengthRatio ? "✓" : `✗(需${(a * c.minLengthRatio).toFixed(2)})`, r = Math.abs(t.t) <= 1.4 ? "✓" : "✗", i = t.lineDist <= .65 ? "✓" : "✗", o = t.angle <= 45 ? "✓" : "✗";
|
|
4615
|
+
console.warn(` #${e} 距=${t.lineDist.toFixed(3)}m t=${t.t.toFixed(3)} 角=${t.angle.toFixed(1)}° 长=${t.length.toFixed(3)}m [长度${n} 投影${r} 距离${i} 角度${o}] 起点(${t.seg.start.x.toFixed(3)},${t.seg.start.y.toFixed(3)})→(${t.seg.end.x.toFixed(3)},${t.seg.end.y.toFixed(3)}) | 5点: ${t.pts.join(" | ")}`);
|
|
4616
|
+
}
|
|
4617
|
+
}
|
|
4618
|
+
function dr(e, t, n, r, i, a) {
|
|
4619
|
+
let o = [{
|
|
4620
|
+
margin: a.projectionMargin,
|
|
4621
|
+
maxDist: a.maxDistance,
|
|
4622
|
+
label: "严格"
|
|
4623
|
+
}, {
|
|
4624
|
+
margin: .4,
|
|
4625
|
+
maxDist: .65,
|
|
4626
|
+
label: "宽松"
|
|
4627
|
+
}], s = [];
|
|
4628
|
+
for (let c of o) {
|
|
4629
|
+
if (s.length > 0) break;
|
|
4630
|
+
for (let o of e) {
|
|
4631
|
+
if (o.length < t * a.minLengthRatio) continue;
|
|
4632
|
+
let { start: e, end: l } = o, u = !1, d = Infinity;
|
|
4633
|
+
for (let t of i) {
|
|
4634
|
+
let { dist: n, t: r } = Xn(t.x, t.y, e.x, e.y, l.x, l.y);
|
|
4635
|
+
r >= -c.margin && r <= 1 + c.margin && n <= c.maxDist && (u = !0, d = Math.min(d, n));
|
|
4636
|
+
}
|
|
4637
|
+
if (!u) continue;
|
|
4638
|
+
let f = Math.sqrt((l.x - e.x) ** 2 + (l.y - e.y) ** 2);
|
|
4639
|
+
if (f < 1e-12) continue;
|
|
4640
|
+
let p = (l.x - e.x) / f, m = (l.y - e.y) / f, h = Math.abs(n * p + r * m);
|
|
4641
|
+
180 / Math.PI * Math.acos(Math.min(h, 1)) > a.angleThreshold || s.push({
|
|
4642
|
+
seg: o,
|
|
4643
|
+
minDist: d,
|
|
4644
|
+
ratio: o.length / t,
|
|
4645
|
+
score: 0,
|
|
4646
|
+
details: {
|
|
4647
|
+
conn: 0,
|
|
4648
|
+
variance: 0,
|
|
4649
|
+
sameSide: 0
|
|
4650
|
+
}
|
|
4651
|
+
});
|
|
4652
|
+
}
|
|
4653
|
+
s.length > 0 && console.log(`[findWindowWall] 候选 ${c.label}模式: ${s.length} 条`);
|
|
4654
|
+
}
|
|
4655
|
+
return s;
|
|
4656
|
+
}
|
|
4657
|
+
function fr(e, t, n, r) {
|
|
4658
|
+
if (e.length <= 1) return e.length === 1 && (e[0].score = -1), e;
|
|
4659
|
+
for (let r of e) {
|
|
4660
|
+
let { score: e, details: i } = er(r.seg, t, n);
|
|
4661
|
+
r.score = e, r.details = i;
|
|
4662
|
+
}
|
|
4663
|
+
e.sort((e, t) => t.score - e.score || e.minDist - t.minDist);
|
|
4664
|
+
let i = e.map((e) => `评分=${e.score}(conn=${e.details.conn}/var=${e.details.variance}/side=${e.details.sameSide}) dist=${e.minDist.toFixed(3)}`).join(" | ");
|
|
4665
|
+
console.log(`[findWindowWall] ${r} 评分排序: ${i}`);
|
|
4666
|
+
let a = e[0];
|
|
4667
|
+
return console.log(`[findWindowWall] ${r} → 选中评分=${a.score}(conn=${a.details.conn}/var=${a.details.variance}/side=${a.details.sameSide}) dist=${a.minDist.toFixed(3)}m`), e;
|
|
4668
|
+
}
|
|
4669
|
+
function pr(e, t, n, r) {
|
|
4670
|
+
let i = e.end.x - e.start.x, a = e.end.y - e.start.y, o = Math.sqrt(i * i + a * a), s = i / o, c = a / o, l = t.map((t) => {
|
|
4671
|
+
let n = t.x - e.start.x, r = t.y - e.start.y;
|
|
4672
|
+
return (n * s + r * c) / o;
|
|
4673
|
+
}), u = Math.min(...l), d = Math.max(...l), f = (d - u) * o, p = (u + d) / 2, m = e.start.x + p * i, h = e.start.y + p * a, g = n.box.min.z, _ = n.box.max.z, v = Math.abs(_ - g), y = Yn(r, e.start.x, e.start.y), b = Math.max(0, g - y), x = u <= 0 && d >= 1;
|
|
4674
|
+
return {
|
|
4675
|
+
p: {
|
|
4676
|
+
x: m,
|
|
4677
|
+
y: h,
|
|
4678
|
+
z: g + v / 2
|
|
4679
|
+
},
|
|
4680
|
+
width: f,
|
|
4681
|
+
full: x,
|
|
4682
|
+
height: v,
|
|
4683
|
+
groundClearance: b
|
|
4684
|
+
};
|
|
4685
|
+
}
|
|
4686
|
+
function mr(e, t, n) {
|
|
4687
|
+
let r = t.map((e) => n[e]), i = [], a = [], o = [], s = [], c = [], l;
|
|
4688
|
+
for (let e of r) {
|
|
4689
|
+
if (e.points?.length) for (let t of e.points) i.push(t);
|
|
4690
|
+
if (e.originalPoints?.length) for (let t of e.originalPoints) a.push(t);
|
|
4691
|
+
if (e.doorAndBeamData?.length) for (let t of e.doorAndBeamData) o.push(t);
|
|
4692
|
+
if (e.insetionArr?.length) for (let t of e.insetionArr) s.push(t);
|
|
4693
|
+
if (e.drawWindow?.length) for (let t of e.drawWindow) c.push(t);
|
|
4694
|
+
e.boxData && !l && (l = e.boxData);
|
|
4695
|
+
}
|
|
4696
|
+
i.length && (e.points = i), a.length && (e.originalPoints = a), o.length && (e.doorAndBeamData = o), s.length && (e.insetionArr = s), c.length && (e.drawWindow = c), l && (e.boxData = l), c.length > 0 && console.log(`[dataMerge] wall (${e.start.x.toFixed(3)},${e.start.y.toFixed(3)})->(${e.end.x.toFixed(3)},${e.end.y.toFixed(3)}) merged from ${t.length} segments drawWindow=${c.length} items`);
|
|
4697
|
+
}
|
|
4698
|
+
function hr(e) {
|
|
4699
|
+
let t = e.filter((e) => e.drawWindow && e.drawWindow.length > 0);
|
|
4700
|
+
if (t.length !== 0) {
|
|
4701
|
+
console.log(`[findWindowWall] 合并后携带 drawWindow 的墙段数量=${t.length}`);
|
|
4702
|
+
for (let e of t) {
|
|
4703
|
+
console.log(`[findWindowWall] 墙段: (${e.start.x.toFixed(3)},${e.start.y.toFixed(3)})->(${e.end.x.toFixed(3)},${e.end.y.toFixed(3)}) len=${e.length.toFixed(3)}m rooftopPz=${e.rooftopPz === void 0 ? "N/A" : e.rooftopPz.toFixed(3)}`);
|
|
4704
|
+
for (let t = 0; t < e.drawWindow.length; t++) {
|
|
4705
|
+
let n = e.drawWindow[t];
|
|
4706
|
+
console.log(` [drawWindow #${t}] p=(${n.p.x.toFixed(3)},${n.p.y.toFixed(3)}) width=${n.width.toFixed(3)}m height=${n.height.toFixed(3)}m groundClearance=${n.groundClearance.toFixed(3)}m full=${n.full}`);
|
|
4707
|
+
}
|
|
4708
|
+
}
|
|
4709
|
+
}
|
|
4710
|
+
}
|
|
4711
|
+
function gr(e, t, n) {
|
|
4712
|
+
let r = cr(n), i = [], { segments: a, sourceMap: o } = sr(t);
|
|
4713
|
+
console.log(`[findWindowWall] 墙线段共线合并: ${t.length} → ${a.length} 条`);
|
|
4714
|
+
let s = [...a, ...t];
|
|
4715
|
+
for (let n of e) {
|
|
4716
|
+
let e = n.coordinatesByArea?.coordinates;
|
|
4717
|
+
if (!e || e.length < 4) {
|
|
4718
|
+
console.warn(`[findWindowWall] ${n.name} 缺少 coordinatesByArea.coordinates,跳过`);
|
|
4719
|
+
continue;
|
|
4720
|
+
}
|
|
4721
|
+
let o = e.slice(0, 4), c = o.reduce((e, t) => e + t.x, 0) / 4, l = o.reduce((e, t) => e + t.y, 0) / 4, { longSide: u, dirX: d, dirY: f } = Jn(o);
|
|
4722
|
+
if (u < .01) {
|
|
4723
|
+
console.warn(`[findWindowWall] ${n.name} 四边形边长过短 (${u.toFixed(3)}),跳过`);
|
|
4724
|
+
continue;
|
|
4725
|
+
}
|
|
4726
|
+
let p = o.reduce((e, t) => e + t.z, 0) / 4, m = Yn(t, c, l);
|
|
4727
|
+
if (p < m - .3) {
|
|
4728
|
+
console.warn(`[findWindowWall] ${n.name} 高度异常(z=${p.toFixed(3)},附近地面=${m.toFixed(3)}),跳过`);
|
|
4729
|
+
continue;
|
|
4730
|
+
}
|
|
4731
|
+
let h = lr(o, c, l);
|
|
4732
|
+
ur(n.name, s, c, l, h, u, d, f, r);
|
|
4733
|
+
let g = dr(s, u, d, f, h, r);
|
|
4734
|
+
g = fr(g, h, t, n.name);
|
|
4735
|
+
let _ = null, v = Infinity, y = 0;
|
|
4736
|
+
if (g.length > 0) {
|
|
4737
|
+
let e = g[0];
|
|
4738
|
+
_ = e.seg, v = e.minDist, y = e.ratio;
|
|
4739
|
+
}
|
|
4740
|
+
let b;
|
|
4741
|
+
if (_ && (b = pr(_, o, n, a), console.log("[drawWindow]", n.name, JSON.stringify(b)), !r.printOnly)) {
|
|
4742
|
+
let e = _;
|
|
4743
|
+
e.drawWindow ||= [], e.drawWindow.push(b);
|
|
4744
|
+
}
|
|
4745
|
+
_ ? i.push({
|
|
4746
|
+
windowName: n.name,
|
|
4747
|
+
windowCategory: n.category,
|
|
4748
|
+
windowCenter: n.center,
|
|
4749
|
+
wallSegment: _,
|
|
4750
|
+
distance: v,
|
|
4751
|
+
wallLengthRatio: y,
|
|
4752
|
+
drawWindow: b
|
|
4753
|
+
}) : console.warn(`[findWindowWall] ${n.name} 未找到匹配的墙线段`);
|
|
4754
|
+
}
|
|
4755
|
+
for (let e of i) {
|
|
4756
|
+
let n = e.wallSegment, r = a.indexOf(n);
|
|
4757
|
+
if (r === -1) continue;
|
|
4758
|
+
let i = o[r];
|
|
4759
|
+
!i || i.length <= 1 || mr(n, i, t);
|
|
4760
|
+
}
|
|
4761
|
+
return hr(a), i;
|
|
4762
|
+
}
|
|
4763
|
+
//#endregion
|
|
4764
|
+
//#region src/wall-window-matcher/entry.ts
|
|
4765
|
+
function _r(e, t, n) {
|
|
4766
|
+
let r = {
|
|
4767
|
+
printOnly: !1,
|
|
4768
|
+
...n
|
|
4769
|
+
}, i = gr(Array.isArray(t) ? t.filter((e) => e && e.category === "window") : [], e, r), { segments: a, sourceMap: o } = sr(e);
|
|
4770
|
+
for (let e of i) if (e.drawWindow) {
|
|
4771
|
+
let t = a.find((t) => Math.abs(t.start.x - e.wallSegment.start.x) < .01 && Math.abs(t.start.y - e.wallSegment.start.y) < .01 && Math.abs(t.end.x - e.wallSegment.end.x) < .01 && Math.abs(t.end.y - e.wallSegment.end.y) < .01);
|
|
4772
|
+
t && (t.drawWindow ||= [], t.drawWindow.push(e.drawWindow));
|
|
4773
|
+
}
|
|
4774
|
+
return {
|
|
4775
|
+
segments: a,
|
|
4776
|
+
matches: i,
|
|
4777
|
+
sourceMap: o
|
|
4778
|
+
};
|
|
4779
|
+
}
|
|
4780
|
+
//#endregion
|
|
4781
|
+
export { z as classifySegments, Yn as computeLocalFloorZ, gr as findWindowWalls, ge as getAllGeometry, Oe as getBeamLine, Ae as getColLine, ke as getMainBeamLine, Kn as getMergeMeaning, I as getParallelism, re as getPointCloudMinMax, te as getPointCoverageOnQuad, j as isParallel, sr as mergeCollinearSegments, L as perpendicularInfo, _r as processData, ae as removeNoisePoints, O as segmentsIntersect2D, _e as updateStEdPoint, De as usegetBeamLine };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rm-graphical-computing",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.54",
|
|
4
4
|
"description": "Three.js wall segment processing utilities.",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
|
-
"dist"
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
18
|
"dev": "vite",
|