@loaders.gl/ply 3.4.0-alpha.2 → 3.4.0-alpha.4
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 +142 -70
- package/dist/es5/index.js +17 -13
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/get-ply-schema.js +0 -1
- package/dist/es5/lib/get-ply-schema.js.map +1 -1
- package/dist/es5/lib/normalize-ply.js +47 -25
- package/dist/es5/lib/normalize-ply.js.map +1 -1
- package/dist/es5/lib/parse-ply-in-batches.js +162 -172
- package/dist/es5/lib/parse-ply-in-batches.js.map +1 -1
- package/dist/es5/lib/parse-ply.js +114 -54
- package/dist/es5/lib/parse-ply.js.map +1 -1
- package/dist/es5/lib/ply-types.js.map +1 -1
- package/dist/es5/ply-loader.js +1 -3
- package/dist/es5/ply-loader.js.map +1 -1
- package/dist/es5/workers/ply-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 +6 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/get-ply-schema.js +0 -1
- package/dist/esm/lib/get-ply-schema.js.map +1 -1
- package/dist/esm/lib/normalize-ply.js +46 -26
- package/dist/esm/lib/normalize-ply.js.map +1 -1
- package/dist/esm/lib/parse-ply-in-batches.js +18 -27
- package/dist/esm/lib/parse-ply-in-batches.js.map +1 -1
- package/dist/esm/lib/parse-ply.js +92 -56
- package/dist/esm/lib/parse-ply.js.map +1 -1
- package/dist/esm/lib/ply-types.js.map +1 -1
- package/dist/esm/ply-loader.js +1 -4
- package/dist/esm/ply-loader.js.map +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -9
- package/dist/lib/normalize-ply.js +33 -11
- package/dist/lib/parse-ply-in-batches.d.ts +1 -1
- package/dist/lib/parse-ply-in-batches.d.ts.map +1 -1
- package/dist/lib/parse-ply-in-batches.js +19 -18
- package/dist/lib/parse-ply.d.ts +4 -1
- package/dist/lib/parse-ply.d.ts.map +1 -1
- package/dist/lib/parse-ply.js +103 -47
- package/dist/lib/ply-types.d.ts +19 -11
- package/dist/lib/ply-types.d.ts.map +1 -1
- package/dist/ply-worker.js +143 -71
- package/package.json +4 -4
- package/src/index.ts +6 -6
- package/src/lib/normalize-ply.ts +34 -12
- package/src/lib/parse-ply-in-batches.ts +20 -22
- package/src/lib/parse-ply.ts +114 -55
- package/src/lib/ply-types.ts +21 -12
package/src/lib/parse-ply.ts
CHANGED
|
@@ -25,17 +25,21 @@ import type {
|
|
|
25
25
|
PLYHeader,
|
|
26
26
|
PLYAttributes,
|
|
27
27
|
MeshHeader,
|
|
28
|
-
|
|
28
|
+
PLYElement,
|
|
29
29
|
PLYProperty
|
|
30
30
|
} from './ply-types';
|
|
31
31
|
import normalizePLY from './normalize-ply';
|
|
32
32
|
|
|
33
|
+
export type ParsePLYOptions = {
|
|
34
|
+
propertyNameMapping?: Record<string, string>;
|
|
35
|
+
};
|
|
36
|
+
|
|
33
37
|
/**
|
|
34
38
|
* @param data
|
|
35
39
|
* @param options
|
|
36
40
|
* @returns
|
|
37
41
|
*/
|
|
38
|
-
export
|
|
42
|
+
export function parsePLY(data: ArrayBuffer | string, options: ParsePLYOptions = {}): PLYMesh {
|
|
39
43
|
let header: PLYHeader & MeshHeader;
|
|
40
44
|
let attributes: PLYAttributes;
|
|
41
45
|
|
|
@@ -56,7 +60,7 @@ export default function parsePLY(data: ArrayBuffer | string, options = {}): PLYM
|
|
|
56
60
|
* @param options
|
|
57
61
|
* @returns header
|
|
58
62
|
*/
|
|
59
|
-
function parseHeader(data: any, options
|
|
63
|
+
function parseHeader(data: any, options?: ParsePLYOptions): PLYHeader {
|
|
60
64
|
const PLY_HEADER_PATTERN = /ply([\s\S]*)end_header\s/;
|
|
61
65
|
|
|
62
66
|
let headerText = '';
|
|
@@ -80,10 +84,11 @@ function parseHeader(data: any, options: {[index: string]: any}): PLYHeader {
|
|
|
80
84
|
* @param options
|
|
81
85
|
* @returns header
|
|
82
86
|
*/
|
|
87
|
+
// eslint-disable-next-line complexity
|
|
83
88
|
function parseHeaderLines(
|
|
84
89
|
lines: string[],
|
|
85
90
|
headerLength: number,
|
|
86
|
-
options
|
|
91
|
+
options?: ParsePLYOptions
|
|
87
92
|
): PLYHeader {
|
|
88
93
|
const header: PLYHeader = {
|
|
89
94
|
comments: [],
|
|
@@ -93,7 +98,7 @@ function parseHeaderLines(
|
|
|
93
98
|
|
|
94
99
|
let lineType: string | undefined;
|
|
95
100
|
let lineValues: string[];
|
|
96
|
-
let currentElement:
|
|
101
|
+
let currentElement: PLYElement | null = null;
|
|
97
102
|
|
|
98
103
|
for (let i = 0; i < lines.length; i++) {
|
|
99
104
|
let line: string = lines[i];
|
|
@@ -119,6 +124,7 @@ function parseHeaderLines(
|
|
|
119
124
|
break;
|
|
120
125
|
|
|
121
126
|
case 'element':
|
|
127
|
+
// Start new element, store previous element
|
|
122
128
|
if (currentElement) {
|
|
123
129
|
header.elements.push(currentElement);
|
|
124
130
|
}
|
|
@@ -131,12 +137,13 @@ function parseHeaderLines(
|
|
|
131
137
|
break;
|
|
132
138
|
|
|
133
139
|
case 'property':
|
|
134
|
-
if (
|
|
135
|
-
|
|
140
|
+
if (currentElement) {
|
|
141
|
+
const property = makePLYElementProperty(lineValues);
|
|
142
|
+
if (options?.propertyNameMapping && property.name in options?.propertyNameMapping) {
|
|
143
|
+
property.name = options?.propertyNameMapping[property.name];
|
|
144
|
+
}
|
|
145
|
+
currentElement.properties.push(property);
|
|
136
146
|
}
|
|
137
|
-
currentElement.properties.push(
|
|
138
|
-
makePLYElementProperty(lineValues, options.propertyNameMapping)
|
|
139
|
-
);
|
|
140
147
|
break;
|
|
141
148
|
|
|
142
149
|
default:
|
|
@@ -145,36 +152,74 @@ function parseHeaderLines(
|
|
|
145
152
|
}
|
|
146
153
|
}
|
|
147
154
|
|
|
148
|
-
|
|
155
|
+
// Store in-progress element
|
|
156
|
+
if (currentElement) {
|
|
149
157
|
header.elements.push(currentElement);
|
|
150
158
|
}
|
|
151
159
|
|
|
152
160
|
return header;
|
|
153
161
|
}
|
|
154
162
|
|
|
155
|
-
/**
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
+
/** Generate attributes arrays from the header */
|
|
164
|
+
// eslint-disable-next-line complexity
|
|
165
|
+
function getPLYAttributes(header: PLYHeader): PLYAttributes {
|
|
166
|
+
// TODO Generate only the attribute arrays actually in the header
|
|
167
|
+
const attributes = {
|
|
168
|
+
indices: [],
|
|
169
|
+
vertices: [],
|
|
170
|
+
normals: [],
|
|
171
|
+
uvs: [],
|
|
172
|
+
colors: []
|
|
163
173
|
};
|
|
164
174
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
175
|
+
for (const element of header.elements) {
|
|
176
|
+
if (element.name === 'vertex') {
|
|
177
|
+
for (const property of element.properties) {
|
|
178
|
+
switch (property.name) {
|
|
179
|
+
case 'x':
|
|
180
|
+
case 'y':
|
|
181
|
+
case 'z':
|
|
182
|
+
case 'nx':
|
|
183
|
+
case 'ny':
|
|
184
|
+
case 'nz':
|
|
185
|
+
case 's':
|
|
186
|
+
case 't':
|
|
187
|
+
case 'red':
|
|
188
|
+
case 'green':
|
|
189
|
+
case 'blue':
|
|
190
|
+
break;
|
|
191
|
+
default:
|
|
192
|
+
// Add any non-geometry attributes
|
|
193
|
+
attributes[property.name] = [];
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
171
198
|
}
|
|
172
199
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
200
|
+
return attributes;
|
|
201
|
+
}
|
|
176
202
|
|
|
177
|
-
|
|
203
|
+
/**
|
|
204
|
+
* @param propertyValues
|
|
205
|
+
* @returns property of ply element
|
|
206
|
+
*/
|
|
207
|
+
function makePLYElementProperty(propertyValues: string[]): PLYProperty {
|
|
208
|
+
const type = propertyValues[0];
|
|
209
|
+
switch (type) {
|
|
210
|
+
case 'list':
|
|
211
|
+
return {
|
|
212
|
+
type,
|
|
213
|
+
name: propertyValues[3],
|
|
214
|
+
countType: propertyValues[1],
|
|
215
|
+
itemType: propertyValues[2]
|
|
216
|
+
};
|
|
217
|
+
default:
|
|
218
|
+
return {
|
|
219
|
+
type,
|
|
220
|
+
name: propertyValues[1]
|
|
221
|
+
};
|
|
222
|
+
}
|
|
178
223
|
}
|
|
179
224
|
|
|
180
225
|
/**
|
|
@@ -216,7 +261,7 @@ function parseASCIINumber(n: string, type: string): number {
|
|
|
216
261
|
* @param line
|
|
217
262
|
* @returns ASCII element
|
|
218
263
|
*/
|
|
219
|
-
function
|
|
264
|
+
function parsePLYElement(properties: any[], line: string) {
|
|
220
265
|
const values: any = line.split(/\s+/);
|
|
221
266
|
|
|
222
267
|
const element = {};
|
|
@@ -247,13 +292,7 @@ function parseASCIIElement(properties: any[], line: string) {
|
|
|
247
292
|
function parseASCII(data: any, header: PLYHeader): PLYAttributes {
|
|
248
293
|
// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
|
|
249
294
|
|
|
250
|
-
const attributes
|
|
251
|
-
indices: [],
|
|
252
|
-
vertices: [],
|
|
253
|
-
normals: [],
|
|
254
|
-
uvs: [],
|
|
255
|
-
colors: []
|
|
256
|
-
};
|
|
295
|
+
const attributes = getPLYAttributes(header);
|
|
257
296
|
|
|
258
297
|
let result: RegExpExecArray | null;
|
|
259
298
|
|
|
@@ -277,7 +316,7 @@ function parseASCII(data: any, header: PLYHeader): PLYAttributes {
|
|
|
277
316
|
currentElementCount = 0;
|
|
278
317
|
}
|
|
279
318
|
|
|
280
|
-
const element =
|
|
319
|
+
const element = parsePLYElement(header.elements[currentElement].properties, line);
|
|
281
320
|
handleElement(attributes, header.elements[currentElement].name, element);
|
|
282
321
|
currentElementCount++;
|
|
283
322
|
}
|
|
@@ -298,18 +337,44 @@ function handleElement(
|
|
|
298
337
|
element: any = {}
|
|
299
338
|
) {
|
|
300
339
|
if (elementName === 'vertex') {
|
|
301
|
-
|
|
340
|
+
for (const propertyName of Object.keys(element)) {
|
|
341
|
+
switch (propertyName) {
|
|
342
|
+
case 'x':
|
|
343
|
+
buffer.vertices.push(element.x, element.y, element.z);
|
|
344
|
+
break;
|
|
345
|
+
case 'y':
|
|
346
|
+
case 'z':
|
|
347
|
+
break;
|
|
302
348
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
349
|
+
case 'nx':
|
|
350
|
+
if ('nx' in element && 'ny' in element && 'nz' in element) {
|
|
351
|
+
buffer.normals.push(element.nx, element.ny, element.nz);
|
|
352
|
+
}
|
|
353
|
+
break;
|
|
354
|
+
case 'ny':
|
|
355
|
+
case 'nz':
|
|
356
|
+
break;
|
|
306
357
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
358
|
+
case 's':
|
|
359
|
+
if ('s' in element && 't' in element) {
|
|
360
|
+
buffer.uvs.push(element.s, element.t);
|
|
361
|
+
}
|
|
362
|
+
break;
|
|
363
|
+
case 't':
|
|
364
|
+
break;
|
|
365
|
+
|
|
366
|
+
case 'red':
|
|
367
|
+
if ('red' in element && 'green' in element && 'blue' in element) {
|
|
368
|
+
buffer.colors.push(element.red, element.green, element.blue);
|
|
369
|
+
}
|
|
370
|
+
break;
|
|
371
|
+
case 'green':
|
|
372
|
+
case 'blue':
|
|
373
|
+
break;
|
|
310
374
|
|
|
311
|
-
|
|
312
|
-
|
|
375
|
+
default:
|
|
376
|
+
buffer[propertyName].push(element[propertyName]);
|
|
377
|
+
}
|
|
313
378
|
}
|
|
314
379
|
} else if (elementName === 'face') {
|
|
315
380
|
const vertexIndices = element.vertex_indices || element.vertex_index; // issue #9338
|
|
@@ -419,14 +484,8 @@ type BinaryAttributes = {
|
|
|
419
484
|
* @param header
|
|
420
485
|
* @returns [attributes] of data
|
|
421
486
|
*/
|
|
422
|
-
function parseBinary(data: ArrayBuffer, header:
|
|
423
|
-
const attributes
|
|
424
|
-
indices: [],
|
|
425
|
-
vertices: [],
|
|
426
|
-
normals: [],
|
|
427
|
-
uvs: [],
|
|
428
|
-
colors: []
|
|
429
|
-
};
|
|
487
|
+
function parseBinary(data: ArrayBuffer, header: PLYHeader): BinaryAttributes {
|
|
488
|
+
const attributes = getPLYAttributes(header);
|
|
430
489
|
|
|
431
490
|
const littleEndian = header.format === 'binary_little_endian';
|
|
432
491
|
const body = new DataView(data, header.headerLength);
|
package/src/lib/ply-types.ts
CHANGED
|
@@ -1,36 +1,45 @@
|
|
|
1
|
+
// loaders.gl, MIT license
|
|
1
2
|
import type {Mesh} from '@loaders.gl/schema';
|
|
2
3
|
|
|
4
|
+
/** A parsed PLY mesh */
|
|
5
|
+
export type PLYMesh = Mesh & {
|
|
6
|
+
loader: 'ply';
|
|
7
|
+
loaderData: PLYHeader;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/** A PLY header */
|
|
3
11
|
export type PLYHeader = {
|
|
4
12
|
format?: string;
|
|
5
13
|
comments: string[];
|
|
6
|
-
elements:
|
|
14
|
+
elements: PLYElement[];
|
|
7
15
|
version?: string;
|
|
8
16
|
headerLength?: number;
|
|
9
17
|
};
|
|
10
18
|
|
|
11
|
-
/** A parsed PLY mesh */
|
|
12
|
-
export type PLYMesh = Mesh & {
|
|
13
|
-
loader: 'ply';
|
|
14
|
-
loaderData: PLYHeader;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
19
|
// INTERNAL TYPES
|
|
18
20
|
|
|
21
|
+
/** A general mesh header */
|
|
19
22
|
export type MeshHeader = {
|
|
20
23
|
vertexCount?: number;
|
|
21
24
|
boundingBox?: [[number, number, number], [number, number, number]];
|
|
22
25
|
};
|
|
23
26
|
|
|
27
|
+
/** The parsed columnar values */
|
|
24
28
|
export type PLYAttributes = {
|
|
25
29
|
[index: string]: number[];
|
|
26
30
|
};
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
/** A top level PLY element (vertex, face, ...) */
|
|
33
|
+
export type PLYElement = {
|
|
34
|
+
name: string;
|
|
35
|
+
count: number;
|
|
36
|
+
properties: PLYProperty[];
|
|
30
37
|
};
|
|
31
38
|
|
|
32
|
-
|
|
39
|
+
/** One property in a top-level PLY element */
|
|
40
|
+
export type PLYProperty = {
|
|
33
41
|
name: string;
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
type: string;
|
|
43
|
+
countType?: string;
|
|
44
|
+
itemType?: string;
|
|
36
45
|
};
|