/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Rendering
 */
import { Transform } from "@itwin/core-geometry";
import { GraphicType } from "../common/render/GraphicType";
import { GraphicAssembler } from "../common/render/GraphicAssembler";
import { _implementationProhibited } from "../common/internal/Symbols";
/** Provides methods for constructing a [[RenderGraphic]] or [[GraphicTemplate]] from geometric primitives and symbology.
 * GraphicBuilder is primarily used for creating [[Decorations]] to be displayed inside a [[Viewport]].
 *
 * The typical process for constructing a [[RenderGraphic]] proceeds as follows:
 *  1. Use [[DecorateContext.createGraphic]] or [[RenderSystem.createGraphic]] to obtain a builder.
 *  2. Set up the symbology using [[GraphicBuilder.activateGraphicParams]] or [[GraphicBuilder.setSymbology]].
 *  3. Add one or more geometric primitives using methods like [[GraphicBuilder.addShape]] and [[GraphicBuilder.addLineString]], possibly setting new symbology in between.
 *  4. Use [[GraphicBuilder.finish]] to produce the finished [[RenderGraphic]].
 *
 * The process for constructing a [[GraphicTemplate]] is similar:
 *  1. Use [[RenderSystem.createGraphic]] to obtain a builder.
 *  2. Set up the symbology using [[GraphicBuilder.activateGraphicParams]] or [[GraphicBuilder.setSymbology]].
 *  3. Add one or more geometric primitives using methods like [[GraphicBuilder.addShape]] and [[GraphicBuilder.addLineString]], possibly setting new symbology in between.
 *  4. Use [[GraphicBuilder.finishTemplate]] to produce the finished [[GraphicTemplate]].
 *
 * @note Most of the methods which add geometry to the builder take ownership of their inputs rather than cloning them.
 * So, for example, if you pass an array of points to addLineString(), you should not subsequently modify that array.
 *
 * @public
 * @extensions
 */
export class GraphicBuilder extends GraphicAssembler {
    /** The iModel associated with this builder, if any. */
    iModel;
    /** @internal */
    _computeChordTolerance;
    /** @internal */
    constructor(options) {
        const vp = options.viewport;
        const placement = options.placement ?? Transform.createIdentity();
        const wantEdges = options.generateEdges ?? (options.type === GraphicType.Scene && (!vp || vp.viewFlags.edgesRequired()));
        const wantNormals = options.wantNormals ?? (wantEdges || options.type === GraphicType.Scene);
        const preserveOrder = options.preserveOrder ?? (options.type === GraphicType.ViewOverlay || options.type === GraphicType.WorldOverlay || options.type === GraphicType.ViewBackground);
        super({
            ...options,
            [_implementationProhibited]: undefined,
            placement,
            wantEdges,
            wantNormals,
            preserveOrder,
        });
        this.iModel = vp?.iModel ?? options.iModel;
        if (!options.viewport) {
            this._computeChordTolerance = options.computeChordTolerance;
            return;
        }
        this._computeChordTolerance = (args) => {
            let pixelSize = 1;
            if (!this.isViewCoordinates) {
                // Compute the horizontal distance in meters between two adjacent pixels at the center of the geometry.
                pixelSize = options.viewport.getPixelSizeAtPoint(args.computeRange().center);
                pixelSize = options.viewport.target.adjustPixelSizeForLOD(pixelSize);
                // Aspect ratio skew > 1.0 stretches the view in Y. In that case use the smaller vertical pixel distance for our stroke tolerance.
                const skew = options.applyAspectRatioSkew ? options.viewport.view.getAspectRatioSkew() : 0;
                if (skew > 1)
                    pixelSize /= skew;
            }
            return pixelSize * 0.25;
        };
    }
}
//# sourceMappingURL=GraphicBuilder.js.map