@loaders.gl/pcd 3.4.0-alpha.2 → 3.4.0-alpha.3
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/dist/dist.min.js +82 -24
- package/dist/es5/index.js +6 -8
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/decompress-lzf.js +21 -7
- package/dist/es5/lib/decompress-lzf.js.map +1 -1
- package/dist/es5/lib/get-pcd-schema.js +6 -0
- package/dist/es5/lib/get-pcd-schema.js.map +1 -1
- package/dist/es5/lib/parse-pcd.js +58 -29
- package/dist/es5/lib/parse-pcd.js.map +1 -1
- package/dist/es5/lib/pcd-types.js.map +1 -1
- package/dist/es5/pcd-loader.js +1 -2
- package/dist/es5/pcd-loader.js.map +1 -1
- package/dist/es5/workers/pcd-worker.js.map +1 -1
- package/dist/esm/bundle.js +0 -1
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/decompress-lzf.js +21 -8
- package/dist/esm/lib/decompress-lzf.js.map +1 -1
- package/dist/esm/lib/get-pcd-schema.js +7 -1
- package/dist/esm/lib/get-pcd-schema.js.map +1 -1
- package/dist/esm/lib/parse-pcd.js +58 -30
- package/dist/esm/lib/parse-pcd.js.map +1 -1
- package/dist/esm/lib/pcd-types.js.map +1 -1
- package/dist/esm/pcd-loader.js +1 -3
- package/dist/esm/pcd-loader.js.map +1 -1
- package/dist/lib/decompress-lzf.d.ts.map +1 -1
- package/dist/lib/decompress-lzf.js +14 -7
- package/dist/lib/get-pcd-schema.d.ts.map +1 -1
- package/dist/lib/get-pcd-schema.js +6 -0
- package/dist/lib/parse-pcd.js +60 -17
- package/dist/lib/pcd-types.d.ts +9 -9
- package/dist/lib/pcd-types.d.ts.map +1 -1
- package/dist/pcd-worker.js +82 -24
- package/package.json +4 -4
- package/src/lib/decompress-lzf.ts +21 -7
- package/src/lib/get-pcd-schema.ts +9 -1
- package/src/lib/parse-pcd.ts +79 -33
- package/src/lib/pcd-types.ts +9 -9
|
@@ -19,8 +19,12 @@ export function decompressLZF(inData: Uint8Array, outLength: number): Uint8Array
|
|
|
19
19
|
|
|
20
20
|
if (ctrl < 1 << 5) {
|
|
21
21
|
ctrl++;
|
|
22
|
-
if (outPtr + ctrl > outLength)
|
|
23
|
-
|
|
22
|
+
if (outPtr + ctrl > outLength) {
|
|
23
|
+
throw new Error('Output buffer is not large enough');
|
|
24
|
+
}
|
|
25
|
+
if (inPtr + ctrl > inLength) {
|
|
26
|
+
throw new Error('Invalid compressed data');
|
|
27
|
+
}
|
|
24
28
|
|
|
25
29
|
do {
|
|
26
30
|
outData[outPtr++] = inData[inPtr++];
|
|
@@ -28,17 +32,27 @@ export function decompressLZF(inData: Uint8Array, outLength: number): Uint8Array
|
|
|
28
32
|
} else {
|
|
29
33
|
len = ctrl >> 5;
|
|
30
34
|
ref = outPtr - ((ctrl & 0x1f) << 8) - 1;
|
|
31
|
-
if (inPtr >= inLength)
|
|
35
|
+
if (inPtr >= inLength) {
|
|
36
|
+
throw new Error('Invalid compressed data');
|
|
37
|
+
}
|
|
32
38
|
|
|
33
39
|
if (len === 7) {
|
|
34
40
|
len += inData[inPtr++];
|
|
35
|
-
if (inPtr >= inLength)
|
|
41
|
+
if (inPtr >= inLength) {
|
|
42
|
+
throw new Error('Invalid compressed data');
|
|
43
|
+
}
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
ref -= inData[inPtr++];
|
|
39
|
-
if (outPtr + len + 2 > outLength)
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
if (outPtr + len + 2 > outLength) {
|
|
48
|
+
throw new Error('Output buffer is not large enough');
|
|
49
|
+
}
|
|
50
|
+
if (ref < 0) {
|
|
51
|
+
throw new Error('Invalid compressed data');
|
|
52
|
+
}
|
|
53
|
+
if (ref >= outPtr) {
|
|
54
|
+
throw new Error('Invalid compressed data');
|
|
55
|
+
}
|
|
42
56
|
|
|
43
57
|
do {
|
|
44
58
|
outData[outPtr++] = outData[ref++];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Schema, Field, Float32, Uint8, FixedSizeList} from '@loaders.gl/schema';
|
|
1
|
+
import {Schema, Field, Float32, Int32, Uint8, FixedSizeList} from '@loaders.gl/schema';
|
|
2
2
|
import type {PCDHeader} from './pcd-types';
|
|
3
3
|
|
|
4
4
|
type SchemaMetadata = Map<string, any>;
|
|
@@ -28,5 +28,13 @@ export function getPCDSchema(PCDheader: PCDHeader, metadata: SchemaMetadata): Sc
|
|
|
28
28
|
fields.push(new Field('COLOR_0', new FixedSizeList(3, new Field('rgb', new Uint8())), false));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
if (offset.intensity !== undefined) {
|
|
32
|
+
fields.push(new Field('intensity', new Field('intensity', new Float32()), false));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (offset.label !== undefined) {
|
|
36
|
+
fields.push(new Field('label', new Field('label', new Int32()), false));
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
return new Schema(fields, metadata);
|
|
32
40
|
}
|
package/src/lib/parse-pcd.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// @author Filipe Caixeta / http://filipecaixeta.com.br
|
|
7
7
|
// @author Mugen87 / https://github.com/Mugen87
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import {MeshAttribute, MeshAttributes} from '@loaders.gl/schema';
|
|
10
10
|
import {getMeshBoundingBox} from '@loaders.gl/schema';
|
|
11
11
|
import {decompressLZF} from './decompress-lzf';
|
|
12
12
|
import {getPCDSchema} from './get-pcd-schema';
|
|
@@ -126,6 +126,22 @@ function getMeshAttributes(attributes: HeaderAttributes): {[attributeName: strin
|
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
if (attributes.intensity && attributes.intensity.length > 0) {
|
|
130
|
+
// TODO - RGBA
|
|
131
|
+
normalizedAttributes.COLOR_0 = {
|
|
132
|
+
value: new Uint8Array(attributes.color),
|
|
133
|
+
size: 3
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (attributes.label && attributes.label.length > 0) {
|
|
138
|
+
// TODO - RGBA
|
|
139
|
+
normalizedAttributes.COLOR_0 = {
|
|
140
|
+
value: new Uint8Array(attributes.label),
|
|
141
|
+
size: 3
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
129
145
|
return normalizedAttributes;
|
|
130
146
|
}
|
|
131
147
|
|
|
@@ -240,11 +256,13 @@ function parsePCDHeader(data: string): PCDHeader {
|
|
|
240
256
|
* @param textData
|
|
241
257
|
* @returns [attributes]
|
|
242
258
|
*/
|
|
243
|
-
|
|
259
|
+
// eslint-enable-next-line complexity, max-statements
|
|
244
260
|
function parsePCDASCII(pcdHeader: PCDHeader, textData: string): HeaderAttributes {
|
|
245
261
|
const position: number[] = [];
|
|
246
262
|
const normal: number[] = [];
|
|
247
263
|
const color: number[] = [];
|
|
264
|
+
const intensity: number[] = [];
|
|
265
|
+
const label: number[] = [];
|
|
248
266
|
|
|
249
267
|
const offset = pcdHeader.offset;
|
|
250
268
|
const pcdData = textData.substr(pcdHeader.headerLen);
|
|
@@ -275,6 +293,14 @@ function parsePCDASCII(pcdHeader: PCDHeader, textData: string): HeaderAttributes
|
|
|
275
293
|
normal.push(parseFloat(line[offset.normal_y]));
|
|
276
294
|
normal.push(parseFloat(line[offset.normal_z]));
|
|
277
295
|
}
|
|
296
|
+
|
|
297
|
+
if (offset.intensity !== undefined) {
|
|
298
|
+
intensity.push(parseFloat(line[offset.intensity]));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (offset.label !== undefined) {
|
|
302
|
+
label.push(parseInt(line[offset.label]));
|
|
303
|
+
}
|
|
278
304
|
}
|
|
279
305
|
}
|
|
280
306
|
|
|
@@ -290,6 +316,8 @@ function parsePCDBinary(pcdHeader: PCDHeader, data: ArrayBufferLike): HeaderAttr
|
|
|
290
316
|
const position: number[] = [];
|
|
291
317
|
const normal: number[] = [];
|
|
292
318
|
const color: number[] = [];
|
|
319
|
+
const intensity: number[] = [];
|
|
320
|
+
const label: number[] = [];
|
|
293
321
|
|
|
294
322
|
const dataview = new DataView(data, pcdHeader.headerLen);
|
|
295
323
|
const offset = pcdHeader.offset;
|
|
@@ -312,9 +340,17 @@ function parsePCDBinary(pcdHeader: PCDHeader, data: ArrayBufferLike): HeaderAttr
|
|
|
312
340
|
normal.push(dataview.getFloat32(row + offset.normal_y, LITTLE_ENDIAN));
|
|
313
341
|
normal.push(dataview.getFloat32(row + offset.normal_z, LITTLE_ENDIAN));
|
|
314
342
|
}
|
|
343
|
+
|
|
344
|
+
if (offset.intensity !== undefined) {
|
|
345
|
+
intensity.push(dataview.getFloat32(row + offset.intensity, LITTLE_ENDIAN));
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (offset.label !== undefined) {
|
|
349
|
+
label.push(dataview.getInt32(row + offset.label, LITTLE_ENDIAN));
|
|
350
|
+
}
|
|
315
351
|
}
|
|
316
352
|
|
|
317
|
-
return {position, normal, color};
|
|
353
|
+
return {position, normal, color, intensity, label};
|
|
318
354
|
}
|
|
319
355
|
|
|
320
356
|
/** Parse compressed PCD data in in binary_compressed form ( https://pointclouds.org/documentation/tutorials/pcd_file_format.html)
|
|
@@ -324,78 +360,86 @@ function parsePCDBinary(pcdHeader: PCDHeader, data: ArrayBufferLike): HeaderAttr
|
|
|
324
360
|
* @param data
|
|
325
361
|
* @returns [attributes]
|
|
326
362
|
*/
|
|
327
|
-
|
|
363
|
+
// eslint-enable-next-line complexity, max-statements
|
|
364
|
+
function parsePCDBinaryCompressed(pcdHeader: PCDHeader, data: ArrayBufferLike): HeaderAttributes {
|
|
328
365
|
const position: number[] = [];
|
|
329
366
|
const normal: number[] = [];
|
|
330
367
|
const color: number[] = [];
|
|
368
|
+
const intensity: number[] = [];
|
|
369
|
+
const label: number[] = [];
|
|
331
370
|
|
|
332
|
-
const sizes = new Uint32Array(data.slice(
|
|
371
|
+
const sizes = new Uint32Array(data.slice(pcdHeader.headerLen, pcdHeader.headerLen + 8));
|
|
333
372
|
const compressedSize = sizes[0];
|
|
334
373
|
const decompressedSize = sizes[1];
|
|
335
374
|
const decompressed = decompressLZF(
|
|
336
|
-
new Uint8Array(data,
|
|
375
|
+
new Uint8Array(data, pcdHeader.headerLen + 8, compressedSize),
|
|
337
376
|
decompressedSize
|
|
338
377
|
);
|
|
339
378
|
const dataview = new DataView(decompressed.buffer);
|
|
340
379
|
|
|
341
|
-
const offset =
|
|
380
|
+
const offset = pcdHeader.offset;
|
|
342
381
|
|
|
343
|
-
for (let i = 0; i <
|
|
382
|
+
for (let i = 0; i < pcdHeader.points; i++) {
|
|
344
383
|
if (offset.x !== undefined) {
|
|
345
384
|
position.push(
|
|
346
|
-
dataview.getFloat32(
|
|
347
|
-
(PCDheader.points as number) * offset.x + (PCDheader.size as number[])[0] * i,
|
|
348
|
-
LITTLE_ENDIAN
|
|
349
|
-
)
|
|
385
|
+
dataview.getFloat32(pcdHeader.points * offset.x + pcdHeader.size[0] * i, LITTLE_ENDIAN)
|
|
350
386
|
);
|
|
351
387
|
position.push(
|
|
352
|
-
dataview.getFloat32(
|
|
353
|
-
(PCDheader.points as number) * offset.y + (PCDheader.size as number[])[1] * i,
|
|
354
|
-
LITTLE_ENDIAN
|
|
355
|
-
)
|
|
388
|
+
dataview.getFloat32(pcdHeader.points * offset.y + pcdHeader.size[1] * i, LITTLE_ENDIAN)
|
|
356
389
|
);
|
|
357
390
|
position.push(
|
|
358
|
-
dataview.getFloat32(
|
|
359
|
-
(PCDheader.points as number) * offset.z + (PCDheader.size as number[])[2] * i,
|
|
360
|
-
LITTLE_ENDIAN
|
|
361
|
-
)
|
|
391
|
+
dataview.getFloat32(pcdHeader.points * offset.z + pcdHeader.size[2] * i, LITTLE_ENDIAN)
|
|
362
392
|
);
|
|
363
393
|
}
|
|
364
394
|
|
|
365
395
|
if (offset.rgb !== undefined) {
|
|
366
396
|
color.push(
|
|
367
|
-
dataview.getUint8(
|
|
368
|
-
(PCDheader.points as number) * offset.rgb + (PCDheader.size as number[])[3] * i + 0
|
|
369
|
-
) / 255.0
|
|
397
|
+
dataview.getUint8(pcdHeader.points * offset.rgb + pcdHeader.size[3] * i + 0) / 255.0
|
|
370
398
|
);
|
|
371
399
|
color.push(
|
|
372
|
-
dataview.getUint8(
|
|
373
|
-
(PCDheader.points as number) * offset.rgb + (PCDheader.size as number[])[3] * i + 1
|
|
374
|
-
) / 255.0
|
|
400
|
+
dataview.getUint8(pcdHeader.points * offset.rgb + pcdHeader.size[3] * i + 1) / 255.0
|
|
375
401
|
);
|
|
376
402
|
color.push(
|
|
377
|
-
dataview.getUint8(
|
|
378
|
-
(PCDheader.points as number) * offset.rgb + (PCDheader.size as number[])[3] * i + 2
|
|
379
|
-
) / 255.0
|
|
403
|
+
dataview.getUint8(pcdHeader.points * offset.rgb + pcdHeader.size[3] * i + 2) / 255.0
|
|
380
404
|
);
|
|
381
405
|
}
|
|
382
406
|
|
|
383
407
|
if (offset.normal_x !== undefined) {
|
|
384
408
|
normal.push(
|
|
385
409
|
dataview.getFloat32(
|
|
386
|
-
|
|
410
|
+
pcdHeader.points * offset.normal_x + pcdHeader.size[4] * i,
|
|
387
411
|
LITTLE_ENDIAN
|
|
388
412
|
)
|
|
389
413
|
);
|
|
390
414
|
normal.push(
|
|
391
415
|
dataview.getFloat32(
|
|
392
|
-
|
|
416
|
+
pcdHeader.points * offset.normal_y + pcdHeader.size[5] * i,
|
|
393
417
|
LITTLE_ENDIAN
|
|
394
418
|
)
|
|
395
419
|
);
|
|
396
420
|
normal.push(
|
|
397
421
|
dataview.getFloat32(
|
|
398
|
-
|
|
422
|
+
pcdHeader.points * offset.normal_z + pcdHeader.size[6] * i,
|
|
423
|
+
LITTLE_ENDIAN
|
|
424
|
+
)
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (offset.intensity !== undefined) {
|
|
429
|
+
const intensityIndex = pcdHeader.fields.indexOf('intensity');
|
|
430
|
+
intensity.push(
|
|
431
|
+
dataview.getFloat32(
|
|
432
|
+
pcdHeader.points * offset.intensity + pcdHeader.size[intensityIndex] * i,
|
|
433
|
+
LITTLE_ENDIAN
|
|
434
|
+
)
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (offset.label !== undefined) {
|
|
439
|
+
const labelIndex = pcdHeader.fields.indexOf('label');
|
|
440
|
+
label.push(
|
|
441
|
+
dataview.getInt32(
|
|
442
|
+
pcdHeader.points * offset.label + pcdHeader.size[labelIndex] * i,
|
|
399
443
|
LITTLE_ENDIAN
|
|
400
444
|
)
|
|
401
445
|
);
|
|
@@ -405,6 +449,8 @@ function parsePCDBinaryCompressed(PCDheader: PCDHeader, data: ArrayBufferLike):
|
|
|
405
449
|
return {
|
|
406
450
|
position,
|
|
407
451
|
normal,
|
|
408
|
-
color
|
|
452
|
+
color,
|
|
453
|
+
intensity,
|
|
454
|
+
label
|
|
409
455
|
};
|
|
410
456
|
}
|
package/src/lib/pcd-types.ts
CHANGED
|
@@ -6,15 +6,15 @@ export type PCDHeader = {
|
|
|
6
6
|
data: any;
|
|
7
7
|
headerLen: number;
|
|
8
8
|
str: string;
|
|
9
|
-
version:
|
|
10
|
-
fields:
|
|
11
|
-
size:
|
|
12
|
-
type:
|
|
13
|
-
count:
|
|
14
|
-
width:
|
|
15
|
-
height:
|
|
16
|
-
viewpoint:
|
|
17
|
-
points:
|
|
9
|
+
version: number;
|
|
10
|
+
fields: string[];
|
|
11
|
+
size: number[];
|
|
12
|
+
type: null | string[];
|
|
13
|
+
count: null | number[];
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
viewpoint: null | string;
|
|
17
|
+
points: number;
|
|
18
18
|
offset: {[index: string]: number};
|
|
19
19
|
rowSize: number;
|
|
20
20
|
vertexCount: number;
|