3.6.0 Change Notes
Table of contents:
- API support policies
- Electron 22 support
- Display system
- Geometry
- Write-ahead logging
- Presentation
- API promotions
- API deprecations
API support policies
iTwin.js now documents the official policies defining the level of stability and support afforded to its public APIs and each major release.
Electron 22 support
In addition to already supported Electron versions, iTwin.js now supports Electron 22.
Display system
Point cloud shading
Point clouds can provide valuable real-world context when visualizing an iTwin, but it can often be difficult to discern individual features within the cloud of points - especially when the point cloud lacks color data. You can now accentuate the depth, shape, and surface of a point cloud using a technique called "eye-dome lighting" that uses the relative depths of the points to compute a lighting effect.
Point cloud shading is specified by several properties of RealityModelDisplaySettings.pointCloud, all with names prefixed with edl
(short for "eye-dome lighting"):
- PointCloudDisplaySettings.edlMode enables the effect if set to "on" or "full".
- PointCloudDisplaySettings.edlStrength specifies the intensity of the effect.
- PointCloudDisplaySettings.edlRadius specifies the radius in pixels around each point that should be sampled to detect differences in depth.
- PointCloudDisplaySettings.edlFilter specifies whether to apply a filtering pass to smooth out the effect, when
edlMode
is set to "full".
Each point cloud in a view can have its own independent EDL settings. You can configure those settings via ContextRealityModel.displaySettings for context reality models, and DisplayStyleSettings.setRealityModelDisplaySettings for persistent reality models. Adjusting related settings like PointCloudDisplaySettings.sizeMode and PointCloudDisplaySettings.shape can influence the shading effect.
A monochrome point cloud with (bottom) and without (top) shading:
A colorized point cloud with (bottom) and without (top) shading:
Normal mapping
Normal mapping is a technique that simulates additional surface details by mapping a texture containing normal vectors onto a surface. RenderMaterials now support applying normal maps.
You can create a RenderMaterial with a normal map on the frontend via RenderSystem.createRenderMaterial. The normal map is specified by the MaterialTextureMappingProps.normalMapParams in your CreateRenderMaterialArgs.textureMapping.
To create a RenderMaterialElement with a normal map on the backend, use RenderMaterialElement.insert or RenderMaterialElement.create. Pass the normal map in RenderMaterialElementParams.normalMap.
The image below illustrates the effects of normal mapping. The cubes in the top row have no normal maps, while the cubes in the bottom row are normal mapped.
Smooth viewport resizing
Previously, when a Viewport's canvas was resized there would be a delay of up to one second during which the viewport's contents would appear stretched or squished, before they were redrawn to match the new canvas dimensions. This was due to the unavailability of ResizeObserver in some browsers. Now that ResizeObserver
is supported by all major browsers, we are able to use it to make the contents of the viewport update smoothly during a resize operation.
Pickable view overlays
A bug preventing users from interacting with pickable decorations defined as GraphicType.ViewOverlay has been fixed.
Element clipping example
In some cases it is useful to apply a clipping volume to a view that mimics the shape of one or more elements. For example, you may have a view displaying a reality mesh captured from a real-world asset like a factory, and a design model representing the same asset, and wish to isolate the portions of the reality mesh corresponding to a series of pipe elements in the design model.
display-test-app now provides an example tool demonstrating how this can be achieved. It uses IModelConnection.generateElementMeshes to produce Polyfaces from one or more elements; decomposes them into a set of convex hulls using VHACD.js; and creates a clipping volume from the hulls via ConvexClipPlaneSet.createConvexPolyface. The example tool can be accessed in display-test-app using the keyin dta clip element geometry
.
Support larger terrain meshes
Previously, RealityMeshParams only supported 16-bit vertex indices, which limited the number of vertices that could be produced by a TerrainMeshProvider. That limit has been extended to 32 bits (the maximum supported by WebGL). The code has also been optimized to allocate only as many bytes per vertex index as required. For example, if a mesh contains fewer than 256 vertices, only one byte will be allocated per vertex index.
Geometry
Query mesh convexity
A new method PolyfaceQuery.isConvexByDihedralAngleCount permits testing the convexity of a mesh by inspecting the dihedral angles of all of its edges. For an example of its usage, see the element clipping example.
Write-ahead logging
Previously, iTwin.js used DELETE journal mode for writes to local briefcase files. It now uses write-ahead logging (WAL) mode. This change should be invisible to applications, other than performance of IModelDb.saveChanges should improve in most cases. However, there are a few subtle implications of this change that may affect existing applications:
- Attempting to open more than one simultaneous writeable connections to the same briefcase will now fail on open. Previously, both opens would succeed, followed by a failure on the first attempted write by one or the other connection.
- Failure to close a writeable briefcase may leave a "-wal" file. Previously, if a program crashed or exited with an open briefcase, it would leave the briefcase file as-of its last call to
IModelDb.saveChanges
. Now, there will be another file with the name of the briefcase with "-wal" appended. This is not a problem and the briefcase is completely intact, except that the briefcase file itself is not sufficient for copying (it will not include recent changes.) The "-wal" file will be used by future connections and will be deleted the next time the briefcase is successfully closed. - Attempting to copy an open-for-write briefcase file may not include recent changes. This scenario generally only arises for tests. If you wish to copy an open-for-write briefcase file, you must now call IModelDb.performCheckpoint first.
Presentation
Hierarchy levels filtering
Ability to filter individual hierarchy levels was added for tree components that use PresentationTreeDataProvider. To enable this, PresentationTreeRenderer should be passed to ControlledTree through ControlledTreeProps.treeRenderer:
return <ControlledTree
// other props
treeRenderer={(treeProps) => <PresentationTreeRenderer {...treeProps} imodel={imodel} modelSource={modelSource} />}
/>;
PresentationTreeRenderer renders nodes with action buttons for applying and clearing filters. Some hierarchy levels might not be filterable depending on the presentation rules used to build them. In that case, action buttons for those hierarchy levels are not rendered. If applied filter does not produce any nodes, There are no child nodes matching current filter
message is rendered in that hierarchy level.
Dialog component for creating hierarchy level filter is opened when node's Filter
button is clicked. This dialog allows to create complex filters with multiple conditions based on properties from instances that are represented by the nodes in that hierarchy level.
Grouping nodes HiliteSet
HiliteSetProvider.getHiliteSet now supports getting HiliteSet for grouping nodes. Previously, HiliteSetProvider.getHiliteSet used to return empty HiliteSet if called with key of the grouping node. Now it returns HiliteSet for all the instances that are grouped under grouping node. This also means that now elements will be hilited in viewport using Unified Selection when grouping node is selected in the tree.
API promotions
The following APIs have been promoted to @public
, indicating they are now part of their respective packages' stability contract.
@itwin/core-bentley
@itwin/core-common
@itwin/core-frontend
@itwin/presentation-common
- Presentation rules:
- Content traversal - related APIs:
- Selection scope computation - related APIs:
- Element properties request - related APIs:
- Content sources request - related APIs:
- Content instance keys request - related APIs:
- NestedContentField.relationshipMeaning
- ContentFlags.IncludeInputKeys and Item.inputKeys
@itwin/presentation-backend
- Presentation manager's caching related APIs:
- PresentationManager.getElementProperties and MultiElementPropertiesResponse
- PresentationManager.getContentSources
- PresentationManager.computeSelection
- RulesetEmbedder and related APIs
@itwin/presentation-frontend
- PresentationManager.getContentSources
- PresentationManager.getElementProperties
- PresentationManager.getContentInstanceKeys
@itwin/presentation-components
- FavoritePropertiesDataFilterer
- PresentationPropertyDataProvider.getPropertyRecordInstanceKeys
- PresentationTreeDataProviderProps.customizeTreeNodeItem
- PresentationTreeNodeLoaderProps.seedTreeModel
API deprecations
@itwin/core-bentley
ByteStream's next
property getters like ByteStream.nextUint32 and ByteStream.nextFloat64 have been deprecated and replaced with corresponding read
methods like ByteStream.readUint32 and ByteStream.readFloat64. The property getters have the side effect of incrementing the stream's current read position, which can result in surprising behavior and may trip up code optimizers that assume property access is free of side effects.
Similarly, TransientIdSequence.next returns a new Id each time it is called. Code optimizers like Angular's may elide repeated calls to next
assuming it will return the same value each time. Prefer to use the new TransientIdSequence.getNext method instead.
@itwin/core-frontend
ScreenViewport.setEventController was only ever intended to be used by ViewManager. In the unlikely event that you are using it for some (probably misguided) purpose, it will continue to behave as before, but it will be removed in a future major version.
NativeApp.requestDownloadBriefcase parameter progress
is deprecated in favor of progressCallback
in DownloadBriefcaseOptions. Similarly, progressCallback
in PullChangesOptions is now deprecated and should be replaced with downloadProgressCallback
in PullChangesOptions. Both new variables are of type OnDownloadProgress, which more accurately represents information reported during downloads.
IModelConnection.displayedExtents and IModelConnection.expandDisplayedExtents are deprecated. The displayed extents are expanded every time a ContextRealityModel is added to any view in the iModel, and never shrink. They were previously used to compute the viewed extents of every SpatialViewState, which could produce an unnecessarily large frustum resulting in graphical artifacts. Now each spatial view computes its extents based on the extents of the models it is currently displaying. displayedExtents
is still computed as before to support existing users of the API, but its use is not recommended.
@itwin/core-backend
RenderMaterialElement.Params is defined as a class, which makes it unwieldy to use. You can now use the interface RenderMaterialElementParams instead.
@itwin/appui-abstract
UiItemsProvider and other AppUI specific types and APIs are deprecated and moved to @itwin/appui-react
package.
For a replacement in case of API rename consult @deprecated tag in the documentation.
@itwin/appui-react
ModelsTree and CategoryTree were moved to @itwin/tree-widget-react package and deprecated in @itwin/appui-react
packages. They will be removed from @itwin/appui-react
in future major version.
SpatialContainmentTree were deprecated in favor of SpatialContainmentTree
from @itwin/breakdown-trees-react package. SpatialContainmentTree will be removed in future major version.
@itwin/presentation-common
A bunch of {api_name}JSON
interfaces, completely matching their sibling {api_name}
definition, thus having no real benefit, have been forcing us to map back and forth between {api_name}
and {api_name}JSON
with {api_name}.toJSON
and {api_name}.fromJSON
helper functions. Majority of them are marked public as they're part of public RPC interface, but are generally not expected to be directly used by consumer code. They have been deprecated with the recommendation to use {api_name}
.
Last Updated: 20 June, 2023