sdl-mcp 0.12.2 → 0.12.3
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/README.md +10 -0
- package/config/sdlmcp.config.example.json +53 -8
- package/config/sdlmcp.config.schema.json +530 -106
- package/dist/.tsbuildinfo +1 -1
- package/dist/benchmark/external-manifest.d.ts +162 -0
- package/dist/benchmark/external-manifest.d.ts.map +1 -0
- package/dist/benchmark/external-manifest.js +336 -0
- package/dist/benchmark/external-manifest.js.map +1 -0
- package/dist/benchmark/external-runner.d.ts +100 -0
- package/dist/benchmark/external-runner.d.ts.map +1 -0
- package/dist/benchmark/external-runner.js +1171 -0
- package/dist/benchmark/external-runner.js.map +1 -0
- package/dist/benchmark/output-file.d.ts +3 -0
- package/dist/benchmark/output-file.d.ts.map +1 -0
- package/dist/benchmark/output-file.js +8 -0
- package/dist/benchmark/output-file.js.map +1 -0
- package/dist/cli/argParsing.d.ts.map +1 -1
- package/dist/cli/argParsing.js +6 -0
- package/dist/cli/argParsing.js.map +1 -1
- package/dist/cli/commands/benchmark.d.ts.map +1 -1
- package/dist/cli/commands/benchmark.js +3 -2
- package/dist/cli/commands/benchmark.js.map +1 -1
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +13 -7
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +5 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +73 -3
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +2 -0
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/transport/http.d.ts +1 -35
- package/dist/cli/transport/http.d.ts.map +1 -1
- package/dist/cli/transport/http.js +151 -175
- package/dist/cli/transport/http.js.map +1 -1
- package/dist/cli/types.d.ts +1 -0
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/config/constants.d.ts +30 -0
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +30 -0
- package/dist/config/constants.js.map +1 -1
- package/dist/config/types.d.ts +53 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +62 -14
- package/dist/config/types.js.map +1 -1
- package/dist/db/ladybug-batching.d.ts +1 -0
- package/dist/db/ladybug-batching.d.ts.map +1 -1
- package/dist/db/ladybug-batching.js +1 -0
- package/dist/db/ladybug-batching.js.map +1 -1
- package/dist/db/ladybug-core.d.ts +3 -0
- package/dist/db/ladybug-core.d.ts.map +1 -1
- package/dist/db/ladybug-core.js +72 -2
- package/dist/db/ladybug-core.js.map +1 -1
- package/dist/db/ladybug-embeddings.d.ts +6 -1
- package/dist/db/ladybug-embeddings.d.ts.map +1 -1
- package/dist/db/ladybug-embeddings.js +6 -1
- package/dist/db/ladybug-embeddings.js.map +1 -1
- package/dist/db/ladybug-file-summaries.d.ts.map +1 -1
- package/dist/db/ladybug-file-summaries.js +23 -0
- package/dist/db/ladybug-file-summaries.js.map +1 -1
- package/dist/db/ladybug-queries.js +1 -1
- package/dist/db/ladybug-queries.js.map +1 -1
- package/dist/db/migrations/index.d.ts.map +1 -1
- package/dist/db/migrations/index.js +2 -0
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts +5 -9
- package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts.map +1 -1
- package/dist/db/migrations/m007-copy-embeddings-to-symbol.js +24 -126
- package/dist/db/migrations/m007-copy-embeddings-to-symbol.js.map +1 -1
- package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts +5 -0
- package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts.map +1 -0
- package/dist/db/migrations/m021-remediate-symbol-embeddings.js +7 -0
- package/dist/db/migrations/m021-remediate-symbol-embeddings.js.map +1 -0
- package/dist/db/migrations/symbol-embedding-remediation.d.ts +57 -0
- package/dist/db/migrations/symbol-embedding-remediation.d.ts.map +1 -0
- package/dist/db/migrations/symbol-embedding-remediation.js +335 -0
- package/dist/db/migrations/symbol-embedding-remediation.js.map +1 -0
- package/dist/graph/layout/force-layout.d.ts +4 -0
- package/dist/graph/layout/force-layout.d.ts.map +1 -0
- package/dist/graph/layout/force-layout.js +127 -0
- package/dist/graph/layout/force-layout.js.map +1 -0
- package/dist/graph/layout/layout-service.d.ts +37 -0
- package/dist/graph/layout/layout-service.d.ts.map +1 -0
- package/dist/graph/layout/layout-service.js +172 -0
- package/dist/graph/layout/layout-service.js.map +1 -0
- package/dist/graph/layout/native-engine.d.ts +9 -0
- package/dist/graph/layout/native-engine.d.ts.map +1 -0
- package/dist/graph/layout/native-engine.js +59 -0
- package/dist/graph/layout/native-engine.js.map +1 -0
- package/dist/graph/layout/prng.d.ts +3 -0
- package/dist/graph/layout/prng.d.ts.map +1 -0
- package/dist/graph/layout/prng.js +19 -0
- package/dist/graph/layout/prng.js.map +1 -0
- package/dist/graph/layout/serializer.d.ts +3 -0
- package/dist/graph/layout/serializer.d.ts.map +1 -0
- package/dist/graph/layout/serializer.js +20 -0
- package/dist/graph/layout/serializer.js.map +1 -0
- package/dist/graph/layout/types.d.ts +30 -0
- package/dist/graph/layout/types.d.ts.map +1 -0
- package/dist/graph/layout/types.js +2 -0
- package/dist/graph/layout/types.js.map +1 -0
- package/dist/indexer/embeddings.d.ts +7 -0
- package/dist/indexer/embeddings.d.ts.map +1 -1
- package/dist/indexer/embeddings.js +44 -4
- package/dist/indexer/embeddings.js.map +1 -1
- package/dist/indexer/file-summary-embeddings.d.ts +12 -0
- package/dist/indexer/file-summary-embeddings.d.ts.map +1 -1
- package/dist/indexer/file-summary-embeddings.js +83 -21
- package/dist/indexer/file-summary-embeddings.js.map +1 -1
- package/dist/indexer/fileWalker.d.ts.map +1 -1
- package/dist/indexer/fileWalker.js +2 -1
- package/dist/indexer/fileWalker.js.map +1 -1
- package/dist/indexer/metrics-updater.d.ts.map +1 -1
- package/dist/indexer/metrics-updater.js +27 -4
- package/dist/indexer/metrics-updater.js.map +1 -1
- package/dist/indexer/watcher.d.ts.map +1 -1
- package/dist/indexer/watcher.js +2 -1
- package/dist/indexer/watcher.js.map +1 -1
- package/dist/mcp/context-response-projection.d.ts.map +1 -1
- package/dist/mcp/context-response-projection.js +49 -13
- package/dist/mcp/context-response-projection.js.map +1 -1
- package/dist/mcp/tools/search-edit/planner.d.ts.map +1 -1
- package/dist/mcp/tools/search-edit/planner.js +10 -3
- package/dist/mcp/tools/search-edit/planner.js.map +1 -1
- package/dist/observability/event-tap.d.ts +2 -1
- package/dist/observability/event-tap.d.ts.map +1 -1
- package/dist/observability/event-tap.js.map +1 -1
- package/dist/observability/service.d.ts +11 -4
- package/dist/observability/service.d.ts.map +1 -1
- package/dist/observability/service.js +83 -13
- package/dist/observability/service.js.map +1 -1
- package/dist/observability/types.d.ts +48 -2
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/ui/.tsbuildinfo +1 -0
- package/dist/ui/vendor/fflate.js +2692 -0
- package/dist/ui/vendor/jsm/controls/ArcballControls.js +3543 -0
- package/dist/ui/vendor/jsm/controls/DragControls.js +452 -0
- package/dist/ui/vendor/jsm/controls/FirstPersonControls.js +488 -0
- package/dist/ui/vendor/jsm/controls/FlyControls.js +384 -0
- package/dist/ui/vendor/jsm/controls/MapControls.js +116 -0
- package/dist/ui/vendor/jsm/controls/OrbitControls.js +1963 -0
- package/dist/ui/vendor/jsm/controls/PointerLockControls.js +264 -0
- package/dist/ui/vendor/jsm/controls/TrackballControls.js +1001 -0
- package/dist/ui/vendor/jsm/controls/TransformControls.js +2003 -0
- package/dist/ui/vendor/jsm/loaders/3DMLoader.js +1836 -0
- package/dist/ui/vendor/jsm/loaders/3MFLoader.js +1621 -0
- package/dist/ui/vendor/jsm/loaders/AMFLoader.js +541 -0
- package/dist/ui/vendor/jsm/loaders/BVHLoader.js +484 -0
- package/dist/ui/vendor/jsm/loaders/ColladaLoader.js +153 -0
- package/dist/ui/vendor/jsm/loaders/DDSLoader.js +385 -0
- package/dist/ui/vendor/jsm/loaders/DRACOLoader.js +772 -0
- package/dist/ui/vendor/jsm/loaders/EXRLoader.js +3395 -0
- package/dist/ui/vendor/jsm/loaders/FBXLoader.js +4580 -0
- package/dist/ui/vendor/jsm/loaders/FontLoader.js +260 -0
- package/dist/ui/vendor/jsm/loaders/GCodeLoader.js +318 -0
- package/dist/ui/vendor/jsm/loaders/GLTFLoader.js +4860 -0
- package/dist/ui/vendor/jsm/loaders/HDRCubeTextureLoader.js +164 -0
- package/dist/ui/vendor/jsm/loaders/HDRLoader.js +463 -0
- package/dist/ui/vendor/jsm/loaders/IESLoader.js +379 -0
- package/dist/ui/vendor/jsm/loaders/KMZLoader.js +163 -0
- package/dist/ui/vendor/jsm/loaders/KTX2Loader.js +1276 -0
- package/dist/ui/vendor/jsm/loaders/KTXLoader.js +197 -0
- package/dist/ui/vendor/jsm/loaders/LDrawLoader.js +2510 -0
- package/dist/ui/vendor/jsm/loaders/LUT3dlLoader.js +205 -0
- package/dist/ui/vendor/jsm/loaders/LUTCubeLoader.js +190 -0
- package/dist/ui/vendor/jsm/loaders/LUTImageLoader.js +190 -0
- package/dist/ui/vendor/jsm/loaders/LWOLoader.js +1051 -0
- package/dist/ui/vendor/jsm/loaders/LottieLoader.js +130 -0
- package/dist/ui/vendor/jsm/loaders/MD2Loader.js +435 -0
- package/dist/ui/vendor/jsm/loaders/MDDLoader.js +147 -0
- package/dist/ui/vendor/jsm/loaders/MTLLoader.js +593 -0
- package/dist/ui/vendor/jsm/loaders/MaterialXLoader.js +1126 -0
- package/dist/ui/vendor/jsm/loaders/NRRDLoader.js +718 -0
- package/dist/ui/vendor/jsm/loaders/OBJLoader.js +955 -0
- package/dist/ui/vendor/jsm/loaders/PCDLoader.js +620 -0
- package/dist/ui/vendor/jsm/loaders/PDBLoader.js +272 -0
- package/dist/ui/vendor/jsm/loaders/PLYLoader.js +968 -0
- package/dist/ui/vendor/jsm/loaders/PVRLoader.js +270 -0
- package/dist/ui/vendor/jsm/loaders/RGBELoader.js +18 -0
- package/dist/ui/vendor/jsm/loaders/STLLoader.js +421 -0
- package/dist/ui/vendor/jsm/loaders/SVGLoader.js +3319 -0
- package/dist/ui/vendor/jsm/loaders/TDSLoader.js +1142 -0
- package/dist/ui/vendor/jsm/loaders/TGALoader.js +538 -0
- package/dist/ui/vendor/jsm/loaders/TIFFLoader.js +59 -0
- package/dist/ui/vendor/jsm/loaders/TTFLoader.js +261 -0
- package/dist/ui/vendor/jsm/loaders/USDLoader.js +303 -0
- package/dist/ui/vendor/jsm/loaders/USDZLoader.js +16 -0
- package/dist/ui/vendor/jsm/loaders/UltraHDRLoader.js +755 -0
- package/dist/ui/vendor/jsm/loaders/VOXLoader.js +919 -0
- package/dist/ui/vendor/jsm/loaders/VRMLLoader.js +3646 -0
- package/dist/ui/vendor/jsm/loaders/VTKLoader.js +1293 -0
- package/dist/ui/vendor/jsm/loaders/XYZLoader.js +143 -0
- package/dist/ui/vendor/jsm/loaders/collada/ColladaComposer.js +3044 -0
- package/dist/ui/vendor/jsm/loaders/collada/ColladaParser.js +1977 -0
- package/dist/ui/vendor/jsm/loaders/lwo/IFFParser.js +1217 -0
- package/dist/ui/vendor/jsm/loaders/lwo/LWO2Parser.js +414 -0
- package/dist/ui/vendor/jsm/loaders/lwo/LWO3Parser.js +373 -0
- package/dist/ui/vendor/jsm/loaders/usd/USDAParser.js +901 -0
- package/dist/ui/vendor/jsm/loaders/usd/USDCParser.js +1878 -0
- package/dist/ui/vendor/jsm/loaders/usd/USDComposer.js +4627 -0
- package/dist/ui/vendor/jsm/utils/BufferGeometryUtils.js +1501 -0
- package/dist/ui/vendor/jsm/utils/CameraUtils.js +82 -0
- package/dist/ui/vendor/jsm/utils/ColorUtils.js +76 -0
- package/dist/ui/vendor/jsm/utils/GeometryCompressionUtils.js +547 -0
- package/dist/ui/vendor/jsm/utils/GeometryUtils.js +226 -0
- package/dist/ui/vendor/jsm/utils/LDrawUtils.js +211 -0
- package/dist/ui/vendor/jsm/utils/SceneOptimizer.js +458 -0
- package/dist/ui/vendor/jsm/utils/SceneUtils.js +363 -0
- package/dist/ui/vendor/jsm/utils/ShadowMapViewer.js +244 -0
- package/dist/ui/vendor/jsm/utils/ShadowMapViewerGPU.js +233 -0
- package/dist/ui/vendor/jsm/utils/SkeletonUtils.js +496 -0
- package/dist/ui/vendor/jsm/utils/SortUtils.js +175 -0
- package/dist/ui/vendor/jsm/utils/UVsDebug.js +173 -0
- package/dist/ui/vendor/jsm/utils/WebGLTextureUtils.js +115 -0
- package/dist/ui/vendor/jsm/utils/WebGPUTextureUtils.js +81 -0
- package/dist/ui/vendor/jsm/utils/WorkerPool.js +167 -0
- package/dist/ui/vendor/three.core.min.js +6 -0
- package/dist/ui/vendor/three.module.min.js +6 -0
- package/dist/ui/viewer/ambient.js +39 -0
- package/dist/ui/viewer/api.js +93 -0
- package/dist/ui/viewer/chrome.js +36 -0
- package/dist/ui/viewer/edges.js +33 -0
- package/dist/ui/viewer/index.html +32 -0
- package/dist/ui/viewer/inspector.js +23 -0
- package/dist/ui/viewer/lenses/activity.js +24 -0
- package/dist/ui/viewer/lenses/community.js +5 -0
- package/dist/ui/viewer/lenses/edges.js +4 -0
- package/dist/ui/viewer/lenses/impact.js +6 -0
- package/dist/ui/viewer/lenses/search.js +69 -0
- package/dist/ui/viewer/lod.js +100 -0
- package/dist/ui/viewer/main.js +92 -0
- package/dist/ui/viewer/picking.js +45 -0
- package/dist/ui/viewer/scene.js +85 -0
- package/dist/ui/viewer/skins/default-skin.js +15 -0
- package/dist/ui/viewer/skins/loader.js +44 -0
- package/dist/ui/viewer/skins/manifest-schema.js +30 -0
- package/dist/ui/viewer/state.js +44 -0
- package/dist/ui/viewer/theme.js +23 -0
- package/dist/ui/viewer/universe.js +151 -0
- package/dist/ui/viewer/viewer.css +85 -0
- package/dist/util/safeRegex.d.ts.map +1 -1
- package/dist/util/safeRegex.js +221 -68
- package/dist/util/safeRegex.js.map +1 -1
- package/dist/viewer/legacy-graph.d.ts +40 -0
- package/dist/viewer/legacy-graph.d.ts.map +1 -0
- package/dist/viewer/legacy-graph.js +152 -0
- package/dist/viewer/legacy-graph.js.map +1 -0
- package/dist/viewer/routes.d.ts +10 -0
- package/dist/viewer/routes.d.ts.map +1 -0
- package/dist/viewer/routes.js +221 -0
- package/dist/viewer/routes.js.map +1 -0
- package/dist/viewer/service.d.ts +44 -0
- package/dist/viewer/service.d.ts.map +1 -0
- package/dist/viewer/service.js +160 -0
- package/dist/viewer/service.js.map +1 -0
- package/dist/viewer/types.d.ts +63 -0
- package/dist/viewer/types.d.ts.map +1 -0
- package/dist/viewer/types.js +2 -0
- package/dist/viewer/types.js.map +1 -0
- package/dist/viewer/viewer-config.d.ts +12 -0
- package/dist/viewer/viewer-config.d.ts.map +1 -0
- package/dist/viewer/viewer-config.js +36 -0
- package/dist/viewer/viewer-config.js.map +1 -0
- package/package.json +18 -9
- package/templates/SDL.md +19 -0
- package/templates/claude-code.json +8 -43
- package/dist/ui/graph.css +0 -108
- package/dist/ui/graph.d.ts +0 -2
- package/dist/ui/graph.d.ts.map +0 -1
- package/dist/ui/graph.html +0 -52
- package/dist/ui/graph.js +0 -259
- package/dist/ui/graph.js.map +0 -1
|
@@ -0,0 +1,968 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BufferGeometry,
|
|
3
|
+
FileLoader,
|
|
4
|
+
BufferAttribute,
|
|
5
|
+
Float32BufferAttribute,
|
|
6
|
+
Int8BufferAttribute,
|
|
7
|
+
Int16BufferAttribute,
|
|
8
|
+
Int32BufferAttribute,
|
|
9
|
+
Loader,
|
|
10
|
+
Uint8BufferAttribute,
|
|
11
|
+
Uint16BufferAttribute,
|
|
12
|
+
Uint32BufferAttribute,
|
|
13
|
+
Color,
|
|
14
|
+
SRGBColorSpace
|
|
15
|
+
} from 'three';
|
|
16
|
+
|
|
17
|
+
const _color = new Color();
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A loader for PLY the PLY format (known as the Polygon
|
|
21
|
+
* File Format or the Stanford Triangle Format).
|
|
22
|
+
*
|
|
23
|
+
* Limitations:
|
|
24
|
+
* - ASCII decoding assumes file is UTF-8.
|
|
25
|
+
*
|
|
26
|
+
* ```js
|
|
27
|
+
* const loader = new PLYLoader();
|
|
28
|
+
* const geometry = await loader.loadAsync( './models/ply/ascii/dolphins.ply' );
|
|
29
|
+
* scene.add( new THREE.Mesh( geometry ) );
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @augments Loader
|
|
33
|
+
* @three_import import { PLYLoader } from 'three/addons/loaders/PLYLoader.js';
|
|
34
|
+
*/
|
|
35
|
+
class PLYLoader extends Loader {
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Constructs a new PLY loader.
|
|
39
|
+
*
|
|
40
|
+
* @param {LoadingManager} [manager] - The loading manager.
|
|
41
|
+
*/
|
|
42
|
+
constructor( manager ) {
|
|
43
|
+
|
|
44
|
+
super( manager );
|
|
45
|
+
|
|
46
|
+
// internals
|
|
47
|
+
|
|
48
|
+
this.propertyNameMapping = {};
|
|
49
|
+
this.customPropertyMapping = {};
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Starts loading from the given URL and passes the loaded PLY asset
|
|
55
|
+
* to the `onLoad()` callback.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
|
|
58
|
+
* @param {function(BufferGeometry)} onLoad - Executed when the loading process has been finished.
|
|
59
|
+
* @param {onProgressCallback} onProgress - Executed while the loading is in progress.
|
|
60
|
+
* @param {onErrorCallback} onError - Executed when errors occur.
|
|
61
|
+
*/
|
|
62
|
+
load( url, onLoad, onProgress, onError ) {
|
|
63
|
+
|
|
64
|
+
const scope = this;
|
|
65
|
+
|
|
66
|
+
const loader = new FileLoader( this.manager );
|
|
67
|
+
loader.setPath( this.path );
|
|
68
|
+
loader.setResponseType( 'arraybuffer' );
|
|
69
|
+
loader.setRequestHeader( this.requestHeader );
|
|
70
|
+
loader.setWithCredentials( this.withCredentials );
|
|
71
|
+
loader.load( url, function ( text ) {
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
|
|
75
|
+
onLoad( scope.parse( text ) );
|
|
76
|
+
|
|
77
|
+
} catch ( e ) {
|
|
78
|
+
|
|
79
|
+
if ( onError ) {
|
|
80
|
+
|
|
81
|
+
onError( e );
|
|
82
|
+
|
|
83
|
+
} else {
|
|
84
|
+
|
|
85
|
+
console.error( e );
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
scope.manager.itemError( url );
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
}, onProgress, onError );
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Sets a property name mapping that maps default property names
|
|
99
|
+
* to custom ones. For example, the following maps the properties
|
|
100
|
+
* “diffuse_(red|green|blue)” in the file to standard color names.
|
|
101
|
+
*
|
|
102
|
+
* ```js
|
|
103
|
+
* loader.setPropertyNameMapping( {
|
|
104
|
+
* diffuse_red: 'red',
|
|
105
|
+
* diffuse_green: 'green',
|
|
106
|
+
* diffuse_blue: 'blue'
|
|
107
|
+
* } );
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @param {Object} mapping - The mapping dictionary.
|
|
111
|
+
*/
|
|
112
|
+
setPropertyNameMapping( mapping ) {
|
|
113
|
+
|
|
114
|
+
this.propertyNameMapping = mapping;
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Custom properties outside of the defaults for position, uv, normal
|
|
120
|
+
* and color attributes can be added using the setCustomPropertyNameMapping method.
|
|
121
|
+
* For example, the following maps the element properties “custom_property_a”
|
|
122
|
+
* and “custom_property_b” to an attribute “customAttribute” with an item size of 2.
|
|
123
|
+
* Attribute item sizes are set from the number of element properties in the property array.
|
|
124
|
+
*
|
|
125
|
+
* ```js
|
|
126
|
+
* loader.setCustomPropertyNameMapping( {
|
|
127
|
+
* customAttribute: ['custom_property_a', 'custom_property_b'],
|
|
128
|
+
* } );
|
|
129
|
+
* ```
|
|
130
|
+
* @param {Object} mapping - The mapping dictionary.
|
|
131
|
+
*/
|
|
132
|
+
setCustomPropertyNameMapping( mapping ) {
|
|
133
|
+
|
|
134
|
+
this.customPropertyMapping = mapping;
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Parses the given PLY data and returns the resulting geometry.
|
|
140
|
+
*
|
|
141
|
+
* @param {ArrayBuffer} data - The raw PLY data as an array buffer.
|
|
142
|
+
* @return {BufferGeometry} The parsed geometry.
|
|
143
|
+
*/
|
|
144
|
+
parse( data ) {
|
|
145
|
+
|
|
146
|
+
function parseHeader( data, headerLength = 0 ) {
|
|
147
|
+
|
|
148
|
+
const patternHeader = /^ply([\s\S]*)end_header(\r\n|\r|\n)/;
|
|
149
|
+
let headerText = '';
|
|
150
|
+
const result = patternHeader.exec( data );
|
|
151
|
+
|
|
152
|
+
if ( result !== null ) {
|
|
153
|
+
|
|
154
|
+
headerText = result[ 1 ];
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const header = {
|
|
159
|
+
comments: [],
|
|
160
|
+
elements: [],
|
|
161
|
+
headerLength: headerLength,
|
|
162
|
+
objInfo: ''
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const lines = headerText.split( /\r\n|\r|\n/ );
|
|
166
|
+
let currentElement;
|
|
167
|
+
|
|
168
|
+
function make_ply_element_property( propertyValues, propertyNameMapping ) {
|
|
169
|
+
|
|
170
|
+
const property = { type: propertyValues[ 0 ] };
|
|
171
|
+
|
|
172
|
+
if ( property.type === 'list' ) {
|
|
173
|
+
|
|
174
|
+
property.name = propertyValues[ 3 ];
|
|
175
|
+
property.countType = propertyValues[ 1 ];
|
|
176
|
+
property.itemType = propertyValues[ 2 ];
|
|
177
|
+
|
|
178
|
+
} else {
|
|
179
|
+
|
|
180
|
+
property.name = propertyValues[ 1 ];
|
|
181
|
+
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if ( property.name in propertyNameMapping ) {
|
|
185
|
+
|
|
186
|
+
property.name = propertyNameMapping[ property.name ];
|
|
187
|
+
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return property;
|
|
191
|
+
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for ( let i = 0; i < lines.length; i ++ ) {
|
|
195
|
+
|
|
196
|
+
let line = lines[ i ];
|
|
197
|
+
line = line.trim();
|
|
198
|
+
|
|
199
|
+
if ( line === '' ) continue;
|
|
200
|
+
|
|
201
|
+
const lineValues = line.split( /\s+/ );
|
|
202
|
+
const lineType = lineValues.shift();
|
|
203
|
+
line = lineValues.join( ' ' );
|
|
204
|
+
|
|
205
|
+
switch ( lineType ) {
|
|
206
|
+
|
|
207
|
+
case 'format':
|
|
208
|
+
|
|
209
|
+
header.format = lineValues[ 0 ];
|
|
210
|
+
header.version = lineValues[ 1 ];
|
|
211
|
+
|
|
212
|
+
break;
|
|
213
|
+
|
|
214
|
+
case 'comment':
|
|
215
|
+
|
|
216
|
+
header.comments.push( line );
|
|
217
|
+
|
|
218
|
+
break;
|
|
219
|
+
|
|
220
|
+
case 'element':
|
|
221
|
+
|
|
222
|
+
if ( currentElement !== undefined ) {
|
|
223
|
+
|
|
224
|
+
header.elements.push( currentElement );
|
|
225
|
+
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
currentElement = {};
|
|
229
|
+
currentElement.name = lineValues[ 0 ];
|
|
230
|
+
currentElement.count = parseInt( lineValues[ 1 ] );
|
|
231
|
+
currentElement.properties = [];
|
|
232
|
+
|
|
233
|
+
break;
|
|
234
|
+
|
|
235
|
+
case 'property':
|
|
236
|
+
|
|
237
|
+
currentElement.properties.push( make_ply_element_property( lineValues, scope.propertyNameMapping ) );
|
|
238
|
+
|
|
239
|
+
break;
|
|
240
|
+
|
|
241
|
+
case 'obj_info':
|
|
242
|
+
|
|
243
|
+
header.objInfo = line;
|
|
244
|
+
|
|
245
|
+
break;
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
default:
|
|
249
|
+
|
|
250
|
+
console.log( 'unhandled', lineType, lineValues );
|
|
251
|
+
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if ( currentElement !== undefined ) {
|
|
257
|
+
|
|
258
|
+
header.elements.push( currentElement );
|
|
259
|
+
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return header;
|
|
263
|
+
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function parseASCIINumber( n, type ) {
|
|
267
|
+
|
|
268
|
+
switch ( type ) {
|
|
269
|
+
|
|
270
|
+
case 'char': case 'uchar': case 'short': case 'ushort': case 'int': case 'uint':
|
|
271
|
+
case 'int8': case 'uint8': case 'int16': case 'uint16': case 'int32': case 'uint32':
|
|
272
|
+
|
|
273
|
+
return parseInt( n );
|
|
274
|
+
|
|
275
|
+
case 'float': case 'double': case 'float32': case 'float64':
|
|
276
|
+
|
|
277
|
+
return parseFloat( n );
|
|
278
|
+
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function parseASCIIElement( properties, tokens ) {
|
|
284
|
+
|
|
285
|
+
const element = {};
|
|
286
|
+
|
|
287
|
+
for ( let i = 0; i < properties.length; i ++ ) {
|
|
288
|
+
|
|
289
|
+
if ( tokens.empty() ) return null;
|
|
290
|
+
|
|
291
|
+
if ( properties[ i ].type === 'list' ) {
|
|
292
|
+
|
|
293
|
+
const list = [];
|
|
294
|
+
const n = parseASCIINumber( tokens.next(), properties[ i ].countType );
|
|
295
|
+
|
|
296
|
+
for ( let j = 0; j < n; j ++ ) {
|
|
297
|
+
|
|
298
|
+
if ( tokens.empty() ) return null;
|
|
299
|
+
|
|
300
|
+
list.push( parseASCIINumber( tokens.next(), properties[ i ].itemType ) );
|
|
301
|
+
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
element[ properties[ i ].name ] = list;
|
|
305
|
+
|
|
306
|
+
} else {
|
|
307
|
+
|
|
308
|
+
element[ properties[ i ].name ] = parseASCIINumber( tokens.next(), properties[ i ].type );
|
|
309
|
+
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return element;
|
|
315
|
+
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function createBuffer() {
|
|
319
|
+
|
|
320
|
+
const buffer = {
|
|
321
|
+
indices: [],
|
|
322
|
+
vertices: [],
|
|
323
|
+
normals: [],
|
|
324
|
+
uvs: [],
|
|
325
|
+
faceVertexUvs: [],
|
|
326
|
+
colors: [],
|
|
327
|
+
faceVertexColors: [],
|
|
328
|
+
descriptors: {}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) {
|
|
332
|
+
|
|
333
|
+
buffer[ customProperty ] = [];
|
|
334
|
+
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return buffer;
|
|
338
|
+
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
function getBufferAttributeClass( type ) {
|
|
343
|
+
|
|
344
|
+
switch ( type ) {
|
|
345
|
+
|
|
346
|
+
case 'int8': case 'char': return Int8BufferAttribute;
|
|
347
|
+
case 'uint8': case 'uchar': return Uint8BufferAttribute;
|
|
348
|
+
case 'int16': case 'short': return Int16BufferAttribute;
|
|
349
|
+
case 'uint16': case 'ushort': return Uint16BufferAttribute;
|
|
350
|
+
case 'int32': case 'int': return Int32BufferAttribute;
|
|
351
|
+
case 'uint32': case 'uint': return Uint32BufferAttribute;
|
|
352
|
+
case 'float32': case 'float': return Float32BufferAttribute;
|
|
353
|
+
case 'float64': case 'double': return Float64BufferAttribute;
|
|
354
|
+
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function getColorScale( type ) {
|
|
360
|
+
|
|
361
|
+
switch ( type ) {
|
|
362
|
+
|
|
363
|
+
case 'uchar': case 'uint8': return 1 / 255;
|
|
364
|
+
case 'ushort': case 'uint16': return 1 / 65535;
|
|
365
|
+
case 'float': case 'float32':
|
|
366
|
+
case 'double': case 'float64': return 1;
|
|
367
|
+
default: return 1 / 255;
|
|
368
|
+
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function isFloatType( type ) {
|
|
374
|
+
|
|
375
|
+
return type === 'float' || type === 'float32' || type === 'double' || type === 'float64';
|
|
376
|
+
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function getAttributeDescriptor( properties ) {
|
|
380
|
+
|
|
381
|
+
function findProperty( names ) {
|
|
382
|
+
|
|
383
|
+
for ( const name of names ) {
|
|
384
|
+
|
|
385
|
+
const property = properties.find( p => p.name === name );
|
|
386
|
+
if ( property ) return property;
|
|
387
|
+
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return null;
|
|
391
|
+
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// property lookup
|
|
395
|
+
|
|
396
|
+
const x = findProperty( [ 'x', 'px', 'posx' ] );
|
|
397
|
+
const y = findProperty( [ 'y', 'py', 'posy' ] );
|
|
398
|
+
const z = findProperty( [ 'z', 'pz', 'posz' ] );
|
|
399
|
+
const nx = findProperty( [ 'nx', 'normalx' ] );
|
|
400
|
+
const ny = findProperty( [ 'ny', 'normaly' ] );
|
|
401
|
+
const nz = findProperty( [ 'nz', 'normalz' ] );
|
|
402
|
+
const s = findProperty( [ 's', 'u', 'texture_u', 'tx' ] );
|
|
403
|
+
const t = findProperty( [ 't', 'v', 'texture_v', 'ty' ] );
|
|
404
|
+
const r = findProperty( [ 'red', 'diffuse_red', 'r', 'diffuse_r' ] );
|
|
405
|
+
const g = findProperty( [ 'green', 'diffuse_green', 'g', 'diffuse_g' ] );
|
|
406
|
+
const b = findProperty( [ 'blue', 'diffuse_blue', 'b', 'diffuse_b' ] );
|
|
407
|
+
const texcoord = findProperty( [ 'texcoord' ] );
|
|
408
|
+
|
|
409
|
+
// custom property lookup
|
|
410
|
+
|
|
411
|
+
const custom = {};
|
|
412
|
+
|
|
413
|
+
for ( const customAttr of Object.keys( scope.customPropertyMapping ) ) {
|
|
414
|
+
|
|
415
|
+
const propNames = scope.customPropertyMapping[ customAttr ];
|
|
416
|
+
const matched = propNames.map( name => properties.find( p => p.name === name ) );
|
|
417
|
+
const types = matched.filter( p => p ).map( p => p.type );
|
|
418
|
+
const uniform = types.length > 0 && types.every( type => type === types[ 0 ] );
|
|
419
|
+
|
|
420
|
+
custom[ customAttr ] = {
|
|
421
|
+
type: uniform ? types[ 0 ] : 'float32',
|
|
422
|
+
usage: matched.every( p => p !== undefined ),
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// build descriptor
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
position: {
|
|
431
|
+
names: [ x ? x.name : 'x', y ? y.name : 'y', z ? z.name : 'z' ],
|
|
432
|
+
type: x ? x.type : 'float32',
|
|
433
|
+
usage: !! ( x && y && z ),
|
|
434
|
+
},
|
|
435
|
+
normal: {
|
|
436
|
+
names: [ nx ? nx.name : 'nx', ny ? ny.name : 'ny', nz ? nz.name : 'nz' ],
|
|
437
|
+
type: nx ? nx.type : 'float32',
|
|
438
|
+
usage: !! ( nx && ny && nz ),
|
|
439
|
+
},
|
|
440
|
+
uv: {
|
|
441
|
+
names: [ s ? s.name : 's', t ? t.name : 't' ],
|
|
442
|
+
type: s ? s.type : 'float32',
|
|
443
|
+
usage: !! ( s && t ),
|
|
444
|
+
},
|
|
445
|
+
texcoord: {
|
|
446
|
+
type: texcoord ? texcoord.itemType : 'float32',
|
|
447
|
+
usage: !! texcoord,
|
|
448
|
+
},
|
|
449
|
+
color: {
|
|
450
|
+
names: [ r ? r.name : 'red', g ? g.name : 'green', b ? b.name : 'blue' ],
|
|
451
|
+
type: r ? r.type : 'uchar',
|
|
452
|
+
usage: !! ( r && g && b ),
|
|
453
|
+
},
|
|
454
|
+
custom: custom,
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function parseASCII( data, header ) {
|
|
460
|
+
|
|
461
|
+
// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
|
|
462
|
+
|
|
463
|
+
const buffer = createBuffer();
|
|
464
|
+
|
|
465
|
+
const patternBody = /end_header\s+(\S[\s\S]*\S|\S)\s*$/;
|
|
466
|
+
let body, matches;
|
|
467
|
+
|
|
468
|
+
if ( ( matches = patternBody.exec( data ) ) !== null ) {
|
|
469
|
+
|
|
470
|
+
body = matches[ 1 ].split( /\s+/ );
|
|
471
|
+
|
|
472
|
+
} else {
|
|
473
|
+
|
|
474
|
+
body = [ ];
|
|
475
|
+
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const tokens = new ArrayStream( body );
|
|
479
|
+
|
|
480
|
+
loop: for ( let i = 0; i < header.elements.length; i ++ ) {
|
|
481
|
+
|
|
482
|
+
const elementDesc = header.elements[ i ];
|
|
483
|
+
const attributeDescriptor = getAttributeDescriptor( elementDesc.properties );
|
|
484
|
+
buffer.descriptors[ elementDesc.name ] = attributeDescriptor;
|
|
485
|
+
|
|
486
|
+
for ( let j = 0; j < elementDesc.count; j ++ ) {
|
|
487
|
+
|
|
488
|
+
const element = parseASCIIElement( elementDesc.properties, tokens );
|
|
489
|
+
|
|
490
|
+
if ( ! element ) break loop;
|
|
491
|
+
|
|
492
|
+
handleElement( buffer, elementDesc.name, element, attributeDescriptor );
|
|
493
|
+
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return postProcess( buffer );
|
|
499
|
+
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
function postProcess( buffer ) {
|
|
503
|
+
|
|
504
|
+
let geometry = new BufferGeometry();
|
|
505
|
+
|
|
506
|
+
const vertexDescriptor = buffer.descriptors.vertex;
|
|
507
|
+
|
|
508
|
+
// mandatory buffer data
|
|
509
|
+
|
|
510
|
+
if ( buffer.indices.length > 0 ) {
|
|
511
|
+
|
|
512
|
+
geometry.setIndex( buffer.indices );
|
|
513
|
+
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const PositionClass = getBufferAttributeClass( vertexDescriptor ? vertexDescriptor.position.type : 'float32' );
|
|
517
|
+
geometry.setAttribute( 'position', new PositionClass( buffer.vertices, 3 ) );
|
|
518
|
+
|
|
519
|
+
// optional buffer data
|
|
520
|
+
|
|
521
|
+
if ( buffer.normals.length > 0 ) {
|
|
522
|
+
|
|
523
|
+
const NormalClass = getBufferAttributeClass( vertexDescriptor.normal.type );
|
|
524
|
+
geometry.setAttribute( 'normal', new NormalClass( buffer.normals, 3 ) );
|
|
525
|
+
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
if ( buffer.uvs.length > 0 ) {
|
|
529
|
+
|
|
530
|
+
const UvClass = getBufferAttributeClass( vertexDescriptor.uv.type );
|
|
531
|
+
geometry.setAttribute( 'uv', new UvClass( buffer.uvs, 2 ) );
|
|
532
|
+
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if ( buffer.colors.length > 0 ) {
|
|
536
|
+
|
|
537
|
+
const colorType = vertexDescriptor.color.type;
|
|
538
|
+
const normalized = ! isFloatType( colorType );
|
|
539
|
+
|
|
540
|
+
const ColorClass = getBufferAttributeClass( colorType );
|
|
541
|
+
geometry.setAttribute( 'color', new ColorClass( buffer.colors, 3, normalized ) );
|
|
542
|
+
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
if ( buffer.faceVertexUvs.length > 0 || buffer.faceVertexColors.length > 0 ) {
|
|
546
|
+
|
|
547
|
+
geometry = geometry.toNonIndexed();
|
|
548
|
+
|
|
549
|
+
if ( buffer.faceVertexUvs.length > 0 ) {
|
|
550
|
+
|
|
551
|
+
const UvClass = getBufferAttributeClass( buffer.descriptors.face.texcoord.type );
|
|
552
|
+
geometry.setAttribute( 'uv', new UvClass( buffer.faceVertexUvs, 2 ) );
|
|
553
|
+
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if ( buffer.faceVertexColors.length > 0 ) {
|
|
557
|
+
|
|
558
|
+
const colorType = buffer.descriptors.face.color.type;
|
|
559
|
+
const normalized = ! isFloatType( colorType );
|
|
560
|
+
|
|
561
|
+
const ColorClass = getBufferAttributeClass( colorType );
|
|
562
|
+
geometry.setAttribute( 'color', new ColorClass( buffer.faceVertexColors, 3, normalized ) );
|
|
563
|
+
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// custom buffer data
|
|
569
|
+
|
|
570
|
+
for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) {
|
|
571
|
+
|
|
572
|
+
if ( buffer[ customProperty ].length > 0 ) {
|
|
573
|
+
|
|
574
|
+
const CustomClass = getBufferAttributeClass( vertexDescriptor.custom[ customProperty ].type );
|
|
575
|
+
geometry.setAttribute( customProperty, new CustomClass( buffer[ customProperty ], scope.customPropertyMapping[ customProperty ].length ) );
|
|
576
|
+
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
geometry.computeBoundingSphere();
|
|
582
|
+
|
|
583
|
+
return geometry;
|
|
584
|
+
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function handleElement( buffer, elementName, element, attributeDescriptor ) {
|
|
588
|
+
|
|
589
|
+
if ( elementName === 'vertex' ) {
|
|
590
|
+
|
|
591
|
+
const { position, normal, uv, color } = attributeDescriptor;
|
|
592
|
+
|
|
593
|
+
if ( position.usage ) {
|
|
594
|
+
|
|
595
|
+
buffer.vertices.push(
|
|
596
|
+
element[ position.names[ 0 ] ],
|
|
597
|
+
element[ position.names[ 1 ] ],
|
|
598
|
+
element[ position.names[ 2 ] ]
|
|
599
|
+
);
|
|
600
|
+
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
if ( normal.usage ) {
|
|
604
|
+
|
|
605
|
+
buffer.normals.push(
|
|
606
|
+
element[ normal.names[ 0 ] ],
|
|
607
|
+
element[ normal.names[ 1 ] ],
|
|
608
|
+
element[ normal.names[ 2 ] ]
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if ( uv.usage ) {
|
|
614
|
+
|
|
615
|
+
buffer.uvs.push(
|
|
616
|
+
element[ uv.names[ 0 ] ],
|
|
617
|
+
element[ uv.names[ 1 ] ]
|
|
618
|
+
);
|
|
619
|
+
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if ( color.usage ) {
|
|
623
|
+
|
|
624
|
+
const scale = getColorScale( color.type );
|
|
625
|
+
const isFloat = isFloatType( color.type );
|
|
626
|
+
|
|
627
|
+
// convert to float for color space conversion
|
|
628
|
+
|
|
629
|
+
_color.setRGB(
|
|
630
|
+
element[ color.names[ 0 ] ] * scale,
|
|
631
|
+
element[ color.names[ 1 ] ] * scale,
|
|
632
|
+
element[ color.names[ 2 ] ] * scale,
|
|
633
|
+
SRGBColorSpace
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
// convert back to original type
|
|
637
|
+
|
|
638
|
+
const invScale = 1 / scale;
|
|
639
|
+
|
|
640
|
+
buffer.colors.push(
|
|
641
|
+
isFloat ? _color.r : Math.round( _color.r * invScale ),
|
|
642
|
+
isFloat ? _color.g : Math.round( _color.g * invScale ),
|
|
643
|
+
isFloat ? _color.b : Math.round( _color.b * invScale )
|
|
644
|
+
);
|
|
645
|
+
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
for ( const customProperty of Object.keys( scope.customPropertyMapping ) ) {
|
|
649
|
+
|
|
650
|
+
for ( const elementProperty of scope.customPropertyMapping[ customProperty ] ) {
|
|
651
|
+
|
|
652
|
+
buffer[ customProperty ].push( element[ elementProperty ] );
|
|
653
|
+
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
} else if ( elementName === 'face' ) {
|
|
659
|
+
|
|
660
|
+
const vertex_indices = element.vertex_indices || element.vertex_index; // issue #9338
|
|
661
|
+
const texcoord = element.texcoord;
|
|
662
|
+
|
|
663
|
+
if ( vertex_indices.length === 3 ) {
|
|
664
|
+
|
|
665
|
+
buffer.indices.push( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 2 ] );
|
|
666
|
+
|
|
667
|
+
if ( texcoord && texcoord.length === 6 ) {
|
|
668
|
+
|
|
669
|
+
buffer.faceVertexUvs.push( texcoord[ 0 ], texcoord[ 1 ] );
|
|
670
|
+
buffer.faceVertexUvs.push( texcoord[ 2 ], texcoord[ 3 ] );
|
|
671
|
+
buffer.faceVertexUvs.push( texcoord[ 4 ], texcoord[ 5 ] );
|
|
672
|
+
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
} else if ( vertex_indices.length === 4 ) {
|
|
676
|
+
|
|
677
|
+
buffer.indices.push( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 3 ] );
|
|
678
|
+
buffer.indices.push( vertex_indices[ 1 ], vertex_indices[ 2 ], vertex_indices[ 3 ] );
|
|
679
|
+
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// face colors
|
|
683
|
+
|
|
684
|
+
const { color } = attributeDescriptor;
|
|
685
|
+
|
|
686
|
+
if ( color.usage ) {
|
|
687
|
+
|
|
688
|
+
// convert to float for color space conversion
|
|
689
|
+
|
|
690
|
+
const scale = getColorScale( color.type );
|
|
691
|
+
|
|
692
|
+
_color.setRGB(
|
|
693
|
+
element[ color.names[ 0 ] ] * scale,
|
|
694
|
+
element[ color.names[ 1 ] ] * scale,
|
|
695
|
+
element[ color.names[ 2 ] ] * scale,
|
|
696
|
+
SRGBColorSpace
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
// convert back to original type
|
|
700
|
+
|
|
701
|
+
const invScale = 1 / scale;
|
|
702
|
+
|
|
703
|
+
const r = _color.r * invScale;
|
|
704
|
+
const g = _color.g * invScale;
|
|
705
|
+
const b = _color.b * invScale;
|
|
706
|
+
|
|
707
|
+
buffer.faceVertexColors.push( r, g, b );
|
|
708
|
+
buffer.faceVertexColors.push( r, g, b );
|
|
709
|
+
buffer.faceVertexColors.push( r, g, b );
|
|
710
|
+
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function binaryReadElement( at, properties ) {
|
|
718
|
+
|
|
719
|
+
const element = {};
|
|
720
|
+
let read = 0;
|
|
721
|
+
|
|
722
|
+
for ( let i = 0; i < properties.length; i ++ ) {
|
|
723
|
+
|
|
724
|
+
const property = properties[ i ];
|
|
725
|
+
const valueReader = property.valueReader;
|
|
726
|
+
|
|
727
|
+
if ( property.type === 'list' ) {
|
|
728
|
+
|
|
729
|
+
const list = [];
|
|
730
|
+
|
|
731
|
+
const n = property.countReader.read( at + read );
|
|
732
|
+
read += property.countReader.size;
|
|
733
|
+
|
|
734
|
+
for ( let j = 0; j < n; j ++ ) {
|
|
735
|
+
|
|
736
|
+
list.push( valueReader.read( at + read ) );
|
|
737
|
+
read += valueReader.size;
|
|
738
|
+
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
element[ property.name ] = list;
|
|
742
|
+
|
|
743
|
+
} else {
|
|
744
|
+
|
|
745
|
+
element[ property.name ] = valueReader.read( at + read );
|
|
746
|
+
read += valueReader.size;
|
|
747
|
+
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
return [ element, read ];
|
|
753
|
+
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
function setPropertyBinaryReaders( properties, body, little_endian ) {
|
|
757
|
+
|
|
758
|
+
function getBinaryReader( dataview, type, little_endian ) {
|
|
759
|
+
|
|
760
|
+
switch ( type ) {
|
|
761
|
+
|
|
762
|
+
// correspondences for non-specific length types here match rply:
|
|
763
|
+
case 'int8': case 'char': return { read: ( at ) => {
|
|
764
|
+
|
|
765
|
+
return dataview.getInt8( at );
|
|
766
|
+
|
|
767
|
+
}, size: 1 };
|
|
768
|
+
case 'uint8': case 'uchar': return { read: ( at ) => {
|
|
769
|
+
|
|
770
|
+
return dataview.getUint8( at );
|
|
771
|
+
|
|
772
|
+
}, size: 1 };
|
|
773
|
+
case 'int16': case 'short': return { read: ( at ) => {
|
|
774
|
+
|
|
775
|
+
return dataview.getInt16( at, little_endian );
|
|
776
|
+
|
|
777
|
+
}, size: 2 };
|
|
778
|
+
case 'uint16': case 'ushort': return { read: ( at ) => {
|
|
779
|
+
|
|
780
|
+
return dataview.getUint16( at, little_endian );
|
|
781
|
+
|
|
782
|
+
}, size: 2 };
|
|
783
|
+
case 'int32': case 'int': return { read: ( at ) => {
|
|
784
|
+
|
|
785
|
+
return dataview.getInt32( at, little_endian );
|
|
786
|
+
|
|
787
|
+
}, size: 4 };
|
|
788
|
+
case 'uint32': case 'uint': return { read: ( at ) => {
|
|
789
|
+
|
|
790
|
+
return dataview.getUint32( at, little_endian );
|
|
791
|
+
|
|
792
|
+
}, size: 4 };
|
|
793
|
+
case 'float32': case 'float': return { read: ( at ) => {
|
|
794
|
+
|
|
795
|
+
return dataview.getFloat32( at, little_endian );
|
|
796
|
+
|
|
797
|
+
}, size: 4 };
|
|
798
|
+
case 'float64': case 'double': return { read: ( at ) => {
|
|
799
|
+
|
|
800
|
+
return dataview.getFloat64( at, little_endian );
|
|
801
|
+
|
|
802
|
+
}, size: 8 };
|
|
803
|
+
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
for ( let i = 0, l = properties.length; i < l; i ++ ) {
|
|
809
|
+
|
|
810
|
+
const property = properties[ i ];
|
|
811
|
+
|
|
812
|
+
if ( property.type === 'list' ) {
|
|
813
|
+
|
|
814
|
+
property.countReader = getBinaryReader( body, property.countType, little_endian );
|
|
815
|
+
property.valueReader = getBinaryReader( body, property.itemType, little_endian );
|
|
816
|
+
|
|
817
|
+
} else {
|
|
818
|
+
|
|
819
|
+
property.valueReader = getBinaryReader( body, property.type, little_endian );
|
|
820
|
+
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function parseBinary( data, header ) {
|
|
828
|
+
|
|
829
|
+
const buffer = createBuffer();
|
|
830
|
+
|
|
831
|
+
const little_endian = ( header.format === 'binary_little_endian' );
|
|
832
|
+
const body = new DataView( data, header.headerLength );
|
|
833
|
+
let result, loc = 0;
|
|
834
|
+
|
|
835
|
+
for ( let currentElement = 0; currentElement < header.elements.length; currentElement ++ ) {
|
|
836
|
+
|
|
837
|
+
const elementDesc = header.elements[ currentElement ];
|
|
838
|
+
const properties = elementDesc.properties;
|
|
839
|
+
const attributeDescriptor = getAttributeDescriptor( properties );
|
|
840
|
+
buffer.descriptors[ elementDesc.name ] = attributeDescriptor;
|
|
841
|
+
|
|
842
|
+
setPropertyBinaryReaders( properties, body, little_endian );
|
|
843
|
+
|
|
844
|
+
for ( let currentElementCount = 0; currentElementCount < elementDesc.count; currentElementCount ++ ) {
|
|
845
|
+
|
|
846
|
+
result = binaryReadElement( loc, properties );
|
|
847
|
+
loc += result[ 1 ];
|
|
848
|
+
const element = result[ 0 ];
|
|
849
|
+
|
|
850
|
+
handleElement( buffer, elementDesc.name, element, attributeDescriptor );
|
|
851
|
+
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
return postProcess( buffer );
|
|
857
|
+
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function extractHeaderText( bytes ) {
|
|
861
|
+
|
|
862
|
+
let i = 0;
|
|
863
|
+
let cont = true;
|
|
864
|
+
|
|
865
|
+
let line = '';
|
|
866
|
+
const lines = [];
|
|
867
|
+
|
|
868
|
+
const startLine = new TextDecoder().decode( bytes.subarray( 0, 5 ) );
|
|
869
|
+
const hasCRNL = /^ply\r\n/.test( startLine );
|
|
870
|
+
|
|
871
|
+
do {
|
|
872
|
+
|
|
873
|
+
const c = String.fromCharCode( bytes[ i ++ ] );
|
|
874
|
+
|
|
875
|
+
if ( c !== '\n' && c !== '\r' ) {
|
|
876
|
+
|
|
877
|
+
line += c;
|
|
878
|
+
|
|
879
|
+
} else {
|
|
880
|
+
|
|
881
|
+
if ( line === 'end_header' ) cont = false;
|
|
882
|
+
if ( line !== '' ) {
|
|
883
|
+
|
|
884
|
+
lines.push( line );
|
|
885
|
+
line = '';
|
|
886
|
+
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
} while ( cont && i < bytes.length );
|
|
892
|
+
|
|
893
|
+
// ascii section using \r\n as line endings
|
|
894
|
+
if ( hasCRNL === true ) i ++;
|
|
895
|
+
|
|
896
|
+
return { headerText: lines.join( '\r' ) + '\r', headerLength: i };
|
|
897
|
+
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
//
|
|
901
|
+
|
|
902
|
+
let geometry;
|
|
903
|
+
const scope = this;
|
|
904
|
+
|
|
905
|
+
if ( data instanceof ArrayBuffer ) {
|
|
906
|
+
|
|
907
|
+
const bytes = new Uint8Array( data );
|
|
908
|
+
const { headerText, headerLength } = extractHeaderText( bytes );
|
|
909
|
+
const header = parseHeader( headerText, headerLength );
|
|
910
|
+
|
|
911
|
+
if ( header.format === 'ascii' ) {
|
|
912
|
+
|
|
913
|
+
const text = new TextDecoder().decode( bytes );
|
|
914
|
+
|
|
915
|
+
geometry = parseASCII( text, header );
|
|
916
|
+
|
|
917
|
+
} else {
|
|
918
|
+
|
|
919
|
+
geometry = parseBinary( data, header );
|
|
920
|
+
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
} else {
|
|
924
|
+
|
|
925
|
+
geometry = parseASCII( data, parseHeader( data ) );
|
|
926
|
+
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
return geometry;
|
|
930
|
+
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
class Float64BufferAttribute extends BufferAttribute {
|
|
936
|
+
|
|
937
|
+
constructor( array, itemSize, normalized ) {
|
|
938
|
+
|
|
939
|
+
super( new Float64Array( array ), itemSize, normalized );
|
|
940
|
+
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
class ArrayStream {
|
|
946
|
+
|
|
947
|
+
constructor( arr ) {
|
|
948
|
+
|
|
949
|
+
this.arr = arr;
|
|
950
|
+
this.i = 0;
|
|
951
|
+
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
empty() {
|
|
955
|
+
|
|
956
|
+
return this.i >= this.arr.length;
|
|
957
|
+
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
next() {
|
|
961
|
+
|
|
962
|
+
return this.arr[ this.i ++ ];
|
|
963
|
+
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
export { PLYLoader };
|