@inweb/viewer-three 26.9.3 → 26.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugins/components/AxesHelperComponent.js +23 -22
- package/dist/plugins/components/AxesHelperComponent.js.map +1 -1
- package/dist/plugins/components/AxesHelperComponent.min.js +23 -0
- package/dist/plugins/components/AxesHelperComponent.module.js +31 -9
- package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -1
- package/dist/plugins/components/ExtentsHelperComponent.js +23 -22
- package/dist/plugins/components/ExtentsHelperComponent.js.map +1 -1
- package/dist/plugins/components/ExtentsHelperComponent.min.js +23 -0
- package/dist/plugins/components/ExtentsHelperComponent.module.js +28 -6
- package/dist/plugins/components/ExtentsHelperComponent.module.js.map +1 -1
- package/dist/plugins/components/LightHelperComponent.js +23 -22
- package/dist/plugins/components/LightHelperComponent.js.map +1 -1
- package/dist/plugins/components/LightHelperComponent.min.js +23 -0
- package/dist/plugins/components/LightHelperComponent.module.js +35 -9
- package/dist/plugins/components/LightHelperComponent.module.js.map +1 -1
- package/dist/plugins/components/RoomEnvironmentComponent.js +23 -97
- package/dist/plugins/components/RoomEnvironmentComponent.js.map +1 -1
- package/dist/plugins/components/RoomEnvironmentComponent.min.js +23 -0
- package/dist/plugins/components/RoomEnvironmentComponent.module.js +27 -7
- package/dist/plugins/components/RoomEnvironmentComponent.module.js.map +1 -1
- package/dist/plugins/components/StatsPanelComponent.js +23 -92
- package/dist/plugins/components/StatsPanelComponent.js.map +1 -1
- package/dist/plugins/components/StatsPanelComponent.min.js +23 -0
- package/dist/plugins/components/StatsPanelComponent.module.js +26 -5
- package/dist/plugins/components/StatsPanelComponent.module.js.map +1 -1
- package/dist/plugins/loaders/GLTFCloudLoader.js +31 -2515
- package/dist/plugins/loaders/GLTFCloudLoader.js.map +1 -1
- package/dist/plugins/loaders/GLTFCloudLoader.min.js +23 -0
- package/dist/plugins/loaders/GLTFCloudLoader.module.js +35 -20
- package/dist/plugins/loaders/GLTFCloudLoader.module.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.js +35 -689
- package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.min.js +23 -0
- package/dist/plugins/loaders/IFCXLoader.module.js +833 -859
- package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/plugins/loaders/PotreeLoader.js +26 -70
- package/dist/plugins/loaders/PotreeLoader.js.map +1 -1
- package/dist/plugins/loaders/PotreeLoader.min.js +23 -0
- package/dist/plugins/loaders/PotreeLoader.module.js +37 -15
- package/dist/plugins/loaders/PotreeLoader.module.js.map +1 -1
- package/dist/viewer-three.js +1502 -55140
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +26 -3
- package/dist/viewer-three.module.js +3584 -3660
- package/dist/viewer-three.module.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,173 +1,87 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
3
|
+
// All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This software and its documentation and related materials are owned by
|
|
6
|
+
// the Alliance. The software may only be incorporated into application
|
|
7
|
+
// programs owned by members of the Alliance, subject to a signed
|
|
8
|
+
// Membership Agreement and Supplemental Software License Agreement with the
|
|
9
|
+
// Alliance. The structure and organization of this software are the valuable
|
|
10
|
+
// trade secrets of the Alliance and its suppliers. The software is also
|
|
11
|
+
// protected by copyright law and international treaty provisions. Application
|
|
12
|
+
// programs incorporating this software must include the following statement
|
|
13
|
+
// with their copyright notices:
|
|
14
|
+
//
|
|
15
|
+
// This application incorporates Open Design Alliance software pursuant to a
|
|
16
|
+
// license agreement with Open Design Alliance.
|
|
17
|
+
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
18
|
+
// All rights reserved.
|
|
19
|
+
//
|
|
20
|
+
// By use of this software, its documentation or related materials, you
|
|
21
|
+
// acknowledge and accept the above terms.
|
|
22
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
23
|
+
|
|
1
24
|
(function (global, factory) {
|
|
2
25
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('@inweb/viewer-three'), require('three')) :
|
|
3
26
|
typeof define === 'function' && define.amd ? define(['@inweb/viewer-three', 'three'], factory) :
|
|
4
27
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ODA.Three, global.THREE));
|
|
5
28
|
})(this, (function (viewerThree, three) { 'use strict';
|
|
6
29
|
|
|
7
|
-
/**
|
|
8
|
-
* A loader for the Point Cloud Data (PCD) format.
|
|
9
|
-
*
|
|
10
|
-
* PCDLoader supports ASCII and (compressed) binary files as well as the following PCD fields:
|
|
11
|
-
* - x y z
|
|
12
|
-
* - rgb
|
|
13
|
-
* - normal_x normal_y normal_z
|
|
14
|
-
* - intensity
|
|
15
|
-
* - label
|
|
16
|
-
*
|
|
17
|
-
* ```js
|
|
18
|
-
* const loader = new PCDLoader();
|
|
19
|
-
*
|
|
20
|
-
* const points = await loader.loadAsync( './models/pcd/binary/Zaghetto.pcd' );
|
|
21
|
-
* points.geometry.center(); // optional
|
|
22
|
-
* points.geometry.rotateX( Math.PI ); // optional
|
|
23
|
-
* scene.add( points );
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @augments Loader
|
|
27
|
-
* @three_import import { PCDLoader } from 'three/addons/loaders/PCDLoader.js';
|
|
28
|
-
*/
|
|
29
30
|
class PCDLoader extends three.Loader {
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Constructs a new PCD loader.
|
|
33
|
-
*
|
|
34
|
-
* @param {LoadingManager} [manager] - The loading manager.
|
|
35
|
-
*/
|
|
36
31
|
constructor( manager ) {
|
|
37
|
-
|
|
38
32
|
super( manager );
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Whether to use little Endian or not.
|
|
42
|
-
*
|
|
43
|
-
* @type {boolean}
|
|
44
|
-
* @default true
|
|
45
|
-
*/
|
|
46
33
|
this.littleEndian = true;
|
|
47
|
-
|
|
48
34
|
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Starts loading from the given URL and passes the loaded PCD asset
|
|
52
|
-
* to the `onLoad()` callback.
|
|
53
|
-
*
|
|
54
|
-
* @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
|
|
55
|
-
* @param {function(Points)} onLoad - Executed when the loading process has been finished.
|
|
56
|
-
* @param {onProgressCallback} onProgress - Executed while the loading is in progress.
|
|
57
|
-
* @param {onErrorCallback} onError - Executed when errors occur.
|
|
58
|
-
*/
|
|
59
35
|
load( url, onLoad, onProgress, onError ) {
|
|
60
|
-
|
|
61
36
|
const scope = this;
|
|
62
|
-
|
|
63
37
|
const loader = new three.FileLoader( scope.manager );
|
|
64
38
|
loader.setPath( scope.path );
|
|
65
39
|
loader.setResponseType( 'arraybuffer' );
|
|
66
40
|
loader.setRequestHeader( scope.requestHeader );
|
|
67
41
|
loader.setWithCredentials( scope.withCredentials );
|
|
68
42
|
loader.load( url, function ( data ) {
|
|
69
|
-
|
|
70
43
|
try {
|
|
71
|
-
|
|
72
44
|
onLoad( scope.parse( data ) );
|
|
73
|
-
|
|
74
45
|
} catch ( e ) {
|
|
75
|
-
|
|
76
46
|
if ( onError ) {
|
|
77
|
-
|
|
78
47
|
onError( e );
|
|
79
|
-
|
|
80
48
|
} else {
|
|
81
|
-
|
|
82
49
|
console.error( e );
|
|
83
|
-
|
|
84
50
|
}
|
|
85
|
-
|
|
86
51
|
scope.manager.itemError( url );
|
|
87
|
-
|
|
88
52
|
}
|
|
89
|
-
|
|
90
53
|
}, onProgress, onError );
|
|
91
|
-
|
|
92
54
|
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Get dataview value by field type and size.
|
|
96
|
-
*
|
|
97
|
-
* @param {DataView} dataview - The DataView to read from.
|
|
98
|
-
* @param {number} offset - The offset to start reading from.
|
|
99
|
-
* @param {'F' | 'U' | 'I'} type - Field type.
|
|
100
|
-
* @param {number} size - Field size.
|
|
101
|
-
* @returns {number} Field value.
|
|
102
|
-
*/
|
|
103
55
|
_getDataView( dataview, offset, type, size ) {
|
|
104
|
-
|
|
105
56
|
switch ( type ) {
|
|
106
|
-
|
|
107
57
|
case 'F': {
|
|
108
|
-
|
|
109
58
|
if ( size === 8 ) {
|
|
110
|
-
|
|
111
59
|
return dataview.getFloat64( offset, this.littleEndian );
|
|
112
|
-
|
|
113
60
|
}
|
|
114
|
-
|
|
115
61
|
return dataview.getFloat32( offset, this.littleEndian );
|
|
116
|
-
|
|
117
62
|
}
|
|
118
|
-
|
|
119
63
|
case 'I': {
|
|
120
|
-
|
|
121
64
|
if ( size === 1 ) {
|
|
122
|
-
|
|
123
65
|
return dataview.getInt8( offset );
|
|
124
|
-
|
|
125
66
|
}
|
|
126
|
-
|
|
127
67
|
if ( size === 2 ) {
|
|
128
|
-
|
|
129
68
|
return dataview.getInt16( offset, this.littleEndian );
|
|
130
|
-
|
|
131
69
|
}
|
|
132
|
-
|
|
133
70
|
return dataview.getInt32( offset, this.littleEndian );
|
|
134
|
-
|
|
135
71
|
}
|
|
136
|
-
|
|
137
72
|
case 'U': {
|
|
138
|
-
|
|
139
73
|
if ( size === 1 ) {
|
|
140
|
-
|
|
141
74
|
return dataview.getUint8( offset );
|
|
142
|
-
|
|
143
75
|
}
|
|
144
|
-
|
|
145
76
|
if ( size === 2 ) {
|
|
146
|
-
|
|
147
77
|
return dataview.getUint16( offset, this.littleEndian );
|
|
148
|
-
|
|
149
78
|
}
|
|
150
|
-
|
|
151
79
|
return dataview.getUint32( offset, this.littleEndian );
|
|
152
|
-
|
|
153
80
|
}
|
|
154
|
-
|
|
155
81
|
}
|
|
156
|
-
|
|
157
82
|
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Parses the given PCD data and returns a point cloud.
|
|
161
|
-
*
|
|
162
|
-
* @param {ArrayBuffer} data - The raw PCD data as an array buffer.
|
|
163
|
-
* @return {Points} The parsed point cloud.
|
|
164
|
-
*/
|
|
165
83
|
parse( data ) {
|
|
166
|
-
|
|
167
|
-
// from https://gitlab.com/taketwo/three-pcd-loader/blob/master/decompress-lzf.js
|
|
168
|
-
|
|
169
84
|
function decompressLZF( inData, outLength ) {
|
|
170
|
-
|
|
171
85
|
const inLength = inData.length;
|
|
172
86
|
const outData = new Uint8Array( outLength );
|
|
173
87
|
let inPtr = 0;
|
|
@@ -176,96 +90,56 @@
|
|
|
176
90
|
let len;
|
|
177
91
|
let ref;
|
|
178
92
|
do {
|
|
179
|
-
|
|
180
93
|
ctrl = inData[ inPtr ++ ];
|
|
181
94
|
if ( ctrl < ( 1 << 5 ) ) {
|
|
182
|
-
|
|
183
95
|
ctrl ++;
|
|
184
96
|
if ( outPtr + ctrl > outLength ) throw new Error( 'Output buffer is not large enough' );
|
|
185
97
|
if ( inPtr + ctrl > inLength ) throw new Error( 'Invalid compressed data' );
|
|
186
98
|
do {
|
|
187
|
-
|
|
188
99
|
outData[ outPtr ++ ] = inData[ inPtr ++ ];
|
|
189
|
-
|
|
190
100
|
} while ( -- ctrl );
|
|
191
|
-
|
|
192
101
|
} else {
|
|
193
|
-
|
|
194
102
|
len = ctrl >> 5;
|
|
195
103
|
ref = outPtr - ( ( ctrl & 0x1f ) << 8 ) - 1;
|
|
196
104
|
if ( inPtr >= inLength ) throw new Error( 'Invalid compressed data' );
|
|
197
105
|
if ( len === 7 ) {
|
|
198
|
-
|
|
199
106
|
len += inData[ inPtr ++ ];
|
|
200
107
|
if ( inPtr >= inLength ) throw new Error( 'Invalid compressed data' );
|
|
201
|
-
|
|
202
108
|
}
|
|
203
|
-
|
|
204
109
|
ref -= inData[ inPtr ++ ];
|
|
205
110
|
if ( outPtr + len + 2 > outLength ) throw new Error( 'Output buffer is not large enough' );
|
|
206
111
|
if ( ref < 0 ) throw new Error( 'Invalid compressed data' );
|
|
207
112
|
if ( ref >= outPtr ) throw new Error( 'Invalid compressed data' );
|
|
208
113
|
do {
|
|
209
|
-
|
|
210
114
|
outData[ outPtr ++ ] = outData[ ref ++ ];
|
|
211
|
-
|
|
212
115
|
} while ( -- len + 2 );
|
|
213
|
-
|
|
214
116
|
}
|
|
215
|
-
|
|
216
117
|
} while ( inPtr < inLength );
|
|
217
|
-
|
|
218
118
|
return outData;
|
|
219
|
-
|
|
220
119
|
}
|
|
221
|
-
|
|
222
120
|
function parseHeader( binaryData ) {
|
|
223
|
-
|
|
224
121
|
const PCDheader = {};
|
|
225
|
-
|
|
226
122
|
const buffer = new Uint8Array( binaryData );
|
|
227
|
-
|
|
228
123
|
let data = '', line = '', i = 0, end = false;
|
|
229
|
-
|
|
230
124
|
const max = buffer.length;
|
|
231
|
-
|
|
232
125
|
while ( i < max && end === false ) {
|
|
233
|
-
|
|
234
126
|
const char = String.fromCharCode( buffer[ i ++ ] );
|
|
235
|
-
|
|
236
127
|
if ( char === '\n' || char === '\r' ) {
|
|
237
|
-
|
|
238
128
|
if ( line.trim().toLowerCase().startsWith( 'data' ) ) {
|
|
239
|
-
|
|
240
129
|
end = true;
|
|
241
|
-
|
|
242
130
|
}
|
|
243
|
-
|
|
244
131
|
line = '';
|
|
245
|
-
|
|
246
132
|
} else {
|
|
247
|
-
|
|
248
133
|
line += char;
|
|
249
|
-
|
|
250
134
|
}
|
|
251
|
-
|
|
252
135
|
data += char;
|
|
253
|
-
|
|
254
136
|
}
|
|
255
|
-
|
|
256
137
|
const result1 = data.search( /[\r\n]DATA\s(\S*)\s/i );
|
|
257
138
|
const result2 = /[\r\n]DATA\s(\S*)\s/i.exec( data.slice( result1 - 1 ) );
|
|
258
|
-
|
|
259
139
|
PCDheader.data = result2[ 1 ];
|
|
260
140
|
PCDheader.headerLen = result2[ 0 ].length + result1;
|
|
261
141
|
PCDheader.str = data.slice( 0, PCDheader.headerLen );
|
|
262
|
-
|
|
263
|
-
// remove comments
|
|
264
|
-
|
|
265
142
|
PCDheader.str = PCDheader.str.replace( /#.*/gi, '' );
|
|
266
|
-
|
|
267
|
-
// parse
|
|
268
|
-
|
|
269
143
|
PCDheader.version = /^VERSION (.*)/im.exec( PCDheader.str );
|
|
270
144
|
PCDheader.fields = /^FIELDS (.*)/im.exec( PCDheader.str );
|
|
271
145
|
PCDheader.size = /^SIZE (.*)/im.exec( PCDheader.str );
|
|
@@ -275,364 +149,191 @@
|
|
|
275
149
|
PCDheader.height = /^HEIGHT (.*)/im.exec( PCDheader.str );
|
|
276
150
|
PCDheader.viewpoint = /^VIEWPOINT (.*)/im.exec( PCDheader.str );
|
|
277
151
|
PCDheader.points = /^POINTS (.*)/im.exec( PCDheader.str );
|
|
278
|
-
|
|
279
|
-
// evaluate
|
|
280
|
-
|
|
281
152
|
if ( PCDheader.version !== null )
|
|
282
153
|
PCDheader.version = parseFloat( PCDheader.version[ 1 ] );
|
|
283
|
-
|
|
284
154
|
PCDheader.fields = ( PCDheader.fields !== null ) ? PCDheader.fields[ 1 ].split( ' ' ) : [];
|
|
285
|
-
|
|
286
155
|
if ( PCDheader.type !== null )
|
|
287
156
|
PCDheader.type = PCDheader.type[ 1 ].split( ' ' );
|
|
288
|
-
|
|
289
157
|
if ( PCDheader.width !== null )
|
|
290
158
|
PCDheader.width = parseInt( PCDheader.width[ 1 ] );
|
|
291
|
-
|
|
292
159
|
if ( PCDheader.height !== null )
|
|
293
160
|
PCDheader.height = parseInt( PCDheader.height[ 1 ] );
|
|
294
|
-
|
|
295
161
|
if ( PCDheader.viewpoint !== null )
|
|
296
162
|
PCDheader.viewpoint = PCDheader.viewpoint[ 1 ];
|
|
297
|
-
|
|
298
163
|
if ( PCDheader.points !== null )
|
|
299
164
|
PCDheader.points = parseInt( PCDheader.points[ 1 ], 10 );
|
|
300
|
-
|
|
301
165
|
if ( PCDheader.points === null )
|
|
302
166
|
PCDheader.points = PCDheader.width * PCDheader.height;
|
|
303
|
-
|
|
304
167
|
if ( PCDheader.size !== null ) {
|
|
305
|
-
|
|
306
168
|
PCDheader.size = PCDheader.size[ 1 ].split( ' ' ).map( function ( x ) {
|
|
307
|
-
|
|
308
169
|
return parseInt( x, 10 );
|
|
309
|
-
|
|
310
170
|
} );
|
|
311
|
-
|
|
312
171
|
}
|
|
313
|
-
|
|
314
172
|
if ( PCDheader.count !== null ) {
|
|
315
|
-
|
|
316
173
|
PCDheader.count = PCDheader.count[ 1 ].split( ' ' ).map( function ( x ) {
|
|
317
|
-
|
|
318
174
|
return parseInt( x, 10 );
|
|
319
|
-
|
|
320
175
|
} );
|
|
321
|
-
|
|
322
176
|
} else {
|
|
323
|
-
|
|
324
177
|
PCDheader.count = [];
|
|
325
|
-
|
|
326
178
|
for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
|
|
327
|
-
|
|
328
179
|
PCDheader.count.push( 1 );
|
|
329
|
-
|
|
330
180
|
}
|
|
331
|
-
|
|
332
181
|
}
|
|
333
|
-
|
|
334
182
|
PCDheader.offset = {};
|
|
335
|
-
|
|
336
183
|
let sizeSum = 0;
|
|
337
|
-
|
|
338
184
|
for ( let i = 0, l = PCDheader.fields.length; i < l; i ++ ) {
|
|
339
|
-
|
|
340
185
|
if ( PCDheader.data === 'ascii' ) {
|
|
341
|
-
|
|
342
186
|
PCDheader.offset[ PCDheader.fields[ i ] ] = i;
|
|
343
|
-
|
|
344
187
|
} else {
|
|
345
|
-
|
|
346
188
|
PCDheader.offset[ PCDheader.fields[ i ] ] = sizeSum;
|
|
347
189
|
sizeSum += PCDheader.size[ i ] * PCDheader.count[ i ];
|
|
348
|
-
|
|
349
190
|
}
|
|
350
|
-
|
|
351
191
|
}
|
|
352
|
-
|
|
353
|
-
// for binary only
|
|
354
|
-
|
|
355
192
|
PCDheader.rowSize = sizeSum;
|
|
356
|
-
|
|
357
193
|
return PCDheader;
|
|
358
|
-
|
|
359
194
|
}
|
|
360
|
-
|
|
361
|
-
// parse header
|
|
362
|
-
|
|
363
195
|
const PCDheader = parseHeader( data );
|
|
364
|
-
|
|
365
|
-
// parse data
|
|
366
|
-
|
|
367
196
|
const position = [];
|
|
368
197
|
const normal = [];
|
|
369
198
|
const color = [];
|
|
370
199
|
const intensity = [];
|
|
371
200
|
const label = [];
|
|
372
|
-
|
|
373
201
|
const c = new three.Color();
|
|
374
|
-
|
|
375
|
-
// ascii
|
|
376
|
-
|
|
377
202
|
if ( PCDheader.data === 'ascii' ) {
|
|
378
|
-
|
|
379
203
|
const offset = PCDheader.offset;
|
|
380
204
|
const textData = new TextDecoder().decode( data );
|
|
381
205
|
const pcdData = textData.slice( PCDheader.headerLen );
|
|
382
206
|
const lines = pcdData.split( '\n' );
|
|
383
|
-
|
|
384
207
|
for ( let i = 0, l = lines.length; i < l; i ++ ) {
|
|
385
|
-
|
|
386
208
|
if ( lines[ i ] === '' ) continue;
|
|
387
|
-
|
|
388
209
|
const line = lines[ i ].split( ' ' );
|
|
389
|
-
|
|
390
210
|
if ( offset.x !== undefined ) {
|
|
391
|
-
|
|
392
211
|
position.push( parseFloat( line[ offset.x ] ) );
|
|
393
212
|
position.push( parseFloat( line[ offset.y ] ) );
|
|
394
213
|
position.push( parseFloat( line[ offset.z ] ) );
|
|
395
|
-
|
|
396
214
|
}
|
|
397
|
-
|
|
398
215
|
if ( offset.rgb !== undefined ) {
|
|
399
|
-
|
|
400
216
|
const rgb_field_index = PCDheader.fields.findIndex( ( field ) => field === 'rgb' );
|
|
401
217
|
const rgb_type = PCDheader.type[ rgb_field_index ];
|
|
402
|
-
|
|
403
218
|
const float = parseFloat( line[ offset.rgb ] );
|
|
404
219
|
let rgb = float;
|
|
405
|
-
|
|
406
220
|
if ( rgb_type === 'F' ) {
|
|
407
|
-
|
|
408
|
-
// treat float values as int
|
|
409
|
-
// https://github.com/daavoo/pyntcloud/pull/204/commits/7b4205e64d5ed09abe708b2e91b615690c24d518
|
|
410
221
|
const farr = new Float32Array( 1 );
|
|
411
222
|
farr[ 0 ] = float;
|
|
412
223
|
rgb = new Int32Array( farr.buffer )[ 0 ];
|
|
413
|
-
|
|
414
224
|
}
|
|
415
|
-
|
|
416
225
|
const r = ( ( rgb >> 16 ) & 0x0000ff ) / 255;
|
|
417
226
|
const g = ( ( rgb >> 8 ) & 0x0000ff ) / 255;
|
|
418
227
|
const b = ( ( rgb >> 0 ) & 0x0000ff ) / 255;
|
|
419
|
-
|
|
420
228
|
c.setRGB( r, g, b, three.SRGBColorSpace );
|
|
421
|
-
|
|
422
229
|
color.push( c.r, c.g, c.b );
|
|
423
|
-
|
|
424
230
|
}
|
|
425
|
-
|
|
426
231
|
if ( offset.normal_x !== undefined ) {
|
|
427
|
-
|
|
428
232
|
normal.push( parseFloat( line[ offset.normal_x ] ) );
|
|
429
233
|
normal.push( parseFloat( line[ offset.normal_y ] ) );
|
|
430
234
|
normal.push( parseFloat( line[ offset.normal_z ] ) );
|
|
431
|
-
|
|
432
235
|
}
|
|
433
|
-
|
|
434
236
|
if ( offset.intensity !== undefined ) {
|
|
435
|
-
|
|
436
237
|
intensity.push( parseFloat( line[ offset.intensity ] ) );
|
|
437
|
-
|
|
438
238
|
}
|
|
439
|
-
|
|
440
239
|
if ( offset.label !== undefined ) {
|
|
441
|
-
|
|
442
240
|
label.push( parseInt( line[ offset.label ] ) );
|
|
443
|
-
|
|
444
241
|
}
|
|
445
|
-
|
|
446
242
|
}
|
|
447
|
-
|
|
448
243
|
}
|
|
449
|
-
|
|
450
|
-
// binary-compressed
|
|
451
|
-
|
|
452
|
-
// normally data in PCD files are organized as array of structures: XYZRGBXYZRGB
|
|
453
|
-
// binary compressed PCD files organize their data as structure of arrays: XXYYZZRGBRGB
|
|
454
|
-
// that requires a totally different parsing approach compared to non-compressed data
|
|
455
|
-
|
|
456
244
|
if ( PCDheader.data === 'binary_compressed' ) {
|
|
457
|
-
|
|
458
245
|
const sizes = new Uint32Array( data.slice( PCDheader.headerLen, PCDheader.headerLen + 8 ) );
|
|
459
246
|
const compressedSize = sizes[ 0 ];
|
|
460
247
|
const decompressedSize = sizes[ 1 ];
|
|
461
248
|
const decompressed = decompressLZF( new Uint8Array( data, PCDheader.headerLen + 8, compressedSize ), decompressedSize );
|
|
462
249
|
const dataview = new DataView( decompressed.buffer );
|
|
463
|
-
|
|
464
250
|
const offset = PCDheader.offset;
|
|
465
|
-
|
|
466
251
|
for ( let i = 0; i < PCDheader.points; i ++ ) {
|
|
467
|
-
|
|
468
252
|
if ( offset.x !== undefined ) {
|
|
469
|
-
|
|
470
253
|
const xIndex = PCDheader.fields.indexOf( 'x' );
|
|
471
254
|
const yIndex = PCDheader.fields.indexOf( 'y' );
|
|
472
255
|
const zIndex = PCDheader.fields.indexOf( 'z' );
|
|
473
256
|
position.push( this._getDataView( dataview, ( PCDheader.points * offset.x ) + PCDheader.size[ xIndex ] * i, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
|
|
474
257
|
position.push( this._getDataView( dataview, ( PCDheader.points * offset.y ) + PCDheader.size[ yIndex ] * i, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
|
|
475
258
|
position.push( this._getDataView( dataview, ( PCDheader.points * offset.z ) + PCDheader.size[ zIndex ] * i, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
|
|
476
|
-
|
|
477
259
|
}
|
|
478
|
-
|
|
479
260
|
if ( offset.rgb !== undefined ) {
|
|
480
|
-
|
|
481
261
|
const rgbIndex = PCDheader.fields.indexOf( 'rgb' );
|
|
482
|
-
|
|
483
262
|
const r = dataview.getUint8( ( PCDheader.points * offset.rgb ) + PCDheader.size[ rgbIndex ] * i + 2 ) / 255.0;
|
|
484
263
|
const g = dataview.getUint8( ( PCDheader.points * offset.rgb ) + PCDheader.size[ rgbIndex ] * i + 1 ) / 255.0;
|
|
485
264
|
const b = dataview.getUint8( ( PCDheader.points * offset.rgb ) + PCDheader.size[ rgbIndex ] * i + 0 ) / 255.0;
|
|
486
|
-
|
|
487
265
|
c.setRGB( r, g, b, three.SRGBColorSpace );
|
|
488
|
-
|
|
489
266
|
color.push( c.r, c.g, c.b );
|
|
490
|
-
|
|
491
267
|
}
|
|
492
|
-
|
|
493
268
|
if ( offset.normal_x !== undefined ) {
|
|
494
|
-
|
|
495
269
|
const xIndex = PCDheader.fields.indexOf( 'normal_x' );
|
|
496
270
|
const yIndex = PCDheader.fields.indexOf( 'normal_y' );
|
|
497
271
|
const zIndex = PCDheader.fields.indexOf( 'normal_z' );
|
|
498
272
|
normal.push( this._getDataView( dataview, ( PCDheader.points * offset.normal_x ) + PCDheader.size[ xIndex ] * i, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
|
|
499
273
|
normal.push( this._getDataView( dataview, ( PCDheader.points * offset.normal_y ) + PCDheader.size[ yIndex ] * i, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
|
|
500
274
|
normal.push( this._getDataView( dataview, ( PCDheader.points * offset.normal_z ) + PCDheader.size[ zIndex ] * i, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
|
|
501
|
-
|
|
502
275
|
}
|
|
503
|
-
|
|
504
276
|
if ( offset.intensity !== undefined ) {
|
|
505
|
-
|
|
506
277
|
const intensityIndex = PCDheader.fields.indexOf( 'intensity' );
|
|
507
278
|
intensity.push( this._getDataView( dataview, ( PCDheader.points * offset.intensity ) + PCDheader.size[ intensityIndex ] * i, PCDheader.type[ intensityIndex ], PCDheader.size[ intensityIndex ] ) );
|
|
508
|
-
|
|
509
279
|
}
|
|
510
|
-
|
|
511
280
|
if ( offset.label !== undefined ) {
|
|
512
|
-
|
|
513
281
|
const labelIndex = PCDheader.fields.indexOf( 'label' );
|
|
514
282
|
label.push( dataview.getInt32( ( PCDheader.points * offset.label ) + PCDheader.size[ labelIndex ] * i, this.littleEndian ) );
|
|
515
|
-
|
|
516
283
|
}
|
|
517
|
-
|
|
518
284
|
}
|
|
519
|
-
|
|
520
285
|
}
|
|
521
|
-
|
|
522
|
-
// binary
|
|
523
|
-
|
|
524
286
|
if ( PCDheader.data === 'binary' ) {
|
|
525
|
-
|
|
526
287
|
const dataview = new DataView( data, PCDheader.headerLen );
|
|
527
288
|
const offset = PCDheader.offset;
|
|
528
|
-
|
|
529
289
|
for ( let i = 0, row = 0; i < PCDheader.points; i ++, row += PCDheader.rowSize ) {
|
|
530
|
-
|
|
531
290
|
if ( offset.x !== undefined ) {
|
|
532
|
-
|
|
533
291
|
const xIndex = PCDheader.fields.indexOf( 'x' );
|
|
534
292
|
const yIndex = PCDheader.fields.indexOf( 'y' );
|
|
535
293
|
const zIndex = PCDheader.fields.indexOf( 'z' );
|
|
536
294
|
position.push( this._getDataView( dataview, row + offset.x, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
|
|
537
295
|
position.push( this._getDataView( dataview, row + offset.y, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
|
|
538
296
|
position.push( this._getDataView( dataview, row + offset.z, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
|
|
539
|
-
|
|
540
297
|
}
|
|
541
|
-
|
|
542
298
|
if ( offset.rgb !== undefined ) {
|
|
543
|
-
|
|
544
299
|
const r = dataview.getUint8( row + offset.rgb + 2 ) / 255.0;
|
|
545
300
|
const g = dataview.getUint8( row + offset.rgb + 1 ) / 255.0;
|
|
546
301
|
const b = dataview.getUint8( row + offset.rgb + 0 ) / 255.0;
|
|
547
|
-
|
|
548
302
|
c.setRGB( r, g, b, three.SRGBColorSpace );
|
|
549
|
-
|
|
550
303
|
color.push( c.r, c.g, c.b );
|
|
551
|
-
|
|
552
304
|
}
|
|
553
|
-
|
|
554
305
|
if ( offset.normal_x !== undefined ) {
|
|
555
|
-
|
|
556
306
|
const xIndex = PCDheader.fields.indexOf( 'normal_x' );
|
|
557
307
|
const yIndex = PCDheader.fields.indexOf( 'normal_y' );
|
|
558
308
|
const zIndex = PCDheader.fields.indexOf( 'normal_z' );
|
|
559
309
|
normal.push( this._getDataView( dataview, row + offset.normal_x, PCDheader.type[ xIndex ], PCDheader.size[ xIndex ] ) );
|
|
560
310
|
normal.push( this._getDataView( dataview, row + offset.normal_y, PCDheader.type[ yIndex ], PCDheader.size[ yIndex ] ) );
|
|
561
311
|
normal.push( this._getDataView( dataview, row + offset.normal_z, PCDheader.type[ zIndex ], PCDheader.size[ zIndex ] ) );
|
|
562
|
-
|
|
563
312
|
}
|
|
564
|
-
|
|
565
313
|
if ( offset.intensity !== undefined ) {
|
|
566
|
-
|
|
567
314
|
const intensityIndex = PCDheader.fields.indexOf( 'intensity' );
|
|
568
315
|
intensity.push( this._getDataView( dataview, row + offset.intensity, PCDheader.type[ intensityIndex ], PCDheader.size[ intensityIndex ] ) );
|
|
569
|
-
|
|
570
316
|
}
|
|
571
|
-
|
|
572
317
|
if ( offset.label !== undefined ) {
|
|
573
|
-
|
|
574
318
|
label.push( dataview.getInt32( row + offset.label, this.littleEndian ) );
|
|
575
|
-
|
|
576
319
|
}
|
|
577
|
-
|
|
578
320
|
}
|
|
579
|
-
|
|
580
321
|
}
|
|
581
|
-
|
|
582
|
-
// build geometry
|
|
583
|
-
|
|
584
322
|
const geometry = new three.BufferGeometry();
|
|
585
|
-
|
|
586
323
|
if ( position.length > 0 ) geometry.setAttribute( 'position', new three.Float32BufferAttribute( position, 3 ) );
|
|
587
324
|
if ( normal.length > 0 ) geometry.setAttribute( 'normal', new three.Float32BufferAttribute( normal, 3 ) );
|
|
588
325
|
if ( color.length > 0 ) geometry.setAttribute( 'color', new three.Float32BufferAttribute( color, 3 ) );
|
|
589
326
|
if ( intensity.length > 0 ) geometry.setAttribute( 'intensity', new three.Float32BufferAttribute( intensity, 1 ) );
|
|
590
327
|
if ( label.length > 0 ) geometry.setAttribute( 'label', new three.Int32BufferAttribute( label, 1 ) );
|
|
591
|
-
|
|
592
328
|
geometry.computeBoundingSphere();
|
|
593
|
-
|
|
594
|
-
// build material
|
|
595
|
-
|
|
596
329
|
const material = new three.PointsMaterial( { size: 0.005 } );
|
|
597
|
-
|
|
598
330
|
if ( color.length > 0 ) {
|
|
599
|
-
|
|
600
331
|
material.vertexColors = true;
|
|
601
|
-
|
|
602
332
|
}
|
|
603
|
-
|
|
604
|
-
// build point cloud
|
|
605
|
-
|
|
606
333
|
return new three.Points( geometry, material );
|
|
607
|
-
|
|
608
334
|
}
|
|
609
|
-
|
|
610
335
|
}
|
|
611
336
|
|
|
612
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
613
|
-
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
614
|
-
// All rights reserved.
|
|
615
|
-
//
|
|
616
|
-
// This software and its documentation and related materials are owned by
|
|
617
|
-
// the Alliance. The software may only be incorporated into application
|
|
618
|
-
// programs owned by members of the Alliance, subject to a signed
|
|
619
|
-
// Membership Agreement and Supplemental Software License Agreement with the
|
|
620
|
-
// Alliance. The structure and organization of this software are the valuable
|
|
621
|
-
// trade secrets of the Alliance and its suppliers. The software is also
|
|
622
|
-
// protected by copyright law and international treaty provisions. Application
|
|
623
|
-
// programs incorporating this software must include the following statement
|
|
624
|
-
// with their copyright notices:
|
|
625
|
-
//
|
|
626
|
-
// This application incorporates Open Design Alliance software pursuant to a
|
|
627
|
-
// license agreement with Open Design Alliance.
|
|
628
|
-
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
629
|
-
// All rights reserved.
|
|
630
|
-
//
|
|
631
|
-
// By use of this software, its documentation or related materials, you
|
|
632
|
-
// acknowledge and accept the above terms.
|
|
633
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
634
|
-
|
|
635
|
-
|
|
636
337
|
const THREE = {
|
|
637
338
|
Box3: three.Box3,
|
|
638
339
|
BufferAttribute: three.BufferAttribute,
|
|
@@ -653,8 +354,6 @@
|
|
|
653
354
|
Scene: three.Scene,
|
|
654
355
|
Vector3: three.Vector3,
|
|
655
356
|
};
|
|
656
|
-
|
|
657
|
-
// ifcx-core/layers/layer-providers.ts
|
|
658
357
|
var StackedLayerProvider = class {
|
|
659
358
|
providers;
|
|
660
359
|
constructor(providers) {
|
|
@@ -676,7 +375,7 @@
|
|
|
676
375
|
var InMemoryLayerProvider = class {
|
|
677
376
|
layers;
|
|
678
377
|
constructor() {
|
|
679
|
-
this.layers =
|
|
378
|
+
this.layers = new Map();
|
|
680
379
|
}
|
|
681
380
|
GetLayerByURI(uri) {
|
|
682
381
|
if (!this.layers.has(uri)) {
|
|
@@ -701,12 +400,10 @@
|
|
|
701
400
|
console.log(`${JSON.stringify(arguments)}`);
|
|
702
401
|
}
|
|
703
402
|
}
|
|
704
|
-
|
|
705
|
-
// ifcx-core/layers/fetch-layer-provider.ts
|
|
706
403
|
var FetchLayerProvider = class {
|
|
707
404
|
layers;
|
|
708
405
|
constructor() {
|
|
709
|
-
this.layers =
|
|
406
|
+
this.layers = new Map();
|
|
710
407
|
}
|
|
711
408
|
async FetchJson(url) {
|
|
712
409
|
let result = await fetch(url);
|
|
@@ -733,8 +430,6 @@
|
|
|
733
430
|
return this.layers.get(uri);
|
|
734
431
|
}
|
|
735
432
|
};
|
|
736
|
-
|
|
737
|
-
// ifcx-core/util/mm.ts
|
|
738
433
|
function MMSet(map, key, value) {
|
|
739
434
|
if (map.has(key)) {
|
|
740
435
|
map.get(key)?.push(value);
|
|
@@ -742,12 +437,10 @@
|
|
|
742
437
|
map.set(key, [value]);
|
|
743
438
|
}
|
|
744
439
|
}
|
|
745
|
-
|
|
746
|
-
// ifcx-core/composition/cycles.ts
|
|
747
440
|
var CycleError = class extends Error {};
|
|
748
441
|
function FindRootsOrCycles(nodes) {
|
|
749
|
-
let dependencies =
|
|
750
|
-
let dependents =
|
|
442
|
+
let dependencies = new Map();
|
|
443
|
+
let dependents = new Map();
|
|
751
444
|
nodes.forEach((node, path) => {
|
|
752
445
|
Object.keys(node.inherits).forEach((inheritName) => {
|
|
753
446
|
MMSet(dependencies, path, node.inherits[inheritName]);
|
|
@@ -771,7 +464,7 @@
|
|
|
771
464
|
}
|
|
772
465
|
perm[path] = true;
|
|
773
466
|
}
|
|
774
|
-
let roots =
|
|
467
|
+
let roots = new Set();
|
|
775
468
|
try {
|
|
776
469
|
paths.forEach((path) => {
|
|
777
470
|
if (!dependents.has(path) && path.indexOf("/") === -1) {
|
|
@@ -784,8 +477,6 @@
|
|
|
784
477
|
}
|
|
785
478
|
return roots;
|
|
786
479
|
}
|
|
787
|
-
|
|
788
|
-
// ifcx-core/composition/path.ts
|
|
789
480
|
function GetHead(path) {
|
|
790
481
|
return path.split("/")[0];
|
|
791
482
|
}
|
|
@@ -794,13 +485,11 @@
|
|
|
794
485
|
parts.shift();
|
|
795
486
|
return parts.join("/");
|
|
796
487
|
}
|
|
797
|
-
|
|
798
|
-
// ifcx-core/composition/node.ts
|
|
799
488
|
function MakePostCompositionNode(node) {
|
|
800
489
|
return {
|
|
801
490
|
node,
|
|
802
|
-
children:
|
|
803
|
-
attributes:
|
|
491
|
+
children: new Map(),
|
|
492
|
+
attributes: new Map(),
|
|
804
493
|
};
|
|
805
494
|
}
|
|
806
495
|
function GetChildNodeWithPath(node, path) {
|
|
@@ -816,8 +505,6 @@
|
|
|
816
505
|
return null;
|
|
817
506
|
}
|
|
818
507
|
}
|
|
819
|
-
|
|
820
|
-
// ifcx-core/composition/compose.ts
|
|
821
508
|
function FlattenPathToPreCompositionNode(path, inputNodes) {
|
|
822
509
|
let compositionNode = {
|
|
823
510
|
path,
|
|
@@ -844,7 +531,7 @@
|
|
|
844
531
|
return compositionNode;
|
|
845
532
|
}
|
|
846
533
|
function FlattenCompositionInput(input) {
|
|
847
|
-
let compositionNodes =
|
|
534
|
+
let compositionNodes = new Map();
|
|
848
535
|
for (let [path, inputNodes] of input) {
|
|
849
536
|
compositionNodes.set(path, FlattenPathToPreCompositionNode(path, inputNodes));
|
|
850
537
|
}
|
|
@@ -864,8 +551,8 @@
|
|
|
864
551
|
}
|
|
865
552
|
let pseudoRoot = {
|
|
866
553
|
node: "",
|
|
867
|
-
attributes:
|
|
868
|
-
children:
|
|
554
|
+
attributes: new Map(),
|
|
555
|
+
children: new Map(),
|
|
869
556
|
};
|
|
870
557
|
roots.forEach((root) => {
|
|
871
558
|
pseudoRoot.children.set(root, ComposeNodeFromPath(root, nodes));
|
|
@@ -911,8 +598,6 @@
|
|
|
911
598
|
node.attributes.set(attrID, attr);
|
|
912
599
|
});
|
|
913
600
|
}
|
|
914
|
-
|
|
915
|
-
// ifcx-core/schema/schema-validation.ts
|
|
916
601
|
var SchemaValidationError = class extends Error {};
|
|
917
602
|
function ValidateAttributeValue(desc, value, path, schemas) {
|
|
918
603
|
if (desc.optional && value === void 0) {
|
|
@@ -1009,10 +694,8 @@
|
|
|
1009
694
|
});
|
|
1010
695
|
});
|
|
1011
696
|
}
|
|
1012
|
-
|
|
1013
|
-
// ifcx-core/workflows.ts
|
|
1014
697
|
function ToInputNodes(data) {
|
|
1015
|
-
let inputNodes =
|
|
698
|
+
let inputNodes = new Map();
|
|
1016
699
|
data.forEach((ifcxNode) => {
|
|
1017
700
|
let node = {
|
|
1018
701
|
path: ifcxNode.path,
|
|
@@ -1110,10 +793,7 @@
|
|
|
1110
793
|
});
|
|
1111
794
|
return result;
|
|
1112
795
|
}
|
|
1113
|
-
|
|
1114
|
-
// ifcx-core/layers/layer-stack.ts
|
|
1115
796
|
var IfcxLayerStack = class {
|
|
1116
|
-
// main layer at 0
|
|
1117
797
|
layers;
|
|
1118
798
|
tree;
|
|
1119
799
|
schemas;
|
|
@@ -1193,7 +873,7 @@
|
|
|
1193
873
|
return activeLayer;
|
|
1194
874
|
}
|
|
1195
875
|
let layerSet = [activeLayer];
|
|
1196
|
-
let placed =
|
|
876
|
+
let placed = new Map();
|
|
1197
877
|
placed.set(activeLayer.header.id, true);
|
|
1198
878
|
let result = await this.SatisfyDependencies(activeLayer, placed, layerSet);
|
|
1199
879
|
if (result instanceof Error) {
|
|
@@ -1202,8 +882,6 @@
|
|
|
1202
882
|
return layerSet;
|
|
1203
883
|
}
|
|
1204
884
|
};
|
|
1205
|
-
|
|
1206
|
-
// viewer/compose-flattened.ts
|
|
1207
885
|
function TreeNodeToComposedObject(path, node, schemas) {
|
|
1208
886
|
let co = {
|
|
1209
887
|
name: path,
|
|
@@ -1261,123 +939,26 @@
|
|
|
1261
939
|
});
|
|
1262
940
|
return TreeNodeToComposedObject("", layerStack.GetFullTree(), layerStack.GetSchemas());
|
|
1263
941
|
}
|
|
1264
|
-
// var controls;
|
|
1265
|
-
// var renderer;
|
|
1266
942
|
var scene;
|
|
1267
943
|
var camera;
|
|
1268
944
|
var datas = [];
|
|
1269
945
|
var autoCamera = true;
|
|
1270
946
|
var objectMap = {};
|
|
1271
|
-
// var domMap = {};
|
|
1272
947
|
var primMap = {};
|
|
1273
|
-
// var currentPathMapping = null;
|
|
1274
|
-
// var rootPrim = null;
|
|
1275
|
-
// var selectedObject = null;
|
|
1276
|
-
// var selectedDom = null;
|
|
1277
|
-
// var raycaster = new THREE.Raycaster();
|
|
1278
|
-
// var mouse = new THREE.Vector2();
|
|
1279
948
|
var envMap;
|
|
1280
949
|
function init() {
|
|
1281
950
|
scene = new THREE.Scene();
|
|
1282
|
-
// const ambient = new THREE.AmbientLight(14544639, 0.4);
|
|
1283
|
-
// scene.add(ambient);
|
|
1284
|
-
// const keyLight = new THREE.DirectionalLight(16777215, 1);
|
|
1285
|
-
// keyLight.position.set(5, -10, 7.5);
|
|
1286
|
-
// scene.add(keyLight);
|
|
1287
|
-
// const fillLight = new THREE.DirectionalLight(16777215, 0.5);
|
|
1288
|
-
// fillLight.position.set(-5, 5, 5);
|
|
1289
|
-
// scene.add(fillLight);
|
|
1290
|
-
// const rimLight = new THREE.DirectionalLight(16777215, 0.3);
|
|
1291
|
-
// rimLight.position.set(0, 8, -10);
|
|
1292
|
-
// scene.add(rimLight);
|
|
1293
951
|
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
1294
952
|
camera.up.set(0, 0, 1);
|
|
1295
953
|
camera.position.set(50, 50, 50);
|
|
1296
954
|
camera.lookAt(0, 0, 0);
|
|
1297
955
|
scene.add(camera);
|
|
1298
|
-
// const nd = document.querySelector(".viewport");
|
|
1299
|
-
// renderer = new THREE.WebGLRenderer({
|
|
1300
|
-
// alpha: true,
|
|
1301
|
-
// logarithmicDepthBuffer: true,
|
|
1302
|
-
// });
|
|
1303
|
-
// const pmremGenerator = new THREE.PMREMGenerator(renderer);
|
|
1304
|
-
// pmremGenerator.compileEquirectangularShader();
|
|
1305
|
-
// new RGBELoader().load("images/wildflower_field_1k.hdr", function (texture) {
|
|
1306
|
-
// envMap = pmremGenerator.fromEquirectangular(texture).texture;
|
|
1307
|
-
// scene.environment = envMap;
|
|
1308
|
-
// texture.dispose();
|
|
1309
|
-
// pmremGenerator.dispose();
|
|
1310
|
-
// });
|
|
1311
|
-
// renderer.setSize(nd.offsetWidth, nd.offsetHeight);
|
|
1312
|
-
// controls = new OrbitControls(camera, renderer.domElement);
|
|
1313
|
-
// controls.enableDamping = true;
|
|
1314
|
-
// controls.dampingFactor = 0.25;
|
|
1315
|
-
// nd.appendChild(renderer.domElement);
|
|
1316
|
-
// renderer.domElement.addEventListener("click", onCanvasClick);
|
|
1317
956
|
return scene;
|
|
1318
957
|
}
|
|
1319
958
|
function HasAttr(node, attrName) {
|
|
1320
959
|
if (!node || !node.attributes) return false;
|
|
1321
960
|
return !!node.attributes[attrName];
|
|
1322
961
|
}
|
|
1323
|
-
// function setHighlight(obj, highlight) {
|
|
1324
|
-
// if (!obj) return;
|
|
1325
|
-
// obj.traverse((o) => {
|
|
1326
|
-
// const mat = o.material;
|
|
1327
|
-
// if (mat && mat.color) {
|
|
1328
|
-
// if (highlight) {
|
|
1329
|
-
// if (!o.userData._origColor) {
|
|
1330
|
-
// o.userData._origColor = mat.color.clone();
|
|
1331
|
-
// }
|
|
1332
|
-
// o.material = mat.clone();
|
|
1333
|
-
// o.material.color.set(16711680);
|
|
1334
|
-
// } else if (o.userData._origColor) {
|
|
1335
|
-
// mat.color.copy(o.userData._origColor);
|
|
1336
|
-
// delete o.userData._origColor;
|
|
1337
|
-
// }
|
|
1338
|
-
// }
|
|
1339
|
-
// });
|
|
1340
|
-
// }
|
|
1341
|
-
// function selectPath(path) {
|
|
1342
|
-
// if (!path) {
|
|
1343
|
-
// if (selectedObject) setHighlight(selectedObject, false);
|
|
1344
|
-
// if (selectedDom) selectedDom.classList.remove("selected");
|
|
1345
|
-
// selectedObject = null;
|
|
1346
|
-
// selectedDom = null;
|
|
1347
|
-
// return;
|
|
1348
|
-
// }
|
|
1349
|
-
// if (selectedObject) {
|
|
1350
|
-
// setHighlight(selectedObject, false);
|
|
1351
|
-
// }
|
|
1352
|
-
// if (selectedDom) {
|
|
1353
|
-
// selectedDom.classList.remove("selected");
|
|
1354
|
-
// }
|
|
1355
|
-
// selectedObject = objectMap[path] || null;
|
|
1356
|
-
// selectedDom = domMap[path] || null;
|
|
1357
|
-
// if (selectedObject) setHighlight(selectedObject, true);
|
|
1358
|
-
// if (selectedDom) selectedDom.classList.add("selected");
|
|
1359
|
-
// }
|
|
1360
|
-
// function onCanvasClick(event) {
|
|
1361
|
-
// const rect = renderer.domElement.getBoundingClientRect();
|
|
1362
|
-
// mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
|
|
1363
|
-
// mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
|
|
1364
|
-
// raycaster.setFromCamera(mouse, camera);
|
|
1365
|
-
// const intersects = raycaster.intersectObjects(Object.values(objectMap), true);
|
|
1366
|
-
// if (intersects.length > 0) {
|
|
1367
|
-
// let obj = intersects[0].object;
|
|
1368
|
-
// while (obj && !obj.userData.path) obj = obj.parent;
|
|
1369
|
-
// if (obj && obj.userData.path) {
|
|
1370
|
-
// const path = obj.userData.path;
|
|
1371
|
-
// const prim = primMap[path];
|
|
1372
|
-
// if (prim) {
|
|
1373
|
-
// handleClick(prim, currentPathMapping, rootPrim || prim);
|
|
1374
|
-
// }
|
|
1375
|
-
// selectPath(path);
|
|
1376
|
-
// }
|
|
1377
|
-
// } else {
|
|
1378
|
-
// selectPath(null);
|
|
1379
|
-
// }
|
|
1380
|
-
// }
|
|
1381
962
|
function tryCreateMeshGltfMaterial(path) {
|
|
1382
963
|
for (let p of path) {
|
|
1383
964
|
if (!p.attributes) {
|
|
@@ -1584,112 +1165,12 @@
|
|
|
1584
1165
|
}
|
|
1585
1166
|
(node.children || []).forEach((child) => traverseTree([child, ...path], elem || parent, pathMapping));
|
|
1586
1167
|
}
|
|
1587
|
-
// function encodeHtmlEntities(str) {
|
|
1588
|
-
// const div = document.createElement("div");
|
|
1589
|
-
// div.textContent = str;
|
|
1590
|
-
// return div.innerHTML;
|
|
1591
|
-
// }
|
|
1592
|
-
// var icons = {
|
|
1593
|
-
// "usd::usdgeom::mesh::points": "deployed_code",
|
|
1594
|
-
// "usd::usdgeom::basiscurves::points": "line_curve",
|
|
1595
|
-
// "usd::usdshade::material::outputs::surface.connect": "line_style",
|
|
1596
|
-
// "pcd::base64": "grain",
|
|
1597
|
-
// "points::array::positions": "grain",
|
|
1598
|
-
// "points::base64::positions": "grain",
|
|
1599
|
-
// };
|
|
1600
|
-
// function handleClick(prim, pathMapping, root) {
|
|
1601
|
-
// const container = document.querySelector(".attributes .table");
|
|
1602
|
-
// if (container !== null) {
|
|
1603
|
-
// container.innerHTML = "";
|
|
1604
|
-
// const table = document.createElement("table");
|
|
1605
|
-
// table.setAttribute("border", "0");
|
|
1606
|
-
// const entries = [
|
|
1607
|
-
// ["name", prim.name],
|
|
1608
|
-
// ...Object.entries(prim.attributes).filter(([k, _]) => !k.startsWith("__internal_")),
|
|
1609
|
-
// ];
|
|
1610
|
-
// const format = (value) => {
|
|
1611
|
-
// if (Array.isArray(value)) {
|
|
1612
|
-
// let N = document.createElement("span");
|
|
1613
|
-
// N.appendChild(document.createTextNode("("));
|
|
1614
|
-
// let first = true;
|
|
1615
|
-
// for (let n of value.map(format)) {
|
|
1616
|
-
// if (!first) {
|
|
1617
|
-
// N.appendChild(document.createTextNode(","));
|
|
1618
|
-
// }
|
|
1619
|
-
// N.appendChild(n);
|
|
1620
|
-
// first = false;
|
|
1621
|
-
// }
|
|
1622
|
-
// N.appendChild(document.createTextNode(")"));
|
|
1623
|
-
// return N;
|
|
1624
|
-
// } else if (typeof value === "object") {
|
|
1625
|
-
// const ks = Object.keys(value);
|
|
1626
|
-
// if (ks.length == 1 && ks[0] === "ref" && pathMapping[value.ref] && pathMapping[value.ref].length == 1) {
|
|
1627
|
-
// let a = document.createElement("a");
|
|
1628
|
-
// let resolvedRefAsPath = pathMapping[value.ref][0];
|
|
1629
|
-
// a.setAttribute("href", "#");
|
|
1630
|
-
// a.textContent = resolvedRefAsPath;
|
|
1631
|
-
// a.onclick = () => {
|
|
1632
|
-
// let prim2 = null;
|
|
1633
|
-
// const recurse = (n) => {
|
|
1634
|
-
// if (n.name === resolvedRefAsPath) {
|
|
1635
|
-
// prim2 = n;
|
|
1636
|
-
// } else {
|
|
1637
|
-
// (n.children || []).forEach(recurse);
|
|
1638
|
-
// }
|
|
1639
|
-
// };
|
|
1640
|
-
// recurse(root);
|
|
1641
|
-
// if (prim2) {
|
|
1642
|
-
// handleClick(prim2, pathMapping, root);
|
|
1643
|
-
// }
|
|
1644
|
-
// };
|
|
1645
|
-
// return a;
|
|
1646
|
-
// } else {
|
|
1647
|
-
// return document.createTextNode(JSON.stringify(value));
|
|
1648
|
-
// }
|
|
1649
|
-
// } else {
|
|
1650
|
-
// return document.createTextNode(value);
|
|
1651
|
-
// }
|
|
1652
|
-
// };
|
|
1653
|
-
// entries.forEach(([key, value]) => {
|
|
1654
|
-
// const tr = document.createElement("tr");
|
|
1655
|
-
// const tdKey = document.createElement("td");
|
|
1656
|
-
// tdKey.textContent = encodeHtmlEntities(key);
|
|
1657
|
-
// const tdValue = document.createElement("td");
|
|
1658
|
-
// tdValue.appendChild(format(value));
|
|
1659
|
-
// tr.appendChild(tdKey);
|
|
1660
|
-
// tr.appendChild(tdValue);
|
|
1661
|
-
// table.appendChild(tr);
|
|
1662
|
-
// });
|
|
1663
|
-
// container.appendChild(table);
|
|
1664
|
-
// }
|
|
1665
|
-
// }
|
|
1666
|
-
// function buildDomTree(prim, node, pathMapping, root = null) {
|
|
1667
|
-
// const elem = document.createElement("div");
|
|
1668
|
-
// let span;
|
|
1669
|
-
// elem.appendChild(document.createTextNode(prim.name ? prim.name.split("/").reverse()[0] : "root"));
|
|
1670
|
-
// elem.appendChild((span = document.createElement("span")));
|
|
1671
|
-
// Object.entries(icons).forEach(([k, v]) => (span.innerText += (prim.attributes || {})[k] ? v : " "));
|
|
1672
|
-
// span.className = "material-symbols-outlined";
|
|
1673
|
-
// domMap[prim.name] = elem;
|
|
1674
|
-
// elem.dataset.path = prim.name;
|
|
1675
|
-
// elem.onclick = (evt) => {
|
|
1676
|
-
// handleClick(prim, pathMapping, root || prim);
|
|
1677
|
-
// selectPath(prim.name);
|
|
1678
|
-
// evt.stopPropagation();
|
|
1679
|
-
// };
|
|
1680
|
-
// node.appendChild(elem);
|
|
1681
|
-
// (prim.children || []).forEach((p) => buildDomTree(p, elem, pathMapping, root || prim));
|
|
1682
|
-
// }
|
|
1683
1168
|
async function composeAndRender() {
|
|
1684
1169
|
if (scene) {
|
|
1685
1170
|
scene.children = [];
|
|
1686
1171
|
}
|
|
1687
1172
|
objectMap = {};
|
|
1688
|
-
// domMap = {};
|
|
1689
1173
|
primMap = {};
|
|
1690
|
-
// currentPathMapping = null;
|
|
1691
|
-
// rootPrim = null;
|
|
1692
|
-
// document.querySelector(".tree").innerHTML = "";
|
|
1693
1174
|
if (datas.length === 0) {
|
|
1694
1175
|
return;
|
|
1695
1176
|
}
|
|
@@ -1705,8 +1186,6 @@
|
|
|
1705
1186
|
}
|
|
1706
1187
|
let pathMapping = {};
|
|
1707
1188
|
traverseTree([tree], scene, pathMapping);
|
|
1708
|
-
// currentPathMapping = pathMapping;
|
|
1709
|
-
// rootPrim = tree;
|
|
1710
1189
|
if (autoCamera) {
|
|
1711
1190
|
const boundingBox = new THREE.Box3();
|
|
1712
1191
|
boundingBox.setFromObject(scene);
|
|
@@ -1716,55 +1195,10 @@
|
|
|
1716
1195
|
camera.position.copy(avg.clone().add(new THREE.Vector3(1, 1, 1).normalize().multiplyScalar(ext)));
|
|
1717
1196
|
camera.far = ext * 3;
|
|
1718
1197
|
camera.updateProjectionMatrix();
|
|
1719
|
-
// controls.target.copy(avg);
|
|
1720
|
-
// controls.update();
|
|
1721
1198
|
autoCamera = false;
|
|
1722
1199
|
}
|
|
1723
1200
|
}
|
|
1724
|
-
// buildDomTree(tree, document.querySelector(".tree"), pathMapping);
|
|
1725
|
-
// animate();
|
|
1726
1201
|
}
|
|
1727
|
-
// function createLayerDom() {
|
|
1728
|
-
// document.querySelector(".layers div").innerHTML = "";
|
|
1729
|
-
// datas.forEach(([name, _], index) => {
|
|
1730
|
-
// const elem = document.createElement("div");
|
|
1731
|
-
// elem.appendChild(document.createTextNode(name));
|
|
1732
|
-
// ["\u25B3", "\u25BD", "\xD7"].reverse().forEach((lbl, cmd) => {
|
|
1733
|
-
// const btn = document.createElement("span");
|
|
1734
|
-
// btn.onclick = (evt) => {
|
|
1735
|
-
// evt.stopPropagation();
|
|
1736
|
-
// if (cmd === 2) {
|
|
1737
|
-
// if (index > 0) {
|
|
1738
|
-
// [datas[index], datas[index - 1]] = [datas[index - 1], datas[index]];
|
|
1739
|
-
// }
|
|
1740
|
-
// } else if (cmd === 1) {
|
|
1741
|
-
// if (index < datas.length - 1) {
|
|
1742
|
-
// [datas[index], datas[index + 1]] = [datas[index + 1], datas[index]];
|
|
1743
|
-
// }
|
|
1744
|
-
// } else if (cmd === 0) {
|
|
1745
|
-
// datas.splice(index, 1);
|
|
1746
|
-
// }
|
|
1747
|
-
// composeAndRender();
|
|
1748
|
-
// createLayerDom();
|
|
1749
|
-
// };
|
|
1750
|
-
// btn.appendChild(document.createTextNode(lbl));
|
|
1751
|
-
// elem.appendChild(btn);
|
|
1752
|
-
// });
|
|
1753
|
-
// document.querySelector(".layers div").appendChild(elem);
|
|
1754
|
-
// });
|
|
1755
|
-
// }
|
|
1756
|
-
// async function addModel(name, m) {
|
|
1757
|
-
// datas.push([name, m]);
|
|
1758
|
-
// createLayerDom();
|
|
1759
|
-
// await composeAndRender();
|
|
1760
|
-
// }
|
|
1761
|
-
// function animate() {
|
|
1762
|
-
// requestAnimationFrame(animate);
|
|
1763
|
-
// controls.update();
|
|
1764
|
-
// renderer.render(scene, camera);
|
|
1765
|
-
// }
|
|
1766
|
-
// export { composeAndRender, addModel as default };
|
|
1767
|
-
|
|
1768
1202
|
async function parse(m, name) {
|
|
1769
1203
|
datas.push([name, m]);
|
|
1770
1204
|
await composeAndRender();
|
|
@@ -1776,28 +1210,6 @@
|
|
|
1776
1210
|
autoCamera = true;
|
|
1777
1211
|
}
|
|
1778
1212
|
|
|
1779
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1780
|
-
// Copyright (C) 2002-2024, Open Design Alliance (the "Alliance").
|
|
1781
|
-
// All rights reserved.
|
|
1782
|
-
//
|
|
1783
|
-
// This software and its documentation and related materials are owned by
|
|
1784
|
-
// the Alliance. The software may only be incorporated into application
|
|
1785
|
-
// programs owned by members of the Alliance, subject to a signed
|
|
1786
|
-
// Membership Agreement and Supplemental Software License Agreement with the
|
|
1787
|
-
// Alliance. The structure and organization of this software are the valuable
|
|
1788
|
-
// trade secrets of the Alliance and its suppliers. The software is also
|
|
1789
|
-
// protected by copyright law and international treaty provisions. Application
|
|
1790
|
-
// programs incorporating this software must include the following statement
|
|
1791
|
-
// with their copyright notices:
|
|
1792
|
-
//
|
|
1793
|
-
// This application incorporates Open Design Alliance software pursuant to a
|
|
1794
|
-
// license agreement with Open Design Alliance.
|
|
1795
|
-
// Open Design Alliance Copyright (C) 2002-2024 by Open Design Alliance.
|
|
1796
|
-
// All rights reserved.
|
|
1797
|
-
//
|
|
1798
|
-
// By use of this software, its documentation or related materials, you
|
|
1799
|
-
// acknowledge and accept the above terms.
|
|
1800
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1801
1213
|
class IFCXLoader extends three.Loader {
|
|
1802
1214
|
load(url, onLoad, onProgress, onError) {
|
|
1803
1215
|
const manager = this.manager;
|
|
@@ -1829,28 +1241,6 @@
|
|
|
1829
1241
|
}
|
|
1830
1242
|
}
|
|
1831
1243
|
|
|
1832
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1833
|
-
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
1834
|
-
// All rights reserved.
|
|
1835
|
-
//
|
|
1836
|
-
// This software and its documentation and related materials are owned by
|
|
1837
|
-
// the Alliance. The software may only be incorporated into application
|
|
1838
|
-
// programs owned by members of the Alliance, subject to a signed
|
|
1839
|
-
// Membership Agreement and Supplemental Software License Agreement with the
|
|
1840
|
-
// Alliance. The structure and organization of this software are the valuable
|
|
1841
|
-
// trade secrets of the Alliance and its suppliers. The software is also
|
|
1842
|
-
// protected by copyright law and international treaty provisions. Application
|
|
1843
|
-
// programs incorporating this software must include the following statement
|
|
1844
|
-
// with their copyright notices:
|
|
1845
|
-
//
|
|
1846
|
-
// This application incorporates Open Design Alliance software pursuant to a
|
|
1847
|
-
// license agreement with Open Design Alliance.
|
|
1848
|
-
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
1849
|
-
// All rights reserved.
|
|
1850
|
-
//
|
|
1851
|
-
// By use of this software, its documentation or related materials, you
|
|
1852
|
-
// acknowledge and accept the above terms.
|
|
1853
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1854
1244
|
class IFCXFileLoader extends viewerThree.Loader {
|
|
1855
1245
|
constructor(viewer) {
|
|
1856
1246
|
super();
|
|
@@ -1892,28 +1282,6 @@
|
|
|
1892
1282
|
}
|
|
1893
1283
|
}
|
|
1894
1284
|
|
|
1895
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1896
|
-
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
1897
|
-
// All rights reserved.
|
|
1898
|
-
//
|
|
1899
|
-
// This software and its documentation and related materials are owned by
|
|
1900
|
-
// the Alliance. The software may only be incorporated into application
|
|
1901
|
-
// programs owned by members of the Alliance, subject to a signed
|
|
1902
|
-
// Membership Agreement and Supplemental Software License Agreement with the
|
|
1903
|
-
// Alliance. The structure and organization of this software are the valuable
|
|
1904
|
-
// trade secrets of the Alliance and its suppliers. The software is also
|
|
1905
|
-
// protected by copyright law and international treaty provisions. Application
|
|
1906
|
-
// programs incorporating this software must include the following statement
|
|
1907
|
-
// with their copyright notices:
|
|
1908
|
-
//
|
|
1909
|
-
// This application incorporates Open Design Alliance software pursuant to a
|
|
1910
|
-
// license agreement with Open Design Alliance.
|
|
1911
|
-
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
1912
|
-
// All rights reserved.
|
|
1913
|
-
//
|
|
1914
|
-
// By use of this software, its documentation or related materials, you
|
|
1915
|
-
// acknowledge and accept the above terms.
|
|
1916
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1917
1285
|
class IFCXCloudLoader extends viewerThree.Loader {
|
|
1918
1286
|
constructor(viewer) {
|
|
1919
1287
|
super();
|
|
@@ -1954,28 +1322,6 @@
|
|
|
1954
1322
|
}
|
|
1955
1323
|
}
|
|
1956
1324
|
|
|
1957
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1958
|
-
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
1959
|
-
// All rights reserved.
|
|
1960
|
-
//
|
|
1961
|
-
// This software and its documentation and related materials are owned by
|
|
1962
|
-
// the Alliance. The software may only be incorporated into application
|
|
1963
|
-
// programs owned by members of the Alliance, subject to a signed
|
|
1964
|
-
// Membership Agreement and Supplemental Software License Agreement with the
|
|
1965
|
-
// Alliance. The structure and organization of this software are the valuable
|
|
1966
|
-
// trade secrets of the Alliance and its suppliers. The software is also
|
|
1967
|
-
// protected by copyright law and international treaty provisions. Application
|
|
1968
|
-
// programs incorporating this software must include the following statement
|
|
1969
|
-
// with their copyright notices:
|
|
1970
|
-
//
|
|
1971
|
-
// This application incorporates Open Design Alliance software pursuant to a
|
|
1972
|
-
// license agreement with Open Design Alliance.
|
|
1973
|
-
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
1974
|
-
// All rights reserved.
|
|
1975
|
-
//
|
|
1976
|
-
// By use of this software, its documentation or related materials, you
|
|
1977
|
-
// acknowledge and accept the above terms.
|
|
1978
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1979
1325
|
viewerThree.loaders.registerLoader("ifcx-file", (viewer) => new IFCXFileLoader(viewer));
|
|
1980
1326
|
viewerThree.loaders.registerLoader("ifcx-cloud", (viewer) => new IFCXCloudLoader(viewer));
|
|
1981
1327
|
|