bimatter-viewer-react 0.5.8 → 0.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -222,94 +222,6 @@ function App() {
222
222
  }
223
223
  ```
224
224
 
225
- ## Viewer API
226
-
227
- ```ts
228
- viewerRef.current?.camera.fitCamera();
229
- viewerRef.current?.camera.getIntersection();
230
- viewerRef.current?.camera.getIntersection(true);
231
-
232
- viewerRef.current?.geometryUtils.showAll();
233
- viewerRef.current?.geometryUtils.showByIds([1, 2, 3]);
234
- viewerRef.current?.geometryUtils.hideByIds([1, 2, 3]);
235
- viewerRef.current?.geometryUtils.hideSelected();
236
- viewerRef.current?.geometryUtils.isolateByIds([1, 2, 3]);
237
- viewerRef.current?.geometryUtils.isolateSelected();
238
- viewerRef.current?.geometryUtils.resetIsolation();
239
- viewerRef.current?.geometryUtils.getAllIds();
240
- viewerRef.current?.geometryUtils.setIfcSpacesVisibility(false);
241
- viewerRef.current?.geometryUtils.getIfcSpacesVisibility();
242
- viewerRef.current?.geometryUtils.toggleIIfcSpacesVisibility();
243
-
244
- viewerRef.current?.selector.setSelected(0, [10, 20], true);
245
- viewerRef.current?.selector.addSelected(0, [30]);
246
- viewerRef.current?.selector.removeSelected(0, [10]);
247
- viewerRef.current?.selector.resetSelection();
248
- viewerRef.current?.selector.getSelected();
249
- viewerRef.current?.selector.collector().ofType("IfcWall").toElements();
250
- viewerRef.current?.selector.setSelectionColor("#1194bd");
251
- viewerRef.current?.selector.getSelectionColor();
252
- viewerRef.current?.selector.setPreselectionColor("#68c6e3");
253
- viewerRef.current?.selector.getPreselectionColor();
254
-
255
- viewerRef.current?.colors.setColor(0, [10, 20], "#ff3355");
256
- viewerRef.current?.colors.clearColor(0, [10]);
257
- viewerRef.current?.colors.clearModelColors(0);
258
- viewerRef.current?.colors.clearAllColors();
259
-
260
- viewerRef.current?.converter.convertToBmt({
261
- activeView: true,
262
- useMinVersion: true,
263
- });
264
- viewerRef.current?.converter.convertIfcFileToBmt(files, {
265
- useIfcColors: true,
266
- useIfcElementAssembly: true,
267
- useIfcSpace: true,
268
- useMinVersion: true,
269
- });
270
-
271
- viewerRef.current?.clipping.createPlane();
272
- viewerRef.current?.clipping.createClippingRectangle();
273
- viewerRef.current?.clipping.toggle();
274
- viewerRef.current?.clipping.setActive(true);
275
- viewerRef.current?.clipping.setEdgesActive(true);
276
- viewerRef.current?.clipping.setHelpersActive(true);
277
- viewerRef.current?.clipping.deleteAllPlanes();
278
-
279
- viewerRef.current?.dimensions.setActive(true);
280
- viewerRef.current?.dimensions.toggle();
281
- viewerRef.current?.dimensions.cancelDrawing();
282
- viewerRef.current?.dimensions.changeAxes();
283
- viewerRef.current?.dimensions.delete();
284
- viewerRef.current?.dimensions.deleteAll();
285
- viewerRef.current?.dimensions.setUnit("mm");
286
- viewerRef.current?.dimensions.setColor("#111827");
287
- viewerRef.current?.dimensions.setWidth(1);
288
- viewerRef.current?.dimensions.setSnapDistance(1);
289
- viewerRef.current?.dimensions.setEndpointScaleFactor(0.015);
290
- viewerRef.current?.dimensions.getDimensions();
291
-
292
- viewerRef.current?.properties.getModelProps();
293
- viewerRef.current?.properties.getModelStructure();
294
- viewerRef.current?.properties.exportExcel(0);
295
- viewerRef.current?.properties.exportAllExcel();
296
- viewerRef.current?.utils.getUserDevice();
297
- viewerRef.current?.utils.getDefaultHotkeysEnabled();
298
- viewerRef.current?.utils.setDefaultHotkeysEnabled(false);
299
- viewerRef.current?.utils.toggleDefaultHotkeys();
300
- viewerRef.current?.utils.getShowStats();
301
- viewerRef.current?.utils.setShowStats(true);
302
- viewerRef.current?.utils.getShowNavCube();
303
- viewerRef.current?.utils.setShowNavCube(false);
304
- viewerRef.current?.utils.toggleShowNavCube();
305
- viewerRef.current?.utils.getShowGridAxes();
306
- viewerRef.current?.utils.setShowGridAxes(true);
307
- viewerRef.current?.utils.toggleShowGridAxes();
308
- viewerRef.current?.utils.getGridAxesVisibility();
309
- viewerRef.current?.utils.setGridAxesVisibility({ top: false, bottom: true });
310
- viewerRef.current?.utils.setGridAxisVisibility("left", false);
311
- ```
312
-
313
225
  ## Geometry Utils
314
226
 
315
227
  Use `ref` to call viewer actions:
@@ -522,12 +434,25 @@ const basicWallIds = viewerRef.current?.selector
522
434
  .ofType("IfcWall")
523
435
  .Where((element) => element.props.Name.startsWith("basic wall"))
524
436
  .toElementsIds();
437
+
438
+ const levels = viewerRef.current?.properties.getAllLevels(true);
439
+ const firstLevel = levels?.[0]?.[0];
440
+
441
+ const firstLevelWallIds = firstLevel
442
+ ? viewerRef.current?.selector
443
+ .collector()
444
+ .ofLevel(firstLevel)
445
+ .ofType("IfcWall")
446
+ .toElementsIds()
447
+ : [];
525
448
  ```
526
449
 
527
450
  Without `ofModel()`, `toElements()` returns `{ [modelID]: { elementID, props }[] }` and `toElementsIds()` returns `{ [modelID]: number[] }`.
528
451
 
529
452
  With `ofModel(0)`, `toElements()` returns `{ elementID, props }[]` and `toElementsIds()` returns `number[]`.
530
453
 
454
+ With `ofLevel(level)`, `toElements()` returns `{ elementID, props }[]` and `toElementsIds()` returns `number[]`. Use `properties.getAllLevels(true)` so each level includes `elements`.
455
+
531
456
  `ofType()` accepts `IfcClass | string`, so TypeScript suggests IFC classes like `"IfcWall"` while still allowing custom type strings.
532
457
 
533
458
  ## Stats And Profiling
@@ -1,5 +1,6 @@
1
1
  import type * as WebIfc from "web-ifc";
2
2
  import type { BmtElementProps, BmtModelData, BmtModelProps } from "../Loaders/BmtLoader";
3
+ import type { ViewerModelLevel } from "../api/ViewerPropertiesApi";
3
4
  type IfcClassConstructor = abstract new (...args: never[]) => unknown;
4
5
  type IfcNamespaceClassNames<TNamespace> = Extract<{
5
6
  [Key in keyof TNamespace]: TNamespace[Key] extends IfcClassConstructor ? Key : never;
@@ -27,6 +28,7 @@ export declare class FilteredElementsCollector<TSingleModel extends boolean = fa
27
28
  ofType(type: IfcClassName | readonly IfcClassName[]): this;
28
29
  ofModel(modelID: number): FilteredElementsCollector<true>;
29
30
  ofModel(modelID: number[]): FilteredElementsCollector<false>;
31
+ ofLevel(level: ViewerModelLevel): FilteredElementsCollector<true>;
30
32
  Where(predicate: FilteredElementPredicate): this;
31
33
  where(predicate: FilteredElementPredicate): this;
32
34
  private getFilteredElements;
@@ -1,10 +1,20 @@
1
1
  import type { ViewerModelPropsStore, ViewerModelStructureStore, ViewerStoreApi } from "../store/ViewerStore";
2
2
  import { type ExportedExcelFile, type ModelPropertiesExcelOptions } from "../utils/ExportUtils";
3
+ import type { BmtModelStructureNode, BmtPropertyRecord, BmtPropertySet, BmtPropertyValue } from "../Loaders/BmtLoader";
3
4
  export type ViewerPropertiesExcelOptions = ModelPropertiesExcelOptions;
5
+ type ViewerModelLevelValue = BmtModelStructureNode[] | BmtPropertyRecord | BmtPropertySet[] | BmtPropertyValue;
6
+ export type ViewerModelLevel = Record<string, ViewerModelLevelValue | undefined> & {
7
+ elements?: number[];
8
+ modelID: number;
9
+ };
10
+ export type ViewerModelLevelsByModel = Record<number, ViewerModelLevel[]>;
4
11
  export type ViewerPropertiesApi = {
5
12
  exportAllExcel: (options?: ViewerPropertiesExcelOptions) => ExportedExcelFile[];
6
13
  exportExcel: (modelID: number, options?: ViewerPropertiesExcelOptions) => ExportedExcelFile | null;
14
+ getAllLevels: (recursive?: boolean) => ViewerModelLevelsByModel;
15
+ getAllModelLevels: (modelID: number, recursive?: boolean) => ViewerModelLevel[];
7
16
  getModelProps: () => ViewerModelPropsStore;
8
17
  getModelStructure: () => ViewerModelStructureStore;
9
18
  };
10
19
  export declare function createViewerPropertiesApi(viewerStore: ViewerStoreApi): ViewerPropertiesApi;
20
+ export {};
package/lib/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { default as Viewer } from "./Viewer";
2
2
  export type { ViewerModelsData, ViewerProps } from "./Viewer";
3
3
  export type { ViewerApi, ViewerCameraApi, ViewerCameraGetIntersection, ViewerClippingApi, ViewerColorsApi, ViewerBmtConverterOptions, ViewerConverterApi, ViewerDimensionsApi, ViewerGeometryUtilsApi, ViewerSelection, ViewerSelectorApi, ViewerUtilsApi, } from "./api/ViewerApi";
4
- export type { ViewerPropertiesApi, ViewerPropertiesExcelOptions, } from "./api/ViewerPropertiesApi";
4
+ export type { ViewerModelLevel, ViewerModelLevelsByModel, ViewerPropertiesApi, ViewerPropertiesExcelOptions, } from "./api/ViewerPropertiesApi";
5
5
  export { BMTLoader } from "./Loaders/BmtLoader";
6
6
  export type { BmtGeometryChunkData, BmtParseCallbacks, BmtParseProgressData, BmtModelGeometryData, BmtGeomData, BmtIndexArray, BmtMaterialData, BmtElementProps, BmtModelData, BmtModelProps, BmtModelStructure, BmtModelStructureNode, BmtPropertyRecord, BmtPropertySet, BmtPropertyValue, } from "./Loaders/BmtLoader";
7
7
  export type { IfcLoadedModels, IfcGeometryChunkData, IfcModelSource, IfcParseCallbacks, } from "./Loaders/IFCLoader/IFCLoader";
package/lib/index.js CHANGED
@@ -2913,7 +2913,107 @@ function xi(e, t = {}) {
2913
2913
  }
2914
2914
  //#endregion
2915
2915
  //#region src/viewer/api/ViewerPropertiesApi.ts
2916
- function Si(e, t, n, r) {
2916
+ function Si(e) {
2917
+ return !!e && typeof e == "object" && !Array.isArray(e);
2918
+ }
2919
+ function Ci(e) {
2920
+ return Si(e);
2921
+ }
2922
+ function wi(e) {
2923
+ return Array.isArray(e) ? e.filter(Ci) : Si(e) ? Object.values(e).filter(Ci) : [];
2924
+ }
2925
+ function Ti(e) {
2926
+ if (typeof e == "number" && Number.isFinite(e)) return e;
2927
+ if (typeof e == "string") {
2928
+ let t = Number(e);
2929
+ if (Number.isFinite(t)) return t;
2930
+ }
2931
+ return null;
2932
+ }
2933
+ function Ei(e) {
2934
+ return Ti(e.id ?? e.expressID ?? e.expressId ?? e.elementID ?? e.elementId);
2935
+ }
2936
+ function Di(e) {
2937
+ let t = [
2938
+ e.children,
2939
+ e.items,
2940
+ e.elements,
2941
+ e.childs
2942
+ ];
2943
+ for (let e of t) {
2944
+ let t = wi(e);
2945
+ if (t.length) return t;
2946
+ }
2947
+ return [];
2948
+ }
2949
+ function Oi(e) {
2950
+ let t = Si(e.props) ? e.props : {}, n = e.type ?? e.Type ?? t.type ?? t.Type;
2951
+ return typeof n == "string" ? n : "";
2952
+ }
2953
+ function ki(e) {
2954
+ return e.replace(/[^a-z0-9]/gi, "").toUpperCase();
2955
+ }
2956
+ function Ai(e) {
2957
+ return ki(Oi(e)) === "IFCBUILDINGSTOREY";
2958
+ }
2959
+ var ji = new Set([
2960
+ "children",
2961
+ "childs",
2962
+ "elements",
2963
+ "items"
2964
+ ]);
2965
+ function Mi(e) {
2966
+ let t = {};
2967
+ return Object.entries(e).forEach(([e, n]) => {
2968
+ ji.has(e) || (t[e] = n);
2969
+ }), t;
2970
+ }
2971
+ function Ni(e, t) {
2972
+ return Array.isArray(t) ? {
2973
+ children: wi(t),
2974
+ name: `Model ${e}`,
2975
+ type: "Model"
2976
+ } : Si(t) ? Ei(t) !== null || typeof t.name == "string" || typeof t.Name == "string" || typeof t.type == "string" || typeof t.Type == "string" || Array.isArray(t.children) ? t : {
2977
+ children: wi(t),
2978
+ name: `Model ${e}`,
2979
+ type: "Model"
2980
+ } : {
2981
+ children: [],
2982
+ name: `Model ${e}`,
2983
+ type: "Model"
2984
+ };
2985
+ }
2986
+ function Pi(e) {
2987
+ let t = [];
2988
+ return Di(e).forEach((e) => {
2989
+ let n = Ei(e);
2990
+ n !== null && t.push(n), t.push(...Pi(e));
2991
+ }), t;
2992
+ }
2993
+ function Fi(e, t, n, r) {
2994
+ let i = Ei(t), a = i === null ? void 0 : n[e]?.[i], o = {
2995
+ ...Mi(t),
2996
+ ...a ?? {},
2997
+ modelID: e
2998
+ };
2999
+ return r && (o.elements = Pi(t)), o;
3000
+ }
3001
+ function Ii(e, t, n, r, i) {
3002
+ Ai(t) && n.push(Fi(e, t, r, i)), Di(t).forEach((t) => Ii(e, t, n, r, i));
3003
+ }
3004
+ function Li(e, t, n = !1) {
3005
+ let r = {};
3006
+ return Object.entries(e).forEach(([e, i]) => {
3007
+ let a = Number(e), o = [];
3008
+ Ii(a, Ni(a, i), o, t, n), r[a] = o;
3009
+ }), r;
3010
+ }
3011
+ function Ri(e, t, n, r = !1) {
3012
+ let i = [], a = e[n];
3013
+ if (!a) throw Error(`Model with modelID ${n} not found`);
3014
+ return Ii(Number(n), Ni(Number(n), a), i, t, r), i;
3015
+ }
3016
+ function zi(e, t, n, r) {
2917
3017
  let i = t[e];
2918
3018
  return i ? {
2919
3019
  data: {},
@@ -2922,33 +3022,41 @@ function Si(e, t, n, r) {
2922
3022
  structure: n[e] ?? {}
2923
3023
  } : null;
2924
3024
  }
2925
- function Ci(e) {
3025
+ function Bi(e) {
2926
3026
  return {
2927
3027
  exportAllExcel: (t) => {
2928
3028
  let n = e.getState();
2929
3029
  return Object.keys(n.modelProps).flatMap((e) => {
2930
- let r = Si(Number(e), n.modelProps, n.modelStructure, n.modelNames);
3030
+ let r = zi(Number(e), n.modelProps, n.modelStructure, n.modelNames);
2931
3031
  return r ? [xi(r, t)] : [];
2932
3032
  });
2933
3033
  },
2934
3034
  exportExcel: (t, n) => {
2935
- let r = e.getState(), i = Si(t, r.modelProps, r.modelStructure, r.modelNames);
3035
+ let r = e.getState(), i = zi(t, r.modelProps, r.modelStructure, r.modelNames);
2936
3036
  return i ? xi(i, n) : null;
2937
3037
  },
3038
+ getAllLevels: (t = !1) => {
3039
+ let n = e.getState();
3040
+ return Li(n.modelStructure, n.modelProps, t);
3041
+ },
3042
+ getAllModelLevels: (t, n = !1) => {
3043
+ let r = e.getState();
3044
+ return Ri(r.modelStructure, r.modelProps, t, n);
3045
+ },
2938
3046
  getModelProps: () => e.getState().modelProps,
2939
3047
  getModelStructure: () => e.getState().modelStructure
2940
3048
  };
2941
3049
  }
2942
3050
  //#endregion
2943
3051
  //#region src/viewer/Loaders/BmtConverter.ts
2944
- var wi = "BMT", Ti = 1, J = {
3052
+ var Vi = "BMT", Hi = 1, J = {
2945
3053
  PROP: 1,
2946
3054
  MESH: 2,
2947
3055
  STRUCTURE: 3,
2948
3056
  GRIDS: 4,
2949
3057
  MATRIX: 5,
2950
3058
  MESHSPACE: 6
2951
- }, Ei = "application/json", Di = "application/octet-stream", Oi = class {
3059
+ }, Ui = "application/json", Wi = "application/octet-stream", Gi = class {
2952
3060
  chunks = [];
2953
3061
  length = 0;
2954
3062
  writeUint8(e) {
@@ -2968,7 +3076,7 @@ var wi = "BMT", Ti = 1, J = {
2968
3076
  e.set(n, t), t += n.byteLength;
2969
3077
  }), e;
2970
3078
  }
2971
- }, ki = class {
3079
+ }, Ki = class {
2972
3080
  textEncoder = new TextEncoder();
2973
3081
  ifcLoader = null;
2974
3082
  async ConvertIfcFileToBmt(e, t = {}) {
@@ -3035,7 +3143,7 @@ var wi = "BMT", Ti = 1, J = {
3035
3143
  }
3036
3144
  createModelFiles(e, t, n) {
3037
3145
  let r = n ? `${t}.min.bmt` : `${t}.bmt`, i = this.createBmtBytes(e, !n), a = [{
3038
- blob: new Blob([i], { type: Di }),
3146
+ blob: new Blob([i], { type: Wi }),
3039
3147
  bytes: i,
3040
3148
  name: r,
3041
3149
  type: "bmt"
@@ -3046,7 +3154,7 @@ var wi = "BMT", Ti = 1, J = {
3046
3154
  structure: e.structure
3047
3155
  });
3048
3156
  a.push({
3049
- blob: new Blob([n], { type: Ei }),
3157
+ blob: new Blob([n], { type: Ui }),
3050
3158
  bytes: n,
3051
3159
  name: `${t}_props.json`,
3052
3160
  type: "json"
@@ -3055,8 +3163,8 @@ var wi = "BMT", Ti = 1, J = {
3055
3163
  return a;
3056
3164
  }
3057
3165
  createBmtBytes(e, t) {
3058
- let n = new Oi();
3059
- return n.writeBytes(this.textEncoder.encode(wi)), n.writeUint8(Ti), t && this.writeProps(n, e.props), e.grids !== void 0 && this.writeJsonChunk(n, J.GRIDS, e.grids), this.writeMeshes(n, e), t && this.writeJsonChunk(n, J.STRUCTURE, e.structure), e.coordinationMatrix && !this.hasMeshMatrices(e) && this.writeTextChunk(n, J.MATRIX, e.coordinationMatrix), n.toUint8Array();
3166
+ let n = new Gi();
3167
+ return n.writeBytes(this.textEncoder.encode(Vi)), n.writeUint8(Hi), t && this.writeProps(n, e.props), e.grids !== void 0 && this.writeJsonChunk(n, J.GRIDS, e.grids), this.writeMeshes(n, e), t && this.writeJsonChunk(n, J.STRUCTURE, e.structure), e.coordinationMatrix && !this.hasMeshMatrices(e) && this.writeTextChunk(n, J.MATRIX, e.coordinationMatrix), n.toUint8Array();
3060
3168
  }
3061
3169
  writeProps(e, t) {
3062
3170
  Object.entries(t).forEach(([t, n]) => {
@@ -3074,7 +3182,7 @@ var wi = "BMT", Ti = 1, J = {
3074
3182
  });
3075
3183
  }
3076
3184
  createMeshPayload(e) {
3077
- let t = new Oi(), n = this.deflateTypedArray(e.pos), r = this.deflateTypedArray(e.ids), i = this.deflateTypedArray(e.ind);
3185
+ let t = new Gi(), n = this.deflateTypedArray(e.pos), r = this.deflateTypedArray(e.ids), i = this.deflateTypedArray(e.ind);
3078
3186
  return t.writeUint32(n.byteLength), t.writeBytes(n), t.writeUint32(r.byteLength), t.writeBytes(r), t.writeUint32(i.byteLength), t.writeUint32(this.getIndexType(e.ind)), t.writeBytes(i), t.writeUint8(this.colorToByte(e.mat.r)), t.writeUint8(this.colorToByte(e.mat.g)), t.writeUint8(this.colorToByte(e.mat.b)), t.writeUint8(this.colorToByte(e.mat.opacity ?? 1)), t.writeUint32(e.mat.name), t.toUint8Array();
3079
3187
  }
3080
3188
  writeJsonChunk(e, t, n) {
@@ -3304,43 +3412,43 @@ var wi = "BMT", Ti = 1, J = {
3304
3412
  isRecord(e) {
3305
3413
  return typeof e == "object" && !!e;
3306
3414
  }
3307
- }, Ai = new ki();
3308
- async function ji(e, t) {
3309
- return Ai.ConvertIfcFileToBmt(e, t);
3415
+ }, qi = new Ki();
3416
+ async function Ji(e, t) {
3417
+ return qi.ConvertIfcFileToBmt(e, t);
3310
3418
  }
3311
- function Mi(e, t) {
3312
- return Ai.ConvertToBmt(e, t);
3419
+ function Yi(e, t) {
3420
+ return qi.ConvertToBmt(e, t);
3313
3421
  }
3314
3422
  //#endregion
3315
3423
  //#region src/viewer/Selector/FilteredElementsCollector.ts
3316
3424
  function Y(e) {
3317
3425
  return !!e && typeof e == "object" && !Array.isArray(e);
3318
3426
  }
3319
- function Ni(e) {
3427
+ function Xi(e) {
3320
3428
  let t = Number(e);
3321
3429
  return Number.isFinite(t) ? t : null;
3322
3430
  }
3323
- function Pi(e) {
3431
+ function Zi(e) {
3324
3432
  return Y(e) && Y(e.data) && Y(e.props) && "structure" in e;
3325
3433
  }
3326
- function Fi(e) {
3434
+ function Qi(e) {
3327
3435
  return Y(e) && ("guid" in e || "id" in e || "props" in e || "sets" in e);
3328
3436
  }
3329
- function Ii(e) {
3437
+ function $i(e) {
3330
3438
  if (!Y(e)) return !1;
3331
3439
  let t = Object.entries(e);
3332
- return t.length ? t.every(([e, t]) => Ni(e) !== null && Fi(t)) : !0;
3440
+ return t.length ? t.every(([e, t]) => Xi(e) !== null && Qi(t)) : !0;
3333
3441
  }
3334
- function Li(e) {
3442
+ function ea(e) {
3335
3443
  return typeof e == "string" ? e : null;
3336
3444
  }
3337
- function Ri(e) {
3445
+ function ta(e) {
3338
3446
  let t = Y(e.props.props) ? e.props.props : {};
3339
- return Li(e.props.type ?? e.props.Type ?? t.type ?? t.Type);
3447
+ return ea(e.props.type ?? e.props.Type ?? t.type ?? t.Type);
3340
3448
  }
3341
- function zi(e, t, n) {
3449
+ function na(e, t, n) {
3342
3450
  Object.entries(n).forEach(([n, r]) => {
3343
- let i = Ni(n);
3451
+ let i = Xi(n);
3344
3452
  i !== null && e.push({
3345
3453
  elementID: i,
3346
3454
  modelID: t,
@@ -3348,29 +3456,29 @@ function zi(e, t, n) {
3348
3456
  });
3349
3457
  });
3350
3458
  }
3351
- function Bi(e) {
3459
+ function ra(e) {
3352
3460
  if (!e || !Y(e)) return [];
3353
- if (Pi(e)) {
3461
+ if (Zi(e)) {
3354
3462
  let t = [];
3355
- return zi(t, 0, e.props), t;
3463
+ return na(t, 0, e.props), t;
3356
3464
  }
3357
- if (Ii(e)) {
3465
+ if ($i(e)) {
3358
3466
  let t = [];
3359
- return zi(t, 0, e), t;
3467
+ return na(t, 0, e), t;
3360
3468
  }
3361
3469
  let t = [];
3362
3470
  return Object.entries(e).forEach(([e, n]) => {
3363
- let r = Ni(e);
3471
+ let r = Xi(e);
3364
3472
  if (r !== null) {
3365
- if (Pi(n)) {
3366
- zi(t, r, n.props);
3473
+ if (Zi(n)) {
3474
+ na(t, r, n.props);
3367
3475
  return;
3368
3476
  }
3369
- Ii(n) && zi(t, r, n);
3477
+ $i(n) && na(t, r, n);
3370
3478
  }
3371
3479
  }), t;
3372
3480
  }
3373
- function Vi(e) {
3481
+ function ia(e) {
3374
3482
  let t = {};
3375
3483
  return e.forEach(({ elementID: e, modelID: n, props: r }) => {
3376
3484
  t[n] ??= [], t[n].push({
@@ -3379,26 +3487,26 @@ function Vi(e) {
3379
3487
  });
3380
3488
  }), t;
3381
3489
  }
3382
- function Hi(e) {
3490
+ function aa(e) {
3383
3491
  let t = {};
3384
3492
  return e.forEach(({ elementID: e, modelID: n }) => {
3385
3493
  t[n] ??= [], t[n].push(e);
3386
3494
  }), t;
3387
3495
  }
3388
- var Ui = class {
3496
+ var oa = class {
3389
3497
  elements;
3390
3498
  filters = [];
3391
3499
  selectedModelIDs = null;
3392
3500
  constructor(e) {
3393
- this.elements = Bi(e);
3501
+ this.elements = ra(e);
3394
3502
  }
3395
3503
  from(e) {
3396
- return this.elements = Bi(e), this.filters = [], this.selectedModelIDs = null, this;
3504
+ return this.elements = ra(e), this.filters = [], this.selectedModelIDs = null, this;
3397
3505
  }
3398
3506
  ofType(e) {
3399
3507
  let t = new Set((Array.isArray(e) ? e : [e]).map((e) => e.toLowerCase()));
3400
3508
  return this.filters.push((e) => {
3401
- let n = Ri(e);
3509
+ let n = ta(e);
3402
3510
  return !!(n && t.has(n.toLowerCase()));
3403
3511
  }), this;
3404
3512
  }
@@ -3406,6 +3514,10 @@ var Ui = class {
3406
3514
  let t = new Set(Array.isArray(e) ? e : [e]);
3407
3515
  return this.selectedModelIDs = t, this.filters.push((e) => t.has(e.modelID)), this;
3408
3516
  }
3517
+ ofLevel(e) {
3518
+ let t = new Set([e.modelID]), n = new Set(e.elements ?? []);
3519
+ return this.selectedModelIDs = t, this.filters.push((t) => t.modelID === e.modelID && n.has(t.elementID)), this;
3520
+ }
3409
3521
  Where(e) {
3410
3522
  return this.filters.push(e), this;
3411
3523
  }
@@ -3423,11 +3535,11 @@ var Ui = class {
3423
3535
  return this.hasSingleSelectedModel() ? e.map(({ elementID: e, props: t }) => ({
3424
3536
  elementID: e,
3425
3537
  props: t
3426
- })) : Vi(e);
3538
+ })) : ia(e);
3427
3539
  }
3428
3540
  toElementsIds() {
3429
3541
  let e = this.getFilteredElements();
3430
- return this.hasSingleSelectedModel() ? e.map(({ elementID: e }) => e) : Hi(e);
3542
+ return this.hasSingleSelectedModel() ? e.map(({ elementID: e }) => e) : aa(e);
3431
3543
  }
3432
3544
  toElementIds() {
3433
3545
  return this.toElementsIds();
@@ -3435,20 +3547,20 @@ var Ui = class {
3435
3547
  };
3436
3548
  //#endregion
3437
3549
  //#region src/viewer/api/ViewerApi.ts
3438
- function Wi(e) {
3550
+ function sa(e) {
3439
3551
  let t = {};
3440
3552
  return Object.entries(e).forEach(([e, n]) => {
3441
3553
  t[Number(e)] = Array.from(n);
3442
3554
  }), t;
3443
3555
  }
3444
- function Gi(e) {
3556
+ function ca(e) {
3445
3557
  let t = {};
3446
3558
  return Object.entries(e).forEach(([e, n]) => {
3447
3559
  t[Number(e)] = new Set(n);
3448
3560
  }), t;
3449
3561
  }
3450
- function Ki(e, t) {
3451
- let n = new ki();
3562
+ function la(e, t) {
3563
+ let n = new Ki();
3452
3564
  return {
3453
3565
  camera: {
3454
3566
  fitCamera: () => {
@@ -3582,15 +3694,15 @@ function Ki(e, t) {
3582
3694
  t()?.geometryUtils.toggleIIfcSpacesVisibility();
3583
3695
  }
3584
3696
  },
3585
- properties: Ci(e),
3697
+ properties: Bi(e),
3586
3698
  selector: {
3587
3699
  addSelected: (t, n) => {
3588
3700
  e.getState().addSelected(t, n);
3589
3701
  },
3590
- collector: () => new Ui(e.getState().modelProps),
3702
+ collector: () => new oa(e.getState().modelProps),
3591
3703
  getPreselectionColor: () => e.getState().preselectionColor,
3592
3704
  getSelectionColor: () => e.getState().selectionColor,
3593
- getSelected: () => Wi(e.getState().selected),
3705
+ getSelected: () => sa(e.getState().selected),
3594
3706
  removeSelected: (t, n) => {
3595
3707
  e.getState().removeSelected(t, n);
3596
3708
  },
@@ -3649,7 +3761,7 @@ function Ki(e, t) {
3649
3761
  }
3650
3762
  //#endregion
3651
3763
  //#region src/viewer/Loaders/BmtLoader.ts
3652
- var qi = class {
3764
+ var ua = class {
3653
3765
  view;
3654
3766
  offset = 0;
3655
3767
  constructor(e) {
@@ -3669,7 +3781,7 @@ var qi = class {
3669
3781
  eof() {
3670
3782
  return this.offset >= this.view.byteLength;
3671
3783
  }
3672
- }, Ji = class {
3784
+ }, da = class {
3673
3785
  decodeBuffer(e) {
3674
3786
  return this.textDecoder.decode(Ee.inflate(e));
3675
3787
  }
@@ -3742,7 +3854,7 @@ var qi = class {
3742
3854
  return a?.props && (i.props = a.props), a?.grids && (i.grids = a.grids), a?.coordinationMatrix && (i.coordinationMatrix = a.coordinationMatrix), a?.structure !== void 0 && (i.structure = a.structure), i;
3743
3855
  }
3744
3856
  parseBinaryFile(e, t = {}) {
3745
- let n = new qi(e);
3857
+ let n = new ua(e);
3746
3858
  if (new TextDecoder().decode(n.readBytes(3)) !== "BMT") throw Error("Invalid file");
3747
3859
  let r = n.readUint8();
3748
3860
  console.log(`model version: ${r}`);
@@ -3810,24 +3922,24 @@ var qi = class {
3810
3922
  };
3811
3923
  //#endregion
3812
3924
  //#region src/viewer/workers/BMTWorker.ts?worker
3813
- function Yi(e) {
3925
+ function fa(e) {
3814
3926
  return new Worker("" + new URL("assets/BMTWorker-yhSXOg2i.js", import.meta.url).href, { name: e?.name });
3815
3927
  }
3816
3928
  //#endregion
3817
3929
  //#region src/viewer/workers/BMTWorkerClient.ts
3818
- function Xi() {
3930
+ function pa() {
3819
3931
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`;
3820
3932
  }
3821
- function Zi(e) {
3933
+ function ma(e) {
3822
3934
  return Array.isArray(e) ? e : [e];
3823
3935
  }
3824
- function Qi(e) {
3936
+ function ha(e) {
3825
3937
  return e.split(/[?#]/)[0].split(/[\\/]/).pop() || "model.bmt";
3826
3938
  }
3827
- function $i(e) {
3939
+ function ga(e) {
3828
3940
  return typeof e == "string" ? {
3829
3941
  kind: "url",
3830
- name: Qi(e),
3942
+ name: ha(e),
3831
3943
  url: new URL(e, globalThis.location.href).href
3832
3944
  } : e instanceof File ? {
3833
3945
  file: e,
@@ -3838,18 +3950,18 @@ function $i(e) {
3838
3950
  kind: "buffer"
3839
3951
  };
3840
3952
  }
3841
- function ea(e) {
3953
+ function _a(e) {
3842
3954
  return e.map((e) => e.kind === "buffer" ? e.buffer : null).filter((e) => e instanceof ArrayBuffer);
3843
3955
  }
3844
- function ta() {
3845
- return new Yi();
3956
+ function va() {
3957
+ return new fa();
3846
3958
  }
3847
- function na(e) {
3959
+ function ya(e) {
3848
3960
  return { streamGeometryChunks: e.streamGeometryChunks ?? !!e.onChunk };
3849
3961
  }
3850
- function ra(e, t = {}) {
3851
- let n = t.worker ?? ta(), r = t.terminateOnComplete ?? !t.worker, i = t.collectChunks ?? !0, a = Zi(e).map($i), o = Xi(), s = {}, c = {
3852
- options: na(t),
3962
+ function ba(e, t = {}) {
3963
+ let n = t.worker ?? va(), r = t.terminateOnComplete ?? !t.worker, i = t.collectChunks ?? !0, a = ma(e).map(ga), o = pa(), s = {}, c = {
3964
+ options: ya(t),
3853
3965
  sources: a,
3854
3966
  taskId: o,
3855
3967
  type: "load-bmt-model"
@@ -3887,29 +3999,29 @@ function ra(e, t = {}) {
3887
3999
  let a = Error(r.error.message);
3888
4000
  r.error.stack && (a.stack = r.error.stack), l(a);
3889
4001
  };
3890
- n.addEventListener("message", f), n.addEventListener("error", d), n.postMessage(c, ea(a));
4002
+ n.addEventListener("message", f), n.addEventListener("error", d), n.postMessage(c, _a(a));
3891
4003
  });
3892
4004
  }
3893
- function ia() {
3894
- return ta();
4005
+ function xa() {
4006
+ return va();
3895
4007
  }
3896
4008
  //#endregion
3897
4009
  //#region src/viewer/workers/IFCWorker.ts?worker
3898
- function aa(e) {
4010
+ function Sa(e) {
3899
4011
  return new Worker("" + new URL("assets/IFCWorker-Dgk5iwps.js", import.meta.url).href, { name: e?.name });
3900
4012
  }
3901
4013
  //#endregion
3902
4014
  //#region src/viewer/workers/IFCWorkerClient.ts
3903
- function oa() {
4015
+ function Ca() {
3904
4016
  return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`;
3905
4017
  }
3906
- function sa(e) {
4018
+ function wa(e) {
3907
4019
  return Array.isArray(e) ? e : [e];
3908
4020
  }
3909
- function ca(e) {
4021
+ function Ta(e) {
3910
4022
  return typeof e == "string" ? {
3911
4023
  kind: "url",
3912
- name: la(e),
4024
+ name: Ea(e),
3913
4025
  url: new URL(e, globalThis.location.href).href
3914
4026
  } : e instanceof File ? {
3915
4027
  file: e,
@@ -3920,23 +4032,23 @@ function ca(e) {
3920
4032
  kind: "buffer"
3921
4033
  };
3922
4034
  }
3923
- function la(e) {
4035
+ function Ea(e) {
3924
4036
  return e.split(/[?#]/)[0].split(/[\\/]/).pop() || "model.ifc";
3925
4037
  }
3926
- function ua() {
4038
+ function Da() {
3927
4039
  return globalThis.document?.baseURI ?? globalThis.location.href;
3928
4040
  }
3929
- function da(e) {
4041
+ function Oa(e) {
3930
4042
  let t = e ?? "ifc-parser.wasm";
3931
- return /^(https?:|blob:|data:)/i.test(t) ? t : new URL(t, ua()).href;
4043
+ return /^(https?:|blob:|data:)/i.test(t) ? t : new URL(t, Da()).href;
3932
4044
  }
3933
- function fa(e) {
4045
+ function ka(e) {
3934
4046
  return e.map((e) => e.kind === "buffer" ? e.buffer : null).filter((e) => e instanceof ArrayBuffer);
3935
4047
  }
3936
- function pa() {
3937
- return new aa();
4048
+ function Aa() {
4049
+ return new Sa();
3938
4050
  }
3939
- function ma(e) {
4051
+ function ja(e) {
3940
4052
  return {
3941
4053
  chunk: e.chunk,
3942
4054
  coordinationMatrix: e.coordinationMatrix,
@@ -3945,12 +4057,12 @@ function ma(e) {
3945
4057
  useIfcColors: e.useIfcColors,
3946
4058
  useIfcElementAssembly: e.useIfcElementAssembly,
3947
4059
  useIfcSpace: e.useIfcSpace,
3948
- wasmPath: da(e.wasmPath)
4060
+ wasmPath: Oa(e.wasmPath)
3949
4061
  };
3950
4062
  }
3951
- function ha(e, t = {}) {
3952
- let n = t.worker ?? pa(), r = t.terminateOnComplete ?? !t.worker, i = t.collectChunks ?? !0, a = sa(e).map(ca), o = oa(), s = {}, c = {
3953
- options: ma(t),
4063
+ function Ma(e, t = {}) {
4064
+ let n = t.worker ?? Aa(), r = t.terminateOnComplete ?? !t.worker, i = t.collectChunks ?? !0, a = wa(e).map(Ta), o = Ca(), s = {}, c = {
4065
+ options: ja(t),
3954
4066
  sources: a,
3955
4067
  taskId: o,
3956
4068
  type: "load-ifc-model"
@@ -3988,34 +4100,34 @@ function ha(e, t = {}) {
3988
4100
  let a = Error(r.error.message);
3989
4101
  r.error.stack && (a.stack = r.error.stack), l(a);
3990
4102
  };
3991
- n.addEventListener("message", f), n.addEventListener("error", d), n.postMessage(c, fa(a));
4103
+ n.addEventListener("message", f), n.addEventListener("error", d), n.postMessage(c, ka(a));
3992
4104
  });
3993
4105
  }
3994
- function ga() {
3995
- return pa();
4106
+ function Na() {
4107
+ return Aa();
3996
4108
  }
3997
4109
  //#endregion
3998
4110
  //#region src/viewer/api/loader.ts
3999
- function _a(e) {
4111
+ function Pa(e) {
4000
4112
  return typeof e == "string" ? e : e.name;
4001
4113
  }
4002
- function va(e) {
4003
- return (_a(e).split(/[?#]/)[0].split(/[\\/]/).pop() || "model").replace(/\.min\.bmt$/i, "").replace(/\.[^.]+$/i, "") || "model";
4114
+ function Fa(e) {
4115
+ return (Pa(e).split(/[?#]/)[0].split(/[\\/]/).pop() || "model").replace(/\.min\.bmt$/i, "").replace(/\.[^.]+$/i, "") || "model";
4004
4116
  }
4005
- function ya(e) {
4006
- let t = _a(e).split(/[?#]/)[0].toLowerCase(), n = t.lastIndexOf(".");
4117
+ function Ia(e) {
4118
+ let t = Pa(e).split(/[?#]/)[0].toLowerCase(), n = t.lastIndexOf(".");
4007
4119
  return n === -1 ? "" : t.slice(n + 1);
4008
4120
  }
4009
- function ba(e) {
4121
+ function La(e) {
4010
4122
  return /\.min\.bmt$/i.test(e.name) ? e.name.replace(/\.min\.bmt$/i, "_props.json") : null;
4011
4123
  }
4012
- function xa(e) {
4013
- return /_props\.json$/i.test(_a(e).split(/[?#]/)[0]);
4124
+ function Ra(e) {
4125
+ return /_props\.json$/i.test(Pa(e).split(/[?#]/)[0]);
4014
4126
  }
4015
- function Sa(e) {
4127
+ function za(e) {
4016
4128
  return e.coordinationMatrix ? e.coordinationMatrix : Object.values(e.data)[0]?.matrix || void 0;
4017
4129
  }
4018
- var Ca = new class {
4130
+ var Ba = new class {
4019
4131
  coordinationMatrix;
4020
4132
  useIfcSpace = !1;
4021
4133
  bmtLoader = null;
@@ -4026,7 +4138,7 @@ var Ca = new class {
4026
4138
  this.getBmtLoader();
4027
4139
  }
4028
4140
  getBmtLoader() {
4029
- return this.bmtLoader ||= new Ji(), this.bmtLoader;
4141
+ return this.bmtLoader ||= new da(), this.bmtLoader;
4030
4142
  }
4031
4143
  async getIfcLoader(e = {}) {
4032
4144
  if (!this.ifcLoader) {
@@ -4054,7 +4166,7 @@ var Ca = new class {
4054
4166
  async loadBmtModel(e, t) {
4055
4167
  let n = this.getBmtLoader();
4056
4168
  if (typeof e == "string") return n.loadModel(e);
4057
- let r = n.parseBinaryFile(await e.arrayBuffer()), i = ba(e), a = i ? t.get(i) : void 0;
4169
+ let r = n.parseBinaryFile(await e.arrayBuffer()), i = La(e), a = i ? t.get(i) : void 0;
4058
4170
  return this.applyBmtMetadata(r, a);
4059
4171
  }
4060
4172
  createWorkerProgressHandler(e, t, n, r) {
@@ -4077,7 +4189,7 @@ var Ca = new class {
4077
4189
  };
4078
4190
  }
4079
4191
  async loadIfcModelInWorker(e, t, n, r, i) {
4080
- return (await ha(e, {
4192
+ return (await Ma(e, {
4081
4193
  chunk: t.chunk,
4082
4194
  collectChunks: t.collectWorkerChunks,
4083
4195
  coordinationMatrix: this.coordinationMatrix,
@@ -4090,14 +4202,14 @@ var Ca = new class {
4090
4202
  }))[0];
4091
4203
  }
4092
4204
  async loadBmtModelInWorker(e, t, n, r, i, a) {
4093
- let o = (await ra(e, {
4205
+ let o = (await ba(e, {
4094
4206
  collectChunks: n.collectWorkerChunks,
4095
4207
  onChunk: this.createWorkerChunkHandler(n, r),
4096
4208
  onProgress: this.createWorkerProgressHandler(n, r, i, a),
4097
4209
  streamGeometryChunks: n.streamGeometryChunks ?? !!n.onChunk
4098
4210
  }))[0];
4099
4211
  if (e instanceof File) {
4100
- let n = ba(e), r = n ? t.get(n) : void 0;
4212
+ let n = La(e), r = n ? t.get(n) : void 0;
4101
4213
  return this.applyBmtMetadata(o, r);
4102
4214
  }
4103
4215
  return o;
@@ -4110,21 +4222,21 @@ var Ca = new class {
4110
4222
  }
4111
4223
  async loadModel(e, t = {}) {
4112
4224
  this.initLoaders();
4113
- let n = Array.isArray(e) ? e : [e], r = this.getFileSourceMap(n), i = {}, a = n.filter((e) => !xa(e)).length, o = 0;
4225
+ let n = Array.isArray(e) ? e : [e], r = this.getFileSourceMap(n), i = {}, a = n.filter((e) => !Ra(e)).length, o = 0;
4114
4226
  this.loadedModelCount === 0 && this.resetCoordinationMatrixState();
4115
4227
  for (let e = 0; e < n.length; e++) {
4116
- let s = n[e], c = ya(s), l;
4117
- if (c === "json" && xa(s)) continue;
4228
+ let s = n[e], c = Ia(s), l;
4229
+ if (c === "json" && Ra(s)) continue;
4118
4230
  let u = this.nextModelID, d = o;
4119
4231
  if (o++, c === "ifc") l = t.useWorker ? await this.loadIfcModelInWorker(s, t, u, d, a) : (await (await this.getIfcLoader(t)).loadModel(s, this.coordinationMatrix))[0];
4120
4232
  else if (c === "bmt") l = t.useWorker ? await this.loadBmtModelInWorker(s, r, t, u, d, a) : await this.loadBmtModel(s, r);
4121
- else throw Error(`Unsupported model format: ${_a(s)}`);
4122
- let f = Sa(l);
4123
- !this.coordinationMatrix && f && (this.coordinationMatrix = f), !l.coordinationMatrix && this.coordinationMatrix && (l.coordinationMatrix = this.coordinationMatrix), l.name ??= va(s), this.nextModelID += 1, this.loadedModelCount += 1, i[u] = l;
4233
+ else throw Error(`Unsupported model format: ${Pa(s)}`);
4234
+ let f = za(l);
4235
+ !this.coordinationMatrix && f && (this.coordinationMatrix = f), !l.coordinationMatrix && this.coordinationMatrix && (l.coordinationMatrix = this.coordinationMatrix), l.name ??= Fa(s), this.nextModelID += 1, this.loadedModelCount += 1, i[u] = l;
4124
4236
  }
4125
4237
  return i;
4126
4238
  }
4127
- }(), wa = .5, X = .04, Z = .16, Ta = Z, Q = wa * 2 - Z * 2, Ea = wa - X / 2, Da = wa - Z / 2, Oa = wa - Ta / 2, ka = .63, Aa = "#dfe6ec", ja = 260, Ma = 52, Na = .17, Pa = new g(), $ = new pe(), Fa = [
4239
+ }(), Va = .5, X = .04, Z = .16, Ha = Z, Q = Va * 2 - Z * 2, Ua = Va - X / 2, Wa = Va - Z / 2, Ga = Va - Ha / 2, Ka = .63, qa = "#dfe6ec", Ja = 260, Ya = 52, Xa = .17, Za = new g(), $ = new pe(), Qa = [
4128
4240
  {
4129
4241
  direction: [
4130
4242
  0,
@@ -4135,7 +4247,7 @@ var Ca = new class {
4135
4247
  position: [
4136
4248
  0,
4137
4249
  0,
4138
- Ea
4250
+ Ua
4139
4251
  ],
4140
4252
  scale: [
4141
4253
  Q,
@@ -4155,7 +4267,7 @@ var Ca = new class {
4155
4267
  position: [
4156
4268
  0,
4157
4269
  0,
4158
- -Ea
4270
+ -Ua
4159
4271
  ],
4160
4272
  rotation: [
4161
4273
  0,
@@ -4178,7 +4290,7 @@ var Ca = new class {
4178
4290
  ],
4179
4291
  label: "right",
4180
4292
  position: [
4181
- Ea,
4293
+ Ua,
4182
4294
  0,
4183
4295
  0
4184
4296
  ],
@@ -4203,7 +4315,7 @@ var Ca = new class {
4203
4315
  ],
4204
4316
  label: "left",
4205
4317
  position: [
4206
- -Ea,
4318
+ -Ua,
4207
4319
  0,
4208
4320
  0
4209
4321
  ],
@@ -4229,7 +4341,7 @@ var Ca = new class {
4229
4341
  label: "top",
4230
4342
  position: [
4231
4343
  0,
4232
- Ea,
4344
+ Ua,
4233
4345
  0
4234
4346
  ],
4235
4347
  rotation: [
@@ -4254,7 +4366,7 @@ var Ca = new class {
4254
4366
  label: "bot",
4255
4367
  position: [
4256
4368
  0,
4257
- -Ea,
4369
+ -Ua,
4258
4370
  0
4259
4371
  ],
4260
4372
  rotation: [
@@ -4271,7 +4383,7 @@ var Ca = new class {
4271
4383
  type: "face"
4272
4384
  }
4273
4385
  ];
4274
- function Ia() {
4386
+ function $a() {
4275
4387
  let e = [], t = [-1, 1];
4276
4388
  return t.forEach((n) => {
4277
4389
  t.forEach((t) => {
@@ -4283,8 +4395,8 @@ function Ia() {
4283
4395
  ],
4284
4396
  position: [
4285
4397
  0,
4286
- n * Da,
4287
- t * Da
4398
+ n * Wa,
4399
+ t * Wa
4288
4400
  ],
4289
4401
  scale: [
4290
4402
  Q,
@@ -4304,9 +4416,9 @@ function Ia() {
4304
4416
  t
4305
4417
  ],
4306
4418
  position: [
4307
- n * Da,
4419
+ n * Wa,
4308
4420
  0,
4309
- t * Da
4421
+ t * Wa
4310
4422
  ],
4311
4423
  scale: [
4312
4424
  Z,
@@ -4326,8 +4438,8 @@ function Ia() {
4326
4438
  0
4327
4439
  ],
4328
4440
  position: [
4329
- n * Da,
4330
- t * Da,
4441
+ n * Wa,
4442
+ t * Wa,
4331
4443
  0
4332
4444
  ],
4333
4445
  scale: [
@@ -4341,7 +4453,7 @@ function Ia() {
4341
4453
  });
4342
4454
  }), e;
4343
4455
  }
4344
- function La() {
4456
+ function eo() {
4345
4457
  let e = [], t = [-1, 1];
4346
4458
  return t.forEach((n) => {
4347
4459
  t.forEach((r) => {
@@ -4353,14 +4465,14 @@ function La() {
4353
4465
  t
4354
4466
  ],
4355
4467
  position: [
4356
- n * Oa,
4357
- r * Oa,
4358
- t * Oa
4468
+ n * Ga,
4469
+ r * Ga,
4470
+ t * Ga
4359
4471
  ],
4360
4472
  scale: [
4361
- Ta,
4362
- Ta,
4363
- Ta
4473
+ Ha,
4474
+ Ha,
4475
+ Ha
4364
4476
  ],
4365
4477
  title: `${r > 0 ? "Top" : "Bottom"} ${n > 0 ? "Right" : "Left"} ${t > 0 ? "Front" : "Back"}`,
4366
4478
  type: "corner"
@@ -4369,21 +4481,21 @@ function La() {
4369
4481
  });
4370
4482
  }), e;
4371
4483
  }
4372
- function Ra(e) {
4484
+ function to(e) {
4373
4485
  e.stopPropagation(), e.nativeEvent.stopPropagation(), e.nativeEvent.stopImmediatePropagation?.();
4374
4486
  }
4375
- function za(e) {
4376
- return e ? "#4f7fa3" : Aa;
4487
+ function no(e) {
4488
+ return e ? "#4f7fa3" : qa;
4377
4489
  }
4378
- function Ba(e) {
4490
+ function ro(e) {
4379
4491
  return e ? 1 : .96;
4380
4492
  }
4381
- function Va(e, t) {
4493
+ function io(e, t) {
4382
4494
  let n = document.createElement("canvas"), r = n.getContext("2d");
4383
4495
  if (!r) throw Error("Could not create navigation cube label context");
4384
- let i = `600 ${Ma}px system-ui, "Segoe UI", sans-serif`;
4496
+ let i = `600 ${Ya}px system-ui, "Segoe UI", sans-serif`;
4385
4497
  r.font = i;
4386
- let a = r.measureText(e), o = a.actualBoundingBoxAscent || Ma * .8, s = a.actualBoundingBoxDescent || Ma * .2, c = Math.ceil(a.width + 36), l = Math.ceil(o + s + 20);
4498
+ let a = r.measureText(e), o = a.actualBoundingBoxAscent || Ya * .8, s = a.actualBoundingBoxDescent || Ya * .2, c = Math.ceil(a.width + 36), l = Math.ceil(o + s + 20);
4387
4499
  n.width = c, n.height = l, r.clearRect(0, 0, c, l), r.font = i, r.fillStyle = t, r.textAlign = "center", r.textBaseline = "alphabetic", r.fillText(e, c / 2, 10 + o);
4388
4500
  let u = new b(n);
4389
4501
  return u.colorSpace = fe, u.generateMipmaps = !1, u.magFilter = A, u.minFilter = A, u.needsUpdate = !0, {
@@ -4391,12 +4503,12 @@ function Va(e, t) {
4391
4503
  texture: u
4392
4504
  };
4393
4505
  }
4394
- function Ha({ color: e, label: t, position: n, rotation: r }) {
4395
- let { aspect: i, texture: a } = c(() => Va(t, e), [e, t]);
4506
+ function ao({ color: e, label: t, position: n, rotation: r }) {
4507
+ let { aspect: i, texture: a } = c(() => io(t, e), [e, t]);
4396
4508
  return o(() => () => a.dispose(), [a]), /* @__PURE__ */ I("mesh", {
4397
4509
  position: n,
4398
4510
  rotation: r,
4399
- children: [/* @__PURE__ */ F("planeGeometry", { args: [Na * i, Na] }), /* @__PURE__ */ F("meshBasicMaterial", {
4511
+ children: [/* @__PURE__ */ F("planeGeometry", { args: [Xa * i, Xa] }), /* @__PURE__ */ F("meshBasicMaterial", {
4400
4512
  alphaTest: .1,
4401
4513
  depthWrite: !1,
4402
4514
  map: a,
@@ -4405,41 +4517,41 @@ function Ha({ color: e, label: t, position: n, rotation: r }) {
4405
4517
  })]
4406
4518
  });
4407
4519
  }
4408
- function Ua(e) {
4520
+ function oo(e) {
4409
4521
  return Math.abs(e.y) > .9 ? new P(0, 0, e.y > 0 ? -1 : 1) : new P(0, 1, 0);
4410
4522
  }
4411
- function Wa(e, t) {
4523
+ function so(e, t) {
4412
4524
  let n = e.current;
4413
- return !n || (n.updateWorldMatrix(!0, !0), Pa.setFromObject(n), Pa.isEmpty()) ? ($.center.copy(t), $.radius = 10, $) : (Pa.getBoundingSphere($), (!Number.isFinite($.radius) || $.radius <= 0) && ($.radius = 10), $);
4525
+ return !n || (n.updateWorldMatrix(!0, !0), Za.setFromObject(n), Za.isEmpty()) ? ($.center.copy(t), $.radius = 10, $) : (Za.getBoundingSphere($), (!Number.isFinite($.radius) || $.radius <= 0) && ($.radius = 10), $);
4414
4526
  }
4415
- function Ga(e) {
4527
+ function co(e) {
4416
4528
  return e.current?.target.clone() ?? new P();
4417
4529
  }
4418
- function Ka({ camera: e, controlRef: t, direction: n, modelRef: r, transitionRef: i }) {
4419
- let a = Ga(t), o = Wa(r, a), s = o.center.clone(), c = new P(...n).normalize(), l = e.position.distanceTo(a), u = Number.isFinite(l) && l > o.radius * .5 ? l : o.radius * 2.4;
4530
+ function lo({ camera: e, controlRef: t, direction: n, modelRef: r, transitionRef: i }) {
4531
+ let a = co(t), o = so(r, a), s = o.center.clone(), c = new P(...n).normalize(), l = e.position.distanceTo(a), u = Number.isFinite(l) && l > o.radius * .5 ? l : o.radius * 2.4;
4420
4532
  i.current = {
4421
4533
  endPosition: s.clone().addScaledVector(c, u),
4422
4534
  endTarget: s,
4423
- endUp: Ua(c),
4535
+ endUp: oo(c),
4424
4536
  startPosition: e.position.clone(),
4425
4537
  startTarget: a,
4426
4538
  startTime: performance.now(),
4427
4539
  startUp: e.up.clone()
4428
4540
  };
4429
4541
  }
4430
- function qa({ action: e, onPick: t }) {
4542
+ function uo({ action: e, onPick: t }) {
4431
4543
  let [n, r] = u(!1);
4432
4544
  return /* @__PURE__ */ I("group", {
4433
4545
  position: e.position,
4434
- onClick: Ra,
4546
+ onClick: to,
4435
4547
  onPointerDown: (n) => {
4436
- Ra(n), t(e);
4548
+ to(n), t(e);
4437
4549
  },
4438
4550
  onPointerEnter: (e) => {
4439
- Ra(e), r(!0);
4551
+ to(e), r(!0);
4440
4552
  },
4441
4553
  onPointerLeave: (e) => {
4442
- Ra(e), r(!1);
4554
+ to(e), r(!1);
4443
4555
  },
4444
4556
  children: [/* @__PURE__ */ I("mesh", {
4445
4557
  scale: e.scale,
@@ -4448,11 +4560,11 @@ function qa({ action: e, onPick: t }) {
4448
4560
  1,
4449
4561
  1
4450
4562
  ] }), /* @__PURE__ */ F("meshBasicMaterial", {
4451
- color: za(n),
4452
- opacity: Ba(n),
4563
+ color: no(n),
4564
+ opacity: ro(n),
4453
4565
  transparent: !0
4454
4566
  })]
4455
- }), e.label && /* @__PURE__ */ F(Ha, {
4567
+ }), e.label && /* @__PURE__ */ F(ao, {
4456
4568
  color: n ? "#ffffff" : "#50606f",
4457
4569
  label: e.label,
4458
4570
  position: [
@@ -4464,11 +4576,11 @@ function qa({ action: e, onPick: t }) {
4464
4576
  })]
4465
4577
  });
4466
4578
  }
4467
- function Ja({ active: e = !0, cameraRef: t, controlRef: n, modelRef: r }) {
4579
+ function fo({ active: e = !0, cameraRef: t, controlRef: n, modelRef: r }) {
4468
4580
  let i = l(null), a = l(null), o = c(() => [
4469
- ...Fa,
4470
- ...Ia(),
4471
- ...La()
4581
+ ...Qa,
4582
+ ...$a(),
4583
+ ...eo()
4472
4584
  ], []);
4473
4585
  return f(() => {
4474
4586
  if (!e) return;
@@ -4477,16 +4589,16 @@ function Ja({ active: e = !0, cameraRef: t, controlRef: n, modelRef: r }) {
4477
4589
  i.current && i.current.quaternion.copy(r.quaternion).invert();
4478
4590
  let o = a.current;
4479
4591
  if (!o) return;
4480
- let s = performance.now() - o.startTime, c = Math.min(s / ja, 1), l = 1 - (1 - c) ** 3, u = n.current;
4592
+ let s = performance.now() - o.startTime, c = Math.min(s / Ja, 1), l = 1 - (1 - c) ** 3, u = n.current;
4481
4593
  r.position.lerpVectors(o.startPosition, o.endPosition, l), r.up.lerpVectors(o.startUp, o.endUp, l), u ? (u.target.lerpVectors(o.startTarget, o.endTarget, l), u.update()) : r.lookAt(o.endTarget), c >= 1 && (r.up.copy(o.endUp), u?.target.copy(o.endTarget), u?.update(), a.current = null);
4482
4594
  }), e ? /* @__PURE__ */ F("group", {
4483
4595
  ref: i,
4484
- scale: ka,
4485
- children: o.map((e) => /* @__PURE__ */ F(qa, {
4596
+ scale: Ka,
4597
+ children: o.map((e) => /* @__PURE__ */ F(uo, {
4486
4598
  action: e,
4487
4599
  onPick: (e) => {
4488
4600
  let i = t.current;
4489
- i && Ka({
4601
+ i && lo({
4490
4602
  camera: i,
4491
4603
  controlRef: n,
4492
4604
  direction: e.direction,
@@ -4499,13 +4611,13 @@ function Ja({ active: e = !0, cameraRef: t, controlRef: n, modelRef: r }) {
4499
4611
  }
4500
4612
  //#endregion
4501
4613
  //#region src/viewer/Viewer.tsx
4502
- var Ya = class {
4614
+ var po = class {
4503
4615
  sceneApi = null;
4504
4616
  get = () => this.sceneApi;
4505
4617
  set = (e) => {
4506
4618
  this.sceneApi = e;
4507
4619
  };
4508
- }, Xa = {
4620
+ }, mo = {
4509
4621
  bottom: 16,
4510
4622
  height: 96,
4511
4623
  pointerEvents: "auto",
@@ -4514,11 +4626,11 @@ var Ya = class {
4514
4626
  touchAction: "none",
4515
4627
  width: 96,
4516
4628
  zIndex: 2
4517
- }, Za = {
4629
+ }, ho = {
4518
4630
  height: "100%",
4519
4631
  position: "relative",
4520
4632
  width: "100%"
4521
- }, Qa = {
4633
+ }, go = {
4522
4634
  far: 50,
4523
4635
  near: .1,
4524
4636
  position: [
@@ -4527,16 +4639,16 @@ var Ya = class {
4527
4639
  10
4528
4640
  ],
4529
4641
  zoom: 72
4530
- }, $a = {
4642
+ }, _o = {
4531
4643
  alpha: !0,
4532
4644
  antialias: !0
4533
4645
  };
4534
- function eo() {
4646
+ function vo() {
4535
4647
  let e = navigator, t = navigator.userAgent.toLowerCase(), n = navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1, r = window.matchMedia?.("(pointer: coarse)").matches ?? !1;
4536
4648
  return e.userAgentData?.mobile || n || /android|iphone|ipad|ipod|mobile|tablet/.test(t) || navigator.maxTouchPoints > 1 && r ? "mobile" : "pc";
4537
4649
  }
4538
- function to({ autoFitCamera: e, cameraRef: t, controlRef: n, lightRef: r, modelRef: i, modelsData: a, onReady: s, publicApi: u, setSceneApi: d }) {
4539
- let f = p((e) => e.camera), g = Mt(i), _ = Ut(g), { colorPaletteTexture: v, colorUtils: y } = Ge(g), b = zn(i), x = _n(i, n, b), S = Mn(i, n, b), C = c(() => new ki(), []), w = _.buildIndex, T = g.resetIndex, E = y.applyStoredColors, D = Nr(), ee = l(!1), O = L((e) => e.showStats), te = c(() => {
4650
+ function yo({ autoFitCamera: e, cameraRef: t, controlRef: n, lightRef: r, modelRef: i, modelsData: a, onReady: s, publicApi: u, setSceneApi: d }) {
4651
+ let f = p((e) => e.camera), g = Mt(i), _ = Ut(g), { colorPaletteTexture: v, colorUtils: y } = Ge(g), b = zn(i), x = _n(i, n, b), S = Mn(i, n, b), C = c(() => new Ki(), []), w = _.buildIndex, T = g.resetIndex, E = y.applyStoredColors, D = Nr(), ee = l(!1), O = L((e) => e.showStats), te = c(() => {
4540
4652
  let e = Object.keys(a).sort((e, t) => Number(e) - Number(t));
4541
4653
  for (let t of e) {
4542
4654
  let e = St(a[Number(t)]);
@@ -4682,7 +4794,7 @@ function to({ autoFitCamera: e, cameraRef: t, controlRef: n, lightRef: r, modelR
4682
4794
  })
4683
4795
  ] });
4684
4796
  }
4685
- function no({ autoFitCamera: e = !0, camera: t = {
4797
+ function bo({ autoFitCamera: e = !0, camera: t = {
4686
4798
  position: [
4687
4799
  10,
4688
4800
  10,
@@ -4692,7 +4804,7 @@ function no({ autoFitCamera: e = !0, camera: t = {
4692
4804
  }, dpr: n = window.devicePixelRatio, modelUrls: r, modelSources: i, modelsData: a, onReady: s, publicApi: c, setSceneApi: f, showNavCube: p, showStats: m }) {
4693
4805
  let h = l(null), g = l(null), _ = l(null), v = l(null), [y, b] = u(), x = R(), S = L((e) => e.setModelNames), C = L((e) => e.setModelProps), w = L((e) => e.setModelStructure), T = L((e) => e.setShowNavCube), E = L((e) => e.setShowStats), D = L((e) => e.setUserDevice), ee = L((e) => e.showNavCube), O = a ?? y;
4694
4806
  return o(() => {
4695
- D(eo());
4807
+ D(vo());
4696
4808
  }, [D]), o(() => {
4697
4809
  E(!!m);
4698
4810
  }, [E, m]), o(() => {
@@ -4713,7 +4825,7 @@ function no({ autoFitCamera: e = !0, camera: t = {
4713
4825
  let e = i ?? r;
4714
4826
  if (!e?.length) return;
4715
4827
  let t = !0;
4716
- return Ca.loadModel(e).then((e) => {
4828
+ return Ba.loadModel(e).then((e) => {
4717
4829
  t && b(e);
4718
4830
  }), () => {
4719
4831
  t = !1;
@@ -4723,13 +4835,13 @@ function no({ autoFitCamera: e = !0, camera: t = {
4723
4835
  i,
4724
4836
  r
4725
4837
  ]), O ? /* @__PURE__ */ I("div", {
4726
- style: Za,
4838
+ style: ho,
4727
4839
  children: [/* @__PURE__ */ F(d, {
4728
4840
  camera: t,
4729
4841
  dpr: n,
4730
4842
  children: /* @__PURE__ */ F(Pr, {
4731
4843
  store: x,
4732
- children: /* @__PURE__ */ F(to, {
4844
+ children: /* @__PURE__ */ F(yo, {
4733
4845
  autoFitCamera: e,
4734
4846
  cameraRef: h,
4735
4847
  controlRef: g,
@@ -4742,13 +4854,13 @@ function no({ autoFitCamera: e = !0, camera: t = {
4742
4854
  })
4743
4855
  })
4744
4856
  }), ee && /* @__PURE__ */ F("div", {
4745
- style: Xa,
4857
+ style: mo,
4746
4858
  children: /* @__PURE__ */ F(d, {
4747
- camera: Qa,
4859
+ camera: go,
4748
4860
  dpr: n,
4749
- gl: $a,
4861
+ gl: _o,
4750
4862
  orthographic: !0,
4751
- children: /* @__PURE__ */ F(Ja, {
4863
+ children: /* @__PURE__ */ F(fo, {
4752
4864
  active: !0,
4753
4865
  cameraRef: h,
4754
4866
  controlRef: g,
@@ -4758,33 +4870,33 @@ function no({ autoFitCamera: e = !0, camera: t = {
4758
4870
  })]
4759
4871
  }) : /* @__PURE__ */ F(Te, {});
4760
4872
  }
4761
- var ro = n(function(e, t) {
4762
- let [n] = u(je), r = l(!1), a = l(!1), d = c(() => new Ya(), []), { defaultSelected: f, onSelectedChange: p, selected: m } = e, h = i((e) => {
4873
+ var xo = n(function(e, t) {
4874
+ let [n] = u(je), r = l(!1), a = l(!1), d = c(() => new po(), []), { defaultSelected: f, onSelectedChange: p, selected: m } = e, h = i((e) => {
4763
4875
  d.set(e);
4764
- }, [d]), g = c(() => Ki(n, d.get), [d, n]);
4876
+ }, [d]), g = c(() => la(n, d.get), [d, n]);
4765
4877
  return s(t, () => g, [g]), o(() => (n.getState().setApi(g), () => {
4766
4878
  n.getState().api === g && n.getState().setApi(null);
4767
4879
  }), [g, n]), o(() => {
4768
- r.current || !f || m !== void 0 || (r.current = !0, n.getState().setSelection(Gi(f)));
4880
+ r.current || !f || m !== void 0 || (r.current = !0, n.getState().setSelection(ca(f)));
4769
4881
  }, [
4770
4882
  m,
4771
4883
  f,
4772
4884
  n
4773
4885
  ]), o(() => {
4774
- m !== void 0 && (a.current = !0, n.getState().setSelection(Gi(m)), a.current = !1);
4886
+ m !== void 0 && (a.current = !0, n.getState().setSelection(ca(m)), a.current = !1);
4775
4887
  }, [m, n]), o(() => {
4776
4888
  if (p) return n.subscribe((e, t) => {
4777
- e.selected !== t.selected && (a.current || p(Wi(e.selected)));
4889
+ e.selected !== t.selected && (a.current || p(sa(e.selected)));
4778
4890
  });
4779
4891
  }, [p, n]), /* @__PURE__ */ F(Pr, {
4780
4892
  store: n,
4781
- children: /* @__PURE__ */ F(no, {
4893
+ children: /* @__PURE__ */ F(bo, {
4782
4894
  ...e,
4783
4895
  publicApi: g,
4784
4896
  setSceneApi: h
4785
4897
  })
4786
4898
  });
4787
4899
  });
4788
- ro.displayName = "Viewer";
4900
+ xo.displayName = "Viewer";
4789
4901
  //#endregion
4790
- export { Ji as BMTLoader, ki as BmtConverter, ji as ConvertIfcFileToBmt, Mi as ConvertToBmt, wn as DimensionLine, jn as DimensionsUtils, Ui as FilteredElementsCollector, vt as ModelGrids, Ja as NavigationCube, ro as Viewer, Pr as ViewerStoreProvider, Ai as bmtConverter, ia as createBmtWorker, ga as createIfcWorker, je as createViewerStore, xi as exportExcel, vi as exportModelPropertiesToExcel, ra as loadBmtModelsInWorker, ha as loadIfcModelsInWorker, Ca as loader, Mn as useDimensionsUtils, L as useViewerStore, R as useViewerStoreApi };
4902
+ export { da as BMTLoader, Ki as BmtConverter, Ji as ConvertIfcFileToBmt, Yi as ConvertToBmt, wn as DimensionLine, jn as DimensionsUtils, oa as FilteredElementsCollector, vt as ModelGrids, fo as NavigationCube, xo as Viewer, Pr as ViewerStoreProvider, qi as bmtConverter, xa as createBmtWorker, Na as createIfcWorker, je as createViewerStore, xi as exportExcel, vi as exportModelPropertiesToExcel, ba as loadBmtModelsInWorker, Ma as loadIfcModelsInWorker, Ba as loader, Mn as useDimensionsUtils, L as useViewerStore, R as useViewerStoreApi };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bimatter-viewer-react",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "license": "PolyForm-Noncommercial-1.0.0",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",