-
Notifications
You must be signed in to change notification settings - Fork 373
/
Copy pathindex.json
9870 lines (9870 loc) · 753 KB
/
index.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[
{
"__docId__": 1,
"kind": "external",
"name": "Infinity",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Infinity",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 2,
"kind": "external",
"name": "NaN",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~NaN",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 3,
"kind": "external",
"name": "undefined",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~undefined",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 4,
"kind": "external",
"name": "null",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~null",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 5,
"kind": "external",
"name": "Object",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Object",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 6,
"kind": "external",
"name": "object",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~object",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 7,
"kind": "external",
"name": "Function",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Function",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 8,
"kind": "external",
"name": "function",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~function",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 9,
"kind": "external",
"name": "Boolean",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Boolean",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 10,
"kind": "external",
"name": "boolean",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~boolean",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 11,
"kind": "external",
"name": "Symbol",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Symbol",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 12,
"kind": "external",
"name": "Error",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Error",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 13,
"kind": "external",
"name": "EvalError",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~EvalError",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 14,
"kind": "external",
"name": "InternalError",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~InternalError",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 15,
"kind": "external",
"name": "RangeError",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~RangeError",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 16,
"kind": "external",
"name": "ReferenceError",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~ReferenceError",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 17,
"kind": "external",
"name": "SyntaxError",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~SyntaxError",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 18,
"kind": "external",
"name": "TypeError",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~TypeError",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 19,
"kind": "external",
"name": "URIError",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~URIError",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 20,
"kind": "external",
"name": "Number",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Number",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 21,
"kind": "external",
"name": "number",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~number",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 22,
"kind": "external",
"name": "Date",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Date",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 23,
"kind": "external",
"name": "String",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~String",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 24,
"kind": "external",
"name": "string",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~string",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 25,
"kind": "external",
"name": "RegExp",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~RegExp",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 26,
"kind": "external",
"name": "Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 27,
"kind": "external",
"name": "Int8Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Int8Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 28,
"kind": "external",
"name": "Uint8Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Uint8Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 29,
"kind": "external",
"name": "Uint8ClampedArray",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Uint8ClampedArray",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 30,
"kind": "external",
"name": "Int16Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Int16Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 31,
"kind": "external",
"name": "Uint16Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Uint16Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 32,
"kind": "external",
"name": "Int32Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Int32Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 33,
"kind": "external",
"name": "Uint32Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Uint32Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 34,
"kind": "external",
"name": "Float32Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Float32Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 35,
"kind": "external",
"name": "Float64Array",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Float64Array",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 36,
"kind": "external",
"name": "Map",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Map",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 37,
"kind": "external",
"name": "Set",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Set",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 38,
"kind": "external",
"name": "WeakMap",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~WeakMap",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 39,
"kind": "external",
"name": "WeakSet",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~WeakSet",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 40,
"kind": "external",
"name": "ArrayBuffer",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~ArrayBuffer",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 41,
"kind": "external",
"name": "DataView",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~DataView",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 42,
"kind": "external",
"name": "JSON",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~JSON",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 43,
"kind": "external",
"name": "Promise",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Promise",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 44,
"kind": "external",
"name": "Generator",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Generator",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 45,
"kind": "external",
"name": "GeneratorFunction",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~GeneratorFunction",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 46,
"kind": "external",
"name": "Reflect",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Reflect",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 47,
"kind": "external",
"name": "Proxy",
"externalLink": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy",
"memberof": "src/.external-ecmascript.js",
"static": true,
"longname": "src/.external-ecmascript.js~Proxy",
"access": "public",
"description": "",
"builtinExternal": true
},
{
"__docId__": 48,
"kind": "file",
"name": "src/BIMViewer.js",
"content": "import {BCFViewpointsPlugin, FastNavPlugin, math, stats, Viewer,} from \"@xeokit/xeokit-sdk/dist/xeokit-sdk.es.js\";\n\nimport {Controller} from \"./Controller.js\";\nimport {BusyModal} from \"./BusyModal.js\";\nimport {ResetAction} from \"./toolbar/ResetAction.js\";\nimport {FitAction} from \"./toolbar/FitAction.js\";\nimport {FirstPersonMode} from \"./toolbar/FirstPersonMode.js\";\nimport {HideTool} from \"./toolbar/HideTool.js\";\nimport {SelectionTool} from \"./toolbar/SelectionTool.js\";\nimport {ShowSpacesMode} from \"./toolbar/ShowSpacesMode.js\";\nimport {QueryTool} from \"./toolbar/QueryTool.js\";\nimport {SectionTool} from \"./toolbar/SectionTool.js\";\nimport {NavCubeMode} from \"./toolbar/NavCubeMode.js\";\n\nimport {ModelsExplorer} from \"./explorer/ModelsExplorer.js\";\nimport {ObjectsExplorer} from \"./explorer/ObjectsExplorer.js\";\nimport {ClassesExplorer} from \"./explorer/ClassesExplorer.js\";\nimport {StoreysExplorer} from \"./explorer/StoreysExplorer.js\";\n\nimport {ThreeDMode} from \"./toolbar/ThreeDMode.js\";\nimport {ObjectContextMenu} from \"./contextMenus/ObjectContextMenu.js\";\nimport {CanvasContextMenu} from \"./contextMenus/CanvasContextMenu.js\";\nimport {OrthoMode} from \"./toolbar/OrthoMode.js\";\nimport {PropertiesInspector} from \"./inspector/PropertiesInspector.js\";\nimport {ObjectsKdTree3} from \"./collision/ObjectsKdTree3.js\";\nimport {MarqueeSelectionTool} from \"./toolbar/MarqueeSelectionTool.js\";\n\n\nconst hideEdgesMinDrawCount = 5; // FastNavPlugin enables dynamic edges when xeokit's per-frame draw count drops below this\nconst scaleCanvasResolutionMinDrawCount = 1000; // FastNavPlugin switches to low-res canvas when xeokit's per-frame draw count rises above this\n\nfunction createExplorerTemplate(cfg) {\n const explorerTemplate = `<div class=\"xeokit-tabs\"> \n <div class=\"xeokit-tab xeokit-modelsTab\">\n <a class=\"xeokit-i18n xeokit-tab-btn\" href=\"#\" data-xeokit-i18n=\"modelsExplorer.title\">Models</a>\n <div class=\"xeokit-tab-content\">\n <div class=\"xeokit-btn-group\">\n <button type=\"button\" class=\"xeokit-i18n xeokit-loadAllModels xeokit-btn disabled\" data-xeokit-i18n=\"modelsExplorer.loadAll\" data-xeokit-i18ntip=\"modelsExplorer.loadAllTip\" data-tippy-content=\"Load all models\">Load all</button>\n <button type=\"button\" class=\"xeokit-i18n xeokit-unloadAllModels xeokit-btn disabled\" data-xeokit-i18n=\"modelsExplorer.unloadAll\" data-xeokit-i18ntip=\"modelsExplorer.unloadAllTip\" data-tippy-content=\"Unload all models\">Unload all</button>` +\n (cfg.enableEditModels ? `<button type=\"button\" class=\"xeokit-i18n xeokit-addModel xeokit-btn disabled\" data-xeokit-i18n=\"modelsExplorer.add\" data-xeokit-i18ntip=\"modelsExplorer.addTip\" data-tippy-content=\"Add model\">Add</button>` : ``) + `</div>\n <div class=\"xeokit-models\" ></div>\n </div>\n </div>\n <div class=\"xeokit-tab xeokit-objectsTab\">\n <a class=\"xeokit-i18n xeokit-tab-btn disabled\" href=\"#\" data-xeokit-i18n=\"objectsExplorer.title\">Objects</a>\n <div class=\"xeokit-tab-content\">\n <div class=\"xeokit-btn-group\">\n <button type=\"button\" class=\"xeokit-i18n xeokit-showAllObjects xeokit-btn disabled\" data-xeokit-i18n=\"objectsExplorer.showAll\" data-xeokit-i18ntip=\"objectsExplorer.showAllTip\" data-tippy-content=\"Show all objects\">Show all</button>\n <button type=\"button\" class=\"xeokit-i18n xeokit-hideAllObjects xeokit-btn disabled\" data-xeokit-i18n=\"objectsExplorer.hideAll\" data-xeokit-i18ntip=\"objectsExplorer.hideAllTip\" data-tippy-content=\"Hide all objects\">Hide all</button>\n </div>\n <div class=\"xeokit-objects xeokit-tree-panel\" ></div>\n </div>\n </div>\n <div class=\"xeokit-i18n xeokit-tab xeokit-classesTab\">\n <a class=\"xeokit-i18n xeokit-tab-btn disabled\" href=\"#\" data-xeokit-i18n=\"classesExplorer.title\">Classes</a>\n <div class=\"xeokit-tab-content\">\n <div class=\"xeokit-btn-group\">\n <button type=\"button\" class=\"xeokit-i18n xeokit-showAllClasses xeokit-btn disabled\" data-xeokit-i18n=\"classesExplorer.showAll\" data-xeokit-i18ntip=\"classesExplorer.hideAllTip\" data-tippy-content=\"Show all classes\">Show all</button>\n <button type=\"button\" class=\"xeokit-i18n xeokit-hideAllClasses xeokit-btn disabled\" data-xeokit-i18n=\"classesExplorer.hideAll\" data-xeokit-i18ntip=\"classesExplorer.hideAllTip\" data-tippy-content=\"Hide all classes\">Hide all</button>\n </div>\n <div class=\"xeokit-classes xeokit-tree-panel\" ></div>\n </div>\n </div>\n <div class=\"xeokit-tab xeokit-storeysTab\">\n <a class=\"xeokit-i18n xeokit-tab-btn disabled\" href=\"#\" data-xeokit-i18n=\"storeysExplorer.title\">Storeys</a>\n <div class=\"xeokit-tab-content\">\n <div class=\"xeokit-btn-group\">\n <button type=\"button\" class=\"xeokit-i18n xeokit-showAllStoreys xeokit-btn disabled\" data-xeokit-i18n=\"storeysExplorer.showAll\" data-xeokit-i18ntip=\"storeysExplorer.showAllTip\" data-tippy-content=\"Show all storeys\">Show all</button>\n <button type=\"button\" class=\"xeokit-i18n xeokit-hideAllStoreys xeokit-btn disabled\" data-xeokit-i18n=\"storeysExplorer.hideAll\" data-xeokit-i18ntip=\"storeysExplorer.hideAllTip\" data-tippy-content=\"Hide all storeys\">Hide all</button>\n </div>\n <div class=\"xeokit-storeys xeokit-tree-panel\"></div>\n </div>\n </div>\n</div>`;\n return explorerTemplate;\n}\n\nfunction createToolbarTemplate() {\n const toolbarTemplate = `<div class=\"xeokit-toolbar\">\n <!-- Reset button -->\n <div class=\"xeokit-btn-group\">\n <button type=\"button\" class=\"xeokit-i18n xeokit-reset xeokit-btn fa fa-home fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.resetViewTip\" data-tippy-content=\"Reset view\"></button>\n </div>\n <div class=\"xeokit-btn-group\" role=\"group\">\n <!-- 3D Mode button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-threeD xeokit-btn fa fa-cube fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.toggle2d3dTip\" data-tippy-content=\"Toggle 2D/3D\"></button>\n <!-- Perspective/Ortho Mode button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-ortho xeokit-btn fa fa-th fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.togglePerspectiveTip\" data-tippy-content=\"Toggle Perspective/Ortho\"></button>\n <!-- Fit button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-fit xeokit-btn fa fa-crop fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.viewFitTip\" data-tippy-content=\"View fit\"></button>\n <!-- First Person mode button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-firstPerson xeokit-btn fa fa-male fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.firstPersonTip\" data-tippy-content=\"Toggle first-person mode\"></button>\n <!-- Show/hide IFCSpaces -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-showSpaces xeokit-btn fab fa-codepen fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.showSpacesTip\" data-tippy-content=\"Show IFCSpaces\"></button> \n </div>\n <!-- Tools button group -->\n <div class=\"xeokit-btn-group\" role=\"group\">\n <!-- Hide tool button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-hide xeokit-btn fa fa-eraser fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.hideObjectsTip\" data-tippy-content=\"Hide objects\"></button>\n <!-- Select tool button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-select xeokit-btn fa fa-mouse-pointer fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.selectObjectsTip\" data-tippy-content=\"Select objects\"></button> \n <!-- Marquee select tool button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-marquee xeokit-btn fas fa-object-group fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.marqueeSelectTip\" data-tippy-content=\"Marquee select objects\"></button> \n <!-- section tool button -->\n <button type=\"button\" class=\"xeokit-i18n xeokit-section xeokit-btn fa fa-cut fa-2x disabled\" data-xeokit-i18ntip=\"toolbar.sliceObjectsTip\" data-tippy-content=\"Slice objects\">\n <div class=\"xeokit-i18n xeokit-section-menu-button disabled\" data-xeokit-i18ntip=\"toolbar.slicesMenuTip\" data-tippy-content=\"Slices menu\">\n <span class=\"xeokit-arrow-down xeokit-section-menu-button-arrow\"></span>\n </div>\n <div class=\"xeokit-i18n xeokit-section-counter\" data-xeokit-i18ntip=\"toolbar.numSlicesTip\" data-tippy-content=\"Number of existing slices\"></div>\n </button>\n </div>\n</div>`;\n return toolbarTemplate;\n}\n\nfunction createInspectorTemplate() {\n const inspectorTemplate = `<div class=\"xeokit-tabs\"> \n <div class=\"xeokit-tab xeokit-propertiesTab\">\n <a class=\"xeokit-i18n xeokit-tab-btn disabled\" href=\"#\" data-xeokit-i18n=\"propertiesInspector.title\">Properties</a>\n <div class=\"xeokit-tab-content\"> \n <div class=\"xeokit-properties\"></div>\n </div>\n </div>\n</div>`;\n return inspectorTemplate;\n}\n\nfunction initTabs(containerElement) {\n\n const tabsClass = 'xeokit-tabs';\n const tabClass = 'xeokit-tab';\n const tabButtonClass = 'xeokit-tab-btn';\n const activeClass = 'active';\n\n // Activates the chosen tab and deactivates the rest\n function activateTab(chosenTabElement) {\n let tabList = chosenTabElement.parentNode.querySelectorAll('.' + tabClass);\n for (let i = 0; i < tabList.length; i++) {\n let tabElement = tabList[i];\n if (tabElement.isEqualNode(chosenTabElement)) {\n tabElement.classList.add(activeClass)\n } else {\n tabElement.classList.remove(activeClass)\n }\n }\n }\n\n // Initialize each tabbed container\n let tabbedContainers = containerElement.querySelectorAll('.' + tabsClass);\n for (let i = 0; i < tabbedContainers.length; i++) {\n let tabbedContainer = tabbedContainers[i];\n let tabList = tabbedContainer.querySelectorAll('.' + tabClass);\n activateTab(tabList[0]);\n for (let i = 0; i < tabList.length; i++) {\n let tabElement = tabList[i];\n let tabButton = tabElement.querySelector('.' + tabButtonClass);\n tabButton.addEventListener('click', function (event) {\n event.preventDefault();\n if (this.classList.contains(\"disabled\")) {\n return;\n }\n activateTab(event.target.parentNode);\n })\n }\n }\n}\n\n\n/**\n * @desc A BIM viewer based on the [xeokit SDK](http://xeokit.io).\n *\n *\n */\nclass BIMViewer extends Controller {\n\n /**\n * Constructs a BIMViewer.\n * @param {Server} server Data access strategy.\n * @param {*} cfg Configuration.\n * @param {Boolean} [cfg.enableEditModels=false] Set ````true```` to show \"Add\", \"Edit\" and \"Delete\" options in the Models tab's context menu.\n * @param {Boolean} [cfg.keyboardEventsElement] Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document.\n */\n constructor(server, cfg = {}) {\n\n if (!cfg.canvasElement) {\n throw \"Config expected: canvasElement\";\n }\n\n if (!cfg.explorerElement) {\n throw \"Config expected: explorerElement\";\n }\n\n if (!cfg.toolbarElement) {\n throw \"Config expected: toolbarElement\";\n }\n\n if (!cfg.navCubeCanvasElement) {\n throw \"Config expected: navCubeCanvasElement\";\n }\n\n const canvasElement = cfg.canvasElement;\n const explorerElement = cfg.explorerElement;\n const inspectorElement = cfg.inspectorElement;\n const toolbarElement = cfg.toolbarElement;\n const navCubeCanvasElement = cfg.navCubeCanvasElement;\n const busyModelBackdropElement = cfg.busyModelBackdropElement;\n\n explorerElement.oncontextmenu = (e) => {\n e.preventDefault();\n };\n\n toolbarElement.oncontextmenu = (e) => {\n e.preventDefault();\n };\n\n navCubeCanvasElement.oncontextmenu = (e) => {\n e.preventDefault();\n };\n\n const viewer = new Viewer({\n localeService: cfg.localeService,\n canvasElement: canvasElement,\n keyboardEventsElement: cfg.keyboardEventsElement,\n transparent: false,\n backgroundColor: [1, 1, 1],\n backgroundColorFromAmbientLight: false,\n saoEnabled: true,\n pbrEnabled: false,\n colorTextureEnabled: true\n });\n\n super(null, cfg, server, viewer);\n\n this._configs = {};\n\n this._enableAddModels = !!cfg.enableEditModels;\n this._enablePropertiesInspector = !!cfg.inspectorElement;\n\n /**\n * The xeokit [Viewer](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html) at the core of this BIMViewer.\n *\n * @type {Viewer}\n */\n this.viewer = viewer;\n\n this._objectsKdTree3 = new ObjectsKdTree3(({\n viewer\n }))\n\n this._customizeViewer();\n this._initCanvasContextMenus();\n\n explorerElement.innerHTML = createExplorerTemplate(cfg);\n toolbarElement.innerHTML = createToolbarTemplate();\n if (this._enablePropertiesInspector) {\n inspectorElement.innerHTML = createInspectorTemplate();\n }\n\n this._explorerElement = explorerElement;\n this._inspectorElement = inspectorElement;\n\n initTabs(explorerElement);\n if (this._enablePropertiesInspector) {\n initTabs(inspectorElement);\n }\n\n this._modelsExplorer = new ModelsExplorer(this, {\n modelsTabElement: explorerElement.querySelector(\".xeokit-modelsTab\"),\n loadModelsButtonElement: explorerElement.querySelector(\".xeokit-loadAllModels\"), // Can be undefined\n unloadModelsButtonElement: explorerElement.querySelector(\".xeokit-unloadAllModels\"),\n addModelButtonElement: explorerElement.querySelector(\".xeokit-addModel\"), // Can be undefined\n modelsElement: explorerElement.querySelector(\".xeokit-models\"),\n enableEditModels: this._enableAddModels\n });\n\n this._objectsExplorer = new ObjectsExplorer(this, {\n objectsTabElement: explorerElement.querySelector(\".xeokit-objectsTab\"),\n showAllObjectsButtonElement: explorerElement.querySelector(\".xeokit-showAllObjects\"),\n hideAllObjectsButtonElement: explorerElement.querySelector(\".xeokit-hideAllObjects\"),\n objectsElement: explorerElement.querySelector(\".xeokit-objects\")\n });\n\n this._classesExplorer = new ClassesExplorer(this, {\n classesTabElement: explorerElement.querySelector(\".xeokit-classesTab\"),\n showAllClassesButtonElement: explorerElement.querySelector(\".xeokit-showAllClasses\"),\n hideAllClassesButtonElement: explorerElement.querySelector(\".xeokit-hideAllClasses\"),\n classesElement: explorerElement.querySelector(\".xeokit-classes\")\n });\n\n this._storeysExplorer = new StoreysExplorer(this, {\n storeysTabElement: explorerElement.querySelector(\".xeokit-storeysTab\"),\n showAllStoreysButtonElement: explorerElement.querySelector(\".xeokit-showAllStoreys\"),\n hideAllStoreysButtonElement: explorerElement.querySelector(\".xeokit-hideAllStoreys\"),\n storeysElement: explorerElement.querySelector(\".xeokit-storeys\")\n });\n\n if (this._enablePropertiesInspector) {\n this._propertiesInspector = new PropertiesInspector(this, {\n propertiesTabElement: inspectorElement.querySelector(\".xeokit-propertiesTab\"),\n propertiesElement: inspectorElement.querySelector(\".xeokit-properties\")\n });\n }\n\n this._resetAction = new ResetAction(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-reset\"),\n active: false\n });\n\n this._fitAction = new FitAction(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-fit\"),\n active: false\n });\n\n // Allows Three-D and First Person toggle buttons to cooperatively switch\n // CameraControl#navMode between \"orbit\", \"firstPerson\" and \"planView\" modes\n\n const cameraControlNavModeMediator = new (function (bimViewer) {\n\n let threeDActive = false;\n let firstPersonActive = false;\n\n this.setThreeDModeActive = (active) => {\n if (active) {\n bimViewer._firstPersonMode.setActive(false);\n bimViewer._marqueeSelectionTool.setEnabled(true);\n bimViewer.viewer.cameraControl.navMode = \"orbit\";\n } else {\n bimViewer._marqueeSelectionTool.setEnabled(false);\n bimViewer._marqueeSelectionTool.setActive(false);\n bimViewer._firstPersonMode.setActive(false);\n bimViewer.viewer.cameraControl.navMode = \"planView\";\n }\n threeDActive = active;\n };\n\n this.setFirstPersonModeActive = (active) => {\n bimViewer.viewer.cameraControl.navMode = active ? \"firstPerson\" : (threeDActive ? \"orbit\" : \"planView\");\n firstPersonActive = active;\n };\n\n })(this);\n\n this._threeDMode = new ThreeDMode(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-threeD\"),\n cameraControlNavModeMediator,\n active: false\n });\n\n this._orthoMode = new OrthoMode(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-ortho\"),\n active: false\n });\n\n this._firstPersonMode = new FirstPersonMode(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-firstPerson\"),\n cameraControlNavModeMediator,\n active: false\n });\n\n this._hideTool = new HideTool(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-hide\"),\n active: false\n });\n\n this._selectionTool = new SelectionTool(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-select\"),\n active: false\n });\n\n this._marqueeSelectionTool = new MarqueeSelectionTool(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-marquee\"),\n active: false,\n objectsKdTree3: this._objectsKdTree3\n });\n\n this._showSpacesMode = new ShowSpacesMode(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-showSpaces\"),\n active: false\n });\n\n this._queryTool = new QueryTool(this, {\n active: false\n });\n\n this._sectionTool = new SectionTool(this, {\n buttonElement: toolbarElement.querySelector(\".xeokit-section\"),\n counterElement: toolbarElement.querySelector(\".xeokit-section-counter\"),\n menuButtonElement: toolbarElement.querySelector(\".xeokit-section-menu-button\"),\n menuButtonArrowElement: toolbarElement.querySelector(\".xeokit-section-menu-button-arrow\"),\n active: false\n });\n\n this._navCubeMode = new NavCubeMode(this, {\n navCubeCanvasElement: navCubeCanvasElement,\n active: true\n });\n\n this._busyModal = new BusyModal(this, {\n busyModalBackdropElement: busyModelBackdropElement\n });\n\n this._threeDMode.setActive(true);\n this._firstPersonMode.setActive(false);\n this._navCubeMode.setActive(true);\n\n this._modelsExplorer.on(\"modelLoaded\", (modelId) => {\n if (this._modelsExplorer.getNumModelsLoaded() > 0) {\n this.setControlsEnabled(true);\n }\n this.fire(\"modelLoaded\", modelId);\n });\n\n this._modelsExplorer.on(\"modelUnloaded\", (modelId) => {\n if (this._modelsExplorer.getNumModelsLoaded() === 0) {\n this.setControlsEnabled(false);\n this.openTab(\"models\");\n }\n this.fire(\"modelUnloaded\", modelId);\n });\n\n this._resetAction.on(\"reset\", () => {\n this.fire(\"reset\", true);\n });\n\n this._mutexActivation([this._hideTool, this._selectionTool, this._marqueeSelectionTool, this._sectionTool]);\n\n explorerElement.querySelector(\".xeokit-showAllObjects\").addEventListener(\"click\", (event) => {\n this.setAllObjectsVisible(true);\n this.setAllObjectsXRayed(false);\n event.preventDefault();\n });\n\n explorerElement.querySelector(\".xeokit-hideAllObjects\").addEventListener(\"click\", (event) => {\n this.setAllObjectsVisible(false);\n event.preventDefault();\n });\n\n explorerElement.querySelector(\".xeokit-showAllClasses\").addEventListener(\"click\", (event) => {\n this.setAllObjectsVisible(true);\n this.setAllObjectsXRayed(false);\n event.preventDefault();\n });\n\n explorerElement.querySelector(\".xeokit-hideAllClasses\").addEventListener(\"click\", (event) => {\n this.setAllObjectsVisible(false);\n event.preventDefault();\n });\n\n explorerElement.querySelector(\".xeokit-showAllStoreys\").addEventListener(\"click\", (event) => {\n this.setAllObjectsVisible(true);\n this.setAllObjectsXRayed(false);\n event.preventDefault();\n });\n\n explorerElement.querySelector(\".xeokit-hideAllStoreys\").addEventListener(\"click\", (event) => {\n this.setAllObjectsVisible(false);\n event.preventDefault();\n });\n\n explorerElement.querySelector(\".xeokit-loadAllModels\").addEventListener(\"click\", (event) => {\n this.setControlsEnabled(false); // For quick UI feedback\n this.loadAllModels();\n event.preventDefault();\n });\n\n explorerElement.querySelector(\".xeokit-unloadAllModels\").addEventListener(\"click\", (event) => {\n this.setControlsEnabled(false); // For quick UI feedback\n this._modelsExplorer.unloadAllModels();\n event.preventDefault();\n });\n\n if (this._enableAddModels) {\n explorerElement.querySelector(\".xeokit-addModel\").addEventListener(\"click\", (event) => {\n this.fire(\"addModel\", {});\n event.preventDefault();\n });\n }\n\n this._bcfViewpointsPlugin = new BCFViewpointsPlugin(this.viewer, {});\n\n this._fastNavPlugin = new FastNavPlugin(viewer, {\n hideEdges: true,\n hideSAO: true,\n hidePBR: false,\n hideColorTexture: false,\n hideTransparentObjects: false,\n scaleCanvasResolution: false,\n scaleCanvasResolutionFactor: 0.6\n });\n\n this.viewer.scene.on(\"rendered\", () => {\n const fastNavPlugin = this._fastNavPlugin;\n fastNavPlugin.hideEdges = (hideEdgesMinDrawCount < (stats.frame.drawElements + stats.frame.drawArrays));\n fastNavPlugin.scaleCanvasResolution = (scaleCanvasResolutionMinDrawCount < (stats.frame.drawElements + stats.frame.drawArrays));\n });\n\n this._initConfigs();\n this.setControlsEnabled(false);\n }\n\n /**\n * Returns the LocaleService that was configured on this Viewer.\n *\n * @return {LocaleService} The LocaleService.\n */\n get localeService() {\n return this.viewer.localeService;\n }\n\n _customizeViewer() {\n\n const scene = this.viewer.scene;\n\n // Emphasis effects\n\n scene.xrayMaterial.fill = false;\n scene.xrayMaterial.fillAlpha = 0.3;\n scene.xrayMaterial.fillColor = [0, 0, 0];\n scene.xrayMaterial.edges = true;\n scene.xrayMaterial.edgeAlpha = 0.1;\n scene.xrayMaterial.edgeColor = [0, 0, 0];\n\n scene.highlightMaterial.edges = true;\n scene.highlightMaterial.edgeColor = [1, 1, 0];\n scene.highlightMaterial.edgeAlpha = 0.9;\n scene.highlightMaterial.fill = true;\n scene.highlightMaterial.fillAlpha = 0.1;\n scene.highlightMaterial.fillColor = [1, 0, 0];\n\n //------------------------------------------------------------------------------------------------------------------\n // Configure points material\n //------------------------------------------------------------------------------------------------------------------\n\n scene.pointsMaterial.pointSize = 1;\n scene.pointsMaterial.roundPoints = true;\n scene.pointsMaterial.perspectivePoints = true;\n scene.pointsMaterial.minPerspectivePointSize = 2;\n scene.pointsMaterial.maxPerspectivePointSize = 4;\n\n // Camera control\n\n this.viewer.cameraControl.panRightClick = true;\n this.viewer.cameraControl.followPointer = true;\n this.viewer.cameraControl.doublePickFlyTo = false;\n this.viewer.cameraControl.smartPivot = true;\n\n // Dolly tweaks for best precision when aligning camera for BCF snapshots\n\n this.viewer.cameraControl.keyboardDollyRate = 100.0;\n this.viewer.cameraControl.mouseWheelDollyRate = 100.0;\n this.viewer.cameraControl.dollyInertia = 0;\n this.viewer.cameraControl.dollyMinSpeed = 0.04;\n this.viewer.cameraControl.dollyProximityThreshold = 30.0;\n\n const cameraPivotElement = document.createRange().createContextualFragment(\"<div class='xeokit-camera-pivot-marker'></div>\").firstChild;\n document.body.appendChild(cameraPivotElement);\n this.viewer.cameraControl.pivotElement = cameraPivotElement;\n\n scene.camera.perspective.near = 0.01;\n scene.camera.perspective.far = 3000.0;\n scene.camera.ortho.near = 0.01;\n scene.camera.ortho.far = 2000.0; //\n\n // Scalable Ambient Obscurance (SAO) defaults\n // Since SAO is non-interactive, set to higher-quality\n\n const sao = scene.sao;\n sao.enabled = true;\n sao.numSamples = 50;\n sao.kernelRadius = 200;\n }\n\n _initCanvasContextMenus() {\n\n this._canvasContextMenu = new CanvasContextMenu(this, {\n hideOnAction: true\n });\n this._objectContextMenu = new ObjectContextMenu(this, {\n hideOnAction: true\n });\n\n this.viewer.cameraControl.on(\"rightClick\", (e) => {\n\n const event = e.event;\n\n const hit = this.viewer.scene.pick({\n canvasPos: e.canvasPos\n });\n\n if (hit && hit.entity.isObject) {\n this._canvasContextMenu.hide();\n this._objectContextMenu.context = {\n viewer: this.viewer,\n bimViewer: this,\n showObjectInExplorers: (objectId) => {\n const openTabId = this.getOpenTab();\n if (openTabId !== \"objects\" && openTabId !== \"classes\" && openTabId !== \"storeys\") {\n // Scroll won't work if tab not open\n this.openTab(\"objects\");\n }\n this.showObjectInExplorers(objectId);\n },\n entity: hit.entity\n };\n this._objectContextMenu.show(e.pagePos[0], e.pagePos[1]);\n } else {\n this._objectContextMenu.hide();\n this._canvasContextMenu.context = {\n viewer: this.viewer,\n bimViewer: this\n };\n this._canvasContextMenu.show(e.pagePos[0], e.pagePos[1]);\n }\n });\n }\n\n _initConfigs() {\n this.setConfigs({\n \"cameraNear\": \"0.05\",\n \"cameraFar\": \"3000.0\",\n \"smartPivot\": \"true\",\n \"saoEnabled\": \"true\",\n \"pbrEnabled\": \"false\",\n \"saoBias\": \"0.5\",\n \"saoIntensity\": \"0.15\",\n \"saoNumSamples\": \"40\",\n \"saoKernelRadius\": \"100\",\n \"edgesEnabled\": true,\n \"xrayContext\": true,\n \"xrayPickable\": false,\n \"selectedGlowThrough\": true,\n \"highlightGlowThrough\": true,\n \"backgroundColor\": [1.0, 1.0, 1.0],\n \"externalMetadata\": false,\n \"dtxEnabled\" : false\n });\n }\n\n /**\n * Sets a batch of viewer configurations.\n *\n * Note that this method is not to be confused with {@link BIMViewer#setViewerState}, which batch-updates various states of the viewer's UI and 3D view.\n *\n * See [Viewer Configurations](https://xeokit.github.io/xeokit-bim-viewer/docs/#viewer-configurations) for the list of available configurations.\n *\n * @param {*} viewerConfigs Map of key-value configuration pairs.\n */\n setConfigs(viewerConfigs) {\n for (let name in viewerConfigs) {\n if (viewerConfigs.hasOwnProperty(name)) {\n const value = viewerConfigs[name];\n this.setConfig(name, value);\n }\n }\n }\n\n /**\n * Sets a viewer configuration.\n *\n * See [Viewer Configurations](https://xeokit.github.io/xeokit-bim-viewer/docs/#viewer-configurations) for the list of available configurations.\n *\n * @param {String} name Configuration name.\n * @param {*} value Configuration value.\n */\n setConfig(name, value) {\n\n function parseBool(value) {\n return ((value === true) || (value === \"true\"));\n }\n\n try {\n switch (name) {\n\n case \"backgroundColor\":\n const rgbColor = value;\n this.setBackgroundColor(rgbColor);\n this._configs[name] = rgbColor;\n break;\n\n case \"cameraNear\":\n const near = parseFloat(value);\n this.viewer.scene.camera.perspective.near = near;\n this.viewer.scene.camera.ortho.near = near;\n this._configs[name] = near;\n break;\n\n case \"cameraFar\":\n const far = parseFloat(value);\n this.viewer.scene.camera.perspective.far = far;\n // this.viewer.scene.camera.ortho.far = far;\n this._configs[name] = far;\n break;\n\n case \"smartPivot\":\n this.viewer.cameraControl.smartPivot = this._configs[name] = parseBool(value);\n break;\n\n case \"saoEnabled\":\n this._fastNavPlugin.saoEnabled = this._configs[name] = parseBool(value);\n break;\n\n case \"saoBias\":\n this.viewer.scene.sao.bias = parseFloat(value);\n break;\n\n case \"saoIntensity\":\n this.viewer.scene.sao.intensity = parseFloat(value);\n break;\n\n case \"saoKernelRadius\":\n this.viewer.scene.sao.kernelRadius = this._configs[name] = parseFloat(value);\n break;\n\n case \"saoNumSamples\":\n this.viewer.scene.sao.numSamples = this._configs[name] = parseFloat(value);\n break;\n\n case \"saoBlur\":\n this.viewer.scene.sao.blur = this._configs[name] = parseBool(value);\n break;\n\n case \"edgesEnabled\":\n this._fastNavPlugin.edgesEnabled = this._configs[name] = parseBool(value);\n break;\n\n case \"pbrEnabled\":\n this._fastNavPlugin.pbrEnabled = this._configs[name] = parseBool(value);\n break;\n\n case \"viewFitFOV\":\n this.viewer.cameraFlight.fitFOV = this._configs[name] = parseFloat(value);\n break;\n\n case \"viewFitDuration\":\n this.viewer.cameraFlight.duration = this._configs[name] = parseFloat(value);\n break;\n\n case \"perspectiveFOV\":\n this.viewer.camera.perspective.fov = this._configs[name] = parseFloat(value);\n break;\n\n case \"excludeUnclassifiedObjects\":\n this._configs[name] = parseBool(value);\n break;\n\n case \"xrayContext\":\n this._configs[name] = value;\n break;\n\n case \"xrayPickable\":\n this._configs[name] = parseBool(value);\n break;\n\n case \"selectedGlowThrough\":\n const selectedGlowThrough = this._configs[name] = parseBool(value);\n const selectedMaterial = this.viewer.scene.selectedMaterial;\n selectedMaterial.glowThrough = selectedGlowThrough;\n selectedMaterial.fillAlpha = selectedGlowThrough ? 0.5 : 1.0;\n selectedMaterial.edgeAlpha = selectedGlowThrough ? 0.5 : 1.0;\n break;\n\n case \"highlightGlowThrough\":\n const highlightGlowThrough = this._configs[name] = parseBool(value);\n const highlightMaterial = this.viewer.scene.highlightMaterial;\n highlightMaterial.glowThrough = highlightGlowThrough;\n highlightMaterial.fillAlpha = highlightGlowThrough ? 0.5 : 1.0;\n highlightMaterial.edgeAlpha = highlightGlowThrough ? 0.5 : 1.0;\n break;\n\n case \"externalMetadata\":\n this._configs[name] = parseBool(value);\n break;\n\n case \"showSpaces\":\n this._configs[name] = parseBool(value);\n this._showSpacesMode.setActive(value);\n break;\n\n case \"dtxEnabled\":\n this._configs[name] = parseBool(value);\n this.viewer.scene.dtxEnabled = value;\n break;\n\n case \"objectColors\":\n this._configs[name] = value;\n this._modelsExplorer.setObjectColors(value);\n break;\n\n default:\n this.warn(\"setConfig() - unsupported configuration: '\" + name + \"'\");\n }\n\n } catch (e) {\n this.error(\"setConfig() - failed to configure '\" + name + \"': \" + e);\n }\n }\n\n /**\n * Gets the value of a viewer configuration.\n *\n * These are set with {@link BIMViewer#setConfig} and {@link BIMViewer#setConfigs}.\n *\n * @param {String} name Configuration name.\n * @ereturns {*} Configuration value.\n */\n getConfig(name) {\n return this._configs[name];\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // Content querying methods\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Gets information on all available projects.\n * Gets information on all available projects.\n *\n * See [Getting Info on Available Projects](https://xeokit.github.io/xeokit-bim-viewer/docs/#getting-info-on-available-projects) for usage.\n *\n * @param {Function} done Callback invoked on success, into which the projects information JSON is passed.\n * @param {Function} error Callback invoked on failure, into which the error message string is passed.\n */\n getProjectsInfo(done, error) {\n if (!done) {\n this.error(\"getProjectsInfo() - Argument expected: 'done'\");\n return;\n }\n this.server.getProjects(done, (errorMsg) => {\n this.error(\"getProjectsInfo() - \" + errorMsg);\n if (error) {\n error(errorMsg);\n }\n });\n }\n\n /**\n * Gets information on the given project.\n *\n * See [Getting Info on a Project](https://xeokit.github.io/xeokit-bim-viewer/docs/#getting-info-on-a-project) for usage.\n *\n * @param {String} projectId ID of the project to get information on. Must be the ID of one of the projects in the information obtained by {@link BIMViewer#getProjects}.\n * @param {Function} done Callback invoked on success, into which the project information JSON is passed.\n * @param {Function} error Callback invoked on failure, into which the error message string is passed.\n */\n getProjectInfo(projectId, done, error) {\n if (!projectId) {\n this.error(\"getProjectInfo() - Argument expected: projectId\");\n return;\n }\n if (!done) {\n this.error(\"getProjectInfo() - Argument expected: 'done'\");\n return;\n }\n this.server.getProject(projectId,\n done, (errorMsg) => {\n this.error(\"getProjectInfo() - \" + errorMsg);\n if (error) {\n error(errorMsg);\n }\n });\n }\n\n /**\n * Gets information on the given object, belonging to the given model, within the given project.\n *\n * See [Getting Info on an Object](https://xeokit.github.io/xeokit-bim-viewer/docs/#getting-info-on-an-object) for usage.\n *\n * @param {String} projectId ID of the project to get information on. Must be the ID of one of the projects in the information obtained by {@link BIMViewer#getProjects}.\n * @param {String} modelId ID of a model within the project. Must be the ID of one of the models in the information obtained by {@link BIMViewer#getProjectInfo}.\n * @param {String} objectId ID of an object in the model.\n * @param {Function} done Callback invoked on success, into which the object information JSON is passed.\n * @param {Function} error Callback invoked on failure, into which the error message string is passed.\n */\n getObjectInfo(projectId, modelId, objectId, done, error) {\n if (!projectId) {\n this.error(\"getObjectInfo() - Argument expected: projectId\");\n return;\n }\n if (!modelId) {\n this.error(\"getObjectInfo() - Argument expected: modelId\");\n return;\n }\n if (!objectId) {\n this.error(\"getObjectInfo() - Argument expected: objectId\");\n return;\n }\n if (!done) {\n this.error(\"getProjectInfo() - Argument expected: 'done'\");\n return;\n }\n this.server.getObjectInfo(projectId, modelId, objectId,\n done,\n (errorMsg) => {\n if (error) {\n error(errorMsg);\n }\n });\n }\n\n //------------------------------------------------------------------------------------------------------------------\n // Content loading methods\n //------------------------------------------------------------------------------------------------------------------\n\n /**\n * Loads a project into the viewer.\n *\n * Unloads any currently loaded project and its models first. If the given project is already loaded, will unload that project first.\n *\n * @param {String} projectId ID of the project to load. Must be the ID of one of the projects in the information obtained by {@link BIMViewer#getProjects}.\n * @param {Function} done Callback invoked on success.\n * @param {Function} error Callback invoked on failure, into which the error message string is passed.\n */\n loadProject(projectId, done, error) {\n if (!projectId) {\n this.error(\"loadProject() - Argument expected: objectId\");\n return;\n }\n this._modelsExplorer.loadProject(projectId,\n () => {\n if (done) {\n done();\n }\n }, (errorMsg) => {\n this.error(\"loadProject() - \" + errorMsg);\n if (error) {\n error(errorMsg);\n }\n });\n }\n\n /**\n * Unloads whatever project is currently loaded.\n */\n unloadProject() {\n this._modelsExplorer.unloadProject();\n this.openTab(\"models\");\n this.setControlsEnabled(false); // For quick UI feedback\n }\n\n /**\n * Returns the ID of the currently loaded project, if any.\n *\n * @returns {String} The ID of the currently loaded project, otherwise ````null```` if no project is currently loaded.\n */\n getLoadedProjectId() {\n return this._modelsExplorer.getLoadedProjectId();\n }\n\n /**\n * Returns the IDs of the models in the currently loaded project.\n *\n * @returns {String[]} The IDs of the models in the currently loaded project.\n */\n getModelIds() {\n return this._modelsExplorer.getModelIds();\n }\n\n /**\n * Loads a model into the viewer.\n *\n * Assumes that the project containing the model is currently loaded.\n *\n * @param {String} modelId ID of the model to load. Must be the ID of one of the models in the currently loaded project.\n * @param {Function} done Callback invoked on success.\n * @param {Function} error Callback invoked on failure, into which the error message string is passed.\n */\n loadModel(modelId, done, error) {\n if (!modelId) {\n this.error(\"loadModel() - Argument expected: modelId\");\n return;\n }\n this._modelsExplorer.loadModel(modelId,\n () => {\n if (done) {\n done();\n }\n }, (errorMsg) => {\n this.error(\"loadModel() - \" + errorMsg);\n if (error) {\n error(errorMsg);\n }\n });\n }\n\n /**\n * Load all models in the currently loaded project.\n *\n * Doesn't reload any models that are currently loaded.\n *\n * @param {Function} done Callback invoked on successful loading of the models.\n */\n loadAllModels(done = function () {\n }) {\n const modelIds = this._modelsExplorer.getModelIds();\n const loadNextModel = (i, done2) => {\n if (i >= modelIds.length) {\n done2();\n } else {\n const modelId = modelIds[i];\n if (!this._modelsExplorer.isModelLoaded(modelId)) {\n this._modelsExplorer.loadModel(modelId, () => {\n loadNextModel(i + 1, done2);\n }, (errorMsg) => {\n this.error(\"loadAllModels() - \" + errorMsg);\n loadNextModel(i + 1, done2);\n });\n } else {\n loadNextModel(i + 1, done2);\n }\n }\n };\n loadNextModel(0, done);\n }\n\n /**\n * Returns the IDs of the currently loaded models, if any.\n *\n * @returns {String[]} The IDs of the currently loaded models, otherwise an empty array if no models are currently loaded.\n */\n getLoadedModelIds() {\n return this._modelsExplorer._getLoadedModelIds();\n }\n\n /**\n * Gets if the given model is loaded.\n *\n * @param {String} modelId ID of the model to check. Must be the ID of one of the models in the currently loaded project.\n * @returns {Boolean} True if the given model is loaded.\n */\n isModelLoaded(modelId) {\n if (!modelId) {\n this.error(\"unloadModel() - Argument expected: modelId\");\n return;\n }\n return this._modelsExplorer.isModelLoaded(modelId);\n }\n\n /**\n * Unloads a model from the viewer.\n *\n * Does nothing if the model is not currently loaded.\n *\n * @param {String} modelId ID of the model to unload.\n */\n unloadModel(modelId) {\n if (!modelId) {\n this.error(\"unloadModel() - Argument expected: modelId\");\n return;\n }\n this._modelsExplorer.unloadModel(modelId);\n }\n\n /**\n * Unloads all currently loaded models.\n */\n unloadAllModels() {\n this._modelsExplorer.unloadAllModels();\n }\n\n /**\n * Edits a model.\n *\n * Assumes that the project containing the model is currently loaded.\n *\n * @param {String} modelId ID of the model to edit. Must be the ID of one of the models in the currently loaded project.\n */\n editModel(modelId) {\n this.fire(\"editModel\", {\n modelId: modelId\n });\n }\n\n /**\n * Deletes a model.\n *\n * Assumes that the project containing the model is currently loaded.\n *\n * @param {String} modelId ID of the model to delete. Must be the ID of one of the models in the currently loaded project.\n */\n deleteModel(modelId) {\n this.fire(\"deleteModel\", {\n modelId: modelId\n });\n }\n\n /**\n * Adds a model.\n *\n */\n addModel() {\n this.fire(\"addModel\", {});\n }\n\n /**\n * Sets the viewer's background color.\n *\n * @param {Number[]} rgbColor Three-element array of RGB values, each in range ````[0..1]````.\n */\n setBackgroundColor(rgbColor) {\n this.viewer.scene.canvas.backgroundColor = rgbColor;\n }\n\n /**\n * Sets where the colors for model objects will be loaded from.\n *\n * Options are:\n *\n * * \"model\" - (default) load colors from models, and\n * * \"viewer\" - load colors from the viewer's inbuilt table of colors for IFC types.\n *\n * This is \"model\" by default.\n *\n * @deprecated\n * @param {String} source Where colors will be loaded from - \"model\" or \"viewer\".\n */\n setObjectColorSource(source) {\n console.log(\"BIMViewer.setObjectColorSource() is now deprecated and no longer functional. By default, \" +\n \"BIMViewer.getObjectColorSource() will now always return the (formerly) default value of `model`.\");\n }\n\n /**\n * Gets where the colors for model objects will be loaded from.\n *\n * This is \"model\" by default.\n *\n * @deprecated\n * @return {String} Where colors will be loaded from - \"model\" to get colors from the model, or \"viewer\" to get them from the viewer's built-in table of colors for IFC types.\n */\n getObjectColorSource() {\n return \"model\";\n }\n\n /**\n * Updates viewer UI state according to the properties in the given object.\n *\n * Note that, since some updates could be animated (e.g. flying the camera to fit objects to view) this\n * method optionally takes a callback, which it invokes after updating the UI.\n *\n * Also, this method is not to be confused with {@link BIMViewer#setConfigs}, which is used to batch-update various configurations and user preferences on the viewer.\n *\n * See [Viewer States](https://xeokit.github.io/xeokit-bim-viewer/docs/#viewer_states) for the list of states that may be batch-updated with this method.\n *\n * @param {Object} viewerState Specifies the viewer UI state updates.\n * @param {Function} done Callback invoked on successful update of the viewer states.\n */\n setViewerState(viewerState, done = () => {\n }) {\n if (viewerState.tabOpen) {\n this.openTab(viewerState.tabOpen);\n }\n if (viewerState.expandObjectsTree) {\n this._objectsExplorer.expandTreeViewToDepth(viewerState.expandObjectsTree);\n }\n if (viewerState.expandClassesTree) {\n this._classesExplorer.expandTreeViewToDepth(viewerState.expandClassesTree);\n }\n if (viewerState.expandStoreysTree) {\n this._storeysExplorer.expandTreeViewToDepth(viewerState.expandStoreysTree);\n }\n if (viewerState.setCamera) {\n this.setCamera(viewerState.setCamera);\n }\n this._parseSelectedStorey(viewerState, () => {\n this._parseThreeDMode(viewerState, () => {\n done();\n });\n });\n }\n\n _parseSelectedStorey(viewerState, done) {\n if (viewerState.selectedStorey) {\n this.selectStorey(viewerState.selectedStorey);\n done();\n } else {\n done();\n }\n }\n\n _parseThreeDMode(viewerState, done) {\n const activateThreeDMode = (viewerState.threeDActive !== false);\n this.set3DEnabled(activateThreeDMode, done);\n }\n\n /**\n * Highlights the given object in the tree views within the Objects, Classes and Storeys tabs.\n *\n * Also scrolls the object's node into view within each tree, then highlights it.\n *\n * De-highlights whatever node is currently highlighted in each of those trees.\n *\n * @param {String} objectId ID of the object\n */\n showObjectInExplorers(objectId) {\n if (!objectId) {\n this.error(\"showObjectInExplorers() - Argument expected: objectId\");\n return;\n }\n this._objectsExplorer.showNodeInTreeView(objectId);\n this._classesExplorer.showNodeInTreeView(objectId);\n this._storeysExplorer.showNodeInTreeView(objectId);\n this.fire(\"openExplorer\", {});\n }\n\n /**\n * De-highlights the object previously highlighted with {@link BIMViewer#showObjectInExplorers}.\n *\n * This only de-highlights the node. If the node is currently scrolled into view, then the node will remain in view.\n *\n * For each tab, does nothing if a node is currently highlighted.\n */\n unShowObjectInExplorers() {\n this._objectsExplorer.unShowNodeInTreeView();\n this._classesExplorer.unShowNodeInTreeView();\n this._storeysExplorer.unShowNodeInTreeView();\n }\n\n /**\n * Shows the properties of the given object in the Properties tab.\n *\n * @param {String} objectId ID of the object\n */\n showObjectProperties(objectId) {\n if (!objectId) {\n this.error(\"showObjectInExplorers() - Argument expected: objectId\");\n return;\n }\n if (this._enablePropertiesInspector) {\n this._propertiesInspector.showObjectPropertySets(objectId);\n }\n this.fire(\"openInspector\", {});\n }\n\n /**\n * Sets whether or not the given objects are visible.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} visible True to set objects visible, false to set them invisible.\n */\n setObjectsVisible(objectIds, visible) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.visible = visible;\n });\n }\n\n /**\n * Sets the visibility of all objects.\n *\n * @param {Boolean} visible True to set objects visible, false to set them invisible.\n */\n setAllObjectsVisible(visible) {\n if (visible) {\n this.viewer.scene.setObjectsVisible(this.viewer.scene.objectIds, true);\n } else {\n this.viewer.scene.setObjectsVisible(this.viewer.scene.visibleObjectIds, false);\n }\n }\n\n /**\n * Sets whether or not the given objects are X-rayed.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} xrayed Whether or not to X-ray the objects.\n */\n setObjectsXRayed(objectIds, xrayed) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.xrayed = xrayed;\n });\n }\n\n /**\n * Sets whether or not all objects are X-rayed.\n *\n * @param {Boolean} xrayed Whether or not to set all objects X-rayed.\n */\n setAllObjectsXRayed(xrayed) {\n if (xrayed) {\n this.viewer.scene.setObjectsXRayed(this.viewer.scene.objectIds, true);\n } else {\n this.viewer.scene.setObjectsXRayed(this.viewer.scene.xrayedObjectIds, false);\n }\n }\n\n /**\n * Sets whether or not the given objects are selected.\n *\n * @param {String[]} objectIds IDs of objects.\n * @param {Boolean} selected Whether or not to set the objects selected.\n */\n setObjectsSelected(objectIds, selected) {\n this._withObjectsInSubtree(objectIds, (entity) => {\n entity.selected = selected;\n });\n }\n\n /**\n * Sets whether or not all objects are selected.\n *\n * @param {Boolean} selected Whether or not to set all objects selected.\n */\n setAllObjectsSelected(selected) {\n if (selected) {\n this.viewer.scene.setObjectsSelected(this.viewer.scene.objectIds, true);\n } else {\n this.viewer.scene.setObjectsSelected(this.viewer.scene.selectedObjectIds, false);\n }\n }\n\n _withObjectsInSubtree(objectIds, callback) {\n if (!objectIds) {\n this.error(\"Argument expected: objectIds\");\n return;\n }\n for (let i = 0, len = objectIds.length; i < len; i++) {\n const objectId = objectIds[i];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n const entity = this.viewer.scene.objects[metaObject.id];\n if (entity) {\n callback(entity);\n }\n });\n }\n }\n\n /**\n * Flies the camera to fit the given object in view.\n *\n * @param {String} objectId ID of the object\n * @param {Function} done Callback invoked on completion\n */\n flyToObject(objectId, done) {\n if (!objectId) {\n this.error(\"flyToObject() - Argument expected: objectId\");\n return;\n }\n const viewer = this.viewer;\n const scene = viewer.scene;\n const objectIds = [];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n objectIds.push(metaObject.id);\n }\n });\n if (objectIds.length === 0) {\n this.error(\"Object not found in viewer: '\" + objectId + \"'\");\n if (done) {\n done();\n }\n return;\n }\n scene.setObjectsVisible(objectIds, true);\n scene.setObjectsHighlighted(objectIds, true);\n const aabb = scene.getAABB(objectIds);\n viewer.cameraFlight.flyTo({\n aabb: aabb\n }, () => {\n if (done) {\n done();\n }\n setTimeout(function () {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n viewer.cameraControl.pivotPos = math.getAABB3Center(aabb);\n }\n\n /**\n * Flies the camera to fit the given objects in view.\n *\n * @param {String[]} objectIds IDs of the objects\n * @param {Function} done Callback invoked on completion\n */\n viewFitObjects(objectIds, done) {\n if (!objectIds) {\n this.error(\"flyToObject() - Argument expected: objectIds\");\n return;\n }\n const viewer = this.viewer;\n const scene = viewer.scene;\n\n const entityIds = [];\n\n for (var i = 0, len = objectIds.length; i < len; i++) {\n const objectId = objectIds[i];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n entityIds.push(metaObject.id);\n }\n });\n }\n if (entityIds.length === 0) {\n if (done) {\n done();\n }\n return;\n }\n scene.setObjectsVisible(entityIds, true);\n scene.setObjectsHighlighted(entityIds, true);\n const aabb = scene.getAABB(entityIds);\n viewer.cameraFlight.flyTo({\n aabb: aabb\n }, () => {\n if (done) {\n done();\n }\n setTimeout(function () {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n viewer.cameraControl.pivotPos = math.getAABB3Center(aabb);\n }\n\n /**\n * Flies the camera to fit all objects in view.\n *\n * @param {Function} done Callback invoked on completion\n */\n viewFitAll(done) {\n const viewer = this.viewer;\n const scene = viewer.scene;\n const aabb = scene.getAABB();\n viewer.cameraFlight.flyTo({\n aabb: aabb\n }, () => {\n if (done) {\n done();\n }\n });\n viewer.cameraControl.pivotPos = math.getAABB3Center(aabb);\n }\n\n /**\n * Jumps the camera to fit the given object in view.\n *\n * @param {String} objectId ID of the object\n */\n jumpToObject(objectId) {\n if (!objectId) {\n this.error(\"jumpToObject() - Argument expected: objectId\");\n return;\n }\n const viewer = this.viewer;\n const scene = viewer.scene;\n const objectIds = [];\n this.viewer.metaScene.withMetaObjectsInSubtree(objectId, (metaObject) => {\n if (scene.objects[metaObject.id]) {\n objectIds.push(metaObject.id);\n }\n });\n if (objectIds.length === 0) {\n this.error(\"Object not found in viewer: '\" + objectId + \"'\");\n return;\n }\n scene.setObjectsVisible(objectIds, true);\n const aabb = scene.getAABB(objectIds);\n viewer.cameraFlight.jumpTo({\n aabb: aabb\n });\n viewer.cameraControl.pivotPos = math.getAABB3Center(aabb);\n }\n\n /**\n * Sets the camera to the given position.\n *\n * @param {Number[]} [params.eye] Eye position.\n * @param {Number[]} [params.look] Point of interest.\n * @param {Number[]} [params.up] Direction of \"up\".\n */\n setCamera(params) {\n const viewer = this.viewer;\n const scene = viewer.scene;\n const camera = scene.camera;\n if (params.eye) {\n camera.eye = params.eye;\n }\n if (params.look) {\n camera.look = params.look;\n }\n if (params.up) {\n camera.up = params.up;\n }\n }\n\n /**\n * Fits the given models in view.\n *\n * @param {String[]} modelIds ID of the models.\n * @param {Function} [done] Callback invoked on completion. Will be animated if this is given, otherwise will be instantaneous.\n */\n viewFitModels(modelIds, done) {\n if (!modelIds) {\n this.error(\"viewFitModels() - Argument expected: modelIds\");\n return;\n }\n const viewer = this.viewer;\n const scene = viewer.scene;\n const aabb = math.AABB3();\n math.collapseAABB3(aabb);\n for (var i = 0, len = modelIds.length; i < len; i++) {\n const modelId = modelIds[i];\n const model = scene.models[modelId];\n if (!model) {\n this.error(\"Model not found in viewer: '\" + modelId + \"'\");\n continue;\n }\n model.visible = true;\n model.highlighted = true;\n math.expandAABB3(aabb, model.aabb);\n }\n if (done) {\n viewer.cameraFlight.flyTo({\n aabb: aabb\n }, () => {\n done();\n setTimeout(function () {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n });\n } else {\n viewer.cameraFlight.jumpTo({\n aabb: aabb\n });\n setTimeout(function () {\n scene.setObjectsHighlighted(scene.highlightedObjectIds, false);\n }, 500);\n }\n viewer.cameraControl.pivotPos = math.getAABB3Center(aabb);\n }\n\n /**\n * Opens the specified viewer tab.\n *\n * The available tabs are:\n *\n * * \"models\" - the Models tab, which lists the models available within the currently loaded project,\n * * \"objects\" - the Objects tab, which contains a tree view for each loaded model, organized to indicate the containment hierarchy of their objects,\n * * \"classes\" - the Classes tab, which contains a tree view for each loaded model, with nodes grouped by IFC types of their objects,\n * * \"storeys\" - the Storeys tab, which contains a tree view for each loaded model, with nodes grouped within ````IfcBuildingStoreys````, sub-grouped by their IFC types, and\n * * \"properties\" - the Properties tab, which shows property sets for a given object.\n *\n * @param {String} tabId ID of the tab to open - see method description.\n */\n openTab(tabId) {\n if (!tabId) {\n this.error(\"openTab() - Argument expected: tabId\");\n return;\n }\n let tabSelector;\n switch (tabId) {\n case \"models\":\n tabSelector = \"xeokit-modelsTab\";\n break;\n case \"objects\":\n tabSelector = \"xeokit-objectsTab\";\n break;\n case \"classes\":\n tabSelector = \"xeokit-classesTab\";\n break;\n case \"storeys\":\n tabSelector = \"xeokit-storeysTab\";\n break;\n case \"properties\":\n tabSelector = \"xeokit-propertiesTab\";\n break;\n default:\n this.error(\"openTab() - tab not recognized: '\" + tabId + \"'\");\n return;\n }\n this._openTab(this._explorerElement, tabSelector);\n // this._openTab(this._inspectorElement, tabSelector);\n }\n\n _openTab(element, tabSelector) {\n const tabClass = 'xeokit-tab';\n const activeClass = 'active';\n let tabs = element.querySelectorAll(\".\" + tabClass);\n let tab = element.querySelector(\".\" + tabSelector);\n for (let i = 0; i < tabs.length; i++) {\n let tabElement = tabs[i];\n if (tabElement.isEqualNode(tab)) {\n tabElement.classList.add(activeClass)\n } else {\n tabElement.classList.remove(activeClass)\n }\n }\n }\n\n /**\n * Returns the ID of the currently open viewer tab.\n *\n * The available tabs are:\n *\n * * \"models\" - the Models tab, which lists the models available within the currently loaded project,\n * * \"objects\" - the Objects tab, which contains a tree view for each loaded model, organized to indicate the containment hierarchy of their objects,\n * * \"classes\" - the Classes tab, which contains a tree view for each loaded model, with nodes grouped by IFC types of their objects,\n * * \"storeys\" - the Storeys tab, which contains a tree view for each loaded model, with nodes grouped within ````IfcBuildingStoreys````, sub-grouped by their IFC types,\n * * \"properties\" - the Properties tab, which shows property sets for a given object, and\n * * \"none\" - no tab is open; this is unlikely, since one of the above tabs should be open at a any time, but here for robustness.\n */\n getOpenTab() {\n function hasClass(element, className) {\n if (!element) {\n return false;\n }\n return (\" \" + element.className + \" \").indexOf(\" \" + className + \" \") > -1;\n }\n\n const activeClass = 'active';\n let modelsTab = this._explorerElement.querySelector(\".xeokit-modelsTab\");\n if (hasClass(modelsTab, activeClass)) {\n return \"models\";\n }\n let objectsTab = this._explorerElement.querySelector(\".xeokit-objectsTab\");\n if (hasClass(objectsTab, activeClass)) {\n return \"objects\";\n }\n let classesTab = this._explorerElement.querySelector(\".xeokit-classesTab\");\n if (hasClass(classesTab, activeClass)) {\n return \"classes\";\n }\n let storeysTab = this._explorerElement.querySelector(\".xeokit-storeysTab\");\n if (hasClass(storeysTab, activeClass)) {\n return \"storeys\";\n }\n let propertiesTab = this._inspectorElement.querySelector(\".xeokit-propertiesTab\");\n if (hasClass(propertiesTab, activeClass)) {\n return \"properties\";\n }\n return \"none\";\n }\n\n /**\n * Switches the viewer between 2D and 3D viewing modes.\n *\n * @param {Boolean} enabled Set true to switch into 3D mode, else false to switch into 2D mode.\n * @param {Function} done Callback to invoke when switch complete. Supplying this callback causes an animated transition. Otherwise, the transition will be instant.\n */\n set3DEnabled(enabled, done) {\n this._threeDMode.setActive(enabled, done);\n }\n\n /**\n * Gets whether the viewer is in 3D or 2D viewing mode.\n *\n * @returns {boolean} True when in 3D mode, else false.\n */\n get3DEnabled() {\n return this._threeDMode.getActive();\n }\n\n /**\n * Sets whether IFCSpace types are ever shown.\n *\n * @param {Boolean} shown Set true to allow IFCSpaces to be shown, else false to always keep them hidden.\n */\n setSpacesShown(shown) {\n this._showSpacesMode.setActive(shown);\n }\n\n /**\n * Gets whether the viewer allows IFCSpace types to be shown.\n *\n * @returns {boolean} True to allow IFCSpaces to be shown, else false to always keep them hidden.\n */\n getSpacesShown() {\n return this._showSpacesMode.getActive();\n }\n\n /**\n * Sets whether the viewer is in orthographic viewing mode.\n *\n * The viewer is either in orthographic mode or perspective mode. The viewer is in perspective mode by default.\n *\n * @param {Boolean} enabled Set true to switch into ortho mode, else false to switch into perspective mode.\n * @param {Function} done Callback to invoke when switch complete. Supplying this callback causes an animated transition. Otherwise, the transition will be instant.\n */\n setOrthoEnabled(enabled, done) {\n this._orthoMode.setActive(enabled, done);\n }\n\n /**\n * Gets whether the viewer is in orthographic viewing mode.\n *\n * The viewer is either in orthographic mode or perspective mode. The viewer is in perspective mode by default.\n *\n * @returns {boolean} True when in ortho mode, else false when in perspective mode.\n */\n getOrthoEnabled() {\n return this._orthoMode.getActive();\n }\n\n /**\n * Transitions the viewer into an isolated view of the given building storey.\n *\n * Does nothing and logs an error if no object of the given ID is in the viewer, or if the object is not an ````IfcBuildingStorey````.\n *\n * @param {String} storeyObjectId ID of an ````IfcBuildingStorey```` object.\n * @param {Function} [done] Optional callback to invoke on completion. When provided, the transition will be animated, with the camera flying into position. Otherwise, the transition will be instant, with the camera jumping into position.\n */\n selectStorey(storeyObjectId, done) {\n const metaScene = this.viewer.metaScene;\n const storeyMetaObject = metaScene.metaObjects[storeyObjectId];\n if (!storeyMetaObject) {\n this.error(\"selectStorey() - Object is not found: '\" + storeyObjectId + \"'\");\n return;\n }\n if (storeyMetaObject.type !== \"IfcBuildingStorey\") {\n this.error(\"selectStorey() - Object is not an IfcBuildingStorey: '\" + storeyObjectId + \"'\");\n return;\n }\n this._storeysExplorer.selectStorey(storeyObjectId, done);\n }\n\n /**\n * Saves viewer state to a BCF viewpoint.\n *\n * This does not save information about the project and model(s) that are currently loaded. When loading the viewpoint,\n * the viewer will assume that the same project and models will be currently loaded (the BCF viewpoint specification\n * does not contain that information).\n *\n * Note that xeokit's {@link Camera#look} is the **point-of-interest**, whereas the BCF ````camera_direction```` is a\n * direction vector. Therefore, we save ````camera_direction```` as the vector from {@link Camera#eye} to {@link Camera#look}.\n *\n * @param {*} [options] Options for getting the viewpoint.\n * @param {Boolean} [options.spacesVisible=false] Indicates whether ````IfcSpace```` types should be forced visible in the viewpoint.\n * @param {Boolean} [options.openingsVisible=false] Indicates whether ````IfcOpening```` types should be forced visible in the viewpoint.\n * @param {Boolean} [options.spaceBoundariesVisible=false] Indicates whether the boundaries of ````IfcSpace```` types should be visible in the viewpoint.\n * @param {Boolean} [options.reverseClippingPlanes=false] When ````true````, clipping planes are reversed (https://github.com/buildingSMART/BCF-XML/issues/193)\n * @param {Boolean} [options.defaultInvisible=false] When ````true````, will save the default visibility of all objects\n * as ````false````. This means that when we load the viewpoint again, and there are additional models loaded that\n * were not saved in the viewpoint, those models will be hidden when we load the viewpoint, and that only the\n * objects in the viewpoint will be visible.\n * @returns {*} BCF JSON viewpoint object\n * @example\n *\n * const viewpoint = bimViewer.saveBCFViewpoint({\n * spacesVisible: false, // Default\n * spaceBoundariesVisible: false, // Default\n * openingsVisible: false // Default\n * });\n *\n * // viewpoint will resemble the following:\n *\n * {\n * perspective_camera: {\n * camera_view_point: {\n * x: 0.0,\n * y: 0.0,\n * z: 0.0\n * },\n * camera_direction: {\n * x: 1.0,\n * y: 1.0,\n * z: 2.0\n * },\n * camera_up_vector: {\n * x: 0.0,\n * y: 0.0,\n * z: 1.0\n * },\n * field_of_view: 90.0\n * },\n * lines: [],\n * clipping_planes: [{\n * location: {\n * x: 0.5,\n * y: 0.5,\n * z: 0.5\n * },\n * direction: {\n * x: 1.0,\n * y: 0.0,\n * z: 0.0\n * }\n * }],\n * bitmaps: [],\n * snapshot: {\n * snapshot_type: png,\n * snapshot_data: \"data:image/png;base64,......\"\n * },\n * components: {\n * visibility: {\n * default_visibility: false,\n * exceptions: [{\n * ifc_guid: 4$cshxZO9AJBebsni$z9Yk,\n * originating_system: xeokit.io,\n * authoring_tool_id: xeokit/v1.0\n * }]\n * },\n * selection: [{\n * ifc_guid: \"4$cshxZO9AJBebsni$z9Yk\",\n * }]\n * }\n * }\n */\n saveBCFViewpoint(options) {\n return this._bcfViewpointsPlugin.getViewpoint(options);\n }\n\n /**\n * Sets viewer state to the given BCF viewpoint.\n *\n * This assumes that the viewer currently contains the same project and model(s) that were loaded at the time that the\n * viewpoint was originally saved (the BCF viewpoint specification does not contain that information).\n *\n * Note that xeokit's {@link Camera#look} is the **point-of-interest**, whereas the BCF ````camera_direction```` is a\n * direction vector. Therefore, when loading a BCF viewpoint, we set {@link Camera#look} to the absolute position\n * obtained by offsetting the BCF ````camera_view_point```` along ````camera_direction````.\n *\n * When loading a viewpoint, we also have the option to find {@link Camera#look} as the closest point of intersection\n * (on the surface of any visible and pickable {@link Entity}) with a 3D ray fired from ````camera_view_point```` in\n * the direction of ````camera_direction````.\n *\n * @param {*} bcfViewpoint BCF JSON viewpoint object or \"reset\" / \"RESET\" to reset the viewer, which clears SectionPlanes,\n * shows default visible entities and restores camera to initial default position.\n * @param {*} [options] Options for setting the viewpoint.\n * @param {Boolean} [options.rayCast=true] When ````true```` (default), will attempt to set {@link Camera#look} to the closest\n * point of surface intersection with a ray fired from the BCF ````camera_view_point```` in the direction of ````camera_direction````.\n * @param {Boolean} [options.immediate=true] When ````true```` (default), immediately set camera position.\n * @param {Boolean} [options.duration] Flight duration in seconds. Overrides {@link CameraFlightAnimation#duration}.\n * @param {Boolean} [options.reset=true] When ````true```` (default), set {@link Entity#xrayed} and {@link Entity#highlighted} ````false```` on all scene objects.\n * @param {Boolean} [options.reverseClippingPlanes=false] When ````true````, clipping planes are reversed (https://github.com/buildingSMART/BCF-XML/issues/193)\n * @param {Boolean} [options.updateCompositeObjects=false] When ````true````, then when visibility and selection updates refer to composite objects (eg. an IfcBuildingStorey),\n * then this method will apply the updates to objects within those composites.\n */\n loadBCFViewpoint(bcfViewpoint, options) {\n if (!bcfViewpoint) {\n this.error(\"loadBCFViewpoint() - Argument expected: bcfViewpoint\");\n return;\n }\n this._orthoMode.setActive(this.viewer.camera.projection === \"ortho\");\n this._bcfViewpointsPlugin.setViewpoint(bcfViewpoint, options);\n }\n\n /**\n * Resets the view.\n *\n * This resets object appearances (visibility, selection, highlight and X-ray), sets camera to\n * default position, and removes section planes.\n */\n resetView() {\n this._resetAction.reset();\n }\n\n /**\n * Enables or disables the various buttons and controls throughout the viewer.\n *\n * This also makes various buttons appear disabled.\n *\n * @param {Boolean} enabled Whether or not to disable the controls.\n */\n setControlsEnabled(enabled) {\n\n // Explorer\n\n // Models tab is always enabled\n this._objectsExplorer.setEnabled(enabled);\n this._classesExplorer.setEnabled(enabled);\n this._storeysExplorer.setEnabled(enabled);\n\n // Toolbar\n\n this._resetAction.setEnabled(enabled);\n this._fitAction.setEnabled(enabled);\n this._threeDMode.setEnabled(enabled);\n this._orthoMode.setEnabled(enabled);\n this._firstPersonMode.setEnabled(enabled);\n this._queryTool.setEnabled(enabled);\n this._hideTool.setEnabled(enabled);\n this._selectionTool.setEnabled(enabled);\n this._marqueeSelectionTool.setEnabled(enabled);\n this._showSpacesMode.setEnabled(enabled);\n this._sectionTool.setEnabled(enabled);\n\n //\n if (this._enablePropertiesInspector) {\n this._propertiesInspector.setEnabled(enabled);\n }\n }\n\n /**\n * Sets whether or not keyboard camera control is enabled.\n *\n * This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.\n *\n * Default value is ````true````.\n *\n * @param {Boolean} enabled Set ````true```` to enable keyboard input.\n */\n setKeyboardEnabled(enabled) {\n this.viewer.scene.input.keyboardEnabled = enabled;\n }\n\n /**\n * Gets whether keyboard camera control is enabled.\n *\n * This is useful when we don't want key events over the canvas to clash with other UI elements outside the canvas.\n *\n * Default value is ````true````.\n *\n * @returns {Boolean} Returns ````true```` if keyboard input is enabled.\n */\n getKeyboardEnabled() {\n return this.viewer.scene.input.keyboardEnabled;\n }\n\n /**\n * Clears sections.\n *\n * Sections are the slicing planes, that we use to section models in order to see interior structures.\n */\n clearSections() {\n this._sectionTool.clear();\n }\n\n /**\n * Disables all sections.\n */\n disableSections() {\n this._sectionTool.disableSections();\n }\n\n /**\n * Enables all sections.\n */\n enableSections() {\n this._sectionTool.enableSections();\n }\n\n /**\n * Inverts the direction of sections.\n */\n flipSections() {\n this._sectionTool.flipSections();\n }\n\n /**\n * Hides the section edition control, if currently shown.\n */\n hideSectionEditControl() {\n this._sectionTool.hideControl();\n }\n\n /**\n * Returns the number of sections that currently exist.\n *\n * sections are the sliceing planes, that we use to slice models in order to see interior structures.\n *\n * @returns {Number} The number of sections.\n */\n getNumSections() {\n return this._sectionTool.getNumSections();\n }\n\n /**\n * Destroys the viewer, freeing all resources.\n */\n destroy() {\n this.viewer.destroy();\n this._bcfViewpointsPlugin.destroy();\n this._canvasContextMenu.destroy();\n this._objectContextMenu.destroy();\n }\n}\n\nexport {BIMViewer};",
"static": true,
"longname": "/home/lindsay/xeolabs/xeokit-bim-viewer-sep13/src/BIMViewer.js",
"access": "public",
"description": null,
"lineNumber": 1
},
{
"__docId__": 49,
"kind": "variable",
"name": "hideEdgesMinDrawCount",
"memberof": "src/BIMViewer.js",
"static": true,
"longname": "src/BIMViewer.js~hideEdgesMinDrawCount",
"access": "public",
"export": false,
"importPath": "@xeokit/xeokit-bim-viewer/src/BIMViewer.js",
"importStyle": null,
"description": null,
"lineNumber": 29,
"undocument": true,
"type": {
"types": [
"number"
]
},
"ignore": true
},
{
"__docId__": 50,
"kind": "variable",
"name": "scaleCanvasResolutionMinDrawCount",
"memberof": "src/BIMViewer.js",
"static": true,
"longname": "src/BIMViewer.js~scaleCanvasResolutionMinDrawCount",
"access": "public",
"export": false,
"importPath": "@xeokit/xeokit-bim-viewer/src/BIMViewer.js",
"importStyle": null,
"description": null,
"lineNumber": 30,
"undocument": true,
"type": {
"types": [
"number"
]
},
"ignore": true
},
{
"__docId__": 51,
"kind": "function",
"name": "createExplorerTemplate",
"memberof": "src/BIMViewer.js",
"generator": false,
"async": false,
"static": true,
"longname": "src/BIMViewer.js~createExplorerTemplate",
"access": "public",
"export": false,
"importPath": "@xeokit/xeokit-bim-viewer/src/BIMViewer.js",
"importStyle": null,
"description": null,
"lineNumber": 32,
"undocument": true,
"params": [
{
"name": "cfg",
"types": [
"*"
]
}
],
"return": {
"types": [
"*"
]
},
"ignore": true
},
{
"__docId__": 52,
"kind": "function",
"name": "createToolbarTemplate",
"memberof": "src/BIMViewer.js",
"generator": false,
"async": false,
"static": true,
"longname": "src/BIMViewer.js~createToolbarTemplate",
"access": "public",
"export": false,
"importPath": "@xeokit/xeokit-bim-viewer/src/BIMViewer.js",
"importStyle": null,
"description": null,
"lineNumber": 78,
"undocument": true,
"params": [],
"return": {
"types": [
"*"
]
},
"ignore": true
},
{
"__docId__": 53,
"kind": "function",
"name": "createInspectorTemplate",
"memberof": "src/BIMViewer.js",
"generator": false,
"async": false,
"static": true,
"longname": "src/BIMViewer.js~createInspectorTemplate",
"access": "public",
"export": false,
"importPath": "@xeokit/xeokit-bim-viewer/src/BIMViewer.js",
"importStyle": null,
"description": null,
"lineNumber": 116,
"undocument": true,
"params": [],
"return": {
"types": [
"*"
]
},
"ignore": true
},
{
"__docId__": 54,
"kind": "function",
"name": "initTabs",
"memberof": "src/BIMViewer.js",
"generator": false,
"async": false,
"static": true,
"longname": "src/BIMViewer.js~initTabs",
"access": "public",
"export": false,
"importPath": "@xeokit/xeokit-bim-viewer/src/BIMViewer.js",
"importStyle": null,
"description": null,
"lineNumber": 128,
"undocument": true,
"params": [
{
"name": "containerElement",
"types": [
"*"
]
}
],
"return": null,
"ignore": true
},
{
"__docId__": 55,
"kind": "class",
"name": "BIMViewer",
"memberof": "src/BIMViewer.js",
"static": true,
"longname": "src/BIMViewer.js~BIMViewer",
"access": "public",
"export": true,
"importPath": "@xeokit/xeokit-bim-viewer/src/BIMViewer.js",
"importStyle": "{BIMViewer}",
"description": "A BIM viewer based on the [xeokit SDK](http://xeokit.io).",
"lineNumber": 174,
"interface": false,
"extends": [
"src/Controller.js~Controller"
]
},
{
"__docId__": 56,
"kind": "constructor",
"name": "constructor",
"memberof": "src/BIMViewer.js~BIMViewer",
"generator": false,
"async": false,
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#constructor",
"access": "public",
"description": "Constructs a BIMViewer.",
"lineNumber": 183,
"params": [
{
"nullable": null,
"types": [
"Server"
],
"spread": false,
"optional": false,
"name": "server",
"description": "Data access strategy."
},
{
"nullable": null,
"types": [
"*"
],
"spread": false,
"optional": false,
"name": "cfg",
"description": "Configuration."
},
{
"nullable": null,
"types": [
"Boolean"
],
"spread": false,
"optional": true,
"defaultValue": "false",
"defaultRaw": false,
"name": "cfg.enableEditModels",
"description": "Set ````true```` to show \"Add\", \"Edit\" and \"Delete\" options in the Models tab's context menu."
},
{
"nullable": null,
"types": [
"Boolean"
],
"spread": false,
"optional": true,
"name": "cfg.keyboardEventsElement",
"description": "Optional reference to HTML element on which key events should be handled. Defaults to the HTML Document."
}
]
},
{
"__docId__": 57,
"kind": "member",
"name": "_configs",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_configs",
"access": "private",
"description": null,
"lineNumber": 234,
"undocument": true,
"ignore": true,
"type": {
"types": [
"{}"
]
}
},
{
"__docId__": 58,
"kind": "member",
"name": "_enableAddModels",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_enableAddModels",
"access": "private",
"description": null,
"lineNumber": 236,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 59,
"kind": "member",
"name": "_enablePropertiesInspector",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_enablePropertiesInspector",
"access": "private",
"description": null,
"lineNumber": 237,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 60,
"kind": "member",
"name": "viewer",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#viewer",
"access": "public",
"description": "The xeokit [Viewer](https://xeokit.github.io/xeokit-sdk/docs/class/src/viewer/Viewer.js~Viewer.html) at the core of this BIMViewer.",
"lineNumber": 244,
"type": {
"nullable": null,
"types": [
"Viewer"
],
"spread": false,
"description": null
}
},
{
"__docId__": 61,
"kind": "member",
"name": "_objectsKdTree3",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_objectsKdTree3",
"access": "private",
"description": null,
"lineNumber": 246,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 62,
"kind": "member",
"name": "_explorerElement",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_explorerElement",
"access": "private",
"description": null,
"lineNumber": 259,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 63,
"kind": "member",
"name": "_inspectorElement",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_inspectorElement",
"access": "private",
"description": null,
"lineNumber": 260,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 64,
"kind": "member",
"name": "_modelsExplorer",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_modelsExplorer",
"access": "private",
"description": null,
"lineNumber": 267,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 65,
"kind": "member",
"name": "_objectsExplorer",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_objectsExplorer",
"access": "private",
"description": null,
"lineNumber": 276,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 66,
"kind": "member",
"name": "_classesExplorer",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_classesExplorer",
"access": "private",
"description": null,
"lineNumber": 283,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 67,
"kind": "member",
"name": "_storeysExplorer",
"memberof": "src/BIMViewer.js~BIMViewer",
"static": false,
"longname": "src/BIMViewer.js~BIMViewer#_storeysExplorer",
"access": "private",
"description": null,
"lineNumber": 290,
"undocument": true,
"ignore": true,
"type": {
"types": [
"*"
]
}
},
{
"__docId__": 68,