@itwin/core-frontend
Version:
iTwin.js frontend components
558 lines • 28.4 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.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlanarClassifier = exports.PlanarClassifierContent = void 0;
/** @packageDocumentation
* @module WebGL
*/
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 internal_1 = require("../../../tile/internal");
const RenderPlanarClassifier_1 = require("../RenderPlanarClassifier");
const BatchState_1 = require("./BatchState");
const BranchStack_1 = require("./BranchStack");
const CachedGeometry_1 = require("./CachedGeometry");
const FrameBuffer_1 = require("./FrameBuffer");
const GL_1 = require("./GL");
const Graphic_1 = require("./Graphic");
const PlanarTextureProjection_1 = require("./PlanarTextureProjection");
const RenderCommands_1 = require("./RenderCommands");
const RenderState_1 = require("./RenderState");
const ScratchDrawParams_1 = require("./ScratchDrawParams");
const System_1 = require("./System");
const Texture_1 = require("./Texture");
var PlanarClassifierContent;
(function (PlanarClassifierContent) {
PlanarClassifierContent[PlanarClassifierContent["None"] = 0] = "None";
PlanarClassifierContent[PlanarClassifierContent["MaskOnly"] = 1] = "MaskOnly";
PlanarClassifierContent[PlanarClassifierContent["ClassifierOnly"] = 2] = "ClassifierOnly";
PlanarClassifierContent[PlanarClassifierContent["ClassifierAndMask"] = 3] = "ClassifierAndMask";
})(PlanarClassifierContent || (exports.PlanarClassifierContent = PlanarClassifierContent = {}));
function createTexture(handle) {
return new Texture_1.Texture({
handle,
ownership: "external",
type: core_common_1.RenderTexture.Type.TileSection,
transparency: core_common_1.TextureTransparency.Opaque,
});
}
function createTextureHandle(width, height, heightMult = 1.0) {
return Texture_1.TextureHandle.createForAttachment(width, height * heightMult, GL_1.GL.Texture.Format.Rgba, GL_1.GL.Texture.DataType.UnsignedByte);
}
class ClassifierTextures {
color;
feature;
hilite;
constructor(color, feature, hilite) {
this.color = color;
this.feature = feature;
this.hilite = hilite;
}
get isDisposed() {
return this.color.isDisposed
&& this.feature.isDisposed
&& this.hilite.isDisposed;
}
[Symbol.dispose]() {
(0, core_bentley_1.dispose)(this.color);
(0, core_bentley_1.dispose)(this.feature);
(0, core_bentley_1.dispose)(this.hilite);
}
collectStatistics(stats) {
stats.addPlanarClassifier(this.color.bytesUsed);
stats.addPlanarClassifier(this.feature.bytesUsed);
stats.addPlanarClassifier(this.hilite.bytesUsed);
}
static create(width, height) {
const hColor = createTextureHandle(width, height);
const hFeature = createTextureHandle(width, height);
const hHilite = createTextureHandle(width, height);
if (!hColor || !hFeature || !hHilite)
return undefined;
const color = createTexture(hColor);
const feature = createTexture(hFeature);
const hilite = createTexture(hHilite);
if (!color || !feature || !hilite)
return undefined;
return new ClassifierTextures(color, feature, hilite);
}
}
class ClassifierFrameBuffers {
textures;
_hilite;
_fbo;
_clearGeom;
constructor(textures, _hilite, _fbo, _clearGeom) {
this.textures = textures;
this._hilite = _hilite;
this._fbo = _fbo;
this._clearGeom = _clearGeom;
}
get isDisposed() {
return this.textures.isDisposed && this._hilite.isDisposed && this._fbo.isDisposed && this._clearGeom.isDisposed;
}
[Symbol.dispose]() {
(0, core_bentley_1.dispose)(this._fbo);
(0, core_bentley_1.dispose)(this._clearGeom);
(0, core_bentley_1.dispose)(this.textures);
(0, core_bentley_1.dispose)(this._hilite);
}
draw(cmds, target) {
System_1.System.instance.frameBufferStack.execute(this._fbo, true, false, () => {
target.techniques.draw((0, ScratchDrawParams_1.getDrawParams)(target, this._clearGeom));
target.techniques.execute(target, cmds, 19 /* RenderPass.PlanarClassification */);
});
}
drawHilite(cmds, target) {
const system = System_1.System.instance;
const gl = system.context;
system.frameBufferStack.execute(this._hilite, true, false, () => {
gl.clearColor(0, 0, 0, 0);
gl.clear(GL_1.GL.BufferBit.Color);
target.techniques.execute(target, cmds, 10 /* RenderPass.Hilite */);
});
}
static create(width, height) {
const textures = ClassifierTextures.create(width, height);
if (undefined === textures)
return undefined;
const hiliteFbo = FrameBuffer_1.FrameBuffer.create([textures.hilite.texture]);
if (undefined === hiliteFbo)
return undefined;
const fbo = FrameBuffer_1.FrameBuffer.create([textures.color.texture, textures.feature.texture]);
if (undefined === fbo)
return undefined;
const geom = CachedGeometry_1.ViewportQuadGeometry.create(21 /* TechniqueId.ClearPickAndColor */);
return undefined !== geom ? new this(textures, hiliteFbo, fbo, geom) : undefined;
}
}
class SingleTextureFrameBuffer {
texture;
fbo;
get isDisposed() { return this.texture.isDisposed && this.fbo.isDisposed; }
collectStatistics(stats) { stats.addPlanarClassifier(this.texture.bytesUsed); }
constructor(textureAndFbo) {
this.texture = textureAndFbo.texture;
this.fbo = textureAndFbo.fbo;
}
[Symbol.dispose]() {
(0, core_bentley_1.dispose)(this.texture);
(0, core_bentley_1.dispose)(this.fbo);
}
static createTextureAndFrameBuffer(width, height) {
const hTexture = Texture_1.TextureHandle.createForAttachment(width, height, GL_1.GL.Texture.Format.Rgba, GL_1.GL.Texture.DataType.UnsignedByte);
if (!hTexture)
return undefined;
const texture = new Texture_1.Texture({ type: core_common_1.RenderTexture.Type.TileSection, ownership: "external", handle: hTexture, transparency: core_common_1.TextureTransparency.Opaque });
if (!texture)
return undefined;
const fbo = FrameBuffer_1.FrameBuffer.create([texture.texture]);
if (undefined === fbo)
return undefined;
return { texture, fbo };
}
}
class MaskFrameBuffer extends SingleTextureFrameBuffer {
static create(width, height) {
const textureFbo = SingleTextureFrameBuffer.createTextureAndFrameBuffer(width, height);
return undefined === textureFbo ? undefined : new MaskFrameBuffer(textureFbo);
}
draw(cmds, target) {
const system = System_1.System.instance;
const gl = system.context;
system.frameBufferStack.execute(this.fbo, true, false, () => {
gl.clearColor(0, 0, 0, 0);
gl.clear(GL_1.GL.BufferBit.Color);
target.techniques.execute(target, cmds, 19 /* RenderPass.PlanarClassification */);
});
}
}
class CombineTexturesFrameBuffer extends SingleTextureFrameBuffer {
_combineGeom;
_width;
_height;
_heightMult;
constructor(textureAndFbo, _combineGeom, _width, _height, _heightMult) {
super(textureAndFbo);
this._combineGeom = _combineGeom;
this._width = _width;
this._height = _height;
this._heightMult = _heightMult;
}
compose(target) {
const system = System_1.System.instance;
const gl = system.context;
system.context.viewport(0, 0, this._width, this._heightMult * this._height);
system.frameBufferStack.execute(this.fbo, true, false, () => {
gl.clearColor(0, 0, 0, 0);
gl.clear(GL_1.GL.BufferBit.Color);
target.techniques.draw((0, ScratchDrawParams_1.getDrawParams)(target, this._combineGeom));
});
}
}
class ClassifierCombinationBuffer extends CombineTexturesFrameBuffer {
static create(width, height, classifierColor, classifierFeature) {
const combineGeom = CachedGeometry_1.CombineTexturesGeometry.createGeometry(classifierColor.texture.getHandle(), classifierFeature.texture.getHandle());
if (undefined === combineGeom)
return undefined;
const textureFbo = SingleTextureFrameBuffer.createTextureAndFrameBuffer(width, 2 * height);
return undefined === textureFbo ? undefined : new ClassifierCombinationBuffer(textureFbo, combineGeom, width, height, 2);
}
}
class ClassifierAndMaskCombinationBuffer extends CombineTexturesFrameBuffer {
static create(width, height, classifierColor, classifierFeature, mask) {
const combineGeom = CachedGeometry_1.Combine3TexturesGeometry.createGeometry(classifierColor.texture.getHandle(), classifierFeature.texture.getHandle(), mask.texture.getHandle());
if (undefined === combineGeom)
return undefined;
const textureFbo = SingleTextureFrameBuffer.createTextureAndFrameBuffer(width, 3 * height);
return undefined === textureFbo ? undefined : new ClassifierAndMaskCombinationBuffer(textureFbo, combineGeom, width, height, 3);
}
}
const scratchPrevRenderState = new RenderState_1.RenderState();
/** @internal */
class PlanarClassifier extends RenderPlanarClassifier_1.RenderPlanarClassifier {
_classifierBuffers;
_maskBuffer;
_classifierCombinedBuffer;
_classifierAndMaskCombinedBuffer;
_projectionMatrix = core_geometry_1.Matrix4d.createIdentity();
_graphics;
_classifierGraphics = [];
_maskGraphics = [];
_frustum;
_width = 0;
_height = 0;
_baseBatchId = 0;
_anyHilited = false;
_anyOpaque = false;
_anyTranslucent = false;
_classifier;
_plane = core_geometry_1.Plane3dByOriginAndUnitNormal.create(new core_geometry_1.Point3d(0, 0, 0), new core_geometry_1.Vector3d(0, 0, 1)); // TBD -- Support other planes - default to X-Y for now.
_renderState = new RenderState_1.RenderState();
_renderCommands;
_branchStack = new BranchStack_1.BranchStack();
_batchState;
_planarClipMask;
_classifierTreeRef;
_planarClipMaskOverrides;
_contentMode = PlanarClassifierContent.None;
_removeMe;
_featureSymbologySource = {
onSourceDisposed: new core_bentley_1.BeEvent(),
};
;
static _postProjectionMatrix = core_geometry_1.Matrix4d.createRowValues(0, 1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 1);
_debugFrustum;
_doDebugFrustum = false;
_debugFrustumGraphic = undefined;
_isClassifyingPointCloud; // we will detect this the first time we draw
_bgColor = core_common_1.ColorDef.from(0, 0, 0, 255);
constructor(classifier, target) {
super();
this._classifier = classifier;
const flags = this._renderState.flags;
flags.depthMask = flags.blend = flags.depthTest = false;
this._batchState = new BatchState_1.BatchState(this._branchStack);
this._renderCommands = new RenderCommands_1.RenderCommands(target, this._branchStack, this._batchState);
}
get textureImageCount() { return this._contentMode; }
getParams(params) {
params[0] = this.insideDisplay;
params[1] = this.outsideDisplay;
params[2] = this._contentMode;
if (this._planarClipMask?.settings.invert) // If the mask sense is inverted, negate the contentMode to indicate this to the shader.
params[2] = -params[2];
params[3] = (this._planarClipMask?.settings.transparency === undefined) ? -1 : this._planarClipMask.settings.transparency;
}
get hiliteTexture() { return undefined !== this._classifierBuffers ? this._classifierBuffers.textures.hilite : undefined; }
get projectionMatrix() { return this._projectionMatrix; }
// public get properties(): SpatialClassifier { return this._classifier; }
get baseBatchId() { return this._baseBatchId; }
get anyHilited() { return this._anyHilited; }
get anyOpaque() { return this._anyOpaque; }
get anyTranslucent() { return this._anyTranslucent; }
get insideDisplay() { return this._classifier ? this._classifier.flags.inside : core_common_1.SpatialClassifierInsideDisplay.Off; }
get outsideDisplay() { return this._classifier ? this._classifier.flags.outside : core_common_1.SpatialClassifierOutsideDisplay.On; }
get isClassifyingPointCloud() { return true === this._isClassifyingPointCloud; }
addGraphic(graphic) {
this._graphics.push(graphic);
}
static create(properties, target) {
return new PlanarClassifier(properties, target);
}
collectStatistics(stats) {
if (undefined !== this._classifierBuffers)
this._classifierBuffers.textures.collectStatistics(stats);
if (undefined !== this._maskBuffer)
this._maskBuffer.collectStatistics(stats);
if (undefined !== this._classifierCombinedBuffer)
this._classifierCombinedBuffer.collectStatistics(stats);
if (undefined !== this._classifierAndMaskCombinedBuffer)
this._classifierAndMaskCombinedBuffer.collectStatistics(stats);
}
get isDisposed() { return undefined === this._classifierBuffers; }
[Symbol.dispose]() {
this._classifierBuffers = (0, core_bentley_1.dispose)(this._classifierBuffers);
this._maskBuffer = (0, core_bentley_1.dispose)(this._maskBuffer);
this._classifierCombinedBuffer = (0, core_bentley_1.dispose)(this._classifierCombinedBuffer);
this._classifierAndMaskCombinedBuffer = (0, core_bentley_1.dispose)(this._classifierAndMaskCombinedBuffer);
if (this._removeMe) {
this._removeMe();
this._removeMe = undefined;
}
this._featureSymbologySource.onSourceDisposed.raiseEvent();
}
get texture() {
switch (this._contentMode) {
case PlanarClassifierContent.None:
return undefined;
case PlanarClassifierContent.ClassifierOnly:
return this._classifierCombinedBuffer?.texture;
case PlanarClassifierContent.MaskOnly:
return this._maskBuffer?.texture;
case PlanarClassifierContent.ClassifierAndMask:
return this._classifierAndMaskCombinedBuffer?.texture;
}
}
getOrCreateClassifierTexture() {
if (undefined === this._classifierBuffers)
this._classifierBuffers = ClassifierFrameBuffers.create(this._width, this._height);
if (undefined !== this._classifierBuffers && undefined === this._classifierCombinedBuffer)
this._classifierCombinedBuffer = ClassifierCombinationBuffer.create(this._width, this._height, this._classifierBuffers.textures.color, this._classifierBuffers.textures.feature);
return this._classifierCombinedBuffer?.texture;
}
pushBatches(batchState, graphics) {
graphics.forEach((graphic) => {
if (graphic instanceof Graphic_1.Batch) {
batchState.push(graphic, true);
batchState.pop();
}
else if (graphic instanceof Graphic_1.Branch) {
this.pushBatches(batchState, graphic.branch.entries);
}
});
}
get sourceTransparency() {
return this._classifierTreeRef?.transparency;
}
pushBatchState(batchState) {
this._baseBatchId = batchState.nextBatchId - 1;
if (undefined !== this._classifierGraphics)
this.pushBatches(batchState, this._classifierGraphics);
}
setSource(classifierTreeRef, planarClipMask) {
this._classifierTreeRef = classifierTreeRef;
this._classifier = classifierTreeRef?.activeClassifier;
this._planarClipMask = planarClipMask;
}
collectGraphics(context, target) {
this._classifierGraphics.length = this._maskGraphics.length = 0;
if (undefined === context.viewingSpace)
return;
const viewState = context.viewingSpace.view;
if (!viewState.isSpatialView())
return;
this._doDebugFrustum = context.target.debugControl?.displayMaskFrustum ?? false;
const maxTextureSize = System_1.System.instance.maxTexSizeAllow;
const requiredHeight = maxTextureSize;
const requiredWidth = maxTextureSize;
if (requiredWidth !== this._width || requiredHeight !== this._height)
this[Symbol.dispose]();
this._width = requiredWidth;
this._height = requiredHeight;
const maskRange = core_geometry_1.Range3d.createNull();
const maskTrees = this._planarClipMask?.getTileTrees(context, target.modelId, maskRange);
if (!maskTrees && !this._classifierTreeRef)
return;
const allTrees = maskTrees ? maskTrees.slice() : new Array();
if (this._classifierTreeRef)
allTrees.push(this._classifierTreeRef);
const projection = PlanarTextureProjection_1.PlanarTextureProjection.computePlanarTextureProjection(this._plane, context, target, allTrees, viewState, this._width, this._height, maskRange);
if (!projection.textureFrustum || !projection.projectionMatrix || !projection.worldToViewMap)
return;
this._projectionMatrix = projection.projectionMatrix;
this._frustum = projection.textureFrustum;
this._debugFrustum = projection.debugFrustum;
this._planarClipMaskOverrides = this._planarClipMask?.getPlanarClipMaskSymbologyOverrides(context, this._featureSymbologySource);
if (!this._planarClipMask?.usingViewportOverrides && this._removeMe) {
this._removeMe();
this._removeMe = undefined;
}
else if (this._planarClipMask?.usingViewportOverrides && !this._removeMe) {
this._removeMe = context.viewport.onFeatureOverridesChanged.addListener(() => {
this._planarClipMaskOverrides = this._planarClipMask?.getPlanarClipMaskSymbologyOverrides(context, this._featureSymbologySource);
context.viewport.requestRedraw();
});
}
const drawTree = (treeRef, graphics) => {
this._graphics = graphics;
const frustumPlanes = this._frustum ? core_common_1.FrustumPlanes.fromFrustum(this._frustum) : core_common_1.FrustumPlanes.createEmpty();
const drawArgs = internal_1.GraphicsCollectorDrawArgs.create(context, this, treeRef, frustumPlanes, projection.worldToViewMap);
if (undefined !== drawArgs)
treeRef.draw(drawArgs);
this._graphics = undefined;
};
if (this._classifierTreeRef)
drawTree(this._classifierTreeRef, this._classifierGraphics);
if (maskTrees)
maskTrees.forEach((maskTree) => drawTree(maskTree, this._maskGraphics));
// Shader behaves slightly differently when classifying surfaces vs point clouds.
this._isClassifyingPointCloud = target.isPointCloud;
if (this._doDebugFrustum) {
this._debugFrustumGraphic = (0, core_bentley_1.dispose)(this._debugFrustumGraphic);
const builder = context.createSceneGraphicBuilder();
builder.setSymbology(core_common_1.ColorDef.green, core_common_1.ColorDef.green, 2);
builder.addFrustum(context.viewingSpace.getFrustum());
builder.setSymbology(core_common_1.ColorDef.red, core_common_1.ColorDef.red, 2);
builder.addFrustum(this._debugFrustum);
builder.setSymbology(core_common_1.ColorDef.blue, core_common_1.ColorDef.blue, 2);
builder.addFrustum(this._frustum);
builder.setSymbology(core_common_1.ColorDef.from(0, 200, 0, 222), core_common_1.ColorDef.from(0, 200, 0, 222), 2);
builder.addFrustumSides(context.viewingSpace.getFrustum());
builder.setSymbology(core_common_1.ColorDef.from(200, 0, 0, 222), core_common_1.ColorDef.from(200, 0, 0, 222), 2);
builder.addFrustumSides(this._debugFrustum);
builder.setSymbology(core_common_1.ColorDef.from(0, 0, 200, 222), core_common_1.ColorDef.from(0, 0, 200, 222), 2);
builder.addFrustumSides(this._frustum);
this._debugFrustumGraphic = builder.finish();
context.outputGraphic(this._debugFrustumGraphic);
}
}
draw(target) {
if (undefined === this._frustum)
return;
this._contentMode = PlanarClassifierContent.None;
let combinationBuffer;
if (this._classifierGraphics.length === 0) {
if (this._maskGraphics.length === 0) {
return;
}
else {
if (undefined === this._maskBuffer) {
this._maskBuffer = MaskFrameBuffer.create(this._width, this._height);
if (undefined === this._maskBuffer)
return;
}
this._contentMode = PlanarClassifierContent.MaskOnly;
}
}
else {
if (undefined === this._classifierBuffers) {
this._classifierBuffers = ClassifierFrameBuffers.create(this._width, this._height);
if (undefined === this._classifierBuffers)
return;
}
if (this._maskGraphics.length === 0) {
if (undefined === this._classifierCombinedBuffer) {
combinationBuffer = this._classifierCombinedBuffer = ClassifierCombinationBuffer.create(this._width, this._height, this._classifierBuffers.textures.color, this._classifierBuffers.textures.feature);
if (undefined === this._classifierCombinedBuffer)
return;
}
this._contentMode = PlanarClassifierContent.ClassifierOnly;
combinationBuffer = this._classifierCombinedBuffer;
}
else {
if (undefined === this._maskBuffer) {
this._maskBuffer = MaskFrameBuffer.create(this._width, this._height);
if (undefined === this._maskBuffer)
return;
}
if (undefined === this._classifierAndMaskCombinedBuffer) {
combinationBuffer = this._classifierAndMaskCombinedBuffer = ClassifierAndMaskCombinationBuffer.create(this._width, this._height, this._classifierBuffers.textures.color, this._classifierBuffers.textures.feature, this._maskBuffer.texture);
if (undefined === this._classifierAndMaskCombinedBuffer)
return;
}
combinationBuffer = this._classifierAndMaskCombinedBuffer;
this._contentMode = PlanarClassifierContent.ClassifierAndMask;
}
}
// Temporarily override the Target's state.
const system = System_1.System.instance;
const maskViewFlags = {
renderMode: core_common_1.RenderMode.SmoothShade,
wiremesh: false,
transparency: !this.isClassifyingPointCloud, // point clouds don't support transparency.
textures: false,
lighting: false,
shadows: false,
monochrome: false,
materials: false,
ambientOcclusion: false,
visibleEdges: false,
hiddenEdges: false,
};
const prevState = system.currentRenderState.clone(scratchPrevRenderState);
system.context.viewport(0, 0, this._width, this._height);
const vf = target.currentViewFlags.copy(this._classifierTreeRef ? this._classifierTreeRef.viewFlags : maskViewFlags);
system.applyRenderState(this._renderState);
const prevPlan = target.plan;
const prevOverrides = target.currentFeatureSymbologyOverrides;
target.uniforms.style.changeBackgroundColor(this._bgColor); // Avoid white on white reversal. Will be reset in changeRenderPlan below.
target.changeFrustum(this._frustum, this._frustum.getFraction(), true);
this._anyTranslucent = false;
const prevProjMatrix = target.uniforms.frustum.projectionMatrix;
target.uniforms.frustum.changeProjectionMatrix(PlanarClassifier._postProjectionMatrix.multiplyMatrixMatrix(prevProjMatrix));
target.uniforms.branch.changeRenderPlan(vf, target.plan.is3d, target.plan.hline);
const addCmds = (oldCmds, newCmds) => {
if (undefined === newCmds)
return oldCmds;
if (newCmds.length > 50000) {
// This method is slower for smaller array sizes, but when the size of newCmds gets larger it's performance is ok.
return oldCmds.concat(newCmds);
}
else {
// This method runs faster, but gets a stack overflow when the size of newCmds is too large.
oldCmds.push(...newCmds);
return oldCmds;
}
};
const renderCommands = this._renderCommands;
const getDrawCommands = (graphics) => {
this._batchState.reset();
renderCommands.reset(target, this._branchStack, this._batchState);
renderCommands.collectGraphicsForPlanarProjection(graphics);
// Draw the classifiers into our attachments.
// When using Display.ElementColor, the color and transparency come from the classifier geometry. Therefore we may need to draw the classified geometry
// in a different pass - or both passes - depending on the transparency of the classifiers.
// NB: "Outside" geometry by definition cannot take color/transparency from element...
let cmds = renderCommands.getCommands(3 /* RenderPass.OpaquePlanar */);
// NB: We don't strictly require the classifier geometry to be planar, and sometimes (e.g., "planar" polyface/bspsurf) we do not detect planarity.
cmds = addCmds(cmds, renderCommands.getCommands(5 /* RenderPass.OpaqueGeneral */));
cmds = addCmds(cmds, renderCommands.getCommands(2 /* RenderPass.OpaqueLinear */));
this._anyOpaque = cmds.length > 0;
const transCmds = renderCommands.getCommands(8 /* RenderPass.Translucent */);
if (transCmds.length > 0) {
cmds = addCmds(cmds, renderCommands.getCommands(8 /* RenderPass.Translucent */));
this._anyTranslucent = true;
}
return cmds;
};
if (this._classifierGraphics.length > 0 && this._classifierBuffers) {
this._classifierBuffers.draw(getDrawCommands(this._classifierGraphics), target);
// Draw any hilited classifiers.
const hiliteCommands = renderCommands.getCommands(10 /* RenderPass.Hilite */);
this._anyHilited = 0 !== hiliteCommands.length;
if (this._anyHilited)
this._classifierBuffers.drawHilite(hiliteCommands, target);
}
if (this._maskGraphics.length > 0 && this._maskBuffer) {
if (this._planarClipMaskOverrides)
target.overrideFeatureSymbology(this._planarClipMaskOverrides);
if (this._planarClipMask && this._planarClipMask.settings.transparency !== undefined && this._planarClipMask.settings.transparency > 0.0)
this._anyTranslucent = true;
this._maskBuffer.draw(getDrawCommands(this._maskGraphics), target);
}
if (combinationBuffer)
combinationBuffer.compose(target);
this._batchState.reset();
target.changeRenderPlan(prevPlan);
target.overrideFeatureSymbology(prevOverrides);
system.applyRenderState(prevState);
system.context.viewport(0, 0, target.viewRect.width, target.viewRect.height);
}
}
exports.PlanarClassifier = PlanarClassifier;
//# sourceMappingURL=PlanarClassifier.js.map