@itwin/core-frontend
Version:
iTwin.js frontend components
157 lines • 6.87 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 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