@thatopen/components 2.4.0-alpha.6 → 2.4.0-alpha.8

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.
@@ -35,7 +35,7 @@ export declare class Viewpoint implements BCFViewpoint {
35
35
  * A map of colors and components GUIDs that should be colorized when displaying a viewpoint.
36
36
  * For this to work, call viewpoint.colorize()
37
37
  */
38
- readonly componentColors: DataMap<string, string[]>;
38
+ readonly componentColors: DataMap<THREE.Color, string[]>;
39
39
  /**
40
40
  * Boolean flags to allow fine control over the visibility of spaces.
41
41
  * A typical use of these flags is when DefaultVisibility=true but spaces should remain hidden.
@@ -163,6 +163,7 @@ export declare class Viewpoint implements BCFViewpoint {
163
163
  * @throws An error if the world's renderer is not available.
164
164
  */
165
165
  updateCamera(): void;
166
+ applyVisibility(): void;
166
167
  /**
167
168
  * Applies color to the components in the viewpoint based on their GUIDs.
168
169
  *
@@ -173,14 +174,13 @@ export declare class Viewpoint implements BCFViewpoint {
173
174
  * The color is applied using the `Classifier.setColor` method, which sets the color of the specified fragments.
174
175
  * The color is provided as a hexadecimal string, prefixed with a '#'.
175
176
  */
176
- colorize(): void;
177
+ applyColors(): void;
177
178
  /**
178
179
  * Resets the colors of all components in the viewpoint to their original color.
179
- * This method iterates through the `componentColors` map, retrieves the fragment IDs
180
- * corresponding to each color, and then uses the `Classifier` to reset the color of those fragments.
181
180
  */
182
181
  resetColors(): void;
183
182
  private createComponentTags;
183
+ private createColorTags;
184
184
  /**
185
185
  * Serializes the viewpoint into a buildingSMART compliant XML string for export.
186
186
  *
@@ -170,5 +170,15 @@ export declare class Classifier extends Component implements Disposable {
170
170
  * @throws Will throw an error if the fragment with the specified ID is not found.
171
171
  */
172
172
  resetColor(items: FRAGS.FragmentIdMap): void;
173
+ /**
174
+ * Exports the computed classification to persists them and import them back
175
+ * later for faster loading.
176
+ */
177
+ export(): string;
178
+ /**
179
+ * Imports a classification previously exported with .export().
180
+ * @param data the serialized classification to import.
181
+ */
182
+ import(data: string): void;
173
183
  protected saveItem(group: FRAGS.FragmentsGroup, systemName: string, className: string, expressID: number, parentID?: number | null): void;
174
184
  }
package/dist/index.cjs CHANGED
@@ -24090,6 +24090,47 @@ const _Classifier = class _Classifier extends Component {
24090
24090
  found.resetColor(ids);
24091
24091
  }
24092
24092
  }
24093
+ /**
24094
+ * Exports the computed classification to persists them and import them back
24095
+ * later for faster loading.
24096
+ */
24097
+ export() {
24098
+ const exported = {};
24099
+ for (const systemName in this.list) {
24100
+ exported[systemName] = {};
24101
+ const system = this.list[systemName];
24102
+ for (const groupName in system) {
24103
+ const group = system[groupName];
24104
+ exported[systemName][groupName] = {
24105
+ map: FRAGS__namespace.FragmentUtils.export(group.map),
24106
+ name: group.name,
24107
+ id: group.id
24108
+ };
24109
+ }
24110
+ }
24111
+ return JSON.stringify(exported);
24112
+ }
24113
+ /**
24114
+ * Imports a classification previously exported with .export().
24115
+ * @param data the serialized classification to import.
24116
+ */
24117
+ import(data) {
24118
+ const imported = JSON.parse(data);
24119
+ for (const systemName in imported) {
24120
+ if (!this.list[systemName]) {
24121
+ this.list[systemName] = {};
24122
+ }
24123
+ const system = imported[systemName];
24124
+ for (const groupName in system) {
24125
+ const group = system[groupName];
24126
+ this.list[systemName][groupName] = {
24127
+ map: FRAGS__namespace.FragmentUtils.import(group.map),
24128
+ name: group.name,
24129
+ id: group.id
24130
+ };
24131
+ }
24132
+ }
24133
+ }
24093
24134
  saveItem(group, systemName, className, expressID, parentID = null) {
24094
24135
  if (!this.list[systemName]) {
24095
24136
  this.list[systemName] = {};
@@ -24402,6 +24443,7 @@ const _IfcGeometryTiler = class _IfcGeometryTiler extends Component {
24402
24443
  this.webIfc.SetLogLevel(logLevel);
24403
24444
  }
24404
24445
  this.webIfc.OpenModelFromCallback(loadCallback, this.settings.webIfc);
24446
+ this._nextAvailableID = this.webIfc.GetMaxExpressID(0);
24405
24447
  }
24406
24448
  async streamAllGeometries() {
24407
24449
  console.log("Converting geometries to tiles...");
@@ -24511,7 +24553,7 @@ const _IfcGeometryTiler = class _IfcGeometryTiler extends Component {
24511
24553
  const factor = isOpaque ? 1 : -1;
24512
24554
  const transpGeometryID = geometryID * factor;
24513
24555
  if (!this._visitedGeometries.has(transpGeometryID)) {
24514
- this.getGeometry(webIfc, geometryID, transpGeometryID);
24556
+ this.getGeometry(webIfc, geometryID, isOpaque);
24515
24557
  }
24516
24558
  this.registerGeometryData(
24517
24559
  group,
@@ -24530,7 +24572,7 @@ const _IfcGeometryTiler = class _IfcGeometryTiler extends Component {
24530
24572
  }
24531
24573
  this._assets.push(asset);
24532
24574
  }
24533
- getGeometry(webIfc, id, transpGeometryID) {
24575
+ getGeometry(webIfc, id, isOpaque) {
24534
24576
  const geometry = webIfc.GetGeometry(0, id);
24535
24577
  const index = webIfc.GetIndexArray(
24536
24578
  geometry.GetIndexData(),
@@ -24550,6 +24592,7 @@ const _IfcGeometryTiler = class _IfcGeometryTiler extends Component {
24550
24592
  normal[i / 2 + 1] = vertexData[i + 4];
24551
24593
  normal[i / 2 + 2] = vertexData[i + 5];
24552
24594
  }
24595
+ const factor = isOpaque ? 1 : -1;
24553
24596
  if (index.length === 0) {
24554
24597
  const boundingBox2 = new Float32Array([
24555
24598
  0,
@@ -24578,6 +24621,7 @@ const _IfcGeometryTiler = class _IfcGeometryTiler extends Component {
24578
24621
  });
24579
24622
  const geomIndex = this._visitedGeometries.size;
24580
24623
  const uuid = THREE__namespace.MathUtils.generateUUID();
24624
+ const transpGeometryID = id * factor;
24581
24625
  this._visitedGeometries.set(transpGeometryID, { uuid, index: geomIndex });
24582
24626
  this._geometryCount++;
24583
24627
  geometry.delete();
@@ -24627,6 +24671,7 @@ const _IfcGeometryTiler = class _IfcGeometryTiler extends Component {
24627
24671
  }
24628
24672
  const geomIndex = this._visitedGeometries.size;
24629
24673
  const uuid = THREE__namespace.MathUtils.generateUUID();
24674
+ const transpGeometryID = geometryID * factor;
24630
24675
  this._visitedGeometries.set(transpGeometryID, { uuid, index: geomIndex });
24631
24676
  this._geometryCount++;
24632
24677
  firstSplit = false;
@@ -24846,9 +24891,9 @@ class Viewpoint {
24846
24891
  */
24847
24892
  __publicField(this, "clippingPlanes", new DataSet());
24848
24893
  __publicField(this, "camera", {
24849
- aspectRatio: 0,
24850
- fov: 0,
24851
- direction: { x: 0, y: 0, z: 80 },
24894
+ aspectRatio: 1,
24895
+ fov: 60,
24896
+ direction: { x: 0, y: 0, z: 0 },
24852
24897
  position: { x: 0, y: 0, z: 0 }
24853
24898
  });
24854
24899
  /**
@@ -25088,6 +25133,19 @@ class Viewpoint {
25088
25133
  if (camera instanceof OrthoPerspectiveCamera) {
25089
25134
  camera.projection.set(this.projection);
25090
25135
  }
25136
+ const basePosition = new THREE__namespace.Vector3(
25137
+ this.camera.position.x,
25138
+ this.camera.position.y,
25139
+ this.camera.position.z
25140
+ );
25141
+ const baseTarget = new THREE__namespace.Vector3(
25142
+ this.camera.direction.x,
25143
+ this.camera.direction.y,
25144
+ this.camera.direction.z
25145
+ );
25146
+ if (basePosition.equals(new THREE__namespace.Vector3()) && baseTarget.equals(new THREE__namespace.Vector3())) {
25147
+ return;
25148
+ }
25091
25149
  const position = this.position;
25092
25150
  const direction = this.direction;
25093
25151
  let target = {
@@ -25109,10 +25167,6 @@ class Viewpoint {
25109
25167
  target = bb.getSphere().center;
25110
25168
  bb.reset();
25111
25169
  }
25112
- const hider = this._components.get(Hider);
25113
- hider.set(this.defaultVisibility);
25114
- hider.set(!this.defaultVisibility, this.exception);
25115
- hider.set(true, selection);
25116
25170
  await camera.controls.setLookAt(
25117
25171
  position.x,
25118
25172
  position.y,
@@ -25173,6 +25227,12 @@ class Viewpoint {
25173
25227
  const manager = this._components.get(Viewpoints);
25174
25228
  manager.list.set(this.guid, this);
25175
25229
  }
25230
+ applyVisibility() {
25231
+ const hider = this._components.get(Hider);
25232
+ hider.set(this.defaultVisibility);
25233
+ hider.set(!this.defaultVisibility, this.exception);
25234
+ hider.set(true, this.selection);
25235
+ }
25176
25236
  /**
25177
25237
  * Applies color to the components in the viewpoint based on their GUIDs.
25178
25238
  *
@@ -25183,24 +25243,17 @@ class Viewpoint {
25183
25243
  * The color is applied using the `Classifier.setColor` method, which sets the color of the specified fragments.
25184
25244
  * The color is provided as a hexadecimal string, prefixed with a '#'.
25185
25245
  */
25186
- colorize() {
25246
+ applyColors() {
25187
25247
  const manager = this._components.get(Viewpoints);
25188
25248
  const fragments = this._components.get(FragmentsManager);
25189
25249
  const classifier = this._components.get(Classifier);
25190
25250
  for (const [color, guids] of this.componentColors) {
25191
25251
  const fragmentIdMap = fragments.guidToFragmentIdMap(guids);
25192
- const threeColor = new THREE__namespace.Color(`#${color}`);
25193
- classifier.setColor(
25194
- fragmentIdMap,
25195
- threeColor,
25196
- manager.config.overwriteColors
25197
- );
25252
+ classifier.setColor(fragmentIdMap, color, manager.config.overwriteColors);
25198
25253
  }
25199
25254
  }
25200
25255
  /**
25201
25256
  * Resets the colors of all components in the viewpoint to their original color.
25202
- * This method iterates through the `componentColors` map, retrieves the fragment IDs
25203
- * corresponding to each color, and then uses the `Classifier` to reset the color of those fragments.
25204
25257
  */
25205
25258
  resetColors() {
25206
25259
  const fragments = this._components.get(FragmentsManager);
@@ -25243,6 +25296,23 @@ class Viewpoint {
25243
25296
  }
25244
25297
  return tags;
25245
25298
  }
25299
+ createColorTags() {
25300
+ let colorTags = "";
25301
+ for (const [color, components] of this.componentColors.entries()) {
25302
+ const hex = `#${color.getHexString()}`;
25303
+ const tags = components.map((globalId) => `
25304
+ <Component IfcGuid="${globalId}" />`).join("\n");
25305
+ colorTags += `<Color Color="${hex}">
25306
+ ${tags}
25307
+ </Color>`;
25308
+ }
25309
+ if (colorTags.length !== 0) {
25310
+ return `<Coloring>
25311
+ ${colorTags}
25312
+ </Coloring>`;
25313
+ }
25314
+ return `<Coloring />`;
25315
+ }
25246
25316
  /**
25247
25317
  * Serializes the viewpoint into a buildingSMART compliant XML string for export.
25248
25318
  *
@@ -25301,6 +25371,7 @@ class Viewpoint {
25301
25371
  const viewSetupHints = `<ViewSetupHints SpacesVisible="${this.spacesVisible ?? false}" SpaceBoundariesVisible="${this.spaceBoundariesVisible ?? false}" OpeningsVisible="${this.openingsVisible ?? false}" />`;
25302
25372
  const selectionTags = (await this.createComponentTags("selection")).trim();
25303
25373
  const exceptionTags = (await this.createComponentTags("exception")).trim();
25374
+ const colorTags = this.createColorTags();
25304
25375
  return `<?xml version="1.0" encoding="UTF-8"?>
25305
25376
  <VisualizationInfo Guid="${this.guid}">
25306
25377
  <Components>
@@ -25310,6 +25381,7 @@ class Viewpoint {
25310
25381
  ${version === "3" ? viewSetupHints : ""}
25311
25382
  ${exceptionTags.length !== 0 ? `<Exceptions>${exceptionTags}</Exceptions>` : ""}
25312
25383
  </Visibility>
25384
+ ${colorTags}
25313
25385
  </Components>
25314
25386
  ${cameraXML}
25315
25387
  </VisualizationInfo>`;
@@ -27262,6 +27334,7 @@ const createEntityFacets = (components, elements) => {
27262
27334
  if (element.cardinality)
27263
27335
  facet.cardinality = element.cardinality;
27264
27336
  facet.predefinedType = getParameterValue(element.predefinedType);
27337
+ facet.instructions = element.instructions;
27265
27338
  facets.push(facet);
27266
27339
  }
27267
27340
  return facets;
@@ -27277,6 +27350,7 @@ const createAttributeFacets = (components, elements) => {
27277
27350
  if (element.cardinality)
27278
27351
  facet.cardinality = element.cardinality;
27279
27352
  facet.value = getParameterValue(element.value);
27353
+ facet.instructions = element.instructions;
27280
27354
  facets.push(facet);
27281
27355
  }
27282
27356
  return facets;
@@ -27300,6 +27374,7 @@ const createClassificationFacets = (components, elements) => {
27300
27374
  }
27301
27375
  facet.value = value;
27302
27376
  facet.uri = element.uri;
27377
+ facet.instructions = element.instructions;
27303
27378
  facets.push(facet);
27304
27379
  }
27305
27380
  return facets;
@@ -27323,6 +27398,7 @@ const createPropertyFacets = (components, elements) => {
27323
27398
  facet.value = value;
27324
27399
  facet.dataType = element.dataType;
27325
27400
  facet.uri = element.uri;
27401
+ facet.instructions = element.instructions;
27326
27402
  facets.push(facet);
27327
27403
  }
27328
27404
  return facets;
@@ -27362,12 +27438,14 @@ const _IDSSpecifications = class _IDSSpecifications extends Component {
27362
27438
  *
27363
27439
  * @returns The newly created IDSSpecification instance.
27364
27440
  */
27365
- create(name, ifcVersion) {
27441
+ create(name, ifcVersion, identifier) {
27366
27442
  const specification = new IDSSpecification(
27367
27443
  this.components,
27368
27444
  name,
27369
27445
  ifcVersion
27370
27446
  );
27447
+ if (identifier)
27448
+ specification.identifier = identifier;
27371
27449
  this.list.set(specification.identifier, specification);
27372
27450
  return specification;
27373
27451
  }
@@ -27387,7 +27465,7 @@ const _IDSSpecifications = class _IDSSpecifications extends Component {
27387
27465
  if (specifications && specifications.specification) {
27388
27466
  const specs = Array.isArray(specifications.specification) ? specifications.specification : [specifications.specification];
27389
27467
  for (const spec of specs) {
27390
- const { name, ifcVersion } = spec;
27468
+ const { name, ifcVersion, description, instructions, identifier } = spec;
27391
27469
  if (!(name && ifcVersion))
27392
27470
  continue;
27393
27471
  const applicabilities = [];
@@ -27406,8 +27484,10 @@ const _IDSSpecifications = class _IDSSpecifications extends Component {
27406
27484
  }
27407
27485
  }
27408
27486
  }
27487
+ let requirementsDescription;
27409
27488
  if (requirements) {
27410
27489
  const { maxOccurs, ...rest } = requirements;
27490
+ requirementsDescription = requirements.description;
27411
27491
  const facets = Array.isArray(rest) ? rest : [rest];
27412
27492
  for (const facet of facets) {
27413
27493
  for (const facetName in facet) {
@@ -27435,7 +27515,14 @@ const _IDSSpecifications = class _IDSSpecifications extends Component {
27435
27515
  }
27436
27516
  }
27437
27517
  if (applicabilities.length > 0 && reqs.length > 0) {
27438
- const specification = this.create(name, ifcVersion.split(/\s+/));
27518
+ const specification = this.create(
27519
+ name,
27520
+ ifcVersion.split(/\s+/),
27521
+ identifier
27522
+ );
27523
+ specification.description = description;
27524
+ specification.instructions = instructions;
27525
+ specification.requirementsDescription = requirementsDescription;
27439
27526
  specification.applicability.add(...applicabilities);
27440
27527
  specification.requirements.add(...reqs);
27441
27528
  result.push(specification);