@loaders.gl/ply 3.1.0-alpha.5 → 3.1.0-beta.5

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.
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const normalize_ply_1 = __importDefault(require("./normalize-ply"));
7
+ /**
8
+ * @param data
9
+ * @param options
10
+ * @returns
11
+ */
12
+ function parsePLY(data, options = {}) {
13
+ let header;
14
+ let attributes;
15
+ if (data instanceof ArrayBuffer) {
16
+ const text = new TextDecoder().decode(data);
17
+ header = parseHeader(text, options);
18
+ attributes = header.format === 'ascii' ? parseASCII(text, header) : parseBinary(data, header);
19
+ }
20
+ else {
21
+ header = parseHeader(data, options);
22
+ attributes = parseASCII(data, header);
23
+ }
24
+ return (0, normalize_ply_1.default)(header, attributes);
25
+ }
26
+ exports.default = parsePLY;
27
+ /**
28
+ * @param data
29
+ * @param options
30
+ * @returns header
31
+ */
32
+ function parseHeader(data, options) {
33
+ const PLY_HEADER_PATTERN = /ply([\s\S]*)end_header\s/;
34
+ let headerText = '';
35
+ let headerLength = 0;
36
+ const result = PLY_HEADER_PATTERN.exec(data);
37
+ if (result !== null) {
38
+ headerText = result[1];
39
+ headerLength = result[0].length;
40
+ }
41
+ const lines = headerText.split('\n');
42
+ const header = parseHeaderLines(lines, headerLength, options);
43
+ return header;
44
+ }
45
+ /**
46
+ * @param lines
47
+ * @param headerLength
48
+ * @param options
49
+ * @returns header
50
+ */
51
+ function parseHeaderLines(lines, headerLength, options) {
52
+ const header = {
53
+ comments: [],
54
+ elements: [],
55
+ headerLength
56
+ };
57
+ let lineType;
58
+ let lineValues;
59
+ let currentElement = null;
60
+ for (let i = 0; i < lines.length; i++) {
61
+ let line = lines[i];
62
+ line = line.trim();
63
+ if (line === '') {
64
+ // eslint-disable-next-line
65
+ continue;
66
+ }
67
+ lineValues = line.split(/\s+/);
68
+ lineType = lineValues.shift();
69
+ line = lineValues.join(' ');
70
+ switch (lineType) {
71
+ case 'format':
72
+ header.format = lineValues[0];
73
+ header.version = lineValues[1];
74
+ break;
75
+ case 'comment':
76
+ header.comments.push(line);
77
+ break;
78
+ case 'element':
79
+ if (currentElement) {
80
+ header.elements.push(currentElement);
81
+ }
82
+ currentElement = {
83
+ name: lineValues[0],
84
+ count: parseInt(lineValues[1], 10),
85
+ properties: []
86
+ };
87
+ break;
88
+ case 'property':
89
+ if (!currentElement) {
90
+ break;
91
+ }
92
+ currentElement.properties.push(makePLYElementProperty(lineValues, options.propertyNameMapping));
93
+ break;
94
+ default:
95
+ // eslint-disable-next-line
96
+ console.log('unhandled', lineType, lineValues);
97
+ }
98
+ }
99
+ if (currentElement !== undefined) {
100
+ header.elements.push(currentElement);
101
+ }
102
+ return header;
103
+ }
104
+ /**
105
+ * @param propertValues
106
+ * @param propertyNameMapping
107
+ * @returns property of ply element
108
+ */
109
+ function makePLYElementProperty(propertValues, propertyNameMapping) {
110
+ const property = {
111
+ type: propertValues[0]
112
+ };
113
+ if (property.type === 'list') {
114
+ property.name = propertValues[3];
115
+ property.countType = propertValues[1];
116
+ property.itemType = propertValues[2];
117
+ }
118
+ else {
119
+ property.name = propertValues[1];
120
+ }
121
+ if (propertyNameMapping && property.name in propertyNameMapping) {
122
+ property.name = propertyNameMapping[property.name];
123
+ }
124
+ return property;
125
+ }
126
+ /**
127
+ * Parses ASCII number
128
+ * @param n
129
+ * @param type
130
+ * @returns
131
+ */
132
+ // eslint-disable-next-line complexity
133
+ function parseASCIINumber(n, type) {
134
+ switch (type) {
135
+ case 'char':
136
+ case 'uchar':
137
+ case 'short':
138
+ case 'ushort':
139
+ case 'int':
140
+ case 'uint':
141
+ case 'int8':
142
+ case 'uint8':
143
+ case 'int16':
144
+ case 'uint16':
145
+ case 'int32':
146
+ case 'uint32':
147
+ return parseInt(n, 10);
148
+ case 'float':
149
+ case 'double':
150
+ case 'float32':
151
+ case 'float64':
152
+ return parseFloat(n);
153
+ default:
154
+ throw new Error(type);
155
+ }
156
+ }
157
+ /**
158
+ * @param properties
159
+ * @param line
160
+ * @returns ASCII element
161
+ */
162
+ function parseASCIIElement(properties, line) {
163
+ const values = line.split(/\s+/);
164
+ const element = {};
165
+ for (let i = 0; i < properties.length; i++) {
166
+ if (properties[i].type === 'list') {
167
+ const list = [];
168
+ const n = parseASCIINumber(values.shift(), properties[i].countType);
169
+ for (let j = 0; j < n; j++) {
170
+ list.push(parseASCIINumber(values.shift(), properties[i].itemType));
171
+ }
172
+ element[properties[i].name] = list;
173
+ }
174
+ else {
175
+ element[properties[i].name] = parseASCIINumber(values.shift(), properties[i].type);
176
+ }
177
+ }
178
+ return element;
179
+ }
180
+ /**
181
+ * @param data
182
+ * @param header
183
+ * @returns [attributes]
184
+ */
185
+ function parseASCII(data, header) {
186
+ // PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
187
+ const attributes = {
188
+ indices: [],
189
+ vertices: [],
190
+ normals: [],
191
+ uvs: [],
192
+ colors: []
193
+ };
194
+ let result;
195
+ const patternBody = /end_header\s([\s\S]*)$/;
196
+ let body = '';
197
+ if ((result = patternBody.exec(data)) !== null) {
198
+ body = result[1];
199
+ }
200
+ const lines = body.split('\n');
201
+ let currentElement = 0;
202
+ let currentElementCount = 0;
203
+ for (let i = 0; i < lines.length; i++) {
204
+ let line = lines[i];
205
+ line = line.trim();
206
+ if (line !== '') {
207
+ if (currentElementCount >= header.elements[currentElement].count) {
208
+ currentElement++;
209
+ currentElementCount = 0;
210
+ }
211
+ const element = parseASCIIElement(header.elements[currentElement].properties, line);
212
+ handleElement(attributes, header.elements[currentElement].name, element);
213
+ currentElementCount++;
214
+ }
215
+ }
216
+ return attributes;
217
+ }
218
+ /**
219
+ * @param buffer
220
+ * @param elementName
221
+ * @param element
222
+ */
223
+ // eslint-disable-next-line complexity
224
+ function handleElement(buffer, elementName, element = {}) {
225
+ if (elementName === 'vertex') {
226
+ buffer.vertices.push(element.x, element.y, element.z);
227
+ if ('nx' in element && 'ny' in element && 'nz' in element) {
228
+ buffer.normals.push(element.nx, element.ny, element.nz);
229
+ }
230
+ if ('s' in element && 't' in element) {
231
+ buffer.uvs.push(element.s, element.t);
232
+ }
233
+ if ('red' in element && 'green' in element && 'blue' in element) {
234
+ buffer.colors.push(element.red, element.green, element.blue);
235
+ }
236
+ }
237
+ else if (elementName === 'face') {
238
+ const vertexIndices = element.vertex_indices || element.vertex_index; // issue #9338
239
+ if (vertexIndices.length === 3) {
240
+ buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[2]);
241
+ }
242
+ else if (vertexIndices.length === 4) {
243
+ buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[3]);
244
+ buffer.indices.push(vertexIndices[1], vertexIndices[2], vertexIndices[3]);
245
+ }
246
+ }
247
+ }
248
+ /**
249
+ * Reads binary data
250
+ * @param dataview
251
+ * @param at
252
+ * @param type
253
+ * @param littleEndian
254
+ * @returns [number, number]
255
+ */
256
+ // eslint-disable-next-line complexity
257
+ function binaryRead(dataview, at, type, littleEndian) {
258
+ switch (type) {
259
+ // corespondences for non-specific length types here match rply:
260
+ case 'int8':
261
+ case 'char':
262
+ return [dataview.getInt8(at), 1];
263
+ case 'uint8':
264
+ case 'uchar':
265
+ return [dataview.getUint8(at), 1];
266
+ case 'int16':
267
+ case 'short':
268
+ return [dataview.getInt16(at, littleEndian), 2];
269
+ case 'uint16':
270
+ case 'ushort':
271
+ return [dataview.getUint16(at, littleEndian), 2];
272
+ case 'int32':
273
+ case 'int':
274
+ return [dataview.getInt32(at, littleEndian), 4];
275
+ case 'uint32':
276
+ case 'uint':
277
+ return [dataview.getUint32(at, littleEndian), 4];
278
+ case 'float32':
279
+ case 'float':
280
+ return [dataview.getFloat32(at, littleEndian), 4];
281
+ case 'float64':
282
+ case 'double':
283
+ return [dataview.getFloat64(at, littleEndian), 8];
284
+ default:
285
+ throw new Error(type);
286
+ }
287
+ }
288
+ /**
289
+ * Reads binary data
290
+ * @param dataview
291
+ * @param at
292
+ * @param properties
293
+ * @param littleEndian
294
+ * @returns [object, number]
295
+ */
296
+ function binaryReadElement(dataview, at, properties, littleEndian) {
297
+ const element = {};
298
+ let result;
299
+ let read = 0;
300
+ for (let i = 0; i < properties.length; i++) {
301
+ if (properties[i].type === 'list') {
302
+ const list = [];
303
+ result = binaryRead(dataview, at + read, properties[i].countType, littleEndian);
304
+ const n = result[0];
305
+ read += result[1];
306
+ for (let j = 0; j < n; j++) {
307
+ result = binaryRead(dataview, at + read, properties[i].itemType, littleEndian);
308
+ // @ts-ignore
309
+ list.push(result[0]);
310
+ read += result[1];
311
+ }
312
+ element[properties[i].name] = list;
313
+ }
314
+ else {
315
+ result = binaryRead(dataview, at + read, properties[i].type, littleEndian);
316
+ element[properties[i].name] = result[0];
317
+ read += result[1];
318
+ }
319
+ }
320
+ return [element, read];
321
+ }
322
+ /**
323
+ * Parses binary data
324
+ * @param data
325
+ * @param header
326
+ * @returns [attributes] of data
327
+ */
328
+ function parseBinary(data, header) {
329
+ const attributes = {
330
+ indices: [],
331
+ vertices: [],
332
+ normals: [],
333
+ uvs: [],
334
+ colors: []
335
+ };
336
+ const littleEndian = header.format === 'binary_little_endian';
337
+ const body = new DataView(data, header.headerLength);
338
+ let result;
339
+ let loc = 0;
340
+ for (let currentElement = 0; currentElement < header.elements.length; currentElement++) {
341
+ const count = header.elements[currentElement].count;
342
+ for (let currentElementCount = 0; currentElementCount < count; currentElementCount++) {
343
+ result = binaryReadElement(body, loc, header.elements[currentElement].properties, littleEndian);
344
+ loc += result[1];
345
+ const element = result[0];
346
+ handleElement(attributes, header.elements[currentElement].name, element);
347
+ }
348
+ }
349
+ return attributes;
350
+ }
@@ -26,3 +26,4 @@ export declare type ASCIIElement = {
26
26
  count: number;
27
27
  properties: any[];
28
28
  };
29
+ //# sourceMappingURL=ply-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ply-types.d.ts","sourceRoot":"","sources":["../../src/lib/ply-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,oBAAoB,CAAC;AAE7C,oBAAY,SAAS,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAwB;AACxB,oBAAY,OAAO,GAAG,IAAI,GAAG;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,UAAU,EAAE,SAAS,CAAC;CACvB,CAAC;AAIF,oBAAY,UAAU,GAAG;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpE,CAAC;AAEF,oBAAY,aAAa,GAAG;IAC1B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF,oBAAY,WAAW,GAAG;IACxB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,GAAG,EAAE,CAAC;CACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -21,3 +21,4 @@ export declare const PLYLoader: {
21
21
  };
22
22
  };
23
23
  export declare const _typecheckPLYLoader: Loader;
24
+ //# sourceMappingURL=ply-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ply-loader.d.ts","sourceRoot":"","sources":["../src/ply-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,0BAA0B,CAAC;AAMrD;;;;GAIG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;CAerB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAkB,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._typecheckPLYLoader = exports.PLYLoader = void 0;
4
+ // __VERSION__ is injected by babel-plugin-version-inline
5
+ // @ts-ignore TS2304: Cannot find name '__VERSION__'.
6
+ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
7
+ /**
8
+ * Worker loader for PLY - Polygon File Format (aka Stanford Triangle Format)'
9
+ * links: ['http://paulbourke.net/dataformats/ply/',
10
+ * 'https://en.wikipedia.org/wiki/PLY_(file_format)']
11
+ */
12
+ exports.PLYLoader = {
13
+ name: 'PLY',
14
+ id: 'ply',
15
+ module: 'ply',
16
+ shapes: ['mesh', 'gltf', 'columnar-table'],
17
+ version: VERSION,
18
+ worker: true,
19
+ extensions: ['ply'],
20
+ mimeTypes: ['text/plain', 'application/octet-stream'],
21
+ text: true,
22
+ binary: true,
23
+ tests: ['ply'],
24
+ options: {
25
+ ply: {}
26
+ }
27
+ };
28
+ exports._typecheckPLYLoader = exports.PLYLoader;