feat: update algorithm integrations and point cloud overlays
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
export type SampledPoint = { x: number; y: number; z: number; error: number };
|
||||
export type SampledPoint = { x: number; y: number; z: number; error: number; r?: number; g?: number; b?: number };
|
||||
|
||||
/** 与 fileRoutes 批量采样一致:随机 seek 文本点云行 */
|
||||
export async function randomSeekSample(
|
||||
@@ -170,15 +170,20 @@ function samplePlyBinary(
|
||||
|
||||
const bytesPerVertex = properties.reduce((s, p) => s + p.byteSize, 0);
|
||||
|
||||
// 找 x, y, z(可能叫 x/y/z 或 X/Y/Z;允许宽松匹配)
|
||||
// 找 x, y, z,以及 red/green/blue(uchar 0-255)
|
||||
let xOff = -1, yOff = -1, zOff = -1;
|
||||
let rOff = -1, gOff = -1, bOff = -1;
|
||||
let xType = 'float', yType = 'float', zType = 'float';
|
||||
let rType = 'uchar', gType = 'uchar', bType = 'uchar';
|
||||
let byteOff = 0;
|
||||
for (const p of properties) {
|
||||
const n = p.name.toLowerCase();
|
||||
if (n === 'x') { xOff = byteOff; xType = p.type; }
|
||||
else if (n === 'y') { yOff = byteOff; yType = p.type; }
|
||||
else if (n === 'z') { zOff = byteOff; zType = p.type; }
|
||||
else if (n === 'red') { rOff = byteOff; rType = p.type; }
|
||||
else if (n === 'green') { gOff = byteOff; gType = p.type; }
|
||||
else if (n === 'blue') { bOff = byteOff; bType = p.type; }
|
||||
byteOff += p.byteSize;
|
||||
}
|
||||
|
||||
@@ -224,7 +229,13 @@ function samplePlyBinary(
|
||||
const z = readNum(recBuf, zOff, zType);
|
||||
if (!isFinite(x) || !isFinite(y) || !isFinite(z)) continue;
|
||||
const error = Math.abs(Math.sin(x * 0.001) * Math.cos(z * 0.001)) * 1.5;
|
||||
points.push({ x, y, z, error });
|
||||
const pt: SampledPoint = { x, y, z, error };
|
||||
if (rOff >= 0 && gOff >= 0 && bOff >= 0) {
|
||||
pt.r = readNum(recBuf, rOff, rType);
|
||||
pt.g = readNum(recBuf, gOff, gType);
|
||||
pt.b = readNum(recBuf, bOff, bType);
|
||||
}
|
||||
points.push(pt);
|
||||
}
|
||||
} finally {
|
||||
fs.closeSync(fd);
|
||||
@@ -277,12 +288,25 @@ function samplePlyAscii(
|
||||
const line = (nl2 === -1 ? afterFirst : afterFirst.slice(0, nl2)).trim();
|
||||
if (!line) continue;
|
||||
const parts = line.split(/\s+/);
|
||||
const x = parseFloat(parts[0]);
|
||||
const y = parseFloat(parts[1]);
|
||||
const z = parseFloat(parts[2]);
|
||||
// 按 header properties 顺序找 x/y/z/red/green/blue 的列索引
|
||||
let xi = -1, yi = -1, zi = -1, ri = -1, gi = -1, bi = -1;
|
||||
header.properties.forEach((p, i) => {
|
||||
const n = p.name.toLowerCase();
|
||||
if (n === 'x') xi = i; else if (n === 'y') yi = i; else if (n === 'z') zi = i;
|
||||
else if (n === 'red') ri = i; else if (n === 'green') gi = i; else if (n === 'blue') bi = i;
|
||||
});
|
||||
const x = parseFloat(parts[xi >= 0 ? xi : 0]);
|
||||
const y = parseFloat(parts[yi >= 0 ? yi : 1]);
|
||||
const z = parseFloat(parts[zi >= 0 ? zi : 2]);
|
||||
if (!isFinite(x) || !isFinite(y) || !isFinite(z)) continue;
|
||||
const error = Math.abs(Math.sin(x * 0.001) * Math.cos(z * 0.001)) * 1.5;
|
||||
points.push({ x, y, z, error });
|
||||
const pt: SampledPoint = { x, y, z, error };
|
||||
if (ri >= 0 && gi >= 0 && bi >= 0 && parts[ri] !== undefined) {
|
||||
pt.r = parseFloat(parts[ri]);
|
||||
pt.g = parseFloat(parts[gi]);
|
||||
pt.b = parseFloat(parts[bi]);
|
||||
}
|
||||
points.push(pt);
|
||||
}
|
||||
} finally {
|
||||
fs.closeSync(fd);
|
||||
|
||||
Reference in New Issue
Block a user