feat: secure analysis PLY sampling

This commit is contained in:
2026-08-13 18:16:57 +08:00
parent 29a69793db
commit 9f4482bea1
5 changed files with 350 additions and 61 deletions

View File

@@ -2,7 +2,7 @@ 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';
import { samplePointcloudFile, samplePointcloudFiles } from './pointcloudSample';
const temporaryDirectories: string[] = [];
@@ -58,3 +58,32 @@ describe('samplePointcloudFile', () => {
expect(points.map((point) => point.error)).toEqual([0.25, -0.5]);
});
});
describe('samplePointcloudFiles', () => {
it('合并彩色与无色 PLY,并使用 28 字节彩色步长', async () => {
const plain = writeBinaryPly(['x', 'y', 'z'], [[1, 2, 3], [4, 5, 6]]);
const colored = writeBinaryPly(
['x', 'y', 'z', 'red', 'green', 'blue'],
[[7, 8, 9, 255, 128, 0], [10, 11, 12, 0, 64, 255]],
);
const result = await samplePointcloudFiles([plain, colored], 4, 10);
expect(result.pointCount).toBe(4);
expect(result.hasColor).toBe(true);
expect(result.hasError).toBe(false);
expect(result.buffer.byteLength).toBe(4 * 28);
expect(result.fileStats.map((file) => file.sampled)).toEqual([2, 2]);
});
it('限制总采样数量,无色 PLY 使用 16 字节步长', async () => {
const first = writeBinaryPly(['x', 'y', 'z'], Array.from({ length: 10 }, (_, i) => [i, i, i]));
const second = writeBinaryPly(['x', 'y', 'z'], Array.from({ length: 10 }, (_, i) => [i + 10, i, i]));
const result = await samplePointcloudFiles([first, second], 100, 6);
expect(result.pointCount).toBe(6);
expect(result.hasColor).toBe(false);
expect(result.buffer.byteLength).toBe(6 * 16);
});
});