1.12.0 Change Notes
MacOS Support
MacOS support is officially available for iModel.js backends. Please see the Supported Platforms page for details.
Plan projection display
Alpha support for controlling the display of "plan projection" models has been added. A plan projection model is a spatial model with geometry all residing in an XY plane, indicated by the GeometricModel3dProps.isPlanProjection flag. Multiple such models can be combined within a spatial view in various ways by using the PlanProjectionSettings
associated with a DisplayStyle3d and DisplayStyle3dState. This allows each model to be displayed with any of the following:
- An absolute elevation in meters;
- A uniform transparency;
- As an overlay, drawn in front of all other geometry in the view;
- Deterministic draw order based on display priority.
The latter groups geometry within plan projection models into "layers" based on subcategory Id: each subcategory represents a single layer containing geometry from any number of plan projection models, and each subcategory's SubCategoryAppearance defines a display priority. At display time, if 2 (or more) plan projection models are displayed at the same elevation, their geometry is drawn in ascending order by the corresponding subcategory's display priority, such that geometry with a higher priority displays in front of geometry with a lower priority. Subcategory priorities can be overridden using DisplayStyleSettings.overrideSubCategory.
Feature flags
Options used to enable or disable certain features when invoking IModelApp.startup have changed:
- RenderSystem.Options.logarithmicDepthBuffer now defaults to
true
. TileAdmin.Props.enableImprovedElision
now defaults totrue
.TileAdmin.Props.ignoreAreaPatterns
has been added to temporarily mitigate issues with large amounts of geometry produced for area patterns. It defaults tofalse
.
View details
Access to optional ViewDefinition and ViewState properties stored as JSON has been consolidated into the ViewDetails class. In addition, a new persistent ViewDetails3d.allow3dManipulations flag allows 3d views to control whether viewing tools can operate on the view in three dimensions or should be limited to the XY plane.
UI
ControlledTree
- New abstract classes:
AbstractTreeNodeLoader
andAbstractTreeNodeLoaderWitProvider
- Uses
TreeModelSource
to add loaded nodes to the model protected abstract load(parentId: TreeModelNode | TreeModelRootNode, childIndex: number): Observable<LoadedNodeHierarchy>
is called to load nodesprotected updateModel(loadedHierarchy: LoadedNodeHierarchy): void
is called when nodes are loaded and is responsible for adding them to the model
- Uses
onNodeLoaded
event removed fromITreeNodeLoader
AbstractTreeNodeLoader.updateModel(loadedHierarchy: LoadedNodeHierarchy): void
should be overridden instead of listening foronNodeLoaded
event
TreeNodeLoader
andPagedTreeNodeLoader
extendsAbstractTreeNodeLoaderWitProvider
and requiresTreeModelSource
to be passed to constructor- overriding
protected updateModel(loadedHierarchy: LoadedNodeHierarchy): void
allows to control how nodes are added to the model.
- overriding
useNodeLoader
andusePagedNodeLoader
hooks requireTreeModelSource
function useNodeLoader<TDataProvider extends TreeDataProvider>(dataProvider: TDataProvider, modelSource: TreeModelSource): TreeNodeLoader<TDataProvider>;
function usePagedNodeLoader<TDataProvider extends TreeDataProvider>(dataProvider: TDataProvider, pageSize: number, modelSource: TreeModelSource): PagedTreeNodeLoader<TDataProvider>;
useModelSource
hook takesTreeDataProvider
instead ofITreeNodeLoader
function useModelSource(dataProvider: TreeDataProvider): TreeModelSource;
- Removed function:
createDefaultNodeLoadHandler(modelSource: TreeModelSource): (loadedHierarchy: LoadedNodeHierarchy) => void;
- Removed function:
createModelSourceForNodeLoader(nodeLoader: ITreeNodeLoader): { modelSource: TreeModelSource; disposeModelSource: () => void; };
Geometry
Ellipsoid
- New instance method:
ellipsoid.localToWorld(localPoint: XYAndZ, result?: Point3d): Point3d
- New instance method:
worldToLocal(worldPoint: XYAndZ, result?: Point3d): Point3d | undefined
local
image of a world point is in the coordinate system of a unit sphere.- The point is (inside,on,outside) the ellipsoid if its local point magnitude (distance from local origin) is respectively (less than, equal to, greater than) one.
- New instance method:
ellipsoid.silhouette (eyePoint:Point4d): Arc3d | undefined
- New instance methods to implement the
Clipper
interface:ellipsoid.isPointOnOrInside(point: Point3d): boolean
ellipsoid.announceClippedArcIntervals(arc: Arc3d, announce?: AnnounceNumberNumberCurvePrimitive): boolean
ellipsoid.announceClippedSegmentIntervals(f0: number, f1: number, pointA: Point3d, pointB: Point3d, announce?: AnnounceNumberNumber): boolean
PolyfaceQuery
- Existing static methods for area booleans of polygons have added (optional) argument to request triangulation of results.
polygonXYAreaUnionLoopsToPolyface
polygonXYAreaDifferenceLoopsToPolyface
polygonXYAreaIntersectLoopsToPolyface
- New (static) method:
cloneByFacetDuplication(source: Polyface, includeSingletons: boolean, clusterSelector: DuplicateFacetClusterSelector): Polyface
- Copy facets from source to a new polyface
includeSingletons
controls inclusion of facets that appear only onceclusterSelector
indicates- omit all duplicated facets
- include single representative among each cluster of duplicates
- omit all if even count, retain one if odd count. (Parity rules)
- include all within clusters of duplicates
- supporting methods to announce and collect arrays of clustered facet indices:
PolyfaceQuery.announceDuplicateFacetIndices(polyface: Polyface, announceCluster: (clusterFacetIndices: number[]) => void): void
PolyfaceQuery.collectDuplicateFacetIndices(polyface: Polyface, includeSingletons?: boolean): number[][]
Arc3d
- Allow undefined center in create methods
Arc3d.create(center: Point3d | undefined, vector0: Vector3d, vector90: Vector3d, sweep?: AngleSweep, result?: Arc3d): Arc3d;
Arc3d.createCenterNormalRadius(center: Point3d | undefined, normal: Vector3d, radius: number, result?: Arc3d): Arc3d;
Arc3d.createScaledXYColumns(center: Point3d | undefined, matrix: Matrix3d, radius0: number, radius90: number, sweep?: AngleSweep, result?: Arc3d): Arc3d;
- in
myArc.extendRange(range, transform)
, compute exact (rather than sampled) range.
Matrix3d
- New instance method:
matrix.multiplyInverseXYZW(x: number, y: number, z: number, w: number, result?: Point4d): Point4d | undefined;
Point4d
- New instance method:
point4d.crossWeightedMinusPoint3d(other: Point3d, result?: Vector3d): Vector3d;
- New instance method:
point4d.realPointOrVector (): Point3d | Vector3d;
Vector3d
- New static method:
Vector3d.dotProductAsXYAndZ(dataA: XYAndZ, dataB: XYAndZ): number
- dot product between x,y,z components of
dataA
anddataB
, even if strong typing (e.g. as Point3d) says they should not be able to act as vectors.
- dot product between x,y,z components of
Transform
- New instance method:
multiplyInversePoint4d(weightedPoint: Point4d, result?: Point4d): Point4d | undefined;
Point3d and Vector3d
- New instance method
data.setAt(index, value)
to address x,y,z by index (inXYZ
base class)
ConvexClipPlaneSet
- allow undefined (zero) tilt in construction
ConvexClipPlaneSet.createSweptPolyline(points: Point3d[], upVector: Vector3d, tiltAngle?: Angle): ConvexClipPlaneSet | undefined
MomentData
- (BUG) in
MomentData.inertiaProductsToPrincipalAxes(rawMomentData.origin, rawMomentData.sums)
, when the computed quantity (e.g. area) is negative, adjust axes directions to have the loop be CCW in thelocalToWorldMap
xy plane. - New optional property
absoluteQuantity
isundefined
in raw moment data- the (positive) quantity sum in principal moment data (produced by call to
inertiaProductsToPrincipalAxes
)
Clipper
support
- new static method
ClipUtilities.isClipper(candidate: any)
to test if candidate supports all the methods of the Clipper interface. - new (static) methods in
BooleanClipFactory
. The static list (including some older methods) is- JSON serialization:
- BooleanClipFactory.anyClipperToJSON(clipper: any): any | undefined;
- BooleanClipFactory.parseToClipper(source?: object): Clipper | undefined;
create
methods for various boolean trees:BooleanClipFactory.createCaptureClipOutside(primaryClipper: Clipper): Clipper;
BooleanClipFactory.createCaptureDifference(primaryClipper: Clipper, excludedClipper: Clipper, keepInside: boolean): Clipper;
BooleanClipFactory.createCaptureIntersection(clippers: Clipper | Clipper[], keepInside: boolean): Clipper;
BooleanClipFactory.createCaptureParity(clippers: Clipper | Clipper[], keepInside: boolean): Clipper;
BooleanClipFactory.createCaptureUnion(clippers: Clipper | Clipper[], keepInside: boolean): Clipper;
- JSON serialization:
IModelSchemaLoader
- New utility class in @itwin/core-backend to retrieve full Schema information from an iModel.
- Requires the @itwin/ecschema-metadata package to be installed. This package contains the EC Schema metadata classes which are the building blocks of the schema returned from the iModel.
- Contains two methods for Schema retrieval.
getSchema
Gets a Schema by name from the iModel and throws an exception if it cannot be found or loaded.tryGetSchema
Attempts to retrieve a Schema by name from the iModel. Returnsundefined
if it cannot be found.
Last Updated: 29 September, 2021