@itwin/core-common
Version:
iTwin.js components common to frontend and backend
206 lines • 10.3 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Views
*/
import { assert, JsonUtils } from "@itwin/core-bentley";
import { RgbColor } from "./RgbColor";
import { HiddenLine } from "./HiddenLine";
import { FeatureAppearance } from "./FeatureSymbology";
import { ColorDef } from "./ColorDef";
/** As part of a [[ClipStyle]], describes how section-cut graphics should be displayed.
* @note Section-cut graphics are only produced if [[ClipStyle.produceCutGeometry]] is `true`.
* @public
*/
export class CutStyle {
/** Selectively overrides some of the view's [[ViewFlags]] when drawing the section-cut graphics. */
viewflags;
/** If defined, overrides the settings the view uses to draw the edges of the section-cut graphics. */
hiddenLine;
/** If defined, overrides aspects of the symbology of the section-cut graphics. */
appearance;
/** The default CutStyle, configured to draw the section-cut graphics using the view's settings, with no overrides. */
static defaults = new CutStyle();
constructor(viewflags, hiddenLine, appearance) {
this.viewflags = viewflags ?? {};
if (hiddenLine && !hiddenLine.matchesDefaults)
this.hiddenLine = hiddenLine;
if (appearance && !appearance.matchesDefaults)
this.appearance = appearance;
}
/** Create a CutStyle from its components. */
static create(viewflags, hiddenLine, appearance) {
if ((viewflags && JsonUtils.isNonEmptyObject(viewflags)) || (hiddenLine && !hiddenLine.matchesDefaults) || (appearance && !appearance.matchesDefaults))
return new CutStyle(viewflags, hiddenLine, appearance);
return this.defaults;
}
static fromJSON(props) {
if (JsonUtils.isNonEmptyObject(props)) {
const viewflags = { ...props?.viewflags };
const hiddenLine = props?.hiddenLine ? HiddenLine.Settings.fromJSON(props.hiddenLine) : undefined;
const appearance = props?.appearance ? FeatureAppearance.fromJSON(props.appearance) : undefined;
return this.create(viewflags, hiddenLine, appearance);
}
else {
return this.defaults;
}
}
/** Return JSON representation. The representation is `undefined` if this style matches the default style. */
toJSON() {
if (this.matchesDefaults)
return undefined;
const props = {};
if (JsonUtils.isNonEmptyObject(this.viewflags))
props.viewflags = this.viewflags;
if (this.hiddenLine && !this.hiddenLine.matchesDefaults)
props.hiddenLine = this.hiddenLine?.toJSON();
if (this.appearance && !this.appearance.matchesDefaults)
props.appearance = this.appearance.toJSON();
return props;
}
/** Returns true if this style matches the default style - that is, it overrides none of the view's settings. */
get matchesDefaults() {
if (this === CutStyle.defaults)
return true;
return !JsonUtils.isNonEmptyObject(this.viewflags) && (!this.hiddenLine || this.hiddenLine.matchesDefaults) && (!this.appearance || this.appearance.matchesDefaults);
}
}
/** As part of a [[ClipStyle]], describes how to colorize geometry intersecting the clip planes.
* @note Edges are highlighted only if [[ClipStyle.ClipIntersectionStyle]] is `true`.
* @public
* @extensions
*/
export class ClipIntersectionStyle {
/** Color to apply to intersection of geometry and clip planes, default white */
color;
/** Number of pixels to be considered intersecting the clip plane, default 1 */
width;
constructor(color = RgbColor.fromColorDef(ColorDef.white), width = 1) {
this.color = color;
this.width = width;
}
/** Create a highlight from its components. */
static create(color, width) {
if (!color && !width)
return this.defaults;
return new ClipIntersectionStyle(color, width);
}
static defaults = new ClipIntersectionStyle();
static fromJSON(props) {
if (props === undefined) {
return ClipIntersectionStyle.defaults;
}
const color = props.color ? RgbColor.fromJSON(props.color) : RgbColor.fromColorDef(ColorDef.white);
const width = props.width ? props.width : 1;
return new ClipIntersectionStyle(color, width);
}
/** The JSON representation of this style. It is `undefined` if this style matches the defaults. */
toJSON() {
const props = {};
if (this.matchesDefaults) {
return undefined;
}
if (this.color)
props.color = this.color.toJSON();
if (this.width)
props.width = this.width;
return props;
}
get matchesDefaults() {
if (this === ClipIntersectionStyle.defaults)
return true;
return !this.color && !this.width;
}
}
/** Describes symbology and behavior applied to a [ClipVector]($core-geometry) when applied to a [ViewState]($frontend) or [[ModelClipGroup]].
* @see [[DisplayStyleSettings.clipStyle]].
* @public
*/
export class ClipStyle {
/** If `true`, geometry will be produced at the clip planes.
* - Solids (closed volumes) will produce facets on the clip planes.
* - Other surfaces will produce line strings representing the edges of the surface at the clip planes.
* @note Cut geometry will only be produced for element geometry - not for, e.g., terrain or reality models.
*/
produceCutGeometry;
/** If 'true', intersection of geometry and clip planes will be colorized */
colorizeIntersection;
/** Controls aspects of how the cut geometry is displayed, if [[produceCutGeometry]] is `true`. */
cutStyle;
/** If defined, geometry inside the clip planes will be drawn in this color. */
insideColor;
/** If defined, geometry outside of the clip planes will be drawn in this color instead of being clipped. */
outsideColor;
/** Controls the style of the intersection of geometry and clip planes */
intersectionStyle;
/** The default style, which overrides none of the view's settings. */
static defaults = new ClipStyle(false, false, CutStyle.defaults, undefined, undefined, undefined);
constructor(produceCutGeometry, colorizeIntersection, cutStyle, inside, outside, intersectionStyle) {
this.produceCutGeometry = produceCutGeometry;
this.colorizeIntersection = colorizeIntersection;
this.cutStyle = cutStyle;
this.insideColor = inside;
this.outsideColor = outside;
this.intersectionStyle = intersectionStyle;
}
/** @internal */
static create(styleOrProduceCutGeometry, cutStyle, insideColor, outsideColor) {
if (typeof styleOrProduceCutGeometry === "boolean") {
cutStyle = cutStyle === undefined ? CutStyle.defaults : cutStyle;
if (!styleOrProduceCutGeometry && cutStyle.matchesDefaults && !insideColor && !outsideColor) {
return this.defaults;
}
return new ClipStyle(styleOrProduceCutGeometry, false, cutStyle, insideColor, outsideColor, undefined);
}
const style = styleOrProduceCutGeometry;
if (!style.produceCutGeometry && !style.colorizeIntersection && (!style.cutStyle || style.cutStyle.matchesDefaults) && !style.insideColor && !style.outsideColor && !style.intersectionStyle)
return this.defaults;
const produceCutGeometry = style.produceCutGeometry ? true : false;
const colorizeIntersection = style.colorizeIntersection ? true : false;
cutStyle = style.cutStyle === undefined ? CutStyle.defaults : style.cutStyle;
return new ClipStyle(produceCutGeometry, colorizeIntersection, cutStyle, style.insideColor, style.outsideColor, style.intersectionStyle);
}
static fromJSON(props) {
if (JsonUtils.isNonEmptyObject(props)) {
const produceCutGeometry = props.produceCutGeometry ?? false;
const colorizeIntersection = props.colorizeIntersection ? true : false;
const cutStyle = CutStyle.fromJSON(props.cutStyle);
const insideColor = props.insideColor ? RgbColor.fromJSON(props.insideColor) : undefined;
const outsideColor = props.outsideColor ? RgbColor.fromJSON(props.outsideColor) : undefined;
const intersectionStyle = props.intersectionStyle ? ClipIntersectionStyle.fromJSON(props.intersectionStyle) : undefined;
return this.create({ produceCutGeometry, colorizeIntersection, cutStyle, insideColor, outsideColor, intersectionStyle });
}
return this.defaults;
}
/** The JSON representation of this style. It is `undefined` if this style matches the defaults. */
toJSON() {
if (this.matchesDefaults)
return undefined;
const props = {};
if (this.produceCutGeometry)
props.produceCutGeometry = true;
if (this.colorizeIntersection)
props.colorizeIntersection = true;
const cutStyle = this.cutStyle.toJSON();
if (cutStyle) {
assert(!this.cutStyle.matchesDefaults);
props.cutStyle = cutStyle;
}
if (this.insideColor)
props.insideColor = this.insideColor.toJSON();
if (this.outsideColor)
props.outsideColor = this.outsideColor.toJSON();
if (this.intersectionStyle)
props.intersectionStyle = this.intersectionStyle.toJSON();
return props;
}
/** Returns true if this style matches the [[ClipStyle.defaults]] - that is, it overrides no settings from the view. */
get matchesDefaults() {
if (this === ClipStyle.defaults)
return true;
return !this.produceCutGeometry && !this.colorizeIntersection && !this.insideColor && !this.outsideColor && this.cutStyle.matchesDefaults && !this.intersectionStyle;
}
}
//# sourceMappingURL=ClipStyle.js.map