import { GrowableXYArray } from "../geometry3d/GrowableXYArray";
import { GrowableXYZArray } from "../geometry3d/GrowableXYZArray";
import { Point2d } from "../geometry3d/Point2dVector2d";
import { Point3d, Vector3d } from "../geometry3d/Point3dVector3d";
import { Range3d } from "../geometry3d/Range";
import { Transform } from "../geometry3d/Transform";
import { PolyfaceAuxData } from "./AuxData";
import { FacetFaceData } from "./FacetFaceData";
import { TaggedNumericData } from "./TaggedNumericData";
/**
 * `PolyfaceData` carries data arrays for point, normal, uv-parameters, and color, and index arrays for each.
 * * Normal, uv-parameter, and color data are optional.
 * * A given data array is defined if and only if its corresponding index array is defined.
 * * All defined index arrays have parallel face loop order and structure, and thus the same length.
 * * `IndexedPolyface` carries a PolyfaceData as a member (NOT as a base class; it already has `GeometryQuery` as base).
 * * `IndexedPolyfaceVisitor` uses PolyfaceData as a base class. In this use, there is only a single facet in `PolyfaceData`.
 * * `PolyfaceData` does not know what index range constitutes a given facet. This is managed by a derived/carrier class.
 * @public
 */
export declare class PolyfaceData {
    /**
     * Relative tolerance used in tests for planar facets.
     * @internal
    */
    static readonly planarityLocalRelTol = 1e-13;
    /** Coordinate data for points in the facets (packed as numbers in a contiguous array). */
    point: GrowableXYZArray;
    /** Indices of points at facet vertices. */
    pointIndex: number[];
    /** Coordinates of normal vectors (packed as numbers in a contiguous array). */
    normal?: GrowableXYZArray;
    /** Indices of normals at facet vertices. */
    normalIndex?: number[];
    /** Coordinates of uv parameters (packed as numbers in a contiguous array). */
    param?: GrowableXYArray;
    /** Indices of params at facet vertices. */
    paramIndex?: number[];
    /**
     * Color values. These are carried around as simple numbers, but are probably required (by display systems) to map
     * exactly to 32-bit integers.
     */
    color?: number[];
    /** Indices of colors at facet vertices. */
    colorIndex?: number[];
    /**
     * Map from facet index to face data.
     * * A "face" is a logical grouping of connected facets in the mesh, e.g., the facets that resulted from faceting
     * a given face of a solid.
     * * Face data remains empty until a face is specified.
     */
    face: FacetFaceData[];
    /** Auxiliary data. */
    auxData?: PolyfaceAuxData;
    /** Tagged geometry data. */
    taggedNumericData?: TaggedNumericData;
    /**
     * Booleans indicating visibility of corresponding edges.
     * * The `edgeVisible` array is parallel to the `pointIndex` array.
     * * The visibility flag applies to the edge whose start vertex index appears in the same place in the `pointIndex` array.
     * * For example, consider the mesh with 2 triangular facets given by `pointIndex = [1,0,2, 1,2,3]`. If the triangles'
     * shared edge is hidden, then the mesh has `edgeVisible = [true,true,false, false,true,true]`.
     */
    edgeVisible: boolean[];
    /** The [[twoSided]] flag. */
    private _twoSided;
    /**
     * Flag indicating if the mesh closure is unknown (0), open sheet (1), closed solid (2).
     * * A boundary edge of a mesh is defined as an edge with only one connected facet.
     * * Closed solid is a mesh with no boundary edge. Open sheet is a mesh that has boundary edge(s).
     */
    private _expectedClosure;
    /**
     * Optional index array for moving "across an edge" to an adjacent facet.
     * * This array:
     *   * completes the topology of the polyface.
     *   * has the same length as the other PolyfaceData index arrays.
     *   * is populated by [[IndexedPolyfaceWalker.buildEdgeMateIndices]].
     *   * is used by [[IndexedPolyfaceWalker]] to traverse the polyface.
     *   * is invalid if the polyface topology is subsequently changed.
     * * Let k1 = edgeMateIndex[k] be defined. Then:
     *   * k1 is an index (an "edge index") into the PolyfaceData index arrays. (The same for k.)
     *   * k and k1 refer to the two oppositely oriented sides of an interior edge in the polyface.
     *   * pointIndex[k1] is the point at the opposite end of the edge that starts at pointIndex[k].
     *   * edgeMateIndex[k1] === k.
     * * If k1 is undefined, then there is no adjacent facet across the edge that starts at pointIndex[k],
     * i.e. k refers to a boundary edge.
     */
    edgeMateIndex?: Array<number | undefined>;
    /**
     * Dereference the edgeMateIndex array.
     * * This method returns undefined if:
     *   * k is undefined
     *   * `this.edgeMateIndex` is undefined
     *   * k is out of bounds for `this.edgeMateIndex`
     *   * `this.edgeMateIndex[k]` is undefined
     */
    edgeIndexToEdgeMateIndex(k: number | undefined): number | undefined;
    /** Test if `value` is a valid index into the `pointIndex` array. */
    isValidEdgeIndex(value: number | undefined): boolean;
    /**
     * Constructor for facets.
     * @param needNormals `true` to allocate empty normal data and index arrays; `false` (default) to leave undefined.
     * @param needParams `true` to allocate empty uv parameter data and index arrays; `false` (default) to leave undefined.
     * @param needColors `true` to allocate empty color data and index arrays; `false` (default) to leave undefined.
     * @param twoSided `true` (default) if the facets are to be considered viewable from the back; `false` if they are amenable to backface culling.
     */
    constructor(needNormals?: boolean, needParams?: boolean, needColors?: boolean, twoSided?: boolean);
    /** Return a deep clone. */
    clone(): PolyfaceData;
    /** Test for equal indices and nearly equal coordinates. */
    isAlmostEqual(other: PolyfaceData): boolean;
    /** Ask if normals are required in this mesh. */
    get requireNormals(): boolean;
    /** Ask if params are required in this mesh. */
    get requireParams(): boolean;
    /** Ask if colors are required in this mesh. */
    get requireColors(): boolean;
    /** Get the point count */
    get pointCount(): number;
    /** Get the normal count */
    get normalCount(): number;
    /** Get the param count */
    get paramCount(): number;
    /** Get the color count */
    get colorCount(): number;
    /** Get the index count. Note that the point array is always indexed, and index arrays all have the same length. */
    get indexCount(): number;
    /**
     * Get the number of faces.
     * * Note that a "face" is not a facet.
     * * A face is a subset of the Polyface's facets grouped for application purposes.
     */
    get faceCount(): number;
    /** Return indexed point at index `i`. This is a COPY of the coordinates, not a reference. */
    getPoint(i: number, result?: Point3d): Point3d | undefined;
    /** Return indexed normal at index `i`. This is a COPY of the normal, not a reference. */
    getNormal(i: number, result?: Vector3d): Vector3d | undefined;
    /** Return indexed param at index `i`. This is a COPY of the coordinates, not a reference. */
    getParam(i: number, result?: Point2d): Point2d | undefined;
    /** Return indexed color at index `i`. Index `i` is not checked for validity. */
    getColor(i: number): number;
    /** Return indexed visibility. at index `i`. Index `i` is not checked for validity. */
    getEdgeVisible(i: number): boolean;
    /**
     * Boolean flag indicating if the facets are viewable from the back.
     * * Default value is true.
     * * Set to false only if the mesh is known to be a closed volume with outward normals,
     * indicating it is amenable to backface culling for improved display performance.
     */
    get twoSided(): boolean;
    set twoSided(value: boolean);
    /** Get flag indicating if the mesh closure is unknown (0), open sheet (1), closed solid (2). */
    get expectedClosure(): number;
    set expectedClosure(value: number);
    /** Set the tagged geometry data. */
    setTaggedNumericData(data: TaggedNumericData | undefined): void;
    /** Copy the contents (not pointer) of `point[i]` into `dest`. Index `i` is not checked for validity. */
    copyPointTo(i: number, dest: Point3d): void;
    /** Copy the contents (not pointer) of `normal[i]` into `dest`. Index `i` is not checked for validity. */
    copyNormalTo(i: number, dest: Vector3d): void;
    /** Copy the contents (not pointer) of `param[i]` into `dest`. Index `i` is not checked for validity. */
    copyParamTo(i: number, dest: Point2d): void;
    /** Test if param at a index `i` matches the given uv */
    isAlmostEqualParamIndexUV(i: number, u: number, v: number): boolean;
    /**
     * Copy data from `other` to `this`.
     * * This is the essence of transferring coordinates spread throughout a large polyface into a visitor's single facet.
     * * Common usage: "other" is a Polyface, "this" is a PolyfaceVisitor to receive data from a single facet of the Polyface.
     * * Does NOT copy face data - visitors reference the FacetFaceData array for the whole polyface.
     * @param other polyface data being mined.
     * @param index0 start index in other's index arrays.
     * @param index1 end index (one beyond last data accessed) in other's index arrays.
     * @param numWrap number of points to replicate as wraparound.
     */
    gatherIndexedData(other: PolyfaceData, index0: number, index1: number, numWrap: number): void;
    /** Trim the `data` arrays to the stated `length`. */
    private static trimArray;
    /**
     * Trim all index arrays to the stated `length`.
     * * This is called by PolyfaceBuilder to clean up after an aborted construction sequence.
     */
    trimAllIndexArrays(length: number): void;
    /**
     * Resize all data and index arrays to the specified `length`.
     * * This is used by visitors, whose data and index arrays are all parallel.
     */
    resizeAllArrays(length: number): void;
    /**
     * Resize all data arrays to the specified `length`.
     * @deprecated in 4.5.0 - will not be removed until after 2026-06-13. Because name is misleading. Call [[PolyfaceData.resizeAllArrays]] instead.
     */
    resizeAllDataArrays(length: number): void;
    /** Return the range of the point array (optionally transformed). */
    range(result?: Range3d, transform?: Transform): Range3d;
    /** Extend `range` with coordinates from this mesh, optionally transformed. */
    extendRange(range: Range3d, transform?: Transform): void;
    /**
     * Apply a transform to the mesh data.
     * * Transform the data as follows:
     *   * apply `transform` to points.
     *   * apply inverse transpose of `transform` to normals and renormalize. This preserves normals perpendicular
     * to transformed facets, and keeps them pointing outward, e.g, if the mesh is closed. If the transform is not
     * invertible or a normal has zero length, the normal(s) are left unchanged, and this error is silently ignored.
     *   * apply `transform` to auxData.
     *   * scale faceData distances by the cube root of the absolute value of the determinant of `transform.matrix`.
     * * Note that if the transform is a mirror, this method does NOT reverse index order. This is the caller's
     * responsibility. This base class is just a data carrier: PolyfaceData does not know if the index order has
     * special meaning.
    * * Note that this method always returns true. If transforming normals fails (due to singular matrix or zero
     * normal), the original normal(s) are left unchanged.
     */
    tryTransformInPlace(transform: Transform): boolean;
    /**
     * Compress the instance by equating duplicate data.
     * * Search for duplicates within vertices, normals, params, and colors.
     * * Compress each data array.
     * * Revise all indexing for the relocated data.
     * * [[PolyfaceAuxData]] is compressed if and only if exactly one [[AuxChannelData]] is present.
     * @param tolerance (optional) tolerance for clustering mesh vertices only. Default value, and the tolerance used to cluster all other data, is [[Geometry.smallMetricDistance]].
     */
    compress(tolerance?: number): void;
    /**
     * Test if `facetStartIndex` is (minimally) valid.
     * * Length must be nonzero (recall that for "no facets", the `facetStartIndex` array still must contain a 0).
     * * Each entry must be strictly smaller than the one that follows.
     * @param facetStartIndex start indices of all facets. Facet k starts at facetStartIndex[k] up to (but not including)
     * `facetStartIndex[k + 1]`
     */
    static isValidFacetStartIndexArray(facetStartIndex: number[]): boolean;
    /**
     * Reverse the indices for the specified facets in the given index array.
     * * Parameterized over type T so non-number data (e.g., boolean visibility flags) can be reversed.
     * @param facetStartIndex start indices of *consecutive* facets to be reversed, e.g., an IndexedPolyface's _facetStart
     * array. See the non-static [[reverseIndices]].
     * @param indices the index array, e.g., pointIndex, normalIndex, etc.
     * @param preserveStart `true` to preserve the start index of each facet (e.g., facet [1,2,3,4] becomes [1,4,3,2]);
     * `false` to reverse all indices (e.g., facet [1,2,3,4] becomes [4,3,2,1]).
     */
    static reverseIndices<T>(facetStartIndex: number[], indices: T[] | undefined, preserveStart: boolean): boolean;
    /**
     * Reverse the indices for the specified facet in the specified index array.
     * * Parameterized over type T so non-number data (e.g., boolean visibility flags) can be reversed.
     * @param facetIndex index of the facet to reverse. The entries of `indices` to be reversed are found at
     * `facetStartIndex[facetIndex] <= i < facetStartIndex[facetIndex + 1]`.
     * @param facetStartIndex start indices of *consecutive* facets, e.g., an IndexedPolyface's _facetStart array.
     * See [[reverseIndices]].
     * @param indices the index array, e.g., pointIndex, normalIndex, etc.
     * @param preserveStart `true` to preserve the start index of each facet (e.g., facet [1,2,3,4] becomes [1,4,3,2]);
     * `false` to reverse all indices (e.g., facet [1,2,3,4] becomes [4,3,2,1]).
     */
    static reverseIndicesSingleFacet<T>(facetIndex: number, facetStartIndex: number[], indices: T[] | undefined, preserveStart: boolean): boolean;
    /**
     * Reverse the indices for the specified facets in the index arrays (pointIndex, normalIndex, paramIndex, colorIndex,
     * and edgeVisible).
     * @param facetStartIndex start indices of *consecutive* facets to be reversed.
     * * Consecutive indices in this array define where a given facet is represented in each of the parallel index arrays.
     * * The indices for facet k are `facetStartIndex[k]` up to (but not including) `facetStartIndex[k + 1]`.
     * * This implies `facetStartIndex[k + 1]` is both the upper limit of facet k's indices, and the start index of facet k+1.
     * * For example, passing an IndexedPolyface's _facetStart array into this method reverses every facet.
    */
    reverseIndices(facetStartIndex?: number[]): void;
    /**
     * Reverse the indices for the specified facet in the index arrays (pointIndex, normalIndex, paramIndex, colorIndex,
     * and edgeVisible).
     * @param facetIndex index of the facet to reverse. The entries of each index array to be reversed are found at
     * `facetStartIndex[facetIndex] <= i < facetStartIndex[facetIndex + 1]`.
     * @param facetStartIndex start indices of *consecutive* facets, e.g., an IndexedPolyface's _facetStart array.
     * See [[reverseIndices]].
     */
    reverseIndicesSingleFacet(facetIndex: number, facetStartIndex: number[]): void;
    /** Scale all the normals by -1. */
    reverseNormals(): void;
}
//# sourceMappingURL=PolyfaceData.d.ts.map