@itwin/core-backend
Version:
iTwin.js backend components
297 lines • 14.9 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 ViewDefinitions
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.DisplayStyle3d = exports.DisplayStyle2d = exports.DisplayStyle = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_common_1 = require("@itwin/core-common");
const Element_1 = require("./Element");
/** A DisplayStyle defines the parameters for 'styling' the contents of a view.
* Internally a DisplayStyle consists of a dictionary of several named 'styles' describing specific aspects of the display style as a whole.
* Many ViewDefinitions may share the same DisplayStyle.
* @public @preview
*/
class DisplayStyle extends Element_1.DefinitionElement {
static get className() { return "DisplayStyle"; }
constructor(props, iModel) {
super(props, iModel);
}
/** @beta */
static deserialize(props) {
const elProps = super.deserialize(props);
const displayOptions = props.options?.element?.displayStyle;
// Uncompress excludedElements if they are compressed
if (!displayOptions?.compressExcludedElementIds && elProps.jsonProperties?.styles?.excludedElements) {
const excludedElements = elProps.jsonProperties.styles.excludedElements;
if (typeof excludedElements === "string" && excludedElements.startsWith("+")) {
const ids = [];
core_bentley_1.CompressedId64Set.decompressSet(excludedElements).forEach((id) => {
ids.push(id);
});
elProps.jsonProperties.styles.excludedElements = ids;
}
}
// Omit Schedule Script Element Ids if the option is set
if (displayOptions?.omitScheduleScriptElementIds && elProps.jsonProperties?.styles?.scheduleScript) {
const scheduleScript = elProps.jsonProperties.styles.scheduleScript;
elProps.jsonProperties.styles.scheduleScript = core_common_1.RenderSchedule.Script.removeScheduleScriptElementIds(scheduleScript);
}
return elProps;
}
/** @beta */
static serialize(props, iModel) {
const inst = super.serialize(props, iModel);
return inst;
}
/** Create a Code for a DisplayStyle given a name that is meant to be unique within the scope of the specified DefinitionModel.
* @param iModel The IModelDb
* @param scopeModelId The Id of the DefinitionModel that contains the DisplayStyle and provides the scope for its name.
* @param codeValue The DisplayStyle name
*/
static createCode(iModel, scopeModelId, codeValue) {
const codeSpec = iModel.codeSpecs.getByName(core_common_1.BisCodeSpec.displayStyle);
return new core_common_1.Code({ spec: codeSpec.id, scope: scopeModelId, value: codeValue });
}
collectReferenceIds(referenceIds) {
super.collectReferenceIds(referenceIds);
for (const [id] of this.settings.subCategoryOverrides) {
referenceIds.addElement(id);
}
for (const excludedElementId of this.settings.excludedElementIds)
referenceIds.addElement(excludedElementId);
if (this.settings.renderTimeline) {
referenceIds.addElement(this.settings.renderTimeline);
}
else {
const script = this.loadScheduleScript();
if (script)
script.script.discloseIds(referenceIds);
}
}
/** @alpha */
static onCloned(context, sourceElementProps, targetElementProps) {
super.onCloned(context, sourceElementProps, targetElementProps);
if (!context.isBetweenIModels || !targetElementProps.jsonProperties?.styles)
return;
const settings = targetElementProps.jsonProperties.styles;
if (settings.subCategoryOvr) {
const targetOverrides = [];
for (const ovr of settings.subCategoryOvr) {
ovr.subCategory;
const targetSubCategoryId = context.findTargetElementId(core_bentley_1.Id64.fromJSON(ovr.subCategory));
if (core_bentley_1.Id64.isValid(targetSubCategoryId))
targetOverrides.push({ ...ovr, subCategory: targetSubCategoryId });
}
settings.subCategoryOvr = targetOverrides;
}
if (settings.excludedElements) {
const excluded = "string" === typeof settings.excludedElements ? core_bentley_1.CompressedId64Set.decompressArray(settings.excludedElements) : settings.excludedElements;
const excludedTargetElements = [];
for (const excludedElement of excluded) {
const remapped = context.findTargetElementId(excludedElement);
if (core_bentley_1.Id64.isValid(remapped))
excludedTargetElements.push(remapped);
}
if (0 === excludedTargetElements.length)
delete settings.excludedElements;
else
settings.excludedElements = core_bentley_1.CompressedId64Set.compressIds(core_bentley_1.OrderedId64Iterable.sortArray(excludedTargetElements));
}
if (settings.renderTimeline) {
const renderTimeline = context.findTargetElementId(settings.renderTimeline);
if (core_bentley_1.Id64.isValid(renderTimeline))
settings.renderTimeline = renderTimeline;
else
delete settings.renderTimeline;
}
else if (settings.scheduleScript) {
const scheduleScript = Element_1.RenderTimeline.remapScript(context, settings.scheduleScript);
if (scheduleScript.length > 0)
settings.scheduleScript = scheduleScript;
else
delete settings.scheduleScript;
}
}
loadScheduleScript() {
let script;
let sourceId;
if (this.settings.renderTimeline) {
const timeline = this.iModel.elements.tryGetElement(this.settings.renderTimeline);
if (timeline) {
script = core_common_1.RenderSchedule.Script.fromJSON(timeline.scriptProps);
sourceId = timeline.id;
}
}
else if (this.settings.scheduleScriptProps) {
script = core_common_1.RenderSchedule.Script.fromJSON(this.settings.scheduleScriptProps);
sourceId = this.id;
}
return undefined !== sourceId && undefined !== script ? new core_common_1.RenderSchedule.ScriptReference(sourceId, script) : undefined;
}
}
exports.DisplayStyle = DisplayStyle;
/** A DisplayStyle for 2d views.
* @public @preview
*/
class DisplayStyle2d extends DisplayStyle {
static get className() { return "DisplayStyle2d"; }
_settings;
get settings() { return this._settings; }
constructor(props, iModel) {
super(props, iModel);
this._settings = new core_common_1.DisplayStyleSettings(this.jsonProperties);
}
/** Create a DisplayStyle2d for use by a ViewDefinition.
* @param iModelDb The iModel
* @param definitionModelId The [[DefinitionModel]]
* @param name The name/CodeValue of the DisplayStyle2d
* @returns The newly constructed DisplayStyle2d element.
* @throws [[IModelError]] if unable to create the element.
*/
static create(iModelDb, definitionModelId, name) {
const displayStyleProps = {
classFullName: this.classFullName,
code: this.createCode(iModelDb, definitionModelId, name),
model: definitionModelId,
isPrivate: false,
jsonProperties: {
styles: {
backgroundColor: 0,
monochromeColor: core_common_1.ColorDef.white.toJSON(),
viewflags: core_common_1.ViewFlags.defaults,
},
},
};
return new DisplayStyle2d(displayStyleProps, iModelDb);
}
/** Insert a DisplayStyle2d for use by a ViewDefinition.
* @param iModelDb Insert into this iModel
* @param definitionModelId Insert the new DisplayStyle2d into this DefinitionModel
* @param name The name of the DisplayStyle2d
* @returns The Id of the newly inserted DisplayStyle2d element.
* @throws [[IModelError]] if unable to insert the element.
*/
static insert(iModelDb, definitionModelId, name) {
const displayStyle = this.create(iModelDb, definitionModelId, name);
return iModelDb.elements.insertElement(displayStyle.toJSON());
}
}
exports.DisplayStyle2d = DisplayStyle2d;
/** A DisplayStyle for 3d views.
* See [how to create a DisplayStyle3d]$(docs/learning/backend/CreateElements.md#DisplayStyle3d).
* @public @preview
*/
class DisplayStyle3d extends DisplayStyle {
static get className() { return "DisplayStyle3d"; }
_settings;
get settings() { return this._settings; }
constructor(props, iModel) {
super(props, iModel);
this._settings = new core_common_1.DisplayStyle3dSettings(this.jsonProperties);
}
collectReferenceIds(referenceIds) {
super.collectReferenceIds(referenceIds);
for (const textureId of this.settings.environment.sky.textureIds)
referenceIds.addElement(textureId);
if (this.settings.planProjectionSettings)
for (const planProjectionSetting of this.settings.planProjectionSettings)
referenceIds.addElement(planProjectionSetting[0]);
const groups = this.settings.contours.groups;
for (const group of groups) {
const subCategories = group.subCategories;
for (const subCategoryId of subCategories) {
referenceIds.addElement(subCategoryId);
}
}
}
/** @alpha */
static onCloned(context, sourceElementProps, targetElementProps) {
super.onCloned(context, sourceElementProps, targetElementProps);
if (context.isBetweenIModels) {
const convertTexture = (id) => core_bentley_1.Id64.isValidId64(id) ? context.findTargetElementId(id) : id;
const skyBoxImageProps = targetElementProps?.jsonProperties?.styles?.environment?.sky?.image;
if (skyBoxImageProps?.texture && core_bentley_1.Id64.isValidId64(skyBoxImageProps.texture))
skyBoxImageProps.texture = convertTexture(skyBoxImageProps.texture);
if (skyBoxImageProps?.textures) {
skyBoxImageProps.textures.front = convertTexture(skyBoxImageProps.textures.front);
skyBoxImageProps.textures.back = convertTexture(skyBoxImageProps.textures.back);
skyBoxImageProps.textures.left = convertTexture(skyBoxImageProps.textures.left);
skyBoxImageProps.textures.right = convertTexture(skyBoxImageProps.textures.right);
skyBoxImageProps.textures.top = convertTexture(skyBoxImageProps.textures.top);
skyBoxImageProps.textures.bottom = convertTexture(skyBoxImageProps.textures.bottom);
}
if (targetElementProps?.jsonProperties?.styles?.planProjections) {
const remappedPlanProjections = {};
for (const entry of Object.entries(targetElementProps.jsonProperties.styles.planProjections)) {
const remappedModelId = context.findTargetElementId(entry[0]);
if (core_bentley_1.Id64.isValidId64(remappedModelId)) {
remappedPlanProjections[remappedModelId] = entry[1];
}
}
targetElementProps.jsonProperties.styles.planProjections = remappedPlanProjections;
}
const groups = targetElementProps?.jsonProperties?.styles?.contours?.groups;
if (groups) {
for (const group of groups) {
if (group.subCategories) {
const subCategories = core_bentley_1.CompressedId64Set.decompressArray(group.subCategories);
const remappedSubCategories = [];
for (const subCategoryId of subCategories) {
const remappedSubCategoryId = context.findTargetElementId(subCategoryId);
if (core_bentley_1.Id64.isValidId64(remappedSubCategoryId)) {
remappedSubCategories.push(remappedSubCategoryId);
}
}
group.subCategories = core_bentley_1.CompressedId64Set.sortAndCompress(remappedSubCategories);
}
}
}
}
}
/** Create a DisplayStyle3d for use by a ViewDefinition.
* @param iModelDb The iModel
* @param definitionModelId The [[DefinitionModel]]
* @param name The name/CodeValue of the DisplayStyle3d
* @returns The newly constructed DisplayStyle3d element.
* @throws [[IModelError]] if unable to create the element.
*/
static create(iModelDb, definitionModelId, name, options) {
options = options ?? {};
let viewflags = options.viewFlags?.toJSON();
if (!viewflags)
viewflags = options.viewflags ?? new core_common_1.ViewFlags().toJSON();
const backgroundColor = options.backgroundColor instanceof core_common_1.ColorDef ? options.backgroundColor.toJSON() : options.backgroundColor;
const settings = {
...options,
viewflags,
backgroundColor,
};
const displayStyleProps = {
classFullName: this.classFullName,
code: this.createCode(iModelDb, definitionModelId, name),
model: definitionModelId,
jsonProperties: { styles: settings },
isPrivate: false,
};
return new DisplayStyle3d(displayStyleProps, iModelDb);
}
/**
* Insert a DisplayStyle3d for use by a ViewDefinition.
* @param iModelDb Insert into this iModel
* @param definitionModelId Insert the new DisplayStyle3d into this [[DefinitionModel]]
* @param name The name of the DisplayStyle3d
* @returns The Id of the newly inserted DisplayStyle3d element.
* @throws [[IModelError]] if unable to insert the element.
*/
static insert(iModelDb, definitionModelId, name, options) {
const displayStyle = this.create(iModelDb, definitionModelId, name, options);
return iModelDb.elements.insertElement(displayStyle.toJSON());
}
}
exports.DisplayStyle3d = DisplayStyle3d;
//# sourceMappingURL=DisplayStyle.js.map
;