@itwin/core-frontend
Version:
iTwin.js frontend components
645 lines • 28.8 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 { assert, comparePossiblyUndefined, compareStrings, } from "@itwin/core-bentley";
import { BatchType, compareIModelTileTreeIds, FeatureAppearanceProvider, iModelTileTreeIdToString, ModelMapLayerDrapeTarget, ModelMapLayerSettings, RenderMode, SpatialClassifier, } from "@itwin/core-common";
import { Range3d, StringifiedClipVector, Transform } from "@itwin/core-geometry";
import { IModelApp } from "../../IModelApp";
import { formatAnimationBranchId } from "../../internal/render/AnimationBranchState";
import { AnimationNodeId } from "../../common/internal/render/AnimationNodeId";
import { IModelTileTree, iModelTileTreeParamsFromJSON, LayerTileTreeReferenceHandler, MapLayerTileTreeReference, TileGraphicType, TileTreeReference, } from "../../tile/internal";
import { _scheduleScriptReference } from "../../common/internal/Symbols";
class PlanProjectionTileTree extends IModelTileTree {
baseElevation;
constructor(params, treeId, baseElevation) {
super(params, treeId);
this.baseElevation = baseElevation;
}
}
class PrimaryTreeSupplier {
constructor() {
}
compareTileTreeIds(lhs, rhs) {
// NB: we don't compare isPlanProjection or is3d - they should always have the same value for a given modelId.
return compareStrings(lhs.modelId, rhs.modelId) || compareIModelTileTreeIds(lhs.treeId, rhs.treeId)
|| comparePossiblyUndefined((x, y) => x.compareTo(y), lhs.timeline, rhs.timeline);
}
async createTileTree(id, iModel) {
const treeId = id.treeId;
const idStr = iModelTileTreeIdToString(id.modelId, treeId, IModelApp.tileAdmin);
const props = await IModelApp.tileAdmin.requestTileTreeProps(iModel, idStr);
// ###TODO remove restriction that animated tile trees can't contained instanced geometry.
const isAnimated = undefined !== treeId.animationId || undefined !== id.timeline;
const allowInstancing = !isAnimated && !treeId.enforceDisplayPriority && !treeId.sectionCut;
const options = {
edges: treeId.edges,
allowInstancing,
is3d: id.is3d,
batchType: BatchType.Primary,
timeline: id.timeline,
};
const params = iModelTileTreeParamsFromJSON(props, iModel, id.modelId, options);
if (!id.isPlanProjection)
return new IModelTileTree(params, id.treeId);
let elevation = 0;
try {
const ranges = await iModel.models.queryExtents(id.modelId);
if (1 === ranges.length) {
const range = Range3d.fromJSON(ranges[0].extents);
const lo = range.low.z;
const hi = range.high.z;
if (lo <= hi)
elevation = (lo + hi) / 2;
}
}
catch {
//
}
return new PlanProjectionTileTree(params, id.treeId, elevation);
}
getOwner(id, iModel) {
return iModel.tiles.getTileTreeOwner(id, this);
}
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.treeId.animationId)
modelIds.add(tree.id.modelId);
}
addSpatialModels(modelIds, trees) {
for (const tree of trees)
if (tree.id.is3d)
modelIds.add(tree.id.modelId);
}
}
const primaryTreeSupplier = new PrimaryTreeSupplier();
/** Find all extant tile trees associated with the specified model Ids and dispose of them.
* This is used by BriefcaseConnection when a GraphicalEditingScope is exited or after a change to the models' geometry guids
* is committed, undone, redone, or merged.
*/
export function disposeTileTreesForGeometricModels(modelIds, iModel) {
const trees = iModel.tiles.getTreeOwnersForSupplier(primaryTreeSupplier);
for (const kvp of trees) {
const id = kvp.id;
assert(undefined !== id.modelId);
if (modelIds.has(id.modelId))
kvp.owner[Symbol.dispose]();
}
}
class PrimaryTreeReference extends TileTreeReference {
view;
model;
/** Chiefly for debugging - disables iteration of this reference in SpatialModelRefs to e.g. omit the reference from the scene. */
deactivated = false;
_viewFlagOverrides;
_id;
_owner;
_sectionClip;
_sectionCutAppearanceProvider;
_animationTransformNodeId;
_layerRefHandler;
iModel;
shouldDrapeLayer(layerTreeRef) {
const mapLayerSettings = layerTreeRef?.layerSettings;
if (mapLayerSettings && mapLayerSettings instanceof ModelMapLayerSettings)
return ModelMapLayerDrapeTarget.IModel === mapLayerSettings.drapeTarget;
return false;
}
constructor(view, model, planProjection, transformNodeId, sectionClip, backgroundBase, backgroundLayers) {
super();
this.iModel = model.iModel;
this._layerRefHandler = new LayerTileTreeReferenceHandler(this, false, backgroundBase, backgroundLayers, false);
this.view = view;
this.model = model;
this._animationTransformNodeId = transformNodeId;
this._sectionClip = sectionClip;
this._viewFlagOverrides = { ...model.jsonProperties.viewFlagOverrides };
if (sectionClip) {
// Clipping will be applied on backend; don't clip out cut geometry.
this._viewFlagOverrides.clipVolume = false;
this._sectionCutAppearanceProvider = FeatureAppearanceProvider.supplement((app) => {
const cutApp = this.view.displayStyle.settings.clipStyle.cutStyle.appearance;
return cutApp ? app.extendAppearance(cutApp) : app;
});
}
const scriptInfo = IModelApp.tileAdmin.getScriptInfoForTreeId(model.id, view.displayStyle[_scheduleScriptReference]);
this._id = {
modelId: model.id,
is3d: model.is3d,
treeId: this.createTreeId(view, model.id),
isPlanProjection: planProjection,
timeline: scriptInfo?.timeline,
};
this._owner = primaryTreeSupplier.getOwner(this._id, model.iModel);
}
getAnimationTransformNodeId() {
return this._animationTransformNodeId ?? AnimationNodeId.Untransformed;
}
getViewFlagOverrides(_tree) {
return this._viewFlagOverrides;
}
getAppearanceProvider(_tree) {
if (this._sectionCutAppearanceProvider && this.view.displayStyle.settings.clipStyle.cutStyle.appearance)
return this._sectionCutAppearanceProvider;
return undefined;
}
getHiddenLineSettings(_tree) {
return this._sectionClip ? this.view.displayStyle.settings.clipStyle.cutStyle.hiddenLine : undefined;
}
get castsShadows() {
return true;
}
get isPlanProjection() {
return false;
}
discloseTileTrees(trees) {
super.discloseTileTrees(trees);
this._layerRefHandler.discloseTileTrees(trees);
}
getClipVolume(_tree) {
// ###TODO: reduce frequency with which getModelClip() is called
return this.view.is3d() && !this._sectionClip ? this.view.getModelClip(this.model.id) : undefined;
}
canSupplyToolTip() {
return false;
}
createDrawArgs(context) {
const args = super.createDrawArgs(context);
if (args)
args.intersectionClip = this._sectionClip;
return args;
}
get treeOwner() {
const newId = this.createTreeId(this.view, this._id.modelId);
const timeline = IModelApp.tileAdmin.getScriptInfoForTreeId(this._id.modelId, this.view.displayStyle[_scheduleScriptReference])?.timeline;
if (0 !== compareIModelTileTreeIds(newId, this._id.treeId) || timeline?.isEditingCommitted) {
this._id = {
modelId: this._id.modelId,
is3d: this._id.is3d,
treeId: newId,
isPlanProjection: this._id.isPlanProjection,
timeline,
};
this._owner = primaryTreeSupplier.getOwner(this._id, this.model.iModel);
}
return this._owner;
}
createTreeId(view, modelId) {
if (this._sectionClip) {
// We do this each time in case the ClipStyle's overrides are modified.
// ###TODO: can we avoid that? Event listeners maybe?
this._viewFlagOverrides = {
...this.view.displayStyle.settings.clipStyle.cutStyle.viewflags,
// Do not clip out the cut geometry intersecting the clip planes.
clipVolume: false,
// The cut geometry is planar - it should win a z-fight.
// Also we need to preserve this flag if this is a plan projection tile tree reference.
forceSurfaceDiscard: true,
};
}
const animationId = IModelApp.tileAdmin.getScriptInfoForTreeId(modelId, view.displayStyle[_scheduleScriptReference])?.animationId;
const renderMode = this._viewFlagOverrides.renderMode ?? view.viewFlags.renderMode;
const visibleEdges = this._viewFlagOverrides.visibleEdges ?? view.viewFlags.visibleEdges;
const edgesRequired = visibleEdges || RenderMode.SmoothShade !== renderMode || IModelApp.tileAdmin.alwaysRequestEdges;
const edges = edgesRequired ? IModelApp.tileAdmin.edgeOptions : false;
const sectionCut = this._sectionClip?.clipString;
const disablePolyfaceDecimation = IModelApp.tileAdmin.disablePolyfaceDecimation;
return { type: BatchType.Primary, edges, animationId, sectionCut, disablePolyfaceDecimation };
}
computeBaseTransform(tree) {
return super.computeTransform(tree);
}
computeTransform(tree) {
const baseTf = this.computeBaseTransform(tree);
const displayTf = this.view.modelDisplayTransformProvider?.getModelDisplayTransform(this.model.id);
if (!displayTf)
return baseTf;
return displayTf.premultiply ? displayTf.transform.multiplyTransformTransform(baseTf) : baseTf.multiplyTransformTransform(displayTf.transform);
}
addToScene(context) {
const tree = this.treeOwner.load();
if (undefined === tree || !this._layerRefHandler.initializeLayers(context))
return; // Not loaded yet.
super.addToScene(context);
}
}
export class AnimatedTreeReference extends PrimaryTreeReference {
_branchId;
constructor(view, model, transformNodeId) {
super(view, model, false, transformNodeId);
this._branchId = formatAnimationBranchId(model.id, transformNodeId);
}
computeBaseTransform(tree) {
const tf = super.computeBaseTransform(tree);
const style = this.view.displayStyle;
const script = style.scheduleScript;
if (undefined === script || undefined === this._animationTransformNodeId)
return tf;
const timePoint = style.settings.timePoint ?? script.duration.low;
const animTf = script.getTransform(this._id.modelId, this._animationTransformNodeId, timePoint);
if (animTf)
animTf.multiplyTransformTransform(tf, tf);
return tf;
}
createDrawArgs(context) {
const animBranch = context.viewport.target.animationBranches?.branchStates.get(this._branchId);
if (animBranch && animBranch.omit)
return undefined;
const args = super.createDrawArgs(context);
if (args?.tree && undefined !== this._animationTransformNodeId) {
assert(args.tree instanceof IModelTileTree);
args.boundingRange = args.tree.getTransformNodeRange(this._animationTransformNodeId);
}
return args;
}
}
class PlanProjectionTreeReference extends PrimaryTreeReference {
get _view3d() { return this.view; }
_baseTransform = Transform.createIdentity();
constructor(view, model, sectionCut, backgroundBase, backgroundLayers) {
super(view, model, true, undefined, sectionCut, backgroundBase, backgroundLayers);
this._viewFlagOverrides.forceSurfaceDiscard = true;
}
get castsShadows() {
return false;
}
get isPlanProjection() {
return true;
}
createDrawArgs(context) {
const args = super.createDrawArgs(context);
if (undefined !== args && this._id.treeId.enforceDisplayPriority) {
args.drawGraphics = () => {
const graphics = args.produceGraphics();
if (undefined !== graphics) {
const settings = this.getSettings();
const asOverlay = undefined !== settings && settings.overlay;
const transparency = settings?.transparency || 0;
let elevation = settings?.elevation;
if (undefined === elevation) {
const tree = this.treeOwner.tileTree;
if (tree) {
assert(tree instanceof PlanProjectionTileTree);
elevation = tree.baseElevation;
}
else {
elevation = 0;
}
}
context.outputGraphic(context.target.renderSystem.createGraphicLayerContainer(graphics, asOverlay, transparency, elevation));
}
};
}
return args;
}
computeBaseTransform(tree) {
assert(tree instanceof PlanProjectionTileTree);
const transform = tree.iModelTransform.clone(this._baseTransform);
const elevation = this.getSettings()?.elevation;
if (undefined !== elevation)
transform.origin.z = elevation;
return transform;
}
draw(args) {
const settings = this.getSettings();
if (undefined === settings || settings.enforceDisplayPriority || !settings.overlay)
super.draw(args);
else
args.context.withGraphicType(TileGraphicType.Overlay, () => args.tree.draw(args));
}
getSettings() {
return this._view3d.getDisplayStyle3d().settings.getPlanProjectionSettings(this.model.id);
}
createTreeId(view, modelId) {
const id = super.createTreeId(view, modelId);
const settings = this.getSettings();
if (undefined !== settings && settings.enforceDisplayPriority)
id.enforceDisplayPriority = true;
return id;
}
}
function isPlanProjection(view, model) {
const model3d = view.is3d() ? model.asGeometricModel3d : undefined;
return undefined !== model3d && model3d.isPlanProjection;
}
function createTreeRef(view, model, sectionCut, backgroundBase, backgroundLayers) {
if (false !== IModelApp.renderSystem.options.planProjections && isPlanProjection(view, model))
return new PlanProjectionTreeReference(view, model, sectionCut, backgroundBase, backgroundLayers);
return new PrimaryTreeReference(view, model, false, undefined, sectionCut, backgroundBase, backgroundLayers);
}
export function createPrimaryTileTreeReference(view, model, getBackgroundBase, getBackgroundLayers) {
const backgroundBase = getBackgroundBase?.();
const backgroundLayers = getBackgroundLayers?.();
return createTreeRef(view, model, undefined, backgroundBase, backgroundLayers);
}
class MaskTreeReference extends TileTreeReference {
_id;
_owner;
model;
get castsShadows() { return false; }
constructor(view, model) {
super();
this.model = model;
this._id = {
modelId: model.id,
is3d: model.is3d,
treeId: this.createTreeId(),
isPlanProjection: isPlanProjection(view, model),
};
this._owner = primaryTreeSupplier.getOwner(this._id, model.iModel);
}
get treeOwner() {
const newId = this.createTreeId();
if (0 !== compareIModelTileTreeIds(newId, this._id.treeId)) {
this._id = { modelId: this._id.modelId, is3d: this._id.is3d, treeId: newId, isPlanProjection: false };
this._owner = primaryTreeSupplier.getOwner(this._id, this.model.iModel);
}
return this._owner;
}
createTreeId() {
return { type: BatchType.Primary, edges: false, disablePolyfaceDecimation: IModelApp.tileAdmin.disablePolyfaceDecimation };
}
}
export function createMaskTreeReference(view, model) {
return new MaskTreeReference(view, model);
}
export class ModelMapLayerTileTreeReference extends MapLayerTileTreeReference {
_classifier;
_source;
_id;
_owner;
get isPlanar() { return true; }
get activeClassifier() { return this._classifier; }
constructor(layerSettings, _classifier, layerIndex, iModel, _source) {
super(layerSettings, layerIndex, iModel);
this._classifier = _classifier;
this._source = _source;
this._id = {
modelId: _classifier.modelId,
is3d: true, // model.is3d,
treeId: this.createTreeId(),
isPlanProjection: false, // isPlanProjection(view, model),
};
this._owner = primaryTreeSupplier.getOwner(this._id, this.iModel);
}
createTreeId() {
return { type: BatchType.Primary, edges: false, disablePolyfaceDecimation: IModelApp.tileAdmin.disablePolyfaceDecimation };
}
get treeOwner() {
const newId = this.createTreeId();
if (0 !== compareIModelTileTreeIds(newId, this._id.treeId)) {
this._id = { modelId: this._id.modelId, is3d: this._id.is3d, treeId: newId, isPlanProjection: false };
this._owner = primaryTreeSupplier.getOwner(this._id, this.iModel);
}
return this._owner;
}
get viewFlags() {
return {
renderMode: RenderMode.SmoothShade,
transparency: true, // Igored for point clouds as they don't support transparency.
textures: true,
lighting: false,
shadows: false,
monochrome: false,
materials: false,
ambientOcclusion: false,
visibleEdges: true,
hiddenEdges: false,
fill: true,
};
}
}
export function createModelMapLayerTileTreeReference(layerSettings, layerIndex, iModel) {
const classifier = SpatialClassifier.fromModelMapLayer(layerSettings);
return classifier ? new ModelMapLayerTileTreeReference(layerSettings, classifier, layerIndex, iModel) : undefined;
}
/** @internal */
export function collectMaskRefs(view, modelIds, excludedModelIds, maskTreeRefs, maskRange) {
for (const modelId of modelIds) {
if (!excludedModelIds?.has(modelId)) {
const model = view.iModel.models.getLoaded(modelId);
assert(model !== undefined); // Models should be loaded by RealityModelTileTree
if (model?.asGeometricModel) {
const treeRef = createMaskTreeReference(view, model.asGeometricModel);
maskTreeRefs.push(treeRef);
const range = treeRef.computeWorldContentRange();
maskRange.extendRange(range);
}
}
}
}
/** Provides [[TileTreeReference]]s for the loaded models present in a [[SpatialViewState]]'s [[ModelSelectorState]] and
* not present in the optionally-supplied exclusion list.
* @internal
*/
export function createSpatialTileTreeReferences(view, excludedModels) {
return new SpatialRefs(view, excludedModels);
}
/** Provides [[TileTreeReference]]s for the loaded models present in a [[SpatialViewState]]'s [[ModelSelectorState]].
* @internal
*/
export var SpatialTileTreeReferences;
(function (SpatialTileTreeReferences) {
/** Create a SpatialTileTreeReferences object reflecting the contents of the specified view. */
function create(view) {
return createSpatialTileTreeReferences(view);
}
SpatialTileTreeReferences.create = create;
})(SpatialTileTreeReferences || (SpatialTileTreeReferences = {}));
/** Represents the [[TileTreeReference]]s associated with one model in a [[SpatialTileTreeReferences]]. */
class SpatialModelRefs {
/** The TileTreeReference representing the model's primary content. */
_modelRef;
/** TileTreeReferences representing nodes transformed by the view's schedule script. */
_animatedRefs = [];
/** TileTreeReference providing cut geometry intersecting the view's clip volume. */
_sectionCutRef;
/** Whether `this._modelRef` is a [[PrimaryTreeReference]] (as opposed to, e.g., a reality model tree reference). */
_isPrimaryRef;
/** Used to mark refs as excluded so that only their _sectionCutRef is returned by the iterator. */
_isExcluded;
constructor(model, view, excluded) {
this._modelRef = model.createTileTreeReference(view);
this._isPrimaryRef = this._modelRef instanceof PrimaryTreeReference;
this._isExcluded = excluded;
}
*[Symbol.iterator]() {
if ((!this._primaryRef || !this._primaryRef.deactivated) && !this._isExcluded)
yield this._modelRef;
for (const animated of this._animatedRefs)
if (!animated.deactivated)
yield animated;
if (this._sectionCutRef && !this._sectionCutRef.deactivated)
yield this._sectionCutRef;
}
updateAnimated(script) {
const ref = this._primaryRef;
if (!ref || this._isExcluded)
return;
this._animatedRefs.length = 0;
const nodeIds = script?.script.getTransformBatchIds(ref.model.id);
if (nodeIds)
for (const nodeId of nodeIds)
this._animatedRefs.push(new AnimatedTreeReference(ref.view, ref.model, nodeId));
}
updateSectionCut(clip) {
const ref = this._primaryRef;
if (!ref) {
assert(undefined === this._sectionCutRef);
return;
}
// If the clip isn't supposed to apply to this model, don't produce cut geometry.
const vfJson = clip ? ref.model.jsonProperties.viewFlagOverrides : undefined;
const vfOvrs = vfJson ? { ...vfJson } : undefined;
if (vfOvrs && !vfOvrs.clipVolume)
clip = undefined;
this._sectionCutRef = clip ? createTreeRef(ref.view, ref.model, clip) : undefined;
}
setDeactivated(deactivated, which) {
if (typeof which !== "string") {
for (const index of which)
if (this._animatedRefs[index])
this._animatedRefs[index].deactivated = deactivated ?? !this._animatedRefs[index].deactivated;
return;
}
if (("all" === which || "primary" === which) && this._primaryRef)
this._primaryRef.deactivated = deactivated ?? !this._primaryRef.deactivated;
if (("all" === which || "section" === which) && this._sectionCutRef)
this._sectionCutRef.deactivated = deactivated ?? !this._sectionCutRef.deactivated;
if (("all" === which || "animated" === which))
for (const ref of this._animatedRefs)
ref.deactivated = deactivated ?? !ref.deactivated;
}
get _primaryRef() {
if (!this._isPrimaryRef)
return undefined;
assert(this._modelRef instanceof PrimaryTreeReference);
return this._modelRef;
}
}
/** Provides [[TileTreeReference]]s for the loaded models present in a [[SpatialViewState]]'s [[ModelSelectorState]]. */
class SpatialRefs {
_allLoaded = false;
_view;
_excludedModels;
_refs = new Map();
_swapRefs = new Map();
_sectionCutOnlyRefs = new Map();
_swapSectionCutOnlyRefs = new Map();
_scheduleScript;
_sectionCut;
constructor(view, excludedModels) {
this._view = view;
this._scheduleScript = view.displayStyle[_scheduleScriptReference];
this._sectionCut = this.getSectionCutFromView();
if (excludedModels)
this._excludedModels = new Set(excludedModels);
}
update() {
this._allLoaded = false;
}
attachToViewport() { }
detachFromViewport() { }
*[Symbol.iterator]() {
this.load();
for (const modelRef of this._refs.values())
for (const ref of modelRef)
yield ref;
if (this._sectionCut) {
for (const modelRef of this._sectionCutOnlyRefs.values())
for (const ref of modelRef)
yield ref;
}
}
setDeactivated(modelIds, deactivated, refs) {
if (undefined === modelIds) {
for (const model of this._refs.values())
model.setDeactivated(deactivated, refs);
return;
}
if (typeof modelIds === "string")
modelIds = [modelIds];
for (const modelId of modelIds)
this._refs.get(modelId)?.setDeactivated(deactivated, refs);
}
/** For getting the [TileTreeReference]s that are in the modelIds, for planar classification.
* @param modelIds modelIds for which to get the TileTreeReferences
* @param maskTreeRefs where to store the TileTreeReferences
* @param maskRange range to extend for the maskRefs
*/
collectMaskRefs(modelIds, maskTreeRefs, maskRange) {
collectMaskRefs(this._view, modelIds, this._excludedModels, maskTreeRefs, maskRange);
}
/** For getting a list of modelIds which do not participate in masking, for planar classification.
* For non-batched tile trees this is not needed, so just return undefined.
*/
getModelsNotInMask(_maskModels, _useVisible) { return undefined; }
load() {
if (!this._allLoaded) {
this._allLoaded = true;
this.updateModels();
}
const curScript = this._view.displayStyle[_scheduleScriptReference];
const prevScript = this._scheduleScript;
if (curScript !== prevScript) {
this._scheduleScript = curScript;
if (!curScript || !prevScript || !curScript.script.equals(prevScript.script))
for (const ref of this._refs.values())
ref.updateAnimated(curScript);
}
const sectionCut = this.getSectionCutFromView();
if (sectionCut?.clipString !== this._sectionCut?.clipString) {
this._sectionCut = sectionCut;
for (const ref of this._refs.values())
ref.updateSectionCut(sectionCut);
for (const ref of this._sectionCutOnlyRefs.values())
ref.updateSectionCut(sectionCut);
}
}
getSectionCutFromView() {
const wantCut = this._view.viewFlags.clipVolume && this._view.displayStyle.settings.clipStyle.produceCutGeometry;
const clip = wantCut ? this._view.getViewClip() : undefined;
return StringifiedClipVector.fromClipVector(clip);
}
/** Ensure this._refs contains a SpatialModelRefs for all loaded models in the model selector. */
updateModels() {
let prev = this._refs;
let cur = this._swapRefs;
this._refs = cur;
this._swapRefs = prev;
cur.clear();
prev = this._sectionCutOnlyRefs;
cur = this._swapSectionCutOnlyRefs;
this._sectionCutOnlyRefs = cur;
this._swapSectionCutOnlyRefs = prev;
cur.clear();
for (const modelId of this._view.modelSelector.models) {
let excluded = false;
if (undefined !== this._excludedModels && this._excludedModels.has(modelId)) {
excluded = true;
cur = this._sectionCutOnlyRefs;
prev = this._swapSectionCutOnlyRefs;
}
else {
cur = this._refs;
prev = this._swapRefs;
}
let modelRefs = prev.get(modelId);
if (!modelRefs) {
const model = this._view.iModel.models.getLoaded(modelId)?.asGeometricModel3d;
if (model) {
modelRefs = new SpatialModelRefs(model, this._view, excluded);
modelRefs.updateAnimated(this._scheduleScript);
modelRefs.updateSectionCut(this._sectionCut);
}
}
if (modelRefs)
cur.set(modelId, modelRefs);
}
}
}
//# sourceMappingURL=PrimaryTileTree.js.map