@loaders.gl/ply 4.0.0-alpha.5 → 4.0.0-alpha.7
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.js +2 -2
- package/dist/dist.min.js +201 -609
- 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 +7 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -11
- package/dist/lib/get-ply-schema.js +34 -24
- package/dist/lib/normalize-ply.js +76 -65
- 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 +237 -202
- 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 +378 -299
- package/dist/lib/ply-types.d.ts +22 -14
- package/dist/lib/ply-types.d.ts.map +1 -1
- package/dist/lib/ply-types.js +2 -2
- package/dist/ply-loader.d.ts +3 -17
- package/dist/ply-loader.d.ts.map +1 -1
- package/dist/ply-loader.js +27 -18
- package/dist/ply-worker.js +240 -578
- package/dist/workers/ply-worker.js +5 -4
- package/package.json +6 -6
- 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 +20 -22
- 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
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const loader_utils_1 = require("@loaders.gl/loader-utils");
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
(0, loader_utils_1.createLoaderWorker)(index_1.PLYLoader);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/ply",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.7",
|
|
4
4
|
"description": "Framework-independent loader for the PLY format",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"PLY"
|
|
20
20
|
],
|
|
21
21
|
"types": "dist/index.d.ts",
|
|
22
|
-
"main": "dist/index.js",
|
|
23
|
-
"module": "dist/index.js",
|
|
22
|
+
"main": "dist/es5/index.js",
|
|
23
|
+
"module": "dist/esm/index.js",
|
|
24
24
|
"sideEffects": false,
|
|
25
25
|
"files": [
|
|
26
26
|
"src",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@babel/runtime": "^7.3.1",
|
|
37
|
-
"@loaders.gl/loader-utils": "4.0.0-alpha.
|
|
38
|
-
"@loaders.gl/schema": "4.0.0-alpha.
|
|
37
|
+
"@loaders.gl/loader-utils": "4.0.0-alpha.7",
|
|
38
|
+
"@loaders.gl/schema": "4.0.0-alpha.7"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "afb59c4d8e5d8ebb9c28f111cb0c96c5527d0ffd"
|
|
41
41
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
// loaders.gl, MIT license
|
|
2
|
+
|
|
3
|
+
import type {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
4
|
+
import type {PLYMesh} from './lib/ply-types';
|
|
2
5
|
import {PLYLoader as PLYWorkerLoader} from './ply-loader';
|
|
3
|
-
import parsePLY from './lib/parse-ply';
|
|
4
|
-
import parsePLYInBatches from './lib/parse-ply-in-batches';
|
|
6
|
+
import {ParsePLYOptions, parsePLY} from './lib/parse-ply';
|
|
7
|
+
import {parsePLYInBatches} from './lib/parse-ply-in-batches';
|
|
5
8
|
|
|
6
9
|
// PLYLoader
|
|
7
10
|
|
|
8
11
|
export {PLYWorkerLoader};
|
|
9
12
|
|
|
13
|
+
export type PLYLoaderOptions = LoaderOptions & {
|
|
14
|
+
ply?: ParsePLYOptions;
|
|
15
|
+
};
|
|
16
|
+
|
|
10
17
|
/**
|
|
11
18
|
* Loader for PLY - Polygon File Format
|
|
12
19
|
*/
|
|
13
|
-
export const PLYLoader = {
|
|
20
|
+
export const PLYLoader: LoaderWithParser<PLYMesh, any, PLYLoaderOptions> = {
|
|
14
21
|
...PLYWorkerLoader,
|
|
15
22
|
// Note: parsePLY supports both text and binary
|
|
16
|
-
parse: async (arrayBuffer, options) => parsePLY(arrayBuffer, options), // TODO - this may not detect text correctly?
|
|
17
|
-
parseTextSync: parsePLY,
|
|
18
|
-
parseSync: parsePLY,
|
|
19
|
-
parseInBatches: parsePLYInBatches
|
|
23
|
+
parse: async (arrayBuffer, options) => parsePLY(arrayBuffer, options?.ply), // TODO - this may not detect text correctly?
|
|
24
|
+
parseTextSync: (arrayBuffer, options) => parsePLY(arrayBuffer, options?.ply),
|
|
25
|
+
parseSync: (arrayBuffer, options) => parsePLY(arrayBuffer, options?.ply),
|
|
26
|
+
parseInBatches: (arrayBuffer, options) => parsePLYInBatches(arrayBuffer, options?.ply)
|
|
20
27
|
};
|
|
21
|
-
|
|
22
|
-
export const _typecheckPLYLoader: LoaderWithParser = PLYLoader;
|
|
@@ -8,8 +8,8 @@ import type {PLYHeader} from './ply-types';
|
|
|
8
8
|
* @returns Schema
|
|
9
9
|
*/
|
|
10
10
|
export function getPLYSchema(plyHeader: PLYHeader, attributes: MeshAttributes): Schema {
|
|
11
|
-
const
|
|
12
|
-
const schema = deduceMeshSchema(attributes,
|
|
11
|
+
const metadata = makeMetadataFromPlyHeader(plyHeader);
|
|
12
|
+
const schema = deduceMeshSchema(attributes, metadata);
|
|
13
13
|
return schema;
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -18,18 +18,19 @@ export function getPLYSchema(plyHeader: PLYHeader, attributes: MeshAttributes):
|
|
|
18
18
|
* @param plyHeader
|
|
19
19
|
* @returns
|
|
20
20
|
*/
|
|
21
|
-
function makeMetadataFromPlyHeader(plyHeader: PLYHeader):
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
function makeMetadataFromPlyHeader(plyHeader: PLYHeader): Record<string, string> {
|
|
22
|
+
/* eslint-disable camelcase */
|
|
23
|
+
const metadata: Record<string, string> = {};
|
|
24
|
+
metadata.ply_comments = JSON.stringify(plyHeader.comments);
|
|
25
|
+
metadata.ply_elements = JSON.stringify(plyHeader.elements);
|
|
25
26
|
if (plyHeader.format !== undefined) {
|
|
26
|
-
|
|
27
|
+
metadata.ply_format = plyHeader.format;
|
|
27
28
|
}
|
|
28
29
|
if (plyHeader.version !== undefined) {
|
|
29
|
-
|
|
30
|
+
metadata.ply_version = plyHeader.version;
|
|
30
31
|
}
|
|
31
32
|
if (plyHeader.headerLength !== undefined) {
|
|
32
|
-
|
|
33
|
+
metadata.ply_headerLength = plyHeader.headerLength.toString(10);
|
|
33
34
|
}
|
|
34
|
-
return
|
|
35
|
+
return metadata;
|
|
35
36
|
}
|
package/src/lib/normalize-ply.ts
CHANGED
|
@@ -50,25 +50,47 @@ export default function normalizePLY(
|
|
|
50
50
|
* @param attributes
|
|
51
51
|
* @returns accessors []
|
|
52
52
|
*/
|
|
53
|
+
// eslint-disable-next-line complexity
|
|
53
54
|
function getMeshAttributes(attributes: PLYAttributes): MeshAttributes {
|
|
54
55
|
const accessors: MeshAttributes = {};
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
for (const attributeName of Object.keys(attributes)) {
|
|
58
|
+
switch (attributeName) {
|
|
59
|
+
case 'vertices':
|
|
60
|
+
if (attributes.vertices.length > 0) {
|
|
61
|
+
accessors.POSITION = {value: new Float32Array(attributes.vertices), size: 3};
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
57
64
|
|
|
58
|
-
|
|
65
|
+
// optional attributes data
|
|
66
|
+
case 'normals':
|
|
67
|
+
if (attributes.normals.length > 0) {
|
|
68
|
+
accessors.NORMAL = {value: new Float32Array(attributes.normals), size: 3};
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
case 'uvs':
|
|
73
|
+
if (attributes.uvs.length > 0) {
|
|
74
|
+
accessors.TEXCOORD_0 = {value: new Float32Array(attributes.uvs), size: 2};
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
63
77
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
case 'colors':
|
|
79
|
+
if (attributes.colors.length > 0) {
|
|
80
|
+
// TODO - normalized shoud be based on `uchar` flag in source data?
|
|
81
|
+
accessors.COLOR_0 = {value: new Uint8Array(attributes.colors), size: 3, normalized: true};
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
67
84
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
accessors.COLOR_0 = {value: new Uint8Array(attributes.colors), size: 3, normalized: true};
|
|
71
|
-
}
|
|
85
|
+
case 'indices':
|
|
86
|
+
break;
|
|
72
87
|
|
|
88
|
+
default:
|
|
89
|
+
if (attributes[attributeName].length > 0) {
|
|
90
|
+
accessors[attributeName] = {value: new Float32Array(attributes[attributeName]), size: 1};
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
73
95
|
return accessors;
|
|
74
96
|
}
|
|
@@ -23,16 +23,16 @@
|
|
|
23
23
|
|
|
24
24
|
import {makeLineIterator, makeTextDecoderIterator, forEach} from '@loaders.gl/loader-utils';
|
|
25
25
|
import normalizePLY from './normalize-ply';
|
|
26
|
-
import {PLYMesh, PLYHeader,
|
|
26
|
+
import {PLYMesh, PLYHeader, PLYElement, PLYProperty, PLYAttributes} from './ply-types';
|
|
27
27
|
|
|
28
|
-
let currentElement:
|
|
28
|
+
let currentElement: PLYElement;
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* PARSER
|
|
32
32
|
* @param iterator
|
|
33
33
|
* @param options
|
|
34
34
|
*/
|
|
35
|
-
export
|
|
35
|
+
export async function* parsePLYInBatches(
|
|
36
36
|
iterator: AsyncIterable<ArrayBuffer> | Iterable<ArrayBuffer>,
|
|
37
37
|
options: any
|
|
38
38
|
): AsyncIterable<PLYMesh> {
|
|
@@ -134,24 +134,22 @@ async function parsePLYHeader(
|
|
|
134
134
|
return header;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
function makePLYElementProperty(
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
137
|
+
function makePLYElementProperty(propertyValues: string[], propertyNameMapping: []): PLYProperty {
|
|
138
|
+
const type = propertyValues[0];
|
|
139
|
+
switch (type) {
|
|
140
|
+
case 'list':
|
|
141
|
+
return {
|
|
142
|
+
type,
|
|
143
|
+
name: propertyValues[3],
|
|
144
|
+
countType: propertyValues[1],
|
|
145
|
+
itemType: propertyValues[2]
|
|
146
|
+
};
|
|
147
|
+
default:
|
|
148
|
+
return {
|
|
149
|
+
type,
|
|
150
|
+
name: propertyValues[1]
|
|
151
|
+
};
|
|
152
152
|
}
|
|
153
|
-
|
|
154
|
-
return property;
|
|
155
153
|
}
|
|
156
154
|
|
|
157
155
|
// ASCII PARSING
|
|
@@ -182,7 +180,7 @@ async function parseASCII(lineIterator: AsyncIterable<string>, header: PLYHeader
|
|
|
182
180
|
currentElementCount = 0;
|
|
183
181
|
}
|
|
184
182
|
|
|
185
|
-
const element =
|
|
183
|
+
const element = parsePLYElement(header.elements[currentElement].properties, line);
|
|
186
184
|
handleElement(attributes, header.elements[currentElement].name, element);
|
|
187
185
|
currentElementCount++;
|
|
188
186
|
}
|
|
@@ -229,7 +227,7 @@ function parseASCIINumber(n: string, type: string): number {
|
|
|
229
227
|
* @param line
|
|
230
228
|
* @returns element
|
|
231
229
|
*/
|
|
232
|
-
function
|
|
230
|
+
function parsePLYElement(properties: any[], line: string) {
|
|
233
231
|
const values: any = line.split(/\s+/);
|
|
234
232
|
|
|
235
233
|
const element = {};
|
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
|
};
|
package/src/ply-loader.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// PLY Loader
|
|
2
|
-
import type {Loader} from '@loaders.gl/loader-utils';
|
|
2
|
+
import type {Loader, LoaderOptions} from '@loaders.gl/loader-utils';
|
|
3
|
+
import {PLYMesh} from './lib/ply-types';
|
|
3
4
|
|
|
4
5
|
// __VERSION__ is injected by babel-plugin-version-inline
|
|
5
6
|
// @ts-ignore TS2304: Cannot find name '__VERSION__'.
|
|
@@ -10,11 +11,11 @@ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
|
|
|
10
11
|
* links: ['http://paulbourke.net/dataformats/ply/',
|
|
11
12
|
* 'https://en.wikipedia.org/wiki/PLY_(file_format)']
|
|
12
13
|
*/
|
|
13
|
-
export const PLYLoader = {
|
|
14
|
+
export const PLYLoader: Loader<PLYMesh, never, LoaderOptions> = {
|
|
14
15
|
name: 'PLY',
|
|
15
16
|
id: 'ply',
|
|
16
17
|
module: 'ply',
|
|
17
|
-
shapes: ['mesh', 'gltf', 'columnar-table'],
|
|
18
|
+
// shapes: ['mesh', 'gltf', 'columnar-table'],
|
|
18
19
|
version: VERSION,
|
|
19
20
|
worker: true,
|
|
20
21
|
extensions: ['ply'],
|
package/dist/bundle.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bundle.ts"],"names":["moduleExports","require","globalThis","loaders","module","exports","Object","assign"],"mappings":"AACA,MAAMA,aAAa,GAAGC,OAAO,CAAC,SAAD,CAA7B;;AACAC,UAAU,CAACC,OAAX,GAAqBD,UAAU,CAACC,OAAX,IAAsB,EAA3C;AACAC,MAAM,CAACC,OAAP,GAAiBC,MAAM,CAACC,MAAP,CAAcL,UAAU,CAACC,OAAzB,EAAkCH,aAAlC,CAAjB","sourcesContent":["// @ts-nocheck\nconst moduleExports = require('./index');\nglobalThis.loaders = globalThis.loaders || {};\nmodule.exports = Object.assign(globalThis.loaders, moduleExports);\n"],"file":"bundle.js"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["PLYLoader","PLYWorkerLoader","parsePLY","parsePLYInBatches","parse","arrayBuffer","options","parseTextSync","parseSync","parseInBatches","_typecheckPLYLoader"],"mappings":"AACA,SAAQA,SAAS,IAAIC,eAArB,QAA2C,cAA3C;AACA,OAAOC,QAAP,MAAqB,iBAArB;AACA,OAAOC,iBAAP,MAA8B,4BAA9B;AAIA,SAAQF,eAAR;AAKA,OAAO,MAAMD,SAAS,GAAG,EACvB,GAAGC,eADoB;AAGvBG,EAAAA,KAAK,EAAE,OAAOC,WAAP,EAAoBC,OAApB,KAAgCJ,QAAQ,CAACG,WAAD,EAAcC,OAAd,CAHxB;AAIvBC,EAAAA,aAAa,EAAEL,QAJQ;AAKvBM,EAAAA,SAAS,EAAEN,QALY;AAMvBO,EAAAA,cAAc,EAAEN;AANO,CAAlB;AASP,OAAO,MAAMO,mBAAqC,GAAGV,SAA9C","sourcesContent":["import type {LoaderWithParser} from '@loaders.gl/loader-utils';\nimport {PLYLoader as PLYWorkerLoader} from './ply-loader';\nimport parsePLY from './lib/parse-ply';\nimport parsePLYInBatches from './lib/parse-ply-in-batches';\n\n// PLYLoader\n\nexport {PLYWorkerLoader};\n\n/**\n * Loader for PLY - Polygon File Format\n */\nexport const PLYLoader = {\n ...PLYWorkerLoader,\n // Note: parsePLY supports both text and binary\n parse: async (arrayBuffer, options) => parsePLY(arrayBuffer, options), // TODO - this may not detect text correctly?\n parseTextSync: parsePLY,\n parseSync: parsePLY,\n parseInBatches: parsePLYInBatches\n};\n\nexport const _typecheckPLYLoader: LoaderWithParser = PLYLoader;\n"],"file":"index.js"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/get-ply-schema.ts"],"names":["deduceMeshSchema","getPLYSchema","plyHeader","attributes","metadataMap","makeMetadataFromPlyHeader","schema","Map","set","JSON","stringify","comments","elements","format","undefined","version","headerLength","toString"],"mappings":"AAAA,SAAgCA,gBAAhC,QAAuD,oBAAvD;AASA,OAAO,SAASC,YAAT,CAAsBC,SAAtB,EAA4CC,UAA5C,EAAgF;AACrF,QAAMC,WAAW,GAAGC,yBAAyB,CAACH,SAAD,CAA7C;AACA,QAAMI,MAAM,GAAGN,gBAAgB,CAACG,UAAD,EAAaC,WAAb,CAA/B;AACA,SAAOE,MAAP;AACD;;AAOD,SAASD,yBAAT,CAAmCH,SAAnC,EAA8E;AAC5E,QAAME,WAAW,GAAG,IAAIG,GAAJ,EAApB;AACAH,EAAAA,WAAW,CAACI,GAAZ,CAAgB,cAAhB,EAAgCC,IAAI,CAACC,SAAL,CAAeR,SAAS,CAACS,QAAzB,CAAhC;AACAP,EAAAA,WAAW,CAACI,GAAZ,CAAgB,cAAhB,EAAgCC,IAAI,CAACC,SAAL,CAAeR,SAAS,CAACU,QAAzB,CAAhC;;AACA,MAAIV,SAAS,CAACW,MAAV,KAAqBC,SAAzB,EAAoC;AAClCV,IAAAA,WAAW,CAACI,GAAZ,CAAgB,YAAhB,EAA8BN,SAAS,CAACW,MAAxC;AACD;;AACD,MAAIX,SAAS,CAACa,OAAV,KAAsBD,SAA1B,EAAqC;AACnCV,IAAAA,WAAW,CAACI,GAAZ,CAAgB,aAAhB,EAA+BN,SAAS,CAACa,OAAzC;AACD;;AACD,MAAIb,SAAS,CAACc,YAAV,KAA2BF,SAA/B,EAA0C;AACxCV,IAAAA,WAAW,CAACI,GAAZ,CAAgB,kBAAhB,EAAoCN,SAAS,CAACc,YAAV,CAAuBC,QAAvB,CAAgC,EAAhC,CAApC;AACD;;AACD,SAAOb,WAAP;AACD","sourcesContent":["import {Schema, MeshAttributes, deduceMeshSchema} from '@loaders.gl/schema';\nimport type {PLYHeader} from './ply-types';\n\n/**\n * Gets schema from PLY header\n * @param plyHeader\n * @param metadata\n * @returns Schema\n */\nexport function getPLYSchema(plyHeader: PLYHeader, attributes: MeshAttributes): Schema {\n const metadataMap = makeMetadataFromPlyHeader(plyHeader);\n const schema = deduceMeshSchema(attributes, metadataMap);\n return schema;\n}\n\n/**\n * Make arrow like schema metadata by PlyHeader properties\n * @param plyHeader\n * @returns\n */\nfunction makeMetadataFromPlyHeader(plyHeader: PLYHeader): Map<string, string> {\n const metadataMap = new Map();\n metadataMap.set('ply_comments', JSON.stringify(plyHeader.comments));\n metadataMap.set('ply_elements', JSON.stringify(plyHeader.elements));\n if (plyHeader.format !== undefined) {\n metadataMap.set('ply_format', plyHeader.format);\n }\n if (plyHeader.version !== undefined) {\n metadataMap.set('ply_version', plyHeader.version);\n }\n if (plyHeader.headerLength !== undefined) {\n metadataMap.set('ply_headerLength', plyHeader.headerLength.toString(10));\n }\n return metadataMap;\n}\n"],"file":"get-ply-schema.js"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/normalize-ply.ts"],"names":["getMeshBoundingBox","getPLYSchema","normalizePLY","plyHeader","plyAttributes","options","attributes","getMeshAttributes","boundingBox","vertexCount","indices","length","vertices","isTriangles","mode","topology","schema","plyMesh","loader","loaderData","header","value","Uint32Array","size","accessors","POSITION","Float32Array","normals","NORMAL","uvs","TEXCOORD_0","colors","COLOR_0","Uint8Array","normalized"],"mappings":"AACA,SAAQA,kBAAR,QAAiC,oBAAjC;AAEA,SAAQC,YAAR,QAA2B,kBAA3B;AAOA,eAAe,SAASC,YAAT,CACbC,SADa,EAEbC,aAFa,EAGbC,OAHa,EAIJ;AACT,QAAMC,UAAU,GAAGC,iBAAiB,CAACH,aAAD,CAApC;AACA,QAAMI,WAAW,GAAGR,kBAAkB,CAACM,UAAD,CAAtC;AACA,QAAMG,WAAW,GAAGL,aAAa,CAACM,OAAd,CAAsBC,MAAtB,IAAgCP,aAAa,CAACQ,QAAd,CAAuBD,MAAvB,GAAgC,CAApF;AAIA,QAAME,WAAW,GAAGT,aAAa,CAACM,OAAd,IAAyBN,aAAa,CAACM,OAAd,CAAsBC,MAAtB,GAA+B,CAA5E;AACA,QAAMG,IAAI,GAAGD,WAAW,GAAG,CAAH,GAAO,CAA/B;AACA,QAAME,QAAQ,GAAGF,WAAW,GAAG,eAAH,GAAqB,YAAjD;AAEA,QAAMG,MAAM,GAAGf,YAAY,CAACE,SAAD,EAAYG,UAAZ,CAA3B;AAEA,QAAMW,OAAgB,GAAG;AACvBC,IAAAA,MAAM,EAAE,KADe;AAEvBC,IAAAA,UAAU,EAAEhB,SAFW;AAGvBiB,IAAAA,MAAM,EAAE;AACNX,MAAAA,WADM;AAEND,MAAAA;AAFM,KAHe;AAOvBQ,IAAAA,MAPuB;AAQvBV,IAAAA,UARuB;AASvBI,IAAAA,OAAO,EAAE;AAACW,MAAAA,KAAK,EAAE,IAAIC,WAAJ,CAAgB,CAAhB,CAAR;AAA4BC,MAAAA,IAAI,EAAE;AAAlC,KATc;AAUvBT,IAAAA,IAVuB;AAWvBC,IAAAA;AAXuB,GAAzB;;AAcA,MAAIX,aAAa,CAACM,OAAd,CAAsBC,MAAtB,GAA+B,CAAnC,EAAsC;AACpCM,IAAAA,OAAO,CAACP,OAAR,GAAkB;AAACW,MAAAA,KAAK,EAAE,IAAIC,WAAJ,CAAgBlB,aAAa,CAACM,OAA9B,CAAR;AAAgDa,MAAAA,IAAI,EAAE;AAAtD,KAAlB;AACD;;AAED,SAAON,OAAP;AACD;;AAMD,SAASV,iBAAT,CAA2BD,UAA3B,EAAsE;AACpE,QAAMkB,SAAyB,GAAG,EAAlC;AAEAA,EAAAA,SAAS,CAACC,QAAV,GAAqB;AAACJ,IAAAA,KAAK,EAAE,IAAIK,YAAJ,CAAiBpB,UAAU,CAACM,QAA5B,CAAR;AAA+CW,IAAAA,IAAI,EAAE;AAArD,GAArB;;AAIA,MAAIjB,UAAU,CAACqB,OAAX,CAAmBhB,MAAnB,GAA4B,CAAhC,EAAmC;AACjCa,IAAAA,SAAS,CAACI,MAAV,GAAmB;AAACP,MAAAA,KAAK,EAAE,IAAIK,YAAJ,CAAiBpB,UAAU,CAACqB,OAA5B,CAAR;AAA8CJ,MAAAA,IAAI,EAAE;AAApD,KAAnB;AACD;;AAED,MAAIjB,UAAU,CAACuB,GAAX,CAAelB,MAAf,GAAwB,CAA5B,EAA+B;AAC7Ba,IAAAA,SAAS,CAACM,UAAV,GAAuB;AAACT,MAAAA,KAAK,EAAE,IAAIK,YAAJ,CAAiBpB,UAAU,CAACuB,GAA5B,CAAR;AAA0CN,MAAAA,IAAI,EAAE;AAAhD,KAAvB;AACD;;AAED,MAAIjB,UAAU,CAACyB,MAAX,CAAkBpB,MAAlB,GAA2B,CAA/B,EAAkC;AAEhCa,IAAAA,SAAS,CAACQ,OAAV,GAAoB;AAACX,MAAAA,KAAK,EAAE,IAAIY,UAAJ,CAAe3B,UAAU,CAACyB,MAA1B,CAAR;AAA2CR,MAAAA,IAAI,EAAE,CAAjD;AAAoDW,MAAAA,UAAU,EAAE;AAAhE,KAApB;AACD;;AAED,SAAOV,SAAP;AACD","sourcesContent":["import type {MeshAttributes} from '@loaders.gl/schema';\nimport {getMeshBoundingBox} from '@loaders.gl/schema';\nimport type {PLYMesh, PLYHeader, PLYAttributes, MeshHeader} from './ply-types';\nimport {getPLYSchema} from './get-ply-schema';\n\n/**\n * @param header\n * @param attributes\n * @returns data and header\n */\nexport default function normalizePLY(\n plyHeader: MeshHeader & PLYHeader,\n plyAttributes: PLYAttributes,\n options?: {}\n): PLYMesh {\n const attributes = getMeshAttributes(plyAttributes);\n const boundingBox = getMeshBoundingBox(attributes);\n const vertexCount = plyAttributes.indices.length || plyAttributes.vertices.length / 3;\n\n // TODO - how to detect POINT CLOUDS vs MESHES?\n // TODO - For Meshes, PLY quadrangles must be split?\n const isTriangles = plyAttributes.indices && plyAttributes.indices.length > 0;\n const mode = isTriangles ? 4 : 0; // TRIANGLES vs POINTS\n const topology = isTriangles ? 'triangle-list' : 'point-list';\n\n const schema = getPLYSchema(plyHeader, attributes);\n\n const plyMesh: PLYMesh = {\n loader: 'ply',\n loaderData: plyHeader,\n header: {\n vertexCount,\n boundingBox\n },\n schema,\n attributes,\n indices: {value: new Uint32Array(0), size: 0},\n mode,\n topology\n };\n\n if (plyAttributes.indices.length > 0) {\n plyMesh.indices = {value: new Uint32Array(plyAttributes.indices), size: 1};\n }\n\n return plyMesh;\n}\n\n/**\n * @param attributes\n * @returns accessors []\n */\nfunction getMeshAttributes(attributes: PLYAttributes): MeshAttributes {\n const accessors: MeshAttributes = {};\n\n accessors.POSITION = {value: new Float32Array(attributes.vertices), size: 3};\n\n // optional attributes data\n\n if (attributes.normals.length > 0) {\n accessors.NORMAL = {value: new Float32Array(attributes.normals), size: 3};\n }\n\n if (attributes.uvs.length > 0) {\n accessors.TEXCOORD_0 = {value: new Float32Array(attributes.uvs), size: 2};\n }\n\n if (attributes.colors.length > 0) {\n // TODO - normalized shoud be based on `uchar` flag in source data?\n accessors.COLOR_0 = {value: new Uint8Array(attributes.colors), size: 3, normalized: true};\n }\n\n return accessors;\n}\n"],"file":"normalize-ply.js"}
|