UNPKG

@itwin/core-frontend

Version:
438 lines • 16.3 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module WebGL */ Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphicsArray = exports.WorldDecorations = exports.AnimationTransformBranch = exports.Branch = exports.Batch = exports.PerTargetData = exports.PerTargetBatchData = exports.GraphicOwner = exports.Graphic = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const core_geometry_1 = require("@itwin/core-geometry"); const FeatureSymbology_1 = require("../../../render/FeatureSymbology"); const GraphicBranch_1 = require("../../../render/GraphicBranch"); const RenderGraphic_1 = require("../../../render/RenderGraphic"); const EdgeSettings_1 = require("./EdgeSettings"); const FeatureOverrides_1 = require("./FeatureOverrides"); const PlanarClassifier_1 = require("./PlanarClassifier"); const TextureDrape_1 = require("./TextureDrape"); const ThematicSensors_1 = require("./ThematicSensors"); const Contours_1 = require("./Contours"); /** @internal */ class Graphic extends RenderGraphic_1.RenderGraphic { addHiliteCommands(_commands, _pass) { (0, core_bentley_1.assert)(false); } toPrimitive() { return undefined; } } exports.Graphic = Graphic; class GraphicOwner extends Graphic { _graphic; constructor(graphic) { super(); this._graphic = graphic; } get graphic() { return this._graphic; } _isDisposed = false; get isDisposed() { return this._isDisposed; } dispose() { this._isDisposed = true; } disposeGraphic() { this.graphic[Symbol.dispose](); } collectStatistics(stats) { this.graphic.collectStatistics(stats); } unionRange(range) { this.graphic.unionRange(range); } addCommands(commands) { this._graphic.addCommands(commands); } get isPickable() { return this._graphic.isPickable; } addHiliteCommands(commands, pass) { this._graphic.addHiliteCommands(commands, pass); } toPrimitive() { return this._graphic.toPrimitive(); } } exports.GraphicOwner = GraphicOwner; /** @internal exported strictly for tests. */ class PerTargetBatchData { target; _featureOverrides = new Map(); _contours; _thematicSensors; constructor(target) { this.target = target; } [Symbol.dispose]() { this._thematicSensors = (0, core_bentley_1.dispose)(this._thematicSensors); this._contours = this._contours?.[Symbol.dispose](); for (const value of this._featureOverrides.values()) (0, core_bentley_1.dispose)(value); this._featureOverrides.clear(); } getThematicSensors(batch) { if (this._thematicSensors && !this._thematicSensors.matchesTarget(this.target)) this._thematicSensors = (0, core_bentley_1.dispose)(this._thematicSensors); if (!this._thematicSensors) this._thematicSensors = ThematicSensors_1.ThematicSensors.create(this.target, batch.range); this._thematicSensors.update(this.target.uniforms.frustum.viewMatrix); return this._thematicSensors; } getFeatureOverrides(batch, provider) { const source = this.target.currentFeatureSymbologyOverrides?.source; let ovrs = this._featureOverrides.get(source); if (!ovrs) { const cleanup = source ? source.onSourceDisposed.addOnce(() => this.onSourceDisposed(source)) : undefined; this._featureOverrides.set(source, ovrs = FeatureOverrides_1.FeatureOverrides.createFromTarget(this.target, batch.options, cleanup)); ovrs.initFromMap(batch.featureTable, provider); } ovrs.update(batch.featureTable, provider); return ovrs; } getContours(batch) { if (this._contours && !this._contours.matchesTargetAndFeatureCount(this.target, batch.featureTable)) this._contours = this._contours[Symbol.dispose](); if (!this._contours) { this._contours = Contours_1.Contours.createFromTarget(this.target, batch.options); this._contours.initFromMap(batch.featureTable); } else { this._contours.update(batch.featureTable); } return this._contours; } collectStatistics(stats) { if (this._thematicSensors) stats.addThematicTexture(this._thematicSensors.bytesUsed); for (const ovrs of this._featureOverrides.values()) stats.addFeatureOverrides(ovrs.byteLength); if (this._contours) stats.addContours(this._contours.byteLength); } /** Exposed strictly for tests. */ get featureOverrides() { return this._featureOverrides; } onSourceDisposed(source) { const ovrs = this._featureOverrides.get(source); if (ovrs) { this._featureOverrides.delete(source); ovrs[Symbol.dispose](); } } } exports.PerTargetBatchData = PerTargetBatchData; /** @internal exported strictly for tests. */ class PerTargetData { _batch; _data = []; constructor(batch) { this._batch = batch; } [Symbol.dispose]() { for (const data of this._data) { data.target.onBatchDisposed(this._batch); data[Symbol.dispose](); } this._data.length = 0; } get isDisposed() { return this._data.length === 0; } /** Exposed strictly for tests. */ get data() { return this._data; } onTargetDisposed(target) { const index = this._data.findIndex((x) => x.target === target); if (-1 === index) return; const data = this._data[index]; data[Symbol.dispose](); this._data.splice(index, 1); } collectStatistics(stats) { for (const data of this._data) data.collectStatistics(stats); } getThematicSensors(target) { return this.getBatchData(target).getThematicSensors(this._batch); } getFeatureOverrides(target, provider) { return this.getBatchData(target).getFeatureOverrides(this._batch, provider); } getContours(target) { return this.getBatchData(target).getContours(this._batch); } getBatchData(target) { let data = this._data.find((x) => x.target === target); if (!data) { this._data.push(data = new PerTargetBatchData(target)); target.addBatch(this._batch); } return data; } } exports.PerTargetData = PerTargetData; /** @internal */ class Batch extends Graphic { graphic; featureTable; range; _context = { batchId: 0 }; /** Public strictly for tests. */ perTargetData = new PerTargetData(this); options; // Chiefly for debugging. get tileId() { return this.options.tileId; } get locateOnly() { return true === this.options.locateOnly; } /** The following are valid only during a draw and reset afterward. */ get batchId() { return this._context.batchId; } get batchIModel() { return this._context.iModel; } get transformFromBatchIModel() { return this._context.transformFromIModel; } get viewAttachmentId() { return this._context.viewAttachmentId; } get inSectionDrawingAttachment() { return this._context.inSectionDrawingAttachment; } setContext(batchId, branch) { this._context.batchId = batchId; this._context.iModel = branch.iModel; this._context.transformFromIModel = branch.transformFromIModel; this._context.viewAttachmentId = branch.viewAttachmentId; this._context.inSectionDrawingAttachment = branch.inSectionDrawingAttachment; } resetContext() { this._context.batchId = 0; this._context.iModel = undefined; this._context.transformFromIModel = undefined; this._context.viewAttachmentId = undefined; this._context.inSectionDrawingAttachment = undefined; } constructor(graphic, features, range, options) { super(); this.graphic = graphic; this.featureTable = features; this.range = range; this.options = options ?? {}; } _isDisposed = false; get isDisposed() { return this._isDisposed && this.perTargetData.isDisposed; } // Note: This does not remove FeatureOverrides from the array, but rather disposes of the WebGL resources they contain dispose() { (0, core_bentley_1.dispose)(this.graphic); this.perTargetData[Symbol.dispose](); this._isDisposed = true; } collectStatistics(stats) { this.graphic.collectStatistics(stats); stats.addFeatureTable(this.featureTable.byteLength); this.perTargetData.collectStatistics(stats); } unionRange(range) { range.extendRange(this.range); } addCommands(commands) { commands.addBatch(this); } get isPickable() { return true; } getThematicSensors(target) { (0, core_bentley_1.assert)(target.plan.thematic !== undefined, "thematic display settings must exist"); (0, core_bentley_1.assert)(target.plan.thematic.displayMode === core_common_1.ThematicDisplayMode.InverseDistanceWeightedSensors, "thematic display mode must be sensor-based"); (0, core_bentley_1.assert)(target.plan.thematic.sensorSettings.sensors.length > 0, "must have at least one sensor to process"); return this.perTargetData.getThematicSensors(target); } getOverrides(target, provider) { return this.perTargetData.getFeatureOverrides(target, provider); } getContours(target) { return this.perTargetData.getContours(target); } onTargetDisposed(target) { this.perTargetData.onTargetDisposed(target); } } exports.Batch = Batch; /** @internal */ class Branch extends Graphic { branch; localToWorldTransform; clips; planarClassifier; textureDrape; layerClassifiers; edgeSettings; iModel; // used chiefly for readPixels to identify context of picked Ids. frustum; appearanceProvider; secondaryClassifiers; viewAttachmentId; inSectionDrawingAttachment; disableClipStyle; transformFromExternalIModel; contourLine; constructor(branch, localToWorld, viewFlags, opts) { super(); this.branch = branch; this.localToWorldTransform = localToWorld; if (undefined !== viewFlags) branch.setViewFlags(viewFlags); if (!opts) return; this.appearanceProvider = opts.appearanceProvider; this.clips = opts.clipVolume; this.iModel = opts.iModel; this.frustum = opts.frustum; this.viewAttachmentId = opts.viewAttachmentId; this.inSectionDrawingAttachment = opts.inSectionDrawingAttachment; this.disableClipStyle = opts.disableClipStyle; this.transformFromExternalIModel = opts.transformFromIModel; this.contourLine = opts.contours; if (opts.hline) this.edgeSettings = EdgeSettings_1.EdgeSettings.create(opts.hline); if (opts.classifierOrDrape instanceof PlanarClassifier_1.PlanarClassifier) this.planarClassifier = opts.classifierOrDrape; else if (opts.classifierOrDrape instanceof TextureDrape_1.TextureDrape) this.textureDrape = opts.classifierOrDrape; if (opts.secondaryClassifiers) { this.secondaryClassifiers = new Array(); opts.secondaryClassifiers.forEach((classifier) => { if (classifier instanceof PlanarClassifier_1.PlanarClassifier) this.secondaryClassifiers?.push(classifier); }); } } get isDisposed() { return 0 === this.branch.entries.length; } dispose() { this.branch[Symbol.dispose](); } get isPickable() { return this.branch.entries.some((gf) => gf.isPickable); } collectStatistics(stats) { this.branch.collectStatistics(stats); } unionRange(range) { const thisRange = new core_geometry_1.Range3d(); for (const graphic of this.branch.entries) graphic.unionRange(thisRange); this.localToWorldTransform.multiplyRange(thisRange, thisRange); range.extendRange(thisRange); } shouldAddCommands(commands) { const group = commands.target.currentBranch.groupNodeId; if (undefined !== group && undefined !== this.branch.groupNodeId && this.branch.groupNodeId !== group) return false; const nodeId = commands.target.getAnimationTransformNodeId(this.branch.animationNodeId); return undefined === nodeId || nodeId === commands.target.currentAnimationTransformNodeId; } addCommands(commands) { if (this.shouldAddCommands(commands)) commands.addBranch(this); } addHiliteCommands(commands, pass) { if (this.shouldAddCommands(commands)) commands.addHiliteBranch(this, pass); } } exports.Branch = Branch; /** @internal */ class AnimationTransformBranch extends Graphic { nodeId; graphic; constructor(graphic, nodeId) { super(); (0, core_bentley_1.assert)(graphic instanceof Graphic); this.graphic = graphic; this.nodeId = nodeId; } dispose() { this.graphic[Symbol.dispose](); } get isDisposed() { return this.graphic.isDisposed; } get isPickable() { return this.graphic.isPickable; } collectStatistics(stats) { this.graphic.collectStatistics(stats); } unionRange(range) { this.graphic.unionRange(range); } addCommands(commands) { commands.target.currentAnimationTransformNodeId = this.nodeId; this.graphic.addCommands(commands); commands.target.currentAnimationTransformNodeId = undefined; } addHiliteCommands(commands, pass) { commands.target.currentAnimationTransformNodeId = this.nodeId; this.graphic.addHiliteCommands(commands, pass); commands.target.currentAnimationTransformNodeId = undefined; } } exports.AnimationTransformBranch = AnimationTransformBranch; /** @internal */ class WorldDecorations extends Branch { constructor(viewFlags) { super(new GraphicBranch_1.GraphicBranch(), core_geometry_1.Transform.identity, viewFlags); // World decorations ignore all the symbology overrides for the "scene" geometry... this.branch.symbologyOverrides = new FeatureSymbology_1.FeatureSymbology.Overrides(); // Make all subcategories visible. this.branch.symbologyOverrides.ignoreSubCategory = true; } init(decs) { this.branch.clear(); for (const dec of decs) { this.branch.add(dec); } } } exports.WorldDecorations = WorldDecorations; /** @internal */ class GraphicsArray extends Graphic { graphics; // Note: We assume the graphics array we get contains undisposed graphics to start constructor(graphics) { super(); this.graphics = graphics; } get isDisposed() { return 0 === this.graphics.length; } get isPickable() { return this.graphics.some((x) => x.isPickable); } dispose() { for (const graphic of this.graphics) (0, core_bentley_1.dispose)(graphic); this.graphics.length = 0; } addCommands(commands) { for (const graphic of this.graphics) { graphic.addCommands(commands); } } addHiliteCommands(commands, pass) { for (const graphic of this.graphics) { graphic.addHiliteCommands(commands, pass); } } collectStatistics(stats) { for (const graphic of this.graphics) graphic.collectStatistics(stats); } unionRange(range) { for (const graphic of this.graphics) graphic.unionRange(range); } } exports.GraphicsArray = GraphicsArray; //# sourceMappingURL=Graphic.js.map