@itwin/core-frontend
Version:
iTwin.js frontend components
122 lines • 7.15 kB
JavaScript
"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 Views
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlanarClipMaskState = void 0;
const core_common_1 = require("@itwin/core-common");
const FeatureSymbology_1 = require("./render/FeatureSymbology");
const core_geometry_1 = require("@itwin/core-geometry");
/** The State of Planar Clip Mask applied to a reality model or background map.
* Handles loading models and their associated tiles for models that are used by masks but may not be otherwise loaded or displayed.
* @beta
*/
class PlanarClipMaskState {
settings;
_tileTreeRefs;
_allLoaded = false;
_usingViewportOverrides = false;
_overridesModelVisibility = false;
_maskRange = core_geometry_1.Range3d.createNull();
constructor(settings) {
this.settings = settings;
}
static create(settings) {
return new PlanarClipMaskState(settings);
}
static fromJSON(props) {
return this.create(core_common_1.PlanarClipMaskSettings.fromJSON(props));
}
get usingViewportOverrides() { return this._usingViewportOverrides; }
;
/** @internal */
get overridesModelVisibility() { return this._overridesModelVisibility; }
discloseTileTrees(trees) {
if (this._tileTreeRefs)
this._tileTreeRefs.forEach((treeRef) => treeRef.discloseTileTrees(trees));
}
// Returns the TileTreeReferences for the models that need to be drawn to create the planar clip mask, and extend the maskRange if needed.
getTileTrees(context, classifiedModelId, maskRange) {
if (this.settings.mode === core_common_1.PlanarClipMaskMode.Priority) {
// For priority mode we simply want refs for all viewed models if the priority is higher than the mask priority.
// For this case, we don't need a maskRange so leave it as null.
const viewTrees = new Array();
const thisPriority = this.settings.priority === undefined ? core_common_1.PlanarClipMaskPriority.RealityModel : this.settings.priority;
for (const ref of context.viewport.getTileTreeRefs()) {
const tree = ref.treeOwner.load();
if (tree && tree.modelId !== classifiedModelId && ref.planarClipMaskPriority > thisPriority)
viewTrees.push(ref);
}
return viewTrees;
}
// For all other modes we need to let the tree refs in the view state decide which refs need to be drawn
// since batched tiles cannot turn on/off individual models just by their tile tree refs.
// Keep calling this until loaded so that the range is valid.
if (!this._allLoaded) {
this._tileTreeRefs = new Array();
if (this.settings.modelIds && context.viewport.view.isSpatialView()) {
context.viewport.view.collectMaskRefs(this.settings.modelIds, this._tileTreeRefs, maskRange);
}
this._allLoaded = this._tileTreeRefs.every((treeRef) => treeRef.treeOwner.load() !== undefined);
maskRange.clone(this._maskRange);
}
else // If already loaded, just set the maskRange to the saved maskRange.
this._maskRange.clone(maskRange);
return this._allLoaded ? this._tileTreeRefs : undefined;
}
// Returns any potential FeatureSymbology overrides for drawing the planar clip mask.
getPlanarClipMaskSymbologyOverrides(context, featureSymbologySource) {
this._usingViewportOverrides = this._overridesModelVisibility = false;
// First obtain a list of models that will need to be turned off for drawing the planar clip mask (only used for batched tile trees).
const overrideModels = context.viewport.view.isSpatialView() ? context.viewport.view.getModelsNotInMask(this.settings.modelIds, core_common_1.PlanarClipMaskMode.Priority === this.settings.mode) : undefined;
const noSubCategoryOrElementIds = !this.settings.subCategoryOrElementIds;
if (noSubCategoryOrElementIds && !overrideModels)
return undefined;
const ovrBasedOnContext = core_common_1.PlanarClipMaskMode.Priority === this.settings.mode || core_common_1.PlanarClipMaskMode.Models === this.settings.mode || noSubCategoryOrElementIds;
const viewport = overrideModels && ovrBasedOnContext ? context.viewport : undefined;
const overrides = FeatureSymbology_1.FeatureSymbology.Overrides.withSource(featureSymbologySource, viewport);
if (overrideModels) {
this._overridesModelVisibility = true;
// overrideModels is used for batched models. For those, we need to create model overrides to turn off models that are
// not wanted in the mask (using transparency) no matter what mask mode is being used.
const appOff = core_common_1.FeatureAppearance.fromTransparency(1.0);
// For Priority or Models mode, we need to start with the current overrides and modify them
if (ovrBasedOnContext) {
this._usingViewportOverrides = true; // Set flag to use listener since context.viewport might change afterwards.
overrides.addInvisibleElementOverridesToNeverDrawn(); // need this for fully trans element overrides to not participate in mask
overrideModels.forEach((modelId) => {
overrides.override({ modelId, appearance: appOff, onConflict: "replace" });
});
return overrides;
}
// Otherwise, we just start with a default overrides and modify it.
overrideModels.forEach((modelId) => {
overrides.override({ modelId, appearance: appOff, onConflict: "replace" });
});
}
// Add overrides to turn things on or off based on the subcategories or elements in the mask settings.
switch (this.settings.mode) {
case core_common_1.PlanarClipMaskMode.IncludeElements: {
overrides.setAlwaysDrawnSet(this.settings.subCategoryOrElementIds ?? [], true);
return overrides;
}
case core_common_1.PlanarClipMaskMode.ExcludeElements: {
overrides.ignoreSubCategory = true;
overrides.setNeverDrawnSet(this.settings.subCategoryOrElementIds ?? []);
return overrides;
}
case core_common_1.PlanarClipMaskMode.IncludeSubCategories: {
for (const subCategoryId of this.settings.subCategoryOrElementIds ?? [])
overrides.setVisibleSubCategory(subCategoryId);
return overrides;
}
}
return undefined;
}
}
exports.PlanarClipMaskState = PlanarClipMaskState;
//# sourceMappingURL=PlanarClipMaskState.js.map