2.16.0 Change Notes

Overview:

Obtaining element geometry on the frontend

Until now, an element's GeometryStreamProps was only available on the backend - IModelConnection.Elements.getProps always omits the geometry. IModelConnection.Elements.loadProps has been introduced to provide greater control over which properties are returned. It accepts the Id, federation Guid, or Code of the element of interest, and optionally an ElementLoadOptions specifying which properties to include or exclude. For example, the following code queries for and iterates over the geometry of a GeometricElement3d:

  function printGeometryStream(elementId: Id64String, iModel: IModelConnection): void {
    const props = await iModel.elements.loadProps(elementId, { wantGeometry: true }) as GeometricElement3dProps;
    assert(undefined !== props, `Element ${elementId} does not exist`);
    const iterator = GeometryStreamIterator.fromGeometricElement3d(props);
    for (const entry of iterator)
      console.log(JSON.stringify(entry));
  }

Keep in mind that geometry streams can be extremely large. They may also contain data like BRepEntity.DataProps that cannot be interpreted on the frontend; for this reason BRep data is omitted from the geometry stream, unless explicitly requested via ElementLoadOptions.wantBRepData.

Clipping enhancements

The contents of a ViewState can be clipped by applying a ClipVector to the view via ViewState.setViewClip. Several enhancements have been made to this feature:

Colorization

ClipStyle.insideColor and ClipStyle.outsideColor can be used to colorize geometry based on whether it is inside or outside of the clip volume. If the outside color is defined, then that geometry will be drawn in the specified color instead of being clipped. These properties replace the beta Viewport methods setInsideColor and setOutsideColor and are saved in the DisplayStyle.

Model clip groups

ModelClipGroups can be used to apply additional clip volumes to groups of models. Try it out with an interactive demo. Note that ViewFlags.clipVolume applies only to the view clip - model clips apply regardless of view flags.

Nested clip volumes

Clip volumes now nest. For example, if you define a view clip, a model clip group, and a schedule script that applies its own clip volume, then geometry will be clipped by the intersection of all three clip volumes. Previously, only one clip volume could be active at a time.

Grid display enhancements

The planar grid that is displayed when ViewFlags.grid is now displayed with a shader rather than as explicit geometry. This improved the overall appearance and efficiency of the grid display and corrects several anomalies when grid display was unstable at the horizon of a perspective view. The view frustum is now expanded as necessary when grids are displayed to avoid truncating the grid to the displayed geometry.

Schedule script enhancements

The RenderSchedule API for defining how to animate the contents of a view over time has been cleaned up and expanded. A new RenderTimeline element class has been introduced with version 1.0.13 of the BisCore ECSchema, to host a RenderSchedule.Script. DisplayStyleSettings.scheduleScriptProps has been deprecated in favor of DisplayStyleSettings.renderTimeline specifying the Id of the RenderTimeline element hosting the script to be applied to the display style. A DisplayStyleState's schedule script is now loaded asynchronously via DisplayStyleState.load - this is done automatically by ViewState.load but must be done manually for display styles obtained through other means.

Sometimes it is useful to make the elements animated by the script more visible by de-emphasizing elements unaffected by the script. The appearance of non-animated elements can now be controlled by EmphasizeElements.unanimatedAppearance.

Querying visible elements

The new @beta API Viewport.queryVisibleFeatures can be used to determine the set of Features - typically, elements - that are currently visible in the viewport. The API offers a choice between two criteria that can be used to determine visibility:

  • The feature lit up at least one pixel on the screen. Pixels drawn behind other, transparent pixels are not included in this criterion. Pixel-based queries can be constrained to a sub-region of the viewport.
  • The feature is included in at least one Tile currently being displayed by the viewport. By this criterion, if a ClipVector is clipping the contents of the viewport, a feature contained in a tile that intersects the clip volume is considered visible even if the feature's geometry would be completely clipped out.

Creating graphics

The new GraphicBuilderOptions makes it easier to create a GraphicBuilder and enables some additional features. DecorateContext.createGraphic and RenderSystem.createGraphic have been added, superseding DecorateContext.createGraphicBuilder and RenderSystem.createGraphicBuilder. Each accepts a GraphicBuilderOptions specifying only those aspects of the GraphicBuilder that the caller wishes to customize. In particular, the behavior of pickable decorations can be customized using GraphicBuilderOptions.pickable:

Map tile trees refactoring

The map tile trees have been moved from DisplayStyleState to Viewport. This enables the maps to be maintained correctly when viewports are synchronized. This will primarily not affect applications except calls to ViewState.areAllTileTreesLoaded should replaced with Viewport.areAllTileTreesLoaded if the map tile trees should be tested.

Presentation changes

InstanceLabelOverride enhancements

The InstanceLabelOverride rule was enhanced with abilities to compose label using related instance values:

Custom category renderers

VirtualizedPropertyGrid now allows developers to fully customize displayed category contents, if the category is assigned a custom renderer via Presentation Rules. You can read more about that in our Category customization learning page.

Custom category nesting

A new parentId attribute was added to PropertyCategorySpecification to provide nesting abilities. See more details in our property categorization page.

Presentation rule schema requirements

A new requiredSchemas attribute was added to Ruleset, Rule and SubCondition definitions. The attribute allows specifying ECSchema requirements for rules and avoid using them when requirements are not met. See the schema requirements page for more details.

Promoted APIs

The following APIs have been promoted to public. Public APIs are guaranteed to remain stable for the duration of the current major version of a package.

@bentley/webgl-compatibility

Breaking API changes

@bentley/imodeljs-backend package

The arguments for the @beta protected static methods called during modifications have been changed to be more consistent and extensible:

  • Element [onInsert, onInserted, onUpdate, onUpdated, onDelete, onDeleted]
  • Model [onInsert, onInserted, onUpdate, onUpdated, onDelete, onDeleted]
  • ElementAspect [onInsert, onInserted, onUpdate, onUpdated, onDelete, onDeleted]

In addition, new protected static methods were added:

  • Element [onChildInsert, onChildInserted, onChildUpdate, onChildUpdated, onChildDelete, onChildDeleted, onChildAdd, onChildAdded, onChildDrop, onChildDropped]
  • Model [onInsertElement, onInsertedElement, onUpdateElement, onUpdatedElement, onDeleteElement, onDeletedElement]

The following method is now async to make it easier to integrate with asynchronous status and health reporting services:

Properties getter in @beta ECClass has been changed to return an iterator of properties instead of an array of properties. Array indexing and properties like .length will no longer work with the returned iterator, so you may need to create an array from the iterator or use its .next() method. Iterating with for...of loop works the same with iterator as before with an array.
This change is made because internally properties are now stored in a map instead of an array, and it is more efficient to return an iterator for the properties to be generated on demand than to create them on the getter.

Last Updated: 11 June, 2024