/*---------------------------------------------------------------------------------------------
* 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
 */
import { dispose } from "@itwin/core-bentley";
import { SurfaceType } from "../../common/internal/render/SurfaceParams";
import { Graphic } from "./Graphic";
import { Primitive } from "./Primitive";
import { EdgeGeometry, PolylineEdgeGeometry, SilhouetteEdgeGeometry } from "./EdgeGeometry";
import { IndexedEdgeGeometry } from "./IndexedEdgeGeometry";
import { SurfaceGeometry } from "./SurfaceGeometry";
import { MeshData } from "./MeshData";
/** @internal */
export class MeshRenderGeometry {
    constructor(data, params) {
        this.renderGeometryType = "mesh";
        this.noDispose = false;
        this.data = data;
        this.isInstanceable = data.viewIndependentOrigin === undefined;
        this.range = params.vertices.qparams.computeRange();
        this.surface = SurfaceGeometry.create(data, params.surface.indices);
        const edges = params.edges;
        if (!edges || data.type === SurfaceType.VolumeClassifier)
            return;
        if (edges.silhouettes)
            this.silhouetteEdges = SilhouetteEdgeGeometry.createSilhouettes(data, edges.silhouettes);
        if (edges.segments)
            this.segmentEdges = EdgeGeometry.create(data, edges.segments);
        if (edges.polylines)
            this.polylineEdges = PolylineEdgeGeometry.create(data, edges.polylines);
        if (edges.indexed)
            this.indexedEdges = IndexedEdgeGeometry.create(data, edges.indexed);
    }
    static create(params, viewIndependentOrigin) {
        const data = MeshData.create(params, viewIndependentOrigin);
        return data ? new this(data, params) : undefined;
    }
    dispose() {
        if (this.noDispose) {
            return;
        }
        dispose(this.data);
        dispose(this.surface);
        dispose(this.segmentEdges);
        dispose(this.silhouetteEdges);
        dispose(this.polylineEdges);
        dispose(this.indexedEdges);
    }
    get isDisposed() {
        return this.data.isDisposed &&
            (!this.surface || this.surface.isDisposed) &&
            (!this.segmentEdges || this.segmentEdges.isDisposed) &&
            (!this.silhouetteEdges || this.silhouetteEdges.isDisposed) &&
            (!this.polylineEdges || this.polylineEdges.isDisposed) &&
            (!this.indexedEdges || this.indexedEdges.isDisposed);
    }
    collectStatistics(stats) {
        this.data.collectStatistics(stats);
        this.surface?.collectStatistics(stats);
        this.segmentEdges?.collectStatistics(stats);
        this.silhouetteEdges?.collectStatistics(stats);
        this.polylineEdges?.collectStatistics(stats);
        this.indexedEdges?.collectStatistics(stats);
    }
    computeRange(out) {
        return this.range.clone(out);
    }
}
/** @internal */
export class MeshGraphic extends Graphic {
    get primitives() { return this._primitives; }
    get meshRange() { return this._meshRange; }
    static create(geometry, instances) {
        return new MeshGraphic(geometry, instances);
    }
    addPrimitive(geometry) {
        if (!geometry)
            return;
        const primitive = Primitive.createShared(geometry, this._instances);
        if (primitive)
            this._primitives.push(primitive);
    }
    constructor(geometry, instances) {
        super();
        this._primitives = [];
        this.meshData = geometry.data;
        this._meshRange = geometry.range;
        this._instances = instances;
        this.addPrimitive(geometry.surface);
        this.addPrimitive(geometry.segmentEdges);
        this.addPrimitive(geometry.silhouetteEdges);
        this.addPrimitive(geometry.polylineEdges);
        this.addPrimitive(geometry.indexedEdges);
    }
    get isDisposed() { return this.meshData.isDisposed && 0 === this._primitives.length; }
    get isPickable() { return false; }
    dispose() {
        for (const primitive of this._primitives)
            dispose(primitive);
        dispose(this.meshData);
        dispose(this._instances);
        this._primitives.length = 0;
    }
    collectStatistics(stats) {
        this.meshData.collectStatistics(stats);
        this._primitives.forEach((prim) => prim.collectStatistics(stats));
        this._instances?.collectStatistics(stats);
    }
    unionRange(range) {
        if (this._instances)
            range.extendRange(range);
        else
            range.extendRange(this._meshRange);
    }
    addCommands(cmds) { this._primitives.forEach((prim) => prim.addCommands(cmds)); }
    addHiliteCommands(cmds, pass) { this._primitives.forEach((prim) => prim.addHiliteCommands(cmds, pass)); }
    get surfaceType() { return this.meshData.type; }
}
//# sourceMappingURL=Mesh.js.map