@thatopen/components 3.1.5 → 3.2.0

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
@@ -1,76 +1,76 @@
1
- <p align="center">
2
- <a href="https://thatopen.com/">TOC</a>
3
- |
4
- <a href="https://docs.thatopen.com/intro">documentation</a>
5
- |
6
- <a href="https://thatopen.github.io/engine_components/examples/IfcLoader/index.html">demo</a>
7
- |
8
- <a href="https://people.thatopen.com/">community</a>
9
- |
10
- <a href="https://www.npmjs.com/org/thatopen">npm package</a>
11
- </p>
12
-
13
- ![cover](https://thatopen.github.io/engine_components/resources/cover.png)
14
-
15
- <h1>Open BIM Components <img src="https://thatopen.github.io/engine_components/resources/favicon.ico" width="32"/></h1>
16
-
17
- [![NPM Package][npm]][npm-url]
18
- [![NPM Package][npm-downloads]][npm-url]
19
-
20
- This library is a collection of BIM tools based on [Three.js](https://github.com/mrdoob/three.js/) and other libraries. It includes pre-made features to easily build browser-based 3D BIM applications, such as postproduction, dimensions, floorplan navigation, DXF export and much more.
21
-
22
-
23
- ## 🤝 Want our help?
24
- Are you developing a project with our technology and would like our help?
25
- Apply now to join [That Open Accelerator Program](https://thatopen.com/accelerator)!
26
-
27
- ## Packages
28
-
29
- This library contains 2 packages:
30
-
31
- `@thatopen/components` - The core functionality. Compatible both with browser and Node.js environments.
32
-
33
- `@thatopen/components-front` - Features exclusive for browser environments.
34
-
35
- ## Usage
36
-
37
- You need to be familiar with [Three.js API](https://github.com/mrdoob/three.js/) to be able to use this library effectively. In the following example, we will create a cube in a 3D scene that can be navigated with the mouse or touch events. You can see the full example [here](https://github.com/ThatOpen/engine_components/blob/main/packages/core/src/core/Worlds/example.ts) and the deployed app [here](https://thatopen.github.io/engine_components/examples/Worlds/index.html).
38
-
39
- ```js
40
- /* eslint import/no-extraneous-dependencies: 0 */
41
-
42
- import * as THREE from "three";
43
- import * as OBC from "../..";
44
-
45
- const container = document.getElementById("container")!;
46
-
47
- const components = new OBC.Components();
48
-
49
- const worlds = components.get(OBC.Worlds);
50
-
51
- const world = worlds.create<
52
- OBC.SimpleScene,
53
- OBC.SimpleCamera,
54
- OBC.SimpleRenderer
55
- >();
56
-
57
- world.scene = new OBC.SimpleScene(components);
58
- world.renderer = new OBC.SimpleRenderer(components, container);
59
- world.camera = new OBC.SimpleCamera(components);
60
-
61
- components.init();
62
-
63
- const material = new THREE.MeshLambertMaterial({ color: "#6528D7" });
64
- const geometry = new THREE.BoxGeometry();
65
- const cube = new THREE.Mesh(geometry, material);
66
- world.scene.three.add(cube);
67
-
68
- world.scene.setup();
69
-
70
- world.camera.controls.setLookAt(3, 3, 3, 0, 0, 0);
71
- ```
72
-
73
-
74
- [npm]: https://img.shields.io/npm/v/@thatopen/components
75
- [npm-url]: https://www.npmjs.com/package/@thatopen/components
76
- [npm-downloads]: https://img.shields.io/npm/dw/@thatopen/components
1
+ <p align="center">
2
+ <a href="https://thatopen.com/">TOC</a>
3
+ |
4
+ <a href="https://docs.thatopen.com/intro">documentation</a>
5
+ |
6
+ <a href="https://thatopen.github.io/engine_components/examples/IfcLoader/index.html">demo</a>
7
+ |
8
+ <a href="https://people.thatopen.com/">community</a>
9
+ |
10
+ <a href="https://www.npmjs.com/org/thatopen">npm package</a>
11
+ </p>
12
+
13
+ ![cover](https://thatopen.github.io/engine_components/resources/cover.png)
14
+
15
+ <h1>Open BIM Components <img src="https://thatopen.github.io/engine_components/resources/favicon.ico" width="32"/></h1>
16
+
17
+ [![NPM Package][npm]][npm-url]
18
+ [![NPM Package][npm-downloads]][npm-url]
19
+
20
+ This library is a collection of BIM tools based on [Three.js](https://github.com/mrdoob/three.js/) and other libraries. It includes pre-made features to easily build browser-based 3D BIM applications, such as postproduction, dimensions, floorplan navigation, DXF export and much more.
21
+
22
+
23
+ ## 🤝 Want our help?
24
+ Are you developing a project with our technology and would like our help?
25
+ Apply now to join [That Open Accelerator Program](https://thatopen.com/accelerator)!
26
+
27
+ ## Packages
28
+
29
+ This library contains 2 packages:
30
+
31
+ `@thatopen/components` - The core functionality. Compatible both with browser and Node.js environments.
32
+
33
+ `@thatopen/components-front` - Features exclusive for browser environments.
34
+
35
+ ## Usage
36
+
37
+ You need to be familiar with [Three.js API](https://github.com/mrdoob/three.js/) to be able to use this library effectively. In the following example, we will create a cube in a 3D scene that can be navigated with the mouse or touch events. You can see the full example [here](https://github.com/ThatOpen/engine_components/blob/main/packages/core/src/core/Worlds/example.ts) and the deployed app [here](https://thatopen.github.io/engine_components/examples/Worlds/index.html).
38
+
39
+ ```js
40
+ /* eslint import/no-extraneous-dependencies: 0 */
41
+
42
+ import * as THREE from "three";
43
+ import * as OBC from "../..";
44
+
45
+ const container = document.getElementById("container")!;
46
+
47
+ const components = new OBC.Components();
48
+
49
+ const worlds = components.get(OBC.Worlds);
50
+
51
+ const world = worlds.create<
52
+ OBC.SimpleScene,
53
+ OBC.SimpleCamera,
54
+ OBC.SimpleRenderer
55
+ >();
56
+
57
+ world.scene = new OBC.SimpleScene(components);
58
+ world.renderer = new OBC.SimpleRenderer(components, container);
59
+ world.camera = new OBC.SimpleCamera(components);
60
+
61
+ components.init();
62
+
63
+ const material = new THREE.MeshLambertMaterial({ color: "#6528D7" });
64
+ const geometry = new THREE.BoxGeometry();
65
+ const cube = new THREE.Mesh(geometry, material);
66
+ world.scene.three.add(cube);
67
+
68
+ world.scene.setup();
69
+
70
+ world.camera.controls.setLookAt(3, 3, 3, 0, 0, 0);
71
+ ```
72
+
73
+
74
+ [npm]: https://img.shields.io/npm/v/@thatopen/components
75
+ [npm-url]: https://www.npmjs.com/package/@thatopen/components
76
+ [npm-downloads]: https://img.shields.io/npm/dw/@thatopen/components
package/dist/index.cjs CHANGED
@@ -124,6 +124,10 @@ class Base {
124
124
  __publicField(this, "isConfigurable", () => {
125
125
  return "setup" in this && "config" in this && "onSetup" in this;
126
126
  });
127
+ /** Whether is component is {@link Serializable}. */
128
+ __publicField(this, "isSerializable", () => {
129
+ return "import" in this && "export" in this;
130
+ });
127
131
  this.components = components;
128
132
  }
129
133
  }
@@ -3176,6 +3180,7 @@ const _FragmentsManager = class _FragmentsManager extends Component {
3176
3180
  super(components);
3177
3181
  /** {@link Disposable.onDisposed} */
3178
3182
  __publicField(this, "onDisposed", new Event());
3183
+ __publicField(this, "onBeforeDispose", new Event());
3179
3184
  /**
3180
3185
  * Event triggered when fragments are loaded.
3181
3186
  */
@@ -3184,10 +3189,12 @@ const _FragmentsManager = class _FragmentsManager extends Component {
3184
3189
  __publicField(this, "baseCoordinationMatrix", new THREE__namespace.Matrix4());
3185
3190
  /** {@link Component.enabled} */
3186
3191
  __publicField(this, "enabled", true);
3187
- __publicField(this, "initialized", false);
3188
3192
  __publicField(this, "_core");
3189
3193
  this.components.add(_FragmentsManager.uuid, this);
3190
3194
  }
3195
+ get initialized() {
3196
+ return !!this._core;
3197
+ }
3191
3198
  /**
3192
3199
  * Map containing all loaded fragment models.
3193
3200
  * The key is the group's unique identifier, and the value is the model itself.
@@ -3201,8 +3208,12 @@ const _FragmentsManager = class _FragmentsManager extends Component {
3201
3208
  }
3202
3209
  return this._core;
3203
3210
  }
3211
+ get _hasCoordinationModel() {
3212
+ return this.baseCoordinationModel !== "";
3213
+ }
3204
3214
  /** {@link Disposable.dispose} */
3205
3215
  dispose() {
3216
+ this.onBeforeDispose.trigger();
3206
3217
  if (this._core) {
3207
3218
  this.core.dispose();
3208
3219
  this._core = void 0;
@@ -3214,12 +3225,14 @@ const _FragmentsManager = class _FragmentsManager extends Component {
3214
3225
  }
3215
3226
  init(workerURL) {
3216
3227
  this._core = new FRAGS.FragmentsModels(workerURL);
3217
- this.initialized = true;
3218
- this.core.onModelLoaded.add(async (model) => {
3219
- if (this.list.size !== 1)
3228
+ this.core.onModelLoaded.add(async () => {
3229
+ if (this._hasCoordinationModel)
3220
3230
  return;
3221
- this.baseCoordinationModel = model.modelId;
3222
- this.baseCoordinationMatrix = await model.getCoordinationMatrix();
3231
+ const firstModel = [...this.list.values()][0];
3232
+ if (!firstModel)
3233
+ return;
3234
+ this.baseCoordinationModel = firstModel.modelId;
3235
+ this.baseCoordinationMatrix = await firstModel.getCoordinationMatrix();
3223
3236
  });
3224
3237
  this.list.onItemDeleted.add(() => {
3225
3238
  if (this.list.size > 0)
@@ -3894,7 +3907,7 @@ __publicField(_BoundingBoxer, "uuid", "d1444724-dba6-4cdd-a0c7-68ee1450d166");
3894
3907
  let BoundingBoxer = _BoundingBoxer;
3895
3908
  class FinderQuery {
3896
3909
  constructor(components, queries) {
3897
- __publicField(this, "description");
3910
+ __publicField(this, "customData", {});
3898
3911
  __publicField(this, "_components");
3899
3912
  __publicField(this, "_queries", []);
3900
3913
  __publicField(this, "_aggregation", "exclusive");
@@ -4017,9 +4030,11 @@ class FinderQuery {
4017
4030
  * @returns A `SerializedFinderQuery` object representing the serialized query.
4018
4031
  */
4019
4032
  toJSON() {
4033
+ const manager = this._components.get(ItemsFinder);
4034
+ const name = manager.list.getKey(this) ?? "Finder Query";
4020
4035
  const result = {
4021
- name: "Finder Query",
4022
- description: this.description,
4036
+ name,
4037
+ customData: this.customData,
4023
4038
  queries: this.queries.map(this.serializeQueryParameters),
4024
4039
  aggregation: this.aggregation,
4025
4040
  cache: this.cache
@@ -4051,7 +4066,7 @@ class FinderQuery {
4051
4066
  * @returns A `FinderQuery` instance.
4052
4067
  */
4053
4068
  fromJSON(data) {
4054
- this.description = data.description;
4069
+ this.customData = data.customData;
4055
4070
  this.aggregation = data.aggregation;
4056
4071
  this.cache = data.cache;
4057
4072
  this.queries = data.queries.map(this.deserializeQueryParameters);
@@ -4151,9 +4166,9 @@ const _ItemsFinder = class _ItemsFinder extends Component {
4151
4166
  if (!data)
4152
4167
  return instances;
4153
4168
  for (const value of data) {
4154
- const { name, description, queries, aggregation, cache } = value;
4169
+ const { name, customData, queries, aggregation, cache } = value;
4155
4170
  const finderQuery = this.create(name, []);
4156
- finderQuery.fromJSON({ description, queries, aggregation, cache });
4171
+ finderQuery.fromJSON({ customData, queries, aggregation, cache });
4157
4172
  instances.push(finderQuery);
4158
4173
  }
4159
4174
  return instances;
@@ -15895,21 +15910,6 @@ ${users}
15895
15910
  const viewpoint = new Viewpoint(this.components, bcfViewpoint);
15896
15911
  createdViewpoints.push(viewpoint);
15897
15912
  }
15898
- const getNameWithoutExtension = (name) => {
15899
- const partsBySlash = name.split("/");
15900
- const partsByDot = partsBySlash[partsBySlash.length - 1].split(".");
15901
- partsByDot.pop();
15902
- return partsByDot.join(".");
15903
- };
15904
- const snapshotFiles = files.filter(
15905
- (file) => file.name.endsWith(".png") || file.name.endsWith(".jpeg")
15906
- );
15907
- for (const file of snapshotFiles) {
15908
- const name = getNameWithoutExtension(file.name);
15909
- const buffer = await file.async("arraybuffer");
15910
- const bytes = new Uint8Array(buffer);
15911
- viewpoints.snapshots.set(name, bytes);
15912
- }
15913
15913
  const topicRelations = {};
15914
15914
  const topics = [];
15915
15915
  const markupFiles = files.filter((file) => file.name.endsWith(".bcf"));
@@ -15958,12 +15958,16 @@ ${users}
15958
15958
  if (!(markupViewpoint && markupViewpoint.Guid))
15959
15959
  continue;
15960
15960
  const viewpoint = viewpoints.list.get(markupViewpoint.Guid);
15961
- if (viewpoint) {
15962
- topic.viewpoints.add(viewpoint.guid);
15963
- const snapshotName = getNameWithoutExtension(
15964
- markupViewpoint.Snapshot
15965
- );
15966
- viewpoint.snapshot = snapshotName ?? null;
15961
+ if (!viewpoint)
15962
+ continue;
15963
+ topic.viewpoints.add(viewpoint.guid);
15964
+ const snapshotName = `${topic.guid}/${markupViewpoint.Snapshot}`;
15965
+ const snapshotFile = files.find(({ name }) => name === snapshotName);
15966
+ if (snapshotFile) {
15967
+ const buffer = await snapshotFile.async("arraybuffer");
15968
+ const bytes = new Uint8Array(buffer);
15969
+ viewpoints.snapshots.set(viewpoint.guid, bytes);
15970
+ viewpoint.snapshot = viewpoint.guid ?? null;
15967
15971
  }
15968
15972
  }
15969
15973
  const markupDocReferences = this.getMarkupDocumentReferences(
@@ -18496,21 +18500,21 @@ ${colorTags}
18496
18500
  </CameraUpVector>`;
18497
18501
  const cameraRatioXML = `<AspectRatio>${this.camera.aspect_ratio}</AspectRatio>`;
18498
18502
  let cameraXML = "";
18499
- if ("viewToWorld" in this.camera) {
18503
+ if ("view_to_world_scale" in this.camera) {
18500
18504
  cameraXML = `<OrthogonalCamera>
18501
18505
  ${cameraViewpointXML}
18502
18506
  ${cameraDirectionXML}
18503
18507
  ${cameraUpVectorXML}
18504
18508
  ${cameraRatioXML}
18505
- <ViewToWorldScale>${this.camera.viewToWorld}</ViewToWorldScale>
18509
+ <ViewToWorldScale>${this.camera.view_to_world_scale}</ViewToWorldScale>
18506
18510
  </OrthogonalCamera>`;
18507
- } else if ("fov" in this.camera) {
18511
+ } else if ("field_of_view" in this.camera) {
18508
18512
  cameraXML = `<PerspectiveCamera>
18509
18513
  ${cameraViewpointXML}
18510
18514
  ${cameraDirectionXML}
18511
18515
  ${cameraUpVectorXML}
18512
18516
  ${cameraRatioXML}
18513
- <FieldOfView>${this.camera.fov}</FieldOfView>
18517
+ <FieldOfView>${this.camera.field_of_view}</FieldOfView>
18514
18518
  </PerspectiveCamera>`;
18515
18519
  }
18516
18520
  const viewSetupHints = `<ViewSetupHints SpacesVisible="${this.spacesVisible ?? false}" SpaceBoundariesVisible="${this.spaceBoundariesVisible ?? false}" OpeningsVisible="${this.openingsVisible ?? false}" />`;
@@ -19590,10 +19594,10 @@ class IDSFacet {
19590
19594
  collector.set(modelId, modelItemResults);
19591
19595
  }
19592
19596
  let result = modelItemResults.get(item._localId.value);
19593
- if (result && skipIfFails) {
19594
- if (!result.pass)
19595
- return null;
19596
- } else {
19597
+ if (result && skipIfFails && !result.pass) {
19598
+ return null;
19599
+ }
19600
+ if (!result) {
19597
19601
  const checks2 = [];
19598
19602
  result = {
19599
19603
  guid: Array.isArray(item._guid) ? void 0 : item._guid.value,
package/dist/index.d.ts CHANGED
@@ -80,6 +80,8 @@ export declare abstract class Base {
80
80
  isHideable: () => this is Hideable;
81
81
  /** Whether is component is {@link Configurable}. */
82
82
  isConfigurable: () => this is Configurable<any, any>;
83
+ /** Whether is component is {@link Serializable}. */
84
+ isSerializable: () => this is Serializable<any, Record<string, any>>;
83
85
  }
84
86
 
85
87
  /**
@@ -1633,7 +1635,7 @@ export declare interface ExternalDocumentReference extends DocumentReference {
1633
1635
  * Represents a finder query for retrieving items based on specified parameters. This class encapsulates the query logic, caching mechanism, and result management.
1634
1636
  */
1635
1637
  export declare class FinderQuery {
1636
- description?: string;
1638
+ customData: Record<string, any>;
1637
1639
  private _components;
1638
1640
  private _queries;
1639
1641
  /**
@@ -1715,7 +1717,8 @@ export declare class FragmentsManager extends Component implements Disposable_2
1715
1717
  */
1716
1718
  static readonly uuid: "fef46874-46a3-461b-8c44-2922ab77c806";
1717
1719
  /** {@link Disposable.onDisposed} */
1718
- readonly onDisposed: Event_2<unknown>;
1720
+ readonly onDisposed: Event_2<undefined>;
1721
+ readonly onBeforeDispose: Event_2<undefined>;
1719
1722
  /**
1720
1723
  * Event triggered when fragments are loaded.
1721
1724
  */
@@ -1724,7 +1727,7 @@ export declare class FragmentsManager extends Component implements Disposable_2
1724
1727
  baseCoordinationMatrix: THREE.Matrix4;
1725
1728
  /** {@link Component.enabled} */
1726
1729
  enabled: boolean;
1727
- initialized: boolean;
1730
+ get initialized(): boolean;
1728
1731
  private _core?;
1729
1732
  /**
1730
1733
  * Map containing all loaded fragment models.
@@ -1732,6 +1735,7 @@ export declare class FragmentsManager extends Component implements Disposable_2
1732
1735
  */
1733
1736
  get list(): FRAGS.DataMap<string, FRAGS.FragmentsModel>;
1734
1737
  get core(): FRAGS.FragmentsModels;
1738
+ private get _hasCoordinationModel();
1735
1739
  constructor(components: Components);
1736
1740
  /** {@link Disposable.dispose} */
1737
1741
  dispose(): void;
@@ -2868,9 +2872,9 @@ export declare interface SerializedFinderQuery {
2868
2872
  */
2869
2873
  name: string;
2870
2874
  /**
2871
- * An optional description of the query.
2875
+ * An object to define custom data.
2872
2876
  */
2873
- description?: string;
2877
+ customData: Record<string, any>;
2874
2878
  /**
2875
2879
  * An array of serialized query parameters.
2876
2880
  */
@@ -4052,7 +4056,7 @@ export declare class Viewpoint {
4052
4056
  }
4053
4057
 
4054
4058
  /**
4055
- * Represents a bitmap image associated with a viewpoint. This interface is compliant with the BCF API specifications.
4059
+ * Represents a bitmap image associated with a viewpoint. This interface is compliant with the BCF API specifications.
4056
4060
  */
4057
4061
  export declare interface ViewpointBitmap {
4058
4062
  /**