"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.MeshGraphic = exports.MeshRenderGeometry = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const SurfaceParams_1 = require("../../common/internal/render/SurfaceParams");
const CachedGeometry_1 = require("./CachedGeometry");
const Graphic_1 = require("./Graphic");
const InstancedGeometry_1 = require("./InstancedGeometry");
const Primitive_1 = require("./Primitive");
const EdgeGeometry_1 = require("./EdgeGeometry");
const IndexedEdgeGeometry_1 = require("./IndexedEdgeGeometry");
const SurfaceGeometry_1 = require("./SurfaceGeometry");
const MeshData_1 = require("./MeshData");
/** @internal */
class MeshRenderGeometry {
    constructor(data, params) {
        this.data = data;
        this.range = params.vertices.qparams.computeRange();
        this.surface = SurfaceGeometry_1.SurfaceGeometry.create(data, params.surface.indices);
        const edges = params.edges;
        if (!edges || data.type === SurfaceParams_1.SurfaceType.VolumeClassifier)
            return;
        if (edges.silhouettes)
            this.silhouetteEdges = EdgeGeometry_1.SilhouetteEdgeGeometry.createSilhouettes(data, edges.silhouettes);
        if (edges.segments)
            this.segmentEdges = EdgeGeometry_1.EdgeGeometry.create(data, edges.segments);
        if (edges.polylines)
            this.polylineEdges = EdgeGeometry_1.PolylineEdgeGeometry.create(data, edges.polylines);
        if (edges.indexed)
            this.indexedEdges = IndexedEdgeGeometry_1.IndexedEdgeGeometry.create(data, edges.indexed);
    }
    static create(params, viewIndependentOrigin) {
        const data = MeshData_1.MeshData.create(params, viewIndependentOrigin);
        return data ? new this(data, params) : undefined;
    }
    dispose() {
        (0, core_bentley_1.dispose)(this.data);
        (0, core_bentley_1.dispose)(this.surface);
        (0, core_bentley_1.dispose)(this.segmentEdges);
        (0, core_bentley_1.dispose)(this.silhouetteEdges);
        (0, core_bentley_1.dispose)(this.polylineEdges);
        (0, core_bentley_1.dispose)(this.indexedEdges);
    }
    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);
    }
}
exports.MeshRenderGeometry = MeshRenderGeometry;
/** @internal */
class MeshGraphic extends Graphic_1.Graphic {
    get primitives() { return this._primitives; }
    get meshRange() { return this._meshRange; }
    static create(geometry, instances) {
        let buffers;
        if (instances) {
            if (instances instanceof InstancedGeometry_1.PatternBuffers) {
                buffers = instances;
            }
            else {
                const instancesRange = instances.range ?? InstancedGeometry_1.InstanceBuffers.computeRange(geometry.range, instances.transforms, instances.transformCenter);
                buffers = InstancedGeometry_1.InstanceBuffers.create(instances, instancesRange);
                if (!buffers)
                    return undefined;
            }
        }
        return new MeshGraphic(geometry, buffers);
    }
    addPrimitive(geometry) {
        if (!geometry)
            return;
        (0, core_bentley_1.assert)(geometry instanceof CachedGeometry_1.CachedGeometry);
        const primitive = Primitive_1.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)
            (0, core_bentley_1.dispose)(primitive);
        (0, core_bentley_1.dispose)(this.meshData);
        (0, core_bentley_1.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; }
}
exports.MeshGraphic = MeshGraphic;
//# sourceMappingURL=Mesh.js.map