UNPKG

@itwin/core-common

Version:

iTwin.js components common to frontend and backend

178 lines 7.52 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module DisplayStyles */ import { Range1d } from "@itwin/core-geometry"; import { ThematicGradientSettings } from "./ThematicDisplay"; import { Gradient } from "./Gradient"; /** Describes how an [[AnalysisStyle]] deforms a [Polyface]($core-geometry) by applying translation to its vertices. * @see [[AnalysisStyle.displacement]]. * @public */ export class AnalysisStyleDisplacement { /** The name of the [AuxChannel]($core-geometry) supplying the displacements to be applied to the vertices. */ channelName; /** A scale applied to the displacements to adjust the magnitude of the effect. * Default value: 1. */ scale; constructor(channelName, scale = 1) { this.channelName = channelName; this.scale = scale; } /** Create from JSON representation. */ static fromJSON(props) { return new this(props.channelName, props.scale); } /** Convert to JSON representation. */ toJSON() { const props = { channelName: this.channelName }; if (this.scale !== 1) props.scale = this.scale; return props; } /** Return true if `this` is equivalent to `other`. */ equals(other) { return this.channelName === other.channelName && this.scale === other.scale; } } /** Describes how an [[AnalysisStyle]] recolors [Polyface]($core-geometry) vertices by mapping values of type * [AuxChannelDataType.Scalar]($core-geometry) or [AuxChannelDataType.Distance]($core-geometry) supplied * by an [AuxChannel]($core-geometry) to colors supplied by a [[Gradient]] image. * @see [[AnalysisStyle.thematic]]. * @public */ export class AnalysisStyleThematic { /** The name of the [AuxChannel]($core-geometry) supplying the values from which the vertex colors are computed. */ channelName; /** The minimum and maximum values that map to colors in the [[Gradient]] image. Vertices with values outside of * this range are displayed with the gradient's margin color. */ range; /** Settings used to produce the [[Gradient]] image. */ thematicSettings; _gradient; constructor(props) { this.channelName = props.channelName; this.range = Range1d.fromJSON(props.range); this.thematicSettings = ThematicGradientSettings.fromJSON(props.thematicSettings); } /** Create from JSON representation. */ static fromJSON(props) { return new this(props); } /** Convert to JSON representation. */ toJSON() { const props = { channelName: this.channelName, range: this.range.toJSON(), }; if (!this.thematicSettings.equals(ThematicGradientSettings.defaults)) props.thematicSettings = this.thematicSettings.toJSON(); return props; } /** The gradient computed from [[thematicSettings]]. */ get gradient() { if (!this._gradient) this._gradient = Gradient.Symb.createThematic(this.thematicSettings); return this._gradient; } /** Return true if `this` is equivalent to `other`. */ equals(other) { return this.channelName === other.channelName && this.range.isAlmostEqual(other.range) && this.thematicSettings.equals(other.thematicSettings); } } function tryConvertLegacyProps(input) { if (input.displacement || input.scalar) return input; const legacy = input; if (undefined === legacy.displacementChannelName && undefined === legacy.scalarChannelName) return input; const output = { normalChannelName: input.normalChannelName, }; if (undefined !== legacy.displacementChannelName) { output.displacement = { channelName: legacy.displacementChannelName, scale: legacy.displacementScale, }; } if (undefined !== legacy.scalarChannelName && undefined !== legacy.scalarRange) { output.scalar = { channelName: legacy.scalarChannelName, range: legacy.scalarRange, thematicSettings: legacy.scalarThematicSettings, }; } return output; } /** As part of a [[DisplayStyleSettings]], describes how to animate meshes in the view that have been augmented with * [PolyfaceAuxData]($core-geometry). The style specifies which channels to use, and can deform the meshes by * translating vertices and/or recolor vertices using [[ThematicDisplay]]. * @see [[DisplayStyleSettings.analysisStyle]] to define the analysis style for a [DisplayStyle]($backend). * @see [[DisplayStyleSettings.analysisFraction]] to control playback of the animation. * @public */ export class AnalysisStyle { displacement; thematic; /** If defined, the name of the [AuxChannel]($core-geometry) from which to obtain normal vectors for the vertices. */ normalChannelName; /** Create an analysis style from its JSON representation. * @note AnalysisStyle is an immutable type - use [[clone]] to produce a modified copy. */ static fromJSON(props) { if (!props) return this.defaults; props = tryConvertLegacyProps(props); if (!props.displacement && !props.scalar && undefined === props.normalChannelName) return this.defaults; return new AnalysisStyle(props); } constructor(props) { this.normalChannelName = props.normalChannelName; if (props.displacement) this.displacement = AnalysisStyleDisplacement.fromJSON(props.displacement); if (props.scalar) this.thematic = AnalysisStyleThematic.fromJSON(props.scalar); } /** Convert this style to its JSON representation. */ toJSON() { const props = {}; if (this === AnalysisStyle.defaults) return props; if (this.displacement) props.displacement = this.displacement.toJSON(); if (this.thematic) props.scalar = this.thematic.toJSON(); if (undefined !== this.normalChannelName) props.normalChannelName = this.normalChannelName; return props; } /** Produce a copy of this style identical except for properties explicitly specified by `changedProps`. */ clone(changedProps) { return AnalysisStyle.fromJSON({ ...this.toJSON(), ...changedProps, }); } /** Return true if this style is equivalent to `other`. */ equals(other) { if (this.normalChannelName !== other.normalChannelName) return false; if ((undefined === this.displacement) !== (undefined === other.displacement)) return false; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion else if (this.displacement && !this.displacement.equals(other.displacement)) return false; if ((undefined === this.thematic) !== (undefined === other.thematic)) return false; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return undefined === this.thematic || this.thematic.equals(other.thematic); } static defaults = new AnalysisStyle({}); } //# sourceMappingURL=AnalysisStyle.js.map