61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
import { samplePointcloudFile } from './pointcloudSample';
|
|
|
|
const temporaryDirectories: string[] = [];
|
|
|
|
afterEach(() => {
|
|
while (temporaryDirectories.length > 0) {
|
|
rmSync(temporaryDirectories.pop()!, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
function writeBinaryPly(properties: string[], records: number[][]): string {
|
|
const directory = mkdtempSync(join(tmpdir(), 'pointcloud-sample-'));
|
|
temporaryDirectories.push(directory);
|
|
const filePath = join(directory, 'cloud.ply');
|
|
const header = Buffer.from([
|
|
'ply',
|
|
'format binary_little_endian 1.0',
|
|
`element vertex ${records.length}`,
|
|
...properties.map((name) => `property float ${name}`),
|
|
'end_header',
|
|
'',
|
|
].join('\n'), 'ascii');
|
|
const body = Buffer.alloc(records.length * properties.length * 4);
|
|
records.forEach((record, recordIndex) => {
|
|
record.forEach((value, propertyIndex) => {
|
|
body.writeFloatLE(value, (recordIndex * properties.length + propertyIndex) * 4);
|
|
});
|
|
});
|
|
writeFileSync(filePath, Buffer.concat([header, body]));
|
|
return filePath;
|
|
}
|
|
|
|
describe('samplePointcloudFile', () => {
|
|
it('不会为只有 xyz 的输入点云伪造误差', async () => {
|
|
const filePath = writeBinaryPly(
|
|
['x', 'y', 'z'],
|
|
[[1, 2, 3], [4, 5, 6]],
|
|
);
|
|
|
|
const points = await samplePointcloudFile(filePath, 1_000, 2);
|
|
|
|
expect(points).toHaveLength(2);
|
|
expect(points.every((point) => point.error === undefined)).toBe(true);
|
|
});
|
|
|
|
it.each(['error', 'deviation'])('保留 PLY 中真实的 %s 属性', async (errorProperty) => {
|
|
const filePath = writeBinaryPly(
|
|
['x', 'y', 'z', errorProperty],
|
|
[[1, 2, 3, 0.25], [4, 5, 6, -0.5]],
|
|
);
|
|
|
|
const points = await samplePointcloudFile(filePath, 1_000, 2);
|
|
|
|
expect(points.map((point) => point.error)).toEqual([0.25, -0.5]);
|
|
});
|
|
});
|