4.4.0 Change Notes

Table of contents:

Tracing API deprecation

As the OpenTelemetry API kept growing, we decided to deprecate the Tracing class and encourage direct usage of @opentelemetry/api instead.

iTwin.js will continue to create spans for RPC requests, and possibly other operations in the future.

Batched tileset enhancements

The @itwin/frontend-tiles package used to stream "batched" tilesets produced by the tech preview mesh export service received several updates.

After upgrading to the 4.4.0 version of this package, previously-published tilesets will fail to load. You will need to produce new exports using the mesh export service.

Per-model display settings

A view can customize how a model (or group of models) is displayed in a handful of ways:

These features work fine for the standard tilesets supplied by the iTwin.js backend, which produces one tileset for each model; but not for the tilesets produced by the mesh export service, which batches many models together into a single tileset to improve performance. That has now been rectified: per-model display settings are applied to the batched tiles while preserving the performance benefits of batching.

Support for excluded models

The mesh export service batches geometry from many SpatialModels together into a single tileset to improve performance, but some models are excluded. For example:

  • Models marked as "private", indicating they are hidden from pick lists in the user interface and generally not intended to be displayed in normal spatial views
    • These are often used to provide 3d geometry within a ViewAttachment.
  • Models that contain a URL pointing to a reality model providing their graphical representation.
  • "Template" models containing geometry that serves as a template for placing 3d components.

Previously, geometry from these models would fail to display. That has been rectified.

Batch table property access

A [[RealityTileTree]] may refer to a tileset in one of the 3D Tiles 1.0. Tiles within such tilesets may include a batch table describing subcomponents ("features") within the tile. For example, a tileset representing a building may encode each door, window, and wall as separate features. The batch table may additionally contain metadata in JSON format describing each feature.

During tile decoding, iTwin.js assigns a unique, transient Id64String to each unique feature within the tileset. When interacting with tileset features (e.g., via a [[SelectionSet]] or [[HitDetail]]), the features are identified by these transient Ids. The tile tree's BatchTableProperties maintains the mapping between the transient Ids and the per-feature properties.

To make use of the per-feature JSON properties, an application needs a way to look up the properties given the corresponding feature Id. The following example illustrates one way to obtain the properties of a specific feature within a reality model's batch table:

/** Given a viewport that is displaying one or more context reality models and the Id of a feature within one of those models' batch tables,
 * return the JSON properties associated with that feature.
 * @beta
export function getBatchTableFeatureProperties(featureId: Id64String, viewport: Viewport): Record<string, any> | undefined {
  // Iterate the viewport's context reality models to find the one to which the specified feature belongs.
  for (const model of viewport.displayStyle.realityModels) {
    const tree = model.treeRef.treeOwner.tileTree;

    // Only RealityTileTrees have batch tables, hence the `instanceof` check.
    const batchTableProperties = tree instanceof RealityTileTree ? tree.batchTableProperties : undefined;
    const featureProperties = batchTableProperties?.getFeatureProperties(featureId);
    if (featureProperties)
      return featureProperties;

  // The specified feature was not found in any context reality model's batch table.
  return undefined;

See [[RealityTileTree.batchTableProperties]] to obtain the batch table properties for a TileTree.


New efficient range tree methods PolyfaceRangeTreeContext.searchForClosestPoint and PolyfaceRangeTreeContext.searchForClosestApproach support searches of a Polyface for the closest facet point to a given space point, and searches of two Polyfaces for the segment spanning their closest approach. New classes Point3dArrayRangeTreeContext and LineString3dRangeTreeContext provide similar functionality for searching Point3d arrays and LineString3d objects, respectively.

Data conflict rejection

When more than one Briefcase contributes changesets to an iModel, conflicts can arise. For example:

  1. Briefcases A and B both modify the same element locally.
  2. Briefcase A pushes its changes to iModelHub.
  3. Briefcase B pulls Briefcase A's changes and attempts to merge them and push its own changes to iModelHub.

The conflict occurs in step 3. These kinds of conflicts are typically prevented through the use of client-side locking. But in the absence of locking, the merge would appear to succeed, and Briefcase B would be permitted to push its changes to iModelHub. When any briefcase subsequently tried to download and merge those changes, the merge would fail, rendering the iModel unusable from that point onward.

Now, the conflict will be detected before Briefcase B can push its changes, producing the error "UPDATE/DELETE before value do not match with one in db or CASCADE action was triggered". Briefcase B will have no recourse in this case but to abandon its local changes. In the future, we plan to introduce a mechanism for resolving such conflicts without abandoning changes. In the meanwhile, use of locking is strongly encouraged.

Last Updated: 12 February, 2024