@loaders.gl/ply 4.0.0-alpha.1 → 4.0.0-alpha.11
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/bundle.d.ts +2 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +2 -2
- package/dist/dist.min.js +833 -0
- package/dist/es5/bundle.js +6 -0
- package/dist/es5/bundle.js.map +1 -0
- package/dist/es5/index.js +51 -0
- package/dist/es5/index.js.map +1 -0
- package/dist/es5/lib/get-ply-schema.js +28 -0
- package/dist/es5/lib/get-ply-schema.js.map +1 -0
- package/dist/es5/lib/normalize-ply.js +93 -0
- package/dist/es5/lib/normalize-ply.js.map +1 -0
- package/dist/es5/lib/parse-ply-in-batches.js +289 -0
- package/dist/es5/lib/parse-ply-in-batches.js.map +1 -0
- package/dist/es5/lib/parse-ply.js +348 -0
- package/dist/es5/lib/parse-ply.js.map +1 -0
- package/dist/es5/lib/ply-types.js +2 -0
- package/dist/es5/lib/ply-types.js.map +1 -0
- package/dist/es5/ply-loader.js +26 -0
- package/dist/es5/ply-loader.js.map +1 -0
- package/dist/es5/workers/ply-worker.js +6 -0
- package/dist/es5/workers/ply-worker.js.map +1 -0
- package/dist/esm/bundle.js +4 -0
- package/dist/esm/bundle.js.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/get-ply-schema.js +22 -0
- package/dist/esm/lib/get-ply-schema.js.map +1 -0
- package/dist/esm/lib/normalize-ply.js +86 -0
- package/dist/esm/lib/normalize-ply.js.map +1 -0
- package/dist/esm/lib/parse-ply-in-batches.js +177 -0
- package/dist/esm/lib/parse-ply-in-batches.js.map +1 -0
- package/dist/esm/lib/parse-ply.js +319 -0
- package/dist/esm/lib/parse-ply.js.map +1 -0
- package/dist/esm/lib/ply-types.js +2 -0
- package/dist/esm/lib/ply-types.js.map +1 -0
- package/dist/esm/ply-loader.js +18 -0
- package/dist/esm/ply-loader.js.map +1 -0
- package/dist/esm/workers/ply-worker.js +4 -0
- package/dist/esm/workers/ply-worker.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -11
- package/dist/lib/get-ply-schema.d.ts +10 -0
- package/dist/lib/get-ply-schema.d.ts.map +1 -0
- package/dist/lib/get-ply-schema.js +34 -24
- package/dist/lib/normalize-ply.d.ts +8 -0
- package/dist/lib/normalize-ply.d.ts.map +1 -0
- package/dist/lib/normalize-ply.js +76 -65
- package/dist/lib/parse-ply-in-batches.d.ts +8 -0
- package/dist/lib/parse-ply-in-batches.d.ts.map +1 -0
- package/dist/lib/parse-ply-in-batches.js +237 -202
- package/dist/lib/parse-ply.d.ts +11 -0
- package/dist/lib/parse-ply.d.ts.map +1 -0
- package/dist/lib/parse-ply.js +378 -299
- package/dist/lib/ply-types.d.ts +37 -0
- package/dist/lib/ply-types.d.ts.map +1 -0
- package/dist/lib/ply-types.js +2 -2
- package/dist/ply-loader.d.ts +10 -0
- package/dist/ply-loader.d.ts.map +1 -0
- package/dist/ply-loader.js +27 -18
- package/dist/ply-worker.js +240 -578
- package/dist/workers/ply-worker.d.ts +2 -0
- package/dist/workers/ply-worker.d.ts.map +1 -0
- package/dist/workers/ply-worker.js +5 -4
- package/package.json +9 -12
- package/src/index.ts +15 -10
- package/src/lib/get-ply-schema.ts +11 -10
- package/src/lib/normalize-ply.ts +34 -12
- package/src/lib/parse-ply-in-batches.ts +23 -26
- package/src/lib/parse-ply.ts +114 -55
- package/src/lib/ply-types.ts +21 -12
- package/src/ply-loader.ts +4 -3
- package/dist/bundle.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/get-ply-schema.js.map +0 -1
- package/dist/lib/normalize-ply.js.map +0 -1
- package/dist/lib/parse-ply-in-batches.js.map +0 -1
- package/dist/lib/parse-ply.js.map +0 -1
- package/dist/lib/ply-types.js.map +0 -1
- package/dist/ply-loader.js.map +0 -1
- package/dist/workers/ply-worker.js.map +0 -1
package/dist/dist.min.js
ADDED
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[Object.keys(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
__markAsModule(target);
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/ply-loader.ts
|
|
17
|
+
var VERSION, PLYLoader;
|
|
18
|
+
var init_ply_loader = __esm({
|
|
19
|
+
"src/ply-loader.ts"() {
|
|
20
|
+
VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
|
|
21
|
+
PLYLoader = {
|
|
22
|
+
name: "PLY",
|
|
23
|
+
id: "ply",
|
|
24
|
+
module: "ply",
|
|
25
|
+
version: VERSION,
|
|
26
|
+
worker: true,
|
|
27
|
+
extensions: ["ply"],
|
|
28
|
+
mimeTypes: ["text/plain", "application/octet-stream"],
|
|
29
|
+
text: true,
|
|
30
|
+
binary: true,
|
|
31
|
+
tests: ["ply"],
|
|
32
|
+
options: {
|
|
33
|
+
ply: {}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// ../schema/src/lib/table/simple-table/data-type.ts
|
|
40
|
+
function getDataTypeFromTypedArray(array) {
|
|
41
|
+
switch (array.constructor) {
|
|
42
|
+
case Int8Array:
|
|
43
|
+
return "int8";
|
|
44
|
+
case Uint8Array:
|
|
45
|
+
case Uint8ClampedArray:
|
|
46
|
+
return "uint8";
|
|
47
|
+
case Int16Array:
|
|
48
|
+
return "int16";
|
|
49
|
+
case Uint16Array:
|
|
50
|
+
return "uint16";
|
|
51
|
+
case Int32Array:
|
|
52
|
+
return "int32";
|
|
53
|
+
case Uint32Array:
|
|
54
|
+
return "uint32";
|
|
55
|
+
case Float32Array:
|
|
56
|
+
return "float32";
|
|
57
|
+
case Float64Array:
|
|
58
|
+
return "float64";
|
|
59
|
+
default:
|
|
60
|
+
return "null";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
var init_data_type = __esm({
|
|
64
|
+
"../schema/src/lib/table/simple-table/data-type.ts"() {
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// ../schema/src/lib/mesh/mesh-utils.ts
|
|
69
|
+
function getMeshBoundingBox(attributes) {
|
|
70
|
+
let minX = Infinity;
|
|
71
|
+
let minY = Infinity;
|
|
72
|
+
let minZ = Infinity;
|
|
73
|
+
let maxX = -Infinity;
|
|
74
|
+
let maxY = -Infinity;
|
|
75
|
+
let maxZ = -Infinity;
|
|
76
|
+
const positions = attributes.POSITION ? attributes.POSITION.value : [];
|
|
77
|
+
const len = positions && positions.length;
|
|
78
|
+
for (let i = 0; i < len; i += 3) {
|
|
79
|
+
const x = positions[i];
|
|
80
|
+
const y = positions[i + 1];
|
|
81
|
+
const z = positions[i + 2];
|
|
82
|
+
minX = x < minX ? x : minX;
|
|
83
|
+
minY = y < minY ? y : minY;
|
|
84
|
+
minZ = z < minZ ? z : minZ;
|
|
85
|
+
maxX = x > maxX ? x : maxX;
|
|
86
|
+
maxY = y > maxY ? y : maxY;
|
|
87
|
+
maxZ = z > maxZ ? z : maxZ;
|
|
88
|
+
}
|
|
89
|
+
return [
|
|
90
|
+
[minX, minY, minZ],
|
|
91
|
+
[maxX, maxY, maxZ]
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
var init_mesh_utils = __esm({
|
|
95
|
+
"../schema/src/lib/mesh/mesh-utils.ts"() {
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// ../schema/src/lib/mesh/deduce-mesh-schema.ts
|
|
100
|
+
function deduceMeshSchema(attributes, metadata = {}) {
|
|
101
|
+
const fields = deduceMeshFields(attributes);
|
|
102
|
+
return { fields, metadata };
|
|
103
|
+
}
|
|
104
|
+
function deduceMeshField(name, attribute, optionalMetadata) {
|
|
105
|
+
const type = getDataTypeFromTypedArray(attribute.value);
|
|
106
|
+
const metadata = optionalMetadata ? optionalMetadata : makeMeshAttributeMetadata(attribute);
|
|
107
|
+
return {
|
|
108
|
+
name,
|
|
109
|
+
type: { type: "fixed-size-list", listSize: attribute.size, children: [{ name: "value", type }] },
|
|
110
|
+
nullable: false,
|
|
111
|
+
metadata
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function deduceMeshFields(attributes) {
|
|
115
|
+
const fields = [];
|
|
116
|
+
for (const attributeName in attributes) {
|
|
117
|
+
const attribute = attributes[attributeName];
|
|
118
|
+
fields.push(deduceMeshField(attributeName, attribute));
|
|
119
|
+
}
|
|
120
|
+
return fields;
|
|
121
|
+
}
|
|
122
|
+
function makeMeshAttributeMetadata(attribute) {
|
|
123
|
+
const result = {};
|
|
124
|
+
if ("byteOffset" in attribute) {
|
|
125
|
+
result.byteOffset = attribute.byteOffset.toString(10);
|
|
126
|
+
}
|
|
127
|
+
if ("byteStride" in attribute) {
|
|
128
|
+
result.byteStride = attribute.byteStride.toString(10);
|
|
129
|
+
}
|
|
130
|
+
if ("normalized" in attribute) {
|
|
131
|
+
result.normalized = attribute.normalized.toString();
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
var init_deduce_mesh_schema = __esm({
|
|
136
|
+
"../schema/src/lib/mesh/deduce-mesh-schema.ts"() {
|
|
137
|
+
init_data_type();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// ../schema/src/index.ts
|
|
142
|
+
var init_src = __esm({
|
|
143
|
+
"../schema/src/index.ts"() {
|
|
144
|
+
init_mesh_utils();
|
|
145
|
+
init_deduce_mesh_schema();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// src/lib/get-ply-schema.ts
|
|
150
|
+
function getPLYSchema(plyHeader, attributes) {
|
|
151
|
+
const metadata = makeMetadataFromPlyHeader(plyHeader);
|
|
152
|
+
const schema = deduceMeshSchema(attributes, metadata);
|
|
153
|
+
return schema;
|
|
154
|
+
}
|
|
155
|
+
function makeMetadataFromPlyHeader(plyHeader) {
|
|
156
|
+
const metadata = {};
|
|
157
|
+
metadata.ply_comments = JSON.stringify(plyHeader.comments);
|
|
158
|
+
metadata.ply_elements = JSON.stringify(plyHeader.elements);
|
|
159
|
+
if (plyHeader.format !== void 0) {
|
|
160
|
+
metadata.ply_format = plyHeader.format;
|
|
161
|
+
}
|
|
162
|
+
if (plyHeader.version !== void 0) {
|
|
163
|
+
metadata.ply_version = plyHeader.version;
|
|
164
|
+
}
|
|
165
|
+
if (plyHeader.headerLength !== void 0) {
|
|
166
|
+
metadata.ply_headerLength = plyHeader.headerLength.toString(10);
|
|
167
|
+
}
|
|
168
|
+
return metadata;
|
|
169
|
+
}
|
|
170
|
+
var init_get_ply_schema = __esm({
|
|
171
|
+
"src/lib/get-ply-schema.ts"() {
|
|
172
|
+
init_src();
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// src/lib/normalize-ply.ts
|
|
177
|
+
function normalizePLY(plyHeader, plyAttributes, options) {
|
|
178
|
+
const attributes = getMeshAttributes(plyAttributes);
|
|
179
|
+
const boundingBox = getMeshBoundingBox(attributes);
|
|
180
|
+
const vertexCount = plyAttributes.indices.length || plyAttributes.vertices.length / 3;
|
|
181
|
+
const isTriangles = plyAttributes.indices && plyAttributes.indices.length > 0;
|
|
182
|
+
const mode = isTriangles ? 4 : 0;
|
|
183
|
+
const topology = isTriangles ? "triangle-list" : "point-list";
|
|
184
|
+
const schema = getPLYSchema(plyHeader, attributes);
|
|
185
|
+
const plyMesh = {
|
|
186
|
+
loader: "ply",
|
|
187
|
+
loaderData: plyHeader,
|
|
188
|
+
header: {
|
|
189
|
+
vertexCount,
|
|
190
|
+
boundingBox
|
|
191
|
+
},
|
|
192
|
+
schema,
|
|
193
|
+
attributes,
|
|
194
|
+
indices: { value: new Uint32Array(0), size: 0 },
|
|
195
|
+
mode,
|
|
196
|
+
topology
|
|
197
|
+
};
|
|
198
|
+
if (plyAttributes.indices.length > 0) {
|
|
199
|
+
plyMesh.indices = { value: new Uint32Array(plyAttributes.indices), size: 1 };
|
|
200
|
+
}
|
|
201
|
+
return plyMesh;
|
|
202
|
+
}
|
|
203
|
+
function getMeshAttributes(attributes) {
|
|
204
|
+
const accessors = {};
|
|
205
|
+
for (const attributeName of Object.keys(attributes)) {
|
|
206
|
+
switch (attributeName) {
|
|
207
|
+
case "vertices":
|
|
208
|
+
if (attributes.vertices.length > 0) {
|
|
209
|
+
accessors.POSITION = { value: new Float32Array(attributes.vertices), size: 3 };
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
case "normals":
|
|
213
|
+
if (attributes.normals.length > 0) {
|
|
214
|
+
accessors.NORMAL = { value: new Float32Array(attributes.normals), size: 3 };
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case "uvs":
|
|
218
|
+
if (attributes.uvs.length > 0) {
|
|
219
|
+
accessors.TEXCOORD_0 = { value: new Float32Array(attributes.uvs), size: 2 };
|
|
220
|
+
}
|
|
221
|
+
break;
|
|
222
|
+
case "colors":
|
|
223
|
+
if (attributes.colors.length > 0) {
|
|
224
|
+
accessors.COLOR_0 = { value: new Uint8Array(attributes.colors), size: 3, normalized: true };
|
|
225
|
+
}
|
|
226
|
+
break;
|
|
227
|
+
case "indices":
|
|
228
|
+
break;
|
|
229
|
+
default:
|
|
230
|
+
if (attributes[attributeName].length > 0) {
|
|
231
|
+
accessors[attributeName] = { value: new Float32Array(attributes[attributeName]), size: 1 };
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return accessors;
|
|
237
|
+
}
|
|
238
|
+
var init_normalize_ply = __esm({
|
|
239
|
+
"src/lib/normalize-ply.ts"() {
|
|
240
|
+
init_src();
|
|
241
|
+
init_get_ply_schema();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// src/lib/parse-ply.ts
|
|
246
|
+
function parsePLY(data, options = {}) {
|
|
247
|
+
let header;
|
|
248
|
+
let attributes;
|
|
249
|
+
if (data instanceof ArrayBuffer) {
|
|
250
|
+
const text = new TextDecoder().decode(data);
|
|
251
|
+
header = parseHeader(text, options);
|
|
252
|
+
attributes = header.format === "ascii" ? parseASCII(text, header) : parseBinary(data, header);
|
|
253
|
+
} else {
|
|
254
|
+
header = parseHeader(data, options);
|
|
255
|
+
attributes = parseASCII(data, header);
|
|
256
|
+
}
|
|
257
|
+
return normalizePLY(header, attributes);
|
|
258
|
+
}
|
|
259
|
+
function parseHeader(data, options) {
|
|
260
|
+
const PLY_HEADER_PATTERN = /ply([\s\S]*)end_header\s/;
|
|
261
|
+
let headerText = "";
|
|
262
|
+
let headerLength = 0;
|
|
263
|
+
const result = PLY_HEADER_PATTERN.exec(data);
|
|
264
|
+
if (result !== null) {
|
|
265
|
+
headerText = result[1];
|
|
266
|
+
headerLength = result[0].length;
|
|
267
|
+
}
|
|
268
|
+
const lines = headerText.split("\n");
|
|
269
|
+
const header = parseHeaderLines(lines, headerLength, options);
|
|
270
|
+
return header;
|
|
271
|
+
}
|
|
272
|
+
function parseHeaderLines(lines, headerLength, options) {
|
|
273
|
+
const header = {
|
|
274
|
+
comments: [],
|
|
275
|
+
elements: [],
|
|
276
|
+
headerLength
|
|
277
|
+
};
|
|
278
|
+
let lineType;
|
|
279
|
+
let lineValues;
|
|
280
|
+
let currentElement2 = null;
|
|
281
|
+
for (let i = 0; i < lines.length; i++) {
|
|
282
|
+
let line = lines[i];
|
|
283
|
+
line = line.trim();
|
|
284
|
+
if (line === "") {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
lineValues = line.split(/\s+/);
|
|
288
|
+
lineType = lineValues.shift();
|
|
289
|
+
line = lineValues.join(" ");
|
|
290
|
+
switch (lineType) {
|
|
291
|
+
case "format":
|
|
292
|
+
header.format = lineValues[0];
|
|
293
|
+
header.version = lineValues[1];
|
|
294
|
+
break;
|
|
295
|
+
case "comment":
|
|
296
|
+
header.comments.push(line);
|
|
297
|
+
break;
|
|
298
|
+
case "element":
|
|
299
|
+
if (currentElement2) {
|
|
300
|
+
header.elements.push(currentElement2);
|
|
301
|
+
}
|
|
302
|
+
currentElement2 = {
|
|
303
|
+
name: lineValues[0],
|
|
304
|
+
count: parseInt(lineValues[1], 10),
|
|
305
|
+
properties: []
|
|
306
|
+
};
|
|
307
|
+
break;
|
|
308
|
+
case "property":
|
|
309
|
+
if (currentElement2) {
|
|
310
|
+
const property = makePLYElementProperty(lineValues);
|
|
311
|
+
if (options?.propertyNameMapping && property.name in options?.propertyNameMapping) {
|
|
312
|
+
property.name = options?.propertyNameMapping[property.name];
|
|
313
|
+
}
|
|
314
|
+
currentElement2.properties.push(property);
|
|
315
|
+
}
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
console.log("unhandled", lineType, lineValues);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (currentElement2) {
|
|
322
|
+
header.elements.push(currentElement2);
|
|
323
|
+
}
|
|
324
|
+
return header;
|
|
325
|
+
}
|
|
326
|
+
function getPLYAttributes(header) {
|
|
327
|
+
const attributes = {
|
|
328
|
+
indices: [],
|
|
329
|
+
vertices: [],
|
|
330
|
+
normals: [],
|
|
331
|
+
uvs: [],
|
|
332
|
+
colors: []
|
|
333
|
+
};
|
|
334
|
+
for (const element of header.elements) {
|
|
335
|
+
if (element.name === "vertex") {
|
|
336
|
+
for (const property of element.properties) {
|
|
337
|
+
switch (property.name) {
|
|
338
|
+
case "x":
|
|
339
|
+
case "y":
|
|
340
|
+
case "z":
|
|
341
|
+
case "nx":
|
|
342
|
+
case "ny":
|
|
343
|
+
case "nz":
|
|
344
|
+
case "s":
|
|
345
|
+
case "t":
|
|
346
|
+
case "red":
|
|
347
|
+
case "green":
|
|
348
|
+
case "blue":
|
|
349
|
+
break;
|
|
350
|
+
default:
|
|
351
|
+
attributes[property.name] = [];
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return attributes;
|
|
358
|
+
}
|
|
359
|
+
function makePLYElementProperty(propertyValues) {
|
|
360
|
+
const type = propertyValues[0];
|
|
361
|
+
switch (type) {
|
|
362
|
+
case "list":
|
|
363
|
+
return {
|
|
364
|
+
type,
|
|
365
|
+
name: propertyValues[3],
|
|
366
|
+
countType: propertyValues[1],
|
|
367
|
+
itemType: propertyValues[2]
|
|
368
|
+
};
|
|
369
|
+
default:
|
|
370
|
+
return {
|
|
371
|
+
type,
|
|
372
|
+
name: propertyValues[1]
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function parseASCIINumber(n, type) {
|
|
377
|
+
switch (type) {
|
|
378
|
+
case "char":
|
|
379
|
+
case "uchar":
|
|
380
|
+
case "short":
|
|
381
|
+
case "ushort":
|
|
382
|
+
case "int":
|
|
383
|
+
case "uint":
|
|
384
|
+
case "int8":
|
|
385
|
+
case "uint8":
|
|
386
|
+
case "int16":
|
|
387
|
+
case "uint16":
|
|
388
|
+
case "int32":
|
|
389
|
+
case "uint32":
|
|
390
|
+
return parseInt(n, 10);
|
|
391
|
+
case "float":
|
|
392
|
+
case "double":
|
|
393
|
+
case "float32":
|
|
394
|
+
case "float64":
|
|
395
|
+
return parseFloat(n);
|
|
396
|
+
default:
|
|
397
|
+
throw new Error(type);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
function parsePLYElement(properties, line) {
|
|
401
|
+
const values = line.split(/\s+/);
|
|
402
|
+
const element = {};
|
|
403
|
+
for (let i = 0; i < properties.length; i++) {
|
|
404
|
+
if (properties[i].type === "list") {
|
|
405
|
+
const list = [];
|
|
406
|
+
const n = parseASCIINumber(values.shift(), properties[i].countType);
|
|
407
|
+
for (let j = 0; j < n; j++) {
|
|
408
|
+
list.push(parseASCIINumber(values.shift(), properties[i].itemType));
|
|
409
|
+
}
|
|
410
|
+
element[properties[i].name] = list;
|
|
411
|
+
} else {
|
|
412
|
+
element[properties[i].name] = parseASCIINumber(values.shift(), properties[i].type);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return element;
|
|
416
|
+
}
|
|
417
|
+
function parseASCII(data, header) {
|
|
418
|
+
const attributes = getPLYAttributes(header);
|
|
419
|
+
let result;
|
|
420
|
+
const patternBody = /end_header\s([\s\S]*)$/;
|
|
421
|
+
let body = "";
|
|
422
|
+
if ((result = patternBody.exec(data)) !== null) {
|
|
423
|
+
body = result[1];
|
|
424
|
+
}
|
|
425
|
+
const lines = body.split("\n");
|
|
426
|
+
let currentElement2 = 0;
|
|
427
|
+
let currentElementCount = 0;
|
|
428
|
+
for (let i = 0; i < lines.length; i++) {
|
|
429
|
+
let line = lines[i];
|
|
430
|
+
line = line.trim();
|
|
431
|
+
if (line !== "") {
|
|
432
|
+
if (currentElementCount >= header.elements[currentElement2].count) {
|
|
433
|
+
currentElement2++;
|
|
434
|
+
currentElementCount = 0;
|
|
435
|
+
}
|
|
436
|
+
const element = parsePLYElement(header.elements[currentElement2].properties, line);
|
|
437
|
+
handleElement(attributes, header.elements[currentElement2].name, element);
|
|
438
|
+
currentElementCount++;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return attributes;
|
|
442
|
+
}
|
|
443
|
+
function handleElement(buffer, elementName, element = {}) {
|
|
444
|
+
if (elementName === "vertex") {
|
|
445
|
+
for (const propertyName of Object.keys(element)) {
|
|
446
|
+
switch (propertyName) {
|
|
447
|
+
case "x":
|
|
448
|
+
buffer.vertices.push(element.x, element.y, element.z);
|
|
449
|
+
break;
|
|
450
|
+
case "y":
|
|
451
|
+
case "z":
|
|
452
|
+
break;
|
|
453
|
+
case "nx":
|
|
454
|
+
if ("nx" in element && "ny" in element && "nz" in element) {
|
|
455
|
+
buffer.normals.push(element.nx, element.ny, element.nz);
|
|
456
|
+
}
|
|
457
|
+
break;
|
|
458
|
+
case "ny":
|
|
459
|
+
case "nz":
|
|
460
|
+
break;
|
|
461
|
+
case "s":
|
|
462
|
+
if ("s" in element && "t" in element) {
|
|
463
|
+
buffer.uvs.push(element.s, element.t);
|
|
464
|
+
}
|
|
465
|
+
break;
|
|
466
|
+
case "t":
|
|
467
|
+
break;
|
|
468
|
+
case "red":
|
|
469
|
+
if ("red" in element && "green" in element && "blue" in element) {
|
|
470
|
+
buffer.colors.push(element.red, element.green, element.blue);
|
|
471
|
+
}
|
|
472
|
+
break;
|
|
473
|
+
case "green":
|
|
474
|
+
case "blue":
|
|
475
|
+
break;
|
|
476
|
+
default:
|
|
477
|
+
buffer[propertyName].push(element[propertyName]);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
} else if (elementName === "face") {
|
|
481
|
+
const vertexIndices = element.vertex_indices || element.vertex_index;
|
|
482
|
+
if (vertexIndices.length === 3) {
|
|
483
|
+
buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[2]);
|
|
484
|
+
} else if (vertexIndices.length === 4) {
|
|
485
|
+
buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[3]);
|
|
486
|
+
buffer.indices.push(vertexIndices[1], vertexIndices[2], vertexIndices[3]);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
function binaryRead(dataview, at, type, littleEndian) {
|
|
491
|
+
switch (type) {
|
|
492
|
+
case "int8":
|
|
493
|
+
case "char":
|
|
494
|
+
return [dataview.getInt8(at), 1];
|
|
495
|
+
case "uint8":
|
|
496
|
+
case "uchar":
|
|
497
|
+
return [dataview.getUint8(at), 1];
|
|
498
|
+
case "int16":
|
|
499
|
+
case "short":
|
|
500
|
+
return [dataview.getInt16(at, littleEndian), 2];
|
|
501
|
+
case "uint16":
|
|
502
|
+
case "ushort":
|
|
503
|
+
return [dataview.getUint16(at, littleEndian), 2];
|
|
504
|
+
case "int32":
|
|
505
|
+
case "int":
|
|
506
|
+
return [dataview.getInt32(at, littleEndian), 4];
|
|
507
|
+
case "uint32":
|
|
508
|
+
case "uint":
|
|
509
|
+
return [dataview.getUint32(at, littleEndian), 4];
|
|
510
|
+
case "float32":
|
|
511
|
+
case "float":
|
|
512
|
+
return [dataview.getFloat32(at, littleEndian), 4];
|
|
513
|
+
case "float64":
|
|
514
|
+
case "double":
|
|
515
|
+
return [dataview.getFloat64(at, littleEndian), 8];
|
|
516
|
+
default:
|
|
517
|
+
throw new Error(type);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function binaryReadElement(dataview, at, properties, littleEndian) {
|
|
521
|
+
const element = {};
|
|
522
|
+
let result;
|
|
523
|
+
let read = 0;
|
|
524
|
+
for (let i = 0; i < properties.length; i++) {
|
|
525
|
+
if (properties[i].type === "list") {
|
|
526
|
+
const list = [];
|
|
527
|
+
result = binaryRead(dataview, at + read, properties[i].countType, littleEndian);
|
|
528
|
+
const n = result[0];
|
|
529
|
+
read += result[1];
|
|
530
|
+
for (let j = 0; j < n; j++) {
|
|
531
|
+
result = binaryRead(dataview, at + read, properties[i].itemType, littleEndian);
|
|
532
|
+
list.push(result[0]);
|
|
533
|
+
read += result[1];
|
|
534
|
+
}
|
|
535
|
+
element[properties[i].name] = list;
|
|
536
|
+
} else {
|
|
537
|
+
result = binaryRead(dataview, at + read, properties[i].type, littleEndian);
|
|
538
|
+
element[properties[i].name] = result[0];
|
|
539
|
+
read += result[1];
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return [element, read];
|
|
543
|
+
}
|
|
544
|
+
function parseBinary(data, header) {
|
|
545
|
+
const attributes = getPLYAttributes(header);
|
|
546
|
+
const littleEndian = header.format === "binary_little_endian";
|
|
547
|
+
const body = new DataView(data, header.headerLength);
|
|
548
|
+
let result;
|
|
549
|
+
let loc = 0;
|
|
550
|
+
for (let currentElement2 = 0; currentElement2 < header.elements.length; currentElement2++) {
|
|
551
|
+
const count = header.elements[currentElement2].count;
|
|
552
|
+
for (let currentElementCount = 0; currentElementCount < count; currentElementCount++) {
|
|
553
|
+
result = binaryReadElement(body, loc, header.elements[currentElement2].properties, littleEndian);
|
|
554
|
+
loc += result[1];
|
|
555
|
+
const element = result[0];
|
|
556
|
+
handleElement(attributes, header.elements[currentElement2].name, element);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return attributes;
|
|
560
|
+
}
|
|
561
|
+
var init_parse_ply = __esm({
|
|
562
|
+
"src/lib/parse-ply.ts"() {
|
|
563
|
+
init_normalize_ply();
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// ../loader-utils/src/lib/iterators/text-iterators.ts
|
|
568
|
+
async function* makeTextDecoderIterator(arrayBufferIterator, options = {}) {
|
|
569
|
+
const textDecoder = new TextDecoder(void 0, options);
|
|
570
|
+
for await (const arrayBuffer of arrayBufferIterator) {
|
|
571
|
+
yield typeof arrayBuffer === "string" ? arrayBuffer : textDecoder.decode(arrayBuffer, { stream: true });
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
async function* makeLineIterator(textIterator) {
|
|
575
|
+
let previous = "";
|
|
576
|
+
for await (const textChunk of textIterator) {
|
|
577
|
+
previous += textChunk;
|
|
578
|
+
let eolIndex;
|
|
579
|
+
while ((eolIndex = previous.indexOf("\n")) >= 0) {
|
|
580
|
+
const line = previous.slice(0, eolIndex + 1);
|
|
581
|
+
previous = previous.slice(eolIndex + 1);
|
|
582
|
+
yield line;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (previous.length > 0) {
|
|
586
|
+
yield previous;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
var init_text_iterators = __esm({
|
|
590
|
+
"../loader-utils/src/lib/iterators/text-iterators.ts"() {
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
// ../loader-utils/src/lib/iterators/async-iteration.ts
|
|
595
|
+
async function forEach(iterator, visitor) {
|
|
596
|
+
while (true) {
|
|
597
|
+
const { done, value } = await iterator.next();
|
|
598
|
+
if (done) {
|
|
599
|
+
iterator.return();
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const cancel = visitor(value);
|
|
603
|
+
if (cancel) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
var init_async_iteration = __esm({
|
|
609
|
+
"../loader-utils/src/lib/iterators/async-iteration.ts"() {
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
// ../loader-utils/src/index.ts
|
|
614
|
+
var init_src2 = __esm({
|
|
615
|
+
"../loader-utils/src/index.ts"() {
|
|
616
|
+
init_text_iterators();
|
|
617
|
+
init_async_iteration();
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
// src/lib/parse-ply-in-batches.ts
|
|
622
|
+
async function* parsePLYInBatches(iterator, options) {
|
|
623
|
+
const lineIterator = makeLineIterator(makeTextDecoderIterator(iterator));
|
|
624
|
+
const header = await parsePLYHeader(lineIterator, options);
|
|
625
|
+
let attributes;
|
|
626
|
+
switch (header.format) {
|
|
627
|
+
case "ascii":
|
|
628
|
+
attributes = await parseASCII2(lineIterator, header);
|
|
629
|
+
break;
|
|
630
|
+
default:
|
|
631
|
+
throw new Error("Binary PLY can not yet be parsed in streaming mode");
|
|
632
|
+
}
|
|
633
|
+
yield normalizePLY(header, attributes, options);
|
|
634
|
+
}
|
|
635
|
+
async function parsePLYHeader(lineIterator, options) {
|
|
636
|
+
const header = {
|
|
637
|
+
comments: [],
|
|
638
|
+
elements: []
|
|
639
|
+
};
|
|
640
|
+
await forEach(lineIterator, (line) => {
|
|
641
|
+
line = line.trim();
|
|
642
|
+
if (line === "end_header") {
|
|
643
|
+
return true;
|
|
644
|
+
}
|
|
645
|
+
if (line === "") {
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
const lineValues = line.split(/\s+/);
|
|
649
|
+
const lineType = lineValues.shift();
|
|
650
|
+
line = lineValues.join(" ");
|
|
651
|
+
switch (lineType) {
|
|
652
|
+
case "ply":
|
|
653
|
+
break;
|
|
654
|
+
case "format":
|
|
655
|
+
header.format = lineValues[0];
|
|
656
|
+
header.version = lineValues[1];
|
|
657
|
+
break;
|
|
658
|
+
case "comment":
|
|
659
|
+
header.comments.push(line);
|
|
660
|
+
break;
|
|
661
|
+
case "element":
|
|
662
|
+
if (currentElement) {
|
|
663
|
+
header.elements.push(currentElement);
|
|
664
|
+
}
|
|
665
|
+
currentElement = {
|
|
666
|
+
name: lineValues[0],
|
|
667
|
+
count: parseInt(lineValues[1], 10),
|
|
668
|
+
properties: []
|
|
669
|
+
};
|
|
670
|
+
break;
|
|
671
|
+
case "property":
|
|
672
|
+
const property = makePLYElementProperty2(lineValues, options.propertyNameMapping);
|
|
673
|
+
currentElement.properties.push(property);
|
|
674
|
+
break;
|
|
675
|
+
default:
|
|
676
|
+
console.log("unhandled", lineType, lineValues);
|
|
677
|
+
}
|
|
678
|
+
return false;
|
|
679
|
+
});
|
|
680
|
+
if (currentElement) {
|
|
681
|
+
header.elements.push(currentElement);
|
|
682
|
+
}
|
|
683
|
+
return header;
|
|
684
|
+
}
|
|
685
|
+
function makePLYElementProperty2(propertyValues, propertyNameMapping) {
|
|
686
|
+
const type = propertyValues[0];
|
|
687
|
+
switch (type) {
|
|
688
|
+
case "list":
|
|
689
|
+
return {
|
|
690
|
+
type,
|
|
691
|
+
name: propertyValues[3],
|
|
692
|
+
countType: propertyValues[1],
|
|
693
|
+
itemType: propertyValues[2]
|
|
694
|
+
};
|
|
695
|
+
default:
|
|
696
|
+
return {
|
|
697
|
+
type,
|
|
698
|
+
name: propertyValues[1]
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
async function parseASCII2(lineIterator, header) {
|
|
703
|
+
const attributes = {
|
|
704
|
+
indices: [],
|
|
705
|
+
vertices: [],
|
|
706
|
+
normals: [],
|
|
707
|
+
uvs: [],
|
|
708
|
+
colors: []
|
|
709
|
+
};
|
|
710
|
+
let currentElement2 = 0;
|
|
711
|
+
let currentElementCount = 0;
|
|
712
|
+
for await (let line of lineIterator) {
|
|
713
|
+
line = line.trim();
|
|
714
|
+
if (line !== "") {
|
|
715
|
+
if (currentElementCount >= header.elements[currentElement2].count) {
|
|
716
|
+
currentElement2++;
|
|
717
|
+
currentElementCount = 0;
|
|
718
|
+
}
|
|
719
|
+
const element = parsePLYElement2(header.elements[currentElement2].properties, line);
|
|
720
|
+
handleElement2(attributes, header.elements[currentElement2].name, element);
|
|
721
|
+
currentElementCount++;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return attributes;
|
|
725
|
+
}
|
|
726
|
+
function parseASCIINumber2(n, type) {
|
|
727
|
+
switch (type) {
|
|
728
|
+
case "char":
|
|
729
|
+
case "uchar":
|
|
730
|
+
case "short":
|
|
731
|
+
case "ushort":
|
|
732
|
+
case "int":
|
|
733
|
+
case "uint":
|
|
734
|
+
case "int8":
|
|
735
|
+
case "uint8":
|
|
736
|
+
case "int16":
|
|
737
|
+
case "uint16":
|
|
738
|
+
case "int32":
|
|
739
|
+
case "uint32":
|
|
740
|
+
return parseInt(n, 10);
|
|
741
|
+
case "float":
|
|
742
|
+
case "double":
|
|
743
|
+
case "float32":
|
|
744
|
+
case "float64":
|
|
745
|
+
return parseFloat(n);
|
|
746
|
+
default:
|
|
747
|
+
throw new Error(type);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
function parsePLYElement2(properties, line) {
|
|
751
|
+
const values = line.split(/\s+/);
|
|
752
|
+
const element = {};
|
|
753
|
+
for (let i = 0; i < properties.length; i++) {
|
|
754
|
+
if (properties[i].type === "list") {
|
|
755
|
+
const list = [];
|
|
756
|
+
const n = parseASCIINumber2(values.shift(), properties[i].countType);
|
|
757
|
+
for (let j = 0; j < n; j++) {
|
|
758
|
+
list.push(parseASCIINumber2(values.shift(), properties[i].itemType));
|
|
759
|
+
}
|
|
760
|
+
element[properties[i].name] = list;
|
|
761
|
+
} else {
|
|
762
|
+
element[properties[i].name] = parseASCIINumber2(values.shift(), properties[i].type);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
return element;
|
|
766
|
+
}
|
|
767
|
+
function handleElement2(buffer, elementName, element = {}) {
|
|
768
|
+
switch (elementName) {
|
|
769
|
+
case "vertex":
|
|
770
|
+
buffer.vertices.push(element.x, element.y, element.z);
|
|
771
|
+
if ("nx" in element && "ny" in element && "nz" in element) {
|
|
772
|
+
buffer.normals.push(element.nx, element.ny, element.nz);
|
|
773
|
+
}
|
|
774
|
+
if ("s" in element && "t" in element) {
|
|
775
|
+
buffer.uvs.push(element.s, element.t);
|
|
776
|
+
}
|
|
777
|
+
if ("red" in element && "green" in element && "blue" in element) {
|
|
778
|
+
buffer.colors.push(element.red / 255, element.green / 255, element.blue / 255);
|
|
779
|
+
}
|
|
780
|
+
break;
|
|
781
|
+
case "face":
|
|
782
|
+
const vertexIndices = element.vertex_indices || element.vertex_index;
|
|
783
|
+
if (vertexIndices.length === 3) {
|
|
784
|
+
buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[2]);
|
|
785
|
+
} else if (vertexIndices.length === 4) {
|
|
786
|
+
buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[3]);
|
|
787
|
+
buffer.indices.push(vertexIndices[1], vertexIndices[2], vertexIndices[3]);
|
|
788
|
+
}
|
|
789
|
+
break;
|
|
790
|
+
default:
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
var currentElement;
|
|
795
|
+
var init_parse_ply_in_batches = __esm({
|
|
796
|
+
"src/lib/parse-ply-in-batches.ts"() {
|
|
797
|
+
init_src2();
|
|
798
|
+
init_normalize_ply();
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
// src/index.ts
|
|
803
|
+
var src_exports = {};
|
|
804
|
+
__export(src_exports, {
|
|
805
|
+
PLYLoader: () => PLYLoader2,
|
|
806
|
+
PLYWorkerLoader: () => PLYLoader
|
|
807
|
+
});
|
|
808
|
+
var PLYLoader2;
|
|
809
|
+
var init_src3 = __esm({
|
|
810
|
+
"src/index.ts"() {
|
|
811
|
+
init_ply_loader();
|
|
812
|
+
init_parse_ply();
|
|
813
|
+
init_parse_ply_in_batches();
|
|
814
|
+
PLYLoader2 = {
|
|
815
|
+
...PLYLoader,
|
|
816
|
+
parse: async (arrayBuffer, options) => parsePLY(arrayBuffer, options?.ply),
|
|
817
|
+
parseTextSync: (arrayBuffer, options) => parsePLY(arrayBuffer, options?.ply),
|
|
818
|
+
parseSync: (arrayBuffer, options) => parsePLY(arrayBuffer, options?.ply),
|
|
819
|
+
parseInBatches: (arrayBuffer, options) => parsePLYInBatches(arrayBuffer, options?.ply)
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
// src/bundle.ts
|
|
825
|
+
var require_bundle = __commonJS({
|
|
826
|
+
"src/bundle.ts"(exports, module) {
|
|
827
|
+
var moduleExports = (init_src3(), src_exports);
|
|
828
|
+
globalThis.loaders = globalThis.loaders || {};
|
|
829
|
+
module.exports = Object.assign(globalThis.loaders, moduleExports);
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
require_bundle();
|
|
833
|
+
})();
|