UNPKG

@itwin/core-frontend

Version:
157 lines 6.87 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 Tiles */ import { compareNumbers, comparePossiblyUndefined, compareStrings, compareStringsOrUndefined, Id64 } from "@itwin/core-bentley"; import { BatchType, iModelTileTreeIdToString, RenderMode, } from "@itwin/core-common"; import { IModelApp } from "../../IModelApp"; import { GeometricModelState } from "../../ModelState"; import { IModelTileTree, iModelTileTreeParamsFromJSON, TileTreeLoadStatus, TileTreeReference, } from "../../tile/internal"; import { _scheduleScriptReference } from "../../common/internal/Symbols"; function compareIds(lhs, rhs) { return compareNumbers(lhs.type, rhs.type) || compareNumbers(lhs.expansion, rhs.expansion) || compareStrings(lhs.modelId, rhs.modelId) || compareStringsOrUndefined(lhs.animationId, rhs.animationId) || comparePossiblyUndefined((x, y) => x.compareTo(y), lhs.timeline, rhs.timeline); } class ClassifierTreeSupplier { _nonexistentTreeOwner = { tileTree: undefined, loadStatus: TileTreeLoadStatus.NotFound, load: () => undefined, [Symbol.dispose]: () => undefined, loadTree: async () => undefined, iModel: undefined, }; compareTileTreeIds(lhs, rhs) { return compareIds(lhs, rhs); } async createTileTree(id, iModel) { await iModel.models.load(id.modelId); const model = iModel.models.getLoaded(id.modelId); if (undefined === model || !(model instanceof GeometricModelState)) return undefined; const idStr = iModelTileTreeIdToString(id.modelId, id, IModelApp.tileAdmin); const props = await IModelApp.tileAdmin.requestTileTreeProps(iModel, idStr); const params = iModelTileTreeParamsFromJSON(props, iModel, id.modelId, { edges: false, allowInstancing: false, is3d: true, batchType: id.type, timeline: id.timeline, }); return new IModelTileTree(params, id); } getOwner(id, iModel) { return Id64.isValid(id.modelId) ? iModel.tiles.getTileTreeOwner(id, this) : this._nonexistentTreeOwner; } addModelsAnimatedByScript(modelIds, scriptSourceId, trees) { // Note: This is invoked when an element hosting a schedule script is updated - it doesn't care about frontend schedule scripts. for (const tree of trees) if (scriptSourceId === tree.id.animationId) modelIds.add(tree.id.modelId); } addSpatialModels(modelIds, trees) { for (const tree of trees) modelIds.add(tree.id.modelId); } } const classifierTreeSupplier = new ClassifierTreeSupplier(); export class SpatialClassifierTileTreeReference extends TileTreeReference { get transparency() { return undefined; } } class ClassifierTreeReference extends SpatialClassifierTileTreeReference { _id; _classifiers; _source; _iModel; _classifiedTree; _owner; constructor(classifiers, classifiedTree, iModel, source) { super(); this._id = createClassifierId(classifiers.active, source); this._source = source; this._iModel = iModel; this._classifiers = classifiers; this._classifiedTree = classifiedTree; this._owner = classifierTreeSupplier.getOwner(this._id, iModel); } get classifiers() { return this._classifiers; } get activeClassifier() { return this.classifiers.activeClassifier; } get castsShadows() { return false; } get treeOwner() { const newId = createClassifierId(this._classifiers.active, this._source); if (0 !== compareIds(this._id, newId)) { this._id = newId; this._owner = classifierTreeSupplier.getOwner(this._id, this._iModel); } return this.activeClassifier?.tileTreeReference?.treeOwner ?? this._owner; } discloseTileTrees(trees) { // NB: We do NOT call super because we don't use our tree if no classifier is active. trees.disclose(this._classifiedTree); const classifier = this.activeClassifier; const classifierTree = undefined !== classifier ? this.treeOwner.tileTree : undefined; if (undefined !== classifierTree) trees.add(classifierTree); } get isPlanar() { if (this.activeClassifier?.flags.isVolumeClassifier) { return false; } return true; } get viewFlags() { return { renderMode: RenderMode.SmoothShade, transparency: true, // Igored for point clouds as they don't support transparency. textures: false, lighting: false, shadows: false, monochrome: false, materials: false, ambientOcclusion: false, visibleEdges: false, hiddenEdges: false, }; } // Add volume classifiers to scene (planar classifiers are added seperately.) addToScene(context) { if (this.isPlanar) return; const classifiedTree = this._classifiedTree.treeOwner.load(); if (undefined === classifiedTree) return; const classifier = this._classifiers.activeClassifier; if (undefined === classifier) return; const classifierTree = this.treeOwner.load(); if (undefined === classifierTree) return; context.setVolumeClassifier(classifier, classifiedTree.modelId); super.addToScene(context); } } export function createClassifierTileTreeReference(classifiers, classifiedTree, iModel, source) { return new ClassifierTreeReference(classifiers, classifiedTree, iModel, source); } function createClassifierId(classifier, source) { const disablePolyfaceDecimation = IModelApp.tileAdmin.disablePolyfaceDecimation; if (undefined === classifier) return { modelId: Id64.invalid, type: BatchType.PlanarClassifier, expansion: 0, animationId: undefined, disablePolyfaceDecimation }; const type = classifier.flags.isVolumeClassifier ? BatchType.VolumeClassifier : BatchType.PlanarClassifier; const scriptInfo = IModelApp.tileAdmin.getScriptInfoForTreeId(classifier.modelId, source ? source[_scheduleScriptReference] : undefined); return { modelId: classifier.modelId, type, expansion: classifier.expand, animationId: scriptInfo?.animationId, timeline: scriptInfo?.timeline, disablePolyfaceDecimation, }; } //# sourceMappingURL=ClassifierTileTree.js.map