Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
928 lines (843 sloc) 38.1 KB
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2019 Bentley Systems, Incorporated. All rights reserved.
* Licensed under the MIT License. See LICENSE.md in the project root for license terms.
*--------------------------------------------------------------------------------------------*/
/** @module Views */
import { Id64, Id64String, Id64Array, JsonUtils } from "@bentley/bentleyjs-core";
import { EntityQueryParams } from "./EntityProps";
import { AngleProps, Vector3d, XYZProps, XYProps, YawPitchRollProps } from "@bentley/geometry-core";
import { ElementProps, DefinitionElementProps, SheetProps } from "./ElementProps";
import { ColorDef, ColorDefProps } from "./ColorDef";
import { AnalysisStyleProps, HiddenLine, AmbientOcclusion, SolarShadows, ViewFlags } from "./Render";
import { SubCategoryAppearance, SubCategoryOverride } from "./SubCategoryAppearance";
import { RenderSchedule } from "./RenderSchedule";
import { SpatialClassificationProps } from "./SpatialClassificationProps";
/** Returned from [IModelDb.Views.getViewStateData]($backend)
* @public
*/
export interface ViewStateProps {
viewDefinitionProps: ViewDefinitionProps;
categorySelectorProps: CategorySelectorProps;
modelSelectorProps?: ModelSelectorProps;
displayStyleProps: DisplayStyleProps;
/** @beta */
sheetProps?: SheetProps;
/** @beta */
sheetAttachments?: Id64Array;
}
/** Properties that define a ModelSelector
* @public
*/
export interface ModelSelectorProps extends DefinitionElementProps {
models: Id64Array;
}
/** Properties that define a CategorySelector
* @public
*/
export interface CategorySelectorProps extends DefinitionElementProps {
categories: Id64Array;
}
/** Parameters for performing a query on [ViewDefinition]($backend) classes.
* @public
*/
export interface ViewQueryParams extends EntityQueryParams {
wantPrivate?: boolean;
}
/** Parameters used to construct a ViewDefinition
* @public
*/
export interface ViewDefinitionProps extends DefinitionElementProps {
categorySelectorId: Id64String;
displayStyleId: Id64String;
description?: string;
}
/** JSON representation of [[ViewFlags]]
* @public
*/
export interface ViewFlagProps {
/** If true, don't show construction class. */
noConstruct?: boolean;
/** If true, don't show dimension class. */
noDim?: boolean;
/** If true, don't show patterns. */
noPattern?: boolean;
/** If true, don't line weights. */
noWeight?: boolean;
/** If true, don't line styles. */
noStyle?: boolean;
/** If true, don't use transparency. */
noTransp?: boolean;
/** If true, don't show filled regions. */
noFill?: boolean;
/** If true, show grids. */
grid?: boolean;
/** If true, show AuxCoordSystem. */
acs?: boolean;
/** If true, don't show textures. */
noTexture?: boolean;
/** If true, don't show materials. */
noMaterial?: boolean;
/** If true, don't use camera lights.
* @note Currently the renderer only supports solar lighting. For backwards-compatibility reasons, solar lights will be displayed if any combination of [[noCameraLights]], [[noSourceLights]], or [[noSolarLight]] is set to `false`.
*/
noCameraLights?: boolean;
/** If true, don't use source lights.
* @note Currently the renderer only supports solar lighting. For backwards-compatibility reasons, solar lights will be displayed if any combination of [[noCameraLights]], [[noSourceLights]], or [[noSolarLight]] is set to `false`.
*/
noSourceLights?: boolean;
/** If true, don't use solar lights.
* @note Currently the renderer only supports solar lighting. For backwards-compatibility reasons, solar lights will be displayed if any combination of [[noCameraLights]], [[noSourceLights]], or [[noSolarLight]] is set to `false`.
*/
noSolarLight?: boolean;
/** If true, show visible edges. */
visEdges?: boolean;
/** If true, show hidden edges. */
hidEdges?: boolean;
/** If true, show shadows. */
shadows?: boolean;
/** If true, use clipping volume. */
clipVol?: boolean;
/** If true, use hidden line material colors. */
hlMatColors?: boolean;
/** If true, show view with monochrome settings. */
monochrome?: boolean;
/** @internal unused */
edgeMask?: number;
/** [[RenderMode]] */
renderMode?: number;
/** Display background map. */
backgroundMap?: boolean;
/** If true, show ambient occlusion. */
ambientOcclusion?: boolean;
/** Controls whether surface discard is always applied regardless of other ViewFlags.
* Surface shaders contain complicated logic to ensure that the edges of a surface always draw in front of the surface, and that planar surfaces sketched coincident with
* non-planar surfaces always draw in front of those non-planar surfaces.
* When this view flag is set to false (the default), then for 3d views if the render mode is wireframe (only edges are displayed) or smooth shader with visible edges turned off (only surfaces are displayed),
* that logic does not execute, potentially improving performance for no degradation in visual quality. In some scenarios - such as wireframe views containing many planar regions with interior fill, or smooth views containing many coincident planar and non-planar surfaces - enabling this view flag improves display quality by forcing that logic to execute.
*/
forceSurfaceDiscard?: boolean;
}
/** Describes the [[SubCategoryOverride]]s applied to a [[SubCategory]] by a [[DisplayStyle]].
* @see [[DisplayStyleSettingsProps]]
* @public
*/
export interface DisplayStyleSubCategoryProps extends SubCategoryAppearance.Props {
/** The Id of the [[SubCategory]] whose appearance is to be overridden. */
subCategory?: Id64String;
}
/** The current set of supported terrain providers. Currently only CesiumWorldTerrain.
* @alpha
* @see [[TerrainProps]]
*/
export type TerrainProviderName = "CesiumWorldTerrain";
/** JSON representation of the settings of the terrain applied to background map display by a [[DisplayStyle]].
* @see [[DisplayStyleSettingsProps]]
* @see [[BackgroundMapProps]]
* @alpha
*/
export interface TerrainProps {
/** Identifies the provider currently only CesiumWorldTerrain is supported. */
providerName?: string;
/** A value greater than one will cause terrain height to be exaggerated/scaled.false (or 1.0) indicate no exaggeration. Default value: 1.0 */
exaggeration?: number;
/** Applying lighting can help to visualize subtle terrain variation. Default value: true */
applyLighting?: boolean;
/** Origin value - height of the IModel origin at the project center as defined by heightOriginMode. Default value: 0.0 */
heightOrigin?: number;
/** Determines how/if the heightOrigin is applied to the terrain height. Default value: Ground */
heightOriginMode?: TerrainHeightOriginMode;
}
/** Correction modes for terrain height
* @alpha
* @see [[TerrainProps]]
*/
export enum TerrainHeightOriginMode {
Geodetic = 0, // Height value indicates the geodetic height of the IModel origin (also referred to as ellipsoidal or GPS height)
Geoid = 1, // Height value indicates the geoidal height of the IModel origin (commonly referred to as sea level).
Ground = 2, // Height value indicates the height of the IModel origin relative to ground level at project center.
}
/** Normalized version of [[TerrainProps]] for which provider has been validated and default values of all members are used.
* @alpha
*/
export class TerrainSettings {
/** Identifies the provider currently only CesiumWorldTerrain supported. */
public readonly providerName: TerrainProviderName;
/** A value greater than one will cause terrain height to be exaggerated/scaled.false (or 1.0) indicate no exaggeration. Default value: 1.0 */
public readonly exaggeration: number;
/** Applying lighting can help to visualize subtle terrain variations. Default value: true */
public readonly applyLighting: boolean;
/** Origin value - height of the IModel origin at the project center as defined by heightOriginMode. Default value 0.0 */
public readonly heightOrigin: number;
/** Determines how/if the heightOrigin is applied to the terrain height. Default value: ground */
public readonly heightOriginMode: TerrainHeightOriginMode;
constructor(providerName: TerrainProviderName = "CesiumWorldTerrain", exaggeration: number = 1.0, applyLighting = true, heightOrigin = 0.0, heightOriginMode = TerrainHeightOriginMode.Ground) {
this.providerName = providerName;
this.exaggeration = Math.min(100, Math.max(0.1, exaggeration));
this.applyLighting = applyLighting;
this.heightOrigin = heightOrigin;
this.heightOriginMode = heightOriginMode;
}
public static fromJSON(json?: TerrainProps) {
if (undefined === json)
return new TerrainSettings();
const providerName = "CesiumWorldTerrain"; // This is only terrain provider currently supported.
return new TerrainSettings(providerName, json.exaggeration, json.applyLighting, json.heightOrigin, json.heightOriginMode);
}
public toJSON(): TerrainProps {
return {
providerName: this.providerName,
exaggeration: this.exaggeration,
applyLighting: this.applyLighting,
heightOrigin: this.heightOrigin,
heightOriginMode: this.heightOriginMode,
};
}
public equals(other: TerrainSettings): boolean {
return this.providerName === other.providerName && this.exaggeration === other.exaggeration && this.applyLighting === other.applyLighting && this.heightOrigin === other.heightOrigin && this.heightOriginMode === other.heightOriginMode;
}
/** Returns true if these settings are equivalent to the supplied JSON settings. */
public equalsJSON(json?: BackgroundMapProps): boolean {
return this.equals(TerrainSettings.fromJSON(json));
}
/** Create a copy of this TerrainSettings, optionally modifying some of its properties.
* @param changedProps JSON representation of the properties to change.
* @returns A TerrainSettings with all of its properties set to match those of`this`, except those explicitly defined in `changedProps`.
*/
public clone(changedProps?: TerrainProps): TerrainSettings {
if (undefined === changedProps)
return this;
const props = {
providerName: undefined !== changedProps.providerName ? changedProps.providerName : this.providerName,
exaggeration: undefined !== changedProps.exaggeration ? changedProps.exaggeration : this.exaggeration,
applyLighting: undefined !== changedProps.applyLighting ? changedProps.applyLighting : this.applyLighting,
heightOrigin: undefined !== changedProps.heightOrigin ? changedProps.heightOrigin : this.heightOrigin,
heightOriginMode: undefined !== changedProps.heightOriginMode ? changedProps.heightOriginMode : this.heightOriginMode,
};
return TerrainSettings.fromJSON(props);
}
}
/** Describes the type of background map displayed by a [[DisplayStyle]]
* @see [[BackgroundMapProps]]
* @see [[DisplayStyleSettingsProps]]
* @public
*/
export enum BackgroundMapType {
Street = 1,
Aerial = 2,
Hybrid = 3,
}
/** JSON representation of the settings associated with a background map displayed by a [[DisplayStyle]].
* @see [[DisplayStyleSettingsProps]]
* @public
*/
export interface BackgroundMapProps {
/** The elevation of the map in meters relative to sea level. Default value: 0. */
groundBias?: number;
/** Identifies the source of the map tiles. Currently supported providers are "BingProvider" and "MapBoxProvider". Support for additional providers may be added in the future.
*
* Default value: "BingProvider"
*/
providerName?: string;
/** Options for customizing the tiles supplied by the provider. If undefined, default values of all members are used. */
providerData?: {
/** The type of map graphics to request. Default value: BackgroundMapType.Hybrid. */
mapType?: BackgroundMapType;
};
/** A transparency value from 0.0 (fully opaque) to 1.0 (fully transparent) to apply to map graphics when drawing, or false to indicate the transparency should not be overridden. Default value: false. */
transparency?: number | false;
/** If set to true, the map tiles will be rendered with depth, allowing them to obscure other geometry. Otherwise, they are always rendered behind all other geometry. Default value: false. */
useDepthBuffer?: boolean;
/** If true, terrain heights will be applied to the map; otherwise the map will be rendered as a plane. */
applyTerrain?: boolean;
/** Properties associated with terrain display
* @alpha
*/
terrainSettings?: TerrainProps;
}
/** The current set of supported background map providers.
* @beta
*/
export type BackgroundMapProviderName = "BingProvider" | "MapBoxProvider";
/** Normalized representation of a [[BackgroundMapProps]] for which type and provider have been validated and default values have been applied where explicit values not defined.
* @beta
*/
export class BackgroundMapSettings {
/** Elevation in meters, relative to sea level. */
public readonly groundBias: number;
/** Identifies the provider from which map image will be obtained. */
public readonly providerName: BackgroundMapProviderName;
/** The type of map graphics to be drawn. */
public readonly mapType: BackgroundMapType;
/** A transparency value from 0.0 (fully opaque) to 1.0 (fully transparent) to apply to map graphics when drawing, or false to indicate the transparency should not be overridden. Default value: false. */
public readonly transparency: number | false;
/** If set to true, the map tiles will be rendered with depth, allowing them to obscure other geometry. Otherwise, they are always rendered behind all other geometry. Default value: false. */
public readonly useDepthBuffer: boolean;
/** If true, terrain heights will be applied to the map; otherwise the map will be rendered as a plane. */
public readonly applyTerrain: boolean;
/** Settings associated with terrain display
* @alpha
*/
public readonly terrainSettings: TerrainSettings;
/** */
/** If transparency is overridden, the transparency to apply; otherwise, undefined. */
public get transparencyOverride(): number | undefined { return false !== this.transparency ? this.transparency : undefined; }
private constructor(providerName: BackgroundMapProviderName = "BingProvider", mapType: BackgroundMapType = BackgroundMapType.Hybrid, groundBias = 0, useDepthBuffer = false, transparency: number | false = false, applyTerrain = false, terrainSettings?: TerrainProps) {
this.groundBias = groundBias;
this.providerName = providerName;
this.useDepthBuffer = useDepthBuffer;
this.transparency = false !== transparency ? Math.min(1, Math.max(0, transparency)) : false;
this.applyTerrain = applyTerrain;
switch (mapType) {
case BackgroundMapType.Street:
case BackgroundMapType.Aerial:
this.mapType = mapType;
break;
default:
this.mapType = BackgroundMapType.Hybrid;
}
this.terrainSettings = TerrainSettings.fromJSON(terrainSettings);
}
/** Construct from JSON, performing validation and applying default values for undefined fields. */
public static fromJSON(json?: BackgroundMapProps): BackgroundMapSettings {
if (undefined === json)
return new BackgroundMapSettings();
const providerName = ("MapBoxProvider" === json.providerName) ? "MapBoxProvider" : "BingProvider";
const mapType = (undefined !== json.providerData) ? json.providerData.mapType : BackgroundMapType.Hybrid;
return new BackgroundMapSettings(providerName, mapType, json.groundBias, json.useDepthBuffer, json.transparency, json.applyTerrain, json.terrainSettings);
}
public toJSON(): BackgroundMapProps {
return {
groundBias: this.groundBias,
providerName: this.providerName,
applyTerrain: this.applyTerrain,
providerData: { mapType: this.mapType },
transparency: this.transparency,
terrainSettings: this.terrainSettings.toJSON(),
};
}
/** Returns true if these settings are equivalent to the supplied JSON settings. */
public equalsJSON(json?: BackgroundMapProps): boolean {
return this.equals(BackgroundMapSettings.fromJSON(json));
}
public equals(other: BackgroundMapSettings): boolean {
return this.groundBias === other.groundBias && this.providerName === other.providerName && this.mapType === other.mapType
&& this.useDepthBuffer === other.useDepthBuffer && this.transparency === other.transparency && this.applyTerrain === other.applyTerrain && this.terrainSettings.equals(other.terrainSettings);
}
/** Create a copy of this BackgroundMapSettings, optionally modifying some of its properties.
* @param changedProps JSON representation of the properties to change.
* @returns A BackgroundMapSettings with all of its properties set to match those of `this`, except those explicitly defined in `changedProps`.
*/
public clone(changedProps?: BackgroundMapProps): BackgroundMapSettings {
if (undefined === changedProps)
return this;
const props = {
providerName: undefined !== changedProps.providerName ? changedProps.providerName : this.providerName,
groundBias: undefined !== changedProps.groundBias ? changedProps.groundBias : this.groundBias,
transparency: undefined !== changedProps.transparency ? changedProps.transparency : this.transparency,
useDepthBuffer: undefined !== changedProps.useDepthBuffer ? changedProps.useDepthBuffer : this.useDepthBuffer,
applyTerrain: undefined !== changedProps.applyTerrain ? changedProps.applyTerrain : this.applyTerrain,
terrainSettings: undefined !== changedProps.terrainSettings ? this.terrainSettings.clone(changedProps.terrainSettings) : this.terrainSettings,
providerData: {
mapType: undefined !== changedProps.providerData && undefined !== changedProps.providerData.mapType ? changedProps.providerData.mapType : this.mapType,
},
};
return BackgroundMapSettings.fromJSON(props);
}
}
/** JSON representation of a [[GroundPlane]].
* @public
*/
export interface GroundPlaneProps {
/** Whether the ground plane should be displayed. Defaults to false. */
display?: boolean;
/** The Z height at which to draw the ground plane. */
elevation?: number;
/** The color in which to draw the ground plane when viewed from above. */
aboveColor?: ColorDefProps;
/** The color in which to draw the ground plane when viewed from below. */
belowColor?: ColorDefProps;
}
/** Enumerates the supported types of [SkyBox]($frontend) images.
* @public
*/
export enum SkyBoxImageType {
None,
/** A single image mapped to the surface of a sphere. @see [[SkySphere]] */
Spherical,
/** 6 images mapped to the faces of a cube. @see [[SkyCube]] */
Cube,
/** @internal not yet supported */
Cylindrical,
}
/** JSON representation of a set of images used by a [[SkyCube]]. Each property specifies the element ID of a texture associated with one face of the cube.
* @public
*/
export interface SkyCubeProps {
/** Id of a persistent texture element stored in the iModel to use for the front side of the skybox cube. */
front?: Id64String;
/** Id of a persistent texture element stored in the iModel to use for the back side of the skybox cube. */
back?: Id64String;
/** Id of a persistent texture element stored in the iModel to use for the top of the skybox cube. */
top?: Id64String;
/** Id of a persistent texture element stored in the iModel to use for the bottom of the skybox cube. */
bottom?: Id64String;
/** Id of a persistent texture element stored in the iModel to use for the right side of the skybox cube. */
right?: Id64String;
/** Id of a persistent texture element stored in the iModel to use for the left side of the skybox cube. */
left?: Id64String;
}
/** JSON representation of an image or images used by a [[SkySphere]] or [[SkyCube]].
* @public
*/
export interface SkyBoxImageProps {
/** The type of skybox image. */
type?: SkyBoxImageType;
/** For [[SkyBoxImageType.Spherical]], the Id of a persistent texture element stored in the iModel to be drawn as the "sky". */
texture?: Id64String;
/** For [[SkyBoxImageType.Cube]], the Ids of persistent texture elements stored in the iModel drawn on each face of the cube. */
textures?: SkyCubeProps;
}
/** JSON representation of a [SkyBox]($frontend).
* @public
*/
export interface SkyBoxProps {
/** Whether or not the skybox should be displayed. Defaults to false. */
display?: boolean;
/** For a [[SkyGradient]], if true, a 2-color gradient skybox is used instead of a 4-color. Defaults to false. */
twoColor?: boolean;
/** For a 4-color [[SkyGradient]], the color of the sky at the horizon. */
skyColor?: ColorDefProps;
/** For a 4-color [[SkyGradient]], the color of the ground at the horizon. */
groundColor?: ColorDefProps;
/** For a 4-color [[SkyGradient]], the color of the sky when looking straight up. For a 2-color [[SkyGradient]], the color of the sky. */
zenithColor?: ColorDefProps;
/** For a 4-color [[SkyGradient]], the color of the ground when looking straight down. For a 2-color [[SkyGradient]], the color of the ground. */
nadirColor?: ColorDefProps;
/** For a 4-color [[SkyGradient]], controls speed of change from sky color to zenith color. */
skyExponent?: number;
/** For a 4-color [[SkyGradient]], controls speed of change from ground color to nadir color. */
groundExponent?: number;
/** For a [[SkySphere]] or [[SkyCube]], the skybox image(s). */
image?: SkyBoxImageProps;
}
/** JSON representation of a solar shadow settings.
* @beta
*/
export interface SolarShadowProps {
/** Shadow color */
color?: ColorDefProps;
/** Shadow bias - a nonzero bias is required to avoid self-shadowing effects. */
bias?: number;
}
/** JSON representation of the environment setup of a [[DisplayStyle3d]].
* @public
*/
export interface EnvironmentProps {
ground?: GroundPlaneProps;
sky?: SkyBoxProps;
}
/** JSON representation of a context reality model
* @public
*/
export interface ContextRealityModelProps {
tilesetUrl: string;
name?: string;
description?: string;
/** @beta */
classifiers?: SpatialClassificationProps.Properties[];
}
/** JSON representation of the settings associated with a [[DisplayStyleProps]].
* These settings are not stored directly as members of the [[DisplayStyleProps]]. Instead, they are stored
* as members of `jsonProperties.styles`.
* @see [[DisplayStyleSettings]].
* @public
*/
export interface DisplayStyleSettingsProps {
viewflags?: ViewFlagProps;
/** The color displayed in the view background. Defaults to black. */
backgroundColor?: ColorDefProps;
/** The color used in monochrome mode. Defaults to white. */
monochromeColor?: ColorDefProps;
/** Settings controlling display of analytical models.
* @alpha
*/
analysisStyle?: AnalysisStyleProps;
/** Schedule script
* @beta
*/
scheduleScript?: RenderSchedule.ModelTimelineProps[];
/** Overrides applied to the appearances of subcategories in the view. */
subCategoryOvr?: DisplayStyleSubCategoryProps[];
/** Settings controlling display of map imagery within views of geolocated models. */
backgroundMap?: BackgroundMapProps;
/** Contextual Reality Models */
contextRealityModels?: ContextRealityModelProps[];
/** List of IDs of excluded elements */
excludedElements?: Id64String[];
}
/** This is incomplete. Many of the lighting properties from MicroStation are not useful or not used in iModel.js.
* @alpha
*/
export interface SceneLightsProps {
sunDir?: XYZProps;
}
/** JSON representation of settings associated with a [[DisplayStyle3dProps]].
* @see [[DisplayStyle3dSettings]].
* @public
*/
export interface DisplayStyle3dSettingsProps extends DisplayStyleSettingsProps {
/** Settings controlling display of skybox and ground plane. */
environment?: EnvironmentProps;
/** Settings controlling display of visible and hidden edges.
* @beta
*/
hline?: HiddenLine.SettingsProps;
/** Settings controlling display of ambient occlusion, stored in Props.
* @beta
*/
ao?: AmbientOcclusion.Props;
/** Settings controlling display of solar shadows, stored in Props.
* @beta
*/
solarShadows?: SolarShadows.Props;
/** Scene lights. Incomplete.
* @alpha
*/
sceneLights?: SceneLightsProps;
}
/** JSON representation of a [[DisplayStyle]] or [[DisplayStyleState]].
* @public
*/
export interface DisplayStyleProps extends DefinitionElementProps {
/** Display styles store their settings in a `styles` property within [[ElementProps.jsonProperties]]. */
jsonProperties?: {
styles?: DisplayStyleSettingsProps;
};
}
/** JSON representation of a [[DisplayStyle3d]] or [[DisplayStyle3dState]].
* @public
*/
export interface DisplayStyle3dProps extends DisplayStyleProps {
/** Display styles store their settings in a `styles` property within [[ElementProps.jsonProperties]]. */
jsonProperties?: {
styles?: DisplayStyle3dSettingsProps;
};
}
/** properties of a camera
* @public
*/
export interface CameraProps {
lens: AngleProps;
focusDist: number; // NOTE: this is abbreviated, do not change!
eye: XYZProps;
}
/** Parameters to construct a ViewDefinition3d
* @public
*/
export interface ViewDefinition3dProps extends ViewDefinitionProps {
/** if true, camera is valid. */
cameraOn: boolean;
/** The lower left back corner of the view frustum. */
origin: XYZProps;
/** The extent of the view frustum. */
extents: XYZProps;
/** Rotation of the view frustum (could be undefined if going Matrix3d -> YawPitchRoll). */
angles?: YawPitchRollProps;
/** The camera used for this view. */
camera: CameraProps;
}
/** Parameters to construct a SpatialViewDefinition
* @public
*/
export interface SpatialViewDefinitionProps extends ViewDefinition3dProps {
modelSelectorId: Id64String;
}
/** Parameters used to construct a ViewDefinition2d
* @public
*/
export interface ViewDefinition2dProps extends ViewDefinitionProps {
baseModelId: Id64String;
origin: XYProps;
delta: XYProps;
angle: AngleProps;
}
/** @public */
export interface AuxCoordSystemProps extends ElementProps {
type?: number;
description?: string;
}
/** Properties of AuxCoordSystem2d
* @public
*/
export interface AuxCoordSystem2dProps extends AuxCoordSystemProps {
/** Origin of the AuxCoordSystem2d */
origin?: XYProps;
/** Rotation angle */
angle?: AngleProps;
}
/** Properties of AuxCoordSystem3d
* @public
*/
export interface AuxCoordSystem3dProps extends AuxCoordSystemProps {
/** Origin of the AuxCoordSystem3d */
origin?: XYZProps;
/** Yaw angle */
yaw?: AngleProps;
/** Pitch angle */
pitch?: AngleProps;
/** Roll angle */
roll?: AngleProps;
}
/** Provides access to the settings defined by a [[DisplayStyle]] or [[DisplayStyleState]], and ensures that
* the style's JSON properties are kept in sync.
* @beta
*/
export class DisplayStyleSettings {
protected readonly _json: DisplayStyleSettingsProps;
private readonly _viewFlags: ViewFlags;
private readonly _background: ColorDef;
private readonly _monochrome: ColorDef;
private readonly _subCategoryOverrides: Map<Id64String, SubCategoryOverride> = new Map<Id64String, SubCategoryOverride>();
private readonly _excludedElements: Set<Id64String> = new Set<Id64String>();
private _backgroundMap: BackgroundMapSettings;
/** Construct a new DisplayStyleSettings from an [[ElementProps.jsonProperties]].
* @param jsonProperties An object with an optional `styles` property containing a display style's settings.
* @note When the `DisplayStyleSetting`'s properties are modified by public setters, the `jsonProperties`'s `styles` object will be updated to reflect the change.
* @note If `jsonProperties` contains no `styles` member, one will be added as an empty object.
* @note Generally there is no reason to create an object of this type directly; a [[DisplayStyle]] or [[DisplayStyleState]] constructs one as part of its own construction.
*/
public constructor(jsonProperties: { styles?: DisplayStyleSettingsProps }) {
if (undefined === jsonProperties.styles)
jsonProperties.styles = {};
this._json = jsonProperties.styles;
this._viewFlags = ViewFlags.fromJSON(this._json.viewflags);
this._background = ColorDef.fromJSON(this._json.backgroundColor);
this._monochrome = undefined !== this._json.monochromeColor ? ColorDef.fromJSON(this._json.monochromeColor) : ColorDef.white.clone();
this._backgroundMap = BackgroundMapSettings.fromJSON(this._json.backgroundMap);
const ovrsArray = JsonUtils.asArray(this._json.subCategoryOvr);
if (undefined !== ovrsArray) {
for (const ovrJson of ovrsArray) {
const subCatId = Id64.fromJSON(ovrJson.subCategory);
if (Id64.isValid(subCatId)) {
const subCatOvr = SubCategoryOverride.fromJSON(ovrJson);
if (subCatOvr.anyOverridden)
this.changeSubCategoryOverride(subCatId, false, subCatOvr);
}
}
}
const exElemArray = JsonUtils.asArray(this._json.excludedElements);
if (undefined !== exElemArray) {
for (const exElemStr of exElemArray) {
const exElem = Id64.fromJSON(exElemStr);
if (Id64.isValid(exElem)) {
this._excludedElements.add(exElem);
}
}
}
}
/** The ViewFlags associated with the display style.
* @note If the style is associated with a [[ViewState]] attached to a [[Viewport]], use [[ViewState.viewFlags]] to modify the ViewFlags to ensure
* the changes are promptly visible on the screen.
* @note Do not modify the ViewFlags in place. Clone them and pass the clone to the setter.
*/
public get viewFlags(): ViewFlags { return this._viewFlags; }
public set viewFlags(flags: ViewFlags) {
flags.clone(this._viewFlags);
this._json.viewflags = flags.toJSON();
}
/** The background color.
* @note Do not modify the color in place. Clone it and pass the clone to the setter.
*/
public get backgroundColor(): ColorDef { return this._background; }
public set backgroundColor(color: ColorDef) {
this._background.setFrom(color);
this._json.backgroundColor = color.toJSON();
}
/** The color used to draw geometry in monochrome mode.
* @note Do not modify the color in place. Clone it and pass the clone to the setter.
* @see [[ViewFlags.monochrome]] for enabling monochrome mode.
*/
public get monochromeColor(): ColorDef { return this._monochrome; }
public set monochromeColor(color: ColorDef) {
this._monochrome.setFrom(color);
this._json.monochromeColor = color.toJSON();
}
/** @alpha */
public get backgroundMap(): BackgroundMapSettings { return this._backgroundMap; }
/** @alpha */
public set backgroundMap(map: BackgroundMapSettings) {
if (!this.backgroundMap.equals(map)) {
this._backgroundMap = map; // it's an immutable type.
this._json.backgroundMap = map.toJSON();
}
}
/** Customize the way geometry belonging to a [[SubCategory]] is drawn by this display style.
* @param id The ID of the SubCategory whose appearance is to be overridden.
* @param ovr The overrides to apply to the [[SubCategoryAppearance]].
* @note If this style is associated with a [[ViewState]] attached to a [[Viewport]], use [[ViewState.overrideSubCategory]] to ensure
* the changes are promptly visible on the screen.
* @see [[dropSubCategoryOverride]]
*/
public overrideSubCategory(id: Id64String, ovr: SubCategoryOverride): void { this.changeSubCategoryOverride(id, true, ovr); }
/** Remove any [[SubCategoryOverride]] applied to a [[SubCategoryAppearance]] by this style.
* @param id The ID of the [[SubCategory]].
* @note If this style is associated with a [[ViewState]] attached to a [[Viewport]], use [[ViewState.dropSubCategoryOverride]] to ensure
* the changes are promptly visible on the screen.
* @see [[overrideSubCategory]]
*/
public dropSubCategoryOverride(id: Id64String): void { this.changeSubCategoryOverride(id, true); }
/** The overrides applied by this style. */
public get subCategoryOverrides(): Map<Id64String, SubCategoryOverride> { return this._subCategoryOverrides; }
/** Obtain the override applied to a [[SubCategoryAppearance]] by this style.
* @param id The ID of the [[SubCategory]].
* @returns The corresponding SubCategoryOverride, or undefined if the SubCategory's appearance is not overridden.
* @see [[overrideSubCategory]]
*/
public getSubCategoryOverride(id: Id64String): SubCategoryOverride | undefined { return this._subCategoryOverrides.get(id); }
/** Returns true if an [[SubCategoryOverride]s are defined by this style. */
public get hasSubCategoryOverride(): boolean { return this._subCategoryOverrides.size > 0; }
/** The set of elements that the display style will exclude.
* @returns The set of excluded elements.
*/
public get excludedElements(): Set<Id64String> { return this._excludedElements; }
/** Add an element to the set of excluded elements defined by the display style.
* @param id The ID of the element to be excluded.
*/
public addExcludedElements(id: Id64String) {
if (Id64.isValid(id)) {
if (undefined === this._json.excludedElements)
this._json.excludedElements = [];
this._json.excludedElements.push(id);
this._excludedElements.add(id);
}
}
/** Remove an element from the set of excluded elements defined by the display style.
* @param id The ID of the element to be removed from the set of excluded elements.
*/
public dropExcludedElement(id: Id64String) {
if (this._json.excludedElements !== undefined) {
const index = this._json.excludedElements.indexOf(id);
if (index > -1)
this._json.excludedElements.splice(index, 1);
if (this._json.excludedElements.length === 0)
this._json.excludedElements = undefined;
}
this._excludedElements.delete(id);
}
/** @internal */
public toJSON(): DisplayStyleSettingsProps { return this._json; }
private findIndexOfSubCategoryOverrideInJSON(id: Id64String, allowAppend: boolean): number {
const ovrsArray = JsonUtils.asArray(this._json.subCategoryOvr);
if (undefined === ovrsArray) {
if (allowAppend) {
this._json.subCategoryOvr = [];
return 0;
} else {
return -1;
}
} else {
for (let i = 0; i < ovrsArray.length; i++) {
if (ovrsArray[i].subCategory === id)
return i;
}
return allowAppend ? ovrsArray.length : -1;
}
}
private changeSubCategoryOverride(id: Id64String, updateJson: boolean, ovr?: SubCategoryOverride): void {
if (undefined === ovr) {
// undefined => drop the override if present.
this._subCategoryOverrides.delete(id);
if (updateJson) {
const index = this.findIndexOfSubCategoryOverrideInJSON(id, false);
if (-1 !== index)
this._json.subCategoryOvr!.splice(index, 1);
}
} else {
// add override, or update if present.
this._subCategoryOverrides.set(id, ovr);
if (updateJson) {
const index = this.findIndexOfSubCategoryOverrideInJSON(id, true);
this._json.subCategoryOvr![index] = ovr.toJSON();
this._json.subCategoryOvr![index].subCategory = id;
}
}
}
/** @internal */
public equalSubCategoryOverrides(other: DisplayStyleSettings): boolean {
if (this._subCategoryOverrides.size !== other._subCategoryOverrides.size)
return false;
for (const [key, value] of this._subCategoryOverrides.entries()) {
const otherValue = other._subCategoryOverrides.get(key);
if (undefined === otherValue || !value.equals(otherValue))
return false;
}
return true;
}
}
/** Provides access to the settings defined by a [[DisplayStyle3d]] or [[DisplayStyle3dState]], and ensures that
* the style's JSON properties are kept in sync.
* @beta
*/
export class DisplayStyle3dSettings extends DisplayStyleSettings {
private _hline: HiddenLine.Settings;
private _ao: AmbientOcclusion.Settings;
private _solarShadows: SolarShadows.Settings;
private _sunDir?: Vector3d;
private get _json3d(): DisplayStyle3dSettingsProps { return this._json as DisplayStyle3dSettingsProps; }
public constructor(jsonProperties: { styles?: DisplayStyle3dSettingsProps }) {
super(jsonProperties);
this._hline = HiddenLine.Settings.fromJSON(this._json3d.hline);
this._ao = AmbientOcclusion.Settings.fromJSON(this._json3d.ao);
this._solarShadows = SolarShadows.Settings.fromJSON(this._json3d.solarShadows);
if (undefined !== this._json3d.sceneLights && undefined !== this._json3d.sceneLights.sunDir)
this._sunDir = Vector3d.fromJSON(this._json3d.sceneLights.sunDir);
}
/** @internal */
public toJSON(): DisplayStyle3dSettingsProps { return this._json3d; }
/** The settings that control how visible and hidden edges are displayed.
* @note Do not modify the settings in place. Clone them and pass the clone to the setter.
*/
public get hiddenLineSettings(): HiddenLine.Settings { return this._hline; }
public set hiddenLineSettings(hline: HiddenLine.Settings) {
this._hline = hline;
this._json3d.hline = hline.toJSON();
}
/** The settings that control how ambient occlusion is displayed.
* @note Do not modify the settings in place. Clone them and pass the clone to the setter.
*/
public get ambientOcclusionSettings(): AmbientOcclusion.Settings { return this._ao; }
public set ambientOcclusionSettings(ao: AmbientOcclusion.Settings) {
this._ao = ao;
this._json3d.ao = ao.toJSON();
}
/** The settings that control how solar shadows are displayed.
* @note Do not modify the settings in place. Clone them and pass the clone to the setter.
*/
public get solarShadowsSettings(): SolarShadows.Settings { return this._solarShadows; }
public set solarShadowsSettings(solarShadows: SolarShadows.Settings) {
this._solarShadows = solarShadows;
this._json3d.solarShadows = solarShadows.toJSON();
}
/** @internal */
public get environment(): EnvironmentProps {
const env = this._json3d.environment;
return undefined !== env ? env : {};
}
public set environment(environment: EnvironmentProps) { this._json3d.environment = environment; }
/** @internal */
public get sunDir(): Vector3d | undefined {
return this._sunDir;
}
public set sunDir(dir: Vector3d | undefined) {
if (undefined === dir) {
this._sunDir = undefined;
if (undefined !== this._json3d.sceneLights)
this._json3d.sceneLights.sunDir = undefined;
return;
}
this._sunDir = dir.clone(this._sunDir);
if (undefined === this._json3d.sceneLights)
this._json3d.sceneLights = {};
this._json3d.sceneLights.sunDir = dir.toJSON();
}
}
You can’t perform that action at this time.