@loaders.gl/pointclouds 0.0.0-stage → 5.0.0-beta.10
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/LAS-README.md +12 -0
- package/LICENSE +24 -0
- package/PCD-README.md +12 -0
- package/PLY-README.md +38 -0
- package/README.md +11 -2
- package/THIRD-PARTY-NOTICES.md +27 -0
- package/dist/dist.dev.js +31514 -0
- package/dist/dist.min.js +54 -0
- package/dist/index.cjs +55 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/las/bundled.cjs +69 -0
- package/dist/las/bundled.cjs.map +7 -0
- package/dist/las/bundled.d.ts +11 -0
- package/dist/las/bundled.d.ts.map +1 -0
- package/dist/las/bundled.js +11 -0
- package/dist/las/bundled.js.map +1 -0
- package/dist/las/index.cjs +75 -0
- package/dist/las/index.cjs.map +7 -0
- package/dist/las/index.d.ts +15 -0
- package/dist/las/index.d.ts.map +1 -0
- package/dist/las/index.js +12 -0
- package/dist/las/index.js.map +1 -0
- package/dist/las/las-copc-loader-types.cjs +49 -0
- package/dist/las/las-copc-loader-types.cjs.map +7 -0
- package/dist/las/las-copc-loader-types.d.ts +67 -0
- package/dist/las/las-copc-loader-types.d.ts.map +1 -0
- package/dist/las/las-copc-loader-types.js +14 -0
- package/dist/las/las-copc-loader-types.js.map +1 -0
- package/dist/las/las-copc-loader.cjs +60 -0
- package/dist/las/las-copc-loader.cjs.map +7 -0
- package/dist/las/las-copc-loader.d.ts +39 -0
- package/dist/las/las-copc-loader.d.ts.map +1 -0
- package/dist/las/las-copc-loader.js +45 -0
- package/dist/las/las-copc-loader.js.map +1 -0
- package/dist/las/las-format.cjs +44 -0
- package/dist/las/las-format.cjs.map +7 -0
- package/dist/las/las-format.d.ts +16 -0
- package/dist/las/las-format.d.ts.map +1 -0
- package/dist/las/las-format.js +19 -0
- package/dist/las/las-format.js.map +1 -0
- package/dist/las/las-loader-shared.cjs +84 -0
- package/dist/las/las-loader-shared.cjs.map +7 -0
- package/dist/las/las-loader-shared.d.ts +68 -0
- package/dist/las/las-loader-shared.d.ts.map +1 -0
- package/dist/las/las-loader-shared.js +60 -0
- package/dist/las/las-loader-shared.js.map +1 -0
- package/dist/las/las-loader-types.cjs +51 -0
- package/dist/las/las-loader-types.cjs.map +7 -0
- package/dist/las/las-loader-types.d.ts +77 -0
- package/dist/las/las-loader-types.d.ts.map +1 -0
- package/dist/las/las-loader-types.js +17 -0
- package/dist/las/las-loader-types.js.map +1 -0
- package/dist/las/las-loader.cjs +128 -0
- package/dist/las/las-loader.cjs.map +7 -0
- package/dist/las/las-loader.d.ts +91 -0
- package/dist/las/las-loader.d.ts.map +1 -0
- package/dist/las/las-loader.js +108 -0
- package/dist/las/las-loader.js.map +1 -0
- package/dist/las/las-writer.cjs +1054 -0
- package/dist/las/las-writer.cjs.map +7 -0
- package/dist/las/las-writer.d.ts +70 -0
- package/dist/las/las-writer.d.ts.map +1 -0
- package/dist/las/las-writer.js +992 -0
- package/dist/las/las-writer.js.map +1 -0
- package/dist/las/laz-rs-loader-types.cjs +49 -0
- package/dist/las/laz-rs-loader-types.cjs.map +7 -0
- package/dist/las/laz-rs-loader-types.d.ts +69 -0
- package/dist/las/laz-rs-loader-types.d.ts.map +1 -0
- package/dist/las/laz-rs-loader-types.js +16 -0
- package/dist/las/laz-rs-loader-types.js.map +1 -0
- package/dist/las/laz-rs-loader.cjs +275 -0
- package/dist/las/laz-rs-loader.cjs.map +7 -0
- package/dist/las/laz-rs-loader.d.ts +39 -0
- package/dist/las/laz-rs-loader.d.ts.map +1 -0
- package/dist/las/laz-rs-loader.js +43 -0
- package/dist/las/laz-rs-loader.js.map +1 -0
- package/dist/las/lazperf-loader-types.cjs +49 -0
- package/dist/las/lazperf-loader-types.cjs.map +7 -0
- package/dist/las/lazperf-loader-types.d.ts +71 -0
- package/dist/las/lazperf-loader-types.d.ts.map +1 -0
- package/dist/las/lazperf-loader-types.js +17 -0
- package/dist/las/lazperf-loader-types.js.map +1 -0
- package/dist/las/lazperf-loader.cjs +63 -0
- package/dist/las/lazperf-loader.cjs.map +7 -0
- package/dist/las/lazperf-loader.d.ts +41 -0
- package/dist/las/lazperf-loader.d.ts.map +1 -0
- package/dist/las/lazperf-loader.js +49 -0
- package/dist/las/lazperf-loader.js.map +1 -0
- package/dist/las/lib/copc/parse-las.cjs +177 -0
- package/dist/las/lib/copc/parse-las.cjs.map +7 -0
- package/dist/las/lib/copc/parse-las.d.ts +17 -0
- package/dist/las/lib/copc/parse-las.d.ts.map +1 -0
- package/dist/las/lib/copc/parse-las.js +215 -0
- package/dist/las/lib/copc/parse-las.js.map +1 -0
- package/dist/las/lib/get-las-schema.cjs +67 -0
- package/dist/las/lib/get-las-schema.cjs.map +7 -0
- package/dist/las/lib/get-las-schema.d.ts +16 -0
- package/dist/las/lib/get-las-schema.d.ts.map +1 -0
- package/dist/las/lib/get-las-schema.js +52 -0
- package/dist/las/lib/get-las-schema.js.map +1 -0
- package/dist/las/lib/las-compatibility.cjs +110 -0
- package/dist/las/lib/las-compatibility.cjs.map +7 -0
- package/dist/las/lib/las-compatibility.d.ts +40 -0
- package/dist/las/lib/las-compatibility.d.ts.map +1 -0
- package/dist/las/lib/las-compatibility.js +115 -0
- package/dist/las/lib/las-compatibility.js.map +1 -0
- package/dist/las/lib/las-extra-bytes.cjs +228 -0
- package/dist/las/lib/las-extra-bytes.cjs.map +7 -0
- package/dist/las/lib/las-extra-bytes.d.ts +35 -0
- package/dist/las/lib/las-extra-bytes.d.ts.map +1 -0
- package/dist/las/lib/las-extra-bytes.js +197 -0
- package/dist/las/lib/las-extra-bytes.js.map +1 -0
- package/dist/las/lib/las-types.cjs +19 -0
- package/dist/las/lib/las-types.cjs.map +7 -0
- package/dist/las/lib/las-types.d.ts +194 -0
- package/dist/las/lib/las-types.d.ts.map +1 -0
- package/dist/las/lib/las-types.js +5 -0
- package/dist/las/lib/las-types.js.map +1 -0
- package/dist/las/lib/las-waveform.cjs +196 -0
- package/dist/las/lib/las-waveform.cjs.map +7 -0
- package/dist/las/lib/las-waveform.d.ts +89 -0
- package/dist/las/lib/las-waveform.d.ts.map +1 -0
- package/dist/las/lib/las-waveform.js +193 -0
- package/dist/las/lib/las-waveform.js.map +1 -0
- package/dist/las/lib/laz-perf/laslaz-decoder.cjs +382 -0
- package/dist/las/lib/laz-perf/laslaz-decoder.cjs.map +7 -0
- package/dist/las/lib/laz-perf/laslaz-decoder.d.ts +129 -0
- package/dist/las/lib/laz-perf/laslaz-decoder.d.ts.map +1 -0
- package/dist/las/lib/laz-perf/laslaz-decoder.js +377 -0
- package/dist/las/lib/laz-perf/laslaz-decoder.js.map +1 -0
- package/dist/las/lib/laz-perf/parse-las.cjs +271 -0
- package/dist/las/lib/laz-perf/parse-las.cjs.map +7 -0
- package/dist/las/lib/laz-perf/parse-las.d.ts +24 -0
- package/dist/las/lib/laz-perf/parse-las.d.ts.map +1 -0
- package/dist/las/lib/laz-perf/parse-las.js +308 -0
- package/dist/las/lib/laz-perf/parse-las.js.map +1 -0
- package/dist/las/lib/laz-rs-wasm/laslaz-decoder.cjs +631 -0
- package/dist/las/lib/laz-rs-wasm/laslaz-decoder.cjs.map +7 -0
- package/dist/las/lib/laz-rs-wasm/laslaz-decoder.d.ts +129 -0
- package/dist/las/lib/laz-rs-wasm/laslaz-decoder.d.ts.map +1 -0
- package/dist/las/lib/laz-rs-wasm/laslaz-decoder.js +414 -0
- package/dist/las/lib/laz-rs-wasm/laslaz-decoder.js.map +1 -0
- package/dist/las/lib/laz-rs-wasm/parse-las.cjs +271 -0
- package/dist/las/lib/laz-rs-wasm/parse-las.cjs.map +7 -0
- package/dist/las/lib/laz-rs-wasm/parse-las.d.ts +24 -0
- package/dist/las/lib/laz-rs-wasm/parse-las.d.ts.map +1 -0
- package/dist/las/lib/laz-rs-wasm/parse-las.js +308 -0
- package/dist/las/lib/laz-rs-wasm/parse-las.js.map +1 -0
- package/dist/las/lib/typescript/parse-las.cjs +2889 -0
- package/dist/las/lib/typescript/parse-las.cjs.map +7 -0
- package/dist/las/lib/typescript/parse-las.d.ts +39 -0
- package/dist/las/lib/typescript/parse-las.d.ts.map +1 -0
- package/dist/las/lib/typescript/parse-las.js +2703 -0
- package/dist/las/lib/typescript/parse-las.js.map +1 -0
- package/dist/las/libs/laz-perf/laz-perf.cjs +18093 -0
- package/dist/las/libs/laz-perf/laz-perf.cjs.map +7 -0
- package/dist/las/libs/laz-perf/laz-perf.d.ts +2 -0
- package/dist/las/libs/laz-perf/laz-perf.d.ts.map +1 -0
- package/dist/las/libs/laz-perf/laz-perf.js +19003 -0
- package/dist/las/libs/laz-perf/laz-perf.js.map +1 -0
- package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.d.ts +95 -0
- package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.d.ts.map +1 -0
- package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.js +442 -0
- package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.js.map +1 -0
- package/dist/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm +0 -0
- package/dist/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm.d.ts +38 -0
- package/dist/las/unbundled.cjs +69 -0
- package/dist/las/unbundled.cjs.map +7 -0
- package/dist/las/unbundled.d.ts +11 -0
- package/dist/las/unbundled.d.ts.map +1 -0
- package/dist/las/unbundled.js +11 -0
- package/dist/las/unbundled.js.map +1 -0
- package/dist/las/workers/las-worker.cjs +23 -0
- package/dist/las/workers/las-worker.cjs.map +7 -0
- package/dist/las/workers/las-worker.d.ts +2 -0
- package/dist/las/workers/las-worker.d.ts.map +1 -0
- package/dist/las/workers/las-worker.js +23 -0
- package/dist/las/workers/las-worker.js.map +1 -0
- package/dist/las-copc-loader-types.cjs +51 -0
- package/dist/las-copc-loader-types.cjs.map +7 -0
- package/dist/las-copc-loader-types.d.ts +2 -0
- package/dist/las-copc-loader-types.d.ts.map +1 -0
- package/dist/las-copc-loader-types.js +2 -0
- package/dist/las-copc-loader-types.js.map +1 -0
- package/dist/las-copc-loader.cjs +62 -0
- package/dist/las-copc-loader.cjs.map +7 -0
- package/dist/las-copc-loader.d.ts +2 -0
- package/dist/las-copc-loader.d.ts.map +1 -0
- package/dist/las-copc-loader.js +2 -0
- package/dist/las-copc-loader.js.map +1 -0
- package/dist/las-loader-types.cjs +53 -0
- package/dist/las-loader-types.cjs.map +7 -0
- package/dist/las-loader-types.d.ts +2 -0
- package/dist/las-loader-types.d.ts.map +1 -0
- package/dist/las-loader-types.js +2 -0
- package/dist/las-loader-types.js.map +1 -0
- package/dist/las-loader.cjs +130 -0
- package/dist/las-loader.cjs.map +7 -0
- package/dist/las-loader.d.ts +2 -0
- package/dist/las-loader.d.ts.map +1 -0
- package/dist/las-loader.js +2 -0
- package/dist/las-loader.js.map +1 -0
- package/dist/las-worker.js +24024 -0
- package/dist/las-writer.cjs +1056 -0
- package/dist/las-writer.cjs.map +7 -0
- package/dist/las-writer.d.ts +2 -0
- package/dist/las-writer.d.ts.map +1 -0
- package/dist/las-writer.js +2 -0
- package/dist/las-writer.js.map +1 -0
- package/dist/laz-rs-loader-types.cjs +51 -0
- package/dist/laz-rs-loader-types.cjs.map +7 -0
- package/dist/laz-rs-loader-types.d.ts +2 -0
- package/dist/laz-rs-loader-types.d.ts.map +1 -0
- package/dist/laz-rs-loader-types.js +2 -0
- package/dist/laz-rs-loader-types.js.map +1 -0
- package/dist/laz-rs-loader.cjs +277 -0
- package/dist/laz-rs-loader.cjs.map +7 -0
- package/dist/laz-rs-loader.d.ts +2 -0
- package/dist/laz-rs-loader.d.ts.map +1 -0
- package/dist/laz-rs-loader.js +2 -0
- package/dist/laz-rs-loader.js.map +1 -0
- package/dist/lazperf-loader-types.cjs +51 -0
- package/dist/lazperf-loader-types.cjs.map +7 -0
- package/dist/lazperf-loader-types.d.ts +2 -0
- package/dist/lazperf-loader-types.d.ts.map +1 -0
- package/dist/lazperf-loader-types.js +2 -0
- package/dist/lazperf-loader-types.js.map +1 -0
- package/dist/lazperf-loader.cjs +65 -0
- package/dist/lazperf-loader.cjs.map +7 -0
- package/dist/lazperf-loader.d.ts +2 -0
- package/dist/lazperf-loader.d.ts.map +1 -0
- package/dist/lazperf-loader.js +2 -0
- package/dist/lazperf-loader.js.map +1 -0
- package/dist/pcd/bundled.cjs +31 -0
- package/dist/pcd/bundled.cjs.map +7 -0
- package/dist/pcd/bundled.d.ts +3 -0
- package/dist/pcd/bundled.d.ts.map +1 -0
- package/dist/pcd/bundled.js +5 -0
- package/dist/pcd/bundled.js.map +1 -0
- package/dist/pcd/index.cjs +37 -0
- package/dist/pcd/index.cjs.map +7 -0
- package/dist/pcd/index.d.ts +6 -0
- package/dist/pcd/index.d.ts.map +1 -0
- package/dist/pcd/index.js +7 -0
- package/dist/pcd/index.js.map +1 -0
- package/dist/pcd/lib/decompress-lzf.cjs +80 -0
- package/dist/pcd/lib/decompress-lzf.cjs.map +7 -0
- package/dist/pcd/lib/decompress-lzf.d.ts +7 -0
- package/dist/pcd/lib/decompress-lzf.d.ts.map +1 -0
- package/dist/pcd/lib/decompress-lzf.js +62 -0
- package/dist/pcd/lib/decompress-lzf.js.map +1 -0
- package/dist/pcd/lib/get-pcd-schema.cjs +70 -0
- package/dist/pcd/lib/get-pcd-schema.cjs.map +7 -0
- package/dist/pcd/lib/get-pcd-schema.d.ts +10 -0
- package/dist/pcd/lib/get-pcd-schema.d.ts.map +1 -0
- package/dist/pcd/lib/get-pcd-schema.js +53 -0
- package/dist/pcd/lib/get-pcd-schema.js.map +1 -0
- package/dist/pcd/lib/parse-pcd.cjs +354 -0
- package/dist/pcd/lib/parse-pcd.cjs.map +7 -0
- package/dist/pcd/lib/parse-pcd.d.ts +20 -0
- package/dist/pcd/lib/parse-pcd.d.ts.map +1 -0
- package/dist/pcd/lib/parse-pcd.js +341 -0
- package/dist/pcd/lib/parse-pcd.js.map +1 -0
- package/dist/pcd/lib/pcd-types.cjs +19 -0
- package/dist/pcd/lib/pcd-types.cjs.map +7 -0
- package/dist/pcd/lib/pcd-types.d.ts +31 -0
- package/dist/pcd/lib/pcd-types.d.ts.map +1 -0
- package/dist/pcd/lib/pcd-types.js +5 -0
- package/dist/pcd/lib/pcd-types.js.map +1 -0
- package/dist/pcd/pcd-format.cjs +42 -0
- package/dist/pcd/pcd-format.cjs.map +7 -0
- package/dist/pcd/pcd-format.d.ts +16 -0
- package/dist/pcd/pcd-format.d.ts.map +1 -0
- package/dist/pcd/pcd-format.js +19 -0
- package/dist/pcd/pcd-format.js.map +1 -0
- package/dist/pcd/pcd-loader-types.cjs +63 -0
- package/dist/pcd/pcd-loader-types.cjs.map +7 -0
- package/dist/pcd/pcd-loader-types.d.ts +82 -0
- package/dist/pcd/pcd-loader-types.d.ts.map +1 -0
- package/dist/pcd/pcd-loader-types.js +35 -0
- package/dist/pcd/pcd-loader-types.js.map +1 -0
- package/dist/pcd/pcd-loader.cjs +201 -0
- package/dist/pcd/pcd-loader.cjs.map +7 -0
- package/dist/pcd/pcd-loader.d.ts +80 -0
- package/dist/pcd/pcd-loader.d.ts.map +1 -0
- package/dist/pcd/pcd-loader.js +179 -0
- package/dist/pcd/pcd-loader.js.map +1 -0
- package/dist/pcd/pcd-writer.cjs +134 -0
- package/dist/pcd/pcd-writer.cjs.map +7 -0
- package/dist/pcd/pcd-writer.d.ts +38 -0
- package/dist/pcd/pcd-writer.d.ts.map +1 -0
- package/dist/pcd/pcd-writer.js +115 -0
- package/dist/pcd/pcd-writer.js.map +1 -0
- package/dist/pcd/unbundled.cjs +31 -0
- package/dist/pcd/unbundled.cjs.map +7 -0
- package/dist/pcd/unbundled.d.ts +3 -0
- package/dist/pcd/unbundled.d.ts.map +1 -0
- package/dist/pcd/unbundled.js +5 -0
- package/dist/pcd/unbundled.js.map +1 -0
- package/dist/pcd/workers/pcd-worker.cjs +23 -0
- package/dist/pcd/workers/pcd-worker.cjs.map +7 -0
- package/dist/pcd/workers/pcd-worker.d.ts +2 -0
- package/dist/pcd/workers/pcd-worker.d.ts.map +1 -0
- package/dist/pcd/workers/pcd-worker.js +23 -0
- package/dist/pcd/workers/pcd-worker.js.map +1 -0
- package/dist/pcd-loader-types.cjs +65 -0
- package/dist/pcd-loader-types.cjs.map +7 -0
- package/dist/pcd-loader-types.d.ts +2 -0
- package/dist/pcd-loader-types.d.ts.map +1 -0
- package/dist/pcd-loader-types.js +2 -0
- package/dist/pcd-loader-types.js.map +1 -0
- package/dist/pcd-loader.cjs +203 -0
- package/dist/pcd-loader.cjs.map +7 -0
- package/dist/pcd-loader.d.ts +2 -0
- package/dist/pcd-loader.d.ts.map +1 -0
- package/dist/pcd-loader.js +2 -0
- package/dist/pcd-loader.js.map +1 -0
- package/dist/pcd-worker.js +18561 -0
- package/dist/pcd-writer.cjs +136 -0
- package/dist/pcd-writer.cjs.map +7 -0
- package/dist/pcd-writer.d.ts +2 -0
- package/dist/pcd-writer.d.ts.map +1 -0
- package/dist/pcd-writer.js +2 -0
- package/dist/pcd-writer.js.map +1 -0
- package/dist/ply/bundled.cjs +31 -0
- package/dist/ply/bundled.cjs.map +7 -0
- package/dist/ply/bundled.d.ts +3 -0
- package/dist/ply/bundled.d.ts.map +1 -0
- package/dist/ply/bundled.js +5 -0
- package/dist/ply/bundled.js.map +1 -0
- package/dist/ply/index.cjs +37 -0
- package/dist/ply/index.cjs.map +7 -0
- package/dist/ply/index.d.ts +6 -0
- package/dist/ply/index.d.ts.map +1 -0
- package/dist/ply/index.js +8 -0
- package/dist/ply/index.js.map +1 -0
- package/dist/ply/lib/get-ply-schema.cjs +128 -0
- package/dist/ply/lib/get-ply-schema.cjs.map +7 -0
- package/dist/ply/lib/get-ply-schema.d.ts +16 -0
- package/dist/ply/lib/get-ply-schema.d.ts.map +1 -0
- package/dist/ply/lib/get-ply-schema.js +117 -0
- package/dist/ply/lib/get-ply-schema.js.map +1 -0
- package/dist/ply/lib/normalize-ply.cjs +96 -0
- package/dist/ply/lib/normalize-ply.cjs.map +7 -0
- package/dist/ply/lib/normalize-ply.d.ts +8 -0
- package/dist/ply/lib/normalize-ply.d.ts.map +1 -0
- package/dist/ply/lib/normalize-ply.js +89 -0
- package/dist/ply/lib/normalize-ply.js.map +1 -0
- package/dist/ply/lib/parse-ply-arrow.cjs +552 -0
- package/dist/ply/lib/parse-ply-arrow.cjs.map +7 -0
- package/dist/ply/lib/parse-ply-arrow.d.ts +25 -0
- package/dist/ply/lib/parse-ply-arrow.d.ts.map +1 -0
- package/dist/ply/lib/parse-ply-arrow.js +493 -0
- package/dist/ply/lib/parse-ply-arrow.js.map +1 -0
- package/dist/ply/lib/parse-ply-in-batches.cjs +613 -0
- package/dist/ply/lib/parse-ply-in-batches.cjs.map +7 -0
- package/dist/ply/lib/parse-ply-in-batches.d.ts +9 -0
- package/dist/ply/lib/parse-ply-in-batches.d.ts.map +1 -0
- package/dist/ply/lib/parse-ply-in-batches.js +630 -0
- package/dist/ply/lib/parse-ply-in-batches.js.map +1 -0
- package/dist/ply/lib/parse-ply.cjs +758 -0
- package/dist/ply/lib/parse-ply.cjs.map +7 -0
- package/dist/ply/lib/parse-ply.d.ts +69 -0
- package/dist/ply/lib/parse-ply.d.ts.map +1 -0
- package/dist/ply/lib/parse-ply.js +855 -0
- package/dist/ply/lib/parse-ply.js.map +1 -0
- package/dist/ply/lib/ply-types.cjs +19 -0
- package/dist/ply/lib/ply-types.cjs.map +7 -0
- package/dist/ply/lib/ply-types.d.ts +37 -0
- package/dist/ply/lib/ply-types.d.ts.map +1 -0
- package/dist/ply/lib/ply-types.js +2 -0
- package/dist/ply/lib/ply-types.js.map +1 -0
- package/dist/ply/ply-format.cjs +43 -0
- package/dist/ply/ply-format.cjs.map +7 -0
- package/dist/ply/ply-format.d.ts +18 -0
- package/dist/ply/ply-format.d.ts.map +1 -0
- package/dist/ply/ply-format.js +22 -0
- package/dist/ply/ply-format.js.map +1 -0
- package/dist/ply/ply-loader-types.cjs +64 -0
- package/dist/ply/ply-loader-types.cjs.map +7 -0
- package/dist/ply/ply-loader-types.d.ts +88 -0
- package/dist/ply/ply-loader-types.d.ts.map +1 -0
- package/dist/ply/ply-loader-types.js +38 -0
- package/dist/ply/ply-loader-types.js.map +1 -0
- package/dist/ply/ply-loader.cjs +192 -0
- package/dist/ply/ply-loader.cjs.map +7 -0
- package/dist/ply/ply-loader.d.ts +81 -0
- package/dist/ply/ply-loader.d.ts.map +1 -0
- package/dist/ply/ply-loader.js +173 -0
- package/dist/ply/ply-loader.js.map +1 -0
- package/dist/ply/ply-writer.cjs +175 -0
- package/dist/ply/ply-writer.cjs.map +7 -0
- package/dist/ply/ply-writer.d.ts +38 -0
- package/dist/ply/ply-writer.d.ts.map +1 -0
- package/dist/ply/ply-writer.js +140 -0
- package/dist/ply/ply-writer.js.map +1 -0
- package/dist/ply/unbundled.cjs +31 -0
- package/dist/ply/unbundled.cjs.map +7 -0
- package/dist/ply/unbundled.d.ts +3 -0
- package/dist/ply/unbundled.d.ts.map +1 -0
- package/dist/ply/unbundled.js +5 -0
- package/dist/ply/unbundled.js.map +1 -0
- package/dist/ply/workers/ply-worker.cjs +34 -0
- package/dist/ply/workers/ply-worker.cjs.map +7 -0
- package/dist/ply/workers/ply-worker.d.ts +2 -0
- package/dist/ply/workers/ply-worker.d.ts.map +1 -0
- package/dist/ply/workers/ply-worker.js +37 -0
- package/dist/ply/workers/ply-worker.js.map +1 -0
- package/dist/ply-loader-types.cjs +66 -0
- package/dist/ply-loader-types.cjs.map +7 -0
- package/dist/ply-loader-types.d.ts +2 -0
- package/dist/ply-loader-types.d.ts.map +1 -0
- package/dist/ply-loader-types.js +2 -0
- package/dist/ply-loader-types.js.map +1 -0
- package/dist/ply-loader.cjs +194 -0
- package/dist/ply-loader.cjs.map +7 -0
- package/dist/ply-loader.d.ts +2 -0
- package/dist/ply-loader.d.ts.map +1 -0
- package/dist/ply-loader.js +2 -0
- package/dist/ply-loader.js.map +1 -0
- package/dist/ply-worker.js +20962 -0
- package/dist/ply-writer.cjs +177 -0
- package/dist/ply-writer.cjs.map +7 -0
- package/dist/ply-writer.d.ts +2 -0
- package/dist/ply-writer.d.ts.map +1 -0
- package/dist/ply-writer.js +2 -0
- package/dist/ply-writer.js.map +1 -0
- package/package.json +238 -4
- package/src/index.ts +19 -0
- package/src/las/bundled.ts +38 -0
- package/src/las/index.ts +66 -0
- package/src/las/las-copc-loader-types.ts +18 -0
- package/src/las/las-copc-loader.ts +61 -0
- package/src/las/las-format.ts +21 -0
- package/src/las/las-loader-shared.ts +126 -0
- package/src/las/las-loader-types.ts +24 -0
- package/src/las/las-loader.ts +163 -0
- package/src/las/las-writer.ts +1477 -0
- package/src/las/laz-rs-loader-types.ts +21 -0
- package/src/las/laz-rs-loader.ts +53 -0
- package/src/las/lazperf-loader-types.ts +22 -0
- package/src/las/lazperf-loader.ts +65 -0
- package/src/las/lib/LASZIP-LICENSE +202 -0
- package/src/las/lib/LASZIP-NOTICE +4 -0
- package/src/las/lib/copc/parse-las.ts +265 -0
- package/src/las/lib/get-las-schema.ts +55 -0
- package/src/las/lib/las-compatibility.ts +178 -0
- package/src/las/lib/las-extra-bytes.ts +276 -0
- package/src/las/lib/las-types.ts +206 -0
- package/src/las/lib/las-waveform.ts +292 -0
- package/src/las/lib/laz-perf/laslaz-decoder.ts +443 -0
- package/src/las/lib/laz-perf/parse-las.ts +411 -0
- package/src/las/lib/laz-rs-wasm/laslaz-decoder.ts +488 -0
- package/src/las/lib/laz-rs-wasm/parse-las.ts +411 -0
- package/src/las/lib/typescript/parse-las.ts +3862 -0
- package/src/las/libs/laz-perf/laz-perf.ts +20615 -0
- package/src/las/libs/laz-rs-wasm/README.md +5 -0
- package/src/las/libs/laz-rs-wasm/laz_rs_wasm.d.ts +89 -0
- package/src/las/libs/laz-rs-wasm/laz_rs_wasm.js +497 -0
- package/src/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm +0 -0
- package/src/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm.d.ts +38 -0
- package/src/las/libs/laz-rs-wasm/package.json +25 -0
- package/src/las/unbundled.ts +38 -0
- package/src/las/workers/las-worker.ts +24 -0
- package/src/las-copc-loader-types.ts +1 -0
- package/src/las-copc-loader.ts +1 -0
- package/src/las-loader-types.ts +1 -0
- package/src/las-loader.ts +1 -0
- package/src/las-writer.ts +1 -0
- package/src/laz-rs-loader-types.ts +1 -0
- package/src/laz-rs-loader.ts +1 -0
- package/src/lazperf-loader-types.ts +1 -0
- package/src/lazperf-loader.ts +1 -0
- package/src/pcd/bundled.ts +6 -0
- package/src/pcd/index.ts +9 -0
- package/src/pcd/lib/decompress-lzf.ts +68 -0
- package/src/pcd/lib/get-pcd-schema.ts +66 -0
- package/src/pcd/lib/parse-pcd.ts +474 -0
- package/src/pcd/lib/pcd-types.ts +34 -0
- package/src/pcd/pcd-format.ts +21 -0
- package/src/pcd/pcd-loader-types.ts +52 -0
- package/src/pcd/pcd-loader.ts +247 -0
- package/src/pcd/pcd-writer.ts +156 -0
- package/src/pcd/unbundled.ts +6 -0
- package/src/pcd/workers/pcd-worker.ts +24 -0
- package/src/pcd-loader-types.ts +1 -0
- package/src/pcd-loader.ts +1 -0
- package/src/pcd-writer.ts +1 -0
- package/src/ply/bundled.ts +6 -0
- package/src/ply/index.ts +11 -0
- package/src/ply/lib/get-ply-schema.ts +133 -0
- package/src/ply/lib/normalize-ply.ts +110 -0
- package/src/ply/lib/parse-ply-arrow.ts +676 -0
- package/src/ply/lib/parse-ply-in-batches.ts +832 -0
- package/src/ply/lib/parse-ply.ts +1084 -0
- package/src/ply/lib/ply-types.ts +47 -0
- package/src/ply/ply-format.ts +24 -0
- package/src/ply/ply-loader-types.ts +60 -0
- package/src/ply/ply-loader.ts +255 -0
- package/src/ply/ply-writer.ts +219 -0
- package/src/ply/unbundled.ts +6 -0
- package/src/ply/workers/ply-worker.ts +40 -0
- package/src/ply-loader-types.ts +1 -0
- package/src/ply-loader.ts +1 -0
- package/src/ply-writer.ts +1 -0
- package/third-party-licenses/plasio-LICENSE +21 -0
- package/third-party-licenses/three-LICENSE +21 -0
|
@@ -0,0 +1,1084 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// PLY Loader, adapted from THREE.js (MIT license)
|
|
6
|
+
//
|
|
7
|
+
// Attributions per original THREE.js source file:
|
|
8
|
+
//
|
|
9
|
+
// @author Wei Meng / http://about.me/menway
|
|
10
|
+
//
|
|
11
|
+
// Description: A loader for PLY ASCII files (known as the Polygon File Format
|
|
12
|
+
// or the Stanford Triangle Format).
|
|
13
|
+
//
|
|
14
|
+
// Limitations: ASCII decoding assumes file is UTF-8.
|
|
15
|
+
//
|
|
16
|
+
// If the PLY file uses non standard property names, they can be mapped while
|
|
17
|
+
// loading. For example, the following maps the properties
|
|
18
|
+
// “diffuse_(red|green|blue)” in the file to standard color names.
|
|
19
|
+
//
|
|
20
|
+
// parsePLY(data, {
|
|
21
|
+
// propertyNameMapping: {
|
|
22
|
+
// diffuse_red: 'red',
|
|
23
|
+
// diffuse_green: 'green',
|
|
24
|
+
// diffuse_blue: 'blue'
|
|
25
|
+
// }
|
|
26
|
+
// });
|
|
27
|
+
import type {MeshAttribute, MeshAttributes, MeshArrowTable} from '@loaders.gl/core/schema';
|
|
28
|
+
import * as arrow from 'apache-arrow';
|
|
29
|
+
import {getMeshBoundingBox} from '@loaders.gl/core/schema-utils';
|
|
30
|
+
import type {
|
|
31
|
+
PLYMesh,
|
|
32
|
+
PLYHeader,
|
|
33
|
+
PLYAttributes,
|
|
34
|
+
MeshHeader,
|
|
35
|
+
PLYElement,
|
|
36
|
+
PLYProperty
|
|
37
|
+
} from './ply-types';
|
|
38
|
+
import normalizePLY from './normalize-ply';
|
|
39
|
+
import {getPLYSchema} from './get-ply-schema';
|
|
40
|
+
|
|
41
|
+
const PLY_END_HEADER = 'end_header';
|
|
42
|
+
|
|
43
|
+
type MutablePLYAttributes = {[index: string]: number[]};
|
|
44
|
+
|
|
45
|
+
export type ParsePLYOptions = {
|
|
46
|
+
/** Force the legacy mesh parser; intended for parser benchmarks and regression checks. */
|
|
47
|
+
_useLegacyParser?: boolean;
|
|
48
|
+
/** Disable direct binary point-cloud parsing; intended for parser benchmarks and regression checks. */
|
|
49
|
+
_useLegacyBinaryPointCloudParser?: boolean;
|
|
50
|
+
propertyNameMapping?: Record<string, string>;
|
|
51
|
+
/** Treat PLY data as a point cloud by reading only the leading vertex element. */
|
|
52
|
+
pointCloud?: boolean;
|
|
53
|
+
shape?: 'mesh' | 'arrow';
|
|
54
|
+
/** Color storage format. Defaults to uint8norm for backwards compatibility. */
|
|
55
|
+
colorFormat?: 'uint8norm' | 'float16' | 'float32';
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param data
|
|
60
|
+
* @param options
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
export function parsePLY(data: ArrayBuffer | string, options: ParsePLYOptions = {}): PLYMesh {
|
|
64
|
+
let header: PLYHeader & MeshHeader;
|
|
65
|
+
let attributes: PLYAttributes;
|
|
66
|
+
|
|
67
|
+
if (data instanceof ArrayBuffer) {
|
|
68
|
+
header = parsePLYHeader(data, options);
|
|
69
|
+
attributes =
|
|
70
|
+
header.format === 'ascii'
|
|
71
|
+
? parseASCII(new TextDecoder().decode(data), header)
|
|
72
|
+
: parseBinary(data, header, options);
|
|
73
|
+
} else {
|
|
74
|
+
header = parsePLYHeader(data, options);
|
|
75
|
+
attributes = parseASCII(data, header);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return normalizePLY(header, attributes);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Parse binary scalar point-cloud PLY directly into an Arrow table.
|
|
83
|
+
* @param data PLY data.
|
|
84
|
+
* @param options Parser options.
|
|
85
|
+
* @returns Arrow table, or null when the file requires the general mesh parser.
|
|
86
|
+
*/
|
|
87
|
+
export function parsePLYToArrowTable(
|
|
88
|
+
data: ArrayBuffer | string,
|
|
89
|
+
options: ParsePLYOptions = {}
|
|
90
|
+
): MeshArrowTable | null {
|
|
91
|
+
if (!(data instanceof ArrayBuffer)) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const header = parsePLYHeader(data, options);
|
|
96
|
+
if (header.format === 'ascii') {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const attributes = parseBinaryPointCloud(data, header, options);
|
|
101
|
+
if (!attributes) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return makePLYArrowTable(header, attributes);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Parse a fixed-width binary point-cloud PLY byte range into an Arrow table.
|
|
110
|
+
* @param data Binary PLY bytes containing only vertex records.
|
|
111
|
+
* @param header PLY header describing the vertex record layout.
|
|
112
|
+
* @param options Parser options.
|
|
113
|
+
* @returns Arrow table, or null when the header is not supported by the fixed-width path.
|
|
114
|
+
*/
|
|
115
|
+
export function parsePLYBinaryPointCloudToArrowTable(
|
|
116
|
+
data: ArrayBuffer,
|
|
117
|
+
header: PLYHeader,
|
|
118
|
+
options: ParsePLYOptions = {}
|
|
119
|
+
): MeshArrowTable | null {
|
|
120
|
+
const attributes = parseBinaryPointCloud(data, header, options);
|
|
121
|
+
return attributes ? makePLYArrowTable(header, attributes) : null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Parse fixed-width binary vertex records directly from a byte view into an Arrow table.
|
|
126
|
+
* @param records Binary PLY vertex records without a header.
|
|
127
|
+
* @param header PLY header with the batch vertex count already applied.
|
|
128
|
+
* @param options Parser options.
|
|
129
|
+
* @param plan Optional reusable parse plan for the same header layout.
|
|
130
|
+
* @returns Arrow table, or null when the header is not supported by the fixed-width path.
|
|
131
|
+
*/
|
|
132
|
+
export function parsePLYBinaryPointCloudRecordsToArrowTable(
|
|
133
|
+
records: Uint8Array,
|
|
134
|
+
header: PLYHeader,
|
|
135
|
+
options: ParsePLYOptions = {},
|
|
136
|
+
plan?: PLYBinaryPointCloudParsePlan
|
|
137
|
+
): MeshArrowTable | null {
|
|
138
|
+
const attributes = parseBinaryPointCloudRecords(records, header, options, plan);
|
|
139
|
+
return attributes ? makePLYArrowTable(header, attributes) : null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param data
|
|
144
|
+
* @param options
|
|
145
|
+
* @returns header
|
|
146
|
+
*/
|
|
147
|
+
export function parsePLYHeader(data: any, options?: ParsePLYOptions): PLYHeader {
|
|
148
|
+
const {headerText, headerLength} =
|
|
149
|
+
data instanceof ArrayBuffer ? getBinaryHeader(data) : getTextHeader(data);
|
|
150
|
+
|
|
151
|
+
const headerStart = headerText.indexOf('ply');
|
|
152
|
+
const headerEndMarker = headerText.lastIndexOf('end_header');
|
|
153
|
+
const headerEnd = headerEndMarker + 'end_header'.length;
|
|
154
|
+
if (
|
|
155
|
+
headerStart >= 0 &&
|
|
156
|
+
headerEndMarker >= headerStart + 3 &&
|
|
157
|
+
headerEnd < headerText.length &&
|
|
158
|
+
/\s/.test(headerText[headerEnd])
|
|
159
|
+
) {
|
|
160
|
+
const lines = headerText.slice(headerStart + 3, headerEndMarker).split('\n');
|
|
161
|
+
const header = parseHeaderLines(lines, headerLength || headerEnd + 1 - headerStart, options);
|
|
162
|
+
return header;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return parseHeaderLines([], headerLength, options);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Return PLY header text and its byte length from binary data without decoding the body. */
|
|
169
|
+
function getBinaryHeader(data: ArrayBuffer): {headerText: string; headerLength: number} {
|
|
170
|
+
const bytes = new Uint8Array(data);
|
|
171
|
+
const headerEnd = findHeaderEnd(bytes);
|
|
172
|
+
return {
|
|
173
|
+
headerText: new TextDecoder().decode(bytes.subarray(0, headerEnd)),
|
|
174
|
+
headerLength: headerEnd
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Return PLY header text and its character length from text data. */
|
|
179
|
+
function getTextHeader(data: string): {headerText: string; headerLength: number} {
|
|
180
|
+
const headerEnd = data.indexOf(PLY_END_HEADER);
|
|
181
|
+
if (headerEnd === -1) {
|
|
182
|
+
return {headerText: '', headerLength: 0};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
let headerLength = headerEnd + PLY_END_HEADER.length;
|
|
186
|
+
if (data[headerLength] === '\r' && data[headerLength + 1] === '\n') {
|
|
187
|
+
headerLength += 2;
|
|
188
|
+
} else if (headerLength < data.length && /\s/.test(data[headerLength])) {
|
|
189
|
+
headerLength += 1;
|
|
190
|
+
}
|
|
191
|
+
return {headerText: data.slice(0, headerLength), headerLength};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Find the byte offset immediately after the `end_header` terminator. */
|
|
195
|
+
function findHeaderEnd(bytes: Uint8Array): number {
|
|
196
|
+
const pattern = new TextEncoder().encode(PLY_END_HEADER);
|
|
197
|
+
const lastPatternStart = bytes.length - pattern.length;
|
|
198
|
+
|
|
199
|
+
for (let byteIndex = 0; byteIndex <= lastPatternStart; byteIndex++) {
|
|
200
|
+
let matches = true;
|
|
201
|
+
for (let patternIndex = 0; patternIndex < pattern.length; patternIndex++) {
|
|
202
|
+
if (bytes[byteIndex + patternIndex] !== pattern[patternIndex]) {
|
|
203
|
+
matches = false;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (matches) {
|
|
209
|
+
let headerEnd = byteIndex + pattern.length;
|
|
210
|
+
if (bytes[headerEnd] === 0x0d && bytes[headerEnd + 1] === 0x0a) {
|
|
211
|
+
headerEnd += 2;
|
|
212
|
+
} else if (headerEnd < bytes.length && isWhitespaceByte(bytes[headerEnd])) {
|
|
213
|
+
headerEnd += 1;
|
|
214
|
+
}
|
|
215
|
+
return headerEnd;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return bytes.length;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Return true for ASCII whitespace bytes that can terminate a PLY header. */
|
|
223
|
+
function isWhitespaceByte(byte: number): boolean {
|
|
224
|
+
return byte === 0x0a || byte === 0x0d || byte === 0x09 || byte === 0x20;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @param lines
|
|
229
|
+
* @param headerLength
|
|
230
|
+
* @param options
|
|
231
|
+
* @returns header
|
|
232
|
+
*/
|
|
233
|
+
// eslint-disable-next-line complexity
|
|
234
|
+
function parseHeaderLines(
|
|
235
|
+
lines: string[],
|
|
236
|
+
headerLength: number,
|
|
237
|
+
options?: ParsePLYOptions
|
|
238
|
+
): PLYHeader {
|
|
239
|
+
const header: PLYHeader = {
|
|
240
|
+
comments: [],
|
|
241
|
+
elements: [],
|
|
242
|
+
headerLength
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
let lineType: string | undefined;
|
|
246
|
+
let lineValues: string[];
|
|
247
|
+
let currentElement: PLYElement | null = null;
|
|
248
|
+
|
|
249
|
+
for (let i = 0; i < lines.length; i++) {
|
|
250
|
+
let line: string = lines[i];
|
|
251
|
+
line = line.trim();
|
|
252
|
+
|
|
253
|
+
if (line === '') {
|
|
254
|
+
// eslint-disable-next-line
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
lineValues = line.split(/\s+/);
|
|
259
|
+
lineType = lineValues.shift();
|
|
260
|
+
line = lineValues.join(' ');
|
|
261
|
+
|
|
262
|
+
switch (lineType) {
|
|
263
|
+
case 'format':
|
|
264
|
+
header.format = lineValues[0];
|
|
265
|
+
header.version = lineValues[1];
|
|
266
|
+
break;
|
|
267
|
+
|
|
268
|
+
case 'comment':
|
|
269
|
+
header.comments.push(line);
|
|
270
|
+
break;
|
|
271
|
+
|
|
272
|
+
case 'element':
|
|
273
|
+
// Start new element, store previous element
|
|
274
|
+
if (currentElement) {
|
|
275
|
+
header.elements.push(currentElement);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
currentElement = {
|
|
279
|
+
name: lineValues[0],
|
|
280
|
+
count: parseInt(lineValues[1], 10),
|
|
281
|
+
properties: []
|
|
282
|
+
};
|
|
283
|
+
break;
|
|
284
|
+
|
|
285
|
+
case 'property':
|
|
286
|
+
if (currentElement) {
|
|
287
|
+
const property = makePLYElementProperty(lineValues);
|
|
288
|
+
if (options?.propertyNameMapping && property.name in options?.propertyNameMapping) {
|
|
289
|
+
property.name = options?.propertyNameMapping[property.name];
|
|
290
|
+
}
|
|
291
|
+
currentElement.properties.push(property);
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
|
|
295
|
+
default:
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Store in-progress element
|
|
300
|
+
if (currentElement) {
|
|
301
|
+
header.elements.push(currentElement);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return header;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** Generate attributes arrays from the header */
|
|
308
|
+
// eslint-disable-next-line complexity
|
|
309
|
+
function getPLYAttributes(header: PLYHeader): MutablePLYAttributes {
|
|
310
|
+
// TODO Generate only the attribute arrays actually in the header
|
|
311
|
+
const attributes = {
|
|
312
|
+
indices: [],
|
|
313
|
+
vertices: [],
|
|
314
|
+
normals: [],
|
|
315
|
+
uvs: [],
|
|
316
|
+
colors: []
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
for (const element of header.elements) {
|
|
320
|
+
if (element.name === 'vertex') {
|
|
321
|
+
for (const property of element.properties) {
|
|
322
|
+
switch (property.name) {
|
|
323
|
+
case 'x':
|
|
324
|
+
case 'y':
|
|
325
|
+
case 'z':
|
|
326
|
+
case 'nx':
|
|
327
|
+
case 'ny':
|
|
328
|
+
case 'nz':
|
|
329
|
+
case 's':
|
|
330
|
+
case 't':
|
|
331
|
+
case 'red':
|
|
332
|
+
case 'green':
|
|
333
|
+
case 'blue':
|
|
334
|
+
break;
|
|
335
|
+
default:
|
|
336
|
+
// Add any non-geometry attributes
|
|
337
|
+
attributes[property.name] = [];
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return attributes;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* @param propertyValues
|
|
349
|
+
* @returns property of ply element
|
|
350
|
+
*/
|
|
351
|
+
function makePLYElementProperty(propertyValues: string[]): PLYProperty {
|
|
352
|
+
const type = propertyValues[0];
|
|
353
|
+
switch (type) {
|
|
354
|
+
case 'list':
|
|
355
|
+
return {
|
|
356
|
+
type,
|
|
357
|
+
name: propertyValues[3],
|
|
358
|
+
countType: propertyValues[1],
|
|
359
|
+
itemType: propertyValues[2]
|
|
360
|
+
};
|
|
361
|
+
default:
|
|
362
|
+
return {
|
|
363
|
+
type,
|
|
364
|
+
name: propertyValues[1]
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Parses ASCII number
|
|
371
|
+
* @param n
|
|
372
|
+
* @param type
|
|
373
|
+
* @returns
|
|
374
|
+
*/
|
|
375
|
+
// eslint-disable-next-line complexity
|
|
376
|
+
function parseASCIINumber(n: string, type: string): number {
|
|
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
|
+
|
|
392
|
+
case 'float':
|
|
393
|
+
case 'double':
|
|
394
|
+
case 'float32':
|
|
395
|
+
case 'float64':
|
|
396
|
+
return parseFloat(n);
|
|
397
|
+
|
|
398
|
+
default:
|
|
399
|
+
throw new Error(type);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* @param properties
|
|
405
|
+
* @param line
|
|
406
|
+
* @returns ASCII element
|
|
407
|
+
*/
|
|
408
|
+
function parsePLYElement(properties: any[], line: string) {
|
|
409
|
+
const values: any = line.split(/\s+/);
|
|
410
|
+
|
|
411
|
+
const element = {};
|
|
412
|
+
|
|
413
|
+
for (let i = 0; i < properties.length; i++) {
|
|
414
|
+
if (properties[i].type === 'list') {
|
|
415
|
+
const list: any = [];
|
|
416
|
+
const n = parseASCIINumber(values.shift(), properties[i].countType);
|
|
417
|
+
|
|
418
|
+
for (let j = 0; j < n; j++) {
|
|
419
|
+
list.push(parseASCIINumber(values.shift(), properties[i].itemType));
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
element[properties[i].name] = list;
|
|
423
|
+
} else {
|
|
424
|
+
element[properties[i].name] = parseASCIINumber(values.shift(), properties[i].type);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return element;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @param data
|
|
433
|
+
* @param header
|
|
434
|
+
* @returns [attributes]
|
|
435
|
+
*/
|
|
436
|
+
function parseASCII(data: any, header: PLYHeader): PLYAttributes {
|
|
437
|
+
// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
|
|
438
|
+
|
|
439
|
+
const attributes = getPLYAttributes(header);
|
|
440
|
+
|
|
441
|
+
const patternBody = /end_header\s([\s\S]*)$/;
|
|
442
|
+
let body = '';
|
|
443
|
+
const result = patternBody.exec(data);
|
|
444
|
+
if (result !== null) {
|
|
445
|
+
body = result[1];
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const lines = body.split('\n');
|
|
449
|
+
let currentElement = 0;
|
|
450
|
+
let currentElementCount = 0;
|
|
451
|
+
|
|
452
|
+
for (let i = 0; i < lines.length; i++) {
|
|
453
|
+
let line = lines[i];
|
|
454
|
+
line = line.trim();
|
|
455
|
+
|
|
456
|
+
if (line !== '') {
|
|
457
|
+
if (currentElementCount >= header.elements[currentElement].count) {
|
|
458
|
+
currentElement++;
|
|
459
|
+
currentElementCount = 0;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const element = parsePLYElement(header.elements[currentElement].properties, line);
|
|
463
|
+
handleElement(attributes, header.elements[currentElement].name, element);
|
|
464
|
+
currentElementCount++;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return attributes;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* @param buffer
|
|
473
|
+
* @param elementName
|
|
474
|
+
* @param element
|
|
475
|
+
*/
|
|
476
|
+
// eslint-disable-next-line complexity
|
|
477
|
+
function handleElement(buffer: MutablePLYAttributes, elementName: string, element: any = {}) {
|
|
478
|
+
if (elementName === 'vertex') {
|
|
479
|
+
for (const propertyName of Object.keys(element)) {
|
|
480
|
+
switch (propertyName) {
|
|
481
|
+
case 'x':
|
|
482
|
+
buffer.vertices.push(element.x, element.y, element.z);
|
|
483
|
+
break;
|
|
484
|
+
case 'y':
|
|
485
|
+
case 'z':
|
|
486
|
+
break;
|
|
487
|
+
|
|
488
|
+
case 'nx':
|
|
489
|
+
if ('nx' in element && 'ny' in element && 'nz' in element) {
|
|
490
|
+
buffer.normals.push(element.nx, element.ny, element.nz);
|
|
491
|
+
}
|
|
492
|
+
break;
|
|
493
|
+
case 'ny':
|
|
494
|
+
case 'nz':
|
|
495
|
+
break;
|
|
496
|
+
|
|
497
|
+
case 's':
|
|
498
|
+
if ('s' in element && 't' in element) {
|
|
499
|
+
buffer.uvs.push(element.s, element.t);
|
|
500
|
+
}
|
|
501
|
+
break;
|
|
502
|
+
case 't':
|
|
503
|
+
break;
|
|
504
|
+
|
|
505
|
+
case 'red':
|
|
506
|
+
if ('red' in element && 'green' in element && 'blue' in element) {
|
|
507
|
+
buffer.colors.push(element.red, element.green, element.blue);
|
|
508
|
+
}
|
|
509
|
+
break;
|
|
510
|
+
case 'green':
|
|
511
|
+
case 'blue':
|
|
512
|
+
break;
|
|
513
|
+
|
|
514
|
+
default:
|
|
515
|
+
buffer[propertyName].push(element[propertyName]);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
} else if (elementName === 'face') {
|
|
519
|
+
const vertexIndices = element.vertex_indices || element.vertex_index; // issue #9338
|
|
520
|
+
|
|
521
|
+
if (vertexIndices.length === 3) {
|
|
522
|
+
buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[2]);
|
|
523
|
+
} else if (vertexIndices.length === 4) {
|
|
524
|
+
buffer.indices.push(vertexIndices[0], vertexIndices[1], vertexIndices[3]);
|
|
525
|
+
buffer.indices.push(vertexIndices[1], vertexIndices[2], vertexIndices[3]);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Reads binary data
|
|
532
|
+
* @param dataview
|
|
533
|
+
* @param at
|
|
534
|
+
* @param type
|
|
535
|
+
* @param littleEndian
|
|
536
|
+
* @returns [number, number]
|
|
537
|
+
*/
|
|
538
|
+
// eslint-disable-next-line complexity
|
|
539
|
+
function binaryRead(dataview: DataView, at: number, type: any, littleEndian: boolean): number[] {
|
|
540
|
+
switch (type) {
|
|
541
|
+
// corespondences for non-specific length types here match rply:
|
|
542
|
+
case 'int8':
|
|
543
|
+
case 'char':
|
|
544
|
+
return [dataview.getInt8(at), 1];
|
|
545
|
+
case 'uint8':
|
|
546
|
+
case 'uchar':
|
|
547
|
+
return [dataview.getUint8(at), 1];
|
|
548
|
+
case 'int16':
|
|
549
|
+
case 'short':
|
|
550
|
+
return [dataview.getInt16(at, littleEndian), 2];
|
|
551
|
+
case 'uint16':
|
|
552
|
+
case 'ushort':
|
|
553
|
+
return [dataview.getUint16(at, littleEndian), 2];
|
|
554
|
+
case 'int32':
|
|
555
|
+
case 'int':
|
|
556
|
+
return [dataview.getInt32(at, littleEndian), 4];
|
|
557
|
+
case 'uint32':
|
|
558
|
+
case 'uint':
|
|
559
|
+
return [dataview.getUint32(at, littleEndian), 4];
|
|
560
|
+
case 'float32':
|
|
561
|
+
case 'float':
|
|
562
|
+
return [dataview.getFloat32(at, littleEndian), 4];
|
|
563
|
+
case 'float64':
|
|
564
|
+
case 'double':
|
|
565
|
+
return [dataview.getFloat64(at, littleEndian), 8];
|
|
566
|
+
|
|
567
|
+
default:
|
|
568
|
+
throw new Error(type);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Reads binary data
|
|
574
|
+
* @param dataview
|
|
575
|
+
* @param at
|
|
576
|
+
* @param properties
|
|
577
|
+
* @param littleEndian
|
|
578
|
+
* @returns [object, number]
|
|
579
|
+
*/
|
|
580
|
+
function binaryReadElement(
|
|
581
|
+
dataview: DataView,
|
|
582
|
+
at: number,
|
|
583
|
+
properties: {[index: string]: any},
|
|
584
|
+
littleEndian: boolean
|
|
585
|
+
): {}[] {
|
|
586
|
+
const element = {};
|
|
587
|
+
let result: number[];
|
|
588
|
+
let read = 0;
|
|
589
|
+
|
|
590
|
+
for (let i = 0; i < properties.length; i++) {
|
|
591
|
+
if (properties[i].type === 'list') {
|
|
592
|
+
const list = [];
|
|
593
|
+
|
|
594
|
+
result = binaryRead(dataview, at + read, properties[i].countType, littleEndian);
|
|
595
|
+
const n = result[0];
|
|
596
|
+
read += result[1];
|
|
597
|
+
|
|
598
|
+
for (let j = 0; j < n; j++) {
|
|
599
|
+
result = binaryRead(dataview, at + read, properties[i].itemType, littleEndian);
|
|
600
|
+
// @ts-ignore
|
|
601
|
+
list.push(result[0]);
|
|
602
|
+
read += result[1];
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
element[properties[i].name] = list;
|
|
606
|
+
} else {
|
|
607
|
+
result = binaryRead(dataview, at + read, properties[i].type, littleEndian);
|
|
608
|
+
element[properties[i].name] = result[0];
|
|
609
|
+
read += result[1];
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
return [element, read];
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
type BinaryAttributes = PLYAttributes;
|
|
617
|
+
|
|
618
|
+
type BinaryPointCloudProperty = {
|
|
619
|
+
name: string;
|
|
620
|
+
offset: number;
|
|
621
|
+
read: (dataView: DataView, at: number, littleEndian: boolean) => number;
|
|
622
|
+
size: number;
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
/** Reusable binary point-cloud parse plan. */
|
|
626
|
+
export type PLYBinaryPointCloudParsePlan = {
|
|
627
|
+
/** Precomputed scalar property readers and record offsets. */
|
|
628
|
+
properties: BinaryPointCloudProperty[];
|
|
629
|
+
/** Fixed byte stride for one vertex record. */
|
|
630
|
+
vertexStride: number;
|
|
631
|
+
/** Whether scalar values are little-endian encoded. */
|
|
632
|
+
littleEndian: boolean;
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/** Build an Arrow table from normalized PLY attribute arrays. */
|
|
636
|
+
function makePLYArrowTable(header: PLYHeader, attributes: PLYAttributes): MeshArrowTable {
|
|
637
|
+
const meshAttributes = getPLYMeshAttributes(attributes);
|
|
638
|
+
const schema = getPLYSchema(header, meshAttributes);
|
|
639
|
+
schema.metadata.topology = 'point-list';
|
|
640
|
+
schema.metadata.mode = '0';
|
|
641
|
+
const boundingBox = getMeshBoundingBox(meshAttributes);
|
|
642
|
+
if (boundingBox) schema.metadata.boundingBox = JSON.stringify(boundingBox);
|
|
643
|
+
|
|
644
|
+
const columns: Record<string, arrow.Vector> = {};
|
|
645
|
+
const fields: arrow.Field[] = [];
|
|
646
|
+
|
|
647
|
+
for (const field of schema.fields) {
|
|
648
|
+
const attribute = meshAttributes[field.name];
|
|
649
|
+
if (!attribute) {
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
const column = getPLYArrowVector(attribute);
|
|
653
|
+
columns[field.name] = column;
|
|
654
|
+
fields.push(new arrow.Field(field.name, column.type, false, getArrowMetadata(field.metadata)));
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const arrowSchema = new arrow.Schema(fields, getArrowMetadata(schema.metadata));
|
|
658
|
+
return {
|
|
659
|
+
shape: 'arrow-table',
|
|
660
|
+
schema,
|
|
661
|
+
data: new arrow.Table(arrowSchema, columns),
|
|
662
|
+
topology: 'point-list'
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/** Convert normalized PLY attributes into mesh-style attribute descriptors. */
|
|
667
|
+
function getPLYMeshAttributes(attributes: PLYAttributes): MeshAttributes {
|
|
668
|
+
const meshAttributes: MeshAttributes = {};
|
|
669
|
+
|
|
670
|
+
for (const attributeName of Object.keys(attributes)) {
|
|
671
|
+
switch (attributeName) {
|
|
672
|
+
case 'vertices':
|
|
673
|
+
if (attributes.vertices.length > 0) {
|
|
674
|
+
meshAttributes.POSITION = {value: getFloat32Array(attributes.vertices), size: 3};
|
|
675
|
+
}
|
|
676
|
+
break;
|
|
677
|
+
case 'normals':
|
|
678
|
+
if (attributes.normals.length > 0) {
|
|
679
|
+
meshAttributes.NORMAL = {value: getFloat32Array(attributes.normals), size: 3};
|
|
680
|
+
}
|
|
681
|
+
break;
|
|
682
|
+
case 'uvs':
|
|
683
|
+
if (attributes.uvs.length > 0) {
|
|
684
|
+
meshAttributes.TEXCOORD_0 = {value: getFloat32Array(attributes.uvs), size: 2};
|
|
685
|
+
}
|
|
686
|
+
break;
|
|
687
|
+
case 'colors':
|
|
688
|
+
if (attributes.colors.length > 0) {
|
|
689
|
+
meshAttributes.COLOR_0 = {
|
|
690
|
+
value: getUint8Array(attributes.colors),
|
|
691
|
+
size: 3,
|
|
692
|
+
normalized: true
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
break;
|
|
696
|
+
case 'indices':
|
|
697
|
+
break;
|
|
698
|
+
default:
|
|
699
|
+
if (attributes[attributeName].length > 0) {
|
|
700
|
+
meshAttributes[attributeName] = {
|
|
701
|
+
value: getFloat32Array(attributes[attributeName]),
|
|
702
|
+
size: 1
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
return meshAttributes;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/** Return an Arrow vector for one PLY mesh attribute. */
|
|
713
|
+
function getPLYArrowVector(attribute: MeshAttribute): arrow.Vector {
|
|
714
|
+
const {value, size} = attribute;
|
|
715
|
+
if (size === 1) {
|
|
716
|
+
return arrow.makeVector(value as any);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
const values = arrow.makeVector(value as any);
|
|
720
|
+
const child = values.data[0];
|
|
721
|
+
const type = new arrow.FixedSizeList(size, new arrow.Field('value', child.type, false));
|
|
722
|
+
const data = new arrow.Data(type, 0, value.length / size, 0, {}, [child]);
|
|
723
|
+
return new arrow.Vector([data]);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/** Convert loaders.gl metadata objects to Arrow metadata maps. */
|
|
727
|
+
function getArrowMetadata(metadata: Record<string, string> | undefined): Map<string, string> {
|
|
728
|
+
return new Map(Object.entries(metadata || {}));
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/** Return a Float32Array without copying when possible. */
|
|
732
|
+
function getFloat32Array(attribute: PLYAttributes[string]): Float32Array {
|
|
733
|
+
return attribute instanceof Float32Array ? attribute : new Float32Array(attribute);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/** Return a Uint8Array without copying when possible. */
|
|
737
|
+
function getUint8Array(attribute: PLYAttributes[string]): Uint8Array {
|
|
738
|
+
return attribute instanceof Uint8Array ? attribute : new Uint8Array(attribute);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Parses binary data
|
|
743
|
+
* @param data
|
|
744
|
+
* @param header
|
|
745
|
+
* @returns [attributes] of data
|
|
746
|
+
*/
|
|
747
|
+
function parseBinary(
|
|
748
|
+
data: ArrayBuffer,
|
|
749
|
+
header: PLYHeader,
|
|
750
|
+
options?: ParsePLYOptions
|
|
751
|
+
): BinaryAttributes {
|
|
752
|
+
const directAttributes = parseBinaryPointCloud(data, header, options);
|
|
753
|
+
if (directAttributes) {
|
|
754
|
+
return directAttributes;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
const attributes = getPLYAttributes(header);
|
|
758
|
+
|
|
759
|
+
const littleEndian = header.format === 'binary_little_endian';
|
|
760
|
+
const body = new DataView(data, header.headerLength);
|
|
761
|
+
let result: any[];
|
|
762
|
+
let loc = 0;
|
|
763
|
+
|
|
764
|
+
for (let currentElement = 0; currentElement < header.elements.length; currentElement++) {
|
|
765
|
+
const count = header.elements[currentElement].count;
|
|
766
|
+
for (let currentElementCount = 0; currentElementCount < count; currentElementCount++) {
|
|
767
|
+
result = binaryReadElement(
|
|
768
|
+
body,
|
|
769
|
+
loc,
|
|
770
|
+
header.elements[currentElement].properties,
|
|
771
|
+
littleEndian
|
|
772
|
+
);
|
|
773
|
+
loc += result[1];
|
|
774
|
+
const element = result[0];
|
|
775
|
+
|
|
776
|
+
handleElement(attributes, header.elements[currentElement].name, element);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
return attributes;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/** Parse binary PLY point clouds directly into typed arrays. */
|
|
784
|
+
function parseBinaryPointCloud(
|
|
785
|
+
data: ArrayBuffer,
|
|
786
|
+
header: PLYHeader,
|
|
787
|
+
options?: ParsePLYOptions
|
|
788
|
+
): BinaryAttributes | null {
|
|
789
|
+
const records = new Uint8Array(data, header.headerLength || 0);
|
|
790
|
+
return parseBinaryPointCloudRecords(records, header, options);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/** Parse binary PLY point-cloud records directly from a byte view into typed arrays. */
|
|
794
|
+
function parseBinaryPointCloudRecords(
|
|
795
|
+
records: Uint8Array,
|
|
796
|
+
header: PLYHeader,
|
|
797
|
+
options?: ParsePLYOptions,
|
|
798
|
+
parsePlan?: PLYBinaryPointCloudParsePlan
|
|
799
|
+
): BinaryAttributes | null {
|
|
800
|
+
const vertexElement = header.elements[0];
|
|
801
|
+
if (
|
|
802
|
+
!parsePlan &&
|
|
803
|
+
(options?._useLegacyBinaryPointCloudParser ||
|
|
804
|
+
(!options?.pointCloud && header.elements.length !== 1) ||
|
|
805
|
+
vertexElement?.name !== 'vertex' ||
|
|
806
|
+
vertexElement.properties.some(property => property.type === 'list'))
|
|
807
|
+
) {
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
const plan = parsePlan || getPLYBinaryPointCloudParsePlan(header, options);
|
|
812
|
+
if (!plan || !vertexElement) {
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
const attributes = getBinaryPointCloudAttributes(vertexElement);
|
|
817
|
+
const dataView = new DataView(records.buffer, records.byteOffset, records.byteLength);
|
|
818
|
+
let vertexOffset = 0;
|
|
819
|
+
|
|
820
|
+
for (let vertexIndex = 0; vertexIndex < vertexElement.count; vertexIndex++) {
|
|
821
|
+
for (const property of plan.properties) {
|
|
822
|
+
const value = property.read(dataView, vertexOffset + property.offset, plan.littleEndian);
|
|
823
|
+
writeBinaryPointCloudProperty(attributes, property.name, value, vertexIndex);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
vertexOffset += plan.vertexStride;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
return attributes;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/** Return a reusable binary point-cloud parse plan, or null when unsupported. */
|
|
833
|
+
export function getPLYBinaryPointCloudParsePlan(
|
|
834
|
+
header: PLYHeader,
|
|
835
|
+
options?: ParsePLYOptions
|
|
836
|
+
): PLYBinaryPointCloudParsePlan | null {
|
|
837
|
+
const vertexElement = header.elements[0];
|
|
838
|
+
if (
|
|
839
|
+
options?._useLegacyBinaryPointCloudParser ||
|
|
840
|
+
(!options?.pointCloud && header.elements.length !== 1) ||
|
|
841
|
+
vertexElement?.name !== 'vertex' ||
|
|
842
|
+
vertexElement.properties.some(property => property.type === 'list')
|
|
843
|
+
) {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
const properties = getBinaryPointCloudProperties(vertexElement);
|
|
848
|
+
return {
|
|
849
|
+
properties,
|
|
850
|
+
vertexStride: getPLYElementSize(properties),
|
|
851
|
+
littleEndian: header.format === 'binary_little_endian'
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/** Allocate direct typed arrays for the normalized PLY attributes. */
|
|
856
|
+
function getBinaryPointCloudAttributes(vertexElement: PLYElement): BinaryAttributes {
|
|
857
|
+
const attributes: BinaryAttributes = {
|
|
858
|
+
indices: [],
|
|
859
|
+
vertices: [],
|
|
860
|
+
normals: [],
|
|
861
|
+
uvs: [],
|
|
862
|
+
colors: []
|
|
863
|
+
};
|
|
864
|
+
const propertyNames = new Set(vertexElement.properties.map(property => property.name));
|
|
865
|
+
const vertexCount = vertexElement.count;
|
|
866
|
+
|
|
867
|
+
if (propertyNames.has('x') && propertyNames.has('y') && propertyNames.has('z')) {
|
|
868
|
+
attributes.vertices = new Float32Array(vertexCount * 3) as unknown as number[];
|
|
869
|
+
}
|
|
870
|
+
if (propertyNames.has('nx') && propertyNames.has('ny') && propertyNames.has('nz')) {
|
|
871
|
+
attributes.normals = new Float32Array(vertexCount * 3) as unknown as number[];
|
|
872
|
+
}
|
|
873
|
+
if (propertyNames.has('s') && propertyNames.has('t')) {
|
|
874
|
+
attributes.uvs = new Float32Array(vertexCount * 2) as unknown as number[];
|
|
875
|
+
}
|
|
876
|
+
if (propertyNames.has('red') && propertyNames.has('green') && propertyNames.has('blue')) {
|
|
877
|
+
attributes.colors = new Uint8Array(vertexCount * 3) as unknown as number[];
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
for (const property of vertexElement.properties) {
|
|
881
|
+
if (!isNormalizedPLYAttributeProperty(property.name)) {
|
|
882
|
+
attributes[property.name] = new Float32Array(vertexCount) as unknown as number[];
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
return attributes;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/** Return true if a PLY property is packed into a normalized mesh attribute. */
|
|
890
|
+
function isNormalizedPLYAttributeProperty(propertyName: string): boolean {
|
|
891
|
+
switch (propertyName) {
|
|
892
|
+
case 'x':
|
|
893
|
+
case 'y':
|
|
894
|
+
case 'z':
|
|
895
|
+
case 'nx':
|
|
896
|
+
case 'ny':
|
|
897
|
+
case 'nz':
|
|
898
|
+
case 's':
|
|
899
|
+
case 't':
|
|
900
|
+
case 'red':
|
|
901
|
+
case 'green':
|
|
902
|
+
case 'blue':
|
|
903
|
+
return true;
|
|
904
|
+
default:
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
/** Write a scalar PLY property into its normalized typed array. */
|
|
910
|
+
function writeBinaryPointCloudProperty(
|
|
911
|
+
attributes: BinaryAttributes,
|
|
912
|
+
propertyName: string,
|
|
913
|
+
value: number,
|
|
914
|
+
vertexIndex: number
|
|
915
|
+
): void {
|
|
916
|
+
switch (propertyName) {
|
|
917
|
+
case 'x':
|
|
918
|
+
attributes.vertices[vertexIndex * 3] = value;
|
|
919
|
+
break;
|
|
920
|
+
case 'y':
|
|
921
|
+
attributes.vertices[vertexIndex * 3 + 1] = value;
|
|
922
|
+
break;
|
|
923
|
+
case 'z':
|
|
924
|
+
attributes.vertices[vertexIndex * 3 + 2] = value;
|
|
925
|
+
break;
|
|
926
|
+
case 'nx':
|
|
927
|
+
attributes.normals[vertexIndex * 3] = value;
|
|
928
|
+
break;
|
|
929
|
+
case 'ny':
|
|
930
|
+
attributes.normals[vertexIndex * 3 + 1] = value;
|
|
931
|
+
break;
|
|
932
|
+
case 'nz':
|
|
933
|
+
attributes.normals[vertexIndex * 3 + 2] = value;
|
|
934
|
+
break;
|
|
935
|
+
case 's':
|
|
936
|
+
attributes.uvs[vertexIndex * 2] = value;
|
|
937
|
+
break;
|
|
938
|
+
case 't':
|
|
939
|
+
attributes.uvs[vertexIndex * 2 + 1] = value;
|
|
940
|
+
break;
|
|
941
|
+
case 'red':
|
|
942
|
+
attributes.colors[vertexIndex * 3] = value;
|
|
943
|
+
break;
|
|
944
|
+
case 'green':
|
|
945
|
+
attributes.colors[vertexIndex * 3 + 1] = value;
|
|
946
|
+
break;
|
|
947
|
+
case 'blue':
|
|
948
|
+
attributes.colors[vertexIndex * 3 + 2] = value;
|
|
949
|
+
break;
|
|
950
|
+
default:
|
|
951
|
+
attributes[propertyName][vertexIndex] = value;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/** Return binary property descriptors with precomputed offsets and readers. */
|
|
956
|
+
function getBinaryPointCloudProperties(element: PLYElement): BinaryPointCloudProperty[] {
|
|
957
|
+
const properties: BinaryPointCloudProperty[] = [];
|
|
958
|
+
let offset = 0;
|
|
959
|
+
|
|
960
|
+
for (const property of element.properties) {
|
|
961
|
+
properties.push({
|
|
962
|
+
name: property.name,
|
|
963
|
+
offset,
|
|
964
|
+
read: getBinaryScalarReader(property.type),
|
|
965
|
+
size: getPLYTypeSize(property.type)
|
|
966
|
+
});
|
|
967
|
+
offset += properties[properties.length - 1].size;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
return properties;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/** Return the byte size of a scalar PLY element. */
|
|
974
|
+
function getPLYElementSize(properties: BinaryPointCloudProperty[]): number {
|
|
975
|
+
if (properties.length === 0) {
|
|
976
|
+
return 0;
|
|
977
|
+
}
|
|
978
|
+
const lastProperty = properties[properties.length - 1];
|
|
979
|
+
return lastProperty.offset + lastProperty.size;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
/** Return the byte size of a scalar PLY type. */
|
|
983
|
+
// eslint-disable-next-line complexity
|
|
984
|
+
function getPLYTypeSize(type: string): number {
|
|
985
|
+
switch (type) {
|
|
986
|
+
case 'int8':
|
|
987
|
+
case 'uint8':
|
|
988
|
+
case 'char':
|
|
989
|
+
case 'uchar':
|
|
990
|
+
return 1;
|
|
991
|
+
case 'int16':
|
|
992
|
+
case 'uint16':
|
|
993
|
+
case 'short':
|
|
994
|
+
case 'ushort':
|
|
995
|
+
return 2;
|
|
996
|
+
case 'int32':
|
|
997
|
+
case 'uint32':
|
|
998
|
+
case 'int':
|
|
999
|
+
case 'uint':
|
|
1000
|
+
case 'float32':
|
|
1001
|
+
case 'float':
|
|
1002
|
+
return 4;
|
|
1003
|
+
case 'float64':
|
|
1004
|
+
case 'double':
|
|
1005
|
+
return 8;
|
|
1006
|
+
default:
|
|
1007
|
+
throw new Error(type);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/** Return one scalar PLY value reader. */
|
|
1012
|
+
// eslint-disable-next-line complexity
|
|
1013
|
+
function getBinaryScalarReader(
|
|
1014
|
+
type: string
|
|
1015
|
+
): (dataView: DataView, at: number, littleEndian: boolean) => number {
|
|
1016
|
+
switch (type) {
|
|
1017
|
+
case 'int8':
|
|
1018
|
+
case 'char':
|
|
1019
|
+
return readInt8;
|
|
1020
|
+
case 'uint8':
|
|
1021
|
+
case 'uchar':
|
|
1022
|
+
return readUint8;
|
|
1023
|
+
case 'int16':
|
|
1024
|
+
case 'short':
|
|
1025
|
+
return readInt16;
|
|
1026
|
+
case 'uint16':
|
|
1027
|
+
case 'ushort':
|
|
1028
|
+
return readUint16;
|
|
1029
|
+
case 'int32':
|
|
1030
|
+
case 'int':
|
|
1031
|
+
return readInt32;
|
|
1032
|
+
case 'uint32':
|
|
1033
|
+
case 'uint':
|
|
1034
|
+
return readUint32;
|
|
1035
|
+
case 'float32':
|
|
1036
|
+
case 'float':
|
|
1037
|
+
return readFloat32;
|
|
1038
|
+
case 'float64':
|
|
1039
|
+
case 'double':
|
|
1040
|
+
return readFloat64;
|
|
1041
|
+
default:
|
|
1042
|
+
throw new Error(type);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/** Read one signed 8-bit integer. */
|
|
1047
|
+
function readInt8(dataView: DataView, at: number): number {
|
|
1048
|
+
return dataView.getInt8(at);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
/** Read one unsigned 8-bit integer. */
|
|
1052
|
+
function readUint8(dataView: DataView, at: number): number {
|
|
1053
|
+
return dataView.getUint8(at);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
/** Read one signed 16-bit integer. */
|
|
1057
|
+
function readInt16(dataView: DataView, at: number, littleEndian: boolean): number {
|
|
1058
|
+
return dataView.getInt16(at, littleEndian);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/** Read one unsigned 16-bit integer. */
|
|
1062
|
+
function readUint16(dataView: DataView, at: number, littleEndian: boolean): number {
|
|
1063
|
+
return dataView.getUint16(at, littleEndian);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/** Read one signed 32-bit integer. */
|
|
1067
|
+
function readInt32(dataView: DataView, at: number, littleEndian: boolean): number {
|
|
1068
|
+
return dataView.getInt32(at, littleEndian);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/** Read one unsigned 32-bit integer. */
|
|
1072
|
+
function readUint32(dataView: DataView, at: number, littleEndian: boolean): number {
|
|
1073
|
+
return dataView.getUint32(at, littleEndian);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
/** Read one 32-bit float. */
|
|
1077
|
+
function readFloat32(dataView: DataView, at: number, littleEndian: boolean): number {
|
|
1078
|
+
return dataView.getFloat32(at, littleEndian);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/** Read one 64-bit float. */
|
|
1082
|
+
function readFloat64(dataView: DataView, at: number, littleEndian: boolean): number {
|
|
1083
|
+
return dataView.getFloat64(at, littleEndian);
|
|
1084
|
+
}
|