/** @packageDocumentation
 * @module CartesianGeometry
 */
import { Arc3d } from "../curve/Arc3d";
import { AnnounceNumberNumber, AnnounceNumberNumberCurvePrimitive } from "../curve/CurvePrimitive";
import { Angle } from "../geometry3d/Angle";
import { GrowableXYZArray } from "../geometry3d/GrowableXYZArray";
import { IndexedXYZCollection } from "../geometry3d/IndexedXYZCollection";
import { Plane3dByOriginAndUnitNormal } from "../geometry3d/Plane3dByOriginAndUnitNormal";
import { Point3d, Vector3d } from "../geometry3d/Point3dVector3d";
import { Range1d, Range3d } from "../geometry3d/Range";
import { Ray3d } from "../geometry3d/Ray3d";
import { GrowableXYZArrayCache } from "../geometry3d/ReusableObjectCache";
import { Transform } from "../geometry3d/Transform";
import { Matrix4d } from "../geometry4d/Matrix4d";
import { Polyface, PolyfaceVisitor } from "../polyface/Polyface";
import { ClipPlane, ClipPlaneProps } from "./ClipPlane";
import { Clipper, ClipPlaneContainment, PolygonClipper } from "./ClipUtils";
/** Wire format describing a [[ConvexClipPlaneSet]].
 * @public
 */
export type ConvexClipPlaneSetProps = ClipPlaneProps[];
/**
 * A ConvexClipPlaneSet is a collection of ClipPlanes, often used for bounding regions of space.
 * @public
 */
export declare class ConvexClipPlaneSet implements Clipper, PolygonClipper {
    /** Value acting as "at infinity" for coordinates along a ray. */
    static readonly hugeVal = 1e+37;
    /** Planes that define the convex set. */
    private _planes;
    private constructor();
    /** Return the (reference to the) array of `ClipPlane`. */
    get planes(): ClipPlane[];
    /**
     * Return an array containing all the planes of the convex set.
     * * Note that this has no leading keyword identifying it as a ConvexClipPlaneSet.
     */
    toJSON(): ConvexClipPlaneSetProps;
    /**
     * Extract clip planes from a json array `[ clipPlane, clipPlane ]`.
     * * Non-clipPlane members are ignored.
     */
    static fromJSON(json: ConvexClipPlaneSetProps | undefined, result?: ConvexClipPlaneSet): ConvexClipPlaneSet;
    /**
     * Return true if all members are almostEqual to corresponding members of other. This includes identical order in array.
     * @param other clip plane to compare
     */
    isAlmostEqual(other: ConvexClipPlaneSet): boolean;
    /**
     * Create ConvexClipPlaneSet from an array of planes.
     * * Each plane reference in the `planes` array is taken into the result.
     * * The input array itself is NOT taken into the result.
     */
    static createPlanes(planes: (ClipPlane | Plane3dByOriginAndUnitNormal)[], result?: ConvexClipPlaneSet): ConvexClipPlaneSet;
    /**
     * Create new convex set using selected planes of a Range3d.
     * @param range range with coordinates
     * @param lowX true to clip at the low x plane
     * @param highX true to clip at the high x plane
     * @param lowY true to clip at the low y plane
     * @param highY true to clip at the high z plane
     * @param lowZ true to clip at the low z plane
     * @param highZ true to clip at the high z plane
     */
    static createRange3dPlanes(range: Range3d, lowX?: boolean, highX?: boolean, lowY?: boolean, highY?: boolean, lowZ?: boolean, highZ?: boolean): ConvexClipPlaneSet;
    /** Create an empty `ConvexClipPlaneSet` */
    static createEmpty(result?: ConvexClipPlaneSet): ConvexClipPlaneSet;
    /** Negate all planes of the set. */
    negateAllPlanes(): void;
    /**
     * Create a convex clip plane set that clips to `x0 <= x <= x1` and `y0 <= y <= y1`.
     * * Note that there is no test for the usual ordering `x0 <= x1` or `y0 <= y1`.
     * * if the usual ordering is violated, the convex set is an empty set.
     * * More details can be found at docs/learning/geometry/Clipping.md
     */
    static createXYBox(x0: number, y0: number, x1: number, y1: number, result?: ConvexClipPlaneSet): ConvexClipPlaneSet;
    /**
     * Create a convex set containing a half space for each edge between points of a polyline.
     * * Caller is responsible for assuring the polyline is convex.
     * @param points array of points. Only xy parts are considered.
     * @param interior array whose boolean value is used as both the `interior` and `invisible` bits of the plane for the
     * succeeding segment. If this array is not provided, both are false.
     * @param leftIsInside if true, the interior is "to the left" of the segments. If false, interior is "to the right".
     */
    static createXYPolyLine(points: Point3d[], interior: boolean[] | undefined, leftIsInside: boolean, result?: ConvexClipPlaneSet): ConvexClipPlaneSet;
    /**
     * Create a convexClipPlaneSet with planes whose "inside" normal is to the left of each segment.
     * @param points array of points.
     */
    static createXYPolyLineInsideLeft(points: Point3d[], result?: ConvexClipPlaneSet): ConvexClipPlaneSet;
    /**
     * Set (or reset) a plane and ConvexClipPlaneSet for a convex array, such as a convex facet used for xy clip.
     * * The planeOfPolygon is (re)initialized with the normal from 3 points, but not otherwise referenced.
     * * The ConvexClipPlaneSet is filled with outward normals of the facet edges as viewed to xy plane.
     * @param points
     * @param result
     */
    static setPlaneAndXYLoopCCW(points: GrowableXYZArray, planeOfPolygon: ClipPlane, frustum: ConvexClipPlaneSet): void;
    /** Deep clone of all planes. */
    clone(result?: ConvexClipPlaneSet): ConvexClipPlaneSet;
    /**
     * Test if there is any intersection with a ray defined by origin and direction.
     * * Optionally record the range (null or otherwise) in caller-allocated result.
     * * If the ray is unbounded inside the clip, result can contain positive or negative
     *  "Geometry.largeCoordinateResult" values.
     * * If no result is provide, there are no object allocations.
     * @param result optional Range1d to receive parameters along the ray.
     */
    hasIntersectionWithRay(ray: Ray3d, result?: Range1d, tolerance?: number): boolean;
    /**
     * Multiply all the ClipPlanes DPoint4d by matrix.
     * @param matrix matrix to apply.
     * @param invert if true, use in verse of the matrix.
     * @param transpose if true, use the transpose of the matrix (or inverse, per invert parameter)
     * * Note that if matrixA is applied to all of space, the matrix to send to this method to get a corresponding effect
     * on the plane is the inverse transpose of matrixA.
     * * Callers that will apply the same matrix to many planes should pre-invert the matrix for efficiency.
     * * Both params default to true to get the full effect of transforming space.
     * @param matrix matrix to apply
     */
    multiplyPlanesByMatrix4d(matrix: Matrix4d, invert?: boolean, transpose?: boolean): boolean;
    /** Return true if `point` satisfies `point.isPointInside` for all planes */
    isPointInside(point: Point3d): boolean;
    /** Return true if `point` satisfies `point.isPointOnOrInside` for all planes */
    isPointOnOrInside(point: Point3d, tolerance?: number): boolean;
    /**
     * Test if a sphere is completely inside the convex set.
     * @param centerPoint center of sphere
     * @param radius radius of sphere.
     */
    isSphereInside(centerPoint: Point3d, radius: number): boolean;
    /**
     * Find the parts of the line segment (if any) that is within the convex clip volume.
     * * The line segment is defined by `pointA` and `pointB`.
     * * The input fractional interval from `fraction0` to `fraction1` (increasing) is the active part to consider.
     * * To clip to the usual bounded line segment, start with fractions (0,1).
     * If the clip volume is unbounded, the line interval may also be unbounded.
     * * An unbounded line portion will have fraction coordinates positive or negative `Number.MAX_VALUE`.
     * @param f0 fraction that is the initial lower fraction of the active interval (e.g., 0.0 for bounded segment).
     * @param f1 fraction that is the initial upper fraction of the active interval (e.g., 1.0 for bounded segment).
     * @param pointA segment start (fraction 0)
     * @param pointB segment end (fraction 1)
     * @param announce function to be called to announce a fraction interval that is within the convex clip volume.
     * @returns true if a segment was announced, false if entirely outside.
     */
    announceClippedSegmentIntervals(f0: number, f1: number, pointA: Point3d, pointB: Point3d, announce?: AnnounceNumberNumber): boolean;
    private static _clipArcFractionArray;
    /**
     * Find fractional parts of the arc that are within this ClipPlaneSet, and announce each as
     * * `announce(fraction, fraction, curve)`
     */
    announceClippedArcIntervals(arc: Arc3d, announce?: AnnounceNumberNumberCurvePrimitive): boolean;
    /**
     * Find the parts of the (unbounded) line segment (if any) that is within the convex clip volume.
     * @param pointA segment start (fraction 0)
     * @param pointB segment end (fraction 1)
     * @param announce function to be called to announce a fraction interval that is within the convex clip volume.
     * @returns true if a segment was announced, false if entirely outside.
     */
    clipUnboundedSegment(pointA: Point3d, pointB: Point3d, announce?: AnnounceNumberNumber): boolean;
    /** transform each plane in place. */
    transformInPlace(transform: Transform): void;
    /**
     * Clip a polygon to the inside of the convex set.
     * * Results with 2 or fewer points are ignored.
     * * Other than ensuring capacity in the arrays, there are no object allocations during execution of this function.
     * @param xyz input points.
     * @param work work buffer
     * @param tolerance tolerance for "on plane" decision.
     */
    clipConvexPolygonInPlace(xyz: GrowableXYZArray, work: GrowableXYZArray, tolerance?: number): void;
    /**
     * Clip a convex polygon to (a single) inside part and (possibly many) outside parts.
     * @param xyz input polygon.
     * @param outsideFragments an array to receive (via push, with no preliminary clear) outside fragments
     * @param arrayCache cache for work arrays.
     * @return the surviving inside part (if any)
     * @see polygonClip
     */
    clipInsidePushOutside(xyz: IndexedXYZCollection, outsideFragments: GrowableXYZArray[] | undefined, arrayCache: GrowableXYZArrayCache): GrowableXYZArray | undefined;
    /**
     * Returns 1, 2, or 3 based on whether point array is strongly inside, ambiguous, or strongly outside respectively.
     * * This has a peculiar expected use case as a very fast pre-filter for more precise clipping.
     * * The expected point set is for a polygon.
     * * Hence any clipping will eventually have to consider the lines between the points.
     * * This method looks for the special case of a single clip plane that has all the points outside.
     * * In this case the whole polygon must be outside.
     * * Note that this does not detect a polygon that is outside but "crosses a corner" -- it is mixed with respect to
     * multiple planes.
     */
    classifyPointContainment(points: Point3d[], onIsOutside: boolean): ClipPlaneContainment;
    /**
     * * Create a convex clip set for a polygon swept with possible tilt angle.
     * * planes are constructed by ClipPlane.createEdgeAndUpVector, using successive points from the array.
     * * If the first and last points match, the polygon area is checked.  If the area is negative, points are used in
     * reverse order.
     * * If first and last points do not match, points are used in order given
     * @param points polygon points. (Closure point optional)
     * @param upVector primary sweep direction, as applied by ClipPlane.createEdgeAndUpVector
     * @param tiltAngle angle to tilt sweep planes away from the sweep direction.
     */
    static createSweptPolyline(points: Point3d[], upVector: Vector3d, tiltAngle?: Angle): ConvexClipPlaneSet | undefined;
    /**
     * Add a plane to the convex set.
     * @param plane plane to add
     */
    addPlaneToConvexSet(plane: ClipPlane | Plane3dByOriginAndUnitNormal | undefined): void;
    /**
     * Test many points. Distribute them to arrays depending on in/out result.
     * @param points points to test
     * @param inOrOn points that are in or on the set
     * @param out points that are out.
     */
    clipPointsOnOrInside(points: Point3d[], inOrOn: Point3d[], out: Point3d[]): void;
    /**
     * Clip a polygon to the planes of the clip plane set.
     * * For a convex input polygon, the output polygon is also convex.
     * * For non-convex input, the output polygon may have double-back edges along plane intersections. This is still a
     * valid clip in a parity sense (overlapping regions cancel).
     * @param input polygon, usually convex. Unchanged.
     * @param output output polygon
     * @param work optional work array.
     * @param planeToSkip if this plane is found in the convex set, it is NOT applied.
     * This is useful when caller knows the polygon lies in one of the instance planes.
     * @param tolerance distance tolerance for "on plane" decision. Default value is [[Geometry.smallMetricDistance]].
     * @see appendPolygonClip
     */
    polygonClip(input: GrowableXYZArray | Point3d[], output: GrowableXYZArray, work?: GrowableXYZArray, planeToSkip?: ClipPlane, tolerance?: number): void;
    /**
     * * Define new planes in this ConvexClipPlaneSet so it clips to the inside of a polygon.
     * * always create planes for the swept edges of the polygon
     * * optionally (with nonzero sideSelect) create a cap plane using the polygon normal.
     * @param points Points of a bounding polygon
     * @param sweepDirection direction to sweep.
     * @param sideSelect 0 to have no cap polygon, 1 if the sweep vector side is in, -1 if sweep vector side is out.
     */
    reloadSweptPolygon(points: Point3d[], sweepDirection: Vector3d, sideSelect: number): number;
    /**
     * Compute intersections among all combinations of 3 planes in the convex set.
     * * optionally throw out points that are not in the set.
     * * optionally push the points in the caller-supplied point array.
     * * optionally extend a caller supplied range.
     * * In the common case where the convex set is (a) a slab or (b) a view frustum, there will be 8 points and the
     * range is the range of the convex set.
     * * If the convex set is unbounded, the range only contains the range of the accepted (corner) points, and the
     * range is not a representative of the "range of all points in the set".
     * @param points (optional) array to which computed points are to be added.
     * @param rangeToExtend (optional) range to be extended by the computed points
     * @param transform (optional) transform to apply to the accepted points.
     * @param testContainment if true, test each point to see if it is within the convex set. (send false if confident
     * that the convex set is rectilinear set such as a slab. Send true if chiseled corners are possible).
     * @returns number of points.
     */
    computePlanePlanePlaneIntersections(points: Point3d[] | undefined, rangeToExtend: Range3d | undefined, transform?: Transform, testContainment?: boolean): number;
    /**
     * Set the `invisible` property on each plane of the convex set.
     * @param invisible value to store
     */
    setInvisible(invisible: boolean): void;
    /**
     * Add planes for z-direction clip between low and high z levels.
     * @param invisible value to apply to the `invisible` bit for the new planes
     * @param zLow low z value.  The plane clips out points with z below this.
     * @param zHigh high z value.  The plane clips out points with z above this.
     */
    addZClipPlanes(invisible: boolean, zLow?: number, zHigh?: number): void;
    /**
     * Implement appendPolygonClip, as defined in interface PolygonClipper.
     * @param xyz convex polygon.  This is not changed.
     * @param insideFragments Array to receive "inside" fragments. Each fragment is a GrowableXYZArray grabbed from
     * the cache. This is NOT cleared.
     * @param outsideFragments Array to receive "outside" fragments. Each fragment is a GrowableXYZArray grabbed from
     * the cache. This is NOT cleared.
     * @param arrayCache cache for reusable GrowableXYZArray.
     * @see polygonClip
     */
    appendPolygonClip(xyz: IndexedXYZCollection, insideFragments: GrowableXYZArray[], outsideFragments: GrowableXYZArray[], arrayCache: GrowableXYZArrayCache): void;
    /**
     * Create a convex clip set from a convex mesh.
     * * Create a plane for each facet.
     * * Assemble the planes as a single clip plane set.
     * * If the facets are closed by edge pairing, use the sign of the computed volume to point the plane normals inward.
     * * If the facets are not closed, the facet orientation determines plane orientation.
     * * The implication of this is that if the facets are a convex volume, the returned clip plane set is convex.
     * @param convexMesh input mesh. For best results, the mesh should be closed and convex.
     * @param result optional preallocated result to reuse and return
     * @return clipper and volume (zero if mesh is not closed)
    */
    static createConvexPolyface(convexMesh: Polyface | PolyfaceVisitor, result?: ConvexClipPlaneSet): {
        clipper: ConvexClipPlaneSet;
        volume: number;
    };
}
//# sourceMappingURL=ConvexClipPlaneSet.d.ts.map